Repository: ElemeFE/element Branch: dev Commit: c345bb453bf1 Files: 1077 Total size: 5.5 MB Directory structure: gitextract_qbif0oxx/ ├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github/ │ ├── CONTRIBUTING.en-US.md │ ├── CONTRIBUTING.es.md │ ├── CONTRIBUTING.fr-FR.md │ ├── CONTRIBUTING.zh-CN.md │ ├── ISSUE_TEMPLATE/ │ │ └── config.yml │ ├── ISSUE_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── stale.yml │ └── workflows/ │ ├── preview-build.yml │ └── preview-deploy.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.en-US.md ├── CHANGELOG.es.md ├── CHANGELOG.fr-FR.md ├── CHANGELOG.zh-CN.md ├── FAQ.md ├── LICENSE ├── Makefile ├── README.md ├── build/ │ ├── bin/ │ │ ├── build-entry.js │ │ ├── build-locale.js │ │ ├── gen-cssfile.js │ │ ├── gen-indices.js │ │ ├── i18n.js │ │ ├── iconInit.js │ │ ├── new-lang.js │ │ ├── new.js │ │ ├── template.js │ │ └── version.js │ ├── config.js │ ├── deploy-ci.sh │ ├── deploy-faas.sh │ ├── gen-single-config.js │ ├── git-release.sh │ ├── md-loader/ │ │ ├── config.js │ │ ├── containers.js │ │ ├── fence.js │ │ ├── index.js │ │ └── util.js │ ├── release.sh │ ├── webpack.common.js │ ├── webpack.component.js │ ├── webpack.conf.js │ ├── webpack.demo.js │ ├── webpack.extension.js │ └── webpack.test.js ├── components.json ├── examples/ │ ├── app.vue │ ├── assets/ │ │ └── styles/ │ │ ├── common.css │ │ └── fonts/ │ │ └── style.css │ ├── bus.js │ ├── color.js │ ├── components/ │ │ ├── demo-block.vue │ │ ├── footer-nav.vue │ │ ├── footer.vue │ │ ├── header.vue │ │ ├── search.vue │ │ ├── side-nav.vue │ │ ├── theme/ │ │ │ ├── basic-tokens-preview.vue │ │ │ ├── components-preview.vue │ │ │ ├── constant.js │ │ │ ├── loader/ │ │ │ │ ├── ajax.js │ │ │ │ ├── api.js │ │ │ │ ├── docStyle.vue │ │ │ │ ├── index.vue │ │ │ │ └── loading/ │ │ │ │ ├── index.vue │ │ │ │ ├── progress.js │ │ │ │ └── progress.vue │ │ │ ├── localstorage.js │ │ │ ├── theme-card.vue │ │ │ ├── theme-list.js │ │ │ └── utils.js │ │ ├── theme-configurator/ │ │ │ ├── action.vue │ │ │ ├── editor/ │ │ │ │ ├── borderRadius.vue │ │ │ │ ├── boxShadow.vue │ │ │ │ ├── color-picker/ │ │ │ │ │ ├── index.js │ │ │ │ │ └── src/ │ │ │ │ │ ├── color.js │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── alpha-slider.vue │ │ │ │ │ │ ├── color-list.vue │ │ │ │ │ │ ├── hue-slider.vue │ │ │ │ │ │ ├── picker-dropdown.vue │ │ │ │ │ │ ├── predefine.vue │ │ │ │ │ │ └── sv-panel.vue │ │ │ │ │ ├── draggable.js │ │ │ │ │ └── main.vue │ │ │ │ ├── color.vue │ │ │ │ ├── fontLineHeight.vue │ │ │ │ ├── fontSize.vue │ │ │ │ ├── fontWeight.vue │ │ │ │ ├── input.vue │ │ │ │ ├── mixin.vue │ │ │ │ └── simpleText.vue │ │ │ ├── index.vue │ │ │ ├── main.vue │ │ │ ├── shortcut.vue │ │ │ └── utils/ │ │ │ ├── boxShadow.js │ │ │ └── utils.js │ │ └── theme-picker.vue │ ├── demo-styles/ │ │ ├── alert.scss │ │ ├── avatar.scss │ │ ├── badge.scss │ │ ├── border.scss │ │ ├── button.scss │ │ ├── calendar.scss │ │ ├── card.scss │ │ ├── carousel.scss │ │ ├── cascader.scss │ │ ├── collapse.scss │ │ ├── color-picker.scss │ │ ├── color.scss │ │ ├── container.scss │ │ ├── date-picker.scss │ │ ├── datetime-picker.scss │ │ ├── descriptions.scss │ │ ├── dialog.scss │ │ ├── divider.scss │ │ ├── drawer.scss │ │ ├── dropdown.scss │ │ ├── form.scss │ │ ├── i18n.scss │ │ ├── icon.scss │ │ ├── image.scss │ │ ├── index.scss │ │ ├── infinite-scroll.scss │ │ ├── input-number.scss │ │ ├── input.scss │ │ ├── layout.scss │ │ ├── loading.scss │ │ ├── menu.scss │ │ ├── pagination.scss │ │ ├── popover.scss │ │ ├── progress.scss │ │ ├── rate.scss │ │ ├── select.scss │ │ ├── skeleton.scss │ │ ├── slider.scss │ │ ├── switch.scss │ │ ├── table.scss │ │ ├── tag.scss │ │ ├── time-picker.scss │ │ ├── timeline.scss │ │ ├── tooltip.scss │ │ ├── transfer.scss │ │ ├── transition.scss │ │ ├── tree.scss │ │ ├── typography.scss │ │ └── upload.scss │ ├── docs/ │ │ ├── en-US/ │ │ │ ├── alert.md │ │ │ ├── avatar.md │ │ │ ├── backtop.md │ │ │ ├── badge.md │ │ │ ├── border.md │ │ │ ├── breadcrumb.md │ │ │ ├── button.md │ │ │ ├── calendar.md │ │ │ ├── card.md │ │ │ ├── carousel.md │ │ │ ├── cascader.md │ │ │ ├── checkbox.md │ │ │ ├── collapse.md │ │ │ ├── color-picker.md │ │ │ ├── color.md │ │ │ ├── container.md │ │ │ ├── custom-theme.md │ │ │ ├── date-picker.md │ │ │ ├── datetime-picker.md │ │ │ ├── descriptions.md │ │ │ ├── dialog.md │ │ │ ├── divider.md │ │ │ ├── drawer.md │ │ │ ├── dropdown.md │ │ │ ├── empty.md │ │ │ ├── form.md │ │ │ ├── i18n.md │ │ │ ├── icon.md │ │ │ ├── image.md │ │ │ ├── infiniteScroll.md │ │ │ ├── input-number.md │ │ │ ├── input.md │ │ │ ├── installation.md │ │ │ ├── layout.md │ │ │ ├── link.md │ │ │ ├── loading.md │ │ │ ├── menu.md │ │ │ ├── message-box.md │ │ │ ├── message.md │ │ │ ├── notification.md │ │ │ ├── page-header.md │ │ │ ├── pagination.md │ │ │ ├── popconfirm.md │ │ │ ├── popover.md │ │ │ ├── progress.md │ │ │ ├── quickstart.md │ │ │ ├── radio.md │ │ │ ├── rate.md │ │ │ ├── result.md │ │ │ ├── select.md │ │ │ ├── skeleton.md │ │ │ ├── slider.md │ │ │ ├── statistic.md │ │ │ ├── steps.md │ │ │ ├── switch.md │ │ │ ├── table.md │ │ │ ├── tabs.md │ │ │ ├── tag.md │ │ │ ├── time-picker.md │ │ │ ├── timeline.md │ │ │ ├── tooltip.md │ │ │ ├── transfer.md │ │ │ ├── transition.md │ │ │ ├── tree.md │ │ │ ├── typography.md │ │ │ └── upload.md │ │ ├── es/ │ │ │ ├── alert.md │ │ │ ├── avatar.md │ │ │ ├── backtop.md │ │ │ ├── badge.md │ │ │ ├── border.md │ │ │ ├── breadcrumb.md │ │ │ ├── button.md │ │ │ ├── calendar.md │ │ │ ├── card.md │ │ │ ├── carousel.md │ │ │ ├── cascader.md │ │ │ ├── checkbox.md │ │ │ ├── collapse.md │ │ │ ├── color-picker.md │ │ │ ├── color.md │ │ │ ├── container.md │ │ │ ├── custom-theme.md │ │ │ ├── date-picker.md │ │ │ ├── datetime-picker.md │ │ │ ├── descriptions.md │ │ │ ├── dialog.md │ │ │ ├── divider.md │ │ │ ├── drawer.md │ │ │ ├── dropdown.md │ │ │ ├── empty.md │ │ │ ├── form.md │ │ │ ├── i18n.md │ │ │ ├── icon.md │ │ │ ├── image.md │ │ │ ├── infiniteScroll.md │ │ │ ├── input-number.md │ │ │ ├── input.md │ │ │ ├── installation.md │ │ │ ├── layout.md │ │ │ ├── link.md │ │ │ ├── loading.md │ │ │ ├── menu.md │ │ │ ├── message-box.md │ │ │ ├── message.md │ │ │ ├── notification.md │ │ │ ├── page-header.md │ │ │ ├── pagination.md │ │ │ ├── popconfirm.md │ │ │ ├── popover.md │ │ │ ├── progress.md │ │ │ ├── quickstart.md │ │ │ ├── radio.md │ │ │ ├── rate.md │ │ │ ├── result.md │ │ │ ├── select.md │ │ │ ├── skeleton.md │ │ │ ├── slider.md │ │ │ ├── statistic.md │ │ │ ├── steps.md │ │ │ ├── switch.md │ │ │ ├── table.md │ │ │ ├── tabs.md │ │ │ ├── tag.md │ │ │ ├── time-picker.md │ │ │ ├── timeline.md │ │ │ ├── tooltip.md │ │ │ ├── transfer.md │ │ │ ├── transition.md │ │ │ ├── tree.md │ │ │ ├── typography.md │ │ │ └── upload.md │ │ ├── fr-FR/ │ │ │ ├── alert.md │ │ │ ├── avatar.md │ │ │ ├── backtop.md │ │ │ ├── badge.md │ │ │ ├── border.md │ │ │ ├── breadcrumb.md │ │ │ ├── button.md │ │ │ ├── calendar.md │ │ │ ├── card.md │ │ │ ├── carousel.md │ │ │ ├── cascader.md │ │ │ ├── checkbox.md │ │ │ ├── collapse.md │ │ │ ├── color-picker.md │ │ │ ├── color.md │ │ │ ├── container.md │ │ │ ├── custom-theme.md │ │ │ ├── date-picker.md │ │ │ ├── datetime-picker.md │ │ │ ├── descriptions.md │ │ │ ├── dialog.md │ │ │ ├── divider.md │ │ │ ├── drawer.md │ │ │ ├── dropdown.md │ │ │ ├── empty.md │ │ │ ├── form.md │ │ │ ├── i18n.md │ │ │ ├── icon.md │ │ │ ├── image.md │ │ │ ├── infiniteScroll.md │ │ │ ├── input-number.md │ │ │ ├── input.md │ │ │ ├── installation.md │ │ │ ├── layout.md │ │ │ ├── link.md │ │ │ ├── loading.md │ │ │ ├── menu.md │ │ │ ├── message-box.md │ │ │ ├── message.md │ │ │ ├── notification.md │ │ │ ├── page-header.md │ │ │ ├── pagination.md │ │ │ ├── popconfirm.md │ │ │ ├── popover.md │ │ │ ├── progress.md │ │ │ ├── quickstart.md │ │ │ ├── radio.md │ │ │ ├── rate.md │ │ │ ├── result.md │ │ │ ├── select.md │ │ │ ├── skeleton.md │ │ │ ├── slider.md │ │ │ ├── statistic.md │ │ │ ├── steps.md │ │ │ ├── switch.md │ │ │ ├── table.md │ │ │ ├── tabs.md │ │ │ ├── tag.md │ │ │ ├── time-picker.md │ │ │ ├── timeline.md │ │ │ ├── tooltip.md │ │ │ ├── transfer.md │ │ │ ├── transition.md │ │ │ ├── tree.md │ │ │ ├── typography.md │ │ │ └── upload.md │ │ └── zh-CN/ │ │ ├── alert.md │ │ ├── avatar.md │ │ ├── backtop.md │ │ ├── badge.md │ │ ├── border.md │ │ ├── breadcrumb.md │ │ ├── button.md │ │ ├── calendar.md │ │ ├── card.md │ │ ├── carousel.md │ │ ├── cascader.md │ │ ├── checkbox.md │ │ ├── collapse.md │ │ ├── color-picker.md │ │ ├── color.md │ │ ├── container.md │ │ ├── custom-theme.md │ │ ├── date-picker.md │ │ ├── datetime-picker.md │ │ ├── descriptions.md │ │ ├── dialog.md │ │ ├── divider.md │ │ ├── drawer.md │ │ ├── dropdown.md │ │ ├── empty.md │ │ ├── form.md │ │ ├── i18n.md │ │ ├── icon.md │ │ ├── image.md │ │ ├── infiniteScroll.md │ │ ├── input-number.md │ │ ├── input.md │ │ ├── installation.md │ │ ├── layout.md │ │ ├── link.md │ │ ├── loading.md │ │ ├── menu.md │ │ ├── message-box.md │ │ ├── message.md │ │ ├── notification.md │ │ ├── page-header.md │ │ ├── pagination.md │ │ ├── popconfirm.md │ │ ├── popover.md │ │ ├── progress.md │ │ ├── quickstart.md │ │ ├── radio.md │ │ ├── rate.md │ │ ├── result.md │ │ ├── select.md │ │ ├── skeleton.md │ │ ├── slider.md │ │ ├── statistic.md │ │ ├── steps.md │ │ ├── switch.md │ │ ├── table.md │ │ ├── tabs.md │ │ ├── tag.md │ │ ├── time-picker.md │ │ ├── timeline.md │ │ ├── tooltip.md │ │ ├── transfer.md │ │ ├── transition.md │ │ ├── tree.md │ │ ├── typography.md │ │ └── upload.md │ ├── dom/ │ │ └── class.js │ ├── entry.js │ ├── extension/ │ │ ├── .gitignore │ │ └── src/ │ │ ├── app.js │ │ ├── background.js │ │ ├── editor/ │ │ │ ├── editor.vue │ │ │ ├── gallery.vue │ │ │ ├── index.vue │ │ │ └── utils.js │ │ ├── entry.js │ │ └── manifest.json │ ├── i18n/ │ │ ├── component.json │ │ ├── page.json │ │ ├── route.json │ │ ├── theme-editor.json │ │ └── title.json │ ├── icon.json │ ├── index.tpl │ ├── nav.config.json │ ├── pages/ │ │ └── template/ │ │ ├── changelog.tpl │ │ ├── component.tpl │ │ ├── design.tpl │ │ ├── guide.tpl │ │ ├── index.tpl │ │ ├── nav.tpl │ │ ├── resource.tpl │ │ ├── theme-nav.tpl │ │ ├── theme-preview.tpl │ │ └── theme.tpl │ ├── play/ │ │ └── index.vue │ ├── play.js │ ├── route.config.js │ ├── util.js │ └── versions.json ├── package.json ├── packages/ │ ├── alert/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── aside/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── autocomplete/ │ │ ├── index.js │ │ └── src/ │ │ ├── autocomplete-suggestions.vue │ │ └── autocomplete.vue │ ├── avatar/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── backtop/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── badge/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── breadcrumb/ │ │ ├── index.js │ │ └── src/ │ │ ├── breadcrumb-item.vue │ │ └── breadcrumb.vue │ ├── breadcrumb-item/ │ │ └── index.js │ ├── button/ │ │ ├── index.js │ │ └── src/ │ │ ├── button-group.vue │ │ └── button.vue │ ├── button-group/ │ │ └── index.js │ ├── calendar/ │ │ ├── index.js │ │ └── src/ │ │ ├── date-table.vue │ │ └── main.vue │ ├── card/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── carousel/ │ │ ├── index.js │ │ └── src/ │ │ ├── item.vue │ │ └── main.vue │ ├── carousel-item/ │ │ └── index.js │ ├── cascader/ │ │ ├── index.js │ │ └── src/ │ │ └── cascader.vue │ ├── cascader-panel/ │ │ ├── index.js │ │ └── src/ │ │ ├── cascader-menu.vue │ │ ├── cascader-node.vue │ │ ├── cascader-panel.vue │ │ ├── node.js │ │ └── store.js │ ├── checkbox/ │ │ ├── index.js │ │ └── src/ │ │ ├── checkbox-button.vue │ │ ├── checkbox-group.vue │ │ └── checkbox.vue │ ├── checkbox-button/ │ │ └── index.js │ ├── checkbox-group/ │ │ └── index.js │ ├── col/ │ │ ├── index.js │ │ └── src/ │ │ └── col.js │ ├── collapse/ │ │ ├── index.js │ │ └── src/ │ │ ├── collapse-item.vue │ │ └── collapse.vue │ ├── collapse-item/ │ │ └── index.js │ ├── color-picker/ │ │ ├── index.js │ │ └── src/ │ │ ├── color.js │ │ ├── components/ │ │ │ ├── alpha-slider.vue │ │ │ ├── hue-slider.vue │ │ │ ├── picker-dropdown.vue │ │ │ ├── predefine.vue │ │ │ └── sv-panel.vue │ │ ├── draggable.js │ │ └── main.vue │ ├── container/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── date-picker/ │ │ ├── index.js │ │ └── src/ │ │ ├── basic/ │ │ │ ├── date-table.vue │ │ │ ├── month-table.vue │ │ │ ├── time-spinner.vue │ │ │ └── year-table.vue │ │ ├── panel/ │ │ │ ├── date-range.vue │ │ │ ├── date.vue │ │ │ ├── month-range.vue │ │ │ ├── time-range.vue │ │ │ ├── time-select.vue │ │ │ └── time.vue │ │ ├── picker/ │ │ │ ├── date-picker.js │ │ │ ├── time-picker.js │ │ │ └── time-select.js │ │ └── picker.vue │ ├── descriptions/ │ │ ├── index.js │ │ └── src/ │ │ ├── descriptions-item.js │ │ ├── descriptions-row.js │ │ └── index.js │ ├── descriptions-item/ │ │ └── index.js │ ├── dialog/ │ │ ├── index.js │ │ └── src/ │ │ └── component.vue │ ├── divider/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── drawer/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── dropdown/ │ │ ├── index.js │ │ └── src/ │ │ ├── dropdown-item.vue │ │ ├── dropdown-menu.vue │ │ └── dropdown.vue │ ├── dropdown-item/ │ │ └── index.js │ ├── dropdown-menu/ │ │ └── index.js │ ├── empty/ │ │ ├── index.js │ │ └── src/ │ │ ├── img-empty.vue │ │ └── index.vue │ ├── footer/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── form/ │ │ ├── index.js │ │ └── src/ │ │ ├── form-item.vue │ │ ├── form.vue │ │ └── label-wrap.vue │ ├── form-item/ │ │ └── index.js │ ├── header/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── icon/ │ │ ├── index.js │ │ └── src/ │ │ └── icon.vue │ ├── image/ │ │ ├── index.js │ │ └── src/ │ │ ├── image-viewer.vue │ │ └── main.vue │ ├── infinite-scroll/ │ │ ├── index.js │ │ └── src/ │ │ └── main.js │ ├── input/ │ │ ├── index.js │ │ └── src/ │ │ ├── calcTextareaHeight.js │ │ └── input.vue │ ├── input-number/ │ │ ├── index.js │ │ └── src/ │ │ └── input-number.vue │ ├── link/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── loading/ │ │ ├── index.js │ │ └── src/ │ │ ├── directive.js │ │ ├── index.js │ │ └── loading.vue │ ├── main/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── menu/ │ │ ├── index.js │ │ └── src/ │ │ ├── menu-item-group.vue │ │ ├── menu-item.vue │ │ ├── menu-mixin.js │ │ ├── menu.vue │ │ └── submenu.vue │ ├── menu-item/ │ │ └── index.js │ ├── menu-item-group/ │ │ └── index.js │ ├── message/ │ │ ├── index.js │ │ └── src/ │ │ ├── main.js │ │ └── main.vue │ ├── message-box/ │ │ ├── index.js │ │ └── src/ │ │ ├── main.js │ │ └── main.vue │ ├── notification/ │ │ ├── index.js │ │ └── src/ │ │ ├── main.js │ │ └── main.vue │ ├── option/ │ │ └── index.js │ ├── option-group/ │ │ └── index.js │ ├── page-header/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── pagination/ │ │ ├── index.js │ │ └── src/ │ │ ├── pager.vue │ │ └── pagination.js │ ├── popconfirm/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── popover/ │ │ ├── index.js │ │ └── src/ │ │ ├── directive.js │ │ └── main.vue │ ├── progress/ │ │ ├── index.js │ │ └── src/ │ │ └── progress.vue │ ├── radio/ │ │ ├── index.js │ │ └── src/ │ │ ├── radio-button.vue │ │ ├── radio-group.vue │ │ └── radio.vue │ ├── radio-button/ │ │ └── index.js │ ├── radio-group/ │ │ └── index.js │ ├── rate/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── result/ │ │ ├── index.js │ │ └── src/ │ │ ├── icon-error.vue │ │ ├── icon-info.vue │ │ ├── icon-success.vue │ │ ├── icon-warning.vue │ │ └── index.vue │ ├── row/ │ │ ├── index.js │ │ └── src/ │ │ └── row.js │ ├── scrollbar/ │ │ ├── index.js │ │ └── src/ │ │ ├── bar.js │ │ ├── main.js │ │ └── util.js │ ├── select/ │ │ ├── index.js │ │ └── src/ │ │ ├── navigation-mixin.js │ │ ├── option-group.vue │ │ ├── option.vue │ │ ├── select-dropdown.vue │ │ └── select.vue │ ├── skeleton/ │ │ ├── index.js │ │ └── src/ │ │ ├── img-placeholder.vue │ │ ├── index.vue │ │ └── item.vue │ ├── skeleton-item/ │ │ └── index.js │ ├── slider/ │ │ ├── index.js │ │ └── src/ │ │ ├── button.vue │ │ ├── main.vue │ │ └── marker.js │ ├── spinner/ │ │ ├── index.js │ │ └── src/ │ │ └── spinner.vue │ ├── statistic/ │ │ ├── index.js │ │ └── src/ │ │ └── main.vue │ ├── step/ │ │ └── index.js │ ├── steps/ │ │ ├── README.md │ │ ├── index.js │ │ └── src/ │ │ ├── step.vue │ │ └── steps.vue │ ├── submenu/ │ │ └── index.js │ ├── switch/ │ │ ├── index.js │ │ └── src/ │ │ └── component.vue │ ├── tab-pane/ │ │ └── index.js │ ├── table/ │ │ ├── index.js │ │ └── src/ │ │ ├── config.js │ │ ├── dropdown.js │ │ ├── filter-panel.vue │ │ ├── layout-observer.js │ │ ├── store/ │ │ │ ├── current.js │ │ │ ├── expand.js │ │ │ ├── helper.js │ │ │ ├── index.js │ │ │ ├── tree.js │ │ │ └── watcher.js │ │ ├── table-body.js │ │ ├── table-column.js │ │ ├── table-footer.js │ │ ├── table-header.js │ │ ├── table-layout.js │ │ ├── table-row.js │ │ ├── table.vue │ │ └── util.js │ ├── table-column/ │ │ └── index.js │ ├── tabs/ │ │ ├── index.js │ │ └── src/ │ │ ├── tab-bar.vue │ │ ├── tab-nav.vue │ │ ├── tab-pane.vue │ │ └── tabs.vue │ ├── tag/ │ │ ├── index.js │ │ └── src/ │ │ └── tag.vue │ ├── theme-chalk/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── gulpfile.js │ │ ├── package.json │ │ └── src/ │ │ ├── alert.scss │ │ ├── aside.scss │ │ ├── autocomplete.scss │ │ ├── avatar.scss │ │ ├── backtop.scss │ │ ├── badge.scss │ │ ├── base.scss │ │ ├── breadcrumb-item.scss │ │ ├── breadcrumb.scss │ │ ├── button-group.scss │ │ ├── button.scss │ │ ├── calendar.scss │ │ ├── card.scss │ │ ├── carousel-item.scss │ │ ├── carousel.scss │ │ ├── cascader-panel.scss │ │ ├── cascader.scss │ │ ├── checkbox-button.scss │ │ ├── checkbox-group.scss │ │ ├── checkbox.scss │ │ ├── col.scss │ │ ├── collapse-item.scss │ │ ├── collapse.scss │ │ ├── color-picker.scss │ │ ├── common/ │ │ │ ├── popup.scss │ │ │ ├── transition.scss │ │ │ └── var.scss │ │ ├── container.scss │ │ ├── date-picker/ │ │ │ ├── date-picker.scss │ │ │ ├── date-range-picker.scss │ │ │ ├── date-table.scss │ │ │ ├── month-table.scss │ │ │ ├── picker-panel.scss │ │ │ ├── picker.scss │ │ │ ├── time-picker.scss │ │ │ ├── time-range-picker.scss │ │ │ ├── time-spinner.scss │ │ │ └── year-table.scss │ │ ├── date-picker.scss │ │ ├── descriptions-item.scss │ │ ├── descriptions.scss │ │ ├── dialog.scss │ │ ├── display.scss │ │ ├── divider.scss │ │ ├── drawer.scss │ │ ├── dropdown-item.scss │ │ ├── dropdown-menu.scss │ │ ├── dropdown.scss │ │ ├── empty.scss │ │ ├── footer.scss │ │ ├── form-item.scss │ │ ├── form.scss │ │ ├── header.scss │ │ ├── icon.scss │ │ ├── image.scss │ │ ├── index.scss │ │ ├── infinite-scroll.scss │ │ ├── infiniteScroll.scss │ │ ├── input-number.scss │ │ ├── input.scss │ │ ├── link.scss │ │ ├── loading.scss │ │ ├── main.scss │ │ ├── menu-item-group.scss │ │ ├── menu-item.scss │ │ ├── menu.scss │ │ ├── message-box.scss │ │ ├── message.scss │ │ ├── mixins/ │ │ │ ├── _button.scss │ │ │ ├── config.scss │ │ │ ├── function.scss │ │ │ ├── mixins.scss │ │ │ └── utils.scss │ │ ├── notification.scss │ │ ├── option-group.scss │ │ ├── option.scss │ │ ├── page-header.scss │ │ ├── pagination.scss │ │ ├── popconfirm.scss │ │ ├── popover.scss │ │ ├── popper.scss │ │ ├── progress.scss │ │ ├── radio-button.scss │ │ ├── radio-group.scss │ │ ├── radio.scss │ │ ├── rate.scss │ │ ├── reset.scss │ │ ├── result.scss │ │ ├── row.scss │ │ ├── scrollbar.scss │ │ ├── select-dropdown.scss │ │ ├── select.scss │ │ ├── skeleton-item.scss │ │ ├── skeleton.scss │ │ ├── slider.scss │ │ ├── spinner.scss │ │ ├── statistic.scss │ │ ├── step.scss │ │ ├── steps.scss │ │ ├── submenu.scss │ │ ├── switch.scss │ │ ├── tab-pane.scss │ │ ├── table-column.scss │ │ ├── table.scss │ │ ├── tabs.scss │ │ ├── tag.scss │ │ ├── time-picker.scss │ │ ├── time-select.scss │ │ ├── timeline-item.scss │ │ ├── timeline.scss │ │ ├── tooltip.scss │ │ ├── transfer.scss │ │ ├── tree.scss │ │ └── upload.scss │ ├── time-picker/ │ │ └── index.js │ ├── time-select/ │ │ └── index.js │ ├── timeline/ │ │ ├── index.js │ │ └── src/ │ │ ├── item.vue │ │ └── main.vue │ ├── timeline-item/ │ │ └── index.js │ ├── tooltip/ │ │ ├── index.js │ │ └── src/ │ │ └── main.js │ ├── transfer/ │ │ ├── index.js │ │ └── src/ │ │ ├── main.vue │ │ └── transfer-panel.vue │ ├── tree/ │ │ ├── index.js │ │ └── src/ │ │ ├── model/ │ │ │ ├── node.js │ │ │ ├── tree-store.js │ │ │ └── util.js │ │ ├── tree-node.vue │ │ └── tree.vue │ └── upload/ │ ├── index.js │ └── src/ │ ├── ajax.js │ ├── index.vue │ ├── upload-dragger.vue │ ├── upload-list.vue │ └── upload.vue ├── src/ │ ├── directives/ │ │ ├── mousewheel.js │ │ └── repeat-click.js │ ├── index.js │ ├── locale/ │ │ ├── format.js │ │ ├── index.js │ │ └── lang/ │ │ ├── af-ZA.js │ │ ├── ar.js │ │ ├── az.js │ │ ├── bg.js │ │ ├── bn.js │ │ ├── ca.js │ │ ├── cs-CZ.js │ │ ├── da.js │ │ ├── de.js │ │ ├── ee.js │ │ ├── el.js │ │ ├── en.js │ │ ├── eo.js │ │ ├── es.js │ │ ├── eu.js │ │ ├── fa.js │ │ ├── fi.js │ │ ├── fr.js │ │ ├── he.js │ │ ├── hr.js │ │ ├── hu.js │ │ ├── hy-AM.js │ │ ├── id.js │ │ ├── is.js │ │ ├── it.js │ │ ├── ja.js │ │ ├── kg.js │ │ ├── km.js │ │ ├── ko.js │ │ ├── ku.js │ │ ├── kz.js │ │ ├── lo-LA.js │ │ ├── lt.js │ │ ├── lv.js │ │ ├── mn.js │ │ ├── ms.js │ │ ├── nb-NO.js │ │ ├── nl.js │ │ ├── pl.js │ │ ├── pt-br.js │ │ ├── pt.js │ │ ├── ro.js │ │ ├── ru-RU.js │ │ ├── si.js │ │ ├── sk.js │ │ ├── sl.js │ │ ├── sr-Latn.js │ │ ├── sr.js │ │ ├── sv-SE.js │ │ ├── sw.js │ │ ├── ta.js │ │ ├── th.js │ │ ├── tk.js │ │ ├── tr-TR.js │ │ ├── ua.js │ │ ├── ug-CN.js │ │ ├── uz-UZ.js │ │ ├── vi.js │ │ ├── zh-CN.js │ │ └── zh-TW.js │ ├── mixins/ │ │ ├── emitter.js │ │ ├── focus.js │ │ ├── locale.js │ │ └── migrating.js │ ├── transitions/ │ │ └── collapse-transition.js │ └── utils/ │ ├── after-leave.js │ ├── aria-dialog.js │ ├── aria-utils.js │ ├── clickoutside.js │ ├── date-util.js │ ├── date.js │ ├── dom.js │ ├── lodash.js │ ├── menu/ │ │ ├── aria-menubar.js │ │ ├── aria-menuitem.js │ │ └── aria-submenu.js │ ├── merge.js │ ├── popper.js │ ├── popup/ │ │ ├── index.js │ │ └── popup-manager.js │ ├── resize-event.js │ ├── scroll-into-view.js │ ├── scrollbar-width.js │ ├── shared.js │ ├── types.js │ ├── util.js │ ├── vdom.js │ └── vue-popper.js ├── test/ │ ├── .eslintrc │ ├── ssr/ │ │ └── require.test.js │ └── unit/ │ ├── index.js │ ├── karma.conf.js │ ├── mocks/ │ │ └── uri.js │ ├── specs/ │ │ ├── alert.spec.js │ │ ├── autocomplete.spec.js │ │ ├── avatar.spec.js │ │ ├── backtop.spec.js │ │ ├── badge.spec.js │ │ ├── breadcrumb.spec.js │ │ ├── button.spec.js │ │ ├── calendar.spec.js │ │ ├── card.spec.js │ │ ├── carousel.spec.js │ │ ├── cascader-panel.spec.js │ │ ├── cascader.spec.js │ │ ├── checkbox.spec.js │ │ ├── col.spec.js │ │ ├── collapse.spec.js │ │ ├── color-picker.spec.js │ │ ├── container.spec.js │ │ ├── date-picker.spec.js │ │ ├── descriptions.spec.js │ │ ├── dialog.spec.js │ │ ├── divider.spec.js │ │ ├── drawer.spec.js │ │ ├── dropdown.spec.js │ │ ├── empty.spec.js │ │ ├── form.spec.js │ │ ├── image.spec.js │ │ ├── infiniteScroll.spec.js │ │ ├── input-number.spec.js │ │ ├── input.spec.js │ │ ├── link.spec.js │ │ ├── loading.spec.js │ │ ├── menu.spec.js │ │ ├── message-box.spec.js │ │ ├── message.spec.js │ │ ├── mixin.vue-popup.spec.js │ │ ├── notification.spec.js │ │ ├── page-header.spec.js │ │ ├── pagination.spec.js │ │ ├── popconfirm.spec.js │ │ ├── popover.spec.js │ │ ├── progress.spec.js │ │ ├── radio.spec.js │ │ ├── rate.spec.js │ │ ├── result.spec.js │ │ ├── row.spec.js │ │ ├── select.spec.js │ │ ├── skeleton.spec.js │ │ ├── slider.spec.js │ │ ├── statistic.spec.js │ │ ├── steps.spec.js │ │ ├── switch.spec.js │ │ ├── table.spec.js │ │ ├── tabs.spec.js │ │ ├── tag.spec.js │ │ ├── time-picker.spec.js │ │ ├── time-select.spec.js │ │ ├── timeline.spec.js │ │ ├── tooltip.spec.js │ │ ├── transfer.spec.js │ │ ├── tree.spec.js │ │ ├── upload.spec.js │ │ ├── util.clickoutside.spec.js │ │ └── util.vue-popper.spec.js │ └── util.js ├── types/ │ ├── alert.d.ts │ ├── aside.d.ts │ ├── autocomplete.d.ts │ ├── avatar.d.ts │ ├── backtop.d.ts │ ├── badge.d.ts │ ├── breadcrumb-item.d.ts │ ├── breadcrumb.d.ts │ ├── button-group.d.ts │ ├── button.d.ts │ ├── calendar.d.ts │ ├── card.d.ts │ ├── carousel-item.d.ts │ ├── carousel.d.ts │ ├── cascader-panel.d.ts │ ├── cascader.d.ts │ ├── checkbox-button.d.ts │ ├── checkbox-group.d.ts │ ├── checkbox.d.ts │ ├── col.d.ts │ ├── collapse-item.d.ts │ ├── collapse.d.ts │ ├── color-picker.d.ts │ ├── component.d.ts │ ├── container.d.ts │ ├── date-picker.d.ts │ ├── descriptions-item.d.ts │ ├── descriptions.d.ts │ ├── dialog.d.ts │ ├── divider.d.ts │ ├── drawer.d.ts │ ├── dropdown-item.d.ts │ ├── dropdown-menu.d.ts │ ├── dropdown.d.ts │ ├── element-ui.d.ts │ ├── empty.d.ts │ ├── footer.d.ts │ ├── form-item.d.ts │ ├── form.d.ts │ ├── header.d.ts │ ├── icon.d.ts │ ├── image.d.ts │ ├── index.d.ts │ ├── infinite-scroll.d.ts │ ├── input-number.d.ts │ ├── input.d.ts │ ├── link.d.ts │ ├── loading.d.ts │ ├── main.d.ts │ ├── menu-item-group.d.ts │ ├── menu-item.d.ts │ ├── menu.d.ts │ ├── message-box.d.ts │ ├── message.d.ts │ ├── notification.d.ts │ ├── option-group.d.ts │ ├── option.d.ts │ ├── page-header.d.ts │ ├── pagination.d.ts │ ├── popconfirm.d.ts │ ├── popover.d.ts │ ├── progress.d.ts │ ├── radio-button.d.ts │ ├── radio-group.d.ts │ ├── radio.d.ts │ ├── rate.d.ts │ ├── result.d.ts │ ├── row.d.ts │ ├── select.d.ts │ ├── skeleton-item.d.ts │ ├── skeleton.d.ts │ ├── slider.d.ts │ ├── spinner.d.ts │ ├── statistic.d.ts │ ├── step.d.ts │ ├── steps.d.ts │ ├── submenu.d.ts │ ├── switch.d.ts │ ├── tab-pane.d.ts │ ├── table-column.d.ts │ ├── table.d.ts │ ├── tabs.d.ts │ ├── tag.d.ts │ ├── time-picker.d.ts │ ├── time-select.d.ts │ ├── timeline-item.d.ts │ ├── timeline.d.ts │ ├── tooltip.d.ts │ ├── transfer.d.ts │ ├── tree.d.ts │ └── upload.d.ts └── web-types.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": [ [ "env", { "loose": true, "modules": false, "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } } ], "stage-2" ], "plugins": ["transform-vue-jsx"], "env": { "utils": { "presets": [ [ "env", { "loose": true, "modules": "commonjs", "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } } ], ], "plugins": [ ["module-resolver", { "root": ["element-ui"], "alias": { "element-ui/src": "element-ui/lib" } }] ] }, "test": { "plugins": ["istanbul"] } } } ================================================ FILE: .eslintignore ================================================ src/utils/popper.js src/utils/date.js src/utils/lodash.js examples/play *.sh node_modules lib coverage *.md *.scss *.woff *.ttf ================================================ FILE: .eslintrc ================================================ { "globals": { "ga": true, "chrome": true }, "plugins": ["html", "json"], "extends": "elemefe", "rules": { "no-restricted-globals": ["error", "event", "fdescribe"] }, "parserOptions": { "ecmaVersion": 6, "ecmaFeatures": { "jsx": true } } } ================================================ FILE: .gitattributes ================================================ test/**/*.js linguist-language=Vue ================================================ FILE: .github/CONTRIBUTING.en-US.md ================================================ # Element UI Contributing Guide Hi! Thank you for choosing Element UI. Element UI is a Vue 2.0 based component library for developers, designers and product managers. We are excited that you are interested in contributing to Element. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines. ## Issue Guidelines - Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly. If any questions come up when you are using Element, please hit [Gitter](https://gitter.im/element-en/Lobby) for help. - Before submitting an issue, please check if similar problems have already been issued. - Please specify which version of `Element` and `Vue` you are using, and provide OS and browser information. [JSFiddle](https://jsfiddle.net/) is recommended to build a live demo so that your issue can be reproduced clearly. ## Pull Request Guidelines - Fork this repository to your own account. Do not create branches here. - Commit info should be formatted as `[Component Name]: Info about commit.` (e.g. `Button: Fix xxx bug`) - **DO NOT** include files inside `lib` directory. - Make sure that running `npm run dist` outputs the correct files. - For the sake of compatibility and file size, our babel configuration only imported `preset-2015`, so APIs like `Array.prototype.find` and `Object.assign` in `ES2015` are not recommended. You can import third party polyfills if necessary. - Rebase before creating a PR to keep commit history clear. - Make sure PRs are created to `dev` branch instead of `master` branch. - If your PR fixes a bug, please provide a description about the related bug. - Merging a PR takes two maintainers: one approves the changes after reviewing, and then the other reviews and merges. ## Prerequisites `Node.js 4+`, `yarn` and `npm 3+` are required. Note: we use yarn to lock dependency versions, so you should install dependencies using `yarn` instead of `npm install`. ```shell git clone git@github.com:ElemeFE/element.git npm run dev # open http://localhost:8085 ``` > **Notice**: modify `examples/play/index.vue` file, use the component you contribute, then run `npm run dev:play`, go ahead [http://localhost:8085](http://localhost:8085), get result, more quickly and friendly. To build: ```shell npm run dist ``` ## Component Developing Guidelines - Run `make new ` to create project directory for a new component. Test codes, entry file and documentation are included. - Refer to `Button` for nested components. - Refer to `Select` for components that depend on other components. ## Code Style Just comply with the [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) configuration of [ElemeFE](https://github.com/elemefe). ================================================ FILE: .github/CONTRIBUTING.es.md ================================================ # Guía para Contribuidores a `Element UI` ¡Hola! Gracias por elegir [Element UI](http://element.eleme.io/#/en-US). `Element UI` es un archivo de componentes para desarrolladores y para gerentes de productos ‘web’ basado en [Vue 2.0](https://vuejs.org/) Estamos orgullosos de que usted esta interesado en contribuir al proyecto `Element`. Antes de someter sus contribuciones, por favor tome un momentito para leer estas simples guías para contribuidores. ## Guía Para Reportar Problemas (“Issues”) - [“Issues”]( https://elementui.github.io/issue-generator) son exclusivamente para informar de errores, sugerencias o solicitaciones para funcionalidad adicional referente a diseño. Preguntas de otro tipo corren el riesgo de ser cerradas inmediatamente. Sí tiene preguntas sobre el uso de `Element`, vea [Gitter](https://gitter.im/element-en/Lobby) para más ayuda. - Antes de someter un informe sobre algún problema, sírvase de revisar sí ya hubo un informe. - Por favor especifique que versión de `Element` y `Vue` que esta utilizando, y que versión de sistema operativo y que versión de navegador web que está utilizando. [JSFiddle](https://jsfiddle.net/) esta recomendado para crear un entorno para reproducir el problema claramente. ## Guías para un “Pull Request (PR)” - Crea una bifurcación (“fork”) del repositorio a su propia cuenta en github.com. Por favor no crea ramas nuevas aquí. - Cuando cometa su cambio, formatea en esta forma: `[Nombre de componente]: Datos sobre el “commit”.` (por ejemplo. `Button: Reparación de xxx error`) - **DE NINGUNA MANERA** incluya archivos dentro del directorio `lib`. - Asegúrese de que el comando `npm run dist` produzca los archivos correctos. - Para asegurar compatibilidad y reducir tamaño de los archivos, nuestra configuración de `babel` solo importa `preset-2015`, así que IPAs como Array.prototype.find` y `Object.assign` en `ES2015` no son recomendados. Puede importar “polyfills” terceros, sí es necesario. - “Rebase” antes de crear un “pull request (PR)” para mantener la historia de “commits” limpia. - Asegúrese que sus PRs se refrieran a la rama `dev` y no a la rama `master`. - Si su PR arregla un error técnico, por favor, haga referencia al error especifico. - Fusión de un PR requiere dos mantenedores: el primero aprueba los cambios después de revisar, y entonces el segundo mantenedor revisa los cambios y hace la fusión. ## Requerimientos Técnicos `Node.js 4+`, `yarn` y `npm 3+` son requisitos. Nota: Usamos yarn para bloquear versiones de dependencias, por lo que debería instalar dependencias usando `yarn` en lugar de `npm install`. . ```shell git clone git@github.com:ElemeFE/element.git npm run dev # abra http://localhost:8085 ``` > **Notice**: modify `examples/play/index.vue` file, use the component you contribute, then run `npm run dev:play`, go ahead [http://localhost:8085](http://localhost:8085), get result, more quickly and friendly. Para armar: ``` shell npm run dist ``` ## Guía Para Desarrollo de Componentes - Corra el comando `make new ` para crear el directorio de su proyecto para un componente nuevo. Verifique su código fuente test, archivo de entrada y documentación están incluidos. - Refiérase al `Button` para componentes anidados. - Refiérase al `Select` para componentes que dependen de otros componentes. ## Estilo de Desarrollo Por favor acate a este estilo [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) configuración de [ElemeFE](https://github.com/elemefe). ================================================ FILE: .github/CONTRIBUTING.fr-FR.md ================================================ # Guide à destination des contributeurs d'Element UI Bonjour! Merci d'avoir choisi Element UI. Element UI est une bibliothèque de composants basée sur Vue 2.0 pour les développeurs, les designers et les chefs de produits. Nous sommes ravis que vous souhaitiez contribuer à Element. Avant de soumettre votre contribution, veuillez vous assurer de prendre un moment pour lire les indications suivantes. ## Concernant les issues - Les issues concernent exclusivement les bugs, les demandes de fonctionnalités et les sujets liés à la conception. Les questions concernant d'autres sujets peuvent être fermées directement. Si vous avez des questions à propos de l'utilisation d'Element, veuillez vous rendre sur [Gitter](https://gitter.im/element-en/Lobby) pour obtenir de l'aide. - Avant de soumettre une issue, veuillez vérifier si des problèmes similaires n'ont pas déjà été signalés. - Veuillez spécifier la version de `Element` et `Vue` que vous utilisez, et fournir des informations sur le système d'exploitation et le navigateur. [JSFiddle](https://jsfiddle.net/) est recommandé afin de construire une démo pour que votre problème puisse être reproduit clairement. ## Concernant les pull requests - Faites un fork de ce dépôt vers votre compte. Ne créez pas de branches ici. - Les informations de validation doivent être formatées en tant que `[Nom du composant] : Info à propos de ce commit` (par exemple `Button : Fix xxx bug`) - **NE PAS** inclure de fichiers dans le répertoire `lib`. - Assurez-vous que l'exécution de `npm run dist` génère les bons fichiers. - Pour des raisons de compatibilité et de taille de fichier, notre configuration babel n'importait que `preset-2015`, donc les API comme `Array.prototype.find` et `Object.assign` dans `ES2015` ne sont pas recommandées. Vous pouvez importer des polyfills si nécessaire. - Faites un rebase avant la création d'une PR pour garder l'historique clair. - Assurez-vous que les PRs sont créés dans la branche `dev` au lieu de la branche `master`. - Si votre PR corrige un bug, veuillez fournir une description du bug en question. - La fusion d'un PR nécessite deux responsables: l'un approuve les modifications après révision, puis l'autre les révise et les fusionne. ## Pré-requis `Node.js 4+`, `yarn` et `npm 3+` sont requis. Note: nous utilisons yarn pour verrouiller les versions des dépendances, donc vous devriez installer les dépendances en utilisant `yarn` au lieu de `npm install`. ```shell git clone git@github.com:ElemeFE/element.git npm run dev # open http://localhost:8085 ``` > **Remarque** : modifiez le fichier `examples/play/index.vue`, utilisez le composant auquel vous contribuez, puis lancez `npm run dev:play`, allez sur [http://localhost:8085](http://localhost:8085), regardez le résultat rapidement et facilement. Pour le build: ```shell npm run dist ``` ## Concernant le développement de composants - Exécutez `make new ` pour créer un répertoire pour le nouveau composant. Les tests, le fichier d'entrée et la documentation sont inclus. - Reportez-vous au `Button` pour les composants imbriqués. - Reportez-vous à `Select` pour connaître les composants qui dépendent d'autres composants. ## Style du code Il suffit de se conformer à la configuration [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) de [ElemeFE](https://github.com/elemefe). ================================================ FILE: .github/CONTRIBUTING.zh-CN.md ================================================ # Element UI 贡献指南 Hi! 首先感谢你使用 Element UI。 Element UI 是一套为开发者、设计师和产品经理准备的开源组件库,旨在快速搭建页面。它基于 Vue 2.0 开发,并提供了配套的设计资源,充分满足可定制化的需求。 Element UI 的成长离不开大家的支持,如果你愿意为 Element UI 贡献代码或提供建议,请阅读以下内容。 ## Issue 规范 - issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。如果你在使用时产生了疑问,请到 Slack 或 [Gitter](https://gitter.im/ElemeFE/element) 里咨询。 - 在提交 issue 之前,请搜索相关内容是否已被提出。 - 请说明 Element UI 和 Vue 的版本号,并提供操作系统和浏览器信息。推荐使用 [JSFiddle](https://jsfiddle.net/) 生成在线 demo,这能够更直观地重现问题。 ## Pull Request 规范 - 请先 fork 一份到自己的项目下,不要直接在仓库下建分支。 - commit 信息要以`[组件名]: 描述信息` 的形式填写,例如 `Button: fix xxx bug`。 - **不要提交** `lib` 里面打包的文件。 - 执行 `npm run dist` 后可以正确打包文件。 - 为了兼容性以及最终打包的文件体积考虑,我们的 babel 只引入了 `preset-2015`,所以不建议使用 ES2015 的 API,例如 `Array.prototype.find`、`Object.assign`等。如果有需要,请引入第三方的 polyfill。 - 提交 PR 前请 rebase,确保 commit 记录的整洁。 - 确保 PR 是提交到 `dev` 分支,而不是 `master` 分支。 - 如果是修复 bug,请在 PR 中给出描述信息。 - 合并代码需要两名维护人员参与:一人进行 review 后 approve,另一人再次 review,通过后即可合并。 ## 开发环境搭建 首先你需要 Node.js 4+,yarn 和 npm 3+。注意:我们使用 yarn 进行依赖版本的锁定,所以请不要使用 `npm install` 安装依赖。 ```shell git clone git@github.com:ElemeFE/element.git npm run dev # open http://localhost:8085 ``` > **提示**:可以运行 `npm run dev:play`,修改 `examples/play/index.vue` 文件,调用你修改后的组件,仍然访问 [http://localhost:8085](http://localhost:8085),查看修改效果,更快更方便。 打包代码: ```shell npm run dist ``` ## 组件开发规范 - 通过 `make new` 创建组件目录结构,包含测试代码、入口文件、文档 - 如果包含父子组件,需要更改目录结构,参考 `Button` - 组件内如果依赖了其他组件,需要在当前组件内引入,参考 `Select` ## 代码规范 遵循饿了么前端的 [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) 即可 ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: true contact_links: - name: Create new issue url: https://elementui.github.io/issue-generator about: The issue which is not created via https://elementui.github.io/issue-generator will be closed immediately. ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ Please make sure these boxes are checked before submitting your PR, thank you! * [ ] 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) | [Español](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.es.md) | [Français](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.fr-FR.md)). * [ ] Make sure you are merging your commits to `dev` branch. * [ ] Add some descriptions and refer relative issues for you PR. ================================================ FILE: .github/stale.yml ================================================ # Number of days of inactivity before an issue becomes stale daysUntilStale: 365 # Number of days of inactivity before a stale issue is closed daysUntilClose: 7 # Issues with these labels will never be considered stale # exemptLabels: # - pinned # - security # Label to use when marking an issue as stale staleLabel: stale # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. # Comment to post when closing a stale issue. Set to `false` to disable closeComment: false ================================================ FILE: .github/workflows/preview-build.yml ================================================ name: Preview Build on: pull_request jobs: build: name: Build runs-on: ubuntu-latest env: PULL_REQUEST_NUMBER: ${{ github.event.number }} steps: - name: Checkout uses: actions/checkout@v2 - name: Setup node uses: actions/setup-node@v2 with: node-version: '10.15.0' registry-url: https://registry.npmjs.com/ - name: Build run: npm run bootstrap && npm run deploy:build # share website dist - name: Upload artifact uses: actions/upload-artifact@v2 with: name: docs path: examples/element-ui/ retention-days: 1 # write pr.txt for share - name: Save pr number if: ${{ always() }} run: echo ${PULL_REQUEST_NUMBER} > ./pr.txt # share pr number - name: Upload pr number if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: pr path: ./pr.txt retention-days: 1 ================================================ FILE: .github/workflows/preview-deploy.yml ================================================ name: Preview Deploy on: workflow_run: workflows: ['Preview Build'] types: - completed jobs: success: runs-on: ubuntu-latest if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' steps: - name: download pr artifact uses: dawidd6/action-download-artifact@v2 with: workflow: ${{ github.event.workflow_run.workflow_id }} name: pr - name: save PR id id: pr run: echo "::set-output name=id::$( body-include: '' number: ${{ steps.pr.outputs.id }} - name: The job failed if: ${{ failure() }} uses: actions-cool/maintain-one-comment@v1.2.1 with: token: ${{ secrets.GITHUB_TOKEN }} body: | 😭 Deploy PR Preview failed. body-include: '' number: ${{ steps.pr.outputs.id }} failed: runs-on: ubuntu-latest if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'failure' steps: - name: download pr artifact uses: dawidd6/action-download-artifact@v2 with: workflow: ${{ github.event.workflow_run.workflow_id }} name: pr - name: save PR id id: pr run: echo "::set-output name=id::$( body-include: '' number: ${{ steps.pr.outputs.id }} ================================================ FILE: .gitignore ================================================ node_modules .DS_Store npm-debug.log yarn-debug.log yarn-error.log lerna-debug.log npm-debug.log.* yarn-debug.log.* yarn-error.log.* lerna-debug.log.* lib .idea .vscode examples/element-ui examples/pages/en-US examples/pages/zh-CN examples/pages/es examples/pages/fr-FR fe.element/element-ui .npmrc coverage waiter.config.js build/bin/algolia-key.js .envrc .history/ ================================================ FILE: .travis.yml ================================================ sudo: false language: node_js node_js: 10 addons: chrome: stable before_install: - export TRAVIS_COMMIT_MSG="[deploy] $(git log --format='%h - %B' --no-merges -n 1)" - export TRAVIS_COMMIT_USER="$(git log --no-merges -n 1 --format=%an)" - export TRAVIS_COMMIT_EMAIL="$(git log --no-merges -n 1 --format=%ae)" after_success: - sh build/deploy-ci.sh - cat ./test/unit/coverage/lcov.info | ./node_modules/.bin/coveralls ================================================ FILE: CHANGELOG.en-US.md ================================================ ## Changelog ### 2.15.14 *2023-08-24* #### Bug fixes - Img - Delete referrerpolicy prop (#22651 by @xinguanhua) #### Optimization - Docs - Update readme and website example links (#22642 by @lyfeyaj) - Update popper links (#22539 by @brizer) - I18n - Update translation of Spanish (#22430 by @jcardus) - Add sr-Latn translation (#22567 by @N-M) - Update Uzbek translation (#22390 by @akahon) - Statistics - Fix doc; Optimized code (#22384 by @webvs2) - Table - Add highlight selection row (#22382 by @wangdaodao) ### 2.15.13 *2023-02-12* #### Bug fixes - Docs - Fix Statistic docs (#22383 by @JUST-Limbo) - Fix Input docs (#22093 by @lm312) - Fix en-US docs (#22268 #22269 #22270 by @Hazel-Lin) - Fix Pagination docs (#22288 by @xujintai123) - Fix: Links docs (#22370 by @itmier) - Statistics - fix slot display bug (#22375 by @webvs2) - Chore - missing web-type after publishing (#22271 by @loosheng) #### Optimization - InputNumber - Fix touch one click trigger twice on the window touch pad (#22185 by @mrsai) - Image - Add initialIndex prop (#22346 by @inkroom) - Statistics - Updated countdown feature to localize lodash Closes (#22260 by @webvs2) - Update code and doc (#22276 by @webvs2) - Other - fix web-types type props (#22281 by @whzxc) ### 2.15.12 *2022-11-16* #### Bug fixes - Statistic: - Fixed the thousandth bit bug (#22252 by @webvs2) - Other - Fix 2.15.11 element-theme-chalk publish fail bug ### 2.15.11 *2022-11-15* #### Bug fixes - Docs - Fix Radio docs (#22178 by @bchen1029) - Fix Progress docs #### Optimization - I18n - Update translation of Malaysian (#22185 by @z4q) - Update translation of Norwegian (#22145 by @Barsnes) - Progress - Add defineBackColor and textColor prop (#22089 by @lm312) - Statistics - Add new component Statistics (#22159 by @webvs2) - Other - Add Web Types to improve code assistance in WebStorm IDE and other JetBrains IDEs (#22135 by @piotrtomiak) ### 2.15.10 *2022-09-13* #### Bug fixes - DatePicker - Fix props placement error (#21908 by @lqzhgood) - Loading - Fix sticky DOM error (#22087 by @zzjjhh001) - Docs - Fix Popover docs (#22083 by @lm312) - Fix Skeleton docs (#22092 by @lm312) - Fix DatePicker docs (#21970 by @guojiongwei) - Tree: - fix lazy-load default check problem (#21934 by @kiss-yu) #### Optimization - I18n - Add translation of Sinhalese (#21936 by @sayuri-gi) - Update translation of Spanish (#21924 by @jcardus) - Add translation of Malaysian (#22028 by @iorange0411) - Update translation of Swahili (#21904 by @Cholowao) - Utils - update date-util.js (#22099 by @Due07) - DatePicker - add months And years type (#21918 by @akiko123456) ### 2.15.9 *2022-06-02* #### Bug fixes - Table - Fix Tabl-header shake bug (#21863 by @bofeng) - Fix when partial import show `el-checkbox not imported` error (#21828 by @bobohuochai) - FormItem - Fix change rules verification not reset bug (#21892 by @bofeng) - Cascader - Fix change options unexpect error (#21759 by @louiebb) - Docs - Fix Popover docs (#21843 by @lod61) - Fix Calendar docs (#21814 by @GoJam11) - Fix TimePicker docs (#21803 by @Alanscut) - Fix DatePicker docs (#21877 by @Nirvanaiu) - Other - Fix codepen display bug (#21863 by @bofeng) #### Optimization - I18n - Add translation of Swahili (#21895 by @quilltouch) - Chore - Use launch-editor-middleware in dev environment (#21633 by @polemices) - DatePicker & Cascader - Optimize the dropdown animation direction (#21806 by @XivLaw) - Tooltip - Optimize `getFirstElement` code (#21886 by @zhankang) - Input - Optimize scss code (#21558 by @cheese-git) ### 2.15.8 *2022-04-12* #### Bug fixes - Drawer - Fix appendToBody failure problem (#21264 by @cs1707) - Switch - Fix toggling value problem(#19473 by @EdwinBetanc0urt) - Docs - Fix input docs (#21723 by @justforuse) - Fix DatePicker docs (#21663 by @justforuse) - Fix Skeleton docs (#21601 by @yanwydxf) - Others - Fix vue version (#21736 by @ckvv) #### Optimization - I18n - add translation of Azerbaijani (#21012 by @ricardotondello) - update translation of Slovenian (#21729 by @patik123) - update translation of Slovak (#21711 by @sjaustirni ) - add translation of Icelandic (#21709 by @aronhr) - add translation of Bengali (#21485 by @llwwtt) #### Others - Due to compatibility considerations, the PR on node-sass (#21019 by @linxsbox) of 2.15.7 release has been withdrawn and will be published in an appropriate version after re-evaluation. ### 2.15.7 *2021-11-18* #### Bug fixes - Select - fix click icon triggering dropdown (#21314 by @dennyak47) - fix keydown event when composition (#21336 by @bchen1029) - Badge - fix type class when is-dot (#21308 by @adaex) - Form - validate method reject error info (#21374 by @cs1707) - Table - fix resizeObserver loop limit exceeded (#21255 by @tomieric) - fix toggleAllSelection bug when table is empty (#21456 by @cs1707) - optimize performance (#21330 by @cs1707) - Button - fix disabled priority (#21375 by @cs1707) - Descriptions - fix label slot bug (#21462 by @cs1707) - SASS - replace node-sass with dart-sass (#21019 by @linxsbox) - Docs - fix skeleton typos (#21408 by @zhhbstudio) ### 2.15.6 *2021-09-02* #### Bug fixes - Cascader - fix a bug that makes the browser jitter in zoom mode (#21207 by @cs1707) - optimize performance (#21231 by @cs1707) - Select - fix long text overflow in multiple mode (#21237 by @cs1707) - Dropdown - add disabled property (#21235 by @mshioda) - Radio - fix checked state when browser go back (#21250 by @cs1707) - Descriptions - fix type declaration (#21265 by @adaex) - avoid table style conflict (#21254 by @adaex) - Drawer - fix append to body (#21264 by @cs1707) - Local - fix italian mistake (#21012 by @ricardotondello) ### 2.15.5 *2021-08-04* #### Bug fixes - Select - fix resetInputHeight (#21201 by @cs1707) ### 2.15.4 *2021-08-03* #### New features - Descriptions - add description component (#21129 by @cs1707) - Result - add result component (#21171 by @cs1707) #### Bug fixes - Utils - fix isScroll (#21098 by @canvascat) - Translation - update it.js (#21133 by @bliberi) - RadioGroup - fix RadioGroup used in component causes exception #17908 (#20783 by @lceric) - Message - fix message[type] (#21088 by @cs1707) - Carousel - reset the timer when setActiveItem method is called (#20846 by @Nekojita1) - Cascader - fix emitPath (#21185 by @cs1707) - Select - fix select filterable bug (#17494 by @profore) - fix a bug that makes the browser jitter in zoom mode (#21197 by @cs1707) - Tree - fix insertChild (#21194 by @cs1707) ### 2.15.3 *2021-06-29* #### New features - Skeleton - add skeleton component (#21038 by @cs1707) - Empty - add empty component (#21080 by @cs1707) #### Bug fixes - Local - fix week translations for hr locale (#21040 by @cs1707) - Table - fix lazy load data (#21041 by @cs1707) - Docs - fix form hide-required-asterisk description (#21045 by @cs1707) - Drawer: - fix destroy (#20715 by @zj9495) - Row - fix align top (#20963 by @cs1707) - Select - fix the bug when the value is Boolean (#21052 by @cs1707) - Calendar - fix first-day-of-week (#21057 by @cs1707) - Utils - fix isScroll (#21065 by @cs1707) - fix(utils.dom by @fw6) - TypeScript - add CascaderPanel export type (#21070 by @qige2016) - add spinner.d.ts (#21090 by @qige2016) ### 2.15.2 *2021-05-28* #### Bug fixes - Image - fix z-index and keydown event add stopPropagation (#20859 by @cs1707) - Input - fix show password cursor (#20870 by @cs1707) - fix show password icon in edge (#20902 by @cs1707) - Carousel - fix interval and scale bug (#20931 by @cs1707) - Cascader - fix delete tag bug (#20939 by @cs1707) - Drawer - add overflow auto (#20948 by @cs1707) - Others - fix isFunction (#20912 by @cs1707) ### 2.15.1 *2021-02-23* #### Bug fixes - Drawer - bugfix (by @cs1707) - Image - fix incorrect image object fit ratio in IE (#19583 by @charlie0228) - Cascader - fix cascader panel active path (#20730 by @cs1707) - Calendar - fix calendar component i18n bug (#20758 by @iamkun) - ColorPicker - fix bugs (by @UxieVerity) #### Optimization - Doc - update Axure resource v2.1.0 (by @iamkun) ### 2.15.0 *2021-01-15* #### Bug fixes - Select - Fix placeholder i18n bug (#17644 by @nzh63) - Popconfirm - Popconfirm i18n bug by @iamkun) - Drawer - Fix focus bug (#20626 by @cs1707) - Image - Preview optimization (#20652 by @cs1707) #### Optimization - Doc - Fix typo in french translation of datetime-picker.md (#20543 by @lonk) - Add format attribute description to the progress component (#20641 by @cs1707) ### 2.14.1 *2020-11-11* #### Bug fixes - Popover - Compatible with Vue 2.6 new v-slot syntax (#20424 by @iamkun) #### Optimization - I18n - Update Arabic translation (#20202 by @elkattan) - Update Uighur translation (#20177 by @IlhamTahir) ### 2.14.0 *2020-10-29* #### Breaking changes - Popconfirm - Rename event name to `confirm`, `cancel` (#20240 by @hugiron) #### Bug fixes - Progress - Fix attribute error (#19985 by @Caaalabash) #### Optimization - I18n - Update Russian translation (#19451 by @yangirov) - Update Khmer translation (#20077 by @Sovai) - Update Ukrainian translation (#20344 by @MammutAlex) ### 2.13.2 *2020-05-18* #### Bug fixes - Autocomplete - Fix change event bug (#19200 by @sxzz) - Image - Update error status (#19194 by @lhx6538665) #### Optimization - I18n - Update ru-RU popconfirm translation (#19220 by @Opppex) - Update vi translation (#19244 by @quangln2810) - Update Catalan and Spanish translations (#19296 by @Ismaaa) - Update Indonesia translation (#19320) by @therour) - Update Brazilian Portuguese translation (#19374 by @diegomengarda) ### 2.13.1 *2020-04-13* #### New features - Autocomplete - Add change event (#17913 by @sxzz) #### Bug fixes - Autocomplete - Fix suggestion error when textarea (#18478 by @Roojay) - Carousel - Fix console typo bug (#18264 by @IceFox) - Image - Fix preview dose not show when preview list not contain src issue (#18975) (#19130 by @luckyCao) - Fix shortcut key not work at second time issue (#18983) (#19156 by @luckyCao) - Don't show image-viewer when preview is false (#18967 by @inooNgt) - Transfer - Fix incorrect line-height of el-transfer's first list item when it was used with el-form-item (#18917 by @Hanx) - InputNumber - Correctly compute inputNumberDisabled (#18439 by @ashuser-pendo) - Chore - Remove index intro (#19155 by @iamkun) - Doc - Popconfirm doc update (#18324 by @iamkun) - Fix step-strictly docs typo (#18705 by @dream2023) - Fix a type error in document of steps component (#17555 by @haoranyu) ### 2.13.0 *2019-11-26* #### New features - Popconfirm - Add popconfirm component (#17548 by @iamkun) #### Bug fixes - BackTop - Use cubic bezier scrolling (by @lon) - DatePicker - Fix bug of only select min date of date range problem (#17191 by @smk0621) - Select - Fix select test cases by (@msidolphin) - Tree - Add font-size for the style of tree empty-text (#17094 by @spengjie) - Table - Column header can be costumed (#17291 by @ziyoung) - Update table header cell style (#17284 by @ziyoung) - Fix table header height after filter (#17348 by @ziyoung) - Fixed row-style with display not work (#17002 by @a631807682) - Fix header table not display (#17341 by @ziyoung) - Calendar - Import el-button and el-button-group (#17376 by @masongzhi) - MessageBox - Fix icon position error (#17410 by @nullptru) - TimePicker - Set the selection range after scrolling up or down (#16868 by @mattheyan) - Message - Fix close instace offsetHeight(#17564) (#17852 by @gzwgq222) - Form - Callback of validateField should be optional (#17314 by @CarterLi) - Cascader - Fix TypeScript 3.7 compatibility (#17881 by @CarterLi) - Menu - Fix router NavigationDuplicated error when using vue-router@^3.1.0 (#17269 by @iamkun) - Dropdown - Update type file (#17550 by @iamkun) - Progress - Add strokeLinecap prop (#17552 by @iamkun) - InfiniteScroll - Skip trigger event on invisible element (#17553 by @iamkun) - Image - Perfect picture preview behavior (#16985 by @luckyCao) - Fix shield the page when preview big image (#16796 by @luckyCao) - Drawer - Bugfix drawer-append-to-body-not-working (#16953 by @JeremyWuuuuu) - Select - Fix tag show value or empty issue (17199 by @luckyCao) - Scrollbar - Fix FireFox scroll bar width (#18091 by @iamkun) #### Optimization - I18n - Update sv-SE.js (#17926 by @FOLLGAD) - Update avatar component fr doc (#17762 by @blombard) - Docs - Fix time-select typo (#17250 by @wacky6) - Fix Drawer attribute accepted value typo in es (#17122 by @haoranyu) - Update Spanish changelog 2.12.0 (#17364 by @Gonzalo2310) - Fix Changelog typo (#17874 by @renlixin) - Fix Loading demo (#17862 by @MBearo) - Add input event in input Events Table (#18061 by @zhouxinyong) - Delete Input repeat change event (#18085 by @zhouxinyong) ### 2.12.0 *2019-08-29* #### New features - Popover - Add close-delay prop (#16671 by @LachlanStuart) - Theme - Add Chrome Extension: Element Theme Extension (#16686 by @iamkun) - Icon - Add font-display to @font-face declaration (#16805 by @iamfaizalandyka) #### Bug fixes - Carousel - Fix onChange emit value (#16705 by @iamkun) - Notification - Fix modifying incoming option object (#16704 by @iamkun) - DatePicker - Add className for picker option (#16632 by @iamkun) - DateTimePicker - Fix time-spinner not scroll to right position (#16854 by @jesse-li) - Table - Prevent click handler after drag (#16850 by @ziyoung) - Fix chrome crash when set thead css display to none (#16956 by @luckyCao) - Fix wrong empty block height (#16861 by @ziyoung) - Not throw error when calling toggleExpansion (#16304 by @yyjjqq94) - Not trigger sort-change event when mounted (#17113 by @a631807682) - Fix setCurrentRow unable to clear highlight row (#16879 by @ziyoung) - Fix expand-row-keys not work when data is loaded asynchronously (#16899 by @ziyoung) - set toggleAllSelection as instance property (#17137 by @ziyoung) - Tree - Fix distance between label and checkbox (#16799 by @Hazlank) - Tabs - Fix incorrect TabItem's position (#16520 by @victorting) - Fix activated tab is out of visual range bug (#17033 by @nullptru) - Calendar - Fix weekdays i18n issue (#16772 by @ubitoffee) - fix locale error (#17208 by @iamkun) - Cascader - Fix CascaderPanel display error (#16716 by @zhangHongEn) - Fix disable status and close button issue (#16224 by @yyjjqq94) - Input - Fix Korean composition event (#15069 by @MoonHyuk) - Fix click event of clear button not trigger when using v-loading (#16576 by @a631807682) - Select - Not toggle dropdown when filtering (#17205 by @luckyCao) - Transfer - Fix style error (#17206 by @iamkun) - Dialog - update sass var (#16365 by @haoranyu) - RadioGroup - Not produce invalid HTML in table if "is" attribute is specify (#17070 by @nullptru) - Divider - Support custom classes (#17078 by @island205) #### Optimization - Checkbox - Improve screen reader experience (#16575 by @tylertrotter) - Docs - Update changelog (#16773 by @SimonaliaChen) - Update contributing guide (#14800 by @sinchang) - Fix typo in Drawer docs (#16848 by @winkay) - Update custom theme (#16983 by @iamkun) - Add Esperanto translation (#16955 by @maxkoryukov) - Update input-number document about change event (#16316 by @luckyCao) - Update spanish doc 2.11.1 (#16961 by @Gonzalo2310) - I18n - Remove translation of 'year' in catalan language as in the other languages (#14722 by @oscaralbareda) - Update spanish changelog 2.10.0 and 2.10.1 (#16548 by @Gonzalo2310) - Update ar.js (#16653 by @l3op) - Test - Correct spelling error (#16672 by @boomler) - Refactor unit test to use data-uri (#16847 by @a631807682) - Types - Fix httprequest type (#16633 by @luckyCao) ### 2.11.1 *2019-07-26* #### Bug fixes - Image - Fix Image component SSR compatibility (#16737 by @luckyCao) - Chore - Update dart-sass compatibility (#16744 by @LewisChennnnn) ### 2.11.0 *2019-07-25* #### New features - Drawer - Add drawer component (#16577 by @JeremyWuuuuu) #### Bug fixes - Checkbox - Enhance css selector (#16006 by @Hazlank) - Tree - Make el-tree generic (#15934 by @JeremyWuuuuu) - Set isCurrent prop to False (#15870 by @kkkisme) - Dropdown - Fix split-button caret default color (#15931 by @JuniorTour) - Cascader - Fix level 1 children is empty update problem (#16399 by @luckyCao) - Add sets default values when lazy is true (#16420 by @luckyCao) - Fix display errors when node value is duplicate (#15935 by @junyiz) - Expose getCheckedNodes and fix options change bug (#16709 by @SimonaliaChen) - Calendar - Display correct header when range is specified (#16354 by @ziyoung) - Submenu - Fix prop append-to-body (#16289 by @a631807682) - Table - Fix tree table when updating data (#16481 by @island205) - Select - Fix memory leak issue (#16463 by @island205) - InfiniteScroll - Update naming & doc (#16698 by @iamkun) - Avatar - Fix image not center vertically issue (#16489 by @luckyCao) - Dialog - Add destroyOnClose attribute (#16455 by @ziyoung) - Image - Add big Image preview feature (#16333 by @luckyCao) #### Optimization - Docs - Fix dropdown demo (#16193 by @webxmsj) - Fix typo in table documents (#15971 by @howiefh) - I18n - Update translation of Thai language (#16689 by @ponkrit) - Chore - Update theme base api (#16607 by @iamkun) - Add form theme token (#16699 by @iamkun) - Mark ali inner user's access (#16609 by @iamkun) - Fix doc anchor bug (#16692 by @iamkun) ### 2.10.1 *2019-07-02* #### Bug fixes - Table - Fix sort icon (#15439 by @bezany) - Fix layout breaks when append slot exists (#16332 by @ziyoung) - Fix showOverflowTooltip not reactive (#16295 by @a631807682) - Register scrollbar in filter-panel (#16246 by @ziyoung) - Chore - Fix 2.9 docs (#16233 by @ziyoung) - Fix index page theme intro english css style issue (#16254 by @iamkun) #### Optimization - Tag - Compatible with IE (#16334 by @ziyoung) - Chore - Update Dingtalk Group QR image (#16236 by @iamkun) - Doc - Update online theme roller doc (#16244 by @iamkun) ### 2.10.0 *2019-06-25* #### New features - I18n - Added Uzbek language (#15796 by @ogabek96) - Calendar - Add first-day-of-week attribute (#16047 by @ziyoung) - Avatar - Add avatar component (#16144 by @luckyCao) - Upload: - Add capability to customize thumbnail template (#13192 by @victorzhuk) #### Bug fixes - Tree - Not highlight tree node when currentKey is null (#15668 by @yyjjqq94) - Fix issue #15538 caused by two Tree sharing the same data (#15615 by @VanMess) - Upload - Update the parameter `fileList` type (#15716 by @underfin) - Table - Fix loading icon not display (#15868 by @ziyoung) - Fix background color of complex table when hovering (#15504 by @cnlon) - Fix current-row-key and select event bug (#15983 by @ziyoung) - Height accepts more units (#16013 by @ziyoung) - Fix reserve-selection not work (#16135 by @ziyoung) - Docs - Fix Divider attribute type in zh-cn (#15889 by @haoranyu) - Menu - Fixed submenu hidden bug after adding popper-append-to-body (#15391 by @PanJiaChen) - Select - Fix initialInputHeight (#15989 by @yyjjqq94) - Fix default-first-option behavior when typing Chinese (#15431 by @VanMess) - fix double import problem (#16215 by @lengband) - Message - Add type def for offset option (#16027 by @matjaz) - Timeline - Fix reverse broken (#16091 by @ziyoung) - Slider - Fix #15545 by adding explains about "input" event in Chinese (#15588 by @VanMess) - InfiniteScroll - Update package name (#16125 by @iamkun) - MessageBox - Fix  distinguishCancelAndClose action not same as docs bug (#15438 by @qingdengyue) - PopupManager - Fix z-index cannot be rewritten at first using (#15738 by @luckyCao) - Docs - Delete an incorrect closing html tag and empty block code (#16194 by @Alexeykhr) - Chore - Update test api host (#15807 by @iamkun) #### Optimization - Tree - Modify loop conditions to improve performance (#15699 by @KingJeason) - Theme - Refine GA track & Update footer link forward to online theme roller (#16007 by @island205) - Badge - Update badge prop check (#16198 by @iamkun) - Avatar - Update theme config var (#16202 by @luckyCao) - I18n - Update pt-br.js (#15776 by @gigioSouza) - Update Farsi translation (#15881 by @pamenary) - Docs - Add missing components in quickstart (#16063 by @pape2016) - Update french translation (#16208 by @blombard) - Add description $slots.default (#15444 by @Alexeykhr) - Update Spanish Doc 2.9.1 (#15840 by @Gonzalo2310) - Fix spelling mistakes in fr (#15837 by @blombard) - Update changelog 2.9.2 Spanish (#16185 by @Gonzalo2310) #### Breaking changes - Form - Remove success status (#16159 by @ziyoung) ### 2.9.2 *2019-06-21* #### Bug fixes - Chore - Fix TS definitions file (#15805 by @NateScarlet) ### 2.9.1 *2019-05-30* #### New features - Table - default-expand-all, expand-row-keys, toggle-row-expansion method and expand-change event are supported in Tree Table (#15709 by @ziyoung) #### Bug fixes - Table - Fix some bugs (#15709 by @ziyoung) - Theme - Update api host (#15784 by @iamkun) #### Optimization - Chore - Update InfiniteScroll type (#15794 by @iamkun) ### 2.9.0 *2019-05-30* #### New features - Backtop - Add Backtop component (#15541 by @iamkun) - PageHeader - Add PageHeader component (#15714 by @ziyoung) - InfiniteScroll - Add InfiniteScroll directive (#15567 by @iamkun) - Cascader - Add multiple mode and filter-method (#15611 by @SimonaliaChen) - Message - Display in stack mode (#15639 by @island205) - Tag - Add prop effect (#15725 by @SimonaliaChen) - Tabs - Left align title when type is card (#15695 by @luckyCao) - DatePicker - Support literal strings (#15525 by island205) - Image - Add support for transmit attrs and listeners (#15578 by @VanMess) - Theme - Add popup background (#15412 by @iamkun) - Chore - Update new 2.9.0 index page (#15682 by @iamkun) #### Bug fixes - Table - Fix sort-change behaviour when sort condition is null (#15012 by @joelxr) - Image - Fix ssr and object-fit compatibility (#15346 by @SimonaliaChen) - Input - Fix show-word-count style in el-form (#15359 by @lvjiaxuan) - Fix clear icon is not centered (#15354 by @YiiGuxing) - Calendar - Fix not correct day of week when the day is Sunday (#15399 by @qingdengyue) - Fix October disappear bug (#15394 by @qingdengyue) - Tabs - Fix basic tab nested in card tab padding error (#15461 by @SimonaliaChen) - Tag - Fix stop propagation problem (#15150 by @infjer) - Form - Fix input-group within form-item height error (#15457 by @SimonaliaChen) - Fix resetFields issue (15181 by @luckyCao) - Tooltip - Fix custom tabindex not work (#15619 by @SimonaliaChen ) - Link - Fix link icon style class (#15752 by @iamkun) - Select - Revert set value to null when cleared (#15447 by @iamkun) - Loading - Fix dom not change when loading state change quickly (#15123 by @FAKER-A) - Switch - Label with el-switch repeating event (#15178 by @FAKER-A) - Slider - Fix style problem when clicking slider bar(#15561 by @luckyCao) - Radio - Fix issue 14808 (#14809 by @OverTree) - Form - Fix resetFields issue (15181 by @luckyCao) - Chore - Upgrade dependencies and fix demo bug (#15324 by ziyoung) - Type - Fix loading type definition (#15635 by @iamkun) - Fix Icon type (#15634 by @iamkun) - Fix Link type definition (#15402 by @iamkun) #### Optimization - Cascader - Refactor (#15611 by @SimonaliaChen) - Chore - Update make new component logic (by @iamkun) - Docs - Rename variable in docs (#15185 by @liupl) - Fix image attribute type and default value (#15423 by @haoranyu) - Fix form doc bug (#15228 by @SHERlocked93) ### 2.8.2 *2019-04-25* #### Bug fixes - Icon - Update icon (#15272 by @iamkun) - Docs - Fix Form and Input doc style (#15273 by @ziyoung) ### 2.8.1 *2019-04-25* #### Bug fixes - Icon - Update icon of cascader and select (#15264 by @SimonaliaChen) - Update icon (#15258 #15268 by @iamkun) #### Optimization - Chore - Update build script (#15267 by @ziyoung) - Docs - Fix link underline color (#15265 by @iamkun) - Other - Fix migrating config not compatible with camel case props and events (#15260 by @SimonaliaChen) ### 2.8.0 *2019-04-25* #### New features - Divider - Add divider component (#15055 by @island205) - Rate - Add custom colors and icon-classes by passing a object (#15051 by @SimonaliaChen) - Link - Add link component (#15052 by @iamkun) - Calendar - Add calendar component (#14908 by @ziyoung) - Icon - Add icon (#15214 by @iamkun) - Alert - Add dark theme (#15041 by @island205) - Image - Add image component (#15117 by @SimonaliaChen) - Collapse - CollapseItem can be disabled (#15076 by @ziyoung) - Carousel - Add direction attribute and support vertical direction (#15122 by @ziyoung) - Pagination - Add hide-on-single-page attribute (#15096 by @ziyoung) - Slider - Add marks attribute (#15133 by @luckyCao) - Input - Add show-word-count attribute (#15075 by @luckyCao) - InputNumber - Add step-strictly attribute (#15050 by @luckyCao) - Tooltip, Dropdown, Popover - Support tabindex attribute (#15167 by @ziyoung) #### Bug fixes - Notification - Fix title word break (#15008 by @iamkun) - Form - Fix switching the rules in el-form not work (#14985 by @luckyCao) - Fix label style (#14969 by @ziyoung) - Required FormItem displays asterisk when label is auto (#15144 by @ziyoung) - Pagination - Fix slot not updated (#14711 by @lucyhao) - Table - Fix load bug in lazy mode (#15101 by @ziyoung) - Fix cell width when colspan is grater than 1 (#15196 by @ziyoung) - Improve performance (#14868 by @ziyoung) - Don't emit triggers sort-change during initialization (#14625 by @PeanutWatson) - Equal behaviour for height and max-height (#14660 by @arthurdenner) - Dialog - Fix dialog body correctly break long words (#15027 by @iamkun) - Alert - update type definition (#15186 by @ziyoung) - Tabs - Fix issue where Promise rejection was hitting application (#14816 by @ffxsam) - Rerender when slot changes (#15238 by @ziyoung) - Message - Fix type definition (#14968 by @agoni1212) - Select - Fix error when value is undefined or null (#15022 by @luckyCao) - Tree - Delete current node after it removed (#14604 by @sinchang) - Improve performance (#14881 by @ChenZhuoSteve) - Dropdown - Fix style (#14907 by @doing123) - Slider - Fix broken keyboard a11y bug (#14792 by @erezsob) - Menu - ActiveIndex value shall be null if defaultIndex does not exist(#14074 by @hoythan) - Directive - RepeatClick: use Date.now() instead of new Date() (#14776 by @pavelmash) - Upload - Fix Upload transparent picture display style (#15039 by @iamkun) - Theme - Add zero border (#15256 by @iamkun) #### Optimization - Chore - Update changelog zh-cn (#14965 by @iamkun) - Hide demo description when it's empty (#15014 by @ziyoung) - Display dev server info by default by @iamkun) - Fix 2.6.0 changelog error (#15026 by @iamkun) - Update build config (#14821 by @abc3660170) - Add hmr (#15221 by @SimonaliaChen) - Use sourcemap in dev environment (#15087 by @ibufu) Docs - Rename variable in docs (#14602 #15003 #15094 #15105 by @liupl) - Fix upload doc error (#15023 by @iamkun) - Update Form custom validator doc (#15040 by @iamkun) - Update Tabs docs to display vertical tabs (#15053 by @iamkun) - Use eleme.cn as domain (#15139 by @ziyoung) - Fix Image route name (#15194 by @iamkun) - Remove duplicated fr translation (#15207 by @iamkun) #### Breaking changes - Rate - Fix decimal display support in disabled mode (#15089 by @haoranyu) - Select - Use placeholder option label to set placeholder in filter mode (#14989 by @ibufu) ### 2.7.2 *2019-04-03* #### Bug fixes - Form - Fix auto `label-width` style (#14955 by @ziyoung) #### Optimization - Docs - Fix doc img link error (#14957 by @iamkun) - Chore - Fix deploy mkdir error (#14952 by @iamkun) ### 2.7.1 *2019-04-03* #### Bug fixes - Select - Set value to null when cleared (#14322 by @aaronfulkerson) - Input - Update DOM dependent values on type change (#14889 by @wacky6) - Table - Make `defaultExpandAll` works when expanded column exists (#14935 by @ziyoung) - Dialog - Background color can be configured (#14939 by @ziyoung) - Form - `label-width` supports auto width (#14944 by @ziyoung) #### Optimization - Docs - Update Spanish docs (#14913 by @Gonzalo2310) - Add French doc for new component (#14924 by @ziyoung) - Optimize Tabs docs (#14938 by @ziyoung) ### 2.7.0 *2019-03-28* #### New features - Table - Add support tree structure data (#14632 by @ziyoung) #### Bug fixes - Tabs - Use primary color as boxShadow color (#14558 by @Richard-Choooou) - Rerender when label changes (#14496 by @akki-jat) - Table - Footer follows body cell align (#14730 by @ziyoung) - NavMenu - Fix click el-submenu trigger childMenu pop again bug (#14443 by @PanJiaChen) - Dropdown - Make compatible with 2.6 new v-slot syntax (#14832 by @ziyoung) - ColorPicker - Fix handle error hex color string (#14793 by @iamkun) - Tree - Revert pr #13349 (#14847 by @ziyoung) - Tooltip - Display when initial value is true (#14826 by @ziyoung) - Docs - Update cascader docs (#14442 by @panhezeng) - Style - Fix media query in sm-only, md-only, lg-only (#14611 by @sinchang) #### Optimization - Chore - Add webpage description (#14802 by @iamkun) ### 2.6.3 *2019-03-21* #### Bug fixes - Fix Cascader demo style (#14789 by @ziyoung) - Remove unnecessary DOM operation (#14788 by @ziyoung) - Fix DatePicker default-value DST (#14562 by @wacky6) ### 2.6.2 *2019-03-21* #### New features - DatePicker - Add monthrange for type attribute (#14487 by @zxyRealm) - i18n - Add Croatian locale (#14360 by @danijelh) #### Bug fixes - Input - Fix regression (#14572 by @wacky6) - DatePicker - Fix first-day-of-week computation (#14523 by @sinchang) - Fix week picker's value-format (#13754 by @wacky6) - Steps - Fix issue #14502 (#14596 by @sinchang) - Fix style with simple theme (#14610 by @sinchang) - Docs - Update french doc for 2.6.1 and fix typos (#14555 by @smalesys) - Rename variable in Table docs (#14587 by @likwotsing) - Add french search index (#14565 by @iamkun) - Fix TimePicker page style (#14579 by @ziyoung) - Rename variable in Upload docs (#14593 by @liupl) - French translation update (#14643 by @smalesys) - Update Form async validator docs (#14694 by @iamkun) - Fix tooltip doc error (#14748 by @iamkun) - Fix typo (#14751 by @2bj) - Fix highlighting control elements for Webkit touch (#14703 by @VladG0r) #### Optimization - Chore - Update ci build script (#14600 by @ziyoung) - Update ga tracking (#14560 by @iamkun) - Add more ga event (#14633 by @iamkun) - Update discusion group (#14741 by @iamkun) - Update test deps and conf (#14735 by @wacky6) - Upgrade gulp (#14745 by @ziyoung) - Use codepen to display demo & fix doc error (#14747 by @ziyoung) ### 2.6.1 *2019-03-03* #### Bug fixes - **Don't specify node version** (by @iamkun in #14546) - Fix doc directory in `deloy-faas.sh` (by @ziyoung in #14553) - Fix date style issue in changelog for 2.6.0 (by @island205 in #14547) - Fix doc typo (by @wack6 in #14552) ### 2.6.0 *2019-03-01* #### New features - Timeline - Add timeline component (by @jikkai in #14248) - DropdownItem - Add icon prop to `el-dropdown-item` (by @gabrielboliveira in #14088) - Input - Add show-password props (by @phshy0607 in #13966) - Select - Add slot `empty` (by @elfman in #13785) - Autocomplete - Add highlight-first-item prop (by @YamenSharaf in #14269) - I18n - Created Armenian locale (by @hamletbarsamyan in #14214) - Docs - French translation (by @smalesys in #12153, #14418, #14434) #### Optimization - Alert - Update alert description default slot class (by @iamkun in #14488) - Input - Update input password (by @iamkun in #14480) - InputNumber - Remove unnecessary parseFloat (by @JuniorTour in #14172) - Menu - Add support for `el-menu-item` without index (by @georgyfarniev in #13298) - Table - Remove some html DOM operations (by @elfman in #13643) - Upload - Optimize code (by @elfman in #13973) - Popup - Optimize code (by @KAionro in #14413) - Docs - Add more detail about how to run play mode for contribution (by @island205 in #14355) - Warn input as a controlled component (by @wacky6 in #14463) - Update Table doc (by @luguokong in #14329) - Update input doc (by @iamkun in #14437) - Update custom-theme docs (by @wangguohao in #14297) - Make the icon style change when hover on it (by @tuxinghuan in #14295) - Build - Minimizing css and js for Element doc site (by @iamkun in #14430) - Speeding up webpack (by @hetech in #14484) - Use cli to select release version (by @hetech in #14354) - Install stale for issue handling (by @island205 in #14392) #### Bug fixes - Menu - Fix subMenu focus bug when switch browser tab (by @liupl in #13976) - MessageBox - Fix type definition (by @NateScarlet in #14278) - ScrollBar - Prevent right button click on thumb (by @xifeiwu in #14196) - Switch - Trigger form validation if value changes (by @hetech in #14426) - Table - Make toggleAllSelection method an instance method (by @letanure in #14075) - Tabs & Dropdown - Fix style (by @hetech in #14452) - Tree - Empty-text tips are different from tables (by @ColinCll in #14331) - Docs - Fix DatetimePicker format doc error (by @iamkun in #14290) - Spelling issue in datepicker documentation (by @helmut in #14481) - Fix pagination doc style (by @liuchuzhang in #14451) #### Breaking changes - Table - Fix params order of row events (by @jikkai in #12086) ### 2.5.4 *2019-02-01* #### Bug fixes - Build: Fix babel config issue which lead to collapse transition broken (by @island205 in #14282) ### 2.5.3 *2019-01-31* #### Optimization - Optimize code of Message (by @vok123 in #14029) - Retire gh-pages (by @ziyoung in #14266) - Add IssueHunt link (by @island205 in #14261) #### Bug fixes - Fix UMD module error on server side (by @island205 in #14242) - Fix active TabBar style (by @iamkun in #14240) - Fix Table demo code error (by @xunmeng in #14253) ### 2.5.2 *2019-01-27* #### Optimization - Docs: - Update ChangeLog ES 2.5.1 (by @Gonzalo2310 in #14231) #### Bug fixes - Build: - Delete unremoved comments in umd module `lib/index.js` (by @island205 in #14233) - Fix export error fired in commonjs module used in nuxt.js (by @island205 in #14232) - Fix 2.5.1 build issues (by @iamkun in #14228) ### 2.5.1 *2019-01-26* #### Optimization - DatePicker: highlight current month and year (by @Debiancc in #14211) - Update 2.5.0 changelog (by @wacky6 in #14217) #### Bug fixes - Fix export issue generate by webpack upgrading (by @island205 in #14220) - Keep 2.4.11 docs && new sub folder for 2.5+ (by @iamkun in #14222) ### 2.5.0 *2019-01-25* #### New features - DatePicker - Add `validate-event` attribute (by @ziyoung in #13531) - DateTimePicker - `pickerOptions` support `selectableRange` option (by @eeeeeeeason) - Tag - Add `click` event (by @licdream in #14106) - I18n - support Kyrgyz language (by @zzjframework in #14174) #### Optimization - Upgrade to webpack@4 (by @jikkai in #14173) - Input - Simplify implementation, follow one-way data flow. Fix several related bugs (by @wacky6 in #13471) - Update Axure file,add new components (by @ziyoung in #13773) #### Bug fixes - Autocomplete - Fix dropdown's last line beging clipped (by @ziyoung in #13597) - Fix missing popper arrow (by @liuchuzhang in #13762) - Carousel - Cleanup timer when component is destroyed (by @elfman in #13820) - Cascader - Remove deprecated property of computed props (by @iamkun in #13737) - Fix CascaderOption's type definition in TypeScript (by @NateScarlet in #13613) - Fix icon covering the text (by @ziyoung in #13596) - Checkbox - Refine style (by @PanJiaChen) - DatePicker - Add missing v-for `key` in TimeSpinner (by @Ende93 in #13547) - Fix week highlight on year boundary (by @suyi91 in #13883) - Input - Fix textarea DOM node reference (by @laomu1988 @island205 in #13803) - Pagination - Input value won't be less than 1 (by @elfman in #13727) - Popover - Fix popover issues with hover trigger (by @goldengecko in #13104) - Fix popper instance memory leak (by @qpxtWhite in #13988) - Radio - Refine style (by @ohhoney1) - Table - Enhanced table sorting when clicking on the sorting arrow (by @ohhoney1 in #12890) - Fix empty text vertical alignment issue on IE10+ (by @imzjy in #13638) - Fix index type documentation (by @ilovefafa in #13628) - Fix `show-summary` display issue when multilevel header has fixed attr (by @luckyCao in #13914) - Tabs - Fix auto scroll bug (by @iamkun in #13696) - Get the correct tab through tab name (by @iamkun in #13705) - Use paneName instead of name to determine pane style (by @iamkun in #13733) - Tree - Fix `showCheckbox` prop on `Tree` can not affect their children `tree-node` (by @KidneyFlower) - Update doc and definition file (by @ziyoung in #13540) - Upload - Add `url` prop to upload file when `list-type` changed (by @elfman in #13771) - Slider - Fix source code indentation (by @wacky6 in #13955) - I18n - Add missing Catalan translations (by @jaumesala) - Add missing ru translation (by @justlp in #13658) - Fix Finnish translations (by @jenkrisu in #14137) - Doc - Update Spanish doc 2.4.11 (by @Gonzalo2310 in #13522) - Others - Remove unnecessary script (by @ziyoung) - Fix error anchor link (by @iamkun in #13753) - Fix inconsistent capitalization in documentation (by @wonderjar) - Add DingDing chat group qr code to readme (by @iamkun in #13957) - Add yarn logs to .gitignore (by @mimimi in #13922) - Remove sponsor duotai (by @island205 in #14156) - Update readme qr code src (by @iamkun in #13960) - Update CDN link, fix typo (by @ziyoung) ### 2.4.11 *2018-11-21* - Revert pr #13296. Fixed clicking on Menu external causing Submenu collapsed, #13478 - Adjust small screen (xs) media query breakpoints, #13468 (by @alekoshen712) ### 2.4.10 *2018-11-16* - Fixed multiple clicks on Select to display the drop-down list, #13268 - The clear icon for input is not displayed when Form is disabled, #13208 - Adjust the style of Select, Progress, Autocomplete, Tooltip, Collaspe, TimePicker, #13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen) - Carousel component added `loop` attribute, #13217 - When the data of Table changes, the highlighted line will remain, #13200 - Table header scoped slot can receive parameters, #13263 - Table's `clearFilter` method supports arguments, #13176 - Tooltip is no longer created when there is no content in the Table cell, #13152 (by @rongxingsun) - The input box contents of the ColorPicker panel can be displayed correctly, #13278 - ColorPicker no longer triggers form validation when dragging, #13299 - InputNumber added `select `method, #13286 (by @st-sloth) - Autocomplete added `clear` event, #12171(by arthurdenner) #13326 - You can close Menu by clicking on Menu outside, #13296 - Form's `validateField` method can receive arguments, #13319 - Cascader added `visible-change` event, #13415 - DatePicker added range-separator slot, #13272 (by @milworm) - Tree adds `iconClass` and `currentNodeKey` properties, #13337 #13197 (by @isnifer) - Progress's` status` added text #13198 (by @ali-master) - Fixing tree's `defaultCheckedKeys` caused an error, #13349 (by @dive2Pro) ### 2.4.9 *2018-10-26* - The parameter of Form's `clearValidate` supports string, #12990 (by @codinglobster) - Added type attribute for Badge, #12991 - Users can use scoped-slot to customize table column header #13012 (by @ivanseidel) - Fixed the input box of Select unable to type text under IE, #13034 (by @GaliMU) - Select option does not wrap when space is enough, #12329 (by @akki-jat) - When dropdown list of Select is expanded, the arrow icon will also display correctly, #12353 (by @firesh) - Fixed that the size attribute of Select does not work, #13070 - Select multiple values can be cleared, #13049 (by @ZSkycat) - Fixed the last TabNav unable be deleted, #13039 - Fixed that TabNav label is not displayed correctly, #13178 - Added title slot for Alert, #13082 (by @Kingwl) - Fixed an issue where the tooltip content in Table was incorrect, #13159 (by @elfman) - Optimize the animation of Upload when file is deleted, #12987 - Adjusted style of InputNumber when control button is not displayed, #13052 ### 2.4.8 - Not displaying outline when Switch is focused, #12771 - Fixed Dropdown's style in ButtonGroup, #12819 (by @bluejfox) - Added opened event for Dialog, #12828 - Fixed the incorrect display order of TabNav, #12846 - Fixed the problem that Tabs did not scroll to the selected tab, #12948 - Fixed the problem that the identifier does not display when the Tree node is dragged, #12854 - The validate event parameter of Form contains the validation message, #12860 (by @YamenSharaf) - Fixed DatePicker not to verify the validity of user input time, #12898 - Fixed the problem that `render-header` attribute of Table header doesn't work, #12914 ### 2.4.7 *2018-09-14* - Fixed DatePicker not triggering form validation, #12328 #12348 - Fixed DatePicker throwing errors in multiple mode, #12347 - Fixed incorrect position of DatePicker spinner, #12415 (by @rang-ali) - Fixed automatic filling of DatePicker input box, #12521 (by @abdallanayer) - Fixed Input not highlighted in Cascader, #12341 - Fixed wrong order of Tabpane, #12346 - Fixed incorrect position of ColorPicker cursor, #12376 (by @cnwhy) - Fixed the style of Submenu, #2457 - Fixed not highlighted after Submenu is selected, #12479 - Fixed incorrect values selected by Cascader, #12508 (by @huangjinqiang) - Fixed incorrect value of Pagination input box, #12525 - Fixed order that Pagination triggers events, #12530 - Fixed Table Filter not displayed, #12539 - Fixed Tree unable to delete nodes, #12684 - Fixed height of Select Input changing in single mode, #12719 - Fixed style of FormItem label in nested Form, #12748 - Added `autocomplete` attribute for Input, deprecated `auto-complete`, #12514 (by @axetroy) - Added slots-scope for Form to display validation information, #12715 (by @YamenSharaf) ### 2.4.6 *2018-08-09* - Fixed Table not showing filter icon when `filters` is assigned empty array, #12165 - Fixed Menu not saving active state when `collapse` is changed, #12178 (by @elfman) - Fixed Cascader not escaping special characters for Regexp, #12248 - Fixed disabled RadioButton showing box-shadow when clicked, #12262 - Fixed arrow key not effect when default value is `undefined`,#12322 - Fixed query function of Select not debounced in multi mode, #12181 - Fixed query keyword of Select disappearing in multi mode, #12304 - Fixed incorrect width of Dialog when it is displayed in full screen, #12203 - Fixed incorrect display of Main on IE, #12237 - Fixed Input triggering two form validations, #12260 - Fixed adding new Tree node causing nodes to disappear, #12256 - Fixed Tree node not deleted after dragging, #12279 - Fixed Popover not visible when InputNumber focuses, #12284 - Added `popper-append-to-body` attribute for Autocomplete, #12241 - Added `sync` modifier support for Pagination's `page-size` attribute, #12281 ### 2.4.5 *2018-07-26* - Fixed Table setting `class-name` does not work for `expand` column, #12006 - Added `toggleAllSelection` method for Table, #12047 - Fixed wrong position of suffix slot when Input contains Select, #12108 - Fixed `line-height` of Option unable to set, #12120 - Fixed TimeSelect with default value of `null` could not be assigned after executing `resetField`, #12010 - Fixed keydown event which is not arrow key does not work in Tree, #12008 - Fixed parent node checked in lazy mode, #12106 - Added `includeHalfChecked` parameter for getCheckedNodes of Tree, #12014 ### 2.4.4 *2018-07-13* - Fixed triggering Select validation after Form resetting, #11837 - Fixed wrong position of Input `suffix` slot when `suffix` slot with `append` slot, #11951 - Fixed clearable Input still displaying the clear icon when readonly, #11967 - Fixed Tree node checked when it's disabled, #11847 - Fixed Tree's `default-checked-keys` not working, #11971 - Fixed `empty-text` not visible when Tree node filtered, #11971 - Fixed the position of oversized `empty-text` in Table, #11965 - Fixed Table row not be unhighlighted when `current-row-key` is assigned to `null`, #11866 - Fixed showing filter dropdown when `filters` is an empty array, #11864 - Fixed Radio's label does not stop event propagation, #11912 ### 2.4.3 *2018-07-03* - Fixed `allow-drop` not working properly when Tree nodes have a custom height, #11797 - Now you can pass a parameter to the `clearValidate` method of Form, specifying which FormItems' validation results need to be cleared, #11821 - Added `distinguishCancelAndClose` attribute for MessageBox, #11831 ### 2.4.2 *2018-06-26* - Now `class-name` and `label-class-name` of Table are reactive, #11626 - Fixed Table still highlighting clicked row when `highlight-current-row` is `false`, #11646 - Fixed a style bug of ButtonGroup when it has only one `round` or `circle` Button, #11605 - Fixed style of page size Select of Pagination, #11622 - Fixed Menu's `open` method error when `collapse` is dynamically changed, #11646 - Added `activeName` and `oldActiveName` parameters to the before-leave hook of Tabs, #11713 - Fixed Cascader focused after outside clicked, #11588 - Fixed Cascader not closing when option is clicked when `change-on-select` is true, #11623 - Now updating Select's value programmatically will trigger form validation, #11672 ### 2.4.1 *2018-06-08* - Removed Autocomplete's duplicate type declaration, #11388 - Fixed Select's dropdown arrow style in FireFox when nested in Form, #11427 - Fixed clear icon of Select still showing when the initial value is `null`, #11460 - Fixed disabled radio showing box-shadow when clicked, #11462 - Added `iconClass` attribute for MessageBox, #11499 - Added `stretch` attribute for Tabs, #11476 - Fixed rendering order issue of TabPane when Tabs is `lazy`, #11461 - Fixed Table not retaining current highlight row when expanded, #11464 - Fixed focusing state when `before-leave` returns a resolved promise, #11386 - Fixed disabled Popover still creating poppers, #11426 - Fixed Tree's endless loop when a new node is added in lazy mode, #11430 (by @wangjingf) - Added `closed` event for Dialog, #11490 ### 2.4.0 Fullerene *2018-05-28* #### New features - General - Dev tool and bundler is switched to native webpack, #11216 - Now you can globally set the initial z-index of popups, #11257 - Autocomplete - Added `hide-loading` attribute, #11260 - Button - Now you can use the `size` attribute on circle buttons to control their sizes, #11275 - InputNumber - Added `precision` attribute, #11281 - Tabs - Added `before-leave` attribute, #11259 - Added `lazy` attribute, #11167(by @Kingwl) - Table - Added `sort` method to manually sort the table, #11311 #### Bug fixes - Input - Fixed an issue that causes a re-render when using the Chinese IME to quickly input text, #11235 (by @STLighter) - Popover - Fixed the console error when the triggering element is Radio or Checkbox, #11265 - Breadcrumb - Fixed the `to` attribute not supporting dynamic update, #11286 - Upload - Fixed the console error when a File is resolved in the returned Promise of the `beforeUpload` method, #11297 (by @qusiba) - Tooltip - Fixed arrow not positioned correctly when content is empty, #11335 - Autocomplete - Fixed incorrect input suggestions after deleting keyword quickly, #11323 - ColorPicker - Fixed `active-change` event incorrectly triggering when picker dropdown is closed, #11304 - Table - Fixed style error of oversized filter panel, #11314 - Fixed currently selected row not retained when the table is sorted, #11348 - Checkbox - Fixed single checkbox not supporting validation, #11271 - Radio - Fixed disabled Radio still being selected when pressing space key, #11303 - MessageBox - Fixed the `el-popup-parent--hidden` class not removed when opening MessageBox in succession, #11371 ### 2.3.9 *2018-05-18* - Fixed when the source data does not have the field specified by a TableColumn's `prop` attribute, an error would occur when the mouse moves into that column's cells, #11137 - The `lockScroll` attribute of pop up components no longer adds an inline style to the parent element, but instead adds a class name, #11114 - Fixed the icon of Progress not displaying when its `status` is exception, #11172 - Fixed options' `disabled` attribute not working in filterable Cascader's filter result list, #11185 - Fixed an issue where Table's expanded row cannot be collapsed if the data source is updated after its expansion, #11186 - `setCurrentKey` of Tree now accepts `null` as its param to cancel the currently highlighted node, #11205 ### 2.3.8 *2018-05-11* - Fixed DatePicker panel jumping to the current month after picking a date in a non-current month when `type` is dates, #10973 - Fixed clearable Input still displaying the clear icon when readonly, #10912 - Fixed closing the DatePicker panel without changing the value incorrectly triggering the `change` event, #11017 - Fixed keyboard navigation not working properly when Select has grouped options, #11058 - Added `prefix` named slot for Select, #11063 - Added `clearValidate` method for FormItem, #11076 - Added `checkOnClickNode` attribute for Tree, #11111 ### 2.3.7 *2018-04-29* - Fixed Table not updating its header widths when the scroll bar disappears due to filtering, #10834 - Fixed clearable Input still showing the clear icon when its initial value is `null`, #10912 - Fixed incorrect trigger of the `active-change` event after changing ColorPicker's binding value programatically, #10903 (by @zhangbobell) - Fixed filterable Select causing an infinite loop when navigating options using keyboard if all options are disabled, #10945 ### 2.3.6 *2018-04-21* - Fixed wrong behavior of Tree's `allow-drop` callback when `type` parameter is used, #10821 - Now you can properly enter keywords in filterable single Select in IE11, #10822 - Fixed single Select incorrectly triggering `blur` event after clicking an option, #10822 ### 2.3.5 *2018-04-20* - Fixed incorrect highlights in DatePicker panel when `type` is week, #10712 - Fixed InputNumber being empty when its initial value is 0, #10714 - Added `automatic-dropdown` attribute for Select, #10042 (by @Seebiscuit) - Fixed disabled Rate's value still being updated by navigation keys, #10726 (by @Richard-Choooou) - Now DatePicker's `type` attribute can be `'dates'`, where you can pick multiple dates in one picker, #10650 (by @Mini256) - Added `prev-click` and `next-click` events for Pagination, #10755 - Added `pager-count` attribute for Pagination, #10493 (by @chongjohn716) - Added `type` as the 3rd param of Tree's `allow-drop` attribute callback, #10792 - Now we use ResizeObserver to detect DOM element resizing, #10779 ### 2.3.4 *2018-04-12* - Deleted duplicate `showTimeout` attribute in SubMenu's TypeScript declaration, #10566 (by @kimond) - Now you can customize Transfer's data item using scoped slot, #10577 - Fixed clicking disabled prev and next button of Pagination still triggers `current-change` event, #10628 - Fixed Textarea displaying `undefined` in SSR when its value is not set, #10630 - Fixed disabled TabItem style when `type` is border-card, #10640 - Added `$index` as `formatter`'s fourth param of Table, #10645 - Fixed CheckboxButton not exported in TypeScript declaration, #10666 ### 2.3.3 *2018-04-04* - Added `shadow` attribute for Card, #10418 (by @YunYouJun) - Fixed Badge being hidden when `value` is `0`, #10470 - Fixed some bugs of draggable Tree, #10474 #10494 - Added `placement` for Autocomplete, #10475 - Now `default-time` attribute also works in non-range DateTimePicker, #10321 (by @RickMacTurk) - Removed the blue outline of TabItem after the browser blurs or is minimized, #10503 - Added `popper-append-to-body` attribute for SubMenu, #10515 - Removed visual feedback when hovering on non-link BreadcrumbItem, #10551 - Fixed InputNumber's `change` event to ensure the component's binding value is updated in the event handler, #10553 ### 2.3.2 *2018-03-29* - Fixed an Autocomplete regression, #10442 ### 2.3.1 *2018-03-29* - Fixed a regression that `type` of Input is not passed down to the native input element, #10415 - Added `blur` method for Select, #10416 ### 2.3.0 Diamond *2018-03-28* #### New features - Table - Now `formatter` of TableColumn can be dynamically updated, #10184 (by @elfman) - Added `select-on-indeterminate` attribute, #9924 (by @syn-zeta) - Menu - Added `collapse-transition` attribute, #8809 (by @limichange) - Input - Added `select` method, #10229 - Added `blur` method, #10356 - ColorPicker - Added `predefine` attribute, #10170 (by @elfman) - Tree - Added `draggable`, `allow-drop` and `allow-drag` attributes, and `node-drag-start`, `node-drag-enter`, `node-drag-leave`, `node-drag-over`, `node-drag-end` and `node-drop` events, #9251 #10372 (by @elfman) - Form - `validate` method now has a second parameter, containing information of form items that failed the validation, #10279 - Added `validate` event, #10351 - Progress - Added `color` attribute, #10352 (by @YunYouJun) - Button - Added `circle` attribute, #10359 (by @YunYouJun) #### Bug fixes - Form - Fixed label of FormItem not align with mixed Input, #10189 - Menu - Now collapsed Menu will only show the Tooltip when the `title` slot of MenuItem is set, #10193 (by @PanJiaChen) - Pagination - Fixed `current-change` event wrongly triggering without user interaction, #10247 - DatePicker - Now the date and time value in the dropdown panel are correctly formatted based on the `format` attribute, #10174(by @remizovvv) - Upload - Fixed `accept` attribute not working when `drag` is true, #10278 ### 2.2.2 *2018-03-14* - Added `clear` event for Input, #9988 (by @blackmiaool) - Now manual input of ColorPicker supports `hsl`, `hsv` and `rgb` modes, #9991 - Fixed DatePicker not triggering `change` event when its initial value is cleared, #9986 - Now icon class related attributes of Rate support dynamic updates, #10003 - Fixed Table with fixed columns not updating its height correctly if `max-height` is set, #10034 - Now DatePicker's range mode supports reverse selection (clicking the end date, then clicking the start date), #8156 (by @earlymeme) - Added `disabled` attribute for Pagination, #10006 - Added `after-enter` and ` after-leave` events for Popover, #10047 - Fixed Select not triggering validation when user selects an option after executing `resetFields` of Form, #10105 - Fixed incorrect widths of fixed columns of Table in some cases, #10130 - Fixed MessageBox inheriting the `title` attribute of its previous instance when called without `title`, #10126 (by @Pochodaydayup) - Added `input-size` attribute for Slider, #10154 - Added `left-check-change` and `right-check-change` events for Transfer, #10156 ### 2.2.1 *2018-03-02* - Fixed Aside, Header and Footer shrinking in some layout, #9812 - Fixed Table with a `height` attribute not rendering in SSR, #9876 - Fixed expandable Table not calculating its height when a row is expanded, #9848 - Fixed `change` event not trigger when manually typing date in DateTimePicker, #9913 - Fixed Select showing its options when the input box is right-clicked, #9894 (by @openks) - Added `tooltip-class` attribute for Slider, #9957 - Now Select will stay focused after selection, #9857 (by @Seebiscuit) - Added `target-order` attribute for Transfer, #9960 ### 2.2.0 Graphite *2018-02-12* #### New features - Menu - Added `popper-class` and `disabled` attributes for SubMenu, #9604 #9771 - Horizontal Menu now supports multi-layered SubMenu, #9741 - Tree - Added `node-contextmenu` event, #9678 - Now you can customize node template using scoped slot, #9686 - Added `getNode`, `remove`, `append`, `insertBefore`, `insertAfter`, `getCheckedKeys`, `getHalfCheckedNodes`, `getHalfCheckedKeys` methods and `check` event, #9718 #9730 - Transfer - Added `clearQuery` method, #9753 - Select - Added `popper-append-to-body` attribute, #9782 #### Bug fixes - Table - Fixed clicking expanding icon of an expandable row triggers `row-click` event, #9654 - Fixed layout not update when column width is changed by user dragging, #9668 - Fixed style issue when summary row co-exists with fixed columns, #9667 - Container - Fixed container components not stretching in IE11, #9655 - Loading - Fixed Loading not showing when the value of `v-loading` is changed to true in the `mounted` hook, #9722 - Switch - Fixed two native click events are triggered when Switch is clicked, #9760 ### 2.1.0 Charcoal *2018-01-31* #### New features - Cascader - Added `focus` and `blur` events, #9184 (by @viewweiwu) - Table - The `filter-method` now has a third param `column`, #9196 (by @liyanlong) - DatePicker - Added `prefix-icon` and `clear-icon` attributes, #9237 (by @AdamSGit) - Added `default-time` attribute, #9094 (by @nighca) - `value-format` now supports `timestamp`, #9319 (by @wacky6) - InputNumber - Now the binding value can be `undefined`, #9361 - Select - Added `auto-complete` attribute, #9388 - Form - Added `disabled` attribute, #9529 - Added `validateOnRuleChange` attribute, #8141 - Notificaition - Added `closeAll` method, #9514 #### Bug fixes - InputNumber - Fixed value resetting when typing decimal point, #9116 - Dropdown - Fixed dropdown menu incorrect positioning when the page only has a horizontal scrollbar in some browsers, #9138 (by @banzhuanmei) - Table - Fixed an error in calculating number of fixed columns after the column data changes, #9188(by @kolesoffac) - Fixed the border of the last column of the grouped header not properly displayed, #9326 - Fixed incorrect positioning of table header in Safari, #9327 - Fixed expanded row collapsing when the table data changes, #9462 - Fixed unnecessary multiple renders in some conditions, #9426 - Fixed column width calculation error when `width` of TableColumn changes, #9426 - Loading - Fixed Loading not hiding correctly in some conditions, #9313 - DatePicker - Fixed `focus` method not working in range mode, #9437 - Fixed clicking the "now" button still selecting the current date even if it is disabled, #9470 (by @wacky6) - Fixed date clamping when navigating, #9577 (by @wacky6) - Steps - Fixed style error in IE 11, #9454 #### Breaking changes - Menu - The popup menu in `collapse` mode now appends directly to `body`, so that it is visible when nested in Aside, #9263 - Table - Now checking the checkboxes in multi-selection Table doesn't trigger `row-click` event, #9467 - Loading - The `z-index` of non-fullscreen loading mask is changed to 2000. The `z-index` of fullscreen loading mask will update dynamically with the popup components, #9522 - Dropdown - `show-timeout` and `hide-timeout` attributes now only works when trigger is `hover`, #9573 ### 2.0.11 *2018-01-08* - Fixed border color issue of Select when in `prepend` or `append` slot of Input, #9089 - Fixed `remove-tag` event's parameter of Select, #9090 - Added `show-timeout` and `hide-timeout` attributes for SubMenu, #8934 (by @HugoLew) - Fixed missing Tooltip style of `show-overflow-tooltip` when Table is imported on demand, #9130 - Fixed Table column's sorting malfunctioning after `clearSort` is executed on that column, #9100 (by @zEmily) - i18n config file for Czech is renamed from `cz` to `cs-CZ`, #9164 ### 2.0.10 *2017-12-29* - Fixed wrong max height calculation of Table when fixed column and summary row co-exist, #9026 - Fixed uncompiled color style of empty text in Table, #9028 - Now DatePicker only emits `change` event when value is truly changed, #9029 (by @remizovvv) - Added `tabindex` attribute for Input, #9041 (by @dicklwm) ### 2.0.9🎄 *2017-12-24* - Added `before-remove` hook function for Upload, #8788 (by @firesh) - Fixed initial value of `error` not working for FormItem, #8840 - Now Loading directive supports custom class name by assigning `element-loading-custom-class` attribute, #8826 (by @earlymeme) - Fixed CarouselItem becoming invisible when data is asynchronously updated, #8921 - Added `renderAfterExpand` attribute for Tree, #8972 ### 2.0.8 *2017-12-12* - Added Spanish documentation - Fixed `show-timeout` of Dropdown not working when trigger is click, #8734 (by @presidenten) - Fixed Form validation timing for rules whose trigger is blur, #8776 - Fixed blur event of ranged DatePicker, #8784 - `format` of TimePicker now supports AM/PM, #8620 (by @firesh) ### 2.0.7 *2017-11-29* - Fixed disabled text button style, #8570 ### 2.0.6 *2017-11-29* - Fixed style bug of Table's sorting icons, #8405 - Fixed trigger mechanism for Popover when its `trigger` is manual, #8467 - Added `prefix-icon` and `suffix-icon` attributes for Autocomplete, #8446 (by @liyanlong) - Added `separator` attribute for Cascader, #8501 - Added `clearable` attribute for Input, #8509 (by @lbogdan) - Added `background` attribute for Pagination, #8553 ### 2.0.5 *2017-11-17* - Fixed Popover, Tree, Breadcrumb and Cascader regression in 2.0.4, #8188 #8217 #8283 - Fixed memory leak of clickoutside directive, #8168 #8225 (by @badpunman @STLighter) - Fixed multiple Select height when its value is cleared, #8317 (by @luciy) - Added `collapse-tags` attribute for multiple Select to replace tags with one line of text, #8190 - Fixed high CPU consumption caused by hidden Table, #8351 - Now you can use `doLayout` method of Table to update its layout, #8351 ### 2.0.4 *2017-11-10* - Improved accessibility for Cascader, Dropdown, Message, Notification, Popover, Tooltip and Tree - Fixed Container resize when the width of viewport decreases, #8042 - Fixed Tree's `updateKeyChildren` incorrectly deleting child nodes, #8100 - Fixed bordered CheckboxButton's height when nested in a Form, #8100 - Fixed Menu's parsing error for custom colors, #8153 (by @zhouyixiang) ### 2.0.3 *2017-11-03* - Fixed `editable` and `readonly` attributes for ranged DatePicker, #7922 - Fixed style error of nested Tabs, #7941 - Fixed style error of the last Step of vertical Steps, #7980 - Fixed trigger timing of `current-change` event for Pagination, #7995 - Fixed unregistered Tooltip in Menu, #7995 ### 2.0.2 *2017-10-31* - Now right-clicking the buttons of InputNumber won't change its value, #7817 - `validate` method of Form can now wait for asynchronous validations before executing its callback, #7774 (by @Allenice) - Fixed range selection of DatePicker not working in Chromium 53-57 browsers, #7838 - Fixed missing preview and delete icons of Upload when its `list-type` is picture-card, #7857 - Added `sort-by` attribute for TableColumn, #7828 (by @wangfengming) - Fixed DatePicker sometimes displaying wrong year number when selecting the first week in week mode, #7860 (by @hh23485) - Fixed icon style error of vertical Steps, #7891 - The hot area for node arrows in Tree is expanded, #7891 ### 2.0.1 *2017-10-28* - Fixed style error of RadioButton and CheckboxButton, #7793 - Fixed TimePicker not respond to mouse scroll in some conditions, #7811 - Fixed incomplete styles of some components when imported on demand, #7811 ### 2.0.0 Carbon *2017-10-27* #### New features - General - A new theme: `theme-chalk` - Accessibility of the following components are improved: Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload - Added TypeScript typings - All existing icons are redesigned. Some new icons are added - Added a series of breakpoint-based utility classes that hide elements when the viewport size meets certain conditions - Added layout components: Container, Header, Aside, Main, Footer - Now you can configure component sizes globally. When importing Element, you can add a global config object with a `size` prop to configure default sizes for all components. - Button - Added `round` attribute. It's used for round-cornered Buttons #6643 - TimeSelect - Now can be navigated by `Up` and `Down`, and hitting `Enter` selects the time #6023 - TimePicker - Now can be navigated by arrow keys, and hitting `Enter` selects the time #6050 - Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169 - Added `arrow-control` attribute to spin the time with arrows #7438 - Tree - Now child nodes don't render before the first expand #6257 - Added `check-descendants` attribute. It determines if child nodes are checked when checking their parent node in `lazy` mode #6235 - Tag - Added `size` attribute #7203 - Datepicker - Now `timeFormat` can format the TimePicker when type is set to `datetimerange` #6052 - Added `start-placeholder` and `end-placeholder`. They're placeholders for the two input boxes in range mode #7169 - Added `value-format` attribute to customize the format of the binding value, #7367 - Added `unlink-panels` attribute to unlink the two date panels when selecting a date range - MessageBox - Added `closeOnHashChange` attribute #6043 - Added `center` attribute so that the content can be centered #7029 - Added `roundButton` attribute to display round Buttons #7029 - Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string* #6043 - Added `inputType` attribute to assign type for the inner input box, #7651 - Dialog - Added `width`、`fullscreen`、`append-to-body` attributes. Now Dialog can be nested - Added `center` attribute so that the content can be centered #7042 - Added `focus-after-closed`、`focus-after-open` to improve accessibility #6511 - ColorPicker - Now you can type colors in the input box #6167 - Added `size` and `disabled` attributes #7026 - Added `popper-class` attribute #7351 - Message - Now color of the icons can be overridden by CSS #6207 - Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string* #6207 - Added `center` attribute so that the content can be centered #6875 - Notification - Added `position` attribute to configure where Notification pops up #6231 - Added `dangerouslyUseHTMLString` attribute. When set to `true`, `message` will be parsed as HTML string* #6231 - Added `showClose` attribute to hide the close button #6402 - Rate - Added `show-score` attribute to determine if current score is displayed #6295 - Tabs - Added `tab-position` attribute #6096 - Radio - Added `border` and `size` attributes #6690 - Checkbox - Added `border` and `size` attributes #6690 - Alert - Added `center` attribute so that the content can be centered #6876 - Menu - Added `background-color`, `text-color` and `active-text-color` attributes #7064 - Added `open` and `close` methods to open and close SubMenu programmatically, #7412 - Form - Added `inline-message` attribute to determine if the validation message is displayed in inline style #7032 - Added `status-icon` attribute to display a feedback icon when validated #7032 - Form and FormItem now have a `size` attribute. Inner components will inherit this size if not specified on themselves, #7428 - `validate` method will now return a promise if the callback is omitted, #7405 - Added `clearValidate` method for clearing validating results for all form items, #7623 - Input - Added `suffix` and `prefix` named slots, `suffixIcon` and `prefixIcon` attributes to add contents inside the input box #7032 - Breadcrumb - Added `separator-class` attribute to support icons as item separators #7203 - Steps - Added `simple` attribute to activate simple-styled Steps #7274 - Pagination - Added `prev-text` and `next-text` attributes to customize texts of previous page and next page #7005 - Loading - Now you can customize spinner icon and background color with `spinner` and `background` prop, #7390 - Autocomplete - Added `debounce` attribute, #7413 - Upload - Added `limit` and `on-exceed` attributes to limit the amount of files, #7405 - DateTimePicker - Added `time-arrow-control` attribute to activate `arrow-control` of the nesting TimePicker, #7438 - Layout - Added a new breakpoint `xl` for viewport wider than 1920px - Table - Added `span-method` attribute for merging cells - Added `clearSort` method to clear sorting programmatically - Added `clearFilter` method to clear filter programmatically - For expandable rows, when a row is expanded, a `.expanded` class will be added to its class list, so that you can customize its style - Added `size` attribute - Added `toggleRowExpansion` method to expand or collapse expandable rows programmatically - Added `cell-class-name` attribute to assign class name for cells - Added `cell-style` attribute to style cells - Added `header-row-class-name` attribute to assign class name for header rows - Added `header-row-style` attribute to style header rows - Added `header-cell-class-name` attribute to assign class name for header cells - Added `header-cell-style` attribute to style header cells - TableColumn's `prop` attribute now accepts `object[key]` notations - Added `index` attribute for TableColumn to customize row indices - Select - Added `reserve-keyword` attribute for reserving current search keyword after selecting an option #### Bug fixes - DatePicker - Fixed `v-model` returning the second day of the selected week in week mode #6038 - Fixed the first input being cleared in `daterange` type #6021 - DateTimePicker - Fixed DateTimePicker and TimePicker affecting each other when picked #6090 - Fixed hour and second can be beyond limit when selecting time #6076 - TimePicker - Fixed `v-model` not update correctly when blurred #6023 - Dialog - Fixed texts having blurry edges when opening and closing nesting dropdowns #6088 - Select - Improved performance. Now Vue dev-tool won't crash when a large number of Selects are destroyed #6151 - Table - Fixed a bug that Table remains hiding when its parent element appears from `display: none` - Fixed Table expanding its width when its parent element has `display: flex` - Fixed a bug that fixed columns of a Table with `append` slot would disappear when data is dynamically fetched - Fixed `expand-row-keys` attribute not working with initial value - Fixed filter failing when `data` updates - Fixed a calculation error of fixed columns layout with grouped headers - Fixed a dynamic `max-height` bug - Fixed some style calculation errors #### Breaking changes - General - Removed `theme-default` - Compatible with Vue 2.5.2+ and IE 10+ - `change` event of form components and `current-change` event of Pagination now only trigger on user interaction - `size` attribute of Button and form components now accept `medium`, `small` and `mini` - To facilitate the use of third-party icons, `icon` attribute of Button and Steps, `prefix-icon` and `suffix-icon` attributes of Input now require a full class name - Dialog - Removed `size` attribute. Now the size of Dialog can be configured by `width` and `fullscreen` - Now the visibility of Dialog cannot be controlled by `v-model` - Rate - `text-template` is renamed to `score-template` - Dropdown - `menu-align` is renamed to `placement`. Now it supports more positions - Transfer - `footer-format` is renamed to `format` - Switch - Attributes starting with `on-*` will be parsed to events in JSX, making all `on-*` attributes of Switch not able to work in JSX. So `on-*` attributes are renamed to `active-*`, and accordingly `off-*` attributes are renamed to `inactive-*`. This change affects the following attributes: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value` - `active-text` and `inactive-text` attributes now don't have default values - Tag - `type` attribute now accepts `success`, `info`, `warning` and `danger` - Menu - Removed `theme` attribute. The color of Menu can be configured using `background-color`, `text-color` and `active-text-color` - Input - Removed `icon` attribute. Now the suffix icon can be configured using `suffix-icon` attribute or `suffix` named slot - Removed `on-icon-click` attribute and `click` event. Now to add click handler on icons, please use named slots - `change` event now behaves like the native input element, which triggers only on blur or pressing enter. If you need to respond to user input in real time, you can use `input` event. - Autocomplete - Removed `custom-item` attribute. Now the template of input suggestions can be customized using `scoped slot` - Removed `props` attribute. Now you can use `value-key` attribute to designate key name of the input suggestion object for display - Steps - Removed `center` attribute - Now the Steps will fill its parent container by default - DatePicker - The params of DatePicker's `change` event is now the binding value itself. Its format is controlled by `value-format` - Table - Removed support for customizing column template using `inline-template` - `sort-method` now aligns with `Array.sort`. It should return a number instead of a boolean - `append` slot is moved outside the `tbody` element to avoid multiple rendering - `expand` event is renamed to `expand-change` - The params of `row-class-name` and `row-style` method is now an object ## * Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to [XSS attacks](https://en.wikipedia.org/wiki/Cross-site_scripting). So when `dangerouslyUseHTMLString` is on, please make sure the content of `message` is trusted, and **never** assign `message` to user-provided content. ================================================ FILE: CHANGELOG.es.md ================================================ ## Changelog ### 2.15.14 *2023-08-24* #### Bug fixes - Img - Delete referrerpolicy prop (#22651 by @xinguanhua) #### Optimization - Docs - Update readme and website example links (#22642 by @lyfeyaj) - Update popper links (#22539 by @brizer) - I18n - Update translation of Spanish (#22430 by @jcardus) - Add sr-Latn translation (#22567 by @N-M) - Update Uzbek translation (#22390 by @akahon) - Statistics - Fix doc; Optimized code (#22384 by @webvs2) - Table - Add highlight selection row (#22382 by @wangdaodao) ### 2.15.13 *2023-02-12* #### Bug fixes - Docs - Fix Statistic docs (#22383 by @JUST-Limbo) - Fix Input docs (#22093 by @lm312) - Fix en-US docs (#22268 #22269 #22270 by @Hazel-Lin) - Fix Pagination docs (#22288 by @xujintai123) - Fix: Links docs (#22370 by @itmier) - Statistics - fix slot display bug (#22375 by @webvs2) - Chore - missing web-type after publishing (#22271 by @loosheng) #### Optimization - InputNumber - Fix touch one click trigger twice on the window touch pad (#22185 by @mrsai) - Image - Add initialIndex prop (#22346 by @inkroom) - Statistics - Updated countdown feature to localize lodash Closes (#22260 by @webvs2) - Update code and doc (#22276 by @webvs2) - Other - fix web-types type props (#22281 by @whzxc) ### 2.15.12 *2022-11-16* #### Bug fixes - Statistic: - Fixed the thousandth bit bug (#22252 by @webvs2) - Other - Fix 2.15.11 element-theme-chalk publish fail bug ### 2.15.11 *2022-11-15* #### Bug fixes - Docs - Fix Radio docs (#22178 by @bchen1029) - Fix Progress docs #### Optimization - I18n - Update translation of Malaysian (#22185 by @z4q) - Update translation of Norwegian (#22145 by @Barsnes) - Progress - Add defineBackColor and textColor prop (#22089 by @lm312) - Statistics - Add new component Statistics (#22159 by @webvs2) - Other - Add Web Types to improve code assistance in WebStorm IDE and other JetBrains IDEs (#22135 by @piotrtomiak) ### 2.15.10 *2022-09-13* #### Bug fixes - DatePicker - Fix props placement error (#21908 by @lqzhgood) - Loading - Fix sticky DOM error (#22087 by @zzjjhh001) - Docs - Fix Popover docs (#22083 by @lm312) - Fix Skeleton docs (#22092 by @lm312) - Fix DatePicker docs (#21970 by @guojiongwei) - Tree: - fix lazy-load default check problem (#21934 by @kiss-yu) #### Optimization - I18n - Add translation of Sinhalese (#21936 by @sayuri-gi) - Update translation of Spanish (#21924 by @jcardus) - Add translation of Malaysian (#22028 by @iorange0411) - Update translation of Swahili (#21904 by @Cholowao) - Utils - update date-util.js (#22099 by @Due07) - DatePicker - add months And years type (#21918 by @akiko123456) ### 2.15.9 *2022-06-02* #### Bug fixes - Table - Fix Tabl-header shake bug (#21863 by @bofeng) - Fix when partial import show `el-checkbox not imported` error (#21828 by @bobohuochai) - FormItem - Fix change rules verification not reset bug (#21892 by @bofeng) - Cascader - Fix change options unexpect error (#21759 by @louiebb) - Docs - Fix Popover docs (#21843 by @lod61) - Fix Calendar docs (#21814 by @GoJam11) - Fix TimePicker docs (#21803 by @Alanscut) - Fix DatePicker docs (#21877 by @Nirvanaiu) - Other - Fix codepen display bug (#21863 by @bofeng) #### Optimization - I18n - Add translation of Swahili (#21895 by @quilltouch) - Chore - Use launch-editor-middleware in dev environment (#21633 by @polemices) - DatePicker & Cascader - Optimize the dropdown animation direction (#21806 by @XivLaw) - Tooltip - Optimize `getFirstElement` code (#21886 by @zhankang) - Input - Optimize scss code (#21558 by @cheese-git) ### 2.15.8 *2022-04-12* #### Bug fixes - Drawer - Fix appendToBody failure problem (#21264 by @cs1707) - Switch - Fix toggling value problem(#19473 by @EdwinBetanc0urt) - Docs - Fix input docs (#21723 by @justforuse) - Fix DatePicker docs (#21663 by @justforuse) - Fix Skeleton docs (#21601 by @yanwydxf) - Others - Fix vue version (#21736 by @ckvv) #### Optimization - I18n - add translation of Azerbaijani (#21012 by @ricardotondello) - update translation of Slovenian (#21729 by @patik123) - update translation of Slovak (#21711 by @sjaustirni ) - add translation of Icelandic (#21709 by @aronhr) - add translation of Bengali (#21485 by @llwwtt) #### Others - Due to compatibility considerations, the PR on node-sass (#21019 by @linxsbox) of 2.15.7 release has been withdrawn and will be published in an appropriate version after re-evaluation. ### 2.15.7 *2021-11-18* #### Bug fixes - Select - fix click icon triggering dropdown (#21314 by @dennyak47) - fix keydown event when composition (#21336 by @bchen1029) - Badge - fix type class when is-dot (#21308 by @adaex) - Form - validate method reject error info (#21374 by @cs1707) - Table - fix resizeObserver loop limit exceeded (#21255 by @tomieric) - fix toggleAllSelection bug when table is empty (#21456 by @cs1707) - optimize performance (#21330 by @cs1707) - Button - fix disabled priority (#21375 by @cs1707) - Descriptions - fix label slot bug (#21462 by @cs1707) - SASS - replace node-sass with dart-sass (#21019 by @linxsbox) - Docs - fix skeleton typos (#21408 by @zhhbstudio) ### 2.15.6 *2021-09-02* #### Bug fixes - Cascader - fix a bug that makes the browser jitter in zoom mode (#21207 by @cs1707) - optimize performance (#21231 by @cs1707) - Select - fix long text overflow in multiple mode (#21237 by @cs1707) - Dropdown - add disabled property (#21235 by @mshioda) - Radio - fix checked state when browser go back (#21250 by @cs1707) - Descriptions - fix type declaration (#21265 by @adaex) - avoid table style conflict (#21254 by @adaex) - Drawer - fix append to body (#21264 by @cs1707) - Local - fix italian mistake (#21012 by @ricardotondello) ### 2.15.5 *2021-08-04* #### Bug fixes - Select - fix resetInputHeight (#21201 by @cs1707) ### 2.15.4 *2021-08-03* #### New features - Descriptions - add description component (#21129 by @cs1707) - Result - add result component (#21171 by @cs1707) #### Bug fixes - Utils - fix isScroll (#21098 by @canvascat) - Translation - update it.js (#21133 by @bliberi) - RadioGroup - fix RadioGroup used in component causes exception #17908 (#20783 by @lceric) - Message - fix message[type] (#21088 by @cs1707) - Carousel - reset the timer when setActiveItem method is called (#20846 by @Nekojita1) - Cascader - fix emitPath (#21185 by @cs1707) - Select - fix select filterable bug (#17494 by @profore) - fix a bug that makes the browser jitter in zoom mode (#21197 by @cs1707) - Tree - fix insertChild (#21194 by @cs1707) ### 2.15.3 *2021-06-29* #### New features - Skeleton - add skeleton component (#21038 by @cs1707) - Empty - add empty component (#21080 by @cs1707) #### Bug fixes - Local - fix week translations for hr locale (#21040 by @cs1707) - Table - fix lazy load data (#21041 by @cs1707) - Docs - fix form hide-required-asterisk description (#21045 by @cs1707) - Drawer: - fix destroy (#20715 by @zj9495) - Row - fix align top (#20963 by @cs1707) - Select - fix the bug when the value is Boolean (#21052 by @cs1707) - Calendar - fix first-day-of-week (#21057 by @cs1707) - Utils - fix isScroll (#21065 by @cs1707) - fix(utils.dom by @fw6) - TypeScript - add CascaderPanel export type (#21070 by @qige2016) - add spinner.d.ts (#21090 by @qige2016) ### 2.15.2 *2021-05-28* #### Bug fixes - Image - fix z-index and keydown event add stopPropagation (#20859 by @cs1707) - Input - fix show password cursor (#20870 by @cs1707) - fix show password icon in edge (#20902 by @cs1707) - Carousel - fix interval and scale bug (#20931 by @cs1707) - Cascader - fix delete tag bug (#20939 by @cs1707) - Drawer - add overflow auto (#20948 by @cs1707) - Others - fix isFunction (#20912 by @cs1707) ### 2.15.1 *2021-02-23* #### Bug fixes - Drawer - bugfix (by @cs1707) - Image - fix incorrect image object fit ratio in IE (#19583 by @charlie0228) - Cascader - fix cascader panel active path (#20730 by @cs1707) - Calendar - fix calendar component i18n bug (#20758 by @iamkun) - ColorPicker - fix bugs (by @UxieVerity) #### Optimization - Doc - update Axure resource v2.1.0 (by @iamkun) ### 2.15.0 *2021-01-15* #### Bug fixes - Select - Fix placeholder i18n bug (#17644 by @nzh63) - Popconfirm - Popconfirm i18n bug by @iamkun - Drawer - Fix focus bug (#20626 by @cs1707) - Image - Preview optimization (#20652 by @cs1707) #### Optimization - Doc - Fix typo in french translation of datetime-picker.md (#20543 by @lonk) - Add format attribute description to the progress component (#20641 by @cs1707) ### 2.14.1 *2020-11-11* #### Bug fixes - Popover - Compatible with Vue 2.6 new v-slot syntax (#20424 by @iamkun) #### Optimization - I18n - Update Arabic translation (#20202 by @elkattan) - Update Uighur translation (#20177 by @IlhamTahir) ### 2.14.0 *2020-10-29* #### Breaking changes - Popconfirm - Rename event name to `confirm`, `cancel` (#20240 by @hugiron) #### Bug fixes - Progress - Fix attribute error (#19985 by @Caaalabash) #### Optimization - I18n - Update Russian translation (#19451 by @yangirov) - Update Khmer translation (#20077 by @Sovai) - Update Ukrainian translation (#20344 by @MammutAlex) ### 2.13.2 *2020-05-18* #### Corrección de errores - Autocomplete - Arreglado el error cuando se daba el evento change (#19200 by @sxzz) - Image - Actualizado el estado de error (#19194 by @lhx6538665) #### Optimización - I18n - Actualización de la traducción del popconfirm al Ruso (#19220 by @Opppex) - Actualización de la traducción al vi (#19244 by @quangln2810) - Actualización de la traducción al Catalán y al Español (#19296 by @Ismaaa) - Actualización de la traducción al Indonesio (#19320) by @therour) - Actualización de la traducción al Portugués Brasileño (#19374 by @diegomengarda) ### 2.13.1 *2020-04-13* #### Nuevas características - Autocomplete - Agregado el evento change (#17913 by @sxzz) #### Corrección de errores - Autocomplete - Solucionado el error de la sugerencia en textarea (#18478 by @Roojay) - Carousel - Arreglado el error de escritura de la consola (#18264 by @IceFox) - Image - Solucionado el error de que no se mostraba el preview si no existía el src (#18975) (#19130 by @luckyCao) - Arreglado el problema de que el shortcut key no funcionaba la segunda vez (#18983) (#19156 by @luckyCao) - No muestra la imagen cuando preview es falso (#18967 by @inooNgt) - Transfer - Corregida la altura (line-height) incorrecta del primer elemento del el-transfer cuando era usado con el-form-item (#18917 by @Hanx) - InputNumber - Calculo correcto de inputNumberDisabled (#18439 by @ashuser-pendo) - Tarea - Se quito la introducción del index (#19155 by @iamkun) - Documentación - Actualización de la documentación de Popconfirm (#18324 by @iamkun) - Arreglado el error tipográfico de la documentación de Fix step-strictly (#18705 by @dream2023) - Corregido un type error en la documentación de steps component (#17555 by @haoranyu) ### 2.13.0 *2019-11-26* #### Nuevas características - Popconfirm - Agregado componente popconfirm (#17548 by @iamkun) #### Corrección de errores - BackTop - Se usa cubic bezier para el scroll (by @lon) - DatePicker - Arreglado el fallo cuando solo se elegía fecha mínima en un rango de fechas (#17191 by @smk0621) - Select - Arreglado los casos de test del select (by @msidolphin) - Tree - Agregado font-size para el estilo del texto cuando esta vacío el tree (#17094 by @spengjie) - Table - La cabecera de la columna puede modificarse (#17291 by @ziyoung) - Se actualizo el estilo de la cabecera de la tabla de la celda (#17284 by @ziyoung) - Se soluciono el problema de height de la cabecera de la tabla después de un filtro (#17348 by @ziyoung) - Corregido el estilo de la fila que con display no funcionaba (#17002 by @a631807682) - Arreglado que la cabecera de la tabla no se mostraba (#17341 by @ziyoung) - Calendar - La importación de el-button y el-button-group (#17376 by @masongzhi) - MessageBox - Corregido el error de posición del icono (#17410 by @nullptru) - TimePicker - Establecido el rango de selección después de hacer scroll (#16868 by @mattheyan) - Message - Corregido el offsetHeight al cerrar la instancia(#17564) (#17852 by @gzwgq222) - Form - La función de llamada de validateField es opcional (#17314 by @CarterLi) - Cascader - Corregida la compatibilidad con TypeScript 3.7 (#17881 by @CarterLi) - Menu - Corregido el error de la ruta de navegación duplicada cuando se usaba vue-router@^3.1.0 (#17269 by @iamkun) - Dropdown - Actualización del tipo de archivo (#17550 by @iamkun) - Progress - Agregada la prop strokeLinecap (#17552 by @iamkun) - InfiniteScroll - Salto del disparo de evento en elementos invisibles (#17553 by @iamkun) - Image - Comportamiento perfecto de personalización de imágenes (#16985 by @luckyCao) - Corregida la pagina cuando se hace preview de imágenes grandes (#16796 by @luckyCao) - Drawer - Corregido el fallo del append-to-body del drawer que no funcionaba (#16953 by @JeremyWuuuuu) - Select - Corregido: ahora muestra el tag o el valor vacío (17199 by @luckyCao) - Scrollbar - Arreglado el ancho del scroll en FireFox (#18091 by @iamkun) #### Optimización - I18n - Actualizado sv-SE.js (#17926 by @FOLLGAD) - Actualizada la documentación para francés para el componente avatar (#17762 by @blombard) - Docs - Arreglada la typografia de time-select (#17250 by @wacky6) - Arreglado en Drawer, ahora el atributo value acepta tipografías en español (#17122 by @haoranyu) - Actualización del Changelog 2.12.0 al español (#17364 by @Gonzalo2310) - Arreglo de la tipografía del Changelog (#17874 by @renlixin) - Arreglada la demo de Loading (#17862 by @MBearo) - Agregado el evento input en los inputs de Table (#18061 by @zhouxinyong) - Eliminado el evento repetitivo change de los input (#18085 by @zhouxinyong) ### 2.12.0 *2019-08-29* #### Nuevas características - Popover - Agregada la prop close-delay (#16671 by @LachlanStuart) - Theme - Añadida la extensión Chrome: Element Theme Extensión (#16686 by @iamkun) - Icon - Añadido font-display a la declaración @font-face (#16805 by @iamfaizalandyka) #### Corrección de errores - Carousel - Corregido el valor emitido por onChange (#16705 by @iamkun) - Notification - Corrección de la modificación del objeto de opción entrante (#16704 by @iamkun) - DatePicker - Agregado el className para la opción picker (#16632 by @iamkun) - DateTimePicker - Corrección del time-spinner que no se desplazaba a la posición correcta (#16854 by @jesse-li) - Table - Evitar la propagación del click después del arrastre (#16850 by @ziyoung) - Corregido una error en chrome que se producía cuando el css de thead tenia display: none (#16956 by @luckyCao) - Corregida la altura incorrecta de los bloques vacíos (#16861 by @ziyoung) - No hay lanzamiento de error cuando se llama a toggleExpansion (#16304 by @yyjjqq94) - No se lanza el evento sort-change cuando esta montado (#17113 by @a631807682) - Corregido que el setCurrentRow no borraba la linea resaltada (#16879 by @ziyoung) - Corregido que expand-row-keys no funcionaba cuando los datos eran cargados asincrónicamente (#16899 by @ziyoung) - Establecido toggleAllSelection como propiedad instanciada (#17137 by @ziyoung) - Tree - Corregida la distancia entre label y checkbox (#16799 by @Hazlank) - Tabs - Corregida la posición incorrecta de los item's del Tab (#16520 by @victorting) - Corregido el error de que la pestaña activada estaba fuera del rango visual (#17033 by @nullptru) - Calendar - Arreglado el problema de los días de la semana con i18n (#16772 by @ubitoffee) - Corregido el error de localización (#17208 by @iamkun) - Cascader - Corregido un error de visualización del CascaderPanel (#16716 by @zhangHongEn) - Corregido el problema de disable status y close button (#16224 by @yyjjqq94) - Input - Arreglado el evento de composición coreana (#15069 by @MoonHyuk) - Arreglado el evento click del botón clear que no se lanzaba cuando se usaba v-loading (#16576 by @a631807682) - Select - No cambiaba el dropdown cuando se filtraba (#17205 by @luckyCao) - Transfer - Arreglado un error de estilo (#17206 by @iamkun) - Dialog - Actualizada las variables Sass (#16365 by @haoranyu) - RadioGroup - No produce HTML invalido en la tabla si el atributo 'is' es especificado (#17070 by @nullptru) - Divider - Soporta clases personalizadas (#17078 by @island205) #### Optimización - Checkbox - Mejorada la experiencia del lector de pantalla (#16575 by @tylertrotter) - Docs - Actualizado changelog (#16773 by @SimonaliaChen) - Actualizada la guía de contribución (#14800 by @sinchang) - Arreglado typo en la documentación de Drawer (#16848 by @winkay) - Actualizado el tema personalizado (#16983 by @iamkun) - Agregada traducción en Esperanto (#16955 by @maxkoryukov) - Actualizada la documentación de input-number sobre el evento change (#16316 by @luckyCao) - Actualizada la documentación en Español 2.11.1 (#16961 by @Gonzalo2310) - I18n - Eliminada la traducción de 'year' en idioma Catalán como en otros idiomas (#14722 by @oscaralbareda) - Actualizado el changelog de las versiones 2.10.0 y 2.10.1 en Español (#16548 by @Gonzalo2310) - Actualizado ar.js (#16653 by @l3op) - Test - Corregir error ortográfico (#16672 by @boomler) - Refractorizacion del unit test para usar data-uri (#16847 by @a631807682) - Types - Corrección del tipo httprequest (#16633 by @luckyCao) ### 2.11.1 *2019-07-26* #### Corrección de errores - Image - Corregido el componente Image para compatibilidad SSR (#16737 by @luckyCao) - Tarea - Actualizado para compatibilidad con dart-sass by @LewisChennnnn) ### 2.11.0 *2019-07-25* #### Nuevas características - Drawer - Agregado componente drawer (#16577 by @JeremyWuuuuu) #### Corrección de errores - Checkbox - Mejora del selector css (#16006 by @Hazlank) - Tree - Establecido el el-tree como genérico (#15934 by @JeremyWuuuuu) - Establecido la prop isCurrent como False (#15870 by @kkkisme) - Dropdown - Corregido el color predeterminado de los split-button (#15931 by @JuniorTour) - Cascader - Corregido un problema de actualización cuando el nivel 1 de children estaba vació (#16399 by @luckyCao) - Ahora se muestra correctamente header cuando range esta especificado (#16354 by @ziyoung) - Agregados valores por defecto cuando lazy es true (#16420 by @luckyCao) - Solucionado problemas de visualización (#15935 by @junyiz) - Expuestos los getCheckedNodes y corrección de errores en el cambio de opciones (#16709 by @SimonaliaChen) - Submenu - Corregida la prop append-to-body (#16289 by @a631807682) - Table - Arreglado un fallo en la actualizacion de los datos de tree table (#16481 by @island205) - Select - Arreglado un problema de fuga de memoria (#16463 by @island205) - InfiniteScroll - Actualizada la nomenclatura y la documentacion (#16698 by @iamkun) - Avatar - Arreglado que la imagen no se centraba verticalmente (#16489 by @luckyCao) - Dialog - Agregado el atributo destroyOnClosee (#16455 by @ziyoung) - Image - Agregada la función de vista previa grande de imágenes (#16333 by @luckyCao) #### Optimización - Documentación - Arreglada la demo de dropdown (#16193 by @webxmsj) - Corrección de errores tipográficos en las tablas de documentos (#15971 by @howiefh) - I18n - Actualizada la traduccion del lenguage Thai (#16689 by @ponkrit) - Tareas - Actualizada la api base del tema (#16607 by @iamkun) - Añadido token del formulario del tema (#16699 by @iamkun) - Marcar todos los accesos internos del usuario (#16609 by @iamkun) - Corrección del error de anclaje del documento (#16692 by @iamkun) ### 2.10.1 *2019-07-02* #### Corrección de errores - Table - Corregido el icono de ordenación (#15439 by @bezany) - Corregidas las rupturas del layout cuando existía un slot (#16332 by @ziyoung) - Corregido showOverflowTooltip no era reactivo (#16295 by @a631807682) - Registrada la scrollbar en el panel de filtro (#16246 by @ziyoung) - Tareas - Arreglada la documentación 2.9 (#16233 by @ziyoung) - Corregido el índice de la página de introducción del tema en inglés que tenia un error en los estilos css (#16254 by @iamkun) #### Optimización - Tag - Compatible con IE (#16334 by @ziyoung) - Tarea - Actualizada la imagen QR de Dingtalk Group (#16236 by @iamkun) - Doc - Actualizada la documentación online del theme roller (#16244 by @iamkun) ### 2.10.0 *2019-06-25* #### Nuevas características - I18n - Añadido idioma Uzbeko (#15796 by @ogabek96) - Calendar - Añadido el atributo del primer día de la semana (#16047 by @ziyoung) - Avatar - Agregado componente Avatar (#16144 by @luckyCao) - Upload: - Añade capacidad para personalizar la plantilla de miniaturas (#13192 by @victorzhuk) #### Corrección de errores - Tree - No resaltar el nodo de árbol cuando currentKey es nulo (#15668 by @yyjjqq94) - Solucionado el problema #15538 causado por dos Tree que compartian los mismos datos.(#15615 by @VanMess) - Upload - Actualizado el tipo del parámetro `fileList` (#15716 by @underfin) - Table - Solucionado que el icono de loading no se mostraba (#15868 by @ziyoung) - Corregido el color de fondo de una tabla compleja cuando se desplaza el cursor (#15504 by @cnlon) - Corregido current-row-key y el bug del evento select (#15983 by @ziyoung) - Height acepta más unidades (#16013 by @ziyoung) - Solucionado reserve-selection no funcionaba (#16135 by @ziyoung) - Docs - Corregido el tipo de atributo Divider en zh-cn (#15889 by @haoranyu) - Se elimina una etiqueta html de cierre incorrecta y el código de bloque vacío (#16194 por @Alexeykhr) - Menu - Corregido un error oculto en el submenú después de añadir popper-append-to-body (#15391 by @PanJiaChen) - Select - Arreglado initialInputHeight (#15989 by @yyjjqq94) - Corregido el comportamiento de default-first-option cuando se escribe chino (#15431 by @VanMess) - Corregido el problema de importación doble (#16215 by @lengband) - Message - Añadida la opción type def para offset (#16027 by @matjaz) - Timeline - Arreglado reverso roto (#16091 by @ziyoung) - Slider - Corregido #15545 agregando explicaciones sobre el evento "input" en chino (#15588 by @VanMess) - InfiniteScroll - Actualización del nombre del paquete (#16125 by @iamkun) - MessageBox - Arreglado el bug de distinguishCancelAndClose, la acción no era la misma que la documentada (#15438 by @qingdengyue) - PopupManager - Arreglado que el z-index no podía ser reescrito la primera vez que se usaba (#15738 by @luckyCao) - Tarea - Actualizado el test del api host (#15807 by @iamkun) #### Optimizacion - Tree - Modificar las condiciones del bucle para mejorar el rendimiento (#15699 by @KingJeason) - Theme - Refinado GA track & actualizado el link del pie que lleva al theme roller online (#16007 by @island205) - Badge - Actualizado el check del prop badge (#16198 by @iamkun) - Avatar - Actualizado el var del config del theme (#16202 by @luckyCao) - I18n - Actualizada la traducción del portugués (#15776 by @gigioSouza) - Actualizada la traducción del idioma Farsi (#15881 by @pamenary) - Docs - Agregado componentes faltantes en el quick start (#16063 by @pape2016) - Actualizada la traducción al francés (#16208 by @blombard) - Agregada descripción $slots.default (#15444 by @Alexeykhr) - Actualizada la Doc en Español 2.9.1 (#15840 by @Gonzalo2310) - Corrección de errores ortográficos en fr (#15837 by @blombard) - Actualizado el changelog 2.9.2 en español (#16185 by @Gonzalo2310) #### Breaking changes - Form - Eliminado el estado success (#16159 by @ziyoung) ### 2.9.2 *2019-06-21* #### Corrección de errores - Tareas - Solucionadas las definiciones de archivos TS (#15805 by @NateScarlet) ### 2.9.1 *2019-05-30* #### Nuevas características - Table - Los metodos tree-props,default-expand-all, expand-row-keys, toggle-row-expansion y el evento expand-change son compatibles con Tree Table (#15709 by @ziyoung) #### Corrección de errores - Table - Corrección de algunos errores (#15709 by @ziyoung) - Theme - Actualización del host de la api (#15784 by @iamkun) #### Optimización - Tarea - Una actualización del tipo InfiniteScroll (#15794 by @iamkun) ### 2.9.0 *2019-05-30* #### Nuevas características - Backtop - Añadido componente Backtop (#15541 by @iamkun) - PageHeader - Añadido el componente PageHeader (#15714 by @ziyoung) - InfiniteScroll - Añadida la directiva InfiniteScroll (#15567 by @iamkun) - Cascader - Agregado modo múltiple y método de filtro (#15611 by @SimonaliaChen) - Message - Visualización en modo stack (#15639 by @island205) - Tag - Añadido prop effect (#15725 by @SimonaliaChen) - Tabs - Alinea el título a la izquierda cuando el tipo es card (#15695 by @luckyCao) - DatePicker - Soporta cadenas literales (#15525 by island205) - Image - Añadido soporte para transmitir attrs y listeners (#15578 by @VanMess) - Theme - Añadido fondo al popup (#15412 by @iamkun) - Tarea - Actualizada la nueva página de índice 2.9.0 (#15682 by @iamkun) #### Corrección de errores - Table - Corregido el comportamiento de cambio de orden cuando la condición de orden es nula (#15012 by @joelxr) - Image - Corregido ssr y compatibilidad de ajuste de objetos (#15346 by @SimonaliaChen) - Input - Corregido estilo show-word-count en el-form (#15359 by @lvjiaxuan) - Corregido el icono de borrar que no estaba centrado (#15354 by @YiiGuxing) - Calendar - Corregido día de la semana no correcto cuando el día es domingo (#15399 by @qingdengyue) - Corregido error de desaparición de octubre (#15394 by @qingdengyue) - Tabs - Corrección de la pestaña básica anidada en el error de relleno de la pestaña de la tarjeta (#15461 by @SimonaliaChen) - Tag - Corregido problema de propagación de stop (#15150 by @infjer) - Form - Corregido el error de grupo de entrada dentro de la altura del elemento de formulario (#15457 by @SimonaliaChen) - Solucionado el problema de resetFields (15181 by @luckyCao) - Tooltip - Corregido tabindex personalizado no funcionaba (#15619 by @SimonaliaChen ) - Link - Arreglada la clase de estilo del icono de enlace (#15752 by @iamkun) - Select - Revertir el valor establecido a nulo cuando se borra (#15447 by @iamkun) - Loading - Corregido dom no cambia cuando el estado de carga cambia rápidamente (#15123 by @FAKER-A) - Switch - Etiqueta con el evento de repetición del interruptor (#15178 by @FAKER-A) - Slider - Arreglado el problema de estilo al hacer clic en la barra deslizante (#15561 by @luckyCao) - Radio - Solucionado el problema 14808 (#14809 by @OverTree) - Form - Solucionado el problema de resetFields (15181 by @luckyCao) - Tarea - Se actualizaron las dependencias y se corrigió el error de demostración (#15324 by ziyoung) - Type - Corregida la definición del tipo de carga (#15635 by @iamkun) - Corregido tipo Icono (#15634 by @iamkun) - Corregida la definición del tipo de enlace (#15402 by @iamkun) #### Optimización - Cascader - Refractorización (#15611 by @SimonaliaChen) - Tarea - Actualización hacer nueva lógica de componentes (by @iamkun) - Documentación - Renombrar variable en docs (#15185 by @liupl) - Corregido el atributo type de imagen y el valor por defecto (#15423 by @haoranyu) - Corregido error en la doc de form (#15228 by @SHERlocked93) ### 2.8.2 *2019-04-25* #### Corrección de errores - Icon - Actualizado icon (#15272 by @iamkun) - Docs - Arreglada la documentacion de Form e Input (#15273 by @ziyoung) ### 2.8.1 *2019-04-25* #### Corrección de errores - Icon - Actualizado el icono de cascader y select (#15264 by @SimonaliaChen) - Actualizado icon (#15258 #15268 by @iamkun) #### Optimización - Chore - Actualizado build script (#15267 by @ziyoung) - Docs - Arreglado el color underline de link (#15265 by @iamkun) - Other - Arreglada la migracion de la configuracion no compatible con camel case props y eventos (#15260 by @SimonaliaChen) ### 2.8.0 *2019-04-25* #### Nuevas características - Divider - Agregado el componente Divider (#15055 by @island205) - Rate - Agregados colores personalizados y clases de iconos pasando un objeto (#15051 by @SimonaliaChen) - Link - Agregado componente Link (#15052 by @iamkun) - Calendar - Agregado el componente Calendar (#14908 by @ziyoung) - Icon - Agregado Icon (#15214 by @iamkun) - Alert - Agregado tema dark (#15041 by @island205) - Image - Agregado componente image (#15117 by @SimonaliaChen) - Collapse - CollapseItem puede ser disabled (#15076 by @ziyoung) - Carousel - Agregado atributo direction y soporte para la direccion vertical (#15122 by @ziyoung) - Pagination - Agregado atributo hide-on-single-page (#15096 by @ziyoung) - Slider - Agregado atributo marks (#15133 by @luckyCao) - Input - Agregado attributo show-word-count (#15075 by @luckyCao) - InputNumber - Agregado atributo step-strictly (#15050 by @luckyCao) - Tooltip, Dropdown, Popover - Soporte para el atributo tabindex (#15167 by @ziyoung) #### Corrección de errores - Notification - Arreglado el word break del titulo (#15008 by @iamkun) - Form - Arreglado que cuando se cambiaban las reglas en el-form no funcionaba (#14985 by @luckyCao) - Arreglado el estilo del label (#14969 by @ziyoung) - Los FormItem requeridos muestran astericos cuando el label es auto (#15144 by @ziyoung) - Pagination - Arreglado que el slot no se actualizaba (#14711 by @lucyhao) - Table - Arreglado un bug del load en el modo lazy (#15101 by @ziyoung) - Arreglado el ancho de la celda cuando colspan es mayor que 1 (#15196 by @ziyoung) - Mejora en el rendimiento (#14868 by @ziyoung) - No se emiten disparadores del evento sort-change durante la inicializacion (#14625 by @PeanutWatson) - Igual comportamiento para height y max-height (#14660 by @arthurdenner) - Dialog - Arreglado que el cuerpo del dialog quiebre las palabras correctamente en las palabras largas (#15027 by @iamkun) - Alert - Actualizada la definicion de type (#15186 by @ziyoung) - Tabs - Solucionado el problema por el que el rechazo de la promesa estaba afectando a la aplicación (#14816 by @ffxsam) - Rerender cuando hay cambios en el slot (#15238 by @ziyoung) - Message - Actualizada la definicion de type (#14968 by @agoni1212) - Select - Solucionado el error cuando value es undefined o null (#15022 by @luckyCao) - Tree - Eliminar el nodo actual despues de removido (#14604 by @sinchang) - Mejora en el rendimiento (#14881 by @ChenZhuoSteve) - Dropdown - Estilo arreglado (#14907 by @doing123) - Slider - Corrección de un fallo en el teclado a11y (#14792 by @erezsob) - Menu - El valor de ActiveIndex será nulo si el defaultIndex no existe (#14074 by @hoythan) - Directive - RepeatClick: usa Date.now() en lugar de new Date() (#14776 by @pavelmash) - Upload - Arreglado el estilo para mostrar imagenes transparentes (#15039 by @iamkun) - Theme - Agregado zero border (#15256 by @iamkun) #### Optimización - Tareas - Actualizado changelog zh-cn (#14965 by @iamkun) - Ocultar la descripcion de la demo cuando esta vacia (#15014 by @ziyoung) - Muestra la info dev del server por defecto @iamkun) - Arreglado un error del changelog v2.6.0 (#15026 by @iamkun) - Actualizado build config (#14821 by @abc3660170) - Agregado hmr (#15221 by @SimonaliaChen) - Uso de sourcemap en entorno dev (#15087 by @ibufu) Docs - Cambio de nombre de variable en docs (#14602 #15003 #15094 #15105 by @liupl) - Arreglado un error en la documentacion de upload (#15023 by @iamkun) - Actualizada la documentacion del custom validator del Form (#15040 by @iamkun) - Actualizada la documentacion de Tabs de como mostrar tabs verticales (#15053 by @iamkun) - Uso del dominio eleme.cn (#15139 by @ziyoung) - Arreglado el nombre de la ruta de imágenes (#15194 by @iamkun) - Eliminada la traducción duplicada en francés (#15207 by @iamkun) #### Breaking changes - Rate - Arreglado Fix decimal display support in disabled mode (#15089 by @haoranyu) - Select - Se usa la opcion placeholder del label para poner el placeholder en el modo filter (#14989 by @ibufu) ### 2.7.2 *2019-04-03* #### Corrección de errores - Form - Arreglado el estilo auto `label-width` (#14955 by @ziyoung) #### Optimización - Docs - Arreglado un error de link de una imagen (#14957 by @iamkun) - Chore - Arreglado un error de mkdir en el deploy (#14952 by @iamkun) ### 2.7.1 *2019-04-03* #### Corrección de errores - Select - Se asigna null a value cuando se limpia (#14322 by @aaronfulkerson) - Input - Actualiza los valores dependientes en el DOM cuando el tipo cambia (#14889 by @wacky6) - Table - Hacer que defaultExpandAll funcione cuando exista una columna expandida (#14935 by @ziyoung) - Dialog - El color de fondo puede ser configurado (#14939 by @ziyoung) - Form - `label-width` soporta auto width (#14944 by @ziyoung) #### Optimización - Docs - Actualización de la documentación en español (#14913 by @Gonzalo2310) - Agregada documentación en francés para el nuevo componente (#14924 by @ziyoung) - Documentación de los Tabs optimizada (#14938 by @ziyoung) ### 2.7.0 *2019-03-28* #### Nuevas características - Table - Agregado soporte de datos con estructura tree (#14632 by @ziyoung) #### Corrección de errores - Tabs - Uso de color primario como boxShadow color (#14558 by @Richard-Choooou) - Renderización cuando cambia la etiqueta (#14496 by @akki-jat) - Table - El pie de página sigue la alineación de las celdas del body (#14730 by @ziyoung) - NavMenu - Se ha corregido que al hacer click en el el-submenu se disparaba childMenu nuevamente (#14443 by @PanJiaChen) - Dropdown - Compatible con la nueva sintaxis de v-slot en V 2.6 (#14832 by @ziyoung) - ColorPicker - Corregido el manejo de error de string en hex color (#14793 by @iamkun) - Tree - Revertido pr #13349 (#14847 by @ziyoung) - Tooltip - Muestra cuando el valor inicial es verdadero (#14826 by @ziyoung) - Docs - Actualización de documentos de cascader (#14442 by @panhezeng) - Style - Corrección de la media query en sm-only, md-only, lg-only (#14611 by @sinchang) #### Optimización - Chore - Añadido descripción de la página web (#14802 by @iamkun) ### 2.6.3 *2019-03-21* #### Corrección de errores - Corrección del estilo de demostración de Cascader (#14789 by @ziyoung) - Eliminación de la operación DOM innecesaria (#14788 by @ziyoung) - Corrección del valor predeterminado del DST de DatePicker (#14562 by @wacky6) ### 2.6.2 *2019-03-21* #### Nuevas características - DatePicker - Añadido monthrange para el atributo type (#14487 by @zxyRealm) - i18n - Añadido Locale Croata (#14360 by @danijelh) - Docs - Actualización del documento en francés para 2.6.1 y corrección de errores tipográficos (#14555 by @smalesys) - Actualización de la traducción al francés (#14643 by @smalesys) #### Corrección de errores - Input - Corregida regresión (#14572 by @wacky6) - DatePicker - Corrección del cálculo del primer día de la semana (#14523 by @sinchang) - Corregido el formato de valor del selector de semana (#13754 by @wacky6) - Steps - Corregida issue #14502 (#14596 by @sinchang) - Arreglado estilo con tema simple (#14610 by @sinchang) - Docs - Renombrada variable en documentos de Table (#14587 by @likwotsing) - Añadido índice de búsqueda en francés (#14565 by @iamkun) - Corrección del estilo de página TimePicker (#14579 by @ziyoung) - Renombrada variable en Upload docs (#14593 by @liupl) - Actualización de los documentos del Form async validator (#14694 by @iamkun) - Solucionado el error de tooltip doc (#14748 by @iamkun) - Corregido error tipográfico (#14751 by @2bj) - Corregido los elementos de control de resaltado para Webkit touch (#14703 by @VladG0r) #### Optimización - Chore - Actualización del script de construcción de ci (#14600 by @ziyoung) - Actualización ga tracking (#14560 por @iamkun) - Añadido más evento ga (#14633 by @iamkun) - Actualización del grupo de discusión (#14741 por @iamkun) - Actualización de los deps y conf de las pruebas (#14735 by @wacky6) - Actualización gulp (#14745 by @ziyoung) - Uso de codepen para mostrar la demo y corregir el error doc (#14747 por @ziyoung) ### 2.6.1 *2019-03-03* #### Corrección de errores - **Don't specify node version** (by @iamkun in #14546) - Corrección del directorio doc en `deloy-faas.sh` (by @ziyoung in #14553) - Arreglado el estilo de date en changelog para 2.6.0 (by @island205 in #14547) - Corregido error tipográfico en doc (by @wack6 in #14552) ### 2.6.0 *2019-03-01* #### Nuevas características - Timeline - Agregado componente timeline (by @jikkai in #14248) - DropdownItem - Añadida la prop icon a `el-dropdown-item` (by @gabrielboliveira in #14088) - Input - Añadida la prop show-password (by @phshy0607 in #13966) - Select - Añadido el slot `empty` (by @elfman in #13785) - Autocomplete - Añadida la prop highlight-first-item (by @YamenSharaf in #14269) - I18n - Locale Armenio creado (by @hamletbarsamyan in #14214) - Docs - Traducción al francés (by @smalesys in #12153, #14418, #14434) #### Optimización - Alert - Actualizada la descripción de Alert (by @iamkun in #14488) - Input - Actualizado input password (by @iamkun in #14480) - InputNumber - Removido parseFloat innecesario (by @JuniorTour in #14172) - Menu - Añadido soporte para `el-menu-item` sin índice (by @georgyfarniev in #13298) - Table - Eliminadas algunas operaciones DOM html (by @elfman in #13643) - Upload - Optimizado el código (by @elfman in #13973) - Popup - Optimizado el código (by @KAionro in #14413) - Docs - Se han agregado más detalles sobre cómo ejecutar el modo de play para contribuir (by @island205 in #14355) - Warn input como componente de control. (by @wacky6 in #14463) - Actualizacion de la documentacion de Table (by @luguokong in #14329) - Actualizacion de la documentacion de input (by @iamkun in #14437) - Actualizacion de la documentacion de custom-theme (by @wangguohao in #14297) - Se ha hecho que el icono cambie de estilo en hover (by @tuxinghuan in #14295) - Build - Minimización de css y js para la doc del sitio de Element (by @iamkun in #14430) - Aceleración de webpack (by @hetech in #14484) - Uso de cli para seleccionar la versión de lanzamiento (by @hetech in #14354) - Instalación de stale para el manejo de issues (by @island205 in #14392) #### Corrección de errores - Menu - Corregido el error de focus del submenú cuando se cambiaba la pestaña del navegador (by @liupl in #13976) - MessageBox - Corregida la definicion de type (by @NateScarlet in #14278) - ScrollBar - Prevenido el clic del botón derecho en la miniatura (by @xifeiwu in #14196) - Switch - Activación de la validación de formularios si el valor cambia (by @hetech in #14426) - Table - Se ha convertido el método toggleAllSelection en un método de instancia (by @letanure in #14075) - Tabs & Dropdown - Estilo arreglado (by @hetech in #14452) - Tree - Los tips de texto vacío son diferentes de las tablas (by @ColinCll in #14331) - Docs - Corregido el error de formato de la documentacion de DatetimePicker (by @iamkun in #14290) - Problema de ortografía en la documentación de datepicker (by @helmut in #14481) - Arreglado estilo doc de paginación (by @liuchuzhang in #14451) #### Breaking changes - Table - Cambiar el orden de los parámetros enviados en los eventos de las filas (by @jikkai in #12086) ### 2.5.4 *2019-02-01* #### Corrección de errores - Build: Se ha solucionado el problema de configuración de babel que provocaba que el efecto de transicion de collpase se rompiera (por @island205 en #14282) ### 2.5.3 *2019-01-31* #### Optimización - Optimización del código de Message (por @vok123 en #14029) - Retirada de gh-pages (por @ziyoung en #14266) - Añadido enlace IssueHunt (por @island205 en #14261) #### Corrección de errores - Corregido el error del módulo UMD en el lado del servidor (por @island205 en #14242) - Corregido el estilo activo de TabBar (por @iamkun en #14240) - Corregido el error de código de demo de la tabla (por @xunmeng en #14253) ### 2.5.2 *2019-01-27* #### Optimización - Docs: - Actualizacion ChangeLog ES 2.5.1 (by @Gonzalo2310 in #14231) #### Corrección de errores - Build: - Eliminar comentarios no borrados en el módulo umd `lib/index.js` (por @island205 en #14233) - Corregido el error de exportación disparado en el módulo commonjs usado en nuxt.js (por @island205 en #14232) - Corrección de problemas de compilación de 2.5.1 (por @iamkun en #14228) ### 2.5.1 *2019-01-26* #### Optimización - DatePicker: resalta el mes y año actual (por @Debiancc en #14211) - Actualizacion del changelog 2.5.0 (por @wacky6 en #14217) #### Corrección de errores - Arreglado el problema de exportación generado por la actualización de webpack (por @island205 en #14220) - Guardados los documentos 2.4.11 y la nueva subcarpeta para 2.5+ (por @iamkun en #14222) ### 2.5.0 *2019-01-25* #### Corrección de errores - Autocompletar - Corregida la última línea del menú desplegable que comenzaba recortada (#13597) (por @ziyoung) - Arreglada la popper arrow que faltaba (#13762) (por @liuchuzhang) - Carrusel - Contador de limpieza cuando el componente es destruido (#13820) (por @elfman) - Cascader - Retirada de los props computados obsoletos (#13737) (por @iamkun) - Se corrigió la definición de tipo de las opciónes de Cascader en TypeScript (#13613) (por @NateScarlet) - Corregido icono que cubre el texto (#13596) (por @ziyoung) - Checkbox - Refinado el estilo (por @PanJiaChen) - DatePicker - Añade el `key` en v-for de TimeSpinner (#13547) (por @Ende93) - Corregido el resaltado de la semana en el límite del año (#13883) (por @suyi91) - Input - Corregida la referencia del nodo DOM del textarea (#13803) (por @laomu1988 @island205) - Pagination - El valor de entrada no será menor que 1 (#13727) (por @elfman) - Popover - Corrección de problemas de popover con el disparador de hover (#13104) (por @goldengecko) - Corregido el fallo de memoria de instancia de popper (#13988) (por @qpxtWhite) - Radio - Refinado el estilo (por @ohhoney1) - Table - Mejorada la ordenación de tablas al hacer clic en la flecha de ordenación (#12890) (por @ohhoney1) - Solucionado el problema de alineación vertical de texto vacío en IE10+ (#13638) (por @imzjjy) - Corregida la documentación del tipo de índice (#13628) (por @ilovefafa) - Corrección del problema de visualización de `show-summary` cuando el encabezado multinivel tiene el attr fixed (#13914) (por @luckyCao) - Tabs - Corregido error de autodesplazamiento (#13696) (por @iamkun) - Obtener la tab correcta a través del nombre de tab (#13705) (por @iamkun) - Uso de paneName en lugar de name para determinar el estilo del panel (#13733) (por @iamkun) - Tree - Corregido que `showCheckbox` prop en `Tree` no puede afectar a los hijos `tree-node` (por @KidneyFlower) - Actualizado documento y archivo de definición (#13540) (por @ziyoung) - Upload - Agregada la prop `url` para subir el archivo cuando `list-type` cambia (#13771) (por @elfman) - Slider - Corrección de la sangría del código fuente (#13955) (por @wacky6) - I18n - Añadidas las traducciones de catalán que faltaban (por @jaumesala) - Añadidas las traducciónes de ruso que faltaban (#13658) (por @justlp) - Corrección de las traducciones al finés (#14137) (por @jenkrisu) - Doc - Actualización del documento 2.4.11 (#13522) (por @Gonzalo2310) - Otros - Eliminar scripts innecesarios (por @ziyoung) - Corregido el error de anchor link (#13753) (por @iamkun) - Corrección de la capitalización inconsistente en la documentación (por @wonderjar) - Añadido código qr del grupo de chat DingDing al readme (by @iamkun in #13957) - Añadido logs de hilo a .gitignore (#13922) (por @mimimi) - Eliminada la cuota de patrocinadores (#14156) (por @island205) - Actualizado readme qr code src (#13960) (por @iamkun) - Actualizado enlace CDN, corregido error tipográfico (por @ziyoung) ### 2.4.11 *2018-11-21* - Revertido pr #13296. Arreglado que al hacer clic fuera del Menú causaba que el Submenú colapsara, #13478 - Ajustados los media query breakpoints de las pantallas pequeñas (xs), #13468 (por @alekoshen712) ### 2.4.10 *2018-11-16* - Se corrigio que se necesitaban varios clics en Select para mostrar la lista desplegable, #13268 - El icono de limpiado para el input no se muestraba cuando Form estaba deshabilitado, #13208 - Ajustados los estilos de Select, Progress, Autocomplete, Tooltip, Collaspe, TimePicker, #13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen) - Se agregó el atributo `loop` al componente carrusel, #13217 - Cuando los datos de Table cambian, la línea resaltada permanecerá, #13200 - Table header scoped slot puede recibir parámetros, #13263 - El método `clearFilter` de la tabla soporta argumentos, #13176 - El tooltip ya no se crea cuando no hay contenido en la celda de Table, #13152 (por @rongxingsun) - El contenido del input del panel ColorPicker se muestra correctamente, #13278 - ColorPicker ya no activa la validación de formularios al arrastrar, #13299 - InputNumber se le ha añadido el método `select`, #13286 (por @st-sloth) - Autocompletar agregó el evento `clear`, #12171(by arthurdenner) #13326 - Puede cerrar Menú haciendo clic fuera del Menú, #13296 - El método `validateField` de Form puede recibir argumentos, #13319 - Cascader añadió el evento `visible-change`, #13415 - DatePicker agregó slot para separador de rango, #13272 (por @milworm) - Tree añade las propiedades `iconClass` y `currentNodeKey`, #13337 #13197 (por @isnifer) - Progress permite texto en el atributo `status` #13198 (por @ali-master) - Corregidas las `defaultCheckedKeys` de Tree que causaba un error, #13349 (por @dive2Pro) ### 2.4.9 *2018-10-26* - El parámetro de Form's `clearValidate` soporta cadenas, #12990 (by @codinglobster) - Se agregó el atributo `type` para Badge, #12991 - Ser puede usar scoped-slot para personalizar el encabezado de la columna de Table #13012 (por @ivanseidel) - Arreglado que el input box de Select no se podia escrbir en IE, #13034 (by @GaliMU) - La opción Seleccionar no se cerraba cuando el espacio era insuficiente, #12329 (by @akki-jat) - Cuando se expande la lista desplegable de Seleccionar, el icono de flecha también se mostrará correctamente, #12353 (by @firesh) - Arreglado que el atributo size de Select no funcionaba, #13070 - Select multiple values pueden ser limpiado en lote, #13049 (by @ZSkycat) - Arreglado el último TabNav que no se podía borrar, #13039 - Arreglado que la etiqueta del TabNav no se mostraba correctamente, #13178 - Añadido title slot para Alert, #13082 (by @Kingwl) - Corregido un problema por el cual el contenido del tooltip en Table era incorrecto, #13159 (by @elfman) - Optimizada la animación de Upload cuando el archivo es eliminado, #12987 - Ajustado el estilo de InputNumber cuando no se muestra el botón de control, #13052 ### 2.4.8 - No se muestra el contorno cuando Switch está enfocado, #12771 - Arreglado el estilo del Dropdown en ButtonGroup, #12819 (por @bluejfox) - Añadido evento opened para Dialog, #12828 - Corregido el orden incorrecto de visualización de TabNav, #12846 - Corregido el problema de que Tabs no se desplazaba a la pestaña seleccionada, #12948 - Corregido el problema de que el identificador no se mostraba cuando se arrastraba el Tree node, #12854 - El parámetro validar evento de Form contiene el mensaje de validación, #12860 (por @YamenSharaf) - Se ha corregido el DatePicker que no verificaba la validez de la hora de entrada del usuario, #12898 - Arreglado el problema de que el atributo `render-header` del encabezado de Table no funcionaba, #12914 ### 2.4.7 *2018-09-14* - Corregido que DatePicker no activaba la validación del Form, #12328 #12348 - Corregidos el lanzamiento de errores del DatePicker en modo múltiple, #12347 - Corregida la posición incorrecta del spinner del DatePicker, #12415 (por @rang-ali) - Se ha corregido el llenado automático del input del DatePicker, #12521 (por @abdallanayer) - Corregida el input no resaltada en Cascader, #12341 - Corregido el orden incorrecto de Tabpane, #12346 - Corregida la posición incorrecta del cursor de ColorPicker, #12376 (por @cnwhy) - Corregido el estilo del Submenú, #2457 - Corregido el resaltado después de seleccionar el Submenú, #12479 - Corregidos los valores incorrectos seleccionados por Cascader, #12508 (por @huangjinqiang) - Corregido el valor incorrecto del input de Paginación, #12525 - Se ha corregido el orden en que la paginación desencadena los eventos, #12530 - Corregido que no se mostraba el Table Filter, #12539 - Corregido Tree que era incapaz de borrar nodos, #12684 - Corregida la altura de los Select Input que cambiaba en modo simple, #12719 - Arreglado el estilo de la etiqueta FormItem en Form anidado, #12748 - Añadido el atributo `autocomplete` para Input, obsoleto `auto-complete`, #12514 (por @axetroy) - Añadido el slots-scope de Form para mostrar la información de validación, #12715 (por @YamenSharaf) ### 2.4.6 *2018-08-09* - Arreglada la tabla que no mostraba el ícono del filtro cuando a `filter` se les asignaba un array vacío, #12165 - Arreglado Menu que no guardaba el estado activo cuando cambiaba `collapse` #12178 (por @elfman) - Se ha corregido que Cascader no escapaba a los caracteres especiales para Regexp, #12248 - Se ha corregido que el RadioBotón deshabilitado mostraba la sombra de la caja cuando se hacía clic, #12262 - Arreglado el efecto de la tecla de flecha en Select cuando el valor por defecto es `undefined`,#12322 - Corregida la función de consulta de Select not debounced en modo multi, #12181 - Corregida que la palabra clave de consulta de Select desaparecía en modo multi, #12304 - Corregido el ancho incorrecto de Dialog cuando se muestra a pantalla completa, #12203 - Corregida la visualización incorrecta de Main en IE, #12237 - Corregido el trigger de Input con dos validaciones de Form, #12260 - Arreglado el añadir un nuevo nodo de árbol que causaba que los nodos desaparecieran, #12256 - Arreglado el nodo Tree no se borraba después de arrastrar, #12279 - Popover corregido porque no era visible cuando InputNumber no enfocaba, #12284 - Añadido el atributo `popper-append-to-body` para Autocompletar, #12241 - Añadido el modificador `sync` para el atributo `page-size` de Pagination, #12281 ### 2.4.5 *2018-07-26* - Se ha corregido en Table que `class-name` no funcionaba para las columnas `expand`, #12006 - Se ha añadido el método `toggleAllSelection` para Table, #12047 - Corregida la posición incorrecta del `suffix slot` cuando Input contiene Select, #12108 - Corregido que el `line-height` de Option no se establecia, #12120 - Corregido que TimeSelect con valor por defecto `null` no podia ser asignado después de ejecutar `resetField`, #12010 - Arreglado el evento `keydown` que cuando no era una tecla de flecha no funciona en Tree, #12008 - Corregido nodo padre checked en modo lazy, #12106 - Añadido el parámetro `includeHalfChecked` para getCheckedNodes de Tree, #12014 ### 2.4.4 *2018-07-13* - Corregido que se disparaba la validacion del Select después de reajustar el formulario, #11837 - Corregida la posición incorrecta del slot Input `suffix` cuando se usaba el slot `suffix` con el slot `append` , #11951 - Corregido el clearable Input que muestraba el icono de borrado cuando era readonly, #11967 - Arreglado el nodo Tree checked cuando estaba disabled, #11847 - Corregido que `default-checked-keys` no funcionaba en Tree, #11971 - Corregido que el `empty-text` no era visible cuando el nodo Tree se filtraba, #11971 - Arreglada la posición de texto vacío sobredimensionado en Table, #11965 - Corregido que la fila de la tabla no se modificado el resaltado cuando `current-row-key` era asignada a null, #11866 - Arreglado que mostraba el filtro del dropdown cuando los filtros eran un array vacío, #11864 - Corregido que el cambio de label de Radio no detenia propagacion de eventos, #11912 ### 2.4.3 *2018-07-03* - Corregido `allow-drop` que no funcionaba correctamente cuando los nodos de árbol tenian una altura personalizada, #11797 - Ahora puede pasar un parámetro al método `clearValidate` de Form, especificando qué resultados de validación de `FormItems` necesita borrar, #11821 - Añadido el atributo `distinguishCancelAndClose` para MessageBox, #11831 ### 2.4.2 *2018-06-26* - Ahora el `class-name` y el `label-class-name` de la tabla son reactivos, #11626 - Arreglado que Table seguia resaltando la fila en la que se había hecho clic cuando `highlight-current-row` era `false`, #11646 - Corregido un error de estilo de ButtonGroup cuando sólo habia un botón `round` o `circle`, #11605 - Arreglado estilo del tamaño de página del Select de Pagination, #11622 - Corregido un error del método `open` de los Menús cuando se cambiaba dinámicamente `collapse`, #11646 - Añadidos los parámetros `activeName` y `oldActiveName` al gancho before-leave de Tabs, #11713 - Arreglado el focus en Cascader después de hacer clic fuera, #11588 - Arreglado que Cascader no se cerraba cuando se hacia clic en la opción estando `change-on-select` como `true`, #11623 - Ahora la actualización del valor de Select programáticamente activará la validación de formulario, #11672 ### 2.4.1 *2018-06-08* - Removida la declaración duplicada de type en Autocompletar, #11388 - Corregido el estilo de flecha en el dropdown de Select en FireFox cuando se anidaba en el formulario, #11427 - Corregido que el ícono `clear` de Select seguia apareciendo cuando el valor inicial era `null`, #11460 - Arreglado que cuando el radio estaba `disabled` mostraba el box-shadow al hacer click, #11462 - Añadido el atributo `iconClass` para MessageBox, #11499 - Añadido el atributo `stretch` para Tabs, #11476 - Arreglado el problema de orden de renderizado de TabPane cuando Tabs es `lazy`, #11461 - Arreglado que Table no retenia la fila actual de resaltados cuando se expandia, #11464 - Arreglado que focusing state cuando `before-leave` devolvia una promesa resuelta, #11386 - Arreglado que Popover deshabilitado seguia creando poppers, #11426 - Arreglado el bucle sin fin de Tree cuando se añadia un nuevo nodo en modo `lazy`, #11430 (por @wangjingf) - Añadido el evento `closed` para Dialog, #11490 ### 2.4.0 Fullerene *2018-05-28* #### Nuevas características - Generalidades - La herramienta de desarrollo y el empaquetador se cambiaron a webpack nativo, #11216 - Ahora puede configurar globalmente el z-index inicial de los popups, #11257 - Autocomplete - Añadido el atributo `hide-loading`, #11260 - Button - Ahora se puede usar el atributo `size` en los botones circulares para controlar sus tamaños, #11275 - InputNumber - Añadido el atributo `precision`, #11281 - Tabs - Añadido el atributo `before-leave`, #11259 - Añadido el atributo `lazy`, #11167(by @Kingwl) - Table - Añadido el método `sort` para ordenar manualmente la tabla, #11311 #### Corrección de errores - Input - Se ha corregido un problema que provocaba que se volviera a procesar al utilizar el IME chino para introducir texto rápidamente, #11235 (por @STLighter). - Popover - Corregido el error de la consola cuando el elemento disparador es Radio o Checkbox, #11265 - Breadcrumb - Arreglado el atributo `to` que no soportaba la actualización dinámica, #11286 - Upload - Corregido el error de la consola cuando se resolvia el Archivo en la Promesa devuelta del método `beforeUpload`, #11297 (por @qusiba) - Tooltip - Solucionado que la flecha no se posicionaba correctamente cuando el contenido estaba vacío, #11335 - Autocompletar - Corregido que las sugerencias de entrada eran incorrectas después de eliminar la palabra clave rápidamente, #11323 - ColorPicker - Corregido el evento `active-change` que se disparaba incorrectamente cuando el menú desplegable del picker estaba cerrado, #11304 - Table - Corregido el error de estilo del panel de filtro cuando se sobredimensionaba, #11314 - Corregida que la fila seleccionada actualmente no se retenia cuando se ordenaba la tabla, #11348 - CheckBox - Arreglado que cuando el checkbox era único no soportaba validación, #11271 - Radio - Arreglado que el Radio desactivado seguia estando seleccionada cuando se pulsaba la tecla espaciadora, #11303 - MessageBox - Corregida la clase `el-popup-parent--hidden` que no se eliminaba al abrir MessageBox sucesivamente, #11371 ### 2.3.9 *2018-05-18* - Corregido que cuando los datos de origen no tenian el campo especificado por el atributo `prop` de una TableColumn, se producía un error al moverse el ratón dentro de las celdas de esa columna, #11137. - El atributo `lockScroll` de los componentes pop-up ya no añade un inline style al elemento padre, sino que añade un nombre de clase, #1111114. - Arreglado el icono de Progreso que no se mostraba cuando su `status` era `exception`, #11172 - El atributo `disabled` no funcionaba en la lista de resultados del filtro de Cascader, #11185 - Se ha corregido un problema por el que la fila expandida de la Tabla no se podía contraer si los datos de origen se actualizaban después de su expansión, #11186. - `setCurrentKey` de Tree ahora acepta `null` como parámetro para cancelar el nodo actualmente resaltado, #11205 ### 2.3.8 *2018-05-11* - Corregido que el panel DatePicker saltaba al mes actual después de escoger una fecha en un mes diferente cuando el tipo era `dates`, #10973 - Arreglado que el `clearable Input` seguía mostrando el icono de borrado cuando era sólo de lectura, #10912 - Arreglado que al cerrar el panel DatePicker sin modificar el valor se desencadenaba incorrectamente el evento `change`, #11017 - Arreglado que la navegación por el teclado no funcionaba correctamente cuando Select tenia opciones agrupadas, #11058 - Agregado el `slot named` `prefix` para Select, #11063 - Agregado el metodo `clearValidate` para FormItem, #11076 - Agregado el atributo `checkOnClickNode` para Tree, #11111 ### 2.3.7 *2018-04-29* - Corregido que Table no actualizaba el ancho de encabezado cuando la barra de desplazamiento desaparecia debido al filtrado, #10834 - Corregido input borrable que mostraba el icono de borrado cuando su valor inicial era `nulo`, #10912 - Corregido el disparador incorrecto del evento `active-change` después de cambiar el valor enlazado de ColorPicker programáticamente, #10903 (por @zhangbobell) - Corregido filterable Select que causaba un bucle infinito al navegar por las opciones usando el teclado si todas las opciones estában deshabilitadas, #10945 ### 2.3.6 *2018-04-21* - Corregido el comportamiento incorrecto del callback `allow-drop` de Tree cuando se usaba el parámetro `type`, #10821 - Ahora puede introducir correctamente las palabras clave en filterable Single Select en IE11, #10822 - Corregido Single Select activaba incorrectamente el evento `blur` después de hacer clic en una opción, #10822 ### 2.3.5 *2018-04-20* - Arreglado los incorrectos realces en el panel de DatePicker cuando `type` es week, #10712 - Arreglado que InputNumber comenzaba vacio cuando el valor inicial era 0, #10714 - Agregado el atributo `automatic-dropdown` para Select, #10042 (by @Seebiscuit) - Arreglado que el valor del Rate pasaba a `disabled` cuando se comenzaba a actualizar con las teclas de navegacion, #10726 (by @Richard-Choooou) - Ahora el atributo `type` de DatePicker's puede ser `'dates'`, donde puede elegir varias fechas en un solo picker, #10650 (by @Mini256) - Agregados los eventos `prev-click` y `next-click` para Pagination, #10755 - Agregado el atributo `pager-count` para Pagination, #10493 (by @chongjohn716) - Agregado `type` como 3rd parametro del atributo `allow-drop` de Tree, #10792 - Ahora usamos ResizeObserver para detectar el redimensionamiento de elementos DOM, #10779 ### 2.3.4 *2018-04-12* - Eliminado el atributo duplicado `showTimeout` en SubMenu's en la declaracion TypeScript, #10566 (by @kimond) - Ahora se puede personalizar los datos de los items de Transfer usando scoped slot, #10577 - Arreglado que los click de los botones `next` y `prev` en Pagination se deshabilitaban cuando se disparaba el evento `current-change`, #10628 - Arreglado que Textarea mostraba `undefined` en SSR cuando el valor no era asignado, #10630 - Arreglado que se deshabilitaba el estilo del TabItem cuando `type` era border-card, #10640 - Agregado `$index` como cuarto parametro en el atributo de las columnas de Table `formatter` , #10645 - Arreglado que CheckboxButton no se exportaba en la declaracion de TypeScript, #10666 ### 2.3.3 *2018-04-04* - Agregar atributo `shadow` para Card, #10418 (by @YunYouJun) - Se ha corregido el error de ocultar Badge cuando `value` es `0`, #10470 - Arreglados algunos bugs del draggable Tree, #10474 #10494 - Agregado `placement` para Autocomplete, #10475 - Ahora el atributo `default-time` también funciona en un rango que no es el rango DateTimePicker, #10321 (by @RickMacTurk) - Eliminado el contorno azul de TabItem después de que el navegador se desdibuja o se minimiza, #10503 - Agregado el atributo `popper-append-to-body` para SubMenu, #10515 - Eliminado el feedback visual cuando se desplaza sobre non-link BreadcrumbItem, #10551 - Se ha corregido el evento `change` de InputNumber para garantizar que el valor de ligado del componente se actualiza en el control de eventos, #10553 ### 2.3.2 *2018-03-29* - Arreglada una regresión de Autocompletar, #10442 ### 2.3.1 *2018-03-29* - Se ha corregido una regresión por la que el `type` de input no se transmitia al elemento de entrada nativo, #10415 - Agregado el metodo `blur` para Select, #10416 ### 2.3.0 Diamond *2018-03-28* #### Nuevas características - Table - Ahora `formatter` de TableColumn puede ser actualizado dinámicamente, #10184 (by @elfman) - Agregado el atributo `select-on-indeterminate`, #9924 (by @syn-zeta) - Menu - Agregado el atributo `collapse-transition`, #8809 (by @limichange) - Input - Agregado el metodo `select` , #10229 - Agregado el metodo `blur`, #10356 - ColorPicker - Agregado el atributo `predefine`, #10170 (by @elfman) - Tree - Agregados los atributos `draggable`, `allow-drop` y `allow-drag`, y los eventos `node-drag-start`, `node-drag-enter`, `node-drag-leave`, `node-drag-over`, `node-drag-end` y `node-drop`, #9251 #10372 (by @elfman) - Form - El metodo `validate` ahora acepta un segundo parametro, que contiene información de los ítems del formulario que no superaron la validación, #10279 - Agregado el evento `validate`, #10351 - Progress - Agregado el atributo `color`, #10352 (by @YunYouJun) - Button - Agregado el atributo `circle`, #10359 (by @YunYouJun) #### Bug's arreglados - Form - Solucionado: Label del FormItem no se alineaba adecuadamente con Input mixto, #10189 - Menu - Ahora collapsed Menu sólo mostrará el Tooltip cuando el slot `title` de MenuItem esté configurado, #10193 (by @PanJiaChen) - Pagination - Corregido el evento `current-change` que se disparaba erróneamente sin interacción del usuario, #10247 - DatePicker - Ahora la fecha y la hora en el panel desplegable están correctamente formateadas según el atributo `format`, #10174(by @remizovvv) - Upload - Solucionado el atributo `accept` no trabajaba cuando `drag` era true, #10278 ### 2.2.2 *2018-03-14* - Agregado el evento `clear` para Input, #9988 (by @blackmiaool) - Ahora la entrada manual de ColorPicker soporta los modos `hsl`, `hsv` y `rgb`, #9991 - Arreglado DatePicker no desencadenaba el evento `change` cuando se borraba su valor inicial, #9986 - Ahora la clase de iconos relacionadas con los atributos de Rate soporta actualizaciones dinamicas, #10003 - Arreglado Table que con columnas `fixed` no actualizaban correctamente su altura si se fijaba `max-height`, #10034 - Ahora DatePicker en modo rango admite la selección inversa (haciendo clic en la fecha final y, a continuación, haciendo clic en la fecha de inicio), #8156 (by @earlymeme) - Agregado el atributo `disabled` para Pagination, #10006 - Agregados los eventos `after-enter` y ` after-leave` para Popover, #10047 - Arreglado Select no disparaba validación cuando el usuario seleccionaba una opción después de ejecutar `resetFields` de Form, #10105 - Arreglado anchos incorrectos de columnas fijas de Table en algunos casos, #10130 - Corregido MessageBox heredaba el atributo `title` de su instancia anterior cuando se llamaba sin `title`, #10126 (by @Pochodaydayup) - Agregado el atributo `input-size` para Slider, #10154 - Agregados los eventos `left-check-change` y `right-check-change` para Transfer, #10156 ### 2.2.1 *2018-03-02* - Corregido Aside, Header y Footer que se contraia en algunos layout, #9812 - Corregido Table con un atributo `height` no renderizaba en SSR, #9876 - Corregido Table con fila expandible no calculaba la altura cuando la fila era expandida, #9484 - Corregido que cuando se escribia la fecha de forma manual en DateTimePicker no se disparaba el evento `change`, #9913 - Corregido que Select mostraba sus opciones cuando se hacia click con el botón derecho del mouse en el Input, #9894 (by @openks) - Agregado el atributo `tooltip-class` para Slider, #9957 - Ahora Select permanecera enfocado despues de la selección, #9857 (by @Seebiscuit) - Agregado el atributo `target-order` para Transfer, #9960 ### 2.2.0 Graphite *2018-02-12* #### New features - Menu - Agregados los atributos `popper-class` y `disabled` para SubMenu, #9604 #9771 - Menu Horizontal ahora soporta SubMenu multi-capas, #9741 - Tree - Agregado el evento `node-contextmenu`, #9678 - Ahora se puede personalizar el template del nodo usando scoped slot, #9686 - Agregados los metodos `getNode`, `remove`, `append`, `insertBefore`, `insertAfter`, `getCheckedKeys`, `getHalfCheckedNodes`, `getHalfCheckedKeys` y el evento `check`, #9718 #9730 - Transfer - Agregado el metodo `clearQuery`, #9753 - Select - Agregado el atributo `popper-append-to-body`, #9782 #### Bug fixes - Table - Corregido el icono de expansión de una fila expandible que al hacer click activaba el evento `row-click`, #9654 - Corregido el layout que no se actualizaba cuando el ancho de columna era cambiado por el usuario arrastrando, #9668 - Corregido problema de estilo cuando la fila de resumen coexistia con columnas fijas, #9667 - Container - Corregido componentes del Container que no se estiraban en IE11, #9655 - Loading - Corregido Loading no se mostraba cuando el valor de `v-loading` era cambiado a true en el `hook` `mounted`, #9722 - Switch - Corregido se disparaban los dos eventos nativos de click cuando se hacia click en el Switch, #9760 ### 2.1.0 Charcoal *2018-01-31* #### New features - Cascader - Agregados los eventos `focus` y `blur`, #9184 (by @viewweiwu) - Table - El `filter-method` ahora tiene un tercer parámetro `column`, #9196 (by @liyanlong) - DatePicker - Agregados los atributos `prefix-icon` y `clear-icon`, #9237 (by @AdamSGit) - Agregado el atributo `default-time`, #9094 (by @nighca) - `value-format` ahora soporta `timestamp`, #9319 (by @wacky6) - InputNumber - Ahora el valor vinculado puede ser `undefined`, #9361 - Select - Agregado el atributo `auto-complete`, #9388 - Form - Agregado el atributo `disabled`, #9529 - Agregado el atributo `validateOnRuleChange`, #8141 - Notification - Agregado el metodo `closeAll`, #9514 #### Bug fixes - InputNumber - Arreglado el reseteo del valor cuando tiene punto decimal, #9116 - Dropdown - Arreglado el dropdown menu que tenia un posicionamiento incorrecto cuando la página sólo tiene una barra de desplazamiento horizontal en algunos navegadores, #9138 (by @banzhuanmei) - Table - Corregido un error en el cálculo del número de columnas fijas después de que los datos de la columna cambian, #9188(by @kolesoffac) - Corregido el borde de la última columna de la cabecera agrupada que no se visualizaba correctamente., #9326 - Corregido el posicionamiento incorrecto del header de la tabla en Safari, #9327 - Corregido fila expandida colapsaba cuando cambiaban los datos de la tabla, #9462 - Corregido renders múltiples innecesarios en algunas condiciones, #9426 - Corregido un error de calculo en el ancho de la columna cuando `width` cambiaba en TableColumn, #9426 - Loading - Corregido que en algunas ocasiones el loading no se ocultaba correctamente, #9313 - DatePicker - Corregido el metodo `focus` que no funcionaba en modo `range`, #9437 - Corregido si se hacia clic en el botón "now" seguia seleccionando la fecha actual aunque estuviera desactivado, #9470 (by @wacky6) - Corregido fijación de fechas al navegar, #9577 (by @wacky6) - Steps - Corregido error de estilos en IE 11, #9454 #### Breaking changes - Menu - El menú desplegable en modo `collapse` ahora se agrega directamente al `body`, de modo que es visible cuando está anidado en Aside, #9263 - Table - Ahora, al marcar los checkboxes en la Tabla de selección múltiple no se activa el evento `row-click`, #9467 - Loading - El `z-index` de la máscara de carga non-fullscreen se cambia a 2000. El `z-index` de la máscara de carga fullscreen se actualiza dinámicamente con los componentes emergentes, #9522 - Dropdown - Los atributos `show-timeout` y `hide-timeout` ahora solo trabajan si se dispara `hover`, #9573 ### 2.0.11 *2018-01-08* - Corregido el problema de color del borde del Select cuando está el slot `prepend` o `append` del Input, #9089 - Corregido el parámetro `remove-tag` de Select, #9090 - Añadido los atributos `show-timeout` y `hide-timeout` para SubMenu, #8934 (por @HugoLew) - Corregido el estilo de Tooltip de `show-overflow-tooltip` que faltaba cuando Table era importada bajo demanda, #9130 - Se ha corregido el mal funcionamiento de ordenación de la columna de Table despues que `clearSort` era ejecutado en esa columna, #9100 (por @zEmily) - El fichero de configuración i18n para el checo se renombra de `cz` a `cs-CZ`, #9164 ### 2.0.10 *2017-12-29* - Corregido el calculo incorrecto de la altura máxima de Table cuando fixed column y summary row coexisten, #9026 - Solucionado el estilo de color que no lo compilaba para textos vacíos en Table, #9028 - Ahora DatePicker sólo emite el evento `change` cuando el valor cambia verdaderamente, #9029 (by @remizovvv) - Añadido atributo `tabindex` para Input, #9041 (by @dicklwm) ### 2.0.9🎄 *2017-12-24* - Añadida la función de enganche (hook) `before-remove` para Upload, #8788 (by @firesh) - Arreglado el valor inicial de error que no funcionaba para FormItem, #8840 - Ahora la directiva Loading soporta nombre de clase personalizado asignando el atributo `element-loading-custom-class`, #8826 (por @earlymeme) - Arreglado CarouselItem que se ponía invisible cuando los datos eran actualizados asincrónicamente, #8921 - Añadido el atributo `renderAfterExpand` para Tree, #8972 ### 2.0.8 *2017-12-12* - Agregada la documentacion en español - Arreglado `show-timeout` de Dropdown que no funcionaba cuando se disparaba el click, #8734 (por @presidenten) - Arreglado el tiempo de validacion del Form cuando se disparaba el blur, #8776 - Arreglado el evento de perdida de foco (blur) del DatePicker por rangos, #8784 - `format` de TimePicker ahora soporta AM/PM, #8620 (por @firesh) ### 2.0.7 *2017-11-29* - Solucionado el estilo disabled en el texto de button, #8570 ### 2.0.6 *2017-11-29* - Corregido error de estilo de los iconos de ordenación de Table, #8405 - Corregido activacion para Popover cuando `trigger` es manual, #8467 - Añadidos los atributos `prefix-icon` y `suffix-icon` para Autocomplete, #8446 (por @liyanlong) - Añadido el atributo `separator` para Cascader, #8501 - Añadido atributo `clearable` para Input, #8509 (por @lbogdan) - Añadido atributo `background` para Pagination, #8553 ### 2.0.5 *2017-11-17* - Solucionado regresion en 2.0.4 de Popover, Tree, Breadcrumb and Cascader, #8188 #8217 #8283 - Solucionado Fuga de memoria de la directiva clickoutside, #8168 #8225 (por @badpunman @STLighter) - Solucionada la altura en multiple Select cuando se borra su valor, #8317 (por @luciy) - Añadido el atributo `collapse-tags` para multiple Select para reemplazar las tags con una línea de texto, #8190 - Solucionado el alto consumo de CPU causado por Table cuando esta oculta, #8351 - Ahora puede usar el método `doLayout` de Table para actualizar su diseño, #8351 ### 2.0.4 *2017-11-10* - Accesibilidad mejorada para Cascader, Dropdown, Message, Notification, Popover, Tooltip y Tree - Arreglado el cambio de tamaño del Container cuando el ancho de la vista disminuye, #8042 - Arreglado Tree's `updateKeyChildren` borraba incorrectamente los nodos hijos, #8100 - Arreglado la altura de los bordes de CheckboxBotón's cuando esta anidado en un Form, #8100 - Arreglado error de análisis de los Menu's para los colores personalizados, #8153 (por @zhouyixiang) ### 2.0.3 *2017-11-03* - Solucionado atributos `editable` and `readonly` de DatePicker de los rangos, #7922 - Corregido error de estilo de los Tabs anidados, #7941 - Corregido error de estilo del último Step de Steps verticales, #7980 - Corregido el tiempo de activación del evento `current-change` para Pagination, #7995 - Corregido Tooltip no registrado en el Menu, #7995 ### 2.0.2 *2017-10-31* - Ahora haciendo clic con el botón derecho del ratón en los botones de InputNumber no cambiará su valor, #7817 - El metodo `validate` de Form ahora puede esperar por validaciones asíncronas antes de ejecutar su devolución de llamada, #7774 (por @Allenice) - Corregido la selección de rango de DatePicker no funcionaba en los navegadores Chromium 53-57, #7838 - Corregido la perdida de previsualización e iconos de eliminar de Upload cuando su `list-type` es picture-card, #7857 - Añadido el atributo `sort-by` para TableColumn, #7828 (por @wangfengming) - Corregido que a veces DatePicker muestra un número de año incorrecto al seleccionar la primera semana en modo week, #7860 (por @hh23485) - Corregido error de estilo de icono de Step vertical, #7891 - El área hot para las flechas de nodo en Tree se expandia, #7891 ### 2.0.1 *2017-10-28* - Corregido error de estilo de RadioButton y CheckboxButton, #7793 - Corregido TimePicker no responde al desplazamiento del ratón en algunas condiciones, #7811 - Corregido estilos incompletos de algunos componentes cuando se importan bajo demanda, #7811 ### 2.0.0 Carbon *2017-10-27* #### New features - General - Un nuevo tema: `theme-chalk` - Se ha mejorado la accesibilidad de los siguientes componentes: Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload - Añadido tipografías TypeScript - Todos los iconos existentes son rediseñados. Se han añadido algunos iconos nuevos - Añadida una serie de clases de utilidades basadas en puntos de ruptura que ocultan elementos cuando el tamaño del viewport cumple ciertas condiciones - Componentes de diseño añadidos: Container, Header, Aside, Main, Footer. - Ahora puede configurar los tamaños de componentes a nivel global. Al importar Element, puede añadir un objeto de configuración global con un prop `size` para configurar tamaños predeterminados para todos los componentes. - Button - Atributo `round` añadido. Se usa para botones de esquinas redondas #6643 - TimeSelect - Ahora puede ser navegado por `Up` y `Down`, y presionando `Enter` selecciona la hora #6023 - TimePicker - Ahora puede ser navegado por `Up` y `Down`, y presionando `Enter` selecciona la hora #6050 - Añadido `start-placeholder` y `end-placeholder`. Son placeholder's para las dos casillas de input en modo range #7169 - Añadido el atributo `arrow-control` para hacer girar el tiempo con las flechas #7438 - Tree - Ahora los nodos hijo no se renderizan antes de la primera expansión #6257 - Añadido el atributo `check-descendants`. Determina si los nodos hijo se seleccionan al seleccionar su nodo padre en modo `lazy` #6235 - Tag - Atributo `size` añadido #7203 - Datepicker - Ahora `timeFormat` puede dar formato al TimePicker cuando type está configurado en `datetimerange` #6052 - Añadido `start-placeholder` y `end-placeholder`. Son placeholder's para las dos casillas de input en modo range #7169 - Atributo `value-format` añadido para personalizar el formato del valor enlazado, #7367 - Añadido el atributo `unlink-panels` para desacoplar los dos paneles de fechas al seleccionar un rango. - MessageBox - Añadido el atributo `closeOnHashChange` #6043 - Atributo `center` agregado para que el contenido pueda ser centrado #7029 - Añadido atributo `roundButton` para mostrar Botones redondeados #7029 - Añadido atributo `dangerouslyUseHTMLString`. Cuando está configurado en true, el mensaje será analizado como cadena HTML* #6043 - Añadido atributo `inputType` para asignar el tipo para el input interno, #7651 - Dialog - Añadidos los atributos `width`, `fullscreen`, `append-to-body`. Ahora Dialog puede ser anidado - Atributo `center` agregado para que el contenido pueda ser centrado #7042 - Añadidos `focus-after-closed`, `focus-after-open` para mejorar la accesibilidad #6511 - ColorPicker - Ahora puede escribir colores en el input #6167 - Añadidos atributos `size` y `disabled` #7026 - Añadido atributo `popper-class` #7351 - Message - Ahora el color de los iconos puede ser sustituido por CSS #6207 - Añadido atributo `dangerouslyUseHTMLString`. Cuando está configurado en true, el mensaje será analizado como cadena HTML* #6207 - Atributo `center` agregado para que el contenido pueda ser centrado #6875 - Notification - Añadido atributo `position` para configurar donde aparece Notification #6231 - Añadido atributo `dangerouslyUseHTMLString` . Cuando está configurado en true, el mensaje será analizado como cadena HTML* #6231 - Añadido el atributo `showClose` para ocultar el botón de cierre #6402 - Rate - Añadido el atributo `show-score` para determinar si la puntuación actual se muestra #6295 - Tabs - Añadido el atributo `tab-position` #6096 - Radio - Añadidos los atributos `border` y `size` #6690 - Checkbox - Añadidos los atributos `border` y `size` #6690 - Alert - Atributo `center` agregado para que el contenido pueda ser centrado #6876 - Menu - Añadidos los atributos `background-color`, `text-color` y `active-text-color` #7064 - Añadidos los methods `open` and `close` para abrir y cerrar los SubMenu con programación, #7412 - Form - Añadido el atributo `inline-message` para determinar si el mensaje de validación se muestra inline #7032 - Añadido el atributo `status-icon` para mostrar un icono de retroalimentación cuando se valida #7032 - Form y FormItem ahora tienen un atributo `size`. Los componentes internos heredarán este tamaño si no se especifica en ellos mismos, #7428 - Método `validate` devolverá ahora una promesa si se omite la llamada de retorno, #7405 - Añadido método `clearValidate` para limpiar los resultados de las validaciones de todos los form items, #7623 - Input - Añadido slots con nombres `suffix` y `prefix` y atributos `suffixIcon` y `prefixIcon` para añadir contenido dentro del input #7032 - Breadcrumb - Añadido el atributo `separator-class` para dar soporte a los iconos como separadores de items #7203 - Steps - Añadido atributo `simple` para activar Steps de estilo sencillo #7274 - Pagination - Añadidos los atributos `prev-text` y `next-text` para personalizar los textos de la página anterior y de la página siguiente #7005 - Loading - Ahora usted puede personalizar el ícono del spinner y el color de fondo con los props `spinner` y `background` , #7390 - Autocomplete - Añadido atributo `debounce`, #7413 - Upload - Añadidos los atributos `limit` and `on-exceed` para limitar la cantidad de archivos, #7405 - DateTimePicker - Añadido el atributo `time-arrow-control` para activar `arrow-control` del TimePicker anidado, #7438 - Layout - Añadido un nuevo breakpoint `xl` para viewport más ancho que 1920px - Table - Añadido el atributo `span-method` para combinar celdas - Añadido el método `clearSort` para borrar la clasificación programáticamente - Añadido el método `clearFilter` para limpiar el filtro de forma programática - Para las filas ampliables, cuando se amplía una fila, se añadirá una clase `.expanded` a su lista de clases, para que pueda personalizar su estilo. - Atributo de `size` añadido - Añadido el método `toggleRowExpansion` para expandir o contraer filas expandibles programáticamente. - Añadido el atributo `cell-class-name` para asignar el nombre de la clase para las celdas - Añadido atributo `cell-style` para dar estilo a las celdas - Añadido atributo `header-row-class-name` para asignar el nombre de clase para las filas de encabezado. - Añadido un atributo `header-row-style` para el estilo de encabezado - Añadido el atributo `header-cell-class-name` para asignar el nombre de la clase para las celdas de encabezado. - Añadido el atributo `header-cell-style` a las celdas de encabezado de estilo - El atributo prop de TableColumn ahora acepta las notaciones `object[key]` - Atributo de `index` añadido para TableColumn para personalizar índices de filas - Select - Añadido el atributo `reserve-keyword` para reservar la palabra clave de búsqueda actual después de seleccionar una opción. #### Bug fixes - DatePicker - Arreglado `v-model` que devolvia el segundo día de la semana seleccionada en modo week #6038 - Arreglado el primer input comenzaba borrado con el type `daterange` #6021 - DateTimePicker - Arreglado DateTimePicker y TimePicker que se afectaban entre sí cuando se seleccionaban #6090 - Arreglado la hora y el segundo podian estar más allá del límite al seleccionar el tiempo #6076 - TimePicker - Arreglado `v-model` que no se actualizaba correctamente cuando no tenia el foco #6023 - Dialog - Arreglado textos que tenian bordes borrosos al abrir y cerrar dropdowns anidados #6088 - Select - Rendimiento mejorado. Ahora Vue dev-tool no se bloqueará cuando un gran número de Selects sean destruidos #6151 - Table - Corregido un bug de Table permanecía oculto cuando su elemento padre tenia el atributo `display: none` - Arreglado Table ahora amplia su ancho cuando el elemento padre tiene `display: flex` - Arreglado un bug que corregía las columnas de una tabla con slot con nombre `append` que desaparecia cuando los datos eran recuperados dinámicamente. - Arreglado el atributo `expand-row-keys` que no funcionan con el valor inicial - Fallo del filtro corregido al actualizar los datos - Se ha corregido un error de cálculo de la disposición de columnas fijas con cabeceras agrupadas. - Corregido un error de `max-height` dinámico - Corregidos algunos errores de cálculo de estilo #### Breaking changes - General - Eliminado `theme-default` - Compatible con Vue 2.5.2+ e IE 10+ - Evento `change` de componentes del formulario y evento `current-change` de Pagination ahora sólo se activa en la interacción del usuario. - El atributo `size` del botón y los componentes del formulario aceptan ahora los tamaños `medium`, `small` y `mini`. - Para facilitar el uso de iconos de terceros, los atributos `icon` de Button y Steps y los atributos `prefix-icon` y `suffix-icon` del input ahora requieren un nombre de clase completo. - Dialog - Atributo `size` eliminado. Ahora el tamaño de Dialog se puede configurar con `width` y `fullscreen` - Ahora la visibilidad del Diálogo no puede ser controlada por `v-model` - Rate - `text-template` a sido renombrado a `score-template` - Dropdown - `menu-align` a sido renombrado a `placement`. Ahora soporta más posiciones - Transfer - `footer-format` a sido renombrado a `format` - Switch - Los atributos que comienzan con `on*` serán analizados en eventos en JSX, haciendo que todos los atributos `on*` de Switch no puedan trabajar en JSX. Por lo tanto, los atributos `on*` se renombran a `active-*`, y por consiguiente los atributos `off-*` se renombran a `inactivado-*`. Este cambio afecta a los siguientes atributos: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value`. - Los atributos `active-text` y `inactive-text` ahora no tienen valores por defecto. - Tag - El atributo type acepta ahora `success`, `info`, `warning` y `danger` - Menu - Atributo `theme` eliminado. El color de Menu se puede configurar utilizando `background-color`, `text-color` y `active-text-color` - Input - Atributo `icon` eliminado. Ahora el icono del sufijo puede configurarse usando el atributo `suffix-icon` o el slot con nombre `suffix`. - Eliminado el atributo `on-icon-click` y el evento `click`. Ahora para añadir el manejador de clics en los iconos, por favor use los slots con nombre. - El evento `change` se comporta ahora como el nativo, que se activa sólo en la perdida del foco o presionando enter. Si necesita responder a las entradas de usuario en tiempo real, puede utilizar el evento `input`. - Autocomplete - Atributo `custom-item` eliminado. Ahora la plantilla de sugerencias del input se puede personalizar utilizando `scoped slot` - Atributo `props` eliminado. Ahora puede utilizar el atributo `value-key` para designar el nombre de la clave del objeto de sugerencia del input para su visualización. - Steps - Atributo `center` eliminado - Ahora Steps llenara su contenedor padre por defecto - DatePicker - Los parámetros del evento `change` de DatePicker son ahora el valor vinculante en sí mismo. Su formato es controlado por `value-format` - Table - Soporte eliminado para personalizar la plantilla de columnas mediante `inline-template` - `sort-method` ahora se alinea con `Array.sort`. Debería devolver un número en lugar de un booleano - El slot `append` se desplazo fuera del elemento `tbody` para evitar múltiples renderizados. - Evento `expand` se renombro a `expand-change` - Los parametros de los métodos `row-class-name` y `row-style` son ahora un objeto # # * El procesamiento dinámico de HTML arbitrario en su sitio web puede ser muy peligroso porque puede conducir fácilmente a [ataques XSS](https://en.wikipedia.org/wiki/Cross-site_scripting). Por lo tanto, cuando `dangerouslyUseHTMLString` está encendido, por favor asegúrese de que el contenido de `message` es confiable, y **nunca** asigne el `message` al contenido proporcionado por el usuario.`` ================================================ FILE: CHANGELOG.fr-FR.md ================================================ ## Changelog ### 2.15.14 *2023-08-24* #### Bug fixes - Img - Delete referrerpolicy prop (#22651 by @xinguanhua) #### Optimization - Docs - Update readme and website example links (#22642 by @lyfeyaj) - Update popper links (#22539 by @brizer) - I18n - Update translation of Spanish (#22430 by @jcardus) - Add sr-Latn translation (#22567 by @N-M) - Update Uzbek translation (#22390 by @akahon) - Statistics - Fix doc; Optimized code (#22384 by @webvs2) - Table - Add highlight selection row (#22382 by @wangdaodao) ### 2.15.13 *2023-02-12* #### Bug fixes - Docs - Fix Statistic docs (#22383 by @JUST-Limbo) - Fix Input docs (#22093 by @lm312) - Fix en-US docs (#22268 #22269 #22270 by @Hazel-Lin) - Fix Pagination docs (#22288 by @xujintai123) - Fix: Links docs (#22370 by @itmier) - Statistics - fix slot display bug (#22375 by @webvs2) - Chore - missing web-type after publishing (#22271 by @loosheng) #### Optimization - InputNumber - Fix touch one click trigger twice on the window touch pad (#22185 by @mrsai) - Image - Add initialIndex prop (#22346 by @inkroom) - Statistics - Updated countdown feature to localize lodash Closes (#22260 by @webvs2) - Update code and doc (#22276 by @webvs2) - Other - fix web-types type props (#22281 by @whzxc) ### 2.15.12 *2022-11-16* #### Bug fixes - Statistic: - Fixed the thousandth bit bug (#22252 by @webvs2) - Other - Fix 2.15.11 element-theme-chalk publish fail bug ### 2.15.11 *2022-11-15* #### Bug fixes - Docs - Fix Radio docs (#22178 by @bchen1029) - Fix Progress docs #### Optimization - I18n - Update translation of Malaysian (#22185 by @z4q) - Update translation of Norwegian (#22145 by @Barsnes) - Progress - Add defineBackColor and textColor prop (#22089 by @lm312) - Statistics - Add new component Statistics (#22159 by @webvs2) - Other - Add Web Types to improve code assistance in WebStorm IDE and other JetBrains IDEs (#22135 by @piotrtomiak) ### 2.15.10 *2022-09-13* #### Bug fixes - DatePicker - Fix props placement error (#21908 by @lqzhgood) - Loading - Fix sticky DOM error (#22087 by @zzjjhh001) - Docs - Fix Popover docs (#22083 by @lm312) - Fix Skeleton docs (#22092 by @lm312) - Fix DatePicker docs (#21970 by @guojiongwei) - Tree: - fix lazy-load default check problem (#21934 by @kiss-yu) #### Optimization - I18n - Add translation of Sinhalese (#21936 by @sayuri-gi) - Update translation of Spanish (#21924 by @jcardus) - Add translation of Malaysian (#22028 by @iorange0411) - Update translation of Swahili (#21904 by @Cholowao) - Utils - update date-util.js (#22099 by @Due07) - DatePicker - add months And years type (#21918 by @akiko123456) ### 2.15.9 *2022-06-02* #### Bug fixes - Table - Fix Tabl-header shake bug (#21863 by @bofeng) - Fix when partial import show `el-checkbox not imported` error (#21828 by @bobohuochai) - FormItem - Fix change rules verification not reset bug (#21892 by @bofeng) - Cascader - Fix change options unexpect error (#21759 by @louiebb) - Docs - Fix Popover docs (#21843 by @lod61) - Fix Calendar docs (#21814 by @GoJam11) - Fix TimePicker docs (#21803 by @Alanscut) - Fix DatePicker docs (#21877 by @Nirvanaiu) - Other - Fix codepen display bug (#21863 by @bofeng) #### Optimization - I18n - Add translation of Swahili (#21895 by @quilltouch) - Chore - Use launch-editor-middleware in dev environment (#21633 by @polemices) - DatePicker & Cascader - Optimize the dropdown animation direction (#21806 by @XivLaw) - Tooltip - Optimize `getFirstElement` code (#21886 by @zhankang) - Input - Optimize scss code (#21558 by @cheese-git) ### 2.15.8 *2022-04-12* #### Bug fixes - Drawer - Fix appendToBody failure problem (#21264 by @cs1707) - Switch - Fix toggling value problem(#19473 by @EdwinBetanc0urt) - Docs - Fix input docs (#21723 by @justforuse) - Fix DatePicker docs (#21663 by @justforuse) - Fix Skeleton docs (#21601 by @yanwydxf) - Others - Fix vue version (#21736 by @ckvv) #### Optimization - I18n - add translation of Azerbaijani (#21012 by @ricardotondello) - update translation of Slovenian (#21729 by @patik123) - update translation of Slovak (#21711 by @sjaustirni ) - add translation of Icelandic (#21709 by @aronhr) - add translation of Bengali (#21485 by @llwwtt) #### Others - Due to compatibility considerations, the PR on node-sass (#21019 by @linxsbox) of 2.15.7 release has been withdrawn and will be published in an appropriate version after re-evaluation. ### 2.15.7 *2021-11-18* #### Bug fixes - Select - fix click icon triggering dropdown (#21314 by @dennyak47) - fix keydown event when composition (#21336 by @bchen1029) - Badge - fix type class when is-dot (#21308 by @adaex) - Form - validate method reject error info (#21374 by @cs1707) - Table - fix resizeObserver loop limit exceeded (#21255 by @tomieric) - fix toggleAllSelection bug when table is empty (#21456 by @cs1707) - optimize performance (#21330 by @cs1707) - Button - fix disabled priority (#21375 by @cs1707) - Descriptions - fix label slot bug (#21462 by @cs1707) - SASS - replace node-sass with dart-sass (#21019 by @linxsbox) - Docs - fix skeleton typos (#21408 by @zhhbstudio) ### 2.15.6 *2021-09-02* #### Bug fixes - Cascader - fix a bug that makes the browser jitter in zoom mode (#21207 by @cs1707) - optimize performance (#21231 by @cs1707) - Select - fix long text overflow in multiple mode (#21237 by @cs1707) - Dropdown - add disabled property (#21235 by @mshioda) - Radio - fix checked state when browser go back (#21250 by @cs1707) - Descriptions - fix type declaration (#21265 by @adaex) - avoid table style conflict (#21254 by @adaex) - Drawer - fix append to body (#21264 by @cs1707) - Local - fix italian mistake (#21012 by @ricardotondello) ### 2.15.5 *2021-08-04* #### Bug fixes - Select - fix resetInputHeight (#21201 by @cs1707) ### 2.15.4 *2021-08-03* #### New features - Descriptions - add description component (#21129 by @cs1707) - Result - add result component (#21171 by @cs1707) #### Bug fixes - Utils - fix isScroll (#21098 by @canvascat) - Translation - update it.js (#21133 by @bliberi) - RadioGroup - fix RadioGroup used in component causes exception #17908 (#20783 by @lceric) - Message - fix message[type] (#21088 by @cs1707) - Carousel - reset the timer when setActiveItem method is called (#20846 by @Nekojita1) - Cascader - fix emitPath (#21185 by @cs1707) - Select - fix select filterable bug (#17494 by @profore) - fix a bug that makes the browser jitter in zoom mode (#21197 by @cs1707) - Tree - fix insertChild (#21194 by @cs1707) ### 2.15.3 *2021-06-29* #### New features - Skeleton - add skeleton component (#21038 by @cs1707) - Empty - add empty component (#21080 by @cs1707) #### Bug fixes - Local - fix week translations for hr locale (#21040 by @cs1707) - Table - fix lazy load data (#21041 by @cs1707) - Docs - fix form hide-required-asterisk description (#21045 by @cs1707) - Drawer: - fix destroy (#20715 by @zj9495) - Row - fix align top (#20963 by @cs1707) - Select - fix the bug when the value is Boolean (#21052 by @cs1707) - Calendar - fix first-day-of-week (#21057 by @cs1707) - Utils - fix isScroll (#21065 by @cs1707) - fix(utils.dom by @fw6) - TypeScript - add CascaderPanel export type (#21070 by @qige2016) - add spinner.d.ts (#21090 by @qige2016) ### 2.15.2 *2021-05-28* #### Bug fixes - Image - fix z-index and keydown event add stopPropagation (#20859 by @cs1707) - Input - fix show password cursor (#20870 by @cs1707) - fix show password icon in edge (#20902 by @cs1707) - Carousel - fix interval and scale bug (#20931 by @cs1707) - Cascader - fix delete tag bug (#20939 by @cs1707) - Drawer - add overflow auto (#20948 by @cs1707) - Others - fix isFunction (#20912 by @cs1707) ### 2.15.1 *2021-02-23* #### Bug fixes - Drawer - bugfix (by @cs1707) - Image - fix incorrect image object fit ratio in IE (#19583 by @charlie0228) - Cascader - fix cascader panel active path (#20730 by @cs1707) - Calendar - fix calendar component i18n bug (#20758 by @iamkun) - ColorPicker - fix bugs (by @UxieVerity) #### Optimization - Doc - update Axure resource v2.1.0 (by @iamkun) ### 2.15.0 *2021-01-15* #### Bug fixes - Select - Fix placeholder i18n bug (#17644 by @nzh63) - Popconfirm - Popconfirm i18n bug by @iamkun - Drawer - Fix focus bug (#20626 by @cs1707) - Image - Preview optimization (#20652 by @cs1707) #### Optimization - Doc - Fix typo in french translation of datetime-picker.md (#20543 by @lonk) - Add format attribute description to the progress component (#20641 by @cs1707) ### 2.14.1 *2020-11-11* #### Bug fixes - Popover - Compatible with Vue 2.6 new v-slot syntax (#20424 by @iamkun) #### Optimization - I18n - Update Arabic translation (#20202 by @elkattan) - Update Uighur translation (#20177 by @IlhamTahir) ### 2.14.0 *2020-10-29* #### Breaking changes - Popconfirm - Rename event name to `confirm`, `cancel` (#20240 by @hugiron) #### Bug fixes - Progress - Fix attribute error (#19985 by @Caaalabash) #### Optimization - I18n - Update Russian translation (#19451 by @yangirov) - Update Khmer translation (#20077 by @Sovai) - Update Ukrainian translation (#20344 by @MammutAlex) ### 2.13.2 *2020-05-18* #### Bug fixes - Autocomplete - Fix change event bug (#19200 by @sxzz) - Image - Update error status (#19194 by @lhx6538665) #### Optimization - I18n - Update ru-RU popconfirm translation (#19220 by @Opppex) - Update vi translation (#19244 by @quangln2810) - Update Catalan and Spanish translations (#19296 by @Ismaaa) - Update Indonesia translation (#19320) by @therour) - Update Brazilian Portuguese translation (#19374 by @diegomengarda) ### 2.13.1 *2020-04-13* #### New features - Autocomplete - Add change event (#17913 by @sxzz) #### Bug fixes - Autocomplete - Fix suggestion error when textarea (#18478 by @Roojay) - Carousel - Fix console typo bug (#18264 by @IceFox) - Image - Fix preview dose not show when preview list not contain src issue (#18975) (#19130 by @luckyCao) - Fix shortcut key not work at second time issue (#18983) (#19156 by @luckyCao) - Don't show image-viewer when preview is false (#18967 by @inooNgt) - Transfer - Fix incorrect line-height of el-transfer's first list item when it was used with el-form-item (#18917 by @Hanx) - InputNumber - Correctly compute inputNumberDisabled (#18439 by @ashuser-pendo) - Chore - Remove index intro (#19155 by @iamkun) - Doc - Popconfirm doc update (#18324 by @iamkun) - Fix step-strictly docs typo (#18705 by @dream2023) - Fix a type error in document of steps component (#17555 by @haoranyu) ### 2.13.0 *2019-11-26* #### New features - Popconfirm - Add popconfirm component (#17548 by @iamkun) #### Bug fixes - BackTop - Use cubic bezier scrolling (by @lon) - DatePicker - Fix bug of only select min date of date range problem (#17191 by @smk0621) - Select - Fix select test cases (by @msidolphin) - Tree - Add font-size for the style of tree empty-text (#17094 by @spengjie) - Table - Column header can be costumed (#17291 by @ziyoung) - Update table header cell style (#17284 by @ziyoung) - Fix table header height after filter (#17348 by @ziyoung) - Fixed row-style with display not work (#17002 by @a631807682) - Fix header table not display (#17341 by @ziyoung) - Calendar - Import el-button and el-button-group (#17376 by @masongzhi) - MessageBox - Fix icon position error (#17410 by @nullptru) - TimePicker - Set the selection range after scrolling up or down (#16868 by @mattheyan) - Message - Fix close instace offsetHeight(#17564) (#17852 by @gzwgq222) - Form - Callback of validateField should be optional (#17314 by @CarterLi) - Cascader - Fix TypeScript 3.7 compatibility (#17881 by @CarterLi) - Menu - Fix router NavigationDuplicated error when using vue-router@^3.1.0 (#17269 by @iamkun) - Dropdown - Update type file (#17550 by @iamkun) - Progress - Add strokeLinecap prop (#17552 by @iamkun) - InfiniteScroll - Skip trigger event on invisible element (#17553 by @iamkun) - Image - Perfect picture preview behavior (#16985 by @luckyCao) - Fix shield the page when preview big image (#16796 by @luckyCao) - Drawer - Bugfix drawer-append-to-body-not-working (#16953 by @JeremyWuuuuu) - Select - Fix tag show value or empty issue (17199 by @luckyCao) - Scrollbar - Fix FireFox scroll bar width (#18091 by @iamkun) #### Optimization - I18n - Update sv-SE.js (#17926 by @FOLLGAD) - Update avatar component fr doc (#17762 by @blombard) - Docs - Fix time-select typo (#17250 by @wacky6) - Fix Drawer attribute accepted value typo in es (#17122 by @haoranyu) - Update Spanish changelog 2.12.0 (#17364 by @Gonzalo2310) - Fix Changelog typo (#17874 by @renlixin) - Fix Loading demo (#17862 by @MBearo) - Add input event in input Events Table (#18061 by @zhouxinyong) - Delete Input repeat change event (#18085 by @zhouxinyong) ### 2.12.0 *2019-08-29* #### New features - Popover - Add close-delay prop (#16671 by @LachlanStuart) - Theme - Add Chrome Extension: Element Theme Extension (#16686 by @iamkun) - Icon - Add font-display to @font-face declaration (#16805 by @iamfaizalandyka) #### Bug fixes - Carousel - Fix onChange emit value (#16705 by @iamkun) - Notification - Fix modifying incoming option object (#16704 by @iamkun) - DatePicker - Add className for picker option (#16632 by @iamkun) - DateTimePicker - Fix time-spinner not scroll to right position (#16854 by @jesse-li) - Table - Prevent click handler after drag (#16850 by @ziyoung) - Fix chrome crash when set thead css display to none (#16956 by @luckyCao) - Fix wrong empty block height (#16861 by @ziyoung) - Not throw error when calling toggleExpansion (#16304 by @yyjjqq94) - Not trigger sort-change event when mounted (#17113 by @a631807682) - Fix setCurrentRow unable to clear highlight row (#16879 by @ziyoung) - Fix expand-row-keys not work when data is loaded asynchronously (#16899 by @ziyoung) - set toggleAllSelection as instance property (#17137 by @ziyoung) - Tree - Fix distance between label and checkbox (#16799 by @Hazlank) - Tabs - Fix incorrect TabItem's position (#16520 by @victorting) - Fix activated tab is out of visual range bug (#17033 by @nullptru) - Calendar - Fix weekdays i18n issue (#16772 by @ubitoffee) - fix locale error by (#17208 by @iamkun) - Cascader - Fix CascaderPanel display error (#16716 by @zhangHongEn) - Fix disable status and close button issue (#16224 by @yyjjqq94) - Input - Fix Korean composition event (#15069 by @MoonHyuk) - Fix click event of clear button not trigger when using v-loading (#16576 by @a631807682) - Select - Not toggle dropdown when filtering (#17205 by @luckyCao) - Transfer - Fix style error (#17206 by @iamkun) - Dialog - update sass var (#16365 by @haoranyu) - RadioGroup - Not produce invalid HTML in table if "is" attribute is specify (#17070 by @nullptru) - Divider - Support custom classes (#17078 by @island205) #### Optimization - Checkbox - Improve screen reader experience (#16575 by @tylertrotter) - Docs - Update changelog (#16773 by @SimonaliaChen) - Update contributing guide (#14800 by @sinchang) - Fix typo in Drawer docs (#16848 by @winkay) - Update custom theme (#16983 by @iamkun) - Add Esperanto translation (#16955 by @maxkoryukov) - Update input-number document about change event (#16316 by @luckyCao) - Update spanish doc 2.11.1 (#16961 by @Gonzalo2310) - I18n - Remove translation of 'year' in catalan language as in the other languages (#14722 by @oscaralbareda) - Update spanish changelog 2.10.0 and 2.10.1 (#16548 by @Gonzalo2310) - Update ar.js (#16653 by @l3op) - Test - Correct spelling error (#16672 by @boomler) - Refactor unit test to use data-uri (#16847 by @a631807682) - Types - Fix httprequest type (#16633 by @luckyCao) ### 2.11.1 *2019-07-26* #### Bug fixes - Image - Fix Image component SSR compatibility (#16737 by @luckyCao) - Chore - Update dart-sass compatibility (#16744 by @LewisChennnnn) ### 2.11.0 *2019-07-25* #### New features - Drawer - Add drawer component (#16577 by @JeremyWuuuuu) #### Bug fixes - Checkbox - Enhance css selector (#16006 by @Hazlank) - Tree - Make el-tree generic (#15934 by @JeremyWuuuuu) - Set isCurrent prop to False (#15870 by @kkkisme) - Dropdown - Fix split-button caret default color (#15931 by @JuniorTour) - Cascader - Fix level 1 children is empty update problem (#16399 by @luckyCao) - Add sets default values when lazy is true (#16420 by @luckyCao) - Fix display errors when node value is duplicate (#15935 by @junyiz) - Expose getCheckedNodes and fix options change bug (#16709 by @SimonaliaChen) - Calendar - Display correct header when range is specified (#16354 by @ziyoung) - Submenu - Fix prop append-to-body (#16289 by @a631807682) - Table - Fix tree table when updating data (#16481 by @island205) - Select - Fix memory leak issue (#16463 by @island205) - InfiniteScroll - Update naming & doc (#16698 by @iamkun) - Avatar - Fix image not center vertically issue (#16489 by @luckyCao) - Dialog - Add destroyOnClose attribute (#16455 by @ziyoung) - Image - Add big Image preview feature (#16333 by @luckyCao) #### Optimization - Docs - Fix dropdown demo (#16193 by @webxmsj) - Fix typo in table documents (#15971 by @howiefh) - I18n - Update translation of Thai language (#16689 by @ponkrit) - Chore - Update theme base api (#16607 by @iamkun) - Add form theme token (#16699 by @iamkun) - Mark ali inner user's access (#16609 by @iamkun) - Fix doc anchor bug (#16692 by @iamkun) ### 2.10.1 *2019-07-02* #### Bug fixes - Table - Fix sort icon (#15439 by @bezany) - Fix layout breaks when append slot exists (#16332 by @ziyoung) - Fix showOverflowTooltip not reactive (#16295 by @a631807682) - Register scrollbar in filter-panel (#16246 by @ziyoung) - Chore - Fix 2.9 docs (#16233 by @ziyoung) - Fix index page theme intro english css style issue (#16254 by @iamkun) #### Optimization - Tag - Compatible with IE (#16334 by @ziyoung) - Chore - Update Dingtalk Group QR image (#16236 by @iamkun) - Doc - Update online theme roller doc (#16244 by @iamkun) ### 2.10.0 *2019-06-25* #### New features - I18n - Added Uzbek language (#15796 by @ogabek96) - Calendar - Add first-day-of-week attribute (#16047 by @ziyoung) - Avatar - Add avatar component (#16144 by @luckyCao) - Upload: - Add capability to customize thumbnail template (#13192 by @victorzhuk) #### Bug fixes - Tree - Not highlight tree node when currentKey is null (#15668 by @yyjjqq94) - Fix issue #15538 caused by two Tree sharing the same data. (#15615 by @VanMess) - Upload - Update the parameter `fileList` type (#15716 by @underfin) - Table - Fix loading icon not display (#15868 by @ziyoung) - Fix background color of complex table when hovering (#15504 by @cnlon) - Fix current-row-key and select event bug (#15983 by @ziyoung) - Height accepts more units (#16013 by @ziyoung) - Fix reserve-selection not work (#16135 by @ziyoung) - Docs - Fix Divider attribute type in zh-cn (#15889 by @haoranyu) - Menu - Fixed submenu hidden bug after adding popper-append-to-body (#15391 by @PanJiaChen) - Select - Fix initialInputHeight (#15989 by @yyjjqq94) - Fix default-first-option behavior when typing Chinese (#15431 by @VanMess) - fix double import problem (#16215 by @lengband) - Message - Add type def for offset option (#16027 by @matjaz) - Timeline - Fix reverse broken (#16091 by @ziyoung) - Slider - Fix #15545 by adding explains about "input" event in Chinese (#15588 by @VanMess) - InfiniteScroll - Update package name (#16125 by @iamkun) - MessageBox - Fix  distinguishCancelAndClose action not same as docs bug (#15438 by @qingdengyue) - PopupManager - Fix z-index cannot be rewritten at first using (#15738 by @luckyCao) - Docs - Delete an incorrect closing html tag and empty block code (#16194 by @Alexeykhr) - Chore - Update test api host (#15807 by @iamkun) #### Optimization - Tree - Modify loop conditions to improve performance (#15699 by @KingJeason) - Theme - Refine GA track & Update footer link forward to online theme roller (#16007 by @island205) - Badge - Update badge prop check (#16198 by @iamkun) - Avatar - Update theme config var (#16202 by @luckyCao) - I18n - Update pt-br.js (#15776 by @gigioSouza) - Update Farsi translation (#15881 by @pamenary) - Docs - Add missing components in quickstart (#16063 by @pape2016) - Update french translation (#16208 by @blombard) - Add description $slots.default (#15444 by @Alexeykhr) - Update Spanish Doc 2.9.1 (#15840 by @Gonzalo2310) - Fix spelling mistakes in fr (#15837 by @blombard) - Update changelog 2.9.2 Spanish (#16185 by @Gonzalo2310) #### Breaking changes - Form - Remove success status (#16159 by @ziyoung) ### 2.9.2 *2019-06-21* #### Correction de bugs - Chore - Correction du fichier de définitions TS (#15805 by @NateScarlet) ### 2.9.1 *2019-05-30* #### Nouvelles fonctionnalités - Table - les événements tree-props,default-expand-all, expand-row-keys, toggle-row-expansion method and expand-change sont pris en charge dans Tree Table (#15709 by @ziyoung) #### Correction de bugs - Table - Correction de quelques bugs (#15709 by @ziyoung) - Theme - Mise à jour de l'hôte api (#15784 by @iamkun) #### Optimisation - Chore - Mise à jour de InfiniteScroll type (#15794 by @iamkun) ### 2.9.0 *2019-05-30* #### Nouvelles fonctionnalités - Backtop - Ajout du composant Backtop (#15541 by @iamkun) - PageHeader - Ajout du composant PageHeader (#15714 by @ziyoung) - InfiniteScroll - Ajout de la directive InfiniteScroll (#15567 by @iamkun) - Cascader - Ajouter plusieurs mode et filter-method (#15611 by @SimonaliaChen) - Message - Affichage en mode pile (#15639 by @island205) - Tag - Ajout d'un effet de prop (#15725 by @SimonaliaChen) - Tabs - Aligner le titre à gauche lorsque le type est carte (#15695 by @luckyCao) - DatePicker - Supporte les chaînes de caractères littérales (#15525 by island205) - Image - Ajout du support pour les attributs de transmission et listeners (#15578 by @VanMess) - Theme - Ajout d'un popup en arrière plan (#15412 by @iamkun) - Chore - Mise à jour de la nouvelle page d'index 2.9.0 (#15682 by @iamkun) #### Correction de bugs - Table - Correction du comportement de sort-change lorsque la condition de tri est nulle (#15012 by @joelxr) - Image - Correction de la compatibilité ssr et object-fit (#15346 by @SimonaliaChen) - Input - Correction du style de show-word-count dans el-form (#15359 by @lvjiaxuan) - Correction de l'icône d'erreur pas centrée (#15354 by @YiiGuxing) - Calendar - Correction du mauvais jour de la semaine quand le jour est dimanche (#15399 by @qingdengyue) - Correction du bug de disparition d'octobre (#15394 by @qingdengyue) - Tabs - Correction de l'onglet de base imbriqué dans l'erreur de remplissage de card (#15461 by @SimonaliaChen) - Tag - Correction du problème de propagation d'arrêt (#15150 by @infjer) - Form - Correction de input-group dans l'erreur de hauteur de form-item (#15457 by @SimonaliaChen) - Résolution de l'issue de resetFields (15181 by @luckyCao) - Tooltip - Correction de tabindex personnalisé ne fonctionnant pas (#15619 by @SimonaliaChen ) - Link - Correction de la classe de style d'icône (#15752 by @iamkun) - Select - Revert définit la valeur à null une fois effacée (#15447 by @iamkun) - Loading - Résolution du problème de mise à jour de dom lorsque l'état de chargement change rapidement (#15123 by @FAKER-A) - Switch - Label avec les événements récurrents el-switch (#15178 by @FAKER-A) - Slider - Correction d'un problème de style lorsque la barre de défilement est cliquée (#15561 by @luckyCao) - Radio - Résolution de l'issue 14808 (#14809 by @OverTree) - Form - Résolution du problème de resetFields (15181 by @luckyCao) - Chore - Mise à jour des dépendances et corrige le bug de démonstration (#15324 by ziyoung) - Type - Correction du type de chargement (#15635 by @iamkun) - Correction du type d'icône (#15634 by @iamkun) - Fixe la définition du type de lien (#15402 by @iamkun) #### Optimisation - Cascader - Refactor (#15611 by @SimonaliaChen) - Chore - Mise à jour de la logique du nouveau composant (by @iamkun) - Docs - Renommage de variables dans la documentation (#15185 by @liupl) - Correction du type d'attribut d'image et de la valeur par défaut (#15423 by @haoranyu) - Correction d'un bug de formulaire (#15228 by @SHERlocked93) ### 2.8.2 *2019-04-25* #### Corrections de bugs - Icon - Mise à jour (#15272 par @iamkun) - Docs - Correction du style de Form et Input (#15273 par @ziyoung) ### 2.8.1 *2019-04-25* #### Corrections de bugs - Icon - Mise à jour de l'icône du cascadeur et du select (#15264 par @SimonaliaChen) - Mise à jour (#15258 #15268 par @iamkun) #### Optimisation - Chore - Mise à jour du script de build (#15267 par @ziyoung) - Docs - Correction de la couleur de souslignage d'un lien (#15265 par @iamkun) - Autre - Correction d'une configuration de migration non compatible avec les propriétés et évènements en camelCase (#15260 par @SimonaliaChen) ### 2.8.0 *2019-04-25* #### Nouvelles fonctionnalités - Divider - Ajout du composant divider (#15055 par @island205) - Rate - Ajout des couleurs et des classes d'icônes personnalisées en passant un objet (#15051 par @SimonaliaChen) - Link - Ajout du composant Link (#15052 par @iamkun) - Calendar - Ajout du composant calendar (#14908 by @ziyoung) - Icon - Ajout d'une icône (#15214 par @iamkun) - Alert - Ajout d'un thème sombre (#15041 par @island205) - Image - Ajout du composant image (#15117 par @SimonaliaChen) - Collapse - CollapseItem peut être désactivé (#15076 par @ziyoung) - Carousel - Ajout d'un attribut de direction et support de la direction verticale (#15122 by @ziyoung) - Pagination - Ajout d'un attribut caché sur une seule page (#15096 par @ziyoung) - Slider - Ajout des marqueurs (#15133 par @luckyCao) - Input - Ajout de l'attribut show-word-count (#15075 par @luckyCao) - InputNumber - Ajout de l'attribut step-strictly (#15050 par @luckyCao) - Tooltip, Dropdown, Popover - Support de l'attribut tabindex (#15167 by @ziyoung) #### Corrections de bugs - Notification - Correction du word-break du titre (#15008 par @iamkun) - Form - Correction d'une erreur dans les règles de validation (#14985 par @luckyCao) - Correction du style du label (#14969 par @ziyoung) - Les FormItem requis affiche un astérisque lorsque le label est auto (#15144 by @ziyoung) - Pagination - Fix du slot non mis à jour (#14711 par @lucyhao) - Table - Correction d'un bug de chargement en mode lazy (#15101 by @ziyoung) - Correction de la largeur des cellules lorsque colspan est supérieur à 1 (#15196 by @ziyoung) - Amélioration des performances (#14868 by @ziyoung) - Ne pas émettre de déclencheurs de changement de tri pendant l'initialisation (#14625 by @PeanutWatson) - Comportement égal pour height et max-height (#14660 by @arthurdenner) - Dialog - Correction de la casse des longs mots (#15027 par @iamkun) - Alert - Mise à jour (#15186 par @ziyoung) - Tabs - Correction d'un problème où le rejet d'une promesse touchait l'application (#14816 par @ffxsam) - Rerendu lors d'un changement de slots (#1523238 by @ziyoung) - Message - Mise à jour (#14968 par @agoni121212) - Select - Correction d'une erreur lorsque la valeur est indéfinie ou nulle (#15022 par @luckyCao) - Tree - Détruire le noeud courant après sa suppression (#14604 par @sinchang) - Amélioration des performances (#14881 par @ChenZhuoSteve) - Dropdown - Correction de style (#14907 par @doing123) - Slider - Correction d'un bug clavier a11y cassé (#14792 by @erezsob) - Menu - La valeur ActiveIndex sera nulle si defaultIndex n'existe pas (#14074 par @hoythan) - Directive - RepeatClick : utilisation de Date.now() au lieu de Date() (#14776 par @pavelmash) - Upload - Correction du style d'affichage des images transparentes (#15039 par @iamkun) - Thème - Ajout d'une bordure (#1525256 par @iamkun) #### Optimisation - Chore - Mise à jour du changelog zh-cn (#14965 par @iamkun) - Masquer la description de la démo quand elle est vide (#15014 par @ziyoung) - Afficher les informations du serveur de développement par défaut par @iamkun) - Correction d'une erreur de changelog 2.6.0 (#15026 par @iamkun) - Mise à jour de la configuration de compilation (#14821 par @abc3660170) - Ajout d'hmr (#15221 par @SimonaliaChen) - Utilisation de sourcemap dans l'environnement dev (#15087 par @ibufu) Docs - Renommage de la variable dans docs (#14602 #15003 #15094 #15105 par @liupl) - Correction d'une erreur de téléchargement de doc (#15023 par @iamkun) - Mise à jour du validateur de formulaire personnalisé doc (#15040 par @iamkun) - Mise à jour des onglets docs pour afficher les onglets verticaux (#15053 par @iamkun) - Utiliser eleme.cn comme domaine (#15139 par @ziyoung) - Correction du nom de route Image (#15194 par @iamkun) - Suppression de la traduction en double (#15207 par @iamkun) #### Breaking changes - Rate - Correction du support de l'affichage décimal en mode désactivé (#15089 par @haoranyu) - Select - Utiliser le label de l'option pour régler le placeholder en mode filtre (#14989 par @ibufu) ### 2.7.2 *2019-04-03* #### Corrections de bugs - Form - Correction du style de `label-width` auto (#14955 par @ziyoung) #### Optimisation - Docs - Correction d'une erreur de lien img (#14957 par @iamkun) - Chore - Correction d'une erreur de déploiement mkdir (#14952 par @iamkun) ### 2.7.1 *2019-04-03* #### Corrections de bugs - Select - Définir la valeur à null lorsqu'elle est effacée (#14322 par @aaronfulkerson) - Input - Mise à jour des valeurs dépendantes du DOM lors d'un changement de type (#14889 par @wacky6) - Table - Faire fonctionner `defaultExpandAll' lorsqu'une colonne étendue existe (#14935 par @ziyoung) - Dialog - Couleur d'arrière-plan configurable (#14939 par @ziyoung) - Form - `label-width` supporte la largeur automatique (#14944 by @ziyoung) #### Optimisation - Docs - Mise à jour de la documentation en espagnol (#14913 par @Gonzalo2310) - Ajout d'un document en français pour le nouveau composant (#14924 by @ziyoung) - Optimiser la documentation des onglets (#14938 by @ziyoung) ### 2.7.0 *2019-03-28* #### Nouvelles fonctionnalités - Table - Ajout du support de l'arborescence des données (#14632 by @ziyoung) #### Corrections de bugs - Tabs - Utilise la couleur primaire comme couleur de l'ombre (#14558 par @Richard-Choooou) - Rerendu lorsque label change (#14496 par @akki-jat) - Table - Le pied de page suit l'alignement des cellules du corps (#14730 by @ziyoung) - NavMenu - Correction d'un bug de clic sur el-submenu (#14443 par @PanJiaChen) - Dropdown - Compatible avec la nouvelle syntaxe v-slot 2.6 (#14832 by @ziyoung) - ColorPicker - Correction d'une erreur de couleur hexadécimale (#14793 par @iamkun) - Tree - Revert pr #13349 (#14847 par @ziyoung) - Tooltip - Affichage lorsque la valeur initiale est vraie (#14826 by @ziyoung) - Docs - Mise à jour de la documentation du cascader (#14442 par @panhezeng) - Style - Correction des media queries dans sm-only, md-only, lg-only (#14611 by @sinchang) #### Optimisation - Chore - Ajouter la description de la page web (#14802 par @iamkun) ### 2.6.3 *2019-03-21* #### Corrections de bugs - Correction du style de la démo de Cascader (#14789 par @ziyoung) - Suppression des opérations DOM inutiles (#14788 by @ziyoung) - Correction DatePicker valeur par défaut DST (#14562 par @wacky6) ### 2.6.2 *2019-03-21* ##### Nouvelles fonctionnalités - DatePicker - Ajout d'une plage de mois pour l'attribut type (#14487 par @zxyRealm) - i18n - Ajout de la locale croate (#14360 par @danijelh) ##### Corrections de bugs - Input - Correction d'un régression (#14572 par @wacky6) - DatePicker - Correction du calcul du premier jour de la semaine (#14523 par @sinchang) - Correction du format de valeur du sélecteur de semaine (#13754 par @wacky6) - Steps - Correction du problème #14502 (#14596 par @sinchang) - Correction du style avec le thème simple (#14610 par @sinchang) - Docs - Mise à jour de la doc française pour la 2.6.1 et correction de fautes de frappe (#1455555 par @smalesys) - Renommage d'une variable dans la documentation de la table (#14587 par @likwotsing) - Ajout de l'index de recherche en français (#14565 par @iamkun) - Correction du style de la page TimePicker (#14579 par @ziyoung) - Renommage d'une variable dans la page Upload (#14593 par @liupl) - Mise à jour de la traduction française (#14643 par @smalesys) - Mise à jour de la documentation du validateur de formulaire asynchrone (#14694 par @iamkun) - Correction d'une erreur de doc tooltip (#14748 par @iamkun) - Correction d'une coquille (#14751 par @2bj) - Correction de la surbrillance pour Webkit touch (#14703 by @VladG0r) ##### Optimisation - Tâche - Mise à jour du script de build dans le ci (#14600 par @ziyoung) - Mise à jour du tracking ga (#14560 par @iamkun) - Ajout d'un événement ga supplémentaire (#14633 par @iamkun) - Mise à jour du groupe de discussion (#14741 par @iamkun) - Mise à jour des deps de test et conf (#14735 par @wacky6) - Mise à jour de Gulp (#14745 by @ziyoung) - Utilisez le codepen pour afficher les démos et correction d'une erreur de doc (#14747 by @ziyoung) ### 2.6.1 *2019-03-03* #### Corrections de bugs - **Ne pas spécifier la version de node** (par @iamkun dans #14546) - Correction du répertoire doc dans `deloy-faas.sh` (par @ziyoung dans #14553) - Correction d'un problème de style de date dans le changelog de la 2.6.0 (par @island205 dans #14547) - Correction d'une typo dans la doc (par @wack6 dans #14552) ### 2.6.0 *2019-03-01* #### Nouvelles fonctionnalités - Timeline - Ajout d'un composant timeline (par @jikkai dans #14248) - DropdownItem - Ajout de la propriété `icon` à `el-dropdown-item` (par @gabrielboliveira dans #14088) - Input - Ajout de propriétés pour afficher les mots de passe (par @phshy0607 dans #13966) - Select - Ajout du slot `empty` (par @elfman au #13785) - Autocomplete - Ajout de la propriété `highlight-first-item` (par @YamenSharaf dans #14269) - I18n - Création de la locale Arménienne (par @hamletbarsamyan dans #14214) - Docs - Traduction française (par @smalesys dans #12153, #14418, #14434) #### Optimisation - Alert - Mise à jour de la classe du slot par défaut de la description de Alert (par @iamkun dans #14488) - Input - Mise à jour de l'input de type password (par @iamkun dans #14480) - InputNumber - Retrait d'un parseFloat inutile (par @JuniorTour au #14172) - Menu - Ajout du support de `el-menu-item` sans index (par @georgyfarniev dans #13298) - Table - Suppression de certaines opérations du DOM (par @elfman dans #13643) - Upload - Optimisation du code (par @elfman dans #13973) - Popup - Optimisation du code (par @KAionro dans #14413) - Docs - Ajout de détails sur la façon d'exécuter le mode play pour les contributeurs (par @island205 dans #14355) - Ajout d'un avertissement concernant Input (par @wacky6 dans #14463) - Mise à jour de la doc de Table (par @luguokong dans #14329) - Mise à jour de la doc d'Input (par @iamkun dans #14437) - Mise à jour de la doc sur le thème (par @wangguohaohao dans #14297) - Le style de l'icône change lorsque vous passez dessus (par @tuxinghuan dans #14295) - Build - Minification du CSS et du JS pour le site d'Element (par @iamkun dans #14430) - Accélération de webpack (par @hetech dans #14484) - Utilisation du cli pour sélectionner la version de publication (par @hetech dans #14354) - Installation de stale pour la gestion des issues (par @island205 dans #14392) #### Corrections de bugs - Menu - Correction d'un bug de focus des sous-menus lors du changement d'onglet du navigateur (par @liupl dans #13976) - MessageBox - Correction de la définition du type (par @NateScarlet dans #14278) - ScrollBar - Empêche le clic droit sur le bouton du pouce (par @xifeiwu dans #14196) - Switch - Déclenchement de la validation du formulaire si la valeur change (par @hetech dans #14426) - Table - La méthode toggleAllSelection est maintenant une méthode d'instance (par @letanure dans #14075) - Tabs & Dropdown - Correction du style (par @hetech dans #14452) - Tree - Les tips sont différents des tableaux (par @ColinCll dans #14331) - Docs - Correction d'une erreur de doc du DatetimePicker (par @iamkun dans #14290) - Problème d'orthographe dans la documentation du DatePicker (par @helmut dans #14481) - Correction du style de la doc de Pagination(par @liuchuzhang dans #14451) #### Breaking changes - Table - Fix params order of row events (by @jikkai in #12086) ### 2.5.4 *2019-02-01* #### Corrections de bugs - Build: Correction d'un problème de configuration de babel qui cassait la transition collapse (par @island205 dans #14282) ### 2.5.3 *2019-01-31* #### Optimisation - Optimisation du code de Message (par @vok123 dans #14029) - Suppression des gh-pages (par @ziyoung dans #14266) - Ajout du lien IssueHunt (par @island205 dans #14261) #### Corrections de bugs - Correction d'une erreur du module UMD côté serveur (par @island205 dans #14242) - Correction du style du TabBar actif (par @iamkun dans #14240) - Correction d'une erreur de code dans la démo de Table (par @xunmeng dans #14253) ### 2.5.2 *2019-01-27* #### Optimisation - Docs: - Mise à jour du ChangeLog ES 2.5.1 (par @Gonzalo2310 dans #14231) #### Corrections de bugs - Build: - Suppression des commentaires non supprimés dans le module umd `lib/index.js` (par @island205 dans #14233) - Correction d'une erreur d'exportation dans le module commonjs utilisé dans nuxt.js (par @island205 dans #14232) - Correction des problèmes de build 2.5.1 (par @iamkun dans #14228) ### 2.5.1 *2019-01-26* #### Optimisation - DatePicker: surbrillance du mois et de l'année courants (par @Debiancc dans #14211) - Mise à jour du changelog 2.5.0 (par @wacky6 dans #14217) #### Corrections de bugs - Correction d'un problème d'exportation due par la mise à jour du webpack (par @island205 dans #14220) - Conservation de la docs 2.4.11 && nouveau sous-dossier pour 2.5+ (par @iamkun dans #14222) ### 2.5.0 *2019-01-25* #### Nouvelles fonctionnalités - DatePicker - Ajout de l'attribut `validate-event` (par @ziyoung dans #13531) - DateTimePicker - `pickerOptions` supporte l'option `selectableRange` (par @eeeeeeeeeeeason) - Tag - Ajout de l'événement `click` (par @licdream dans #14106) - I18n - Support de la langue kirghize (par @zzjframework dans #14174) #### Optimisation - Mise à niveau vers webpack@4 (par @jikkai dans #14173) - Input - Simplification de l'implémentation, suivant un flux de données à sens unique. Correction de plusieurs bugs liés. (par @wacky6 dans #13471) - Mise à jour du fichier Axure avec de nouveaux composants (par @ziyoung dans #13773) #### Corrections de bugs - Autocomplete - Correction de la dernière ligne du menu déroulant qui était coupée (#13597) (par @ziyoung) - Correction d'une flèche de popper manquante (#13762) (par @liuchuzhang) - Carrousel - Nettoyage du timer lorsque le composant est détruit (#13820) (par @elfman) - Cascader - Suppression de la propriété obsolète des props calculées (#13737) (par @iamkun) - Correction de la définition du type CascaderOption dans TypeScript (#13613) (par @NateScarlet) - Correction de l'icône couvrant le texte (#13596) (par @ziyoung) - Checkbox - Refonte du style (par @PanJiaChen) - DatePicker - Ajout d'un `key` de v-for manquant dans TimeSpinner (#13547) (par @Ende93) - Correction du surlignage de la semaine dans la bordure de l'année (#13883) (par @suyi91) - Input - Correction de la référence de textarea dans le DOM (#13803) (par @laomu1988 @island205) - Pagination - La valeur d'entrée ne sera pas inférieure à 1 (#13727) (par @elfman) - Popover - Correction d'un problème de popover avec le déclencheur de hover (#13104) (par @goldengecko) - Correction d'une fuite de mémoire de l'instance popper (#13988) (par @qpxtWhite) - Radio - Refonte du style (par @ohhhoney1) - Table - Amélioration du tri des tables en cliquant sur la flèche de tri (#12890) (par @ohhoney1) - Correction d'un problème d'alignement vertical du texte vide sur IE10+ (#13638) (par @imzjy) - Correction de la documentation sur le type d'index (#13628) (par @ilovefafafa) - Correction du problème d'affichage `show-summary` lorsque le header multi-niveaux est fixe (#13914) (par @luckyCao) - Tabs - Correction d'un bug de défilement automatique (#13696) (par @iamkun) - Obtenir l'onglet correct par le nom de l'onglet (#13705) (par @iamkun) - Utilisez paneName au lieu de name pour déterminer le style du panneau (#13733) (par @iamkun) - Tree - Correction de la propriété `showCheckbox` sur `Tree` qui ne pouvait pas affecter leurs `tree-node` enfants(par @KidneyFlower) - Mise à jour des fichiers de doc et de définition (#13540) (par @ziyoung) - Upload - Ajout de le propriété `url` au fichier uploadé lorsque `list-type` est modifié (#13771) (par @elfman) - Slider - Correction de l'indentation du code source (#13955) (par @wacky6) - I18n - Ajout des traductions manquantes en catalan (par @jaumesala) - Ajout de la traduction russe manquante (#13658) (par @justlp) - Correction des traductions en finnois (#14137) (par @jenkrisu) - Doc - Mise à jour de la documentation espagnol depuis la 2.4.11 (#13522) (par @Gonzalo2310) - Autres - Suppression d'un script inutile (par @ziyoung) - Correction des ancres (#13753) (par @iamkun) - Correction de l'incohérence des majuscules dans la documentation (par @wonderjar) - Ajout du QR code du chat DingDing au readme (#13957) (par @iamkun) - Ajout des logs yarn au .gitignore (#13922) (par @mimimi) - Suppression du sponsor duotai (#14156) (par @island205) - Mise à jour du QR code dans le readme (#13960) (par @iamkun) - Mise à jour du lien CDN, correction d'une typo (par @ziyoung) ### 2.4.11 *2018-11-21* - Revert pr #13296. Correction d'un clic sur Menu externe causant l'effondrement du SubMenu, #13478 - Ajustement des points de rupture media query sur petit écran (xs), #13468 (par @alekoshen712) ### 2.4.10 *2018-11-16* - Correction des clics multiples sur Select pour afficher la liste déroulante, #13268 - L'icône d'effacement des champs n'est pas affichée lorsque Form est désactivé, #13208 - Ajustement des styles de Select, Progress, Autocomplete, Tooltip, Collaspe, TimePicker, #13188 (par @porcelainHeart) #13210 #13266 #13266 #13257 #13290 #13347 (par @PanJiaChen) - Ajout de l'attribut `loop` dans le composant Carrousel, #13217 - Lorsque les données de Table changent, la ligne en surbrillance reste, #13200 - Le slot du header de Table peut recevoir des paramètres, #13263 - La méthode `clearFilter` de Table peut recevoir des arguments, #13176 - La bulle d'aide n'est plus créée lorsqu'il n'y a pas de contenu dans la cellule de Table, #13152 (par @rongxingsun) - Le contenu de la zone de saisie du panneau ColorPicker peut être affiché correctement, #13278 - ColorPicker ne déclenche plus la validation des formulaires lors du glisser-déposer, #13299 - InputNumber: ajout de la méthode `select`, #13286 (par @st-sloth) - AutoComplete: ajout de l'événement `clear`, #12171(par arthurdenner) #13326 - Vous pouvez fermer Menu en cliquant à l'extérieur, #13296 - La méthode `validateField` du formulaire peut recevoir des arguments, #13319 - Cascader: ajout de l'événement `visible-change`, #13415 - DatePicker: a ajout d'un slot pour les séparateurs d'intervalle, #13272 (par @milworm) - Tree: ajout des propriétés `iconClass` et `currentNodeKey`, #13337 #13197 (par @isnifer) - Progress: ajout du texte de statut #13198 (par @ali-master) - Correction de `defaultCheckedKeys` de Tree, #13349 (par @dive2Pro) ### 2.4.9 *2018-10-26* - Le paramètre `clearValidate` de Form supporte les strings #12990 (par @codinglobster) - Ajout de l'attribut `type` pour Badge, #12991 - Les utilisateurs peuvent utiliser scoped-slot pour personnaliser l'en-tête de colonne de Table #13012 (par @ivanseidel) - Correction du champ de Select incapable d'entrer du texte sous IE, #13034 (par @GaliMU) - Les options Select ne s'enroule pas lorsque l'espace est suffisant, #12329 (par @akki-jat) - Lorsque la liste déroulante de Select est ouverte, l'icône de la flèche s'affichera également correctement, #12353 (par @firesh) - Correction de l'attribut de taille de Select qui ne fonctionnait pas, #13070 - La sélection de plusieurs valeurs peut aussi être effacée, #13049 (par @ZSkycat) - Correction du dernier TabNav qui ne pouvait pas être supprimé, #13039 - Correction d'un problème d'affichage du label TabNav, #13178 - Ajout d'un slot de titre pour Alert, #13082 (par @Kingwl) - Correction d'un problème où le contenu de l'infobulle de Table était incorrect, #13159 (par @elfman) - Optimisation de l'animation de Upload lorsque le fichier est supprimé, #12987 - Style ajusté pour InputNumber lorsque le bouton de commande n'est pas affiché, #13052 ### 2.4.8 - Ne pas afficher le contour lorsque le Switch est focus, #12771 - Correction du style de Dropdown dans ButtonGroup, #12819 (par @bluejfox) - Ajout d'un événement d'ouverture pour Dialog, #12828 - Correction de l'ordre d'affichage incorrect de TabNav, #12846 - Correction d'un problème qui empêchait les Tabs de défiler jusqu'à l'onglet sélectionné, #12948 - Correction d'un problème de l'identificateur qui ne s'affiche pas lorsque le noeud de Tree est glissé, #12854 - Le paramètre de l'événement validation du formulaire contient le message de validation #12860 (par @YamenSharaf). - Correction de DatePicker pour ne pas vérifier la validité du temps d'entrée de l'utilisateur, #12898 - Correction d'un problème avec l'attribut `render-header` de l'en-tête de table qui ne fonctionnait pas, #12914 ### 2.4.7 *2018-09-14* - Correction de DatePicker ne déclenchant pas la validation du formulaire, #12328 #12348 - Correction des erreurs lancées par DatePicker en mode multiple, #12347 - Correction d'une position incorrecte du spinner de DatePicker, #12415 (par @rang-ali) - Correction du remplissage automatique de la zone de saisie de DatePicker, #12521 (par @abdallanayer) - Correction du champ non-subrillant dans Cascader, #12341 - Correction d'un mauvais ordre de Tabpane, #12346 - Correction d'une position incorrecte du curseur ColorPicker, #12376 (par @cnwhy) - Correction du style de SubMenu, #2457 - Correction de la surbrillance après la sélection de SubMenu, #12479 - Correction des valeurs incorrectes sélectionnées par Cascader, #12508 (par @huangjinqiang) - Correction d'une valeur incorrecte dans le champ d'entrée Pagination, #12525 - Correction de l'ordre dans lequel la Pagination déclenche les événements, #12530 - Correction des filtres de table non-affichés, #12539 - Correction de l'arbre incapable de supprimer des nœuds, #12684 - Correction de la hauteur de Select Input changeant en mode simple, #12719 - Correction d'un style du label de FormItem sous forme imbriquée, #12748 - Ajout de l'attribut `autocomplete` pour Input, `auto-complete` devenant obsolète, #12514 (par @axetroy) - Ajout des slots-scope pour Form pour afficher les informations de validation, #12715 (par @YamenSharaf) ### 2.4.6 *2018-08-09* - Correction de Table n'affichant pas l'icône de filtre lorsque `filters` est un tableau vide, #12165 - Correction de Menu ne sauvegardant pas l'état actif lorsque `collapse` change, #12178 (par @elfman) - Correction du Cascader n'échappant pas les caractères spéciaux poue les Regexp, #12248 - Correction d'un bouton Radio désactivé affichant l'ombre d'une case lorsqu'on clique dessus, #12262 - Correction de arrow key qui n'a pas d'effet lorsque la valeur par défaut est `undefined`, #12322 - Correction de la fonction de requête de Select non-stabilisée en mode multi, #12181 - Correction du mot-clé de la requête Select disparaissant en mode multi, #12304 - Correction d'une largeur incorrecte de Dialog lorsqu'il est affiché en plein écran, #12203 - Correction de l'affichage incorrect de Main sur IE, #12237 - Correction de Input déclenchant deux validations de formulaire, #12260 - Correction de l'ajout d'un nouveau nœud d'arborescence provoquant la disparition des nœuds, #12256 - Correction d'un nœud d'arborescence non supprimé après avoir glissé, #12279 - Correction du Popover non-visible quand InputNumber a le focus, #12284 - Ajout de l'attribut `popper-append-to-body` pour Autocomplete, #12241 - Ajout du support du modificateur `sync` pour l'attribut `page-size` de Pagination, #12281 ### 2.4.5 *2018-07-26* - Correction du réglage de Table `class-name` qui ne fonctionne pas pour les colonnes `expand`, #12006 - Ajout de la méthode `toggleAllSelection` pour Table, #12047 - Correction d'une mauvaise position du slot de suffixe lorsque Input contient Select, #12108 - Correction de `line-height` de l'option impossible à régler, #12120 - Correction de TimeSelect avec la valeur par défaut `null` ne pouvant être assigné après avoir exécuté `resetField`, #12010 - Correction d'un événement keydown qui n'étant pas arrow key ne fonctionne pas dans Tree, #12008 - Correction d'un nœud parent vérifié en mode lazy, #12106 - Ajout du paramètre `includeHalfChecked` pour getCheckedNodes de Tree, #12014 ### 2.4.4 *2018-07-13* - Correction du déclenchement de la validation de Select après la réinitialisation du formulaire, #11837 - Correction d'une mauvaise position du slot `suffix` de Input lorsque le slot `suffixe` est avec le slot `append`, #11951 - Correction de Input affichant toujours l'icône clear même en lecture seule, #11967 - Correction d'un nœud d'arborescence coché lorsqu'il est désactivé, #11847 - Correction des `default-checked-keys` qui ne fonctionnait pas, #11971 - Correction de `empty-text` non visible lorsque le noeud de Tree est filtré, #11971 - Correction de la position du `empty-text` surdimensionné dans Table, #11965 - Correction de la surbrillance de la ligne de Table lorsque `current-row-key` est assignée à `null`, #11866 - Correction de l'affichage de la liste déroulante des filtres lorsque `filters` est un tableau vide, #11864 - Correction du label de Radio qui n'arrête pas la propagation des événements, #11912 ### 2.4.3 *2018-07-03* - Correction de `allow-drop` qui ne fonctionnait pas correctement lorsque les nœuds de Tree avaient une hauteur personnalisée, #11797 - Maintenant vous pouvez passer un paramètre à la méthode `clearValidate` du formulaire, en spécifiant quels résultats de validation FormItems doivent être effacés, #11821 - Ajout de l'attribut `distinguishCancelAndClose` pour MessageBox, #11831 ### 2.4.2 *2018-06-26* - Maintenant `class-name` et `label-class-name` de Table sont réactifs, #11626 - Correction de Table qui mettait toujours en surbrillance la ligne cliquée lorsque `highlight-current-row` était `false`, #11646 - Correction d'un bug de style de ButtonGroup lorsqu'il n'a qu'un seul bouton `round` ou `circle`, #11605 - Correction du style du Select de Pagination, #11622 - Correction de la méthode `open` du menu quand `collapse` est dynamiquement changé, #11646 - Ajout des paramètres `activeName` et `oldActiveName` au hook before-leave de Tabs, #11713 - Correction de Cascader ayant le focus après avoir cliqué à l'extérieur, #11588 - Correction de Cascader ne se fermant pas quand l'option est cliquée quand `change-on-select` est `true`, #11623 - La mise à jour programmatique de la valeur de Select déclenchera la validation du formulaire, #11672 ### 2.4.1 *2018-06-08* - Suppression du duplicata de la déclaration de type pour Autocomplete, #11388 - Correction du style de flèche déroulante de Select dans FireFox lorsqu'il est imbriqué dans Form, #11427 - Correction de l'icône de l'option de Select qui s'affiche toujours lorsque la valeur initiale est `null`, #11460 - Correction d'un Radio désactivé affichant l'ombre de la boîte quand on clique dessus, #11462 - Ajout de l'attribut `iconClass` pour MessageBox, #11499 - Ajout de l'attribut `stretch` pour Tabs, #11476 - Correction d'un problème d'ordre de rendu de TabPane lorsque Tabs est `lazy`, #11461 - Correction de Table ne conservant pas la surbrillance de la ligne actuelle lors de son ouverture, #11464 - Correction de l'état de la mise au point lorsque `before-leave` renvoie une promesse résolue, #11386 - Correction de la désactivation du Popover qui créait encore des poppers, #11426 - Correction de la boucle sans fin de Tree lorsqu'un nouveau noeud est ajouté en mode lazy, #11430 (par @wangjingf) - Ajout de l'événement `closed` pour Dialog, #11490 ### 2.4.0 Fullerene *2018-05-28* #### Nouvelles fonctionnalités - Général - L'outil de développement et le bundler sont basculés vers le webpack natif, #11216 - Vous pouvez maintenant définir globalement l'index z initial des popups, #11257 - Autocomplete - Ajout de l'attribut `hide-loading`, #11260 - Button - Vous pouvez maintenant utiliser l'attribut `size` sur les boutons circulaires pour contrôler leur taille, #11275 - InputNumber - Ajout de l'attribut `precision`, #11281 - Tabs - Ajout de l'attribut `before-leave`, #11259 - Ajout de l'attribut `lazy`, #11167(by @Kingwl) - Table - Ajout de la méthode `sort` pour trier manuellement la table, #11311 #### Corrections de bugs - Input - Correction d'un problème qui provoquait un re-rendu lors de l'utilisation de l'IME chinois pour saisir rapidement du texte, #11235 (par @STLighter) - Popover - Correction de l'erreur de console lorsque l'élément déclencheur est Radio ou Checkbox, #11265 - Breadcrumb - Correction de l'attribut `to` ne supportant pas la mise à jour dynamique, #11286 - Upload - Correction de l'erreur de console lorsqu'un fichier est résolu dans la promesse retournée de la méthode `beforeUpload`, #11297 (par @qusiba) - Infobulle - Correction d'une flèche mal positionnée lorsque le contenu est vide, #11335 - Autocomplete - Correction de suggestions d'entrée incorrectes après la suppression rapide d'un mot-clé, #11323 - ColorPicker - Correction d'un événement `active-change` se déclenchant incorrectement lorsque le menu déroulant du picker est fermé, #11304 - Table - Correction d'une erreur de style du panneau de filtre surdimensionné, #11314 - Correction de la ligne actuellement sélectionnée qui n'était pas conservée lors du tri de la table, #11348 - Checkbox - Correction d'une checkbox unique ne supportant pas la validation, #11271 - Radio - Correction du Radio désactivé quand même sélectionné en appuyant sur la touche espace, #11303 - MessageBox - Correction de la classe `el-popup-parent-hidden` qui n'était pas supprimée à l'ouverture successive de MessageBox, #11371 ### 2.3.9 *2018-05-18* - Correction d'une erreur lorsque les données source n'ont pas le champ spécifié par l'attribut `prop` d'une TableColumn, lorsque la souris se déplace dans les cellules de cette colonne, #11137 - L'attribut `lockScroll` des composants popup n'ajoute plus un style en ligne à l'élément parent, mais ajoute un nom de classe, #1111114 - Correction de l'icône de Progression qui ne s'affichait pas quand son `status` était une exception, #11172 - Correction de l'attribut `désactivé` qui ne fonctionnait pas dans la liste des résultats de filtrage du Cascader filtrable, #11185 - Correction d'un problème où la ligne étendue de la table ne peut pas être réduite si la source de données est mise à jour après son extension, #11186 - `setCurrentKey` de Tree accepte maintenant `null` comme paramètre pour annuler le noeud actuellement mis en surbrillance, #11205 ### 2.3.8 *2018-05-11* - Correction du saut du panneau DatePicker au mois courant après avoir choisi une date dans un mois non courant quand `type` est dates, #10973 - Correction de l'Input effaçable affichant toujours l'icône d'effacement en lecture seule, #10912 - Correction de la fermeture du panneau DatePicker sans changer la valeur déclenchant incorrectement l'événement `change`, #11017 - Correction d'un problème de navigation du clavier lorsque Select a regroupé les options, #11058 - Ajout du slot nommé `préfixe` pour Select, #11063 - Ajout de la méthode `clearValidate` pour FormItem, #11076 - Ajout de l'attribut `checkOnClickNode` pour Tree, #1111111 ### 2.3.7 *2018-04-29* - Correction d'une table qui ne mettait pas à jour ses largeurs de headers lorsque la barre de défilement disparaissait à cause du filtrage, #10834 - Correction de l'Input effaçable affichant toujours l'icône d'effacement lorsque sa valeur initiale est `null`, #10912 - Correction d'un déclencheur incorrect de l'événement `active-change` après avoir changé la valeur liée de ColorPicker par programmation, #10903 (par @zhangbobell) - Correction du Select filtrable qui provoquait une boucle infinie lors de la navigation dans les options à l'aide du clavier si toutes les options sont désactivées, #10945 ### 2.3.6 *2018-04-21* - Correction d'un comportement incorrect du callback `allow-drop` de Tree lorsque le paramètre `type` est utilisé, #10821 - Maintenant vous pouvez entrer correctement les mots-clés dans le Select simple filtrable dans IE11, #10822 - Correction d'un Select simple déclenchant incorrectement un événement `blur` après avoir cliqué sur une option, #10822 ### 2.3.5 *2018-04-20* - Correction d'une surbrillance incorrecte dans le panneau DatePicker lorsque `type` est la semaine, #10712 - Correction d'un InputNumber vide lorsque sa valeur initiale est 0, #10714 - Ajout de l'attribut `automatic-dropdown` pour Select, #10042 (par @Seebiscuit) - Correction de Rate désactivé quand même mis à jour par les touches de navigation, #10726 (par @Richard-Choooou) - L'attribut `type` de DatePicker peut être `dates`, où vous pouvez choisir plusieurs dates dans un sélecteur, #10650 (par @Mini256) - Ajout des événements `prev-click` et `next-click` pour Pagination, #10755 - Ajout de l'attribut `pager-count` pour Pagination, #10493 (par @chongjohn716) - Ajout de `type` comme 3ème paramètre de l'attribut `allow-drop` de Tree, #10792 - Nous utilisons maintenant ResizeObserver pour détecter le redimensionnement des éléments DOM, #10779 ### 2.3.4 *2018-04-12* - Suppression du double de l'attribut `showTimeout` dans la déclaration TypeScript de SubMenu, #10566 (par @kimond) - Vous pouvez maintenant personnaliser les éléments de Transfert en utilisant le scoped slot, #10577 - Correction d'un clic sur le bouton précédent désactivé et le bouton suivant de la pagination déclenchant toujours l'événement `current-current-change`, #10628 - Correction de Textarea affichant `undefined` dans le SSR lorsque sa valeur n'est pas définie, #10630 - Correction de la désactivation du style TabItem lorsque `type` est border-card, #10640 - Ajout de `$index` comme quatrième paramètre du `formatter` de la Table, #10645 - Correction de CheckboxButton non exporté dans la déclaration TypeScript, #10666 ### 2.3.3 *2018-04-04* - Ajout de l'attribut `shadow` pour Card, #10418 (par @YunYouJun) - Correction de Badge masqué lorsque `value` est `0`, #10470 - Correction de quelques bugs de Tree, #10474 #10494 - Ajout de `placement` pour Autocomplete, #10475 - L'attribut `default-time` fonctionne également dans DateTimePicker, #10321 (par @RickMacTurk) - Suppression du contour bleu de TabItem après que le navigateur n'ait plus le focus ou soit minimisé, #10503 - Ajout de l'attribut `popper-append-to-body` pour SubMenu, #10515 - Suppression du feedback visuel lors du survol d'un élément BreadcrumbItem non lié, #10551 - Correction de l'événement `change` d'InputNumber pour s'assurer que la valeur liée du composant est mise à jour dans le gestionnaire d'événements, #10553 ### 2.3.2 *2018-03-29* - Correction d'une régression d'Autocomplete, #10442 ### 2.3.1 *2018-03-29* - Correction d'une régression de `type` d'Inputqui n'était pas transmis à l'élément natif, #10415 - Ajout de la méthode `blur` pour Select, #10416 #### 2.3.0 Diamant *2018-03-28* #### Nouvelles fonctionnalités - Table - Maintenant le `formatter` de TableColumn peut être mis à jour dynamiquement, #10184 (par @elfman) - Ajout de l'attribut `select-on-indeterminate`, #9924 (par @syn-zeta) - Menu - Ajout de l'attribut `collapse-transition`, #8809 (par @limichange) - Input - Ajout de la méthode `select`, #10229 - Ajout de la méthode `blur`, #10356 - ColorPicker - Ajout de l'attribut `predefine`, #10170 (par @elfman) - Tree - Ajout des attributs `draggable`, `allow-drop` et `allow-drag`, et `node-drag-start`, `node-drag-enter`, `node-drag-leave`, `node-drag-leave`, `node-drag-over`, `node-drag-end` et `node-drop`, #9251 #10372 (par @elfman) - Form - La méthode `validate` a maintenant un deuxième paramètre, contenant l'information des éléments de formulaire qui ont échoué à la validation, #10279 - Ajout de l'événement `validate`, #10351 - Progress - Ajout de l'attribut `color`, #10352 (par @YunYouJun) - Button - Ajout de l'attribut `circle`, #10359 (par @YunYouJun) #### Corrections de bugs - Form - Correction du label de FormItem non aligné avec l'Input mixte, #10189 - Menu - Désormais, le menu réduit n'affichera la bulle d'aide que lorsque le slot `title` de l'élément MenuItem est défini, #10193 (par @PanJiaChen). - Pagination - Correction d'un événement `current-current-change` qui se déclenchait incorrectement sans interaction de l'utilisateur, #10247 - DatePicker - Maintenant, la date et l'heure dans le panneau déroulant sont correctement formatées en fonction de l'attribut `format`, #10174(by @remizovvv) - Upload - Correction de l'attribut `accept` qui ne fonctionnait pas quand `drag` est vrai, #10278 ### 2.2.2 *2018-03-14* - Ajout de l'événement `clear` pour Input, #9988 (par @blackmiaool) - Maintenant la saisie manuelle de ColorPicker supporte les modes `hsl`, `hsv` et `rgb`, #9991 - Correction de DatePicker ne déclenchant pas l'événement `change` lorsque sa valeur initiale est effacée, #9986 - Maintenant les attributs liés à la classe d'icônes de Rate supportent les mises à jour dynamiques, #10003 - Correction de Table avec des colonnes fixes dont la hauteur n'est pas mise à jour correctement si `max-height` est réglé, #10034 - Maintenant le mode plage de DatePicker supporte la sélection inverse (en cliquant sur la date de fin, puis sur la date de début), #8156 (par @earlymeme) - Ajout de l'attribut `désactivé` pour Pagination, #10006 - Ajout des événements `after-enter` et `after-leave` pour Popover, #10047 - Correction de Select ne déclenchant pas la validation lorsque l'utilisateur sélectionne une option après avoir exécuté `resetFields` du formulaire, #10105 - Correction des largeurs incorrectes des colonnes fixes de Table dans certains cas, #10130 - Correction de MessageBox héritant de l'attribut `title` de son instance précédente lorsqu'il était appelé sans `title`, #10126 (par @Pochodaydaydayup) - Ajout de l'attribut `input-size` pour Slider, #10154 - Ajout des événements `left-check-change` et `right-check-change` pour Transfer, #10156 ### 2.2.1 *2018-03-02* - Correction d'un rétrécissement de Aside, Header et Footer dans certaines mises en page, #9812 - Correction de Table avec un attribut `height` qui ne rendait pas dans SSR, #9876 - Correction d'une Table extensible ne calculant pas sa hauteur lorsqu'une rangée est agrandie, #9848 - Correction d'un événement `change` qui ne se déclenchait pas lors de la saisie manuelle de la date dans DateTimePicker, #9913 - Correction de Select affichant ses options lorsque la boîte de saisie est cliquée avec le bouton droit de la souris, #9894 (par @openks) - Ajout de l'attribut `tooltip-class` pour Slider, #9957 - Maintenant Select garde le focus après la sélection, #9857 (par @Seebiscuit) - Ajout de l'attribut `target-order` pour Transfer, #9960 ### 2.2.0 Graphite *2018-02-12* #### Nouvelles fonctionnalités - Menu - Ajout des attributs `popper-class` et `disabled` pour le sous-menu, #9604 #9771 - Le menu horizontal prend maintenant en charge le sous-menu multicouche, #9741 - Tree - Ajout de l'évènement `node-contextmenu`, #9678 - Vous pouvez maintenant personnaliser le modèle de nœud en utilisant un slot avec portée, #9686 - Ajout des méthodes `getNode`, `remove`, `remove`, `append`, `insertBefore`, `insertAfter`, `getCheckedKeys`, `getHalfCheckedNodes`, `getHalfCheckedNodes`, `getHalfCheckedKeys` et de l'événement `check`, #9718 #9730 - Transfer - Ajout de la méthode `clearQuery`, #9753 - Select - Ajout de l'attribut `popper-append-to-body`, #9782 #### Corrections de bugs - Table - Correction d'un clic sur l'icône d'expansion d'une ligne extensible qui déclenche l'événement `row-click`, #9654 - Correction de la mise en page non mise à jour lorsque la largeur des colonnes est modifiée par glisser-déposer de l'utilisateur, #9668 - Correction d'un problème de style lorsque la ligne de résumé coexiste avec des colonnes fixes, #9667 - Container - Les composants fixes de Container ne s'étirent pas dans IE11, #9655 - Loading - Correction du chargement n'apparaissant pas lorsque la valeur de `v-loading` est changée en true dans le hook `mounted`, #9722 - Switch - Correction de deux événements de clics natifs déclenchés lorsque Switch est cliqué, #9760 ### 2.1.0 Charcoal *2018-01-31* #### Nouvelles fonctionnalités - Cascader - Ajout des événements `focus` et `blur`, #9184 (par @viewweiwu) - Table - La méthode `filter-method` a maintenant un troisième paramètre `column`, #9196 (par @liyanlong) - DatePicker - Ajout des attributs `prefix-icon` et `clear-icon`, #9237 (par @AdamSGit) - Ajout de l'attribut `default-time`, #9094 (par @nighca) - Le format `value-format` supporte maintenant `timestamp`, #9319 (par @wacky6) - InputNumber - Maintenant la valeur liée peut être `undefined`, #9361 - Select - Ajouté l'attribut `auto-complete`, #9388 - Form - Ajout de l'attribut `désactivé`, #9529 - Ajout de l'attribut `validateOnRuleChange`, #8141 - Notification - Ajout de la méthode `closeAll`, #9514 #### Corrections de bugs - InputNumber - Correstion du reset lors de la saisie du point des nombres décimaux, #9116 - Dropdown - Correction du mauvais positionnement du menu déroulant lorsque la page n'a qu'une barre de défilement horizontale dans certains navigateurs, #9138 (par @banzhuanmei) - Table - Correction d'une erreur dans le calcul du nombre de colonnes fixes après les changements de données des colonnes, #9188(by @kolesoffac) - Correction de la bordure de la dernière colonne de l'en-tête groupé qui n'était pas correctement affichée, #9326 - Correction d'un positionnement incorrect de l'en-tête du tableau dans Safari, #9327 - Correction de la réduction des lignes extensibles lorsque les données de la table changent, #9462 - Correction de rendus multiples inutiles dans certaines conditions, #9426 - Correction d'une erreur de calcul de la largeur de colonne lors de la modification de `width` de TableColumn, #9426 - Loading - Correction de Loading ne se cachant pas correctement dans certaines conditions, #9313 - DatePicker - Correction de la méthode `focus` qui ne fonctionnait pas en mode "range", #9437 - Correction du clic sur le bouton "now" qui sélectionnait toujours la date actuelle même si elle était désactivée, #9470 (par @wacky6) - Correction d'une date trop serrée lors de la navigation, #9577 (par @wacky6) - Steps - Correction d'une erreur de style dans IE 11, #9454 #### Changements - Menu - Le menu contextuel en mode `collapse` s'ajoute maintenant directement à `body`, de sorte qu'il est visible lorsqu'il est imbriqué dans Aside, #9263 - Table - Maintenant, cocher les cases dans la Table multi-sélection ne déclenche pas l'événement `row-click`, #9467 - Loading - Le `z-index` du masque de chargement non plein écran est changé à 2000. Le `z-index` du masque de chargement plein écran se mettra à jour dynamiquement avec les composants popup, #9522 - Dropdown - Les attributs `show-timeout` et `hide-timeout` ne fonctionnent maintenant que lorsque le déclencheur est `hover`, #9573 ### 2.0.11 *2018-01-08* - Correction d'un problème de couleur de bordure de Select dans les slots `prepend` ou `append` de Input, #9089 - Correction du paramètre `remove-tag` de l'événement Select, #909090 - Ajout des attributs `show-timeout` et `hide-timeout` pour le sous-menu, #8934 (par @HugoLew) - Correction d'un style Tooltip manquant de `show-overflow-tooltip` lors de l'importation de Table sur demande, #9130 - Correction d'un dysfonctionnement du tri des colonnes de la table après l'exécution de `clearSort` sur cette colonne, #9100 (par @zEmily) - Le fichier de configuration i18n pour le tchèque est renommé de `cz` en `cs-CZ`, #9164 ### 2.0.10 *2017-12-29* - Calcul erroné de la hauteur du tableau lorsque la colonne fixe et la ligne de somme coexistent, #9026 - Correction d'un style de couleur non compilé du texte vide dans le tableau, #9028 - Maintenant, DatePicker n'émet que l'événement `change` quand la valeur est vraiment changée, #9029 (par @remizovvvv) - Ajout de l'attribut `tabindex` pour Input, #9041 (par @dicklwm) ### 2.0.9🎄 *2017-12-24* - Ajouté la fonction de hook "avant suppression" pour Upload, #8788 (par @firesh) - Correction de la valeur initiale de `error` qui ne fonctionnait pas pour FormItem, #8840 - La directive Loading prend maintenant en charge le nom de classe personnalisé grâce à l'attribut `element-loading-custom-class`, #8826 (par @earlymeme) - Correction CarouselItem devenant invisible lorsque les données sont mises à jour de manière asynchrone, #8921 - Ajout de l'attribut `renderAfterExpand` pour Tree, #8972 ### 2.0.8 *2017-12-12* - Ajout de la documentation en espagnol - Correction du `show-timeout` de Dropdown qui ne fonctionnait pas quand le déclencheur est click, #8734 (par @presidenten) - Correction du temps de validation des formulaires pour les règles dont le déclencheur est blur, #8776 - Correction d'un événement de blur de DatePicker avec intervalle, #8784 - L'attribut `format` de TimePicker supporte maintenant AM/PM, #8620 (par @firesh) ### 2.0.7 *2017-11-29* - Correction du style du bouton de type texte désactivé, #8570 ### 2.0.6 *2017-11-29* - Correction d'un bug de style des icônes de tri de la table, #8405 - Correction du mécanisme de déclenchement de Popover lorsque son `trigger` est manuel, #8467 - Ajout des attributs `prefix-icon` et `suffix-icon` pour Autocomplete, #8446 (par @liyanlong) - Ajout de l'attribut `separator` pour Cascader, #8501 - Ajout de l'attribut `clearable` pour Input, #8509 (par @lbogdan) - Ajout de l'attribut `background` pour Pagination, #8553 ### 2.0.5 *2017-11-17* - Correction de la régression Popover, Tree, Breadcrumb et Cascader dans 2.0.4, #8188 #8217 #8283 - Correction d'une fuite de mémoire de la directive `clickoutside`, #8168 #8225 (par @badpunman @STLighter) - Correction de la hauteur du Select multiple lorsque sa valeur est effacée, #8317 (par @luciy) - Ajout de l'attribut `collapse-tags` pour plusieurs Sélectionner pour remplacer les balises par une ligne de texte, #8190 - Correction d'une consommation CPU élevée causée par la table cachée, #8351 - Maintenant vous pouvez utiliser la méthode `doLayout` de la Table pour mettre à jour sa disposition, #8351 ### 2.0.4 *2017-11-10* - Accessibilité améliorée pour Cascader, Dropdown, Message, Notification, Popover, Tooltip et Tree. - Correction du redimensionnement de Container lorsque la largeur de la fenêtre d'affichage diminue, #8042 - Correction de la suppression incorrecte de `updateKeyChildren` dans Tree, #8100 - Correction de la hauteur de la CheckboxButton avec bordure lorsque le bouton est imbriqué dans un formulaire, #8100 - Correction d'une erreur d'analyse du menu pour les couleurs personnalisées, #8153 (par @zhouyixiang) ### 2.0.3 *2017-11-03* - Correction des attributs `éditable` et `readonly` pour DatePicker avec intervalle, #7922 - Correction d'une erreur de style des Tabs imbriqués, #7941 - Correction d'une erreur de style de la dernière étape des Steps verticales, #7980 - Correction de la synchronisation du déclenchement de l'événement `current-current-change` pour Pagination, #7995 - Correction d'une infobulle non enregistrée dans Menu, #7995 ### 2.0.2 *2017-10-31* - Un clic droit sur les boutons de InputNumber ne changera pas sa valeur, #7817 - La méthode `validate` de Form peut maintenant attendre des validations asynchrones avant d'exécuter son callback, #7774 (par @Allenice) - Correction de la plage de sélection de DatePicker ne fonctionnant pas dans les navigateurs Chromium 53-57, #7838 - Correction des icônes manquantes de prévisualisation et de suppression de Upload lorsque son `list-type` est picture-card, #7857 - Ajout de l'attribut `sort-by` pour TableColumn, #7828 (par @wangfengming) - Correction de DatePicker affichant parfois un mauvais numéro d'année lors de la sélection de la première semaine en mode semaine, #7860 (par @hhh23485) - Correction d'une erreur de style d'icône des Steps verticales, #7891 - La 'hot area' pour les flèches de nœud dans Tree est étendue, #7891 ### 2.0.1 *2017-10-28* - Correction d'une erreur de style de RadioButton et CheckboxButton, #7793 - Correction de TimePicker qui ne répondait pas au défilement de la souris dans certaines conditions, #7811 - Correction des styles incomplets de certains composants lors de l'importation à la demande, #7811 ### 2.0.0 Carbon *2017-10-27* #### Nouvelles fonctionnalités - Général - Un nouveau thème : `theme-chalk`. - L'accessibilité des éléments suivants est améliorée : Alert, AutoComplete, Breadcrumb, Button, Checkbox, Collapse, Input, InputNumber, Menu, Progress, Radio, Rate, Slider, Switch, Upload - Ajout du typage TypeScript - Toutes les icônes existantes sont redessinées. De nouvelles icônes sont ajoutées - Ajout d'une série de classes basées sur les breakpoints qui masquent les éléments lorsque la taille de la fenêtre remplit certaines conditions - Ajout des composants de mise en page : Container, Header, Aside, Main, Footer - Vous pouvez maintenant configurer la taille des composants de manière globale. Lors de l'importation d'un élément, vous pouvez ajouter un objet de configuration global avec une propriété `size` pour configurer les tailles par défaut pour tous les composants. - Button - Ajout de l'attribut `round`. Il est utilisé pour les boutons à coins ronds #6643 - TimeSelect - Vous pouvez maintenant naviguer en appuyant sur les touches `Up` et `Down`, et en appuyant sur `Enter` vous sélectionnez l'heure #6023. - TimePicker - Vous pouvez maintenant naviguer à l'aide des touches fléchées, et en appuyant sur `Entrée` vous sélectionnez l'heure #6050. - Ajout de `start-placeholder` et de `end-placeholder`. Ce sont des placeholders pour les deux champs en mode intervalle #7169 - Ajout de l'attribut `farrow-control` pour faire tourner le temps avec les flèches #7438 - Tree - Maintenant les noeuds enfants ne font pas de rendu avant la première ouverture #6257 - Ajout de l'attribut `check-descendants`. Il détermine si les nœuds enfants sont vérifiés lors du contrôle de leur nœud parent en mode `lazy` #6235 - Tag - Ajouté l'attribut `size` #7203 - Datepicker - Maintenant `timeFormat` peut formater le TimePicker quand le type est réglé sur `datetimerange` #6052 - Ajout de `start-placeholder` et de `end-placeholder`. Ce sont des placeholders pour les deux champs en mode intervalle #7169 - Ajout de l'attribut `value-format` pour personnaliser le format de la valeur liée, #7367 - Ajout de l'attribut `unlink-panels` pour dissocier les deux panneaux de date lors de la sélection d'une plage de dates - MessageBox - Ajout de l'attribut `closeOnHashChange` #6043 - Ajout de l'attribut `center` pour que le contenu puisse être centré #7029 - Ajout de l'attribut `roundButton` pour afficher les boutons ronds #7029 - Ajout de l'attribut `dangerouslyUseHTMLString`. Lorsqu'il est réglé sur `true`, `message` sera interprété comme une chaîne HTML\* #6043 - Ajout de l'attribut `inputType` pour assigner le type de l'input intérieur, #7651 - Dialog - Ajout des attributs `width`、`fullscreen`、`append-to-body`. La boîte de dialogue peut maintenant être imbriquée - Ajout de l'attribut `center` pour que le contenu puisse être centré #7042 - Ajout de `focus-after-closed`、`focus-after-open` pour améliorer l'accessibilité #6511 - ColorPicker - Maintenant vous pouvez taper les couleurs dans le champ de saisie #6167 - Ajout des attributs `size` et `disabled` #7026 - Ajout de l'attribut `popper-class` #7351 - Message - Maintenant la couleur des icônes peut être modifiée par CSS #6207 - Ajout de l'attribut `dangerouslyUseHTMLString`. Lorsqu'il est réglé sur `true`, `message` sera interprété comme une chaîne HTML\* #6207 - Ajout de l'attribut `center` pour que le contenu puisse être centré #6875 - Notification - Ajout de l'attribut `position` pour configurer où Notification apparaît #6231 - Ajout de l'attribut `dangerouslyUseHTMLString`. Lorsqu'il est réglé sur `true`, `message` sera interprété comme une chaîne HTML\* #6231 - Ajout de l'attribut `showClose` pour cacher le bouton de fermeture #6402 - Rate - Ajout de l'attribut `show-score` pour déterminer si le score actuel est affiché #6295 - Tabs - Ajout de l'attribut `tab-position` #6096 - Radio - Ajout des attributs `border` et `size` #6690 - Checkbox - Ajout des attributs `border` et `size` #6690 - Alert - Ajout de l'attribut `center` pour que le contenu puisse être centré #6876 - Menu - Ajout des attributs `background-color`, `text-color` et `active-text-color` #7064 - Ajout des méthodes `open` et `close` pour ouvrir et fermer les sous-menus par programmation, #7412 - Form - Ajout de l'attribut `inline-message` pour déterminer si le message de validation est affiché en ligne #7032 - Ajout de l'attribut `status-icon` pour afficher une icône de feedback après validation #7032 - Form et FormItem ont maintenant un attribut `size`. Les composants internes hériteront de cette taille s'ils ne sont pas spécifiés sur eux-mêmes, #7428 - La méthode `validate` retournera maintenant une promesse si le rappel est omis, #7405 - Ajout de la méthode `clearValidate` pour la validation des résultats pour tous les éléments de formulaire, #7623 - Input - Ajout des attributs `suffixe` et `préfixe` des slots nommés, `suffixIcon` et `prefixIcon` pour ajouter du contenu dans la zone de saisie #7032 - Breadcrumb - Ajout de l'attribut `separator-class` pour supporter les icônes comme séparateurs d'éléments #7203 - Steps - Ajout de l'attribut `simple` pour activer les étapes de style simple #7274 - Pagination - Ajout des attributs `prev-text` et `next-text` pour personnaliser les textes des pages précédente et suivante #7005 - Loading - Maintenant vous pouvez personnaliser l'icône et la couleur de fond avec les propriétés `spinner` et `background` #7390 - Autocomplete - Ajout de l'attribut `debounce`, #7413 - Upload - Ajout des attributs `limit` et `on-exceed` pour limiter le nombre de fichiers, #7405 - DateTimePicker - Ajout de l'attribut `time-arrow-control` pour activer `arrow-control` du TimePicker imbriqué, #743838 - Layout - Ajout d'un nouveau point d'arrêt `xl` pour les fenêtres plus larges que 1920px - Table - Ajout de l'attribut `span-method` pour la fusion de cellules - Ajout de la méthode `clearSort` pour effacer le tri par programmation - Ajout de la méthode `clearFilter` pour effacer le filtre par programmation - Pour les lignes extensibles, lorsqu'une ligne est étendue, une classe `.expanded` sera ajoutée à sa liste de classes, afin que vous puissiez personnaliser son style - Ajout de l'attribut `size` - Ajout de la méthode `toggleRowExpansionRowExpansion` pour ouvrir ou réduire les lignes extensibles par programmation - Ajout de l'attribut `cell-class-name` pour assigner un nom de classe aux cellules - Ajout de l'attribut `cell-style` pour le style des cellules - Ajout de l'attribut `header-row-class-name` pour assigner un nom de classe aux lignes d'en-tête - Ajout de l'attribut `header-row-style` pour le style d'en-tête - Ajout de l'attribut `header-cell-class-name` pour assigner un nom de classe aux cellules d'en-tête - Ajout de l'attribut `header-cell-style` pour le style des cellules d'en-tête - L'attribut `prop` de la tableColumn accepte maintenant les notations `object[key]` - Ajout de l'attribut `index` pour TableColumn pour personnaliser les index de lignes - Select - Ajout de l'attribut `reserve-keyword` pour réserver le mot-clé de la recherche courante après avoir sélectionné une option. #### Corrections de bugs - DatePicker - Correction de `v-model` retournant le deuxième jour de la semaine sélectionnée en mode semaine #6038 - Correction de la première entrée effacée dans le type `daterange` #6021 - DateTimePicker - Correction de DateTimePicker et TimePicker s'affectant l'un l'autre lors de la sélection #6090 - Correction de l'heure et de la seconde qui peuvent être au-delà de la limite en sélectionnant l'heure #6076 - TimePicker - Correction de `v-model` qui ne se mettait pas à jour correctement lors du blur #6023 - Dialog - Correction des textes ayant des bords flous lors de l'ouverture et de la fermeture des listes déroulantes imbriquées #6088 - Select - Performances améliorées. Maintenant Vue dev-tool ne crashera pas quand un grand nombre de Select sont détruits #6151 - Table - Correction d'un bug ou la table reste masquée lorsque son élément parent apparaît depuis `display : none` - Correction de l'extension de la largeur de la table lorsque l'élément parent a `display : flex` - Correction d'un bug qui corrigeait le fait que les colonnes d'une table avec l'emplacement `append` disparaissaient lorsque les données étaient récupérées dynamiquement - Correction de l'attribut `expand-row-keys` qui ne fonctionnait pas avec la valeur initiale - Correction d'une défaillance du filtre lors de la mise à jour de `data` - Correction d'une erreur de calcul dans la mise en page des colonnes fixes avec en-têtes groupés - Correction d'un bug dynamique de `max-height` - Correction de quelques erreurs de calcul de style #### Breaking changes - Général - Suppression de `theme-default`. - Compatible avec Vue 2.5.2+ et IE 10+ - L'événement `change` des composants de formulaire et l'événement `current-current-change` de la pagination ne se déclenchent plus que lors de l'interaction de l'utilisateur - L'attribut `size` de Button et les composants de formulaire acceptent maintenant `medium`, `small` et `mini` - Pour faciliter l'utilisation d'icônes tierces, les attributs `icon` du bouton et des étapes, `prefix-icon` et `suffix-icon` d'Input nécessitent maintenant un nom de classe complet - Dialog - Suppression de l'attribut `taille`. Maintenant la taille de Dialog peut être configurée par `width` et `fullscreen` - Maintenant la visibilité de Dialog ne peut plus être contrôlée par `v-model` - Rate - Le `text-template` est renommé `score-template` - Dropdown - `menu-align` est renommé en `placement`. Maintenant il supporte plus de positions - Transfert - le `footer-format` est renommé en `format` - Switch - Les attributs commençant par `on-**` seront analysés pour les événements dans JSX, ce qui rend tous les attributs `on-*` de Switch incapable de fonctionner en JSX. Ainsi, les attributs `on-**` sont renommés en `active-*`, et par conséquent les attributs `off-*` sont renommés en `inactive-*`. Cette modification affecte les attributs suivants: `on-icon-class`, `off-icon-class`, `on-text`, `off-text`, `off-text`, `on-color`, `off-color`, `on-value`, `off-value` - Les attributs `active-text` et `inactive-text` n'ont plus de valeurs par défaut - Tag - L'attribut `type` accepte maintenant `success`, `info`, ` warning` et `danger` - Menu - Suppression de l'attribut `theme`. La couleur du menu peut être configurée en utilisant `background-color`, `text-color` et `active-text-color` - Input - Suppression de l'attribut `icon`. L'icône du suffixe peut maintenant être configurée à l'aide de l'attribut `suffix-icon` ou du slot `suffix-icon` - Suppression de l'attribut `on-icon-click` et de l'événement `click`. Maintenant pour ajouter le gestionnaire de clic sur les icônes, veuillez utiliser les slots nommés - L'événement `change` se comporte maintenant comme dans l'input natif, qui ne se déclenche qu'en cas de blur ou en appuyant sur Entrée. Si vous avez besoin de répondre à l'entrée de l'utilisateur en temps réel, vous pouvez utiliser l'événement `input` - Autocomplete - Suppression de l'attribut `custom-item`. Le template de suggestions d'entrée peut maintenant être personnalisé en utilisant `scoped slot`. - Suppression de l'attribut `props`. Vous pouvez maintenant utiliser l'attribut `value-key` pour désigner le nom de clé de l'objet de suggestion d'entrée pour l'affichage. - Steps - Suppression de l'attribut `center` - Maintenant le Steps va remplir son conteneur parent par défaut - DatePicker - Le paramètre de l'événement `change` de DatePicker est maintenant la valeur liée elle-même. Son format est contrôlé par `value-format` - Table - Suppression de la prise en charge de la personnalisation du modèle de colonne à l'aide de `inline-template` - `sort-method` s'aligne maintenant avec `Array.sort`. Il devrait retourner un nombre au lieu d'un booléen - L'emplacement `append` est déplacé à l'extérieur de l'élément `tbody` pour éviter les rendus multiples - L'événement `expand` est renommé en `expand-change` - Les paramètres de la méthode `row-class-name` et `row-style` sont maintenant un objet ## * Rendre du HTML arbitraire de façon dynamique sur votre site Web peut être très dangereux car cela peut facilement mener à[des attaques XSS](https://en.wikipedia.org/wiki/Cross-site_scripting). Donc quand `dangerouslyUseHTMLString' est activé, assurez-vous que le contenu du `message' est fiable, et **ne jamais** assigner `message` au contenu fourni par l'utilisateur.. ================================================ FILE: CHANGELOG.zh-CN.md ================================================ ## 更新日志 ### 2.15.14 *2023-08-24* #### Bug 修复 - Img - 删除 referrerpolicy 属性 (#22651 by @xinguanhua) #### 优化 - Docs - 更新 readme and website example links (#22642 by @lyfeyaj) - 更新 popper 官方文档链接 (#22539 by @brizer) - I18n - 更新 西班牙语 翻译 (#22430 by @jcardus) - 新增 塞尔维亚语(拉丁) 翻译 (#22567 by @N-M) - 更新 乌兹别克语 翻译 (#22390 by @akahon) - Statistics - 文档更新; 代码优化 (#22384 by @webvs2) - Table - 增加高亮选中行属性 (#22382 by @wangdaodao) ### 2.15.13 *2023-02-12* #### Bug 修复 - Docs - 修复 Statistic 文案 (#22383 by @JUST-Limbo) - 修复 Input 文案 (#22093 by @lm312) - 修复 en-US 文案 (#22268 #22269 #22270 by @Hazel-Lin) - 修复 Pagination 文案 (#22288 by @xujintai123) - 修复 Links 文案 (#22370 by @itmier) - Statistics - 修复 slot 显示问题 (#22375 by @webvs2) - Chore - 修复 web-type 文件丢失问题 (#22271 by @loosheng) #### 优化 - InputNumber - windows触摸屏响应优化 (#22185 by @mrsai) - Image - 新增 initialIndex 属性 (#22346 by @inkroom) - Statistics - countdown 特性更新 (#22260 by @webvs2) - 代码优化及doc更新 (#22276 by @webvs2) - 其他 - web-type代码优化 (#22281 by @whzxc) ### 2.15.12 *2022-11-16* #### Bug 修复 - Statistics - 修改 千分位 问题 (#22252 by @webvs2) - 其他 - 修复 2.15.11版本element-theme-chalk未成功发布 问题 ### 2.15.11 *2022-11-15* #### Bug 修复 - Docs - 修复 Radio 文案 (#22178 by @bchen1029) - 修复 Progress 文案 #### 优化 - I18n - 更新 马来西亚语 翻译 (#22185 by @z4q) - 更新 挪威语 翻译 (#22145 by @Barsnes) - Progress - 新增 defineBackColor 和 textColor 属性 (#22089 by @lm312) - Statistics - 新增组件 Statistics (#22159 by @webvs2) - Other - 改进WebStorm IDE和其他JetBrains IDE中的代码帮助 (#22135 by @piotrtomiak) ### 2.15.10 *2022-09-13* #### Bug 修复 - DatePicker - 修复 props placement 报错信息 问题 (#21908 by @lqzhgood) - Loading - 修复 使用 Loading 的DOM元素 sticky失效 问题 (#22087 by @zzjjhh001) - Docs - 修复 Popover 文案 (#22083 by @lm312) - 修复 Skeleton 文案 (#22092 by @lm312) - 修复 DatePicker 文案 (#21970 by @guojiongwei) - Tree - 修复 懒加载默认选中 问题 (#21934 by @kiss-yu) #### 优化 - I18n - 新增 僧伽罗语 翻译 (#21936 by @sayuri-gi) - 更新 西班牙语 翻译 (#21924 by @jcardus) - 新增 马来西亚语 翻译 (#22028 by @iorange0411) - 更新 斯瓦希里语 翻译 (#21904 by @Cholowao) - Utils - 更新 date-util.js (#22099 by @Due07) - DatePicker - 新增 months 和 years 类型 (#21918 by @akiko123456) ### 2.15.9 *2022-06-02* #### Bug 修复 - Table - 表头抖动修复 (#21863 by @bofeng) - 按需引用时 `el-checkbox not imported` 修复 (#21828 by @bobohuochai) - FormItem - 修复 rules 切换为 null 时校验未重置 问题 (#21892 by @bofeng) - Cascader - 修复 切换 options 时错误报错信息 问题 (#21759 by @louiebb) - Docs - 修复 Popover 文案 (#21843 by @lod61) - 修复 Calendar 文案 (#21814 by @GoJam11) - 修复 TimePicker 文案 (#21803 by @Alanscut) - 修复 DatePicker 文案 (#21877 by @Nirvanaiu) - 其他 - 官网在线演示功能修复 (#21863 by @bofeng) #### 优化 - I18n - 新增 斯瓦希里语 翻译 (#21895 by @quilltouch) - Chore - 本地开发时可从 devTools 工具跳转源代码 (#21633 by @polemices) - DatePicker & Cascader - 弹窗方向优化 (#21806 by @XivLaw) - Tooltip - 优化 `getFirstElement` 代码 (#21886 by @zhankang) - Input - 优化 scss 代码 (#21558 by @cheese-git) ### 2.15.8 *2022-04-12* #### Bug 修复 - Drawer - 修复 appendToBody 失效问题 (#21264 by @cs1707) - Switch - 修复 toggling value 问题(#19473 by @EdwinBetanc0urt) - Docs - 修复 input 文案 (#21723 by @justforuse) - 修复 DatePicker 文案 (#21663 by @justforuse) - 修复 Skeleton 文案 (#21601 by @yanwydxf) - 其他 - 修复 vue 版本(#21736 by @ckvv) #### 优化 - I18n - 新增 阿塞拜疆语 翻译 (#21012 by @ricardotondello) - 更新 斯洛文尼亚语 翻译 (#21729 by @patik123) - 更新 斯洛伐克语 翻译 (#21711 by @sjaustirni ) - 新增 冰岛语 的翻译 (#21709 by @aronhr) - 新增 孟加拉 语的翻译 (#21485 by @llwwtt) #### 其他 - 因兼容性考虑,撤回2.15.7关于node-sass的更新(#21019 by @linxsbox),重新评估后会在后续合适版本上线 ### 2.15.7 *2021-11-18* #### Bug 修复 - Select - 修复 filter 模式下,点击图标不能触发下拉的 bug (#21314 by @dennyak47) - 修复 composition 模式下 keydown 事件 (#21336 by @bchen1029) - Badge - 修复 is-dot class (#21308 by @adaex) - Form - validate 方法返回错误信息 (#21374 by @cs1707) - Table - 修复 resizeObserver loop limit exceeded (#21255 by @tomieric) - 修复 toggleAllSelection (#21456 by @cs1707) - 优化 table 性能 (#21330 by @cs1707) - Button - 修复 disabled 优先级 (#21375 by @cs1707) - Descriptions - 修复 label slot bug (#21462 by @cs1707) - SASS - node-sass 替换为 dart-sass (#21019 by @linxsbox) - Docs - 修复 skeleton 文案 (#21408 by @zhhbstudio) ### 2.15.6 *2021-09-02* #### Bug 修复 - Cascader - 修复浏览器缩放模式下抖动的 bug (#21207 by @cs1707) - 优化性能 (#21231 by @cs1707) - Select - 修复多选模式下文字溢出的 bug (#21237 by @cs1707) - Dropdown - 增加 disabled 属性 (#21235 by @mshioda) - Radio - 修复浏览器返回后保留状态的 bug (#21250 by @cs1707) - Descriptions - 修复类型定义 (#21265 by @adaex) - 修复与表格组件混用样式冲突的问题 (#21254 by @adaex) - Drawer - 修复 append-to-body (#21264 by @cs1707) - Local - 修复 italian 翻译错误 (#21012 by @ricardotondello) ### 2.15.5 *2021-08-04* #### Bug 修复 - Select - 修复 resetInputHeight 报错的 bug (#21201 by @cs1707) ### 2.15.4 *2021-08-03* #### 新特性 - Descriptions - 新增 Descriptions 组件 (#21129 by @cs1707) - Result - 新增 Result 组件 (#21171 by @cs1707) #### Bug 修复 - Utils - 修复 isScroll (#21098 by @canvascat) - Translation - 更新 it.js (#21133 by @bliberi) - RadioGroup - 修复 RadioGroup 与 component 兼容的 bug (#20783 by @lceric) - Message - 修复 message[type] (#21088 by @cs1707) - Carousel - 修复 setActiveItem 重置计时 (#20846 by @Nekojita1) - Cascader - 修复 emitPath (#21185 by @cs1707) - Select - 修复 filterable bug (#17494 by @profore) - 修复浏览器缩放模式下抖动的 bug (#21197 by @cs1707) - Tree - 修复 insertChild (#21194 by @cs1707) ### 2.15.3 *2021-06-29* #### 新特性 - Skeleton - 新增 Skeleton 组件 (#21038 by @cs1707) - Empty - 新增 Empty 组件 (#21080 by @cs1707) #### Bug 修复 - Local - 修复 hr 语言 week 翻译 (#21040 by @cs1707) - Table - 修复 lazy load data (#21041 by @cs1707) - Docs - 修改 form 组件 hide-required-asterisk 描述 (#21045 by @cs1707) - Drawer: - 修复 destroy (#20715 by @zj9495) - Row - 修复 align top (#20963 by @cs1707) - Select - 修复 value 为 Boolean 类型的bug (#21052 by @cs1707) - Calendar - 修复 first-day-of-week (#21057 by @cs1707) - Utils - 修复 fix isScroll (#21065 by @cs1707) - 修复 (utils.dom by @fw6) - TypeScript - 增加 CascaderPanel 类型导出 (#21070 by @qige2016) - 增加 spinner.d.ts (#21090 by @qige2016) ### 2.15.2 *2021-05-28* #### Bug 修复 - Image - 修复 z-index 增加 keydown 事件 添加 stopPropagation (#20859 by @cs1707) - Input - 修复 password cursor 展示 (#20870 by @cs1707) - 修复 password icon 在 edge 下的展示 (#20902 by @cs1707) - Carousel - 修复 interval 和 scale bug (#20931 by @cs1707) - Cascader - 修复 delete tag bug (#20939 by @cs1707) - Drawer - 支持 overflow auto (#20948 by @cs1707) - 其他 - 修复 isFunction (#20912 by @cs1707) ### 2.15.1 *2021-02-23* #### Bug 修复 - Drawer - 修复 Drawer bug (by @cs1707) - Image - 修复 image object fit ratio 在 IE 下的 bug (#19583 by @charlie0228) - Cascader - 修复 cascader panel active path (#20730 by @cs1707) - Calendar - 修复 calendar 国际化 bug (#20758 by @iamkun) - ColorPicker - 修复 bugs (by @UxieVerity) #### 优化 - Doc - 更新 Axure 设计资源 v2.1.0 (by @iamkun) ### 2.15.0 *2021-01-15* #### Bug 修复 - Select - 修复 placeholder 国际化 bug (#17644 by @nzh63) - Popconfirm - 修复 Popconfirm 国际化 bug by @iamkun - Drawer - 修复 focus bug (#20626 by @cs1707) - Image - 图片预览优化 (#20652 by @cs1707) #### 优化 - Doc - 更新法语文档 datetime-picker.md (#20543 by @lonk) - 更新 Progress 组件文档 (#20641 by @cs1707) ### 2.14.1 *2020-11-11* #### Bug 修复 - Popover - 兼容 Vue 2.6 新 v-slot 语法 (#20424 by @iamkun) #### 优化 - I18n - 更新阿拉伯语翻译 (#20202 by @elkattan) - 更新维吾尔语翻译 (#20177 by @IlhamTahir) ### 2.14.0 *2020-10-29* #### 非兼容性更新 - Popconfirm - 事件名称修改为 `confirm`, `cancel` (#20240 by @hugiron) #### Bug 修复 - Progress - 修复参数错误的问题 (#19985 by @Caaalabash) #### 优化 - I18n - 更新俄语翻译 (#19451 by @yangirov) - 更新高棉语翻译 (#20077 by @Sovai) - 更新乌克兰语翻译 (#20344 by @MammutAlex) ### 2.13.2 *2020-05-18* #### Bug 修复 - Autocomplete - 修复 'change event' 错误 (#19200 by @sxzz) - Image - 更新错误状态 (#19194 by @lhx6538665) #### 优化 - I18n - 更新 ru-RU popconfirm 翻译 (#19220 by @Opppex) - 更新 vi 翻译 (#19244 by @quangln2810) - 更新 Catalan 和 Spanish 翻译 (#19296 by @Ismaaa) - 更新 Indonesia 翻译 (#19320) by @therour) - 更新 Brazilian Portuguese 翻译 (#19374 by @diegomengarda) ### 2.13.1 *2020-04-13* #### 新特性 - Autocomplete - 添加 change 事件 (#17913 by @sxzz) #### Bug 修复 - Autocomplete - 修复类型为 textarea 时建议错误问题 (#18478 by @Roojay) - Carousel - 修复 console.warn 文案拼写错误 (#18264 by @IceFox) - Image - 修复当 preview-src-list 属性不包含 src 时图片预览大图展示为空的问题 (#18975) (#19130 by @luckyCao) - 修复第二次图片预览时快捷键失效问题 (#18983) (#19156 by @luckyCao) - 修复 preview-src-list 为空时点击图片会给 body 添加 overflow: scroll 的问题 (#18967 by @inooNgt) - Transfer - 修复和 Form 组件一起使用时错误的行高问题 (#18917 by @Hanx) - InputNumber - 正确计算 inputNumberDisabled (#18439 by @ashuser-pendo) - Chore - 更新首页文案 (#19155 by @iamkun) - Doc - 更新 Popconfirm 文档 (#18324 by @iamkun) - 修复 step-strictly 文档拼写问题 (#18705 by @dream2023) - 修复 Steps 组件文档问题 (#17555 by @haoranyu) ### 2.13.0 *2019-11-26* #### 新特性 - Popconfirm - 新增 Popconfirm 组件 (#17548 by @iamkun) #### Bug fixes - BackTop - 平滑过渡动画 (by @lon) - DatePicker - 修复选择最小日期的 bug (#17191 by @smk0621) - Select - 修复测试用例 (by @msidolphin) - Tree - 增加 font-size 样式 (#17094 by @spengjie) - Table - 头部可自定义 (#17291 by @ziyoung) - 更新头部样式 (#17284 by @ziyoung) - 修复时候 filter 之后高度问题 (#17348 by @ziyoung) - 修复 row-style 失效的 bug (#17002 by @a631807682) - 修复头部消失的 bug (#17341 by @ziyoung) - Calendar - 导入 el-button 和 el-button-group (#17376 by @masongzhi) - MessageBox - 修复图表位置 (#17410 by @nullptru) - TimePicker - 滚动后设置正确的位置 (#16868 by @mattheyan) - Message - 修复关闭的 offsetHeight(#17564) (#17852 by @gzwgq222) - Form - ValidateField 的回调应为可选项 (#17314 by @CarterLi) - Cascader - 修复 TypeScript 3.7 的兼容问题 (#17881 by @CarterLi) - Menu - 修复 NavigationDuplicated 在 vue-router@^3.1.0 的报错 (#17269 by @iamkun) - Dropdown - 更新类型文件 (#17550 by @iamkun) - Progress - 增加 strokeLinecap 属性 (#17552 by @iamkun) - InfiniteScroll - 跳过不可见元素触发 (#17553 by @iamkun) - Image - 优化用户体验 (#16985 by @luckyCao) - 优化大图片展示问题 (#16796 by @luckyCao) - Drawer - 修复 drawer-append-to-body 失效的 bug (#16953 by @JeremyWuuuuu) - Select - 修复空 tag 的 bug (17199 by @luckyCao) - Scrollbar - 修复 FireFox 双滚动条的 bug (#18091 by @iamkun) #### Optimization - I18n - 更新 sv-SE.js (#17926 by @FOLLGAD) - 更新 avatar 组件法语文档 (#17762 by @blombard) - Docs - 修复 time-select 文档错误 (#17250 by @wacky6) - 修复 Drawer 文档错误 (#17122 by @haoranyu) - 更新 Spanish changelog 2.12.0 (#17364 by @Gonzalo2310) - 修复 Changelog 文档错误 (#17874 by @renlixin) - 修复 Loading 示例 (#17862 by @MBearo) - 增加 input event 相关文档 (#18061 by @zhouxinyong) - 移除 Input repeat change event 相关文档 (#18085 by @zhouxinyong) ### 2.12.0 *2019-08-29* #### 新特性 - Popover - 添加 close-delay 属性 (#16671 by @LachlanStuart) - Theme - 增加 Chrome 插件: Element Theme Extension (#16686 by @iamkun) - Icon - 支持 font-display 属性的配置 (#16805 by @iamfaizalandyka) #### Bug fixes - Table - 在表头拖拽后阻止 click 事件的触发 (#16850 by @ziyoung) - 修复表头 display 为 none 造成浏览器崩溃的问题 (#16956 by @luckyCao) - 修复没有数据的时表格高度问题 (#16861 by @ziyoung) - 调用 toggleExpansion 不再抛出异常 (#16304 by @yyjjqq94) - 挂载时不再触发 sort-change 事件 (#17113 by @a631807682) - 修复 setCurrentRow 方法不生效的问题 (#16879 by @ziyoung) - 修复当数据异步加载时,expand-row-keys 不生效的问题 (#16899 by @ziyoung) - 把 toggleAllSelection 设置为 Table 示例的属性 (#17137 by @ziyoung) - Tree - 修复文字与复选框之间的距离 (#16799 by @Hazlank) - Tabs - 修复 TabItem 位置不正确的问题 (#16520 by @victorting) - 修复高亮的 Tab 不在可视区的问题 (#17033 by @nullptru) - Calendar - 修复日期的显示问题 (#16772 by @ubitoffee) - 修复在夏令时的显示问题 (#17208 by @iamkun) - Cascader - 修复 CascaderPanel 的显示问题 (#16716 by @zhangHongEn) - 禁用状态下,关闭按钮不显示 (#16224 by @yyjjqq94) - Input - 修复韩语输入问题 (#15069 by @MoonHyuk) - 触发清除按钮的点击事件 (#16576 by @a631807682) - Select - 过滤时,不收起下拉框 (#17205 by @luckyCao) - Transfer - 修复样式问题 (#17206 by @iamkun) - Dialog - 添加 SCSS 变量 (#16365 by @haoranyu) - RadioGroup - is 指定时,不产生非法的 HTML 片段 (#17070 by @nullptru) - Divider - 支持自定义类 (#17078 by @island205) - Carousel - 修复 change 的触发时机 (#16705 by @iamkun) - Notification - 不修改传入的 option (#16704 by @iamkun) - DatePicker - 给 picker-option 添加 className 属性 (#16632 by @iamkun) - DateTimePicker - 修复时间选择滚动条的问题 (#16854 by @jesse-li) #### Optimization - Checkbox - 提高可访问性 (#16575 by @tylertrotter) - Docs - 更新 changelog (#16773 by @SimonaliaChen) - 更新贡献指南 (#14800 by @sinchang) - 修复 Drawer 文档中的拼写错误 (#16848 by @winkay) - 更新自定义主题 (#16983 by @iamkun) - 新增 Esperanto 翻译 (#16955 by @maxkoryukov) - 更新 input-number 文档 (#16316 by @luckyCao) - 更新 Spanish 文档 (#16961 #16548 by @Gonzalo2310) - I18n - 更新加泰罗尼亚语翻译 (#14722 by @oscaralbareda) - 更新阿拉伯语翻译 (#16653 by @l3op) - Test - 修复拼写错误 (#16672 by @boomler) - 优化 image 的单元测试 (#16847 by @a631807682) - Types - 修复 httprequest 的类型 (#16633 by @luckyCao) ### 2.11.1 *2019-07-26* #### Bug 修复 - Image - 修复 Image 组件 SSR 兼容性 (#16737 by @luckyCao) - Chore - 更新 dart-sass 的兼容性 (#16744 by @LewisChennnnn) ### 2.11.0 *2019-07-25* #### 新特性 - Drawer - 新增抽屉组件 (#16577 by @JeremyWuuuuu) #### Bug 修复 - Checkbox - 修复 CSS 样式问题 (#16006 by @Hazlank) - Tree - 更新类型定义为泛类型 (#15934 by @JeremyWuuuuu) - 修复设置节点 isCurrent 的为 false 的问题 (#15870 by @kkkisme) - Dropdown - 更新 split-button 默认颜色 (#15931 by @JuniorTour) - Cascader - 修复一级菜单更新问题 (#16399 by @luckyCao) - 懒加载时设默认值 (#16420 by @luckyCao) - 修复当节点值重复时的显示问题 (#15935 by @junyiz) - 对外暴露 getCheckedNodes 和修复 options 改变会影响选中的问题 (#16709 by @SimonaliaChen) - Calendar - 更新显示正确的 header 的逻辑 (#16354 by @ziyoung) - Submenu - 修复 append-to-body 问题 (#16289 by @a631807682) - Table - 修复 tree table 数据更新问题 (#16481 by @island205) - Select - 修复内存泄漏问题 (#16463 by @island205) - InfiniteScroll - 更新命名和说明 (#16698 by @iamkun) - Avatar - 修复图片不居中的问题 (#16489 by @luckyCao) - Dialog - 增加 destroyOnClose 属性 (#16455 by @ziyoung) - Image - 增加大图预览 (#16333 by @luckyCao) #### 优化 - Docs - 修复 dropdown 示例 (#16193 by @webxmsj) - 修正笔误 (#15971 by @howiefh) - I18n - 更新泰文翻译 (#16689 by @ponkrit) - Chore - 更新基础 API 地址 (#16607 by @iamkun) - 增加 Form 的主题 token (#16699 by @iamkun) - 更新统计 (#16609 by @iamkun) - 修复文档锚点问题 (#16692 by @iamkun) ### 2.10.1 *2019-07-02* #### Bug 修复 - Table - 排序 icon 问题修复 (#15439 by @bezany) - 修复 `append` slot 存在时布局错位问题 (#16332 by @ziyoung) - 修复 `showOverflowTooltip` 更新无效的问题 (#16295 by @a631807682) - 修复 `FilterPanel` 中 `Scrollbar` 未注册问题 (#16246 by @ziyoung) - Chore - 更新版本号,修复文档问题 (#16233 by @ziyoung) - 修复英文首页样式问题 (#16254 by @iamkun) #### 优化 - Tag - 兼容 IE (#16334 by @ziyoung) - Chore - 更新钉钉3群二维码 (#16236 by @iamkun) - Doc - 更新主题编辑器文档 (#16244 by @iamkun) ### 2.10.0 *2019-06-25* #### 新特性 - I18n - 支持乌兹别克语 (#15796 by @ogabek96) - Calendar - 支持 `first-day-of-week` 配置 (#16047 by @ziyoung) - Avatar - 新增 `Avatar` 组件 (#16144 by @luckyCao) - Upload: - 支持自定义缩略图模版 (#13192 by @victorzhuk) #### Bug 修复 - Tree - 当 `currentKey` 为 `null` 时取消对树节点的高亮 (#15668 by @yyjjqq94) - 修复多实例共享数据的问题 #15538 (#15615 by @VanMess) - Upload - 更新 `fileList` 的类型定义 (#15716 by @underfin) - Table - 修复加载 icon 不显示的问题 (#15868 by @ziyoung) - 修复复杂表格中 hover 行背景色问题 (#15504 by @cnlon) - 修复 `current-row-key` 和选择事件的问题 (#15983 by @ziyoung) - `height` 属性接受更多单位 (#16013 by @ziyoung) - 修复 `reserve-selection` 无效的问题 (#16135 by @ziyoung) - Menu - 修复 `popper-append-to-body` 设置后,子菜单无法收起的问题 (#15391 by @PanJiaChen) - Select - 修复 `initialInputHeight` 问题 (#15989 by @yyjjqq94) - 修复输入中文时 `default-first-option` 的行为问题 (#15431 by @VanMess) - `import` 重复 (#16215 by @lengband) - Message - 类型定义中添加 `offset` 属性 (#16027 by @matjaz) - Timeline - 修复逆序问题 (#16091 by @ziyoung) - Slider - 补充 `input` 事件文档 (#15588 by @VanMess) - InfiniteScroll - 更新包名 (#16125 by @iamkun) - MessageBox - 修复 `distinguishCancelAndClose` 行为与文档不符的问题 (#15438 by @qingdengyue) - PopupManager - 修复无法复写 `z-index` 的问题 (#15738 by @luckyCao) - Docs - 删除不必要的内容 (#16194 by @Alexeykhr) - 更正 `Divider` 属性类型 (#15889 by @haoranyu) - Chore - 更新测试 API 地址 (#15807 by @iamkun) #### 优化 - Tree -优化循环性能 (#15699 by @KingJeason) - Theme - 更新 GA 打点,修改页底地址链接到主题编辑器 (#16007 by @island205) - Badge - 更新类型定义 (#16198 by @iamkun) - Avatar - 更新主题变量配置 (#16202 by @luckyCao) - I18n - 更新葡萄牙语 (#15776 by @gigioSouza) - 更新波斯语 (#15881 by @pamenary) - Docs - 补充入门文档中的组件列表 (#16063 by @pape2016) - 更新法语文档 (#16208 by @blombard) - 为 `Alert` 添加 默认插槽文档 (#15444 by @Alexeykhr) - 更新西班牙语文档 (#15840 by @Gonzalo2310) - 更新法语文档中的拼写错误 (#15837 by @blombard) - 更新 2.9.2 西班牙文档 (#16185 by @Gonzalo2310) #### 非兼容性更新 - Form - 移除输入框的成功状态 (#16159 by @ziyoung) ### 2.9.2 *2019-06-21* #### Bug 修复 - Chore - 修复 TS 定义文件 (#15805 by @NateScarlet) ### 2.9.1 *2019-05-30* #### 新特性 - Table - Tree Table 支持 tree-props,default-expand-all,expand-row-keys 属性, toggle-row-expansion 方法,expand-change 事件 (#15709 by @ziyoung) #### Bug 修复 - Table - 修复了一些问题 (#15709 by @ziyoung) - Theme - 更新接口域名 (#15784 by @iamkun) #### 优化 - Chore - 更新 InfiniteScroll 组件定义文件 (#15794 by @iamkun) ### 2.9.0 *2019-05-30* #### 新特性 - Backtop - 新增 Backtop 组件 (#15541 by @iamkun) - PageHeader - 新增 PageHeader 组件 (#15714 by @ziyoung) - InfiniteScroll - 新增 InfiniteScroll 指令 (#15567 by @iamkun) - Cascader - 新增多选模式和 filter-method 方法 (#15611 by @SimonaliaChen) - Message - 信息依次展示 (#15639 by @island205) - Tag - 新增 effect 属性 (#15725 by @SimonaliaChen) - Tabs - 卡片模式下标题左对齐 (#15695 by @luckyCao) - DatePicker - 支持字符串常量 (#15525 by island205) - Image - 支持 attrs 和 listeners (#15578 by @VanMess) - Theme - 新增 popup 背景配置 (#15412 by @iamkun) - Chore - 更新文档首页 (#15682 by @iamkun) #### Bug 修复 - Table - 修复排序条件为空时的排序问题 (#15012 by @joelxr) - Image - 修复 ssr 问题和 object-fit 的兼容性 (#15346 by @SimonaliaChen) - Input - 修复 show-word-count 样式问题 (#15359 by @lvjiaxuan) - 修复删除图标样式 (#15354 by @YiiGuxing) - Calendar - 修复星期展示错误 (#15399 by @qingdengyue) - 修复十月展示问题 (#15394 by @qingdengyue) - Tabs - 修复 padding 问题 (#15461 by @SimonaliaChen) - Tag - 修复阻止冒泡问题 (#15150 by @infjer) - Form - 修复 form-item 的高度错误 (#15457 by @SimonaliaChen) - 修复 resetFields 问题 (15181 by @luckyCao) - Tooltip - 修复自定义 tabindex 不生效问题 (#15619 by @SimonaliaChen) - Link - 修复图标 class 问题 (#15752 by @iamkun) - Select - 回滚清除时,设置 value 为 null 的修改 (#15447 by @iamkun) - Loading - 修复 Dom 不更新的问题 (#15123 by @FAKER-A) - Switch - 修复事件重复触发问题 (#15178 by @FAKER-A) - Slider - 修复点击时样式问题 (#15561 by @luckyCao) - Radio - 修复 value 不更新的问题 (#14809 by @OverTree) - Form - 修复 resetFields 问题 (15181 by @luckyCao) - Chore - 更新依赖 (#15324 by ziyoung) - Type - 修复 Loading 定义文件 (#15635 by @iamkun) - 修复 Icon 定义文件 (#15634 by @iamkun) - 修复 Link 定义文件 (#15402 by @iamkun) #### 优化 - Cascader - 重构 (#15611 by @SimonaliaChen) - Chore - 更新新建组件的脚本 (by @iamkun) - Docs - 重新命名文档变量 (#15185 by @liupl) - 更新 Image 组件文档 (#15423 by @haoranyu) - 修复 Form 组件文档错误 (#15228 by @SHERlocked93) ### 2.8.2 *2019-04-25* #### Bug 修复 - Icon - 更新 icon (#15272 by @iamkun) - 文档 - 修复 Form 与 Input 文档样式 (#15273 by @ziyoung) ### 2.8.1 *2019-04-25* #### Bug 修复 - Icon - 更新 Select 与 Cascader 的 icon (#15264 by @SimonaliaChen) - 更新 icon (#15258 by @iamkun) #### 优化 - Chore - 更新构建脚本 (#15267 by @ziyoung) - Docs - 修复 link 的样式 (#15265 by @iamkun) - 其他 - migrating 配置兼容驼峰名称 (#15260 by @SimonaliaChen) ### 2.8.0 *2019-04-25* #### 新特性 - Divider - 新增 Divider 组件 (#15055 by @island205) - Rate - 支持通过对象自定义 colors 与 icon-classes 属性 (#15051 by @SimonaliaChen) - Link - 新增 Link 组件 (#15052 by @iamkun) - Calendar - 新增 Calendar 组件 (#14908 by @ziyoung) - Icon - 新增图标 (#15214 by @iamkun) - Alert - 新增高饱和度主题 (#15041 by @island205) - Image - 新增 Image 组件 (#15117 by @SimonaliaChen) - Collapse - CollapseItem 支持禁用 (#15076 by @ziyoung) - Carousel - 新增 direction 属性,支持垂直方向切换 (#15122 by @ziyoung) - Pagination - 新增 hide-on-single-page 属性 (#15096 by @ziyoung) - Slider - 新增 marks 属性 (#15133 by @luckyCao) - Input - 新增 show-word-count 属性 (#15075 by @luckyCao) - InputNumber - 新增 step-strictly 属性 (#15050 by @luckyCao) - Tooltip, Dropdown, Popover - 新增 tabindex 属性 (#15167 by @ziyoung) #### Bug 修复 - Notification - 修复标题不换行的问题 (#15008 by @iamkun) - Form - 修复动态表单校验规则不生效的问题 (#14985 by @luckyCao) - 修复 label 的样式 (#14969 by @ziyoung) - 当 required 为 true 时,显示星号 (#15144 by @ziyoung) - Pagination - 修复 slot 未更新的问题 (#14711 by @lucyhao) - Table - 修复懒加载时加载数据的 bug (#15101 by @ziyoung) - 在合并单元格时,修复单元格的宽度计算不正确的问题 (#15196 by @ziyoung) - 提升表格的性能 (#14868 by @ziyoung) - 初始化时不再触发 sort-change 事件 (#14625 by @PeanutWatson) - 让 height 与 max-height 属性的行为保持一致 (#14660 by @arthurdenner) - Dialog - 修复内容不换行的问题 (#15027 by @iamkun) - Alert - 更新 typescript 定义文件 (#15186 by @ziyoung) - Tabs - Fix issue where Promise rejection was hitting application (#14816 by @ffxsam) - slot 改变时,重新渲染 (#15238 by @ziyoung) - Message - 修复 typescript 定义文件 (#14968 by @agoni1212) - Select - 修复当 value 为 undefined 或者 null 的报错 (#15022 by @luckyCao) - Tree - 当前节点被删除后,选中的节点也应该删除 (#14604 by @sinchang) - 提升性能 (#14881 by @ChenZhuoSteve) - Dropdown - 修复样式 (#14907 by @doing123) - Slider - 修复可访问性问题 (#14792 by @erezsob) - Menu - 如果 defaultIndex 不存在,activeIndex 应该为空 (#14074 by @hoythan) - Directive - RepeatClick: 使用 Date.now 提升性能 (#14776 by @pavelmash) - Upload - 修复 Upload 的背景颜色 (#15039 by @iamkun) - Theme - 添加无圆角变量 (#15256 by @iamkun) #### 优化 - Chore - 更新中文 changelog (#14965 by @iamkun) - 当 demo 描述为空时,不再显示 (#15014 by @ziyoung) - 显示 DevServer 的信息 (#15028 by @iamkun) - 修复 2.6 changelog 的 bug (#15026 by @iamkun) - 更新构建脚本 (#14821 by @abc3660170) - 本次开发时支持热更新 (#15221 by @SimonaliaChen) - 本地开发时,加载 sourcemap (#15087 by @ibufu) Docs - 重命名 demo 中的变量 (#14602 #15003 #15094 #15105 by @liupl) - 修复 upload 文档中的错误 (#15023 by @iamkun) - 更新 Form 文档 (#15040 by @iamkun) - 更新 Tabs 文档 (#15053 by @iamkun) - 使用 eleme.cn 作为新域名 (#15139 by @ziyoung) - 修复 Image 组件的路由名 (#15194 by @iamkun) - 删除多余的法语翻译 (#15207 by @iamkun) #### 非兼容性更新 - Rate - 禁用情况下,显示小位数 (#15089 by @haoranyu) - Select - 过滤情况下,placeholder 为选中选项的 label (#14989 by @ibufu) ### 2.7.2 *2019-04-03* #### 修复 - Form - 修复 `label-width` 为 `auto` 的样式 (#14955 by @ziyoung) #### 优化 - Docs - 修复文档内图片链接错误 (#14957 by @iamkun) - Chore - 修复发布时 mkdir 异常 (#14952 by @iamkun) ### 2.7.1 *2019-04-03* #### 修复 - Select - 清空时设置 value 为 null (#14322 by @aaronfulkerson) - Input - 当类型改变时更新 DOM (#14889 by @wacky6) - Table - 修复当有展开列时 `defaultExpandAll` 的行为 (#14935 by @ziyoung) - Dialog - 可以设置背景色 (#14939 by @ziyoung) - Form - `label-width` 支持自动宽度 (#14944 by @ziyoung) #### 优化 - Docs - 更新西班牙语文档 (#14913 by @Gonzalo2310) - 新增组件自动生成法语文档 (#14924 by @ziyoung) - 更新 Tabs 文档 (#14938 by @ziyoung) ### 2.7.0 *2019-03-28* #### 新特性 - Table - 增加对树形结构数据的支持 (#14632 by @ziyoung) #### 修复 - Tabs - 阴影样式使用全局主颜色 (#14558 by @Richard-Choooou) - 当 label 改变时触发更新 (#14496 by @akki-jat) - Table - Table footer 与 body 的对齐一致 (#14730 by @ziyoung) - NavMenu - 修复点击 el-submenu 多次触发 childMenu 问题 (#14443 by @PanJiaChen) - Dropdown - 兼容 Vue 2.6 新 v-slot 语法 (#14832 by @ziyoung) - ColorPicker - 修复十六进制颜色字符串解析问题 (#14793 by @iamkun) - Tree - 恢复 pr #13349 (#14847 by @ziyoung) - Tooltip - 当初始值为 true 时默认显示 (#14826 by @ziyoung) - Docs - 更新 Cascader 文档 (#14442 by @panhezeng) - Style - 修复媒体查询 sm-only, md-only, lg-only 问题 (#14611 by @sinchang) #### 优化 - Chore - 增加网页描述信息 (#14802 by @iamkun) ### 2.6.3 *2019-03-21* #### 修复 - 修复 Cascader 文档页的样式 (#14789 by @ziyoung) - 移除 Cascader 中多余的 DOM 操作 (#14788 by @ziyoung) - DateRange 支持夏令时 (#14562 by @wacky6) ### 2.6.2 *2019-03-21* #### 新特性 - DatePicker - 支持 monthrange 类型 (#14487 by @zxyRealm) - i18n - 添加 Croatian 语言包 (#14360 by @danijelh) - Docs - 更新 2.6.1 法语文档,修复笔误 (#14555 by @smalesys) - 更新法语翻译 (#14643 by @smalesys) #### 修复 - Input - Fix regression (#14572 by @wacky6) - DatePicker - 修复 first-day-of-week 的计算 (#14523 by @sinchang) - 修复 WeekPicker value-format 的问题 (#13754 by @wacky6) - Steps - 修复 #14502 (#14596 by @sinchang) - 修复简单模式下的样式 (#14610 by @sinchang) - Docs - 重命名 Table 文档中的变量 (#14587 by @likwotsing) - 添加法语文档索引 (#14565 by @iamkun) - 修复 TimePicker 文档页的样式 (#14579 by @ziyoung) - 重命名 Upload 文档中的变量 (#14593 by @liupl) - 在 Form 文档中 添加的 async-validator 文档 (#14694 by @iamkun) - 修复 Tooltip 文档的 bug (#14748 by @iamkun) - 修复笔误 (#14751 by @2bj) - 修复 Switch 在移动端 Webkit 浏览器的高亮问题 (#14703 by @VladG0r) #### 优化 - Chore: - 更新 ci 构建脚本 (#14600 by @ziyoung) - 更新谷歌统计 (#14560 by @iamkun) - 添加更多谷歌统计事件 (#14633 by @iamkun) - 更新聊天组信息 (#14741 by @iamkun) - 升级测试依赖 (#14735 by @wacky6) - 升级 gulp (#14745 by @ziyoung) - 使用 codepen 显示 demo,修复文档中的错误 (#14747 by @ziyoung) ### 2.6.1 *2019-03-03* #### 修复 - **不再指定 node 版本** (by @iamkun in #14546) - 调整 `deloy-faas.sh` 中的文档目录 (by @ziyoung in #14553) - 调整 2.6.0 中 changelog 日期样式 (by @island205 in #14547) - 修复拼写错误 (by @wack6 in #14552) ### 2.6.0 *2019-03-01* #### 新特性 - Timeline - 添加 Timeline 组件 (by @jikkai in #14248) - DropdownItem - `el-dropdown-item` 支持添加 icon (by @gabrielboliveira in #14088) - Input - 添加 `show-password` 属性,支持配置显示密码按钮 (by @phshy0607 in #13966) - Select - 添加 slot `empty` (by @elfman in #13785) - Autocomplete - 添加 `highlight-first-item` 属性,控制是否默认突出显示远程搜索建议中的第一项 (by @YamenSharaf in #14269) - I18n - 添加亚美尼亚语支持 (by @hamletbarsamyan in #14214) - Docs - 新增法语文档 (by @smalesys in #12153, #14418, #14434) #### 优化 - Alert - 组件对通过 slot 传入的 description 也应用默认样式类 (by @iamkun in #14488) - InputNumber -移除多余的 `parseFloat` (by @JuniorTour in #14172) - Menu - 支持 `el-menu-item` 不添加 index (by @georgyfarniev in #13298) - Table - 移除无用的 DOM 操作 (by @elfman in #13643) - Upload - 代码优化 (by @elfman in #13973) - Popup - 移除无用代码 (by @KAionro in #14413) - Docs - 添加更多文档说明如何贡献代码 (by @island205 in #14355) - 添加 `el-input` 是受控组件的警示 (by @wacky6 in #14463) - 优化 Table 的文档 (by @luguokong in #14329) - 更新 Input 文档 (by @iamkun in #14437) - 优化自定义主题文档 (by @wangguohao in #14297) - 为 Icon 文档添加 hover 效果 (by @tuxinghuan in #14295) - Build - 压缩 Element 文档站的 JS 和 CSS 文件 (by @iamkun in #14430) - 优化 Webpack 打包速度,从6分钟优化到1分多 (by @hetech in #14484) - 添加 CLI 工具,选择版本号 (by @hetech in #14354) - 使用 Stale 来管理过时(暂定1年)的 Issue 和 PR (by @island205 in #14392) #### 问题修复 - Menu - 修复浏览器标签切换引起的 focus 问题 (by @liupl in #13976) - MessageBox - 修复 TS 定义 (by @NateScarlet in #14278) - ScrollBar - 修复点击鼠标右键导致拖动的问题 (by @xifeiwu in #14196) - Switch - 添加 `validate-event` 属性,设置改变 Switch 状态时是否触发表单的校验 (by @hetech in #14426) - Table - 修复多 Table 实例共享 `toggleAllSelection` 方法,造成无法切换问题 (by @letanure in #14075) - Tabs & Dropdown - 修复样式问题 (by @hetech in #14452) - Tree - 与 Table 统一占位文样式 (by @ColinCll in #14331) - Docs - 修复 DatetimePicker 文档问题 (by @iamkun in #14290) - 修复 DatePicker 文档拼写问题 (by @helmut in #14481) - 修复分页组件文档样式问题 (by @liuchuzhang in #14451) #### 非兼容性更新 - Table - 修复 row 事件的参数顺序 (by @jikkai in #12086) ### 2.5.4 *2019-02-01* #### 修复 - 构建: 修复 `.babelrc` 配置问题——导致 Tree 等组件没有动画 (by @island205 in #14282) ### 2.5.3 *2019-01-31* #### 优化 - 优化 Message 的代码 (by @vok123 in #14029) - 移除 gh-pages (by @ziyoung in #14266) - 添加 IssueHunt 的链接 (by @island205 in #14261) #### 修复 - 修复 UMD 包在服务器端运行出错的问题 (by @island205 in #14242) - 修复 Tabbar 高亮时的样式 (by @iamkun in #14240) - 修复 Table 示例代码的错误 (by @xunmeng in #14253) ### 2.5.2 *2019-01-27* #### 优化 - 文档: - 2.5.1 版本西班牙语文档更新 (by @Gonzalo2310 in #14231) #### 修复 - 构建: - 删除 umd 模块 `lib/index.js` 中本没有的注释 (by @island205 in #14233) - 修复 nuxt.js 中关于 `export` 关键字的报错 (by @island205 in #14232) - 修复发布 2.5.1 过程中的错误 (by @iamkun in #14228) ### 2.5.1 *2019-01-26* #### 优化 - DatePicker:添加月、年高亮的样式(by @Debiancc in #14211) - 更新 2.5.0 changelog (by @wacky6 in #14217) #### 修复 - 修复升级 Webpack 4 产生的问题,无法具名 `import` 组件,`ELEMENT.locale()` 调用报错。(by @island205 in #14220) - 恢复 2.4.11 文档 (by @iamkun in #14222) ### 2.5.0 *2019-01-25* #### 新特性 - DatePicker - 新增 `validate-event` 属性 (by @ziyoung in #13531) - DateTimePicker - `pickerOptions` 支持 `selectableRange` 选项 (by @eeeeeeeason) - Tag - 新增 `click` 事件 (by @licdream in #14106) - I18n - 新增 柯尔克孜语 (Kyrgyz) (by @zzjframework in #14174) #### 优化 - 升级到 webpack@4 (by @jikkai in #14173) - Input - 简化内部实现,遵循单向数据流;修复若干相关 Bug (by @wacky6 in #13471) - 更新 Axure 文件,增加新组件 (by @ziyoung in #13773) #### 修复 - Autocomplete - 修正下拉框最后一行显示不完整的问题 (by @ziyoung in #13597) - 修正下拉框箭头 (by @liuchuzhang in #13762) - Carousel - 组件销毁时释放内部 Timer (by @elfman in #13820) - Cascader - 移除已废弃的计算属性的 cache 属性 (by @iamkun in #13737) - 修正 TypeScript 中 CascaderOption 类型定义 (by @NateScarlet in #13613) - 修正图标覆盖文字的问题 (by @ziyoung in #13596) - Checkbox - 改进显示样式 (by @PanJiaChen) - DatePicker - 修正 TimeSpinner 中缺失的 v-for `key` 属性 (by @Ende93 in #13547) - 修正周选择器在跨年时的高亮行为 (by @suyi91 in #13883) - Input - 修复 textarea 时的 DOM 节点引用 (by @laomu1988 @island205 in #13803) - Pagination - 输入框的值不会小于 1 (by @elfman in #13727) - Popover - 修正 hover 的触发行为 (by @goldengecko in #13104) - 修正弹出框的内存泄漏 (by @qpxtWhite in #13988) - Radio - 改进显示样式 (by @ohhoney1) - Table - 改进点击排序箭头时的行为 (by @ohhoney1 in #12890) - 修正 IE10+ 中 “暂无数据” 提示的垂直布局 (by @imzjy in #13638) - 修正文档中 `index` 的类型说明 (by @ilovefafa in #13628) - 修正多级表头使用 `fixed` 属性时,表尾合计行的显示样式 (by @luckyCao in #13914) - Tabs - 修正自动滚动 (by @iamkun in #13696) - 通过面板名称查找面板 (by @iamkun in #13705) - 使用 `paneName` 计算面板样式 (by @iamkun in #13733) - Tree - 修正 `showCheckbox` 不能影响子节点的问题 (by @KidneyFlower) - 更新文档和 TypeScript 定义 (by @ziyoung in #13540) - Upload - `list-type` 改变时,保留 `url` 属性 (by @elfman in #13771) - Slider - 修正源代码缩进 (by @wacky6 in #13955) - I18n - 补充加泰罗尼亚语 (Catalan) 翻译 (by @jaumesala) - 补充俄语 (Russian) 翻译 (by @justlp in #13658) - 补充芬兰语 (Finnish) 翻译 (by @jenkrisu in #14137) - Doc - 更新西班牙语文档至 2.4.11 (by @Gonzalo2310 in #13522) - 其它 - 移除多余的构建脚本 (by @ziyoung) - 修正文档超链接 (by @iamkun in #13753) - 修正文档中不一致的大小写 (by @wonderjar) - 增加钉钉群的二维码 (by @iamkun in #13957) - .gitignore 增加 yarn 日志文件 (by @mimimi in #13922) - 移除赞助商 多态 (by @island205 in #14156) - Update readme qr code src (by @iamkun in #13960) - 更新 CDN 链接,修正错别字 (by @ziyoung) ### 2.4.11 *2018-11-21* - 撤销 pr #13296,修复点击 Menu 外部导致 Submenu 收起的问题,#13478 - 调整小屏幕(xs)媒体查询断点,#13468 (by @alekoshen712) ### 2.4.10 *2018-11-16* - 修复多次点击 Select 才显示下拉列表的问题,#13268 - Form 禁用时不显示 Input 的 clear 图标,#13208 - 调整 Select,Progress,Autocomplete,Tooltip,Collaspe,TimePicker 的样式,#13188 (by @porcelainHeart) #13210 #13266 #13257 #13290 #13347 (by @PanJiaChen) - Carousel 组件新增 `loop` 属性,#13217 - Table 的 data 改变时,高亮行会继续保留,#13200 - Table 的 header slot 可以接收参数,#13263 - Table 的 `clearFilter` 方法支持参数,#13176 - Table 单元格内没有内容时不再创建 Tooltip,#13152 (by @rongxingsun) - ColorPicker 面板的输入框内容可以正常显示了,#13278 - 在拖拽时,ColorPicker 不再触发表单校验,#13299 - InputNumber 新增 `select` 方法,#13286 (by @st-sloth) - Autocomplete 新增 `clear` 事件,#12171(by arthurdenner) #13326 - 可以通过点击 Menu 外部来关闭 Menu,#13296 - Form 的 `validateField` 方法可以接收参数,#13319 - Cascader 新增 `visible-change` 事件,#13415 - DatePicker 新增 range-separator slot, #13272 (by @milworm) - Tree 新增 `iconClass` 与 `currentNodeKey` 属性,#13337 #13197 (by @isnifer) - Progress 的 `status` 添加了 text #13198 (by @ali-master) - 修复 Tree 的 `defaultCheckedKeys` 导致显示的错误,#13349 (by @dive2Pro) ### 2.4.9 *2018-10-26* - Form 组件 clearValidate 方法参数支持字符串,#12990 (by @codinglobster) - Badge 新增 type 属性,#12991 - 用户可以使用 scoped-slot 来自定义表头,#13012(by @ivanseidel) - 修复 IE 下 Select 输入框不能输入的问题,#13034(by @GaliMU) - Select 多选时,选项不换行,#12329 (by @akki-jat) - Select 下拉列表展开后,箭头图标也可以正确显示,#12353(by @firesh) - 修复 Select 的 size 属性不生效的问题,#13070 - 多选时可以清除 Select 已选中的值,#13049(by @ZSkycat) - 修复最后一个 TabNav 不能删除的问题,#13039 - 修复 TabNav 中 label 显示不正确的问题,#13178 - Alert 新增 title slot,#13082(by @Kingwl) - 修复 Table 中的 tooltip 内容不正确的问题,#13159(by @elfman) - 优化 Upload 文件列表删除时的动画,#12987 - 当 InputNumber 控制按钮不显示时,调整了边距,#13052 ### 2.4.8 - Switch 聚焦时不显示轮廓,#12771 - 修复 Dropdown 在 ButtonGroup 中样式问题,#12819 (by @bluejfox) - Dialog 新增 opened 事件,#12828 - 修复 TabNav 显示顺序不正确的问题,#12846 - 修复 Tabs 没有滑动到选中 tab 的问题,#12948 - 修复 Tree 节点在拖拽时标识符不显示的问题,#12854 - Form 的 validate 事件参数中包含了校验的信息,#12860 (by @YamenSharaf) - 修复 DatePicker 没有校验用户输入时间的合法性问题,#12898 - 修复 Table 表头的 `render-header`属性不生效的问题,#12914 ### 2.4.7 *2018-09-14* - 修复 DatePicker 未触发表单检验的问题,#12328,#12348 - 修复 DatePicker 多选时报错的问题,#12347 - 修复 DatePicker 选择时间时 spinner 位置不正确的问题,#12415 (by @rang-ali) - 修复 Datepicker 输入框自动填充的问题,#12521 (by @abdallanayer) - 修复 Cascader 中 Input 未高亮的问题,#12341 - 修复 Tabpane 顺序不正确的问题,#12346 - 修复 ColorPicker 取色光标位置不正确的问题,#12376 (by @cnwhy) - 调整 Submenu 的样式,#12457 - 修复 Submenu 选中后没有高亮的问题,#12479 - 修复 Cascader 选择值不正确的问题,#12508 (by @huangjinqiang) - 修复 Pagination 输入框值不正确的问题,#12525 - 调整 Pagination 触发事件的顺序,#12530 - 修复 Table 的 filter 不显示的问题,#12539 - 修复 Tree 无法删除节点的问题,#12684 - 修复 Select 在单选时 Input 高度变化的问题,#12719 - 修复 Form 在嵌套时 label 显示不正确的问题,#12748 - 新增 Input 的 autocomplete 属性,废弃 auto-complete 属性,#12514 (by @axetroy) - 新增 Form 的 slot-scope 展示表单校验信息,#12715 (by @YamenSharaf) ### 2.4.6 *2018-08-09* - 修复 Table 的 filter 初始值为空数组时不显示筛选图标的问题,#12165 - 修复 Menu 在更改 `collapse` 时不保存菜单激活状态的问题,#12178 (by @elfman) - 修复 Cascader 未转义特殊字符的问题,#12248 - 修复禁用的 RadioButton 在点击时显示 box-shadow 的问题,#12262 - 修复 Select 初始值为 `undefined` 时方向键失效的问题,#12322 - 修复 Select 多选时输入的关键字消失的问题,#12304 - 修复 Select 多选时查询函数没有去抖的问题,#12181 - 修复 Dialog 在全屏显示时宽度不正确的问题,#12203 - 修复 Main 在 IE 下的显示不正确的问题,#12237 - 修复 Input 触发两次表单校验的问题,#12260 - 修复 Tree 在懒加载时添加节点导致节点消失的问题,#12256 - 修复 Tree 节点在拖拽后无法删除的问题,#12279 - 修复 Popover 在 InputNumber 聚焦时不显示的问题,#12284 - 添加 Autocomplete 的 popper-append-to-body 属性,#12241 - 添加 Pagination 的 `page-size` 属性 `sync` 修饰符的支持,#12281 ### 2.4.5 *2018-07-26* - 修复 Table 设置 `class-name` 对 `expand` 列不生效的问题,#12006 - 新增 Table 的 `toggleAllSelection` 方法,#12047 - 修复 Input 包含 Select 时,suffix 插槽位置显示不正确的问题,#12108 - 修复 Option 的 `line-height` 无法设置的问题,#12120 - 修复初始值为 `null` 的 TimeSelect 在执行 `resetField` 后无法再赋值的问题,#12010 - 修复 Tree 组件中不响应方向键以外 keydown 事件的问题,#12008 - 修复 Tree 在懒加载情况下选中父节点的问题,#12106 - Tree 的 `getCheckedNodes` 方法新增 `includeHalfChecked` 参数,#12014 ### 2.4.4 *2018-07-13* - 修复重置表单后触发 Select 组件校验问题,#11837 - 修复 Input 组件 `suffix` 与 `append` 共存时样式错乱问题,#11951 - 修复可清空的只读 Input 仍会显示清空图标的问题,#11967 - 修复 Tree 节点禁用时仍可以选中的问题,#11847 - 修复 Tree `default-checked-keys` 属性不生效的问题,#11971 - 修复 Tree 在过滤节点时下 `empty-text` 不显示的问题,#11971 - 修复 Table 的 `empty-text` 过长时的位置样式问题,#11965 - 修复 Table 的 `current-row-key` 设置为 `null` 时高亮行不清除的问题,#11866 - 修复当 `filters` 为空数组时显示过滤器下拉列表的问题,#11864 - 修复 Radio 的 label 不阻止事件冒泡的问题,#11912 ### 2.4.3 *2018-07-03* - 修复当自定义 Tree 节点高度时,`allow-drop` 不能正常工作的问题,#11797 - 现在 Form 的 `clearValidate` 方法支持传入参数,指定需要清空校验结果的 FormItem,#11821 - 新增 MessageBox 的 `distinguishCancelAndClose` 属性,#11831 ### 2.4.2 *2018-06-26* - 修复 Table 的 `class-name` 和 `label-class-name` 属性不支持动态更新的问题,#11626 - 修复 Table 在 `highlight-current-row` 为 `false` 时点击行也会触发高亮的问题,#11691 #11563 - 修复 ButtonGroup 中只有一个 `round` 或 `circle` 的 Button 时的样式错误,#11605 - 修复在某些情况下 Pagination 的条目数选择器的样式错误,#11622 - 修复 Menu 的 `collapse` 属性变化后无法使用 `open` 方法的问题,#11646 - Tabs 的 `before-leave` 钩子添加了 `activeName` 和 `oldActiveName` 参数,#11713 - 修复 Cascader 关闭后的聚焦问题,#11588 - 修复 Cascader 在 `change-on-select` 状态下点击选项不关闭的问题,#11623 - 现在通过代码改变 Select 的值后会触发表单校验,与 Input 行为一致,#11672 ### 2.4.1 *2018-06-08* - 移除 Autocomplete 的重复类型声明,#11388 - 修复嵌套在 Form 内的 Select 在 FireFox 浏览器中下拉箭头错位的问题,#11427 - 修复 Select 的初始值为 `null` 时仍然显示清除图标的问题,#11460 - 修复禁用的 Radio 在点击时显示 box-shadow 的问题,#11462 - 新增 MessageBox 的 `iconClass` 属性,#11499 - 新增 Tabs 的 `stretch` 属性,#11476 - 修复 Tabs 开启 `lazy` 时渲染顺序异常的问题,#11461 - 修复 Table 展开行时无法保留选中行样式的问题,#11464 - 修复 Tabs 调用 `before-leave` 并返回 Promise 的时候,Tabs 会存在 focus 状态的问题,#11386 - 修复 Popover 禁用状态下创建弹出框的问题,#11426 - 修复 Tree 在懒加载状态下添加新节点造成无限循环的问题,#11430 (by @wangjingf) - 新增 Dialog 的 `closed` 事件,#11490 ### 2.4.0 Fullerene *2018-05-28* #### 新特性 - 综合 - 使用原生 webpack 作为构建和打包工具,#11216 - 可以全局配置弹出层的初始 z-index,#11257 - Autocomplete - 新增 `hide-loading` 属性,#11260 - Button - 现在圆形按钮也支持通过 `size` 属性改变其尺寸了,#11275 - InputNumber - 新增 `precision` 属性,#11281 - Tabs - 新增 `before-leave` 钩子,#11259 - 新增 `lazy` 属性,#11167(by @Kingwl) - Table - 新增 `sort` 方法,支持手动排序,#11311 #### 修复 - Input - 修复使用中文输入法快速输入文字时会导致视图重新渲染的问题,#11235(by @STLighter) - Popover - 修复当触发元素为 Radio 或 Checkbox 时控制台报错的问题,#11265 - Breadcrumb - 修复 `to` 属性不支持动态更新的问题,#11286 - Upload - 修复在 `beforeUpload` 方法返回的 Promise 中 resolve 一个 File 时控制台报错的问题,#11297(by @qusiba) - Tooltip - 修复内容为空时箭头错位的问题,#11335 - Autocomplete - 修复在快速删除搜索内容后输入建议不正确的问题,#11323 - ColorPicker - 修复关闭选色器时触发 `active-change` 事件的问题,#11304 - Table - 修复筛选列表过长导致样式超出的问题,#11314 - 修复排序后导致无法正常显示选中行样式的问题,#11348 - Checkbox - 修复单个 Checkbox 不支持表单验证的问题,#11271 - Radio - 修复通过空格可以选中被禁用的 Radio 的问题,#11303 - MessageBox - 修复连续打开两个 MessageBox 时 `el-popup-parent--hidden` 无法移除的问题,#11371 ### 2.3.9 *2018-05-18* - 修复当 TableColumn 的 `prop` 属性指定的字段在数据源中不存在时,鼠标移入该列单元格会报错的问题,#11137 - 弹出类组件的 `lockScroll` 属性不再为父元素添加内联样式,而是添加相应类名,#11114 - 修复 Progress 在 `status` 为 exception 时图标不显示的问题,#11172 - 修复可搜索的 Cascader 在输入关键词后,选项的 `disabled` 属性失效的问题,#11185 - 修复可展开的 Table 在展开某一行后更新数据源会造成该行无法收起的问题,#11186 - Tree 的 `setCurrentKey` 方法支持传入 `null`,可取消当前高亮的节点,#11205 ### 2.3.8 *2018-05-11* - 修复 `type` 为 dates 的 DatePicker 在选择非当前月的日期后,面板会跳转至当前月的问题,#10973 - 修复可清空的只读 Input 仍会显示清空图标的问题,#10912 - 修复范围选择的 DatePicker 在未改变值的情况下关闭下拉面板仍会触发 `change` 事件的问题,#11017 - 修复 Select 在有分组选项时不能正确通过键盘导航的问题,#11058 - 新增 Select 的 `prefix` 具名 slot,#11063 - 新增 FormItem 的 `clearValidate` 方法,#11076 - 新增 Tree 的 `checkOnClickNode` 属性,#11111 ### 2.3.7 *2018-04-29* - 修复 Table 在由于筛选而使原有的滚动条消失后表头各列宽度未及时更新的问题,#10834 - 修复可清空的 Input 在初始值为 `null` 时仍然显示清空图标的问题,#10912 - 修复在通过代码改变 ColorPicker 的绑定值后错误地触发 `active-change` 事件的问题,#10903(by @zhangbobell) - 修复可搜索的 Select 在备选项均被禁用时,通过键盘导航会造成无限循环的问题,#10945 ### 2.3.6 *2018-04-21* - 修复 Tree 的 `allow-drop` 回调在使用 `type` 参数后的错误行为,#10821 - 修复可搜索的单选 Select 在 IE11 中无法输入搜索关键词的问题,#10822 - 修复单选 Select 在使用鼠标选中某个选项后错误地触发 `blur` 事件的问题,#10822 ### 2.3.5 *2018-04-20* - 修复 DatePicker 的 `type` 为 week 时面板错误高亮的问题,#10712 - 修复 InputNumber 初始值为 0 时输入框为空的问题,#10714 - 新增 Select 的 `automatic-dropdown` 属性,#10042(by @Seebiscuit) - 修复 `disabled` 的 Rate 仍能通过键盘左右键改变组件值的问题,#10726(by @Richard-Choooou) - 现在 DatePicker 的 `type` 属性可以接收 `'dates'`,用于选择多个日期,#10650(by @Mini256) - 新增 Pagination 的 `prev-click` 和 `next-click` 事件,#10755 - 新增 Pagination 的 `pager-count` 属性,#10493(by @chongjohn716) - 新增 `type` 作为 Tree 的 `allow-drop` 属性回调的第三个参数,#10792 - 改用 ResizeObserver 对元素的尺寸变化进行监测,#10779 ### 2.3.4 *2018-04-12* - 删除 SubMenu 在 TypeScript 类型声明中重复的 `showTimeout` 属性,#10566(by @kimond) - 现在 Transfer 数据项的渲染支持通过 scoped slot 自定义,#10577 - 修复点击 Pagination 禁用的上一页、下一页按钮仍会触发 `current-change` 事件的问题,#10628 - 修复未绑定值的 Textarea 在 SSR 中会显示 `undefined` 的问题,#10630 - 修复 `type` 为 border-card 的 Tabs 中被禁用标签项的样式,#10640 - 新增 `$index` 作为 Table 的 `formatter` 属性回调的第四个参数,#10645 - 修复 TypeScript 类型声明未导出 CheckboxButton 的问题,#10666 ### 2.3.3 *2018-04-04* - 新增 Card 的 `shadow` 属性,#10418(by @YunYouJun) - 修复 Badge 在 `value` 属性为 `0` 时不显示上标的问题,#10470 - 修复 Tree 节点拖拽相关的问题,#10474 #10494 - 新增 Autocomplete 的 `placement` 属性,#10475 - 现在 `default-time` 属性也可用于非范围选择的 DateTimePicker 了,#10321(by @RickMacTurk) - 修复 TabItem 在浏览器失焦和隐藏后出现蓝色边框的问题,#10503 - 新增 SubMenu 的 `popper-append-to-body` 属性,#10515 - 现在非链接的 BreadcrumbItem 在 hover 时不再具有视觉反馈,#10551 - 调整 InputNumber `change` 事件的触发时机,使得在回调中能够取得最新的组件绑定值,#10553 ### 2.3.2 *2018-03-29* - 修复 Autocomplete 报错的问题,#10442 ### 2.3.1 *2018-03-29* - 修复 Input 的 `type` 属性未传递至原生 input 元素的问题,#10415 - 新增 Select 的 `blur` 方法,#10416 ### 2.3.0 Diamond *2018-03-28* #### 新特性 - Table - 现在 TableColumn 的 `formatter` 属性可以是动态的,#10184(by @elfman) - 新增 `select-on-indeterminate` 属性,#9924(by @syn-zeta) - Menu - 新增 `collapse-transition` 属性,#8809(by @limichange) - Input - 新增 `select` 方法,#10229 - 新增 `blur` 方法,#10356 - ColorPicker - 新增 `predefine` 属性,#10170(by @elfman) - Tree - 新增 `draggable`、`allow-drop` 和 `allow-drag` 属性,以及 `node-drag-start`、`node-drag-enter`、`node-drag-leave`、`node-drag-over`、`node-drag-end` 和 `node-drop` 事件,#9251 #10372(by @elfman) - Form - `validate` 方法新增第二个参数,包含未通过本次校验的表单项信息,#10279 - 新增 `validate` 事件,#10351 - Progress - 新增 `color` 属性,#10352(by @YunYouJun) - Button - 新增 `circle` 属性,#10359(by @YunYouJun) #### 修复 - Form - 修复嵌套复合型 Input 时,FormItem 标签与输入框未对齐的问题,#10189 - Menu - 现在折叠状态的菜单项仅在传入 `title` slot 时才显示 Tooltip,#10193(by @PanJiaChen) - Pagination - 修复 `current-change` 在未发生用户交互时错误触发的问题,#10247 - DatePicker - 现在时间日期选择器下拉面板中的值能够正确地从 `format` 属性中获取对应格式了,#10174(by @remizovvv) - Upload - 现在拖拽上传会拦截不在 `accept` 属性范围内的文件,#10278 ### 2.2.2 *2018-03-14* - 新增 Input 的 `clear` 事件,#9988(by @blackmiaool) - 现在 ColorPicker 的手动输入支持 `hsl`、`hsv` 和 `rgb` 格式了,#9991 - 修复 DatePicker 在清除初始值时不触发 `change` 事件的问题,#9986 - 现在 Rate 的图标类相关属性支持动态更新了,#10003 - 修复含有固定列的 Table 在设置 `max-height` 属性后有时不能及时更新布局高度的问题,#10034 - 现在 DatePicker 的范围选择支持先点选结束日期,再点选开始日期了,#8156(by @earlymeme) - 新增 Pagination 的 `disabled` 属性,#10006 - 新增 Popover 的 `after-enter` 和 `after-leave` 事件,#10047 - 修复重置表单后,用户第一次改变 Select 的值时不触发校验的问题,#10105 - 修复 Table 的固定列在某些情况下宽度不正确的问题,#10130 - 修复调用 MessageBox 未传入 `title` 时,打开的 MessageBox 会继承上一个实例的 `title` 属性的问题,#10126(by @Pochodaydayup) - 新增 Slider 的 `input-size` 属性,#10154 - 新增 Transfer 的 `left-check-change` 和 `right-check-change` 事件,#10156 ### 2.2.1 *2018-03-02* - 修复 Aside、Header 和 Footer 在某些布局中被压缩的问题,#9812 - 修复设置了 `height` 属性的 Table 在服务端渲染时无法加载的问题,#9876 - 修复可展开的 Table 在展开某一行后高度未重新计算的问题,#9848 - 修复在 DateTimePicker 中手动输入日期后不能正确触发 `change` 事件的问题,#9913 - 修复鼠标右键点击 Select 的输入框会展开选项的问题,#9894(by @openks) - 新增 Slider 的 `tooltip-class` 属性,#9957 - 现在的 Select 在选中选项后仍然处于 focus 状态,#9857(by @Seebiscuit) - 新增 Transfer 的 `target-order` 属性,#9960 ### 2.2.0 Graphite *2018-02-12* #### 新特性 - Menu - SubMenu 新增 `popper-class` 和 `disabled` 属性,#9604 #9771 - 现在水平模式下的 Menu 支持多级 SubMenu 了,#9741 - Tree - 新增 `node-contextmenu` 事件,#9678 - 现在可以使用 scoped slot 自定义树节点的模板了,#9686 - 新增 `getNode`、`remove`、`append`、`insertBefore`、`insertAfter`、`getCheckedKeys`、`getHalfCheckedNodes`、`getHalfCheckedKeys` 方法和 `check` 事件,#9718 #9730 - Transfer - 新增 `clearQuery` 方法,#9753 - Select - 新增 `popper-append-to-body` 属性,#9782 #### 修复 - Table - 修复点击可展开行的展开图标会触发 `row-click` 事件的问题,#9654 - 修复某些情况下通过拖动改变列宽后,布局没有同步更新的问题,#9668 - 修复合计行与固定列并存时的样式问题,#9667 - Container - 修复布局组件在 IE11 中无法自动填充可用空间的问题,#9655 - Loading - 修复在 `mounted` 中修改 `v-loading` 的值为 true 时不能正确显示 Loading 的问题,#9722 - Switch - 修复点击时会触发两次原生 click 事件的问题,#9760 ### 2.1.0 Charcoal *2018-01-31* #### 新特性 - Cascader - 新增 `focus` 和 `blur` 事件,#9184(by @viewweiwu) - Table - `filter-method` 方法加入第三个参数 `column`,#9196(by @liyanlong) - DatePicker - 新增 `prefix-icon` 和 `clear-icon` 属性,#9237(by @AdamSGit) - 新增 `default-time` 属性,#9094(by @nighca) - `value-format` 属性增加对 `timestamp` 的支持,#9319(by @wacky6) - InputNumber - 组件绑定变量的值支持 `undefined`,#9361 - Select - 新增 `auto-complete` 属性,#9388 - Form - 新增 `disabled` 属性,#9529 - 新增 `validateOnRuleChange` 属性,#8141 - Notificaition - 新增 `closeAll` 方法,#9514 #### 修复 - InputNumber - 修复初始输入小数点时被重置的问题,#9116 - Dropdown - 修复当页面仅有水平滚动条时,某些浏览器下拉菜单定位错误的问题,#9138(by @banzhuanmei) - Table - 修复带有固定列的 Table 在列数据变化后固定列的个数计算错误的问题,#9188(by @kolesoffac) - 修复多级表头最后一列的边框不能正确显示的问题,#9326 - 修复在 Safari 浏览器中表头错位的问题,#9327 - 修复带有展开行的表格在展开某一行后,当表格数据更新但 `row-key` 值不变时,该行会自动收起的问题,#9462 - 修复在一些情况下不必要的多次渲染问题,#9426 - 修复动态改变 TableColumn 的 `width` 属性时,其宽度计算错误的问题,#9426 - Loading - 修复某些情况下 Loading 不能被正确隐藏的问题,#9313 - DatePicker - 修复 `focus` 方法在范围选择时无效的问题,#9437 - 修复当目前时刻处于不可选择的范围内时,点击面板上的「此刻」按钮仍能选中目前时刻的问题,#9470(by @wacky6) - 修复当在月选择面板中选中天数较少的月份时,日期面板呈现下一个月的问题,#9577(by @wacky6) - Steps - 修复在 IE 11 中的样式问题,#9454 #### 非兼容性更新 - Menu - `collapse` 状态下的弹出菜单现在会插入至 body 元素,修复其位于 Aside 内时弹出菜单不可见的问题,#9263 - Table - 勾选多选表格的 checkbox 时不再同时触发 `row-click` 事件,#9467 - Loading - 非全屏 Loading 遮罩层的 `z-index` 修改为 2000;全屏 Loading 遮罩层的 `z-index` 值会随页面上的弹出组件动态更新,#9522 - Dropdown - `show-timeout` 和 `hide-timeout` 属性现在仅在 trigger 为 `hover` 时生效,#9573 ### 2.0.11 *2018-01-08* - 修复 Input 的 `prepend` 或 `append` slot 中 Select 的边框颜色错误,#9089 - 修复 Select 的 `remove-tag` 事件参数与文档不符的问题,#9090 - 新增 SubMenu 的 `show-timeout` 和 `hide-timeout` 属性,#8934(by @HugoLew) - 修复按需引入 Table 时 `show-overflow-tooltip` 的 Tooltip 样式丢失的问题,#9130 - 修复 Table 在执行 `clearSort` 后点击对应列的排序图标无法正常排序的问题,#9100(by @zEmily) - 捷克语的 i18n 配置文件由 `cz` 重命名为 `cs-CZ`,#9164 ### 2.0.10 *2017-12-29* - 修复了 Table 在固定列和合计行并存时的高度计算错误的问题,#9026 - 修复了 Table 样式 SCSS 文件错误编译的问题,#9028 - 现在 DatePicker 的 `change` 事件只会在 `value` 真正改变的时候触发,#9029(by @remizovvv) - 新增 Input 的 `tabindex` 属性,#9041(by @dicklwm) ### 2.0.9🎄 *2017-12-24* - 新增 Upload 的 `before-remove` 钩子方法,#8788(by @firesh) - 修复 FormItem 的 `error` 属性初始值无效的问题,#8840 - 通过指令调用的 Loading 现在支持以 `element-loading-custom-class` 属性的方式设置自定义类名,#8826(by @earlymeme) - 修复 CarouselItem 为异步获取时被隐藏的问题,#8921 - 新增 Tree 的 `renderAfterExpand` 属性,#8972 ### 2.0.8 *2017-12-12* - 新增西班牙语文档 - 修复 `show-timeout` 对点击触发的 Dropdown 无效的问题,#8734(by @presidenten) - 修复 Form 对于 `trigger` 为 blur 的校验规则触发时机有误的问题,#8776 - 修复 DatePicker 在范围选择时 blur 事件触发时机有误的问题,#8784 - TimePicker 的 `format` 新增对 AM/PM 的支持,#8620(by @firesh) ### 2.0.7 *2017-11-29* - 修复禁用文字按钮的样式问题,#8570 ### 2.0.6 *2017-11-29* - 修复 Table 排序图标的样式问题,#8405 - 修复 `trigger` 为 manual 的 Popover 的触发问题,#8467 - 新增 Autocomplete 的 `prefix-icon` 和 `suffix-icon` 属性,#8446(by @liyanlong) - 新增 Cascader 的 `separator` 属性,#8501 - 新增 Input 的 `clearable` 属性,#8509(by @lbogdan) - 新增 Pagination 的 `background` 属性,#8553 ### 2.0.5 *2017-11-17* - 修复上个版本引入的 Popover、Tree、Breadcrumb、Cascader 的 bug,#8188 #8217 #8283 - 修复 clickoutside 指令的内存泄露问题,#8168 #8225(by @badpunman @STLighter) - 修复默认尺寸的多选 Select 在清空选项后输入框高度不随之更新的问题,#8317(by @luciy) - 新增 Select 的 `collapse-tags` 属性,用于在多选时以文字代替 Tag,避免组件高度的增大,#8190 - 修复被隐藏的 Table 会造成 CPU 占用持续增加的问题,#8351 - 开放 Table 的 `doLayout` 方法,用于重新计算 Table 的布局,#8351 ### 2.0.4 *2017-11-10* - 提升 Cascader、Dropdown、Message、Notification、Popover、Tooltip、Tree 的可访问性 - 修复当视口变窄时 Container 无法同步更新其宽度的问题,#8042 - 修复 Tree 的 `updateKeyChildren` 在删除子节点时的行为错误,#8100 - 修复带有边框的 CheckboxButton 在 Form 中高度错误的问题,#8100 - 修复 Menu 在解析自定义颜色时的错误,#8153(by @zhouyixiang) ### 2.0.3 *2017-11-03* - 修复范围选择的 DatePicker `editable` 和 `readonly` 属性无法正常工作的问题,#7922 - 修复嵌套的 Tabs 的样式错误,#7941 - 修复纵向 Steps 中最后一个 Step 的样式错误,#7980 - 修复 Pagination 的 `current-change` 事件触发时机错误的问题,#7995 - 修复由于 Menu 使用了未注册的 Tooltip 造成其在按需引入时报错的问题,#7995 ### 2.0.2 *2017-10-31* - 在 InputNumber 的加减按钮上单击鼠标右键不再触发值的改变,#7817 - Form 的 `validate` 方法现在能够正确地在异步校验完成后执行回调了,#7774(by @Allenice) - 修复 DatePicker 的范围选择在内核为 Chromium 53-57 的浏览器中无法使用的问题,#7838 - 修复 `list-type` 为 picture-card 的 Upload 预览和删除图标丢失的问题,#7857 - 新增 TableColumn 的 `sort-by` 属性,#7828(by @wangfengming) - 修复周模式下的 DatePicker 在选择某年第一周可能会显示为前一年第一周的问题,#7860(by @hh23485) - 修复垂直模式的 Steps 中图标宽度的样式错误,#7891 - 增大了 Tree 中展开箭头的点击热区,#7891 ### 2.0.1 *2017-10-28* - 修复 RadioButton 和 CheckboxButton 的样式问题,#7793 - 修复 TimePicker 在某些情况下无法滚动的问题,#7811 - 修复部分组件在按需引入时样式不完整的问题,#7811 ### 2.0.0 Carbon *2017-10-27* #### 新特性 - 综合 - 新增 `theme-chalk` 主题 - 增强以下组件的可访问性:Alert、AutoComplete、Breadcrumb、Button、Checkbox、Collapse、Input、InputNumber、Menu、Progress、Radio、Rate、Slider、Switch 和 Upload - 新增布局组件 Container、Header、Aside、Main 和 Footer - 新增 TypeScript 类型声明 - 重绘了全部图标,并新增了部分图标 - 新增了一系列基于断点的工具类,用于当视口尺寸满足一定条件时隐藏元素 - 新增全局配置组件尺寸的功能。在引入 Element 时,配置 `size` 字段可以改变所有组件的默认尺寸 - Button - 新增 `round` 属性,用于圆角按钮 #6643 - TimeSelect - 可以用 `Up`、`Down` 导航,用 `Enter` 选中时间 #6023 - TimePicker - 可以用方向键导航,用 `Enter` 选中时间 #6050 - 新增 `start-placeholder` 和 `end-placeholder`,用于设置范围选择时两个输入框的占位符 #7169 - 新增 `arrow-control` 属性,提供另一种交互形式,#7438 - Tree - 子节点在首次被展开之前不进行渲染 #6257 - 新增 `check-descendants` 属性,设置 `lazy` 模式下勾选节点时,是否完全展开整个子树 #6235 - Tag - 新增 `size` 属性 #7203 - Datepicker - type 为 `datetimerange` 时可以使用 `timeFormat` 格式化时间选择器 #6052 - 新增 `start-placeholder` 和 `end-placeholder`,用于设置范围选择时两个输入框的占位符 #7169 - 新增 `value-format` 属性,支持对绑定值的格式进行自定义,#7367 - 新增 `unlink-panels` 属性,用于在选择日期范围时取消两个日期面板之间的联动 - MessageBox - 新增 `closeOnHashChange` 属性 #6043 - 新增 `center` 属性,提供居中布局 #7029 - 新增 `roundButton` 属性,使得内部按钮为圆角按钮 #7029 - 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 支持传入 HTML 字符串* #6043 - 新增 `inputType` 属性,用户指定内部输入框的类型,#7651 - Dialog - 新增 `width`、`fullscreen`、`append-to-body` 属性,支持嵌套使用 - 新增 `center` 属性,提供居中布局 #7042 - 新增 `focus-after-closed`、`focus-after-open`属性,支持无障碍访问 #6511 - ColorPicker - 增加手动输入色值的支持 #6167 - 新增 `size` 属性,用于控制组件的大小 #7026 - 新增 `disabled` 属性,用于禁用组件 #7026 - 新增 `popper-class` 属性,#7351 - Message - 图标部分使用 icon 代替图片,从而支持通过 CSS 修改图标背景色 #6207 - 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 属性支持传入 HTML 字符串* #6207 - 新增 `center` 属性,提供居中布局 #6875 - Notification - 新增 `position` 属性,用于配置 Notification 出现的位置 #6231 - 新增 `dangerouslyUseHTMLString` 属性,使得 `message` 属性支持传入 HTML 字符串* #6231 - 新增 `showClose` 属性,用于隐藏关闭按钮 #6402 - Rate - 新增 `show-score` 属性,控制是否在右侧显示当前分数 #6295 - Tabs - 新增 `tab-position` 属性,控制选项面板内容显示的上、下、左、右四个方向 #6096 - Radio - 增加 `border` 属性和 `size` 属性 #6690 - Checkbox - 增加 `border` 属性和 `size` 属性 #6690 - Alert - 新增 `center` 属性,提供居中布局 #6876 - Menu - 新增 `background-color`、`text-color` 和 `active-text-color` 属性,分别用于设置菜单的背景色、菜单的文字颜色和当前激活菜单的文字颜色 #7064 - 新增 `open` 和 `close` 方法,支持手动打开和关闭 SubMenu,#7412 - Form - 新增 `inline-message` 属性,设置后校验信息会以行内样式显示 #7032 - 新增 `status-icon` 属性,用于在输入框中显示校验结果反馈图标 #7032 - Form 和 FormItem 新增 `size` 属性,用于控制表单内组件的尺寸,#7428 - `validate` 方法在不传入 callback 的情况下返回 promise,#7405 - 新增 `clearValidate` 方法,用于清空所有表单项的验证信息,#7623 - Input - 新增 `suffix`、`prefix` 的 slot,以及 `suffixIcon`、`prefixIcon` 属性,用于给输入框内部增加前置和后置内容 #7032 - Breadcrumb - 新增 `separator-class` 属性,可使用图标作为分隔符 #7203 - Steps - 新增 `simple` 属性,用于开启简洁风格的步骤条 #7274 - Pagination - 新增 `prev-text` 和 `next-text` 属性,用于自定义上一页和下一页的文本 #7005 - Loading - 配置对象新增 `spinner` 和 `background` 字段,支持自定义加载图标和背景色,#7390 - Autocomplete - 新增 `debounce` 属性,#7413 - Upload - 新增 `limit` 和 `on-exceed` 属性,支持对上传文件的个数进行限制,#7405 - DateTimePicker - 新增 `time-arrow-control` 属性,用于开启时间选择器的 `arrow-control`,#7438 - Layout - 新增断点 `xl`,适用于宽度大于 1920px 的视口 - Table - 新增 `span-method` 属性,用于合并行或列 - 新增 `clearSort` 方法,用于清空排序状态 - 新增 `clearFilter` 方法,用于清空过滤状态 - 对于可展开行,当该行展开时会获得一个 `.expanded` 类名,方便自定义样式 - 新增 `size` 属性,用于控制表格尺寸 - 新增 `toggleRowExpansion` 方法,用于手动展开或关闭行 - 新增 `cell-class-name` 属性,用于指定单元格的类名 - 新增 `cell-style` 属性,用于指定单元格的样式 - 新增 `header-row-class-name` 属性,用于指定表头行的类名 - 新增 `header-row-style` 属性,用于指定表头行的样式 - 新增 `header-cell-class-name` 属性,用于指定表头单元格的类名 - 新增 `header-cell-style` 属性,用于指定表头单元格的样式 - TableColumn 的 `prop` 属性支持 `object[key]` 格式 - TableColumn 新增 `index` 属性,用于自定义索引值 - Select - 新增 `reserve-keyword` 属性,用于在选择某个选项后保留当前的搜索关键词 #### 修复 - DatePicker - 选择周数时,`v-model` 结果返回该周第二天的问题 #6038 - 在 `daterange` 类型中,第一次的输入会被清空的问题 #6021 - DateTimePicker - 和 TimePicker 相互影响的问题 #6090 - 选择时间小时和秒可超出限制的问题 #6076 - TimePicker - 失去焦点时无法正确改变 `v-model` 值的问题 #6023 - Dialog - 当含有下拉框时,下拉框的打开和关闭会造成文字虚晃的问题 #6088 - Select - 提升性能,修复组件销毁时可能导致 Vue dev-tool 卡死的问题 #6151 - Table - 修复 Table 在父元素从 `display: none` 变成其他状态时会隐藏的问题 - 修复 Table 在父元素为 `display: flex` 时可能出现的宽度逐渐变大的问题 - 修复 `append` 具名 slot 和固定列并存时,动态获取表格数据会导致固定列消失的问题 - 修复 `expand-row-keys` 属性初始化无效的问题 - 修复 `data` 改变时过滤条件失效的问题 - 修复多级表头时固定列隐藏情况计算错误的问题 - 修复 `max-height` 变更后无法恢复的问题 - 修复一些样式上的计算错误 #### 非兼容性更新 - 综合 - 移除 `theme-default` - 最低兼容 Vue 2.5.2 和 IE 10 - 表单组件的 `change` 事件和 Pagination 的 `current-change` 事件现在仅响应用户交互 - Button 和表单组件的 `size` 属性现在可接受 `medium`、`small` 和 `mini` - 为了方便使用第三方图标,Button 的 `icon` 属性、Input 的 `prefix-icon` 和 `suffix-icon` 属性、Steps 的 `icon` 属性现在需要传入完整的图标类名 - Dialog - 移除 `size` 属性。现在 Dialog 的尺寸由 `width` 和 `fullscreen` 控制 - 移除通过 `v-model` 控制 Dialog 显示和隐藏的功能 - Rate - `text-template` 属性更名为 `score-template` - Dropdown - `menu-align` 属性变更为 `placement`,增加更多方位属性 - Transfer - `footer-format` 属性更名为 `format` - Switch - 由于 `on-*` 属性在 JSX 中会被识别为事件,导致 Switch 所有 `on-*` 属性在 JSX 中无法正常工作,所以 `on-*` 属性更名为 `active-*`,对应地,`off-*` 属性更名为 `inactive-*`。受到影响的属性有:`on-icon-class`、`off-icon-class`、`on-text`、`off-text`、`on-color`、`off-color`、`on-value`、`off-value` - `active-text` 和 `inactive-text` 属性不再有默认值 - Tag - `type` 属性现在支持 `success`、`info`、`warning` 和 `danger` 四个值 - Menu - 移除 `theme` 属性。现在通过 `background-color`、`text-color` 和 `active-text-color` 属性进行颜色的自定义 - Input - 移除 `icon` 属性。现在通过 `suffix-icon` 属性或者 `suffix` 具名 slot 来加入尾部图标 - 移除 `on-icon-click` 属性和 `click` 事件。现在如果需要为输入框中的图标添加点击事件,请以具名 slot 的方式添加图标 - `change` 事件现在仅在输入框失去焦点或用户按下回车时触发,与原生 input 元素一致。如果需要实时响应用户的输入,可以使用 `input` 事件 - Autocomplete - 移除 `custom-item` 属性。现在通过 `scoped slot` 自定义输入建议列表项的内容 - 移除 `props` 属性,现在使用 `value-key` 属性指定输入建议对象中用于显示的键名 - Steps - 移除 `center` 属性 - 现在步骤条将默认充满父容器 - DatePicker - `change` 事件参数现在为组件的绑定值,格式由 `value-format` 控制 - Table - 移除通过 `inline-template` 自定义列模板的功能 - `sort-method` 现在和 `Array.sort` 保持一致的逻辑,要求返回一个数字 - 将 `append` slot 移至 `tbody` 元素以外,以保证其只被渲染一次 - `expand` 事件更名为 `expand-change`,以保证 API 的命名一致性 - `row-class-name` 和 `row-style` 的函数参数改为对象,以保证 API 的一致性 ## * 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 [XSS 攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。因此请在 `dangerouslyUseHTMLString` 打开的情况下,确保 `message` 的内容是可信的,**永远不要**将用户提交的内容赋值给 `message` 属性。 ================================================ FILE: FAQ.md ================================================ ## 常见问题
给组件绑定的事件为什么无法触发? 在 Vue 2.0 中,为**自定义**组件绑定**原生**事件必须使用 `.native` 修饰符: ```html Click Me ``` 从易用性的角度出发,我们对 `Button` 组件进行了处理,使它可以监听 `click` 事件: ```html Click Me ``` 但是对于其他组件,还是需要添加 `.native` 修饰符。
如何在 Table 组件的每一行添加操作该行数据的按钮? 使用 [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots) 即可: ```html ``` 参数 `row` 即为对应行的数据。
Tree 组件的 `render-content` 和 Table 组件的 `render-header` 怎么用? 请阅读 Vue 文档 [Render Function](http://vuejs.org/v2/guide/render-function.html) 的相关内容。注意,使用 JSX 来写 Render Function 的话,需要安装 `babel-plugin-transform-vue-jsx`,并参照其[文档](https://github.com/vuejs/babel-plugin-transform-vue-jsx)进行配置。
所有组件的任意属性都支持 `.sync` 修饰符吗? 不是。对于支持 `.sync` 修饰符的属性,我们会在文档的 API 表格中注明。更多 `.sync` 的用法请查看 [Vue 文档](https://vuejs.org/v2/guide/components.html#sync-Modifier)。
你们的文档怎么偷偷更新了? 我们只会在 Element 发布新版本时同步更新文档,以体现最新的变化。详细的更新内容可以查看 [changelog](https://github.com/ElemeFE/element/blob/master/CHANGELOG.zh-CN.md)。
在项目中引入 Element,但是 CSS 报错/字体文件报错/组件没有样式是什么原因? 请参考我们提供的 [starter kit](https://github.com/ElementUI/element-starter),在 webpack 的 loaders 中正确配置 file-loader、css-loader 和 style-loader。此外,我们还提供了基于 [cooking](https://github.com/ElementUI/element-cooking-starter) 和 [laravel](https://github.com/ElementUI/element-in-laravel-starter) 的项目模板。
将 Element 克隆至本地,运行时为何会报错/跑不起来? 首先,确保克隆的是 master 分支的最新代码,并且文件完整。其次,确保本地的 node 版本在 4.0 以上,npm 版本在 3.0 以上。最后,可以启动开发环境: ```bash npm run dev ``` 或是直接打包: ```bash npm run dist ```
## FAQ
Why are my event listeners not working? In Vue 2.0, adding **native** event handlers in **custom** components requires a `.native` modifier: ```html Click Me ``` For the sake of usability, we processed `Button` so it can listen to `click` events: ```html Click Me ``` For other components, the `.native` modifier is still mandatory.
How do I add buttons in each row of Table to operate data of that row? Just use [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots): ```html ``` The parameter `row` is the data object of corresponding row.
How do `render-content` of Tree and `render-header` of Table work? Please refer to [Render Function](http://vuejs.org/v2/guide/render-function.html) in Vue's documentation. In addition, if you are writing render functions with JSX, `babel-plugin-transform-vue-jsx` is required. See [here](https://github.com/vuejs/babel-plugin-transform-vue-jsx) for its configurations.
Can I use `.sync` modifier on every attribute? No, only a few attributes supports the `.sync` modifier, and we have explicitly marked them on the documentation's API table. For more information about `.sync`, please refer to [Vue documentation](https://vuejs.org/v2/guide/components.html#sync-Modifier).
When do you update documentations of Element? We update documentations only when a new version of Element is published so that it reflects all the changes introduced in that version. Updated changed can be found in the [changelog](https://github.com/ElemeFE/element/blob/master/CHANGELOG.en-US.md)。
I imported Element in my project, but why does it report CSS error/font file error/components have no style? Please refer to our [starter kit](https://github.com/ElementUI/element-starter) and correctly configure file-loader, css-loader and style-loader in webpack config file. Besides, we also provide templated based on [cooking](https://github.com/ElementUI/element-cooking-starter) and [laravel](https://github.com/ElementUI/element-in-laravel-starter).
I cloned Element's repo, but failed to run it. How do I solve it? First, please make sure to clone the latest code in master branch and cloned files are intact. Then, note that the version of Nodejs should be 4.0+ and npm 3.0+. Finally, activate development: ```bash npm run dev ``` or build it: ```bash npm run dist ```
## Preguntas más frecuentes
¿Porque mis receptores de eventos no funcionan? En Vue 2.0, agregando **nativos** receptores de evento **a medida** componentes requiere el modificador `.native`: ``` html Haga Clic Aquí ``` Para conveniencia, hemos ya procesado eventos para el componente `Button` para que el interfaz sea consistente con `clic` eventos de otros componentes: ```html Haga Clic Aquí ``` Para otros componentes el uso del modificador `.native` sigue siendo obligatorio.
¿Como agrego botones en cada linea de una tabla para que operen en los datos de esa linea? Simplemente agregue [“Scoped slot”](https://vuejs.org/v2/guide/components.html#Scoped-Slots): ```html ``` El parámetro `row` contiene los datos de la linea correspondiente de la tabla.
¿Como funcionan `render-content` de `Tree` y `render-header` de `Table`? Por favor refiérase a [Función de representación](http://vuejs.org/v2/guide/render-function.html) en la documentación de `Vue`. Adicionalmente, sí usted está escribiendo funciones de representar con JSX, se requiere el componente `babel-plugin-transform-vue-jsx`. Más información [aquí](https://github.com/vuejs/babel-plugin-transform-vue-jsx) para su uso y configuración.
¿Puedo usar el modificador `.sync` con cada atributo? No, solamente un grupo pequeño de atributos apoyan el modificador `.sync`, y están anotados claramente en la documentación del IPA. Para información adicional sobre `.sync`, por favor refiérase a [documentación de Vue](https://vuejs.org/v2/guide/components.html#sync-Modifier).
¿Cuando añaden a la documentación de `Element`? Añadamos la documentación con cada versión nueva de `Element` y los cambios reflejan los cambios del software de esa versión. Los cambios actuales y históricos se encuentran [aquí](https://github.com/ElemeFE/element/blob/master/CHANGELOG.en-US.md).
¿Importé `Element` a mi proyecto pero tengo errores con `CSS` y/o fuentes y mis componentes no tienen ningún estilo? Refiérase a [nuestro ‘kit’ de inicio](https://github.com/ElementUI/element-starter) y configure correctamente `file-loader`, `css-loader` y `style-loader` en el archivo `webpack config`. Además, proveemos un ejemplar para [cooking](https://github.com/ElementUI/element-cooking-starter) y para [laravel](https://github.com/ElementUI/element-in-laravel-starter).
Hice un clon del repositorio de `Element` pero no arranca. ¿Como lo resuelvo? Primero, pro favor, asegúrese de usar la versión más corriente en la rama `master` y que los archivos están en orden. Después, revise sí la versión de `Nodejs` es 4.0+ y `npm` debe ser 3.0+. Finalmente active el modo desarrollo: ```bash npm run dev ``` O arme su aplicación así: ```bash npm run dist ```
================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2016-present ElemeFE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ .PHONY: dist test default: help # build all theme build-theme: npm run build:theme install: npm install install-cn: npm install --registry=http://registry.npm.taobao.org dev: npm run dev play: npm run dev:play new: node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS)) new-lang: node build/bin/new-lang.js $(filter-out $@,$(MAKECMDGOALS)) dist: install npm run dist deploy: @npm run deploy pub: npm run pub test: npm run test:watch help: @echo " \033[35mmake\033[0m \033[1m命令使用说明\033[0m" @echo " \033[35mmake install\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 安装依赖" @echo " \033[35mmake new [中文名]\033[0m\t--- 创建新组件 package. 例如 'make new button 按钮'" @echo " \033[35mmake dev\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 开发模式" @echo " \033[35mmake dist\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 编译项目,生成目标文件" @echo " \033[35mmake deploy\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 部署 demo" @echo " \033[35mmake pub\033[0m\t\033[0m\t\033[0m\t\033[0m\t--- 发布到 npm 上" @echo " \033[35mmake new-lang \033[0m\t\033[0m\t\033[0m\t--- 为网站添加新语言. 例如 'make new-lang fr'" ================================================ FILE: README.md ================================================


> A Vue.js 2.0 UI Toolkit for Web. Element will stay with Vue 2.x For Vue 3.0, we recommend using [Element Plus](https://github.com/element-plus/element-plus)(Element Plus is a community develop project) For MiniProgram development, we recommend using [MorJS](https://github.com/eleme/morjs) ## Links - Homepage and documentation - [International users](http://element.eleme.io/#/en-US) - [Chinese users](http://element.eleme.io/#/zh-CN) - [Spanish users](http://element.eleme.io/#/es) - [French users](http://element.eleme.io/#/fr-FR) - [awesome-element](https://github.com/ElementUI/awesome-element) - [FAQ](./FAQ.md) - [Vue.js 3.0 migration](https://github.com/element-plus/element-plus) - [Customize theme](http://element.eleme.io/#/en-US/component/custom-theme) - [Preview and generate theme online](https://elementui.github.io/theme-chalk-preview) - [Element for React](https://github.com/elemefe/element-react) - [Element for Angular](https://github.com/ElemeFE/element-angular) - [Atom helper](https://github.com/ElemeFE/element-helper) - [Visual Studio Code helper](https://github.com/ElemeFE/vscode-element-helper) - Starter kit - [element-starter](https://github.com/ElementUI/element-starter) - [element-in-laravel-starter](https://github.com/ElementUI/element-in-laravel-starter) - [Design resources](https://github.com/ElementUI/Resources) - Gitter - [International users](https://gitter.im/element-en/Lobby) - [Chinese users](https://gitter.im/ElemeFE/element) ## Install ```shell npm install element-ui -S ``` ## Quick Start ``` javascript import Vue from 'vue' import Element from 'element-ui' Vue.use(Element) // or import { Select, Button // ... } from 'element-ui' Vue.component(Select.name, Select) Vue.component(Button.name, Button) ``` For more information, please refer to [Quick Start](http://element.eleme.io/#/en-US/component/quickstart) in our documentation. ## Browser Support Modern browsers and Internet Explorer 10+. ## Development Skip this part if you just want to use Element. For those who are interested in contributing to Element, please refer to our 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) | [Español](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.es.md) | [Français](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.fr-FR.md)) to see how to run this project. ## Changelog Detailed changes for each release are documented in the [release notes](https://github.com/ElemeFE/element/releases). ## FAQ We have collected some [frequently asked questions](https://github.com/ElemeFE/element/blob/master/FAQ.md). Before reporting an issue, please search if the FAQ has the answer to your problem. ## Contribution Please make sure to read the 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) | [Español](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.es.md) | [Français](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.fr-FR.md)) before making a pull request. ## Special Thanks English documentation is brought to you by SwiftGG Translation Team: - [raychenfj](https://github.com/raychenfj) - [kevin](http://thekevin.cn/) - [曾小涛](https://github.com/zengxiaotao) - [湾仔王二](https://github.com/wanzaiwanger) - [BlooDLine](http://www.ibloodline.com/) - [陈铭嘉](https://chenmingjia.github.io/) - [千叶知风](http://mpc6.com/) - [梁杰](http://numbbbbb.com) - [Changing](https://github.com/sunzhuo11) - [mmoaay](https://github.com/mmoaay) Spanish documentation is made possible by these community developers: - [adavie1](https://github.com/adavie1) - [carmencitaqiu](https://github.com/carmencitaqiu) - [coderdiaz](https://github.com/coderdiaz) - [fedegar33](https://github.com/fedegar33) - [Gonzalo2310](https://github.com/Gonzalo2310) - [lesterbx](https://github.com/lesterbx) - [ProgramerGuy](https://github.com/ProgramerGuy) - [SantiagoGdaR](https://github.com/SantiagoGdaR) - [sigfriedCub1990](https://github.com/sigfriedCub1990) - [thechosenjuan](https://github.com/thechosenjuan) French documentation is made possible by these community developers: - [smalesys](https://github.com/smalesys) - [blombard](https://github.com/blombard) ## Join Discussion Group Scan the QR code using [Dingtalk App](https://www.dingtalk.com/) to join in discussion group : Join Discusion Group ## LICENSE [MIT](LICENSE) ================================================ FILE: build/bin/build-entry.js ================================================ var Components = require('../../components.json'); var fs = require('fs'); var render = require('json-templater/string'); var uppercamelcase = require('uppercamelcase'); var path = require('path'); var endOfLine = require('os').EOL; var OUTPUT_PATH = path.join(__dirname, '../../src/index.js'); var IMPORT_TEMPLATE = 'import {{name}} from \'../packages/{{package}}/index.js\';'; var INSTALL_COMPONENT_TEMPLATE = ' {{name}}'; var MAIN_TEMPLATE = `/* Automatically generated by './build/bin/build-entry.js' */ {{include}} import locale from 'element-ui/src/locale'; import CollapseTransition from 'element-ui/src/transitions/collapse-transition'; const components = [ {{install}}, CollapseTransition ]; const install = function(Vue, opts = {}) { locale.use(opts.locale); locale.i18n(opts.i18n); components.forEach(component => { Vue.component(component.name, component); }); Vue.use(InfiniteScroll); Vue.use(Loading.directive); Vue.prototype.$ELEMENT = { size: opts.size || '', zIndex: opts.zIndex || 2000 }; Vue.prototype.$loading = Loading.service; Vue.prototype.$msgbox = MessageBox; Vue.prototype.$alert = MessageBox.alert; Vue.prototype.$confirm = MessageBox.confirm; Vue.prototype.$prompt = MessageBox.prompt; Vue.prototype.$notify = Notification; Vue.prototype.$message = Message; }; /* istanbul ignore if */ if (typeof window !== 'undefined' && window.Vue) { install(window.Vue); } export default { version: '{{version}}', locale: locale.use, i18n: locale.i18n, install, CollapseTransition, Loading, {{list}} }; `; delete Components.font; var ComponentNames = Object.keys(Components); var includeComponentTemplate = []; var installTemplate = []; var listTemplate = []; ComponentNames.forEach(name => { var componentName = uppercamelcase(name); includeComponentTemplate.push(render(IMPORT_TEMPLATE, { name: componentName, package: name })); if (['Loading', 'MessageBox', 'Notification', 'Message', 'InfiniteScroll'].indexOf(componentName) === -1) { installTemplate.push(render(INSTALL_COMPONENT_TEMPLATE, { name: componentName, component: name })); } if (componentName !== 'Loading') listTemplate.push(` ${componentName}`); }); var template = render(MAIN_TEMPLATE, { include: includeComponentTemplate.join(endOfLine), install: installTemplate.join(',' + endOfLine), version: process.env.VERSION || require('../../package.json').version, list: listTemplate.join(',' + endOfLine) }); fs.writeFileSync(OUTPUT_PATH, template); console.log('[build entry] DONE:', OUTPUT_PATH); ================================================ FILE: build/bin/build-locale.js ================================================ var fs = require('fs'); var save = require('file-save'); var resolve = require('path').resolve; var basename = require('path').basename; var localePath = resolve(__dirname, '../../src/locale/lang'); var fileList = fs.readdirSync(localePath); var transform = function(filename, name, cb) { require('babel-core').transformFile(resolve(localePath, filename), { plugins: [ 'add-module-exports', ['transform-es2015-modules-umd', {loose: true}] ], moduleId: name }, cb); }; fileList .filter(function(file) { return /\.js$/.test(file); }) .forEach(function(file) { var name = basename(file, '.js'); transform(file, name, function(err, result) { if (err) { console.error(err); } else { var code = result.code; code = code .replace('define(\'', 'define(\'element/locale/') .replace('global.', 'global.ELEMENT.lang = global.ELEMENT.lang || {}; \n global.ELEMENT.lang.'); save(resolve(__dirname, '../../lib/umd/locale', file)).write(code); console.log(file); } }); }); ================================================ FILE: build/bin/gen-cssfile.js ================================================ var fs = require('fs'); var path = require('path'); var Components = require('../../components.json'); var themes = [ 'theme-chalk' ]; Components = Object.keys(Components); var basepath = path.resolve(__dirname, '../../packages/'); function fileExists(filePath) { try { return fs.statSync(filePath).isFile(); } catch (err) { return false; } } themes.forEach((theme) => { var isSCSS = theme !== 'theme-default'; var indexContent = isSCSS ? '@import "./base.scss";\n' : '@import "./base.css";\n'; Components.forEach(function(key) { if (['icon', 'option', 'option-group'].indexOf(key) > -1) return; var fileName = key + (isSCSS ? '.scss' : '.css'); indexContent += '@import "./' + fileName + '";\n'; var filePath = path.resolve(basepath, theme, 'src', fileName); if (!fileExists(filePath)) { fs.writeFileSync(filePath, '', 'utf8'); console.log(theme, ' 创建遗漏的 ', fileName, ' 文件'); } }); fs.writeFileSync(path.resolve(basepath, theme, 'src', isSCSS ? 'index.scss' : 'index.css'), indexContent); }); ================================================ FILE: build/bin/gen-indices.js ================================================ 'use strict'; const fs = require('fs'); const path = require('path'); const algoliasearch = require('algoliasearch'); const slugify = require('transliteration').slugify; const key = require('./algolia-key'); const client = algoliasearch('4C63BTGP6S', key); const langs = { 'zh-CN': 'element-zh', 'en-US': 'element-en', 'es': 'element-es', 'fr-FR': 'element-fr' }; ['zh-CN', 'en-US', 'es', 'fr-FR'].forEach(lang => { const indexName = langs[lang]; const index = client.initIndex(indexName); index.clearIndex(err => { if (err) return; fs.readdir(path.resolve(__dirname, `../../examples/docs/${ lang }`), (err, files) => { if (err) return; let indices = []; files.forEach(file => { const component = file.replace('.md', ''); const content = fs.readFileSync(path.resolve(__dirname, `../../examples/docs/${ lang }/${ file }`), 'utf8'); const matches = content .replace(/:::[\s\S]*?:::/g, '') .replace(/```[\s\S]*?```/g, '') .match(/#{2,4}[^#]*/g) .map(match => match.replace(/\n+/g, '\n').split('\n').filter(part => !!part)) .map(match => { const length = match.length; if (length > 2) { const desc = match.slice(1, length).join(''); return [match[0], desc]; } return match; }); indices = indices.concat(matches.map(match => { const isComponent = match[0].indexOf('###') < 0; const title = match[0].replace(/#{2,4}/, '').trim(); const index = { component, title }; index.ranking = isComponent ? 2 : 1; index.anchor = slugify(title); index.content = (match[1] || title).replace(/<[^>]+>/g, ''); return index; })); }); index.addObjects(indices, (err, res) => { console.log(err, res); }); }); }); }); ================================================ FILE: build/bin/i18n.js ================================================ 'use strict'; var fs = require('fs'); var path = require('path'); var langConfig = require('../../examples/i18n/page.json'); langConfig.forEach(lang => { try { fs.statSync(path.resolve(__dirname, `../../examples/pages/${ lang.lang }`)); } catch (e) { fs.mkdirSync(path.resolve(__dirname, `../../examples/pages/${ lang.lang }`)); } Object.keys(lang.pages).forEach(page => { var templatePath = path.resolve(__dirname, `../../examples/pages/template/${ page }.tpl`); var outputPath = path.resolve(__dirname, `../../examples/pages/${ lang.lang }/${ page }.vue`); var content = fs.readFileSync(templatePath, 'utf8'); var pairs = lang.pages[page]; Object.keys(pairs).forEach(key => { content = content.replace(new RegExp(`<%=\\s*${ key }\\s*>`, 'g'), pairs[key]); }); fs.writeFileSync(outputPath, content); }); }); ================================================ FILE: build/bin/iconInit.js ================================================ 'use strict'; var postcss = require('postcss'); var fs = require('fs'); var path = require('path'); var fontFile = fs.readFileSync(path.resolve(__dirname, '../../packages/theme-chalk/src/icon.scss'), 'utf8'); var nodes = postcss.parse(fontFile).nodes; var classList = []; nodes.forEach((node) => { var selector = node.selector || ''; var reg = new RegExp(/\.el-icon-([^:]+):before/); var arr = selector.match(reg); if (arr && arr[1]) { classList.push(arr[1]); } }); classList.reverse(); // 希望按 css 文件顺序倒序排列 fs.writeFile(path.resolve(__dirname, '../../examples/icon.json'), JSON.stringify(classList), () => {}); ================================================ FILE: build/bin/new-lang.js ================================================ 'use strict'; console.log(); process.on('exit', () => { console.log(); }); if (!process.argv[2]) { console.error('[language] is required!'); process.exit(1); } var fs = require('fs'); const path = require('path'); const fileSave = require('file-save'); const lang = process.argv[2]; // const configPath = path.resolve(__dirname, '../../examples/i18n', lang); // 添加到 components.json const componentFile = require('../../examples/i18n/component.json'); if (componentFile.some(item => item.lang === lang)) { console.error(`${lang} already exists.`); process.exit(1); } let componentNew = Object.assign({}, componentFile.filter(item => item.lang === 'en-US')[0], { lang }); componentFile.push(componentNew); fileSave(path.join(__dirname, '../../examples/i18n/component.json')) .write(JSON.stringify(componentFile, null, ' '), 'utf8') .end('\n'); // 添加到 page.json const pageFile = require('../../examples/i18n/page.json'); let pageNew = Object.assign({}, pageFile.filter(item => item.lang === 'en-US')[0], { lang }); pageFile.push(pageNew); fileSave(path.join(__dirname, '../../examples/i18n/page.json')) .write(JSON.stringify(pageFile, null, ' '), 'utf8') .end('\n'); // 添加到 route.json const routeFile = require('../../examples/i18n/route.json'); routeFile.push({ lang }); fileSave(path.join(__dirname, '../../examples/i18n/route.json')) .write(JSON.stringify(routeFile, null, ' '), 'utf8') .end('\n'); // 添加到 nav.config.json const navFile = require('../../examples/nav.config.json'); navFile[lang] = navFile['en-US']; fileSave(path.join(__dirname, '../../examples/nav.config.json')) .write(JSON.stringify(navFile, null, ' '), 'utf8') .end('\n'); // docs 下新建对应文件夹 try { fs.statSync(path.resolve(__dirname, `../../examples/docs/${ lang }`)); } catch (e) { fs.mkdirSync(path.resolve(__dirname, `../../examples/docs/${ lang }`)); } console.log('DONE!'); ================================================ FILE: build/bin/new.js ================================================ 'use strict'; console.log(); process.on('exit', () => { console.log(); }); if (!process.argv[2]) { console.error('[组件名]必填 - Please enter new component name'); process.exit(1); } const path = require('path'); const fs = require('fs'); const fileSave = require('file-save'); const uppercamelcase = require('uppercamelcase'); const componentname = process.argv[2]; const chineseName = process.argv[3] || componentname; const ComponentName = uppercamelcase(componentname); const PackagePath = path.resolve(__dirname, '../../packages', componentname); const Files = [ { filename: 'index.js', content: `import ${ComponentName} from './src/main'; /* istanbul ignore next */ ${ComponentName}.install = function(Vue) { Vue.component(${ComponentName}.name, ${ComponentName}); }; export default ${ComponentName};` }, { filename: 'src/main.vue', content: ` ` }, { filename: path.join('../../examples/docs/zh-CN', `${componentname}.md`), content: `## ${ComponentName} ${chineseName}` }, { filename: path.join('../../examples/docs/en-US', `${componentname}.md`), content: `## ${ComponentName}` }, { filename: path.join('../../examples/docs/es', `${componentname}.md`), content: `## ${ComponentName}` }, { filename: path.join('../../examples/docs/fr-FR', `${componentname}.md`), content: `## ${ComponentName}` }, { filename: path.join('../../test/unit/specs', `${componentname}.spec.js`), content: `import { createTest, destroyVM } from '../util'; import ${ComponentName} from 'packages/${componentname}'; describe('${ComponentName}', () => { let vm; afterEach(() => { destroyVM(vm); }); it('create', () => { vm = createTest(${ComponentName}, true); expect(vm.$el).to.exist; }); }); ` }, { filename: path.join('../../packages/theme-chalk/src', `${componentname}.scss`), content: `@import "mixins/mixins"; @import "common/var"; @include b(${componentname}) { }` }, { filename: path.join('../../types', `${componentname}.d.ts`), content: `import { ElementUIComponent } from './component' /** ${ComponentName} Component */ export declare class El${ComponentName} extends ElementUIComponent { }` } ]; // 添加到 components.json const componentsFile = require('../../components.json'); if (componentsFile[componentname]) { console.error(`${componentname} 已存在.`); process.exit(1); } componentsFile[componentname] = `./packages/${componentname}/index.js`; fileSave(path.join(__dirname, '../../components.json')) .write(JSON.stringify(componentsFile, null, ' '), 'utf8') .end('\n'); // 添加到 index.scss const sassPath = path.join(__dirname, '../../packages/theme-chalk/src/index.scss'); const sassImportText = `${fs.readFileSync(sassPath)}@import "./${componentname}.scss";`; fileSave(sassPath) .write(sassImportText, 'utf8') .end('\n'); // 添加到 element-ui.d.ts const elementTsPath = path.join(__dirname, '../../types/element-ui.d.ts'); let elementTsText = `${fs.readFileSync(elementTsPath)} /** ${ComponentName} Component */ export class ${ComponentName} extends El${ComponentName} {}`; const index = elementTsText.indexOf('export') - 1; const importString = `import { El${ComponentName} } from './${componentname}'`; elementTsText = elementTsText.slice(0, index) + importString + '\n' + elementTsText.slice(index); fileSave(elementTsPath) .write(elementTsText, 'utf8') .end('\n'); // 创建 package Files.forEach(file => { fileSave(path.join(PackagePath, file.filename)) .write(file.content, 'utf8') .end('\n'); }); // 添加到 nav.config.json const navConfigFile = require('../../examples/nav.config.json'); Object.keys(navConfigFile).forEach(lang => { let groups = navConfigFile[lang][4].groups; groups[groups.length - 1].list.push({ path: `/${componentname}`, title: lang === 'zh-CN' && componentname !== chineseName ? `${ComponentName} ${chineseName}` : ComponentName }); }); fileSave(path.join(__dirname, '../../examples/nav.config.json')) .write(JSON.stringify(navConfigFile, null, ' '), 'utf8') .end('\n'); console.log('DONE!'); ================================================ FILE: build/bin/template.js ================================================ const path = require('path'); const templates = path.resolve(process.cwd(), './examples/pages/template'); const chokidar = require('chokidar'); let watcher = chokidar.watch([templates]); watcher.on('ready', function() { watcher .on('change', function() { exec('npm run i18n'); }); }); function exec(cmd) { return require('child_process').execSync(cmd).toString().trim(); } ================================================ FILE: build/bin/version.js ================================================ var fs = require('fs'); var path = require('path'); var version = process.env.VERSION || require('../../package.json').version; var content = { '1.4.13': '1.4', '2.0.11': '2.0', '2.1.0': '2.1', '2.2.2': '2.2', '2.3.9': '2.3', '2.4.11': '2.4', '2.5.4': '2.5', '2.6.3': '2.6', '2.7.2': '2.7', '2.8.2': '2.8', '2.9.2': '2.9', '2.10.1': '2.10', '2.11.1': '2.11', '2.12.0': '2.12', '2.13.2': '2.13', '2.14.1': '2.14' }; if (!content[version]) content[version] = '2.15'; fs.writeFileSync(path.resolve(__dirname, '../../examples/versions.json'), JSON.stringify(content)); ================================================ FILE: build/config.js ================================================ var path = require('path'); var fs = require('fs'); var nodeExternals = require('webpack-node-externals'); var Components = require('../components.json'); var utilsList = fs.readdirSync(path.resolve(__dirname, '../src/utils')); var mixinsList = fs.readdirSync(path.resolve(__dirname, '../src/mixins')); var transitionList = fs.readdirSync(path.resolve(__dirname, '../src/transitions')); var externals = {}; Object.keys(Components).forEach(function(key) { externals[`element-ui/packages/${key}`] = `element-ui/lib/${key}`; }); externals['element-ui/src/locale'] = 'element-ui/lib/locale'; utilsList.forEach(function(file) { file = path.basename(file, '.js'); externals[`element-ui/src/utils/${file}`] = `element-ui/lib/utils/${file}`; }); mixinsList.forEach(function(file) { file = path.basename(file, '.js'); externals[`element-ui/src/mixins/${file}`] = `element-ui/lib/mixins/${file}`; }); transitionList.forEach(function(file) { file = path.basename(file, '.js'); externals[`element-ui/src/transitions/${file}`] = `element-ui/lib/transitions/${file}`; }); externals = [Object.assign({ vue: 'vue' }, externals), nodeExternals()]; exports.externals = externals; exports.alias = { main: path.resolve(__dirname, '../src'), packages: path.resolve(__dirname, '../packages'), examples: path.resolve(__dirname, '../examples'), 'element-ui': path.resolve(__dirname, '../') }; exports.vue = { root: 'Vue', commonjs: 'vue', commonjs2: 'vue', amd: 'vue' }; exports.jsexclude = /node_modules|utils\/popper\.js|utils\/date\.js|utils\/lodash\.js/; ================================================ FILE: build/deploy-ci.sh ================================================ #! /bin/sh mkdir temp_web git config --global user.name "element-bot" git config --global user.email "wallement@gmail.com" if [ "$ROT_TOKEN" = "" ]; then echo "Bye~" exit 0 fi # release if [ "$TRAVIS_TAG" ]; then # build lib npm run dist cd temp_web git clone https://$ROT_TOKEN@github.com/ElementUI/lib.git && cd lib rm -rf `find * ! -name README.md` cp -rf ../../lib/** . git add -A . git commit -m "[build] $TRAVIS_TAG" git tag $TRAVIS_TAG git push origin master --tags cd ../.. # build theme-chalk cd temp_web git clone https://$ROT_TOKEN@github.com/ElementUI/theme-chalk.git && cd theme-chalk rm -rf * cp -rf ../../packages/theme-chalk/** . git add -A . git commit -m "[build] $TRAVIS_TAG" git tag $TRAVIS_TAG git push origin master --tags cd ../.. # build site npm run deploy:build cd temp_web git clone --depth 1 -b gh-pages --single-branch https://$ROT_TOKEN@github.com/ElemeFE/element.git && cd element # build sub folder echo $TRAVIS_TAG SUB_FOLDER='2.15' mkdir $SUB_FOLDER rm -rf *.js *.css *.map static rm -rf $SUB_FOLDER/** cp -rf ../../examples/element-ui/** . cp -rf ../../examples/element-ui/** $SUB_FOLDER/ git add -A . git commit -m "$TRAVIS_COMMIT_MSG" git push origin gh-pages cd ../.. echo "DONE, Bye~" exit 0 fi # build dev site npm run build:file && CI_ENV=/dev/$TRAVIS_BRANCH/ node_modules/.bin/cross-env NODE_ENV=production node_modules/.bin/webpack --config build/webpack.demo.js cd temp_web git clone https://$ROT_TOKEN@github.com/ElementUI/dev.git && cd dev mkdir $TRAVIS_BRANCH rm -rf $TRAVIS_BRANCH/** cp -rf ../../examples/element-ui/** $TRAVIS_BRANCH/ git add -A . git commit -m "$TRAVIS_COMMIT_MSG" git push origin master cd ../.. # push dev theme-chalk cd temp_web git clone -b $TRAVIS_BRANCH https://$ROT_TOKEN@github.com/ElementUI/theme-chalk.git && cd theme-chalk rm -rf * cp -rf ../../packages/theme-chalk/** . git add -A . git commit -m "$TRAVIS_COMMIT_MSG" git push origin $TRAVIS_BRANCH cd ../.. ================================================ FILE: build/deploy-faas.sh ================================================ #! /bin/sh set -ex mkdir temp_web npm run deploy:build cd temp_web git clone --depth 1 -b gh-pages --single-branch https://github.com/ElemeFE/element.git && cd element # build sub folder SUB_FOLDER='2.15' mkdir -p $SUB_FOLDER rm -rf *.js *.css *.map static rm -rf $SUB_FOLDER/** cp -rf ../../examples/element-ui/** . cp -rf ../../examples/element-ui/** $SUB_FOLDER/ cd ../.. # deploy domestic site faas deploy daily -P element rm -rf temp_web ================================================ FILE: build/gen-single-config.js ================================================ var path = require('path'); var config = require('./config'); module.exports = function(context, moduleName, entry) { return { entry: { index: path.resolve(context, entry || 'index.js') }, dist: path.resolve(context, 'lib'), template: false, format: 'umd', moduleName: moduleName, extends: ['vue2'], alias: config.alias, externals: { vue: config.vue } }; }; ================================================ FILE: build/git-release.sh ================================================ #!/usr/bin/env sh git checkout dev if test -n "$(git status --porcelain)"; then echo 'Unclean working tree. Commit or stash changes first.' >&2; exit 128; fi if ! git fetch --quiet 2>/dev/null; then echo 'There was a problem fetching your branch. Run `git fetch` to see more...' >&2; exit 128; fi if test "0" != "$(git rev-list --count --left-only @'{u}'...HEAD)"; then echo 'Remote history differ. Please pull changes.' >&2; exit 128; fi echo 'No conflicts.' >&2; ================================================ FILE: build/md-loader/config.js ================================================ const Config = require('markdown-it-chain'); const anchorPlugin = require('markdown-it-anchor'); const slugify = require('transliteration').slugify; const containers = require('./containers'); const overWriteFenceRule = require('./fence'); const config = new Config(); config .options.html(true).end() .plugin('anchor').use(anchorPlugin, [ { level: 2, slugify: slugify, permalink: true, permalinkBefore: true } ]).end() .plugin('containers').use(containers).end(); const md = config.toMd(); overWriteFenceRule(md); module.exports = md; ================================================ FILE: build/md-loader/containers.js ================================================ const mdContainer = require('markdown-it-container'); module.exports = md => { md.use(mdContainer, 'demo', { validate(params) { return params.trim().match(/^demo\s*(.*)$/); }, render(tokens, idx) { const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/); if (tokens[idx].nesting === 1) { const description = m && m.length > 1 ? m[1] : ''; const content = tokens[idx + 1].type === 'fence' ? tokens[idx + 1].content : ''; return ` ${description ? `
${md.render(description)}
` : ''} `; } return '
'; } }); md.use(mdContainer, 'tip'); md.use(mdContainer, 'warning'); }; ================================================ FILE: build/md-loader/fence.js ================================================ // 覆盖默认的 fence 渲染策略 module.exports = md => { const defaultRender = md.renderer.rules.fence; md.renderer.rules.fence = (tokens, idx, options, env, self) => { const token = tokens[idx]; // 判断该 fence 是否在 :::demo 内 const prevToken = tokens[idx - 1]; const isInDemoContainer = prevToken && prevToken.nesting === 1 && prevToken.info.trim().match(/^demo\s*(.*)$/); if (token.info === 'html' && isInDemoContainer) { return ``; } return defaultRender(tokens, idx, options, env, self); }; }; ================================================ FILE: build/md-loader/index.js ================================================ const { stripScript, stripTemplate, genInlineComponentText } = require('./util'); const md = require('./config'); module.exports = function(source) { const content = md.render(source); const startTag = ''; const endTagLen = endTag.length; let componenetsString = ''; let id = 0; // demo 的 id let output = []; // 输出的内容 let start = 0; // 字符串开始位置 let commentStart = content.indexOf(startTag); let commentEnd = content.indexOf(endTag, commentStart + startTagLen); while (commentStart !== -1 && commentEnd !== -1) { output.push(content.slice(start, commentStart)); const commentContent = content.slice(commentStart + startTagLen, commentEnd); const html = stripTemplate(commentContent); const script = stripScript(commentContent); let demoComponentContent = genInlineComponentText(html, script); const demoComponentName = `element-demo${id}`; output.push(``); componenetsString += `${JSON.stringify(demoComponentName)}: ${demoComponentContent},`; // 重新计算下一次的位置 id++; start = commentEnd + endTagLen; commentStart = content.indexOf(startTag, start); commentEnd = content.indexOf(endTag, commentStart + startTagLen); } // 仅允许在 demo 不存在时,才可以在 Markdown 中写 script 标签 // todo: 优化这段逻辑 let pageScript = ''; if (componenetsString) { pageScript = ``; } else if (content.indexOf('') + ''.length; pageScript = content.slice(0, start); } output.push(content.slice(start)); return ` ${pageScript} `; }; ================================================ FILE: build/md-loader/util.js ================================================ const { compileTemplate } = require('@vue/component-compiler-utils'); const compiler = require('vue-template-compiler'); function stripScript(content) { const result = content.match(/<(script)>([\s\S]+)<\/\1>/); return result && result[2] ? result[2].trim() : ''; } function stripStyle(content) { const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/); return result && result[2] ? result[2].trim() : ''; } // 编写例子时不一定有 template。所以采取的方案是剔除其他的内容 function stripTemplate(content) { content = content.trim(); if (!content) { return content; } return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim(); } function pad(source) { return source .split(/\r?\n/) .map(line => ` ${line}`) .join('\n'); } function genInlineComponentText(template, script) { // https://github.com/vuejs/vue-loader/blob/423b8341ab368c2117931e909e2da9af74503635/lib/loaders/templateLoader.js#L46 const finalOptions = { source: `
${template}
`, filename: 'inline-component', // TODO:这里有待调整 compiler }; const compiled = compileTemplate(finalOptions); // tips if (compiled.tips && compiled.tips.length) { compiled.tips.forEach(tip => { console.warn(tip); }); } // errors if (compiled.errors && compiled.errors.length) { console.error( `\n Error compiling template:\n${pad(compiled.source)}\n` + compiled.errors.map(e => ` - ${e}`).join('\n') + '\n' ); } let demoComponentContent = ` ${compiled.code} `; // todo: 这里采用了硬编码有待改进 script = script.trim(); if (script) { script = script.replace(/export\s+default/, 'const democomponentExport ='); } else { script = 'const democomponentExport = {}'; } demoComponentContent = `(function() { ${demoComponentContent} ${script} return { render, staticRenderFns, ...democomponentExport } })()`; return demoComponentContent; } module.exports = { stripScript, stripStyle, stripTemplate, genInlineComponentText }; ================================================ FILE: build/release.sh ================================================ #!/usr/bin/env sh set -e git checkout master git merge dev VERSION=`npx select-version-cli` read -p "Releasing $VERSION - are you sure? (y/n)" -n 1 -r echo # (optional) move to a new line if [[ $REPLY =~ ^[Yy]$ ]] then echo "Releasing $VERSION ..." # build VERSION=$VERSION npm run dist # ssr test node test/ssr/require.test.js # publish theme echo "Releasing theme-chalk $VERSION ..." cd packages/theme-chalk npm version $VERSION --message "[release] $VERSION" if [[ $VERSION =~ "beta" ]] then npm publish --tag beta else npm publish fi cd ../.. # commit git add -A git commit -m "[build] $VERSION" npm version $VERSION --message "[release] $VERSION" # publish git push eleme master git push eleme refs/tags/v$VERSION git checkout dev git rebase master git push eleme dev if [[ $VERSION =~ "beta" ]] then npm publish --tag beta else npm publish fi fi ================================================ FILE: build/webpack.common.js ================================================ const path = require('path'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const config = require('./config'); module.exports = { mode: 'production', entry: { app: ['./src/index.js'] }, output: { path: path.resolve(process.cwd(), './lib'), publicPath: '/dist/', filename: 'element-ui.common.js', chunkFilename: '[id].js', libraryExport: 'default', library: 'ELEMENT', libraryTarget: 'commonjs2' }, resolve: { extensions: ['.js', '.vue', '.json'], alias: config.alias, modules: ['node_modules'] }, externals: config.externals, performance: { hints: false }, stats: { children: false }, optimization: { minimize: false }, module: { rules: [ { test: /\.(jsx?|babel|es6)$/, include: process.cwd(), exclude: config.jsexclude, loader: 'babel-loader' }, { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } }, { test: /\.css$/, loaders: ['style-loader', 'css-loader'] }, { test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, loader: 'url-loader', query: { limit: 10000, name: path.posix.join('static', '[name].[hash:7].[ext]') } } ] }, plugins: [ new ProgressBarPlugin(), new VueLoaderPlugin() ] }; ================================================ FILE: build/webpack.component.js ================================================ const path = require('path'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const Components = require('../components.json'); const config = require('./config'); const webpackConfig = { mode: 'production', entry: Components, output: { path: path.resolve(process.cwd(), './lib'), publicPath: '/dist/', filename: '[name].js', chunkFilename: '[id].js', libraryTarget: 'commonjs2' }, resolve: { extensions: ['.js', '.vue', '.json'], alias: config.alias, modules: ['node_modules'] }, externals: config.externals, performance: { hints: false }, stats: 'none', optimization: { minimize: false }, module: { rules: [ { test: /\.(jsx?|babel|es6)$/, include: process.cwd(), exclude: config.jsexclude, loader: 'babel-loader' }, { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } }, { test: /\.css$/, loaders: ['style-loader', 'css-loader'] }, { test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, loader: 'url-loader', query: { limit: 10000, name: path.posix.join('static', '[name].[hash:7].[ext]') } } ] }, plugins: [ new ProgressBarPlugin(), new VueLoaderPlugin() ] }; module.exports = webpackConfig; ================================================ FILE: build/webpack.conf.js ================================================ const path = require('path'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const TerserPlugin = require('terser-webpack-plugin'); const config = require('./config'); module.exports = { mode: 'production', entry: { app: ['./src/index.js'] }, output: { path: path.resolve(process.cwd(), './lib'), publicPath: '/dist/', filename: 'index.js', chunkFilename: '[id].js', libraryTarget: 'umd', libraryExport: 'default', library: 'ELEMENT', umdNamedDefine: true, globalObject: 'typeof self !== \'undefined\' ? self : this' }, resolve: { extensions: ['.js', '.vue', '.json'], alias: config.alias }, externals: { vue: config.vue }, optimization: { minimizer: [ new TerserPlugin({ terserOptions: { output: { comments: false } } }) ] }, performance: { hints: false }, stats: { children: false }, module: { rules: [ { test: /\.(jsx?|babel|es6)$/, include: process.cwd(), exclude: config.jsexclude, loader: 'babel-loader' }, { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } } ] }, plugins: [ new ProgressBarPlugin(), new VueLoaderPlugin() ] }; ================================================ FILE: build/webpack.demo.js ================================================ const path = require('path'); const webpack = require('webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const launchEditorMiddleware = require('launch-editor-middleware'); const config = require('./config'); const isProd = process.env.NODE_ENV === 'production'; const isPlay = !!process.env.PLAY_ENV; const webpackConfig = { mode: process.env.NODE_ENV, entry: isProd ? { docs: './examples/entry.js' } : (isPlay ? './examples/play.js' : './examples/entry.js'), output: { path: path.resolve(process.cwd(), './examples/element-ui/'), publicPath: process.env.CI_ENV || '', filename: '[name].[hash:7].js', chunkFilename: isProd ? '[name].[hash:7].js' : '[name].js' }, resolve: { extensions: ['.js', '.vue', '.json'], alias: config.alias, modules: ['node_modules'] }, devServer: { host: '0.0.0.0', port: 8085, publicPath: '/', hot: true, before: (app) => { /* * 编辑器类型 :此处的指令表示的时各个各个编辑器在cmd或terminal中的命令 * webstorm * code // vscode * idea */ app.use('/__open-in-editor', launchEditorMiddleware('code')); } }, performance: { hints: false }, stats: { children: false }, module: { rules: [ { enforce: 'pre', test: /\.(vue|jsx?)$/, exclude: /node_modules/, loader: 'eslint-loader' }, { test: /\.(jsx?|babel|es6)$/, include: process.cwd(), exclude: config.jsexclude, loader: 'babel-loader' }, { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } }, { test: /\.(scss|css)$/, use: [ isProd ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader', 'sass-loader' ] }, { test: /\.md$/, use: [ { loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } }, { loader: path.resolve(__dirname, './md-loader/index.js') } ] }, { test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, loader: 'url-loader', // todo: 这种写法有待调整 query: { limit: 10000, name: path.posix.join('static', '[name].[hash:7].[ext]') } } ] }, plugins: [ new webpack.HotModuleReplacementPlugin(), new HtmlWebpackPlugin({ template: './examples/index.tpl', filename: './index.html', favicon: './examples/favicon.ico' }), new CopyWebpackPlugin([ { from: 'examples/versions.json' } ]), new ProgressBarPlugin(), new VueLoaderPlugin(), new webpack.DefinePlugin({ 'process.env.FAAS_ENV': JSON.stringify(process.env.FAAS_ENV) }), new webpack.LoaderOptionsPlugin({ vue: { compilerOptions: { preserveWhitespace: false } } }) ], optimization: { minimizer: [] }, devtool: '#eval-source-map' }; if (isProd) { webpackConfig.externals = { vue: 'Vue', 'vue-router': 'VueRouter', 'highlight.js': 'hljs' }; webpackConfig.plugins.push( new MiniCssExtractPlugin({ filename: '[name].[contenthash:7].css' }) ); webpackConfig.optimization.minimizer.push( new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }), new OptimizeCSSAssetsPlugin({}) ); // https://webpack.js.org/configuration/optimization/#optimizationsplitchunks webpackConfig.optimization.splitChunks = { cacheGroups: { vendor: { test: /\/src\//, name: 'element-ui', chunks: 'all' } } }; webpackConfig.devtool = false; } module.exports = webpackConfig; ================================================ FILE: build/webpack.extension.js ================================================ const path = require('path'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const demoConfig = require('./webpack.demo'); const webpack = require('webpack'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); demoConfig.entry = { background: path.join(process.cwd(), './examples/extension/src/background'), entry: path.join(process.cwd(), './examples/extension/src/entry') }; demoConfig.output = { path: path.join(process.cwd(), './examples/extension/dist'), filename: '[name].js' }; demoConfig.plugins = [ new CopyWebpackPlugin([ { from: 'examples/extension/src/manifest.json' }, { from: 'examples/extension/src/icon.png' } ]), new VueLoaderPlugin(), new ProgressBarPlugin(), new webpack.LoaderOptionsPlugin({ vue: { compilerOptions: { preserveWhitespace: false } } }), new webpack.HotModuleReplacementPlugin() ]; demoConfig.module.rules.find(a => a.loader === 'url-loader').query = {}; module.exports = demoConfig; ================================================ FILE: build/webpack.test.js ================================================ const path = require('path'); const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const config = require('./config'); const webpackConfig = { mode: 'development', entry: { app: ['./src/index.js'] }, output: { path: path.resolve(process.cwd(), './dist'), publicPath: '/dist/', filename: '[name].js', chunkFilename: '[id].js' }, resolve: { extensions: ['.js', '.vue', '.json'], alias: Object.assign(config.alias, { 'vue$': 'vue/dist/vue.common.js' }), modules: ['node_modules'] }, module: { rules: [ { test: /\.(jsx?|babel|es6)$/, include: process.cwd(), exclude: config.jsexclude, loader: 'babel-loader' }, { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } }, { test: /\.css$/, loaders: ['style-loader', 'css-loader'] }, { test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/, loader: 'url-loader', query: { limit: 10000, name: path.posix.join('static', '[name].[hash:7].[ext]') } } ] }, plugins: [ new VueLoaderPlugin() ] }; if (!process.env.CI_ENV) { webpackConfig.plugins.push( new ProgressBarPlugin() ); } module.exports = webpackConfig; ================================================ FILE: components.json ================================================ { "pagination": "./packages/pagination/index.js", "dialog": "./packages/dialog/index.js", "autocomplete": "./packages/autocomplete/index.js", "dropdown": "./packages/dropdown/index.js", "dropdown-menu": "./packages/dropdown-menu/index.js", "dropdown-item": "./packages/dropdown-item/index.js", "menu": "./packages/menu/index.js", "submenu": "./packages/submenu/index.js", "menu-item": "./packages/menu-item/index.js", "menu-item-group": "./packages/menu-item-group/index.js", "input": "./packages/input/index.js", "input-number": "./packages/input-number/index.js", "radio": "./packages/radio/index.js", "radio-group": "./packages/radio-group/index.js", "radio-button": "./packages/radio-button/index.js", "checkbox": "./packages/checkbox/index.js", "checkbox-button": "./packages/checkbox-button/index.js", "checkbox-group": "./packages/checkbox-group/index.js", "switch": "./packages/switch/index.js", "select": "./packages/select/index.js", "option": "./packages/option/index.js", "option-group": "./packages/option-group/index.js", "button": "./packages/button/index.js", "button-group": "./packages/button-group/index.js", "table": "./packages/table/index.js", "table-column": "./packages/table-column/index.js", "date-picker": "./packages/date-picker/index.js", "time-select": "./packages/time-select/index.js", "time-picker": "./packages/time-picker/index.js", "popover": "./packages/popover/index.js", "tooltip": "./packages/tooltip/index.js", "message-box": "./packages/message-box/index.js", "breadcrumb": "./packages/breadcrumb/index.js", "breadcrumb-item": "./packages/breadcrumb-item/index.js", "form": "./packages/form/index.js", "form-item": "./packages/form-item/index.js", "tabs": "./packages/tabs/index.js", "tab-pane": "./packages/tab-pane/index.js", "tag": "./packages/tag/index.js", "tree": "./packages/tree/index.js", "alert": "./packages/alert/index.js", "notification": "./packages/notification/index.js", "slider": "./packages/slider/index.js", "loading": "./packages/loading/index.js", "icon": "./packages/icon/index.js", "row": "./packages/row/index.js", "col": "./packages/col/index.js", "upload": "./packages/upload/index.js", "progress": "./packages/progress/index.js", "spinner": "./packages/spinner/index.js", "message": "./packages/message/index.js", "badge": "./packages/badge/index.js", "card": "./packages/card/index.js", "rate": "./packages/rate/index.js", "steps": "./packages/steps/index.js", "step": "./packages/step/index.js", "carousel": "./packages/carousel/index.js", "scrollbar": "./packages/scrollbar/index.js", "carousel-item": "./packages/carousel-item/index.js", "collapse": "./packages/collapse/index.js", "collapse-item": "./packages/collapse-item/index.js", "cascader": "./packages/cascader/index.js", "color-picker": "./packages/color-picker/index.js", "transfer": "./packages/transfer/index.js", "container": "./packages/container/index.js", "header": "./packages/header/index.js", "aside": "./packages/aside/index.js", "main": "./packages/main/index.js", "footer": "./packages/footer/index.js", "timeline": "./packages/timeline/index.js", "timeline-item": "./packages/timeline-item/index.js", "link": "./packages/link/index.js", "divider": "./packages/divider/index.js", "image": "./packages/image/index.js", "calendar": "./packages/calendar/index.js", "backtop": "./packages/backtop/index.js", "infinite-scroll": "./packages/infinite-scroll/index.js", "page-header": "./packages/page-header/index.js", "cascader-panel": "./packages/cascader-panel/index.js", "avatar": "./packages/avatar/index.js", "drawer": "./packages/drawer/index.js", "statistic": "./packages/statistic/index.js", "popconfirm": "./packages/popconfirm/index.js", "skeleton": "./packages/skeleton/index.js", "skeleton-item": "./packages/skeleton-item/index.js", "empty": "./packages/empty/index.js", "descriptions": "./packages/descriptions/index.js", "descriptions-item": "./packages/descriptions-item/index.js", "result": "./packages/result/index.js" } ================================================ FILE: examples/app.vue ================================================ ================================================ FILE: examples/assets/styles/common.css ================================================ html, body { margin: 0; padding: 0; height: 100%; font-family: 'Helvetica Neue',Helvetica,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',SimSun,sans-serif; font-weight: 400; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; &.is-component { overflow: hidden; } } #app { height: 100%; &.is-component { overflow-y: hidden; .main-cnt { padding: 0; margin-top: 0; height: 100%; min-height: auto; } .headerWrapper { position: fixed; width: 100%; left: 0; top: 0; z-index: 1500; .container { padding: 0; } } } } a { color: #409EFF; text-decoration: none; } code { background-color: #f9fafc; padding: 0 4px; border: 1px solid #eaeefb; border-radius: 4px; } button, input, select, textarea { font-family: inherit; font-size: inherit; line-height: inherit; color: inherit; } .hljs { line-height: 1.8; font-family: Menlo, Monaco, Consolas, Courier, monospace; font-size: 12px; padding: 18px 24px; background-color: #fafafa; border: solid 1px #eaeefb; margin-bottom: 25px; border-radius: 4px; -webkit-font-smoothing: auto; } .main-cnt { margin-top: -80px; padding: 80px 0 340px; box-sizing: border-box; min-height: 100%; } .container, .page-container { width: 1140px; padding: 0; margin: 0 auto; } .page-container { padding-top: 55px; h2 { font-size: 28px; color: #1f2d3d; margin: 0; } h3 { font-size: 22px; } h2, h3, h4, h5 { font-weight: normal; color: #1f2f3d; &:hover a { opacity: .4; } a { float: left; margin-left: -20px; opacity: 0; cursor: pointer; &:hover { opacity: .4; } } } p { font-size: 14px; color: #5e6d82; line-height: 1.5em; } .tip { padding: 8px 16px; background-color: #ECF8FF; border-radius: 4px; border-left: #50bfff 5px solid; margin: 20px 0; code { background-color: rgba(255, 255, 255, .7); color: #445368; } } .warning { padding: 8px 16px; background-color: #fff6f7; border-radius: 4px; border-left: #FE6C6F 5px solid; margin: 20px 0; code { background-color: rgba(255, 255, 255, .7); color: #445368; } } } .demo { margin: 20px 0; } @media (max-width: 1140px) { .container, .page-container { width: 100%; } } @media (max-width: 768px) { .container, .page-container { padding: 0 20px; } #app.is-component .headerWrapper .container { padding: 0 12px; } } ================================================ FILE: examples/assets/styles/fonts/style.css ================================================ @font-face { font-family: 'icomoon'; src: url('icomoon.eot?h6xgdm'); src: url('icomoon.eot?h6xgdm#iefix') format('embedded-opentype'), url('icomoon.ttf?h6xgdm') format('truetype'), url('icomoon.woff?h6xgdm') format('woff'), url('icomoon.svg?h6xgdm#icomoon') format('svg'); font-weight: normal; font-style: normal; } [class^="icon-"], [class*=" icon-"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'icomoon' !important; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .icon-rate-face-off:before { content: "\e900"; } .icon-rate-face-1:before { content: "\e901"; } .icon-rate-face-2:before { content: "\e902"; } .icon-rate-face-3:before { content: "\e903"; } ================================================ FILE: examples/bus.js ================================================ import Vue from 'vue'; export default new Vue(); ================================================ FILE: examples/color.js ================================================ export const tintColor = (c, tint) => { const color = c.replace('#', ''); let red = parseInt(color.slice(0, 2), 16); let green = parseInt(color.slice(2, 4), 16); let blue = parseInt(color.slice(4, 6), 16); if (tint === 0) { // when primary color is in its rgb space return [red, green, blue].join(','); } else { red += Math.round(tint * (255 - red)); green += Math.round(tint * (255 - green)); blue += Math.round(tint * (255 - blue)); red = red.toString(16); green = green.toString(16); blue = blue.toString(16); return `#${ red }${ green }${ blue }`; } }; ================================================ FILE: examples/components/demo-block.vue ================================================ ================================================ FILE: examples/components/footer-nav.vue ================================================ ================================================ FILE: examples/components/footer.vue ================================================ ================================================ FILE: examples/components/header.vue ================================================ ================================================ FILE: examples/components/search.vue ================================================ ================================================ FILE: examples/components/side-nav.vue ================================================ ================================================ FILE: examples/components/theme/basic-tokens-preview.vue ================================================ ================================================ FILE: examples/components/theme/components-preview.vue ================================================ ================================================ FILE: examples/components/theme/constant.js ================================================ export const DEFAULT_THEME_CONFIG = { global: {}, local: {} }; export const ELEMENT_THEME_USER_CONFIG = 'ELEMENT_THEME_USER_CONFIG'; export const ELEMENT_THEME_PREVIEW_CONFIG = 'ELEMENT_THEME_PREVIEW_CONFIG'; export const ACTION_DOWNLOAD_THEME = 'ELEMENT_THEME_ACTION_DOWNLOAD'; export const ACTION_APPLY_THEME = 'ELEMENT_THEME_ACTION_ALLPY_CSS'; export const ACTION_COMPONECT_SELECT = 'ELEMENT_THEME_ACTION_COMPONECT_SELECT'; export const ACTION_USER_CONFIG_UPDATE = 'ELEMENT_THEME_USER_CONFIG_UPDATE'; ================================================ FILE: examples/components/theme/loader/ajax.js ================================================ const defaultError = 'Server Error 500'; const defaultTimeout = 'Request Timeout'; const xhr = (method, url, data = null, cb) => { return new window.Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); const doReject = (xhr) => { reject(xhr.response || xhr.statusText || defaultError); }; xhr.open(method, url); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.timeout = 10000; if (cb) cb(xhr); xhr.onload = () => { if (xhr.readyState === 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { let response = xhr.response; const type = xhr.getResponseHeader('Content-Type'); if (type.indexOf('zip') > -1) { let filename = 'style.zip'; const disposition = xhr.getResponseHeader('content-disposition'); if (disposition && disposition.indexOf('attachment') !== -1) { var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; var matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) { filename = matches[1].replace(/['"]/g, ''); } } var blob = new Blob([response], { type }); var zipUrl = URL.createObjectURL(blob); var link = document.createElement('a'); link.href = zipUrl; link.download = filename; link.click(); resolve(response); return; } try { response = JSON.parse(xhr.response); } catch (e) {} resolve(response); } else { doReject(xhr); } } else { doReject(xhr); } }; xhr.onerror = () => { doReject(xhr); }; xhr.ontimeout = () => { xhr.abort(); reject(defaultTimeout); }; xhr.send(JSON.stringify(data)); }); }; export const post = (url, data, cb) => { return xhr('POST', url, data, cb); }; export const get = (url) => { return xhr('GET', url); }; ================================================ FILE: examples/components/theme/loader/api.js ================================================ import Element from 'main/index.js'; import { post, get } from './ajax'; const { version } = Element; const hostList = { local: 'http://localhost:3008/', production: 'https://element-api.ele.me/element/theme/' }; const host = hostList[process.env.FAAS_ENV] || hostList.production; export const getVars = () => { return get(`${host}getVariable?version=${version}`); }; export const updateVars = (data, cb) => { return post(`${host}updateVariable?version=${version}`, data, cb); }; ================================================ FILE: examples/components/theme/loader/docStyle.vue ================================================ ================================================ FILE: examples/components/theme/loader/index.vue ================================================ ================================================ FILE: examples/components/theme/loader/loading/index.vue ================================================ ================================================ FILE: examples/components/theme/loader/loading/progress.js ================================================ import Vue from 'vue'; import ProgressBar from './progress.vue'; Vue.prototype.$bar = new Vue(ProgressBar).$mount(); document.body.appendChild(Vue.prototype.$bar.$el); ================================================ FILE: examples/components/theme/loader/loading/progress.vue ================================================ ================================================ FILE: examples/components/theme/localstorage.js ================================================ import { ELEMENT_THEME_PREVIEW_CONFIG, ELEMENT_THEME_USER_CONFIG } from './constant'; export const saveToLocal = (key, value) => { localStorage.setItem(key, JSON.stringify(value)); }; export const loadFromLocal = (key) => { try { return JSON.parse(localStorage.getItem(key)); } catch (e) { console.error(e); return null; } }; export const savePreviewToLocal = (value) => { saveToLocal(ELEMENT_THEME_PREVIEW_CONFIG, value); }; export const loadPreviewFromLocal = () => { return loadFromLocal(ELEMENT_THEME_PREVIEW_CONFIG) || {}; }; export const removePreviewFromLocal = () => { return localStorage.removeItem(ELEMENT_THEME_PREVIEW_CONFIG); }; export const saveUserThemeToLocal = (value) => { saveToLocal(ELEMENT_THEME_USER_CONFIG, value); }; export const loadUserThemeFromLocal = () => { return loadFromLocal(ELEMENT_THEME_USER_CONFIG); }; ================================================ FILE: examples/components/theme/theme-card.vue ================================================ ================================================ FILE: examples/components/theme/theme-list.js ================================================ export const themeList = [ { name: 'Element', author: 'Element', theme: '{"global":{"$--color-primary":"#409EFF"},"local":{}}' } ]; export const eleThemeList = [ { name: 'Kiwi', author: 'Element', theme: '{"global":{"$--color-primary":"#1989FA","$--color-success":"#5CB87A","$--color-warning":"#E6A23C","$--color-danger":"#F56C6C","$--color-info":"#8896B3","$--font-size-small":"13px","$--font-size-base":"14px","$--font-size-medium":"16px","$--font-size-large":"22px","$--font-size-extra-large":"28px","$--font-line-height-secondary":"20px"},"local":{"$--button-primary-background-color":"$--color-primary","$--switch-font-size":"14px","$--datepicker-active-color":"$--color-primary","$--tooltip-border-color":"$--border-color-base","$--tooltip-color":"#FFFFFF","$--tooltip-padding":"10px","$--collapse-header-font-size":"14px","$--collapse-content-font-size":"14px","$--collapse-content-font-color":"$--color-text-regular","$--radio-input-background-color":"#FFFFFF","$--radio-icon-color":"$--color-warning","$--radio-button-checked-background-color":"$--color-primary","$--input-border-radius":"$--border-radius-base","$--select-input-focus-border-color":"$--color-primary","$--select-font-size":"14px","$--select-option-selected-font-color":"$--color-primary","$--select-input-font-size":"14px","$--select-option-height":"34px","$--slider-main-background-color":"$--color-primary","$--tag-font-color":"$--color-primary","$--tag-default-hover-background-color":"$--color-primary","$--message-warning-font-color":"$--color-warning","$--alert-title-font-size":"14px","$--alert-icon-size":"14px","$--alert-icon-large-size":"22px","$--alert-close-customed-font-size":"12px","$--notification-title-font-size":"16px","$--notification-content-font-size":"14px","$--menu-item-font-color":"$--color-primary"}}' } ]; ================================================ FILE: examples/components/theme/utils.js ================================================ export const isEmptyObject = (obj) => (JSON.stringify(obj) === '{}'); export const getThemeConfigObject = (config) => { try { const conf = JSON.parse(config); const { global, local } = conf; if (!isEmptyObject(global) || !isEmptyObject(local)) { return conf; } return false; } catch (e) { return false; } }; export const updateDomHeadStyle = (id, styleContent) => { let styleTag = document.getElementById(id); if (!styleTag) { styleTag = document.createElement('style'); styleTag.setAttribute('id', id); document.head.appendChild(styleTag); } styleTag.innerText = styleContent.replace(/@font-face{[^}]+}/, ''); }; ================================================ FILE: examples/components/theme-configurator/action.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/borderRadius.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/boxShadow.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color-picker/index.js ================================================ import ColorPicker from './src/main'; /* istanbul ignore next */ ColorPicker.install = function(Vue) { Vue.component(ColorPicker.name, ColorPicker); }; export default ColorPicker; ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/color.js ================================================ const hsv2hsl = function(hue, sat, val) { return [ hue, (sat * val / ((hue = (2 - sat) * val) < 1 ? hue : 2 - hue)) || 0, hue / 2 ]; }; // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 // const isOnePointZero = function(n) { return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1; }; const isPercentage = function(n) { return typeof n === 'string' && n.indexOf('%') !== -1; }; // Take input from [0, n] and return it as [0, 1] const bound01 = function(value, max) { if (isOnePointZero(value)) value = '100%'; const processPercent = isPercentage(value); value = Math.min(max, Math.max(0, parseFloat(value))); // Automatically convert percentage into number if (processPercent) { value = parseInt(value * max, 10) / 100; } // Handle floating point rounding errors if ((Math.abs(value - max) < 0.000001)) { return 1; } // Convert into [0, 1] range if it isn't already return (value % max) / parseFloat(max); }; const INT_HEX_MAP = { 10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F' }; const toHex = function({ r, g, b }) { const hexOne = function(value) { value = Math.min(Math.round(value), 255); const high = Math.floor(value / 16); const low = value % 16; return '' + (INT_HEX_MAP[high] || high) + (INT_HEX_MAP[low] || low); }; if (isNaN(r) || isNaN(g) || isNaN(b)) return ''; return '#' + hexOne(r) + hexOne(g) + hexOne(b); }; const HEX_INT_MAP = { A: 10, B: 11, C: 12, D: 13, E: 14, F: 15 }; const parseHexChannel = function(hex) { if (hex.length === 2) { return (HEX_INT_MAP[hex[0].toUpperCase()] || +hex[0]) * 16 + (HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1]); } return HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1]; }; const hsl2hsv = function(hue, sat, light) { sat = sat / 100; light = light / 100; let smin = sat; const lmin = Math.max(light, 0.01); let sv; let v; light *= 2; sat *= (light <= 1) ? light : 2 - light; smin *= lmin <= 1 ? lmin : 2 - lmin; v = (light + sat) / 2; sv = light === 0 ? (2 * smin) / (lmin + smin) : (2 * sat) / (light + sat); return { h: hue, s: sv * 100, v: v * 100 }; }; // `rgbToHsv` // Converts an RGB color value to HSV // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] // *Returns:* { h, s, v } in [0,1] const rgb2hsv = function(r, g, b) { r = bound01(r, 255); g = bound01(g, 255); b = bound01(b, 255); const max = Math.max(r, g, b); const min = Math.min(r, g, b); let h, s; let v = max; const d = max - min; s = max === 0 ? 0 : d / max; if (max === min) { h = 0; // achromatic } else { switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return { h: h * 360, s: s * 100, v: v * 100 }; }; // `hsvToRgb` // Converts an HSV color value to RGB. // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] // *Returns:* { r, g, b } in the set [0, 255] const hsv2rgb = function(h, s, v) { h = bound01(h, 360) * 6; s = bound01(s, 100); v = bound01(v, 100); const i = Math.floor(h); const f = h - i; const p = v * (1 - s); const q = v * (1 - f * s); const t = v * (1 - (1 - f) * s); const mod = i % 6; const r = [v, q, p, p, t, v][mod]; const g = [t, v, v, q, p, p][mod]; const b = [p, p, t, v, v, q][mod]; return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) }; }; export default class Color { constructor(options) { this._hue = 0; this._saturation = 100; this._value = 100; this._alpha = 100; this.enableAlpha = false; this.format = 'hex'; this.value = ''; options = options || {}; for (let option in options) { if (options.hasOwnProperty(option)) { this[option] = options[option]; } } this.doOnChange(); } set(prop, value) { if (arguments.length === 1 && typeof prop === 'object') { for (let p in prop) { if (prop.hasOwnProperty(p)) { this.set(p, prop[p]); } } return; } this['_' + prop] = value; this.doOnChange(); } get(prop) { return this['_' + prop]; } toRgb() { return hsv2rgb(this._hue, this._saturation, this._value); } fromString(value) { if (!value) { this._hue = 0; this._saturation = 100; this._value = 100; this.doOnChange(); return; } const fromHSV = (h, s, v) => { this._hue = Math.max(0, Math.min(360, h)); this._saturation = Math.max(0, Math.min(100, s)); this._value = Math.max(0, Math.min(100, v)); this.doOnChange(); }; if (value.indexOf('hsl') !== -1) { const parts = value.replace(/hsla|hsl|\(|\)/gm, '') .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10)); if (parts.length === 4) { this._alpha = Math.floor(parseFloat(parts[3]) * 100); } else if (parts.length === 3) { this._alpha = 100; } if (parts.length >= 3) { const { h, s, v } = hsl2hsv(parts[0], parts[1], parts[2]); fromHSV(h, s, v); } } else if (value.indexOf('hsv') !== -1) { const parts = value.replace(/hsva|hsv|\(|\)/gm, '') .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10)); if (parts.length === 4) { this._alpha = Math.floor(parseFloat(parts[3]) * 100); } else if (parts.length === 3) { this._alpha = 100; } if (parts.length >= 3) { fromHSV(parts[0], parts[1], parts[2]); } } else if (value.indexOf('rgb') !== -1) { const parts = value.replace(/rgba|rgb|\(|\)/gm, '') .split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10)); if (parts.length === 4) { this._alpha = Math.floor(parseFloat(parts[3]) * 100); } else if (parts.length === 3) { this._alpha = 100; } if (parts.length >= 3) { const { h, s, v } = rgb2hsv(parts[0], parts[1], parts[2]); fromHSV(h, s, v); } } else if (value.indexOf('#') !== -1) { const hex = value.replace('#', '').trim(); let r, g, b; if (hex.length === 3) { r = parseHexChannel(hex[0] + hex[0]); g = parseHexChannel(hex[1] + hex[1]); b = parseHexChannel(hex[2] + hex[2]); } else if (hex.length === 6 || hex.length === 8) { r = parseHexChannel(hex.substring(0, 2)); g = parseHexChannel(hex.substring(2, 4)); b = parseHexChannel(hex.substring(4, 6)); } if (hex.length === 8) { this._alpha = Math.floor(parseHexChannel(hex.substring(6)) / 255 * 100); } else if (hex.length === 3 || hex.length === 6) { this._alpha = 100; } const { h, s, v } = rgb2hsv(r, g, b); fromHSV(h, s, v); } } compare(color) { return Math.abs(color._hue - this._hue) < 2 && Math.abs(color._saturation - this._saturation) < 1 && Math.abs(color._value - this._value) < 1 && Math.abs(color._alpha - this._alpha) < 1; } doOnChange() { const { _hue, _saturation, _value, _alpha, format } = this; if (this.enableAlpha) { switch (format) { case 'hsl': const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100); this.value = `hsla(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%, ${ _alpha / 100})`; break; case 'hsv': this.value = `hsva(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%, ${ _alpha / 100})`; break; default: const { r, g, b } = hsv2rgb(_hue, _saturation, _value); this.value = `rgba(${r}, ${g}, ${b}, ${ _alpha / 100 })`; } } else { switch (format) { case 'hsl': const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100); this.value = `hsl(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%)`; break; case 'hsv': this.value = `hsv(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%)`; break; case 'rgb': const { r, g, b } = hsv2rgb(_hue, _saturation, _value); this.value = `rgb(${r}, ${g}, ${b})`; break; default: this.value = toHex(hsv2rgb(_hue, _saturation, _value)); } } } }; ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/components/alpha-slider.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/components/color-list.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/components/hue-slider.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/components/picker-dropdown.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/components/predefine.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/components/sv-panel.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/draggable.js ================================================ import Vue from 'vue'; let isDragging = false; export default function(element, options) { if (Vue.prototype.$isServer) return; const moveFn = function(event) { if (options.drag) { options.drag(event); } }; const upFn = function(event) { document.removeEventListener('mousemove', moveFn); document.removeEventListener('mouseup', upFn); document.onselectstart = null; document.ondragstart = null; isDragging = false; if (options.end) { options.end(event); } }; element.addEventListener('mousedown', function(event) { if (isDragging) return; document.onselectstart = function() { return false; }; document.ondragstart = function() { return false; }; document.addEventListener('mousemove', moveFn); document.addEventListener('mouseup', upFn); isDragging = true; if (options.start) { options.start(event); } }); } ================================================ FILE: examples/components/theme-configurator/editor/color-picker/src/main.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/color.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/fontLineHeight.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/fontSize.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/fontWeight.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/input.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/mixin.vue ================================================ ================================================ FILE: examples/components/theme-configurator/editor/simpleText.vue ================================================ ================================================ FILE: examples/components/theme-configurator/index.vue ================================================ ================================================ FILE: examples/components/theme-configurator/main.vue ================================================ ================================================ FILE: examples/components/theme-configurator/shortcut.vue ================================================ ================================================ FILE: examples/components/theme-configurator/utils/boxShadow.js ================================================ const VALUES_REG = /,(?![^\(]*\))/; const PARTS_REG = /\s(?![^(]*\))/; const LENGTH_REG = /^[0-9]+[a-zA-Z%]+?$/; const parseValue = str => { const parts = str.split(PARTS_REG); const inset = parts.includes('inset'); const last = parts.slice(-1)[0]; const color = !isLength(last) ? last : undefined; const nums = parts .filter(n => n !== 'inset') .filter(n => n !== color) .map(toNum); const [ offsetX, offsetY, blurRadius, spreadRadius ] = nums; return { inset, offsetX, offsetY, blurRadius, spreadRadius, color }; }; const stringifyValue = obj => { const { inset, offsetX = 0, offsetY = 0, blurRadius = 0, spreadRadius, color } = obj || {}; return [ (inset ? 'inset' : null), offsetX, offsetY, blurRadius, spreadRadius, color ].filter(v => v !== null && v !== undefined) .map(toPx) .map(s => ('' + s).trim()) .join(' '); }; const isLength = v => v === '0' || LENGTH_REG.test(v); const toNum = v => { if (!/px$/.test(v) && v !== '0') return v; const n = parseFloat(v); return !isNaN(n) ? n : v; }; const toPx = n => typeof n === 'number' && n !== 0 ? (n + 'px') : n; export const parse = str => str.split(VALUES_REG).map(s => s.trim()).map(parseValue); export const stringify = arr => arr.map(stringifyValue).join(', '); ================================================ FILE: examples/components/theme-configurator/utils/utils.js ================================================ import deepmerge from 'deepmerge'; import constant from '../../../i18n/theme-editor.json'; export const filterConfigType = (name) => { switch (name) { case 'color': case 'typography': case 'border': return 'global'; default: return 'local'; } }; export const filterGlobalValue = (defaultConfig, userConfig) => { const valueObject = {}; const globalArr = ['color', 'typography', 'border']; globalArr.forEach((global) => { const configObj = {}; defaultConfig .find(config => (config.name === global)) .config.forEach(c => (configObj[c.key] = deepmerge({}, c))); valueObject[global] = configObj; Object.keys(configObj).forEach((c) => { if (userConfig.global[c]) { configObj[c].value = userConfig.global[c]; } }); }); return valueObject; }; export const getStyleDisplayValue = (displayValue, global) => { if (displayValue.startsWith('$')) { return global[displayValue].value; } return displayValue; }; const getLang = () => { return location.hash.replace('#', '').split('/')[1] || 'zh-CN'; }; const getNameFromI18N = (name) => { const lang = getLang(); return constant.filter(config => config.lang === lang)[0][name]; }; export const getVariableDisplayName = (key) => { return getNameFromI18N('variable-name')[key] || key; }; export const getStyleDisplayName = (config, componentName) => { const displayNameMap = getNameFromI18N('display-name'); if (config.name) { return getVariableDisplayName(config.key.replace('$--', '')); } let displayName = config.key.replace(`$--${componentName}-`, ''); Object.keys(displayNameMap).forEach((name) => { displayName = displayName.replace(name, displayNameMap[name]); }); displayName = displayName.replace(/-/g, ' '); return displayName.trim(); }; export const getActionDisplayName = (key) => { return getNameFromI18N('action')[key] || key; }; ================================================ FILE: examples/components/theme-picker.vue ================================================ ================================================ FILE: examples/demo-styles/alert.scss ================================================ .demo-block.demo-alert .el-alert { margin: 20px 0 0; } .demo-block.demo-alert .el-alert:first-child { margin: 0; } ================================================ FILE: examples/demo-styles/avatar.scss ================================================ .demo-avatar { &.demo-basic { text-align: center; .demo-basic--circle, .demo-basic--square { display: flex; justify-content: space-between; align-items: center; .block { flex: 1; } .block:not(:last-child) { border-right: 1px solid rgba(224, 230, 237, 0.5); } } } .sub-title { margin-bottom: 10px; font-size: 14px; color: #8492a6; } .el-col:not(:last-child) { border-right: 1px solid rgba(224,230,237,.5); } .demo-type { display: flex; >div { flex: 1; text-align: center; } >div:not(:last-child) { border-right: 1px solid rgba(224,230,237,.5); } } .demo-fit { display: flex; text-align: center; justify-content: space-between; .block { flex: 1; display: flex; flex-direction: column; flex-grow: 0; } .title { margin-bottom: 10px; font-size: 14px; color: #8492a6; } } } ================================================ FILE: examples/demo-styles/badge.scss ================================================ .demo-badge.demo-block .el-dropdown { vertical-align: middle; } .demo-badge.demo-block { .share-button { width: 36px; padding: 10px; } .mark { margin-top: 8px; line-height: 1; float: right; } .item { margin-right: 40px; } } ================================================ FILE: examples/demo-styles/border.scss ================================================ .demo-border .text { width: 15%; } .demo-border .line { width: 70%; } .demo-border .line div { width: 100%; height: 0; border-top: 1px solid #eee; } .demo-border .line .dashed { border-top: 2px dashed #eee; } .demo-shadow { height: 100px; width: 50%; border: 1px solid #eee; } .demo-shadow-text { line-height: 50px; color: #666; font-size: 14px; } .demo-radius .title { color: #666; font-size: 18px; margin: 10px 0; } .demo-radius .value { color: #333; font-size: 16px; margin: 10px 0; } .demo-radius .radius { height: 60px; width: 70%; border: 1px solid #d7dae2; border-radius: 0; margin-top: 20px; } .demo-radius .radius-30 { border-radius: 30px; } ================================================ FILE: examples/demo-styles/button.scss ================================================ .demo-block.demo-button { .el-row { margin-bottom: 20px; &:last-child { margin-bottom: 0; } } .el-button + .el-button { margin-left: 10px; } .el-button-group { .el-button + .el-button { margin-left: 0; } & + .el-button-group { margin-left: 10px; } } } ================================================ FILE: examples/demo-styles/calendar.scss ================================================ .demo-calendar.demo-block { .is-selected { color: #1989FA; } } ================================================ FILE: examples/demo-styles/card.scss ================================================ .demo-block.demo-card { .text { font-size: 14px; } .time { font-size: 13px; color: #999; } .bottom { margin-top: 13px; line-height: 12px; } .item { margin-bottom: 18px; } .button { padding: 0; float: right; } .image { width: 100%; display: block; } .box-card { width: 480px; } } ================================================ FILE: examples/demo-styles/carousel.scss ================================================ .demo-carousel .block { padding: 30px; text-align: center; border-right: solid 1px #eff2f6; display: inline-block; width: 49%; box-sizing: border-box; &:last-child { border-right: none; } } .demo-carousel .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } .demo-carousel .el-carousel__container { text-align: center; } .demo-carousel .el-carousel__item { h3 { color: #fff; font-size: 18px; line-height: 300px; margin: 0; &.small { font-size: 14px; line-height: 150px; } &.medium { font-size: 14px; line-height: 200px; } } &:nth-child(2n) { background-color: #99a9bf; } &:nth-child(2n + 1) { background-color: #d3dce6; } } ================================================ FILE: examples/demo-styles/cascader.scss ================================================ .demo-cascader { .el-cascader { width: 222px; } } .demo-cascader-size { .el-cascader { vertical-align: top; margin-right: 15px; } } .demo-cascader .source > div { display: flex; } .demo-cascader .block { padding: 30px 0; text-align: center; border-right: solid 1px #eff2f6; width: 50%; box-sizing: border-box; &:last-child { border-right: none; } } .demo-cascader .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } ================================================ FILE: examples/demo-styles/collapse.scss ================================================ .demo-collapse { .el-collapse-item__header { .header-icon { margin-left: 5px; } } } ================================================ FILE: examples/demo-styles/color-picker.scss ================================================ .demo-color-picker .block { padding: 30px 0; text-align: center; border-right: solid 1px #eff2f6; display: inline-block; width: 50%; box-sizing: border-box; &:last-child { border-right: none; } } .demo-color-picker .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } .demo-color-picker .el-color-picker + .el-color-picker { margin-left: 20px; } ================================================ FILE: examples/demo-styles/color.scss ================================================ .demo-color-box { position: relative; border-radius: 4px; padding: 20px; margin: 5px 0; height: 114px; box-sizing: border-box; color: #fff; font-size: 14px; & .value { font-size: 12px; opacity: 0.69; line-height: 24px; } } .demo-color-box-other { height: 74px; margin: 10px 0 !important; border-radius: 4px 4px 4px 4px !important; padding: 15px 20px; } .demo-color-box-group { .demo-color-box { border-radius: 0; margin: 0; } .demo-color-box:first-child { border-radius: 4px 4px 0 0; } .demo-color-box:last-child { border-radius: 0 0 4px 4px; } } .bg-color-sub { width: 100%; height: 40px; left: 0; bottom: 0; position: absolute; border-radius: 0 0 4px 4px; } .bg-blue-sub-item { width: 11.1111111%; height: 100%; display: inline-block; } .bg-blue-sub-item:first-child { border-radius: 0 0 0 4px; } .bg-success-sub-item { width: 50%; height: 100%; display: inline-block; } .bg-success-sub-item:first-child { border-radius: 0 0 0 4px; } .bg-success-sub-item:last-child { border-radius: 0 0 4px 0; } .bg-transparent { border: 1px solid #fcc3c3; color: #303133; background: url("data:image/svg+xml;utf8,"); background-repeat: no-repeat; background-position: center center; background-size: 100% 100%, auto; } .demo-color-box-lite { color: #303133; } ================================================ FILE: examples/demo-styles/container.scss ================================================ .el-header, .el-footer { background-color: #b3c0d1; color: #333; line-height: 60px; } .el-aside { color: #333; } #chang-jian-ye-mian-bu-ju + .demo-container { .el-header, .el-footer { text-align: center; } .el-aside { background-color: #d3dce6; text-align: center; line-height: 200px; } .el-main { background-color: #e9eef3; color: #333; text-align: center; line-height: 160px; } & > .source > .el-container { margin-bottom: 40px; &:nth-child(5) .el-aside, &:nth-child(6) .el-aside { line-height: 260px; } &:nth-child(7) .el-aside { line-height: 320px; } } } ================================================ FILE: examples/demo-styles/date-picker.scss ================================================ .demo-block.demo-date-picker .source > div { padding: 0; display: flex; flex-wrap: wrap; } .demo-date-picker .block { padding: 30px 0; text-align: center; border-right: solid 1px #eff2f6; flex: 1; &:last-child { border-right: none; } } .demo-date-picker .container { flex: 1; border-right: solid 1px #eff2f6; .block { border-right: none; &:last-child { border-top: solid 1px #eff2f6; } } &:last-child { border-right: none; } } .demo-date-picker .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } ================================================ FILE: examples/demo-styles/datetime-picker.scss ================================================ .demo-block.demo-datetime-picker .source > div { padding: 0; display: flex; } .demo-datetime-picker .block { padding: 30px 0; text-align: center; border-right: solid 1px #eff2f6; flex: 1; &:last-child { border-right: none; } } .demo-datetime-picker .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } ================================================ FILE: examples/demo-styles/descriptions.scss ================================================ .demo-block.demo-descriptions { .margin-top { margin-top: 20px; } .my-label { background: #E1F3D8; } .my-content { background: #FDE2E2; } } ================================================ FILE: examples/demo-styles/dialog.scss ================================================ .demo-block.demo-dialog { .dialog-footer button:first-child { margin-right: 10px; } .full-image { width: 100%; } .el-dialog__wrapper { margin: 0; } .el-select { width: 300px; } .el-input { width: 300px; } .el-button--text { margin-right: 15px; } } ================================================ FILE: examples/demo-styles/divider.scss ================================================ .demo-divider-container-1 { display: inline-block; width: 33%; } .demo-divider-container-2 { display: inline-block; width: 50%; } ================================================ FILE: examples/demo-styles/drawer.scss ================================================ .demo-drawer { &__content { display: flex; flex-direction: column; height: 100%; form { flex: 1; } } &__footer { display: flex; button { flex: 1; } } } .el-drawer__body { padding: 20px; } ================================================ FILE: examples/demo-styles/dropdown.scss ================================================ .demo-block { .el-dropdown { vertical-align: top; & + .el-dropdown { margin-left: 15px; } } .el-dropdown-link { cursor: pointer; color: #409eff; } .el-icon-arrow-down { font-size: 12px; } } .block-col-2 { margin: -24px; .el-col { padding: 30px 0; text-align: center; border-right: 1px solid #eff2f6; &:last-child { border-right: 0; } } } .demo-dropdown .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } ================================================ FILE: examples/demo-styles/form.scss ================================================ .demo-form { .el-select .el-input { width: 380px; } .el-form { width: 460px; } .line { text-align: center; } .el-checkbox-group { width: 320px; margin: 0; padding: 0; list-style: none; &:after, &:before { content: " "; display: table; } &:after { clear: both; visibility: hidden; font-size: 0; height: 0; } .el-checkbox { float: left; width: 160px; padding-right: 20px; margin: 0; padding: 0; + .el-checkbox { margin-left: 0; } } } .demo-form-normal { width: 460px; } .demo-form-inline { width: auto; .el-input { width: 150px; } > * { margin-right: 10px; } } .demo-ruleForm { width: 460px; .el-select .el-input { width: 360px; } } .demo-dynamic { .el-input { margin-right: 10px; width: 270px; vertical-align: top; } } .fr { float: right; } } ================================================ FILE: examples/demo-styles/i18n.scss ================================================ ul.language-list { color: #5e6d82; font-size: 14px; padding-left: 20px; li { line-height: 1.8; } } ================================================ FILE: examples/demo-styles/icon.scss ================================================ .demo-icon .source > div > i { color: #606266; margin: 0 20px; font-size: 1.5em; vertical-align: middle; } .demo-icon .source button { margin: 0 20px; } .page-component .content > ul.icon-list { overflow: hidden; list-style: none; padding: 0!important; border: solid 1px #eaeefb; border-radius: 4px; } .icon-list li { float: left; width: 16.66%; text-align: center; height: 120px; line-height: 120px; color: #666; font-size: 13px; border-right: 1px solid #eee; border-bottom: 1px solid #eee; margin-right: -1px; margin-bottom: -1px; &::after { display: inline-block; content: ""; height: 100%; vertical-align: middle; } span { display: inline-block; line-height: normal; vertical-align: middle; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif; color: #99a9bf; transition: color 0.15s linear; } i { display: block; font-size: 32px; margin-bottom: 15px; color: #606266; transition: color 0.15s linear; } .icon-name { display: inline-block; padding: 0 3px; height: 1em; } &:hover { span, i { color: rgb(92, 182, 255); } } } ================================================ FILE: examples/demo-styles/image.scss ================================================ @keyframes dot { 0% { width: 0; margin-right: 1em; } 100% { width: 1em; margin-right: 0; } } .demo-image { .block { padding: 30px 0; text-align: center; border-right: solid 1px #eff2f6; display: inline-block; width: 20%; box-sizing: border-box; vertical-align: top; &:last-child { border-right: none; } } .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } } .demo-image__placeholder, .demo-image__error { @extend .demo-image; .block { width: 49%; } .el-image { width: 300px; height: 200px; } .image-slot { display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; background: #f5f7fa; color: #909399; font-size: 14px; } } .demo-image__placeholder { .dot { animation: dot 2s infinite steps(3, start); overflow: hidden; } } .demo-image__error { .image-slot { font-size: 30px; } } .demo-image__lazy { height: 400px; overflow-y: auto; .el-image { display: block; min-height: 200px; margin-bottom: 10px; &:last-child { margin-bottom: 0; } } } ================================================ FILE: examples/demo-styles/index.scss ================================================ @import "./alert.scss"; @import "./badge.scss"; @import "./border.scss"; @import "./button.scss"; @import "./calendar.scss"; @import "./card.scss"; @import "./carousel.scss"; @import "./cascader.scss"; @import "./collapse.scss"; @import "./color-picker.scss"; @import "./color.scss"; @import "./container.scss"; @import "./date-picker.scss"; @import "./datetime-picker.scss"; @import "./dialog.scss"; @import "./dropdown.scss"; @import "./form.scss"; @import "./i18n.scss"; @import "./icon.scss"; @import "./input-number.scss"; @import "./input.scss"; @import "./layout.scss"; @import "./loading.scss"; @import "./menu.scss"; @import "./pagination.scss"; @import "./popover.scss"; @import "./progress.scss"; @import "./rate.scss"; @import "./select.scss"; @import "./slider.scss"; @import "./switch.scss"; @import "./table.scss"; @import "./tag.scss"; @import "./time-picker.scss"; @import "./timeline.scss"; @import "./tooltip.scss"; @import "./transition.scss"; @import "./transfer.scss"; @import "./tree.scss"; @import "./typography.scss"; @import "./upload.scss"; @import "./divider.scss"; @import "./image.scss"; @import "./infinite-scroll.scss"; @import "./avatar.scss"; @import "./drawer.scss"; @import "./skeleton.scss"; @import "./descriptions.scss"; ================================================ FILE: examples/demo-styles/infinite-scroll.scss ================================================ .infinite-list { height: 300px; padding: 0; margin: 0; list-style: none; .infinite-list-item { display: flex; align-items: center; justify-content: center; height: 50px; background: #e8f3fe; margin: 10px; color: lighten(#1989fa, 20%); & + .list-item { margin-top: 10px } } } .infinite-list-wrapper { height: 300px; text-align: center; .list{ padding: 0; margin: 0; list-style: none; } .list-item{ display: flex; align-items: center; justify-content: center; height: 50px; background: #fff6f6; color: #ff8484; & + .list-item { margin-top: 10px } } } ================================================ FILE: examples/demo-styles/input-number.scss ================================================ .demo-block.demo-input-number { .el-input-number + .el-input-number { margin-left: 10px; } } ================================================ FILE: examples/demo-styles/input.scss ================================================ .demo-input { .el-select .el-input { width: 130px; } .el-input { width: 180px; } .el-textarea { width: 414px; } .el-input-group { width: 100%; } .demo-input-size { .el-input { vertical-align: top; margin: 0 10px 10px 0; } } .input-with-select .el-input-group__prepend { background-color: #fff; } .demo-autocomplete { text-align: center; .sub-title { margin-bottom: 10px; font-size: 14px; color: #8492a6; } .el-col:not(:last-child) { border-right: 1px solid rgba(224, 230, 237, 0.5); } .el-autocomplete { text-align: left; } } } .el-autocomplete-suggestion.my-autocomplete { li { line-height: normal; padding-top: 7px; padding-bottom: 7px; .name { text-overflow: ellipsis; overflow: hidden; } .addr { font-size: 12px; color: #b4b4b4; } .highlighted .addr { color: #ddd; } } } .demo-input-suffix { margin-bottom: 15px; .el-input { margin-right: 15px; } } ================================================ FILE: examples/demo-styles/layout.scss ================================================ .demo-layout { .el-row { margin-bottom: 20px; &:last-child { margin-bottom: 0; } } .el-col { border-radius: 4px; } .bg-purple-dark { background: #99a9bf; } .bg-purple { background: #d3dce6; } .bg-purple-light { background: #e5e9f2; } .grid-content { border-radius: 4px; min-height: 36px; } .row-bg { padding: 10px 0; background-color: #f9fafc; } } ================================================ FILE: examples/demo-styles/loading.scss ================================================ .demo-loading .el-table { border: none; } ================================================ FILE: examples/demo-styles/menu.scss ================================================ .demo-block.demo-menu { .el-menu-demo { padding-left: 55px; } .el-menu-vertical-demo:not(.el-menu--collapse) { width: 240px; min-height: 400px; } .line { height: 1px; background-color: #e0e6ed; margin: 35px -24px; } h5 { font-size: 14px; color: #8492a6; margin-top: 10px; } .tac { text-align: center; .el-menu-vertical-demo { display: inline-block; text-align: left; } } } ================================================ FILE: examples/demo-styles/pagination.scss ================================================ .demo-pagination .source.first { padding: 0; } .demo-pagination .first .block { padding: 30px 0; text-align: center; border-right: solid 1px #eff2f6; display: inline-block; width: 50%; box-sizing: border-box; &:last-child { border-right: none; } } .demo-pagination .first .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } .demo-pagination .source.last { padding: 0; } .demo-pagination .last .block { padding: 30px 24px; border-bottom: solid 1px #eff2f6; &:last-child { border-bottom: none; } } .demo-pagination .last .demonstration { font-size: 14px; color: #8492a6; line-height: 44px; } .demo-pagination .last .demonstration + .el-pagination { width: 70%; margin: 5px 20px 0 0; } ================================================ FILE: examples/demo-styles/popover.scss ================================================ .demo-block.demo-popover { .el-popover + .el-popover { margin-left: 10px; } .el-input { width: 360px; } .el-button { margin-left: 10px; } } ================================================ FILE: examples/demo-styles/progress.scss ================================================ .demo-block.demo-progress { .el-progress--line { margin-bottom: 15px; width: 350px; } .el-progress--circle { margin-right: 15px; } } ================================================ FILE: examples/demo-styles/rate.scss ================================================ .demo-rate .block { padding: 30px 0; text-align: center; border-right: solid 1px #eff2f6; display: inline-block; width: 49%; box-sizing: border-box; &:last-child { border-right: none; } } .demo-rate .demonstration { display: block; color: #8492a6; font-size: 14px; margin-bottom: 20px; } ================================================ FILE: examples/demo-styles/select.scss ================================================ .demo-select .el-select { width: 240px; } ================================================ FILE: examples/demo-styles/skeleton.scss ================================================ .demo-block.demo-skeleton { .el-card { margin-bottom: 16px; } .card-header { display: flex; justify-content: space-between; align-items: center; } .time { font-size: 13px; color: #999; } .bottom { margin-top: 13px; line-height: 12px; } .button { padding: 0; min-height: auto; } .image { &.multi-content { width: 400px; height: 267px; } width: 100%; display: block; } .clearfix:before, .clearfix:after { display: table; content: ''; } .clearfix:after { clear: both; } } ================================================ FILE: examples/demo-styles/slider.scss ================================================ .demo-block.demo-slider .source { padding: 0; } .demo-block.demo-slider .block { padding: 30px 24px; overflow: hidden; border-bottom: solid 1px #eff2f6; &:last-child { border-bottom: none; } } .demo-block.demo-slider .demonstration { font-size: 14px; color: #8492a6; line-height: 44px; } .demo-block.demo-slider .demonstration + .el-slider { float: right; width: 70%; margin-right: 20px; } ================================================ FILE: examples/demo-styles/switch.scss ================================================ .demo-block.demo-switch { .el-switch { margin: 20px 20px 20px 0; } } ================================================ FILE: examples/demo-styles/table.scss ================================================ .el-table .warning-row { background: oldlace; } .el-table .success-row { background: #f0f9eb; } .demo-table .name-wrapper { display: inline-block; } .demo-table .demo-table-expand { label { width: 90px; color: #99a9bf; } .el-form-item { margin-right: 0; margin-bottom: 0; width: 50%; } } ================================================ FILE: examples/demo-styles/tag.scss ================================================ .demo-block.demo-tag { .el-tag + .el-tag { margin-left: 10px; } .button-new-tag { margin-left: 10px; height: 32px; line-height: 30px; padding-top: 0; padding-bottom: 0; } .input-new-tag { width: 90px; margin-left: 10px; vertical-align: bottom; } .tag-group { display: flex; align-items: center; &__title { width: 45px; font-size: 14px; color: #606266; } &+.tag-group { margin-top: 10px; } } } ================================================ FILE: examples/demo-styles/time-picker.scss ================================================ .demo-block { .el-date-editor + .el-date-editor { margin-left: 10px; } } ================================================ FILE: examples/demo-styles/timeline.scss ================================================ .demo-timeline .source .radio { margin-bottom: 20px; } .demo-timeline .source .radio .el-radio-group { margin-left: 20px; } ================================================ FILE: examples/demo-styles/tooltip.scss ================================================ .demo-tooltip { .el-tooltip + .el-tooltip { margin-left: 15px; } .box { width: 400px; .top { text-align: center; } .left { float: left; width: 60px; } .right { float: right; width: 60px; } .bottom { clear: both; text-align: center; } .item { margin: 4px; } .left .el-tooltip__popper, .right .el-tooltip__popper { padding: 8px 10px; } .el-tooltip { margin-left: 0; } } } ================================================ FILE: examples/demo-styles/transfer.scss ================================================ .demo-transfer { .transfer-footer { margin-left: 15px; padding: 6px 5px; } } ================================================ FILE: examples/demo-styles/transition.scss ================================================ .demo-transition { .transition-box { margin-bottom: 10px; width: 200px; height: 100px; border-radius: 4px; background-color: #409EFF; text-align: center; color: #fff; padding: 40px 20px; margin-right: 20px; box-sizing: border-box; } } ================================================ FILE: examples/demo-styles/tree.scss ================================================ .demo-tree { .leaf { width: 20px; background: #ddd; } .folder { width: 20px; background: #888; } .buttons { margin-top: 20px; } .filter-tree { margin-top: 20px; } .custom-tree-container { display: flex; margin: -24px; } .block { flex: 1; padding: 8px 24px 24px; &:first-child { border-right: solid 1px #eff2f6; } > p { text-align: center; margin: 0; line-height: 4; } } .custom-tree-node { flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px; } } ================================================ FILE: examples/demo-styles/typography.scss ================================================ .demo-typo-size { .color-dark-light { color: #99a9bf; } } .demo-term-box img { width: 24%; margin: 0 4% 20px 0; } .lineH-left { display: inline-block; height: 80px; } .lineH-right { display: inline-block; list-style: none; padding: 0 0 0 90px; margin: 0; vertical-align: top; } .lineH-right li { font-size: 13px; color: #666; height: 20px; line-height: 20px; } .lineH-right li span { padding-left: 40px; } ================================================ FILE: examples/demo-styles/upload.scss ================================================ .upload-tip { color: #8492a6; font-size: 12px; margin-top: 7px; } .demo-block { margin-bottom: 24px; .upload-demo { width: 360px; } .avatar-uploader { .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; &:hover, &:focus { border-color: #409eff; } } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } } } ================================================ FILE: examples/docs/en-US/alert.md ================================================ ## Alert Displays important alert messages. ### Basic usage Alert components are non-overlay elements in the page that does not disappear automatically. :::demo Alert provides 4 types of themes defined by `type`, whose default value is `info`. ```html ``` ::: ### Theme Alert provide two different themes, `light` and `dark`. :::demo Set `effect` to change theme, default is `light`. ```html ``` ::: ### Customizable close button Customize the close button as texts or other symbols. :::demo Alert allows you to configure if it's closable. The close button text and closing callbacks are also customizable. `closable` attribute decides if the component can be closed or not. It accepts `boolean`, and the default is `true`. You can set `close-text` attribute to replace the default cross symbol as the close button. Be careful that `close-text` must be a string. `close` event fires when the component is closed. ```html ``` ::: ### With icon Displaying an icon improves readability. :::demo Setting the `show-icon` attribute displays an icon that corresponds with the current Alert type. ```html ``` ::: ## Centered text Use the `center` attribute to center the text. :::demo ```html ``` ::: ### With description Description includes a message with more detailed information. :::demo Besides the required `title` attribute, you can add a `description` attribute to help you describe the alert with more details. Description can only store text string, and it will word wrap automatically. ```html ``` ::: ### With icon and description :::demo At last, this is an example with both icon and description. ```html ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | title | title | string | — | — | | type | Component type | string | success/warning/info/error | info | | description | Descriptive text. Can also be passed with the default slot | string | — | — | | closable | If closable or not | boolean | — | true | | center | Whether to center the text | boolean | — | false | | close-text | Customized close button text | string | — | — | | show-icon | If a type icon is displayed | boolean | — | false | | effect | Choose theme | string | light/dark | light | ### Slot | Name | Description | |------|--------| | — | description | | title | content of the Alert title | ### Events | Event Name | Description | Parameters | |---------- |-------- |---------- | | close | fires when alert is closed | — | ================================================ FILE: examples/docs/en-US/avatar.md ================================================ ## Avatar avatar Avatars can be used to represent people or objects. It supports images, Icons, or characters. ### Basic use `shape` and `size` prop to set avatar's shape and size :::demo ```html ``` ::: ### Types It supports images, Icons, or characters :::demo ```html ``` ::: ### Fallback when image load error fallback when image load error :::demo ```html ``` ::: ### How the image fit its container Set how the image fit its container for an image avatar, same as [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit). :::demo ```html ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | | ----------------- | -------------------------------- | --------------- | ------ | ------ | | icon | set representation type to Icon, more info on Icon Component | string | | | | size | set avatar size | number/string | number / large / medium / small | large | | shape | set avatar shape | string | circle / square | circle | | src | the address of the image for an image avatar | string | | | | srcSet | A list of one or more strings separated by commas indicating a set of possible image sources for the user agent to use | string | | | | alt | This attribute defines an alternative text description of the image | string | | | | fit | set how the image fit its container for an image avatar | string | fill / contain / cover / none / scale-down | cover | ### Events | Event Name | Description | Parameters | | ------ | ------------------ | -------- | | error | handler when img load error, return false to prevent default fallback behavior |(e: Event) | ### Slot | Slot Name | Description | | default | customize avatar content | ================================================ FILE: examples/docs/en-US/backtop.md ================================================ ## Backtop A button to back to top ### Basic usage Scroll down to see the bottom-right button. :::demo ```html ``` ::: ### Customizations Display area is 40px \* 40px. :::demo ```html ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | | ----------------- | ------------------------------------------------------------------- | --------------- | --------------- | ------- | | target | the target to trigger scroll | string | | | | visibility-height | the button will not show until the scroll height reaches this value | number | | 200 | | right | right distance | number | | 40 | | bottom | bottom distance | number | | 40 | ### Events | Event Name | Description | Parameters | | ---------- | ------------------- | ----------- | | click | triggers when click | click event | ================================================ FILE: examples/docs/en-US/badge.md ================================================ ## Badge A number or status mark on buttons and icons. ### Basic usage Displays the amount of new messages. :::demo The amount is defined with `value` which accepts `Number` or `String`. ```html comments replies comments replies Click Me comments replies ``` ::: ### Max value You can customize the max value. :::demo The max value is defined by property `max` which is a `Number`. Note that it only works when `value` is also a `Number`. ```html comments replies ``` ::: ### Customizations Displays text content other than numbers. :::demo When `value` is a `String`, it can display customized text. ```html comments replies ``` ::: ### Little red dot Use a red dot to mark content that needs to be noticed. :::demo Use the attribute `is-dot`. It is a `Boolean`. ```html query ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |------------- |---------------- |---------------- |---------------------- |-------- | | value | display value | string, number | — | — | | max | maximum value, shows '{max}+' when exceeded. Only works if `value` is a `Number` | number | — | — | | is-dot | if a little dot is displayed | boolean | — | false | | hidden | hidden badge | boolean | — | false | | type | button type | string | primary / success / warning / danger / info | — | ================================================ FILE: examples/docs/en-US/border.md ================================================ ## Border We standardize the borders that can be used in buttons, cards, pop-ups and other components. ### Border There are few border styles to choose.
Name Thickness Demo
Solid 1px
Dashed 2px
### Radius There are few radius styles to choose.
No Radius
border-radius: 0px
Small Radius
border-radius: {{borderRadiusSmall}}
Large Radius
border-radius: {{borderRadiusBase}}
Round Radius
border-radius: 30px
### Shadow There are few shadow styles to choose.
Basic Shadow box-shadow: {{boxShadowBase}}
Light Shadow box-shadow: {{boxShadowLight}} ================================================ FILE: examples/docs/en-US/breadcrumb.md ================================================ ## Breadcrumb Displays the location of the current page, making it easier to browser back. ### Basic usage :::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 '/'. ```html homepage promotion management promotion list promotion detail ``` ::: ### Icon separator :::demo Set `separator-class` to use `iconfont` as the separator,it will cover `separator` ```html homepage promotion management promotion list promotion detail ``` ::: ### Breadcrumb Attributes | Attribute | Description | Type | Accepted Values | Default| |---------- |-------------- |---------- |-------------------------------- |-------- | | separator | separator character | string | — | / | | separator-class | class name of icon separator | string | — | - | ### Breadcrumb Item Attributes | Attribute | Description | Type | Accepted Values | Default| |---------- |-------------- |---------- |-------------------------------- |-------- | | to | target route of the link, same as `to` of `vue-router` | string/object | — | — | | replace | if `true`, the navigation will not leave a history record | boolean | — | false | ================================================ FILE: examples/docs/en-US/button.md ================================================ ## Button Commonly used button. ### Basic usage :::demo Use `type`, `plain`, `round` and `circle` to define Button's style. ```html Default Primary Success Info Warning Danger Plain Primary Success Info Warning Danger Round Primary Success Info Warning Danger ``` ::: ### Disabled Button The `disabled` attribute determines if the button is disabled. :::demo Use `disabled` attribute to determine whether a button is disabled. It accepts a `Boolean` value. ```html Default Primary Success Info Warning Danger Plain Primary Success Info Warning Danger ``` ::: ### Text Button Buttons without border and background. :::demo ```html Text Button Text Button ``` ::: ### Icon Button Use icons to add more meaning to Button. You can use icon alone to save some space, or use it with text. :::demo Use the `icon` attribute to add icon. You can find the icon list in Element icon component. Adding icons to the right side of the text is achievable with an `` tag. Custom icons can be used as well. ```html Search Upload ``` ::: ### Button Group Displayed as a button group, can be used to group a series of similar operations. :::demo Use tag `` to group your buttons. ```html Previous Page Next Page ``` ::: ### Loading Button Click the button to load data, then the button displays a loading state. :::demo Set `loading` attribute to `true` to display loading state. ```html Loading ``` ::: ### Sizes Besides default size, Button component provides three additional sizes for you to choose among different scenarios. :::demo Use attribute `size` to set additional sizes with `medium`, `small` or `mini`. ```html Default Medium Small Mini Default Medium Small Mini ``` ::: ### Attributes | Attribute | Description | Type | Accepted values | Default | |---------- |-------- |---------- |------------- |-------- | | size | button size | string | medium / small / mini | — | | type | button type | string | primary / success / warning / danger / info / text | — | | plain | determine whether it's a plain button | boolean | — | false | | round | determine whether it's a round button | boolean | — | false | | circle | determine whether it's a circle button | boolean | — | false | | loading | determine whether it's loading | boolean | — | false | | disabled | disable the button | boolean | — | false | | icon | icon class name | string | — | — | | autofocus | same as native button's `autofocus` | boolean | — | false | | native-type | same as native button's `type` | string | button / submit / reset | button | ================================================ FILE: examples/docs/en-US/calendar.md ================================================ ## Calendar Display date. ### Basic :::demo Set `value` to specify the currently displayed month. If `value` is not specified, current month is displayed. `value` supports two-way binding. ```html ``` ::: ### Custom Content :::demo Customize what is displayed in the calendar cell by setting `scoped-slot` named `dateCell`. In `scoped-slot` you can get the date (the date of the current cell), data (including the type, isSelected, day attribute). For details, please refer to the API documentation below. ```html ``` ::: ### Range :::demo Set the `range` attribute to specify the display range of the calendar. Start time must be Monday, end time must be Sunday, and the time span cannot exceed two months. ```html ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |-----------------|------------------- |---------- |---------------------- |--------- | | value / v-model | binding value | Date/string/number | — | — | | range | time range, including start time and end time. Start time must be start day of week, end time must be end day of week, the time span cannot exceed two months. | Array | — | — | | first-day-of-week | first day of week| Number | 1 to 7 | 1 | ### dateCell Scoped Slot Parameters | Attribute | Description | Type | Accepted Values | Default | |-----------------|-------------- |---------- |---------------------- |--------- | | date | date the cell represents | Date | — | — | | data | { type, isSelected, day}. The `type` property indicates which month the date belongs, optional values are `prev-month`, `current-month`, `next-month`. The `isSelected` property indicates whether the date is selected. The `day` property is the formatted date in the format yyyy-MM-dd | Object | — | — | ================================================ FILE: examples/docs/en-US/card.md ================================================ ## Card Integrate information in a card container. ### Basic usage Card includes title, content and operations. :::demo Card is made up of `header` and `body`. `header` is optional, and its content distribution depends on a named slot. ```html
Card name Operation button
{{'List item ' + o }}
``` ::: ### Simple card The header part can be omitted. :::demo ```html
{{'List item ' + o }}
``` ::: ### With images Display richer content by adding some configs. :::demo The `body-style` attribute defines CSS style of custom `body`. This example also uses `el-col` for layout. ```html
Yummy hamburger
Operating
``` ::: ### Shadow You can define when to show the card shadows :::demo The `shadow` attribute determines when the card shadows are displayed. It can be `always`, `hover` or `never`. ```html Always Hover Never ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------- |---------- |------------- |-------- | | header | title of the card. Also accepts a DOM passed by `slot#header` | string| — | — | | body-style | CSS style of body | object| — | { padding: '20px' } | | shadow | when to show card shadows | string | always / hover / never | always | ================================================ FILE: examples/docs/en-US/carousel.md ================================================ ## Carousel Loop a series of images or texts in a limited space ### Basic usage :::demo Combine `el-carousel` with `el-carousel-item`, and you'll get a carousel. Content of each slide is completely customizable, and you just need to place it inside `el-carousel-item` tag. By default the carousel switches when mouse hovers over an indicator. Set `trigger` to `click`, and the carousel switches only when an indicator is clicked. ```html ``` ::: ### Indicators Indicators can be displayed outside the carousel :::demo The `indicator-position` attribute determines where the indicators are located. By default they are inside the carousel, and setting `indicator-position` to `outside` moves them outside; setting `indicator-position` to `none` hides the indicators. ```html ``` ::: ### Arrows You can define when arrows are displayed :::demo The `arrow` attribute determines when arrows are displayed. By default they appear when mouse hovers over the carousel. Setting `arrow` to `always` or `never` shows/hides the arrows permanently. ```html ``` ::: ### Card mode When a page is wide enough but has limited height, you can activate card mode for carousels :::demo Setting `type` to `card` activates the card mode. Apart from the appearance, the biggest difference between card mode and common mode is that clicking the slides at both sides directly switches the carousel in card mode. ```html ``` ::: By default, `direction` is `horizontal`. Let carousel be displayed in the vertical direction by setting `direction` to `vertical`. :::demo ```html ``` ::: ### Carousel Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | height | height of the carousel | string | — | — | | initial-index | index of the initially active slide (starting from 0) | number | — | 0 | | trigger | how indicators are triggered | string | hover/click | hover | | autoplay | whether automatically loop the slides | boolean | — | true | | interval | interval of the auto loop, in milliseconds | number | — | 3000 | | indicator-position | position of the indicators | string | outside/none | — | | arrow | when arrows are shown | string | always/hover/never | hover | | type | type of the Carousel | string | card | — | | loop | display the items in loop | boolean | - | true | | direction | display direction | string | horizontal/vertical | horizontal | ### Carousel Events | Event Name | Description | Parameters | |---------|---------|---------| | change | triggers when the active slide switches | index of the new active slide, index of the old active slide | ### Carousel Methods | Method | Description | Parameters | |---------- |-------------- | -- | | setActiveItem | manually switch slide | index of the slide to be switched to, starting from 0; or the `name` of corresponding `el-carousel-item` | | prev | switch to the previous slide | — | | next | switch to the next slide | — | ### Carousel-Item Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | name | name of the item, can be used in `setActiveItem` | string | — | — | | label | text content for the corresponding indicator | string | — | — | ================================================ FILE: examples/docs/en-US/cascader.md ================================================ ## Cascader If the options have a clear hierarchical structure, Cascader can be used to view and select them. ### Basic usage There are two ways to expand child option items. :::demo Assigning the `options` attribute to an array of options renders a Cascader. The `props.expandTrigger` attribute defines how child options are expanded. ```html
Child options expand when clicked (default)
Child options expand when hovered
``` ::: ### Disabled option Disable an option by setting a `disabled` field in the option object. :::demo In this example, the first item in `options` array has a `disabled: true` field, so it is disabled. By default, Cascader checks the `disabled` field in each option object; if you are using another field name to indicate whether an option is disabled, you can assign it in the `props.disabled` attribute (see the API table below for details). And of course, field name `value`, `label` and `children` can also be customized in the same way. ```html ``` ::: ### Clearable Set `clearable` attribute for `el-cascader` and a clear icon will appear when selected and hovered :::demo ```html ``` ::: ### Display only the last level The input can display only the last level instead of all levels. :::demo The `show-all-levels` attribute defines if all levels are displayed. If it is `false`, only the last level is displayed. ```html ``` ::: ### Multiple Selection Set `props.multiple = true` to use multiple selection. :::demo When using multiple selection, all selected tags will display by default, You can set `collapse-tags = true` to fold selected tags. ```html
Display all tags (default)
Collapse tags
``` ::: ### Select any level of options In single selection, only the leaf nodes can be checked, and in multiple selection, check parent nodes will lead to leaf nodes be checked eventually. When enable this feature, it can make parent and child nodes unlinked and you can select any level of options. :::demo Set `props.checkStrictly = true` to make checked state of a node not affects its parent nodes and child nodes, and then you can select any level of options. ```html
Select any level of options (Single selection)
Select any level of options (Multiple selection)
``` ::: ### Dynamic loading Dynamic load its child nodes when checked a node. :::demo Set `lazy = true` to use dynamic loading, and you have to specify how to load the data source by `lazyload`. There are two parameters of `lazyload`,the first parameter `node` is the node currently clicked, and the `resolve` is a callback that indicate loading is finished which must invoke. To display the status of node more accurately, you can add a `leaf` field (can be modified by `props.leaf`) to indicate whether it is a leaf node. Otherwise, it will be inferred by if has any child nodes. ```html ``` ::: ### Filterable Search and select options with a keyword. :::demo Adding `filterable` to `el-cascader` enables filtering. Cascader will match nodes whose label or parent's label (according to `show-all-levels`) includes input keyword. Of course, you can customize search logic by `filter-method` which accepts a function, the first parameter is `node`, the second is `keyword`, and need return a boolean value indicating whether it hits. ```html
Filterable (Single selection)
Filterable (Multiple selection)
``` ::: ### Custom option content You can customize the content of cascader node. :::demo You can customize the content of cascader node by `scoped slot`. You'll have access to `node` and `data` in the scope, standing for the Node object and node data of the current node respectively。 ```html ``` ::: ### Cascader panel `CascaderPanel` is the core component of `Cascader` which has various of features such as single selection, multiple selection, dynamic loading and so on. :::demo Just like `el-cascader`, you can set alternative options by `options`, and enable other features by `props`, see the API form below for details. ```html ``` ::: ### Cascader Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------- |---------- |------------- |-------- | | value / v-model | binding value | - | — | — | | options | data of the options,the key of `value` and `label` can be customize by `Props`.| array | — | — | | props | configuration options, see the following table. | object | — | — | | size | size of input | string | medium / small / mini | — | | placeholder | placeholder of input | string | — | Select | | disabled | whether Cascader is disabled | boolean | — | false | | clearable | whether selected value can be cleared | boolean | — | false | | show-all-levels | whether to display all levels of the selected value in the input | boolean | — | true | | collapse-tags | whether to collapse tags in multiple selection mode | boolean | - | false | | separator | option label separator | string | — | ' / ' | | filterable | whether the options can be searched | boolean | — | — | | filter-method | customize search logic, the first parameter is `node`, the second is `keyword`, and need return a boolean value indicating whether it hits. | function(node, keyword) | - | - | | debounce | debounce delay when typing filter keyword, in milliseconds | number | — | 300 | | before-filter | hook function before filtering with the value to be filtered as its parameter. If `false` is returned or a `Promise` is returned and then is rejected, filtering will be aborted | function(value) | — | — | | popper-class | custom class name for Cascader's dropdown | string | — | — | ### Cascader Events | Event Name | Description | Parameters | |---------- |-------- |---------- | | change | triggers when the binding value changes | value | | expand-change | triggers when expand option changes | an array of the expanding node's parent nodes | | blur | triggers when Cascader blurs | (event: Event) | | focus | triggers when Cascader focuses | (event: Event) | | visible-change | triggers when the dropdown appears/disappears | true when it appears, and false otherwise | | remove-tag | triggers when remove tag in multiple selection mode | the value of the tag which is removed | ### Cascader Methods | Method Name | Description | Parameters | | ---- | ---- | ---- | | getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` | ### Cascader Slots | Slot Name | Description | |---------|-------------| | - | the custom content of cascader node, the parameter is { node, data }, which are current Node object and node data respectively. | | empty | content when there is no matched options. | ### CascaderPanel Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------- |---------- |------------- |-------- | | value / v-model | binding value | - | — | — | | options | data of the options,the key of `value` and `label` can be customize by `Props`.| array | — | — | | props | configuration options, see the following table. | object | — | — | ### CascaderPanel Events | Event Name | Description | Parameters | |---------- |-------- |---------- | | change | triggers when the binding value changes | value | | expand-change | triggers when expand option changes | an array of the expanding node's parent nodes | ### CascaderPanel Methods | Method Name | Description | Parameters | | ---- | ---- | ---- | | getCheckedNodes | get an array of currently selected node | (leafOnly) whether only return the leaf checked nodes, default is `false` | | clearCheckedNodes | clear checked nodes | - | ### CascaderPanel Slots | Slot Name | Description | |---------|-------------| | - | the custom content of cascader node, the parameter is { node, data }, which are current Node object and node data respectively. | ### Props | Attribute | Description | Type | Accepted Values | Default | | -------- | ----------------- | ------ | ------ | ------ | | expandTrigger | trigger mode of expanding options | string | click / hover | 'click' | | multiple | whether multiple selection is enabled | boolean | - | false | | checkStrictly | whether checked state of a node not affects its parent and child nodes | boolean | - | false | | emitPath | when checked nodes change, whether to emit an array of node's path, if false, only emit the value of node. | boolean | - | true | | lazy | whether to dynamic load child nodes, use with `lazyload` attribute | boolean | - | false | | lazyLoad | method for loading child nodes data, only works when `lazy` is true | function(node, resolve) | - | - | | value | specify which key of node object is used as the node's value | string | — | 'value' | | label | specify which key of node object is used as the node's label | string | — | 'label' | | children | specify which key of node object is used as the node's children | string | — | 'children' | | disabled | specify which key of node object is used as the node's disabled | string | — | 'disabled' | | leaf | specify which key of node object is used as the node's leaf field | string | — | 'leaf' | ================================================ FILE: examples/docs/en-US/checkbox.md ================================================ ## Checkbox A group of options for multiple choices. ### Basic usage Checkbox can be used alone to switch between two states. :::demo Define `v-model`(bind variable) in `el-checkbox`. The default value is a `Boolean` for single `checkbox`, and it becomes `true` when selected. Content inside the `el-checkbox` tag will become the description following the button of the checkbox. ```html ``` ::: ### Disabled State Disabled state for checkbox. :::demo Set the `disabled` attribute. ```html ``` ::: ### Checkbox group It is used for multiple checkboxes which are bound in one group, and indicates whether one option is selected by checking if it is checked. :::demo `checkbox-group` element can manage multiple checkboxes in one group by using `v-model` which is bound as an `Array`. Inside the `el-checkbox` element, `label` is the value of the checkbox. If no content is nested in that tag, `label` will be rendered as the description following the button of the checkbox. `label` also corresponds with the element values in the array. It is selected if the specified value exists in the array, and vice versa. ```html ``` ::: ### Indeterminate The `indeterminate` property can help you to achieve a 'check all' effect. :::demo ```html ``` ::: ### Minimum / Maximum items checked The `min` and `max` properties can help you to limit the number of checked items. :::demo ```html ``` ::: ### Button style Checkbox with button styles. :::demo You just need to change `el-checkbox` element into `el-checkbox-button` element. We also provide `size` attribute. ```html ``` ::: ### With borders :::demo The `border` attribute adds a border to Checkboxes. ```html ``` ::: ### Checkbox Attributes | Attribute | Description | Type | Options | Default| |---------- |-------- |---------- |------------- |-------- | | value / v-model | binding value | string / number / boolean | — | — | | label | value of the Checkbox when used inside a `checkbox-group` | string / number / boolean | — | — | | true-label | value of the Checkbox if it's checked | string / number | — | — | | false-label | value of the Checkbox if it's not checked | string / number | — | — | | disabled | whether the Checkbox is disabled | boolean | — | false | | border | whether to add a border around Checkbox | boolean | — | false | | size | size of the Checkbox, only works when `border` is true | string | medium / small / mini | — | | name | native 'name' attribute | string | — | — | | checked | if the Checkbox is checked | boolean | — | false | | indeterminate | same as `indeterminate` in native checkbox | boolean | — | false | ### Checkbox Events | Event Name | Description | Parameters | |---------- |-------- |---------- | | change | triggers when the binding value changes | the updated value | ### Checkbox-group Attributes | Attribute | Description | Type | Options | Default| |---------- |-------- |---------- |------------- |-------- | | value / v-model | binding value | array | — | — | |size | size of checkbox buttons or bordered checkboxes | string | medium / small / mini | — | | disabled | whether the nesting checkboxes are disabled | boolean | — | false | | min | minimum number of checkbox checked | number | — | — | | max | maximum number of checkbox checked | number | — | — | |text-color | font color when button is active | string | — | #ffffff | |fill | border and background color when button is active | string | — | #409EFF | ### Checkbox-group Events | Event Name | Description | Parameters | |---------- |-------- |---------- | | change | triggers when the binding value changes | the updated value | ### Checkbox-button Attributes | Attribute | Description | Type | Options | Default| |---------- |-------- |---------- |------------- |-------- | | label | value of the checkbox when used inside a `checkbox-group` | string / number / boolean | — | — | | true-label | value of the checkbox if it's checked | string / number | — | — | | false-label | value of the checkbox if it's not checked | string / number | — | — | | disabled | whether the checkbox is disabled | boolean | — | false | | name | native 'name' attribute | string | — | — | | checked | if the checkbox is checked | boolean | — | false | ================================================ FILE: examples/docs/en-US/collapse.md ================================================ ## Collapse Use Collapse to store contents. ### Basic usage You can expand multiple panels :::demo ```html
Consistent with real life: in line with the process and logic of real life, and comply with languages and habits that the users are used to;
Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.
Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;
Visual feedback: reflect current state by updating or rearranging elements of the page.
Simplify the process: keep operating process simple and intuitive;
Definite and clear: enunciate your intentions clearly so that the users can quickly understand and make decisions;
Easy to identify: the interface should be straightforward, which helps the users to identify and frees them from memorizing and recalling.
Decision making: giving advices about operations is acceptable, but do not make decisions for the users;
Controlled consequences: users should be granted the freedom to operate, including canceling, aborting or terminating current operation.
``` ::: ### Accordion In accordion mode, only one panel can be expanded at once :::demo Activate accordion mode using the `accordion` attribute. ```html
Consistent with real life: in line with the process and logic of real life, and comply with languages and habits that the users are used to;
Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.
Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;
Visual feedback: reflect current state by updating or rearranging elements of the page.
Simplify the process: keep operating process simple and intuitive;
Definite and clear: enunciate your intentions clearly so that the users can quickly understand and make decisions;
Easy to identify: the interface should be straightforward, which helps the users to identify and frees them from memorizing and recalling.
Decision making: giving advices about operations is acceptable, but do not make decisions for the users;
Controlled consequences: users should be granted the freedom to operate, including canceling, aborting or terminating current operation.
``` ::: ### Custom title Besides using the `title` attribute, you can customize panel title with named slots, which makes adding custom content, e.g. icons, possible. :::demo ```html
Consistent with real life: in line with the process and logic of real life, and comply with languages and habits that the users are used to;
Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.
Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;
Visual feedback: reflect current state by updating or rearranging elements of the page.
Simplify the process: keep operating process simple and intuitive;
Definite and clear: enunciate your intentions clearly so that the users can quickly understand and make decisions;
Easy to identify: the interface should be straightforward, which helps the users to identify and frees them from memorizing and recalling.
Decision making: giving advices about operations is acceptable, but do not make decisions for the users;
Controlled consequences: users should be granted the freedom to operate, including canceling, aborting or terminating current operation.
``` ::: ### Collapse Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | value / v-model | currently active panel | string (accordion mode) / array (non-accordion mode) | — | — | | accordion | whether to activate accordion mode | boolean | — | false | ### Collapse Events | Event Name | Description | Parameters | |---------|---------|---------| | change | triggers when active panels change | (activeNames: array (non-accordion mode) / string (accordion mode)) | ### Collapse Item Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | name | unique identification of the panel | string/number | — | — | | title | title of the panel | string | — | — | | disabled | disable the collapse item | boolean | — | — | ================================================ FILE: examples/docs/en-US/color-picker.md ================================================ ## ColorPicker ColorPicker is a color selector supporting multiple color formats. ### Basic usage :::demo ColorPicker requires a string typed variable to be bound to v-model. ```html
With default value
With no default value
``` ::: ### Alpha :::demo ColorPicker supports alpha channel selecting. To activate alpha selecting, just add the `show-alpha` attribute. ```html ``` ::: ### Predefined colors :::demo ColorPicker supports predefined color options ```html ``` ::: ### Sizes :::demo ```html ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------- |---------- |------------- |-------- | | value / v-model | binding value | string | — | — | | disabled | whether to disable the ColorPicker | boolean | — | false | | size | size of ColorPicker | string | — | medium / small / mini | | show-alpha | whether to display the alpha slider | boolean | — | false | | color-format | color format of v-model | string | hsl / hsv / hex / rgb | hex (when show-alpha is false)/ rgb (when show-alpha is true) | | popper-class | custom class name for ColorPicker's dropdown | string | — | — | | predefine | predefined color options | array | — | — | ### Events | Event Name | Description | Parameters | |---------|--------|---------| | change | triggers when input value changes | color value | | active-change | triggers when the current active color changes | active color value | ================================================ FILE: examples/docs/en-US/color.md ================================================ ## Color Element uses a specific set of palettes to specify colors to provide a consistent look and feel for the products you build. ### Main Color The main color of Element is bright and friendly blue.
Brand Color
#409EFF
### Secondary Color Besides the main color, you need to use different scene colors in different scenarios (for example, dangerous color indicates dangerous operation)
Success
#67C23A
Warning
#E6A23C
Danger
#F56C6C
Info
#909399
### Neutral Color Neutral colors are for text, background and border colors. You can use different neutral colors to represent the hierarchical structure.
Primary Text
{{textPrimary}}
Regular Text
{{textRegular}}
Secondary Text
{{textSecondary}}
Placeholder Text
{{textPlaceholder}}
Base Border
{{borderBase}}
Light Border
{{borderLight}}
Lighter Border
{{borderLighter}}
Extra Light Border
{{borderExtraLight}}
Basic Black
{{black}}
Basic White
{{white}}
Transparent
Transparent
================================================ FILE: examples/docs/en-US/container.md ================================================ ## Container Container components for scaffolding basic structure of the page: ``: wrapper container. When nested with a `` or ``, all its child elements will be vertically arranged. Otherwise horizontally. ``: container for headers. ``: container for side sections (usually a side nav). ``: container for main sections. ``: container for footers. :::tip These components use flex for layout, so please make sure your browser supports it. Besides, ``'s direct child elements have to be one or more of the latter four components. And father element of the latter four components must be a ``. ::: ### Common layouts :::demo ```html Header Main Header Main Footer Aside Main Header Aside Main Header Aside Main Footer Aside Header Main Aside Header Main Footer ``` ::: ### Example :::demo ```html Option 1 Option 2 Option 3 Option 4-1 Option 1 Option 2 Option 3 Option 4-1 Option 1 Option 2 Option 3 Option 4-1 View Add Delete Tom ``` ::: ### Container Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | direction | layout direction for child elements | string | horizontal / vertical | vertical when nested with `el-header` or `el-footer`; horizontal otherwise | ### Header Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | height | height of the header | string | — | 60px | ### Aside Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | width | width of the side section | string | — | 300px | ### Footer Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | height | height of the footer | string | — | 60px | ================================================ FILE: examples/docs/en-US/custom-theme.md ================================================ ## Custom theme Element uses BEM-styled CSS so that you can override styles easily. But if you need to replace styles at a large scale, e.g. change the theme color from blue to orange or green, maybe overriding them one by one is not a good idea. We provide four ways to change the style variables. ### Theme Roller Use [Online Theme Roller](./#/en-US/theme) to customize all Design Tokens of global variables and components,and preview the new theme in real-time.and it can generate a complete style package based on the new theme for you to download directly (to import new style files in your project, please refer to the 'Import custom theme' part of this section). Also, use [Theme Roller Chrome Extension](https://chrome.google.com/webstore/detail/element-theme-roller/lifkjlojflekabbmlddfccdkphlelmim),to customize theme and preview in real-time on any website developed by Element. ### Changing theme color If you just want to change the theme color of Element, the [theme preview website](https://elementui.github.io/theme-chalk-preview/#/en-US) is recommended. The theme color of Element is bright and friendly blue. By changing it, you can make Element more visually connected to specific projects. The above website enables you to preview theme of a new theme color in real-time, and it can generate a complete style package based on the new theme color for you to download directly (to import new style files in your project, please refer to the 'Import custom theme' or 'Import component theme on demand' part of this section). ### Update SCSS variables in your project `theme-chalk` is written in SCSS. If your project also uses SCSS, you can directly change Element style variables. Create a new style file, e.g. `element-variables.scss`: ```html /* theme color */ $--color-primary: teal; /* icon font path, required */ $--font-path: '~element-ui/lib/theme-chalk/fonts'; @import "~element-ui/packages/theme-chalk/src/index"; ``` Then in the entry file of your project, import this style file instead of Element's built CSS: ```JS import Vue from 'vue' import Element from 'element-ui' import './element-variables.scss' Vue.use(Element) ``` :::tip Note that it is required to override icon font path to the relative path of Element's font files. ::: ### CLI theme tool If you project doesn't use SCSS, you can customize themes with our CLI theme tool: #### Install First install the theme generator globally or locally. Local install is recommended because in this way, when others clone your project, npm will automatically install it for them. ```shell npm i element-theme -g ``` Then install the chalk theme from npm or GitHub. ```shell # from npm npm i element-theme-chalk -D # from GitHub npm i https://github.com/ElementUI/theme-chalk -D ``` #### Initialize variable file After successfully installing the above packages, a command named `et` is available in CLI (if the packages are installed locally, use `node_modules/.bin/et` instead). Run `-i` to initialize the variable file which outputs to `element-variables.scss` by default. And you can specify its output directory as you will. ```shell et -i [custom output file] > ✔ Generator variables file ``` In `element-variables.scss` you can find all the variables we used to style Element and they are defined in SCSS format. Here's a snippet: ```css $--color-primary: #409EFF !default; $--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */ $--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */ $--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */ $--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */ $--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */ $--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */ $--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */ $--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */ $--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */ $--color-success: #67c23a !default; $--color-warning: #e6a23c !default; $--color-danger: #f56c6c !default; $--color-info: #909399 !default; ... ``` #### Modify variables Just edit `element-variables.scss`, e.g. changing the theme color to red: ```CSS $--color-primary: red; ``` #### Build theme After saving the variable file, use `et` to build your theme. You can activate `watch` mode by adding a parameter `-w`. And if you customized the variable file's output, you need to add a parameter `-c` and variable file's name. By default the build theme file is placed inside `./theme`. You can specify its output directory with parameter `-o`. ```shell et > ✔ build theme font > ✔ build element theme ``` ### Use custom theme #### Import custom theme Importing your own theme is just like importing the default theme, only this time you import the file built from "Online Theme Roller" or "CLI tool": ```javascript import '../theme/index.css' import ElementUI from 'element-ui' import Vue from 'vue' Vue.use(ElementUI) ``` #### Import component theme on demand If you are using `babel-plugin-component` for on-demand import, just modify `.babelrc` and specify `styleLibraryName` to the path where your custom theme is located relative to `.babelrc`. Note that `~` is required: ```json { "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "~theme" } ] ] } ``` If you are unfamiliar with `babel-plugin-component`, please refer to Quick Start. For more details, check out the [project repository](https://github.com/ElementUI/element-theme) of `element-theme`. ================================================ FILE: examples/docs/en-US/date-picker.md ================================================ ## DatePicker Use Date Picker for date input. ### Enter Date Basic date picker measured by 'day'. :::demo The measurement is determined by the `type` attribute. You can enable quick options by creating a `picker-options` object with `shortcuts` property. The disabled date is set by `disabledDate`, which is a function. ```html ``` ::: ### Other measurements You can choose week, month, year or multiple dates by extending the standard date picker component. :::demo ```html
Week
Month
Year
Dates
months
years
``` ::: ### Date Range Picking a date range is supported. :::demo When in range mode, the left and right panels are linked by default. If you want the two panels to switch current months independently, you can use the `unlink-panels` attribute. ```html ``` ::: ### Month Range Picking a month range is supported. :::demo When in range mode, the left and right panels are linked by default. If you want the two panels to switch current years independently, you can use the `unlink-panels` attribute. ```html ``` ::: ### Default Value If user hasn't picked a date, shows today's calendar by default. You can use `default-value` to set another date. Its value should be parsable by `new Date()`. If type is `daterange`, `default-value` sets the left side calendar. :::demo ```html ``` ::: ### Date Formats Use `format` to control displayed text's format in the input box. Use `value-format` to control binding value's format. By default, the component accepts and emits a `Date` object. Below are supported format strings, using UTC 2017-01-02 03:04:05 as an example: :::warning Pay attention to capitalization ::: | format | meaning | note | example | |------|------|------|------|------| | `yyyy` | year | | 2017 | | `M` | month | no leading 0 | 1 | | `MM` | month | | 01 | | `MMM` | month | | Jan | | `MMMM` | month | | January | | `W` | week | only for week picker's `format`; no leading 0 | 1 | | `WW` | week | only for week picker's `format`| 01 | | `d` | day | no leading 0 | 2 | | `dd` | day | | 02 | | `H` | hour | 24-hour clock; no leading 0 | 3 | | `HH` | hour | 24-hour clock | 03 | | `h` | hour | 12-hour clock; must be used with `A` or `a`; no leading 0 | 3 | | `hh` | hour | 12-hour clock; must be used with `A` or `a` | 03 | | `m` | minute | no leading 0 | 4 | | `mm` | minute | | 04 | | `s` | second | no leading 0 | 5 | | `ss` | second | | 05 | | `A` | AM/PM | only for `format`, uppercased | AM | | `a` | am/pm | only for `format`, lowercased | am | | `timestamp` | JS timestamp | only for `value-format`; binding value will be a `number` | 1483326245000 | | `[MM]` | No escape characters | To escape characters, wrap them in square brackets (e.g. [A] [MM]) | MM | :::demo ```html ``` ::: ### Default time for start date and end date When picking a date range, you can assign the time part for start date and end date. :::demo By default, the time part of start date and end date are both `00:00:00`. Setting `default-time` can change their time respectively. It accepts an array of up to two strings with the format of `12:00:00`. The first string sets the time for the start date, and the second for the end date. ```html ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | value / v-model | binding value | date(DatePicker) / array(DateRangePicker) | — | — | | readonly | whether DatePicker is read only | boolean | — | false | | disabled | whether DatePicker is disabled | boolean | — | false | | size | size of Input | string | large/small/mini | — | | editable | whether the input is editable | boolean | — | true | | clearable | whether to show clear button | boolean | — | true | | placeholder | placeholder in non-range mode | string | — | — | | start-placeholder | placeholder for the start date in range mode | string | — | — | | end-placeholder | placeholder for the end date in range mode | string | — | — | | type | type of the picker | string | year/month/date/dates/months/years/datetime/ week/datetimerange/daterange/ monthrange | date | | format | format of the displayed value in the input box | string | see [date formats](#/en-US/component/date-picker#date-formats) | yyyy-MM-dd | | align | alignment | left/center/right | left | | popper-class | custom class name for DatePicker's dropdown | string | — | — | | picker-options | additional options, check the table below | object | — | {} | | range-separator | range separator | string | — | '-' | | default-value | optional, default date of the calendar | Date | anything accepted by `new Date()` | — | | default-time | optional, the time value to use when selecting date range | string[] | Array with length 2, each item is a string like `12:00:00`. The first item for the start date and then second item for the end date | — | | value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | see [date formats](#/en-US/component/date-picker#date-formats) | — | | name | same as `name` in native input | string | — | — | | unlink-panels | unlink two date-panels in range-picker | boolean | — | false | | prefix-icon | Custom prefix icon class | string | — | el-icon-date | | clear-icon | Custom clear icon class | string | — | el-icon-circle-close | | validate-event | whether to trigger form validation | boolean | - | true | | append-to-body | whether to append DatePicker itself to body | boolean | — | true | ### Picker Options | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | shortcuts | a { text, onClick } object array to set shortcut options, check the table below | object[] | — | — | | disabledDate | a function determining if a date is disabled with that date as its parameter. Should return a Boolean | function | — | — | | cellClassName | set custom className | Function(Date) | — | — | | firstDayOfWeek | first day of week | Number | 1 to 7 | 7 | | onPick | a callback that triggers when the selected date is changed. Only for `daterange` and `datetimerange`. | Function({ maxDate, minDate }) | - | - | ### shortcuts | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | text | title of the shortcut | string | — | — | | onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — | ### Events | Event Name | Description | Parameters | |---------|--------|---------| | change | triggers when user confirms the value | component's binding value | | blur | triggers when Input blurs | component instance | | focus | triggers when Input focuses | component instance | ### Methods | Method | Description | Parameters | |------|--------|-------| | focus | focus the Input component | — | ### Slots | Name | Description | |---------|-------------| | range-separator | custom range separator content | ================================================ FILE: examples/docs/en-US/datetime-picker.md ================================================ ## DateTimePicker Select date and time in one picker. :::tip DateTimePicker is derived from DatePicker and TimePicker. For a more detailed explanation on `pickerOptions` and other attributes, you can refer to DatePicker and TimePicker. ::: ### Date and time :::demo You can select date and time in one picker at the same time by setting `type` to `datetime`. The way to use shortcuts is the same as Date Picker. ```html ``` ::: ### Date and time range :::demo You can select date and time range by setting `type` to `datetimerange`. ```html ``` ::: ### Default time value for start date and end date :::demo When picking date range on the date panel with type `datetimerange`, `00:00:00` will be used as the default time value for start and end date. We can control it with the `default-time` attribute. `default-time` accepts an array of up to two strings. The first item controls time value of the start date and the second item controls time value of the end date. ```html ``` ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | value / v-model | binding value | date(DateTimePicker) / array(DateTimeRangePicker) | — | — | | readonly | whether DatePicker is read only | boolean | — | false | | disabled | whether DatePicker is disabled | boolean | — | false | | editable | whether the input is editable | boolean | — | true | | clearable | whether to show clear button | boolean | — | true | |size | size of Input | string | large/small/mini | — | | placeholder | placeholder in non-range mode | string | — | — | | start-placeholder | placeholder for the start date in range mode | string | — | — | | end-placeholder | placeholder for the end date in range mode | string | — | — | | time-arrow-control | whether to pick time using arrow buttons | boolean | — | false | | type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date | | format | format of the displayed value in the input box | string | see [date formats](#/en-US/component/date-picker#date-formats) | yyyy-MM-dd HH:mm:ss | | align | alignment | left/center/right | left | | popper-class | custom class name for DateTimePicker's dropdown | string | — | — | | picker-options | additional options, check the table below | object | — | {} | | range-separator | range separator | string | - | '-' | | default-value | optional, default date of the calendar | Date | anything accepted by `new Date()` | — | | default-time | the default time value after picking a date | non-range: string / range: string[] | non-range: a string like `12:00:00`, range: array of two strings, and the first item is for the start date and second for the end date. `00:00:00` will be used if not specified | — | | value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | see [date formats](#/en-US/component/date-picker#date-formats) | — | | name | same as `name` in native input | string | — | — | | unlink-panels | unlink two date-panels in range-picker | boolean | — | false | | prefix-icon | Custom prefix icon class | string | — | el-icon-date | | clear-icon | Custom clear icon class | string | — | el-icon-circle-close | ### Picker Options | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | shortcuts | a { text, onClick } object array to set shortcut options, check the table below | object[] | — | — | | disabledDate | a function determining if a date is disabled with that date as its parameter. Should return a Boolean | function | — | — | | cellClassName | set custom className | Function(Date) | — | — | | firstDayOfWeek | first day of week | Number | 1 to 7 | 7 | ### shortcuts | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | text | title of the shortcut | string | — | — | | onClick | callback function, triggers when the shortcut is clicked, with the `vm` as its parameter. You can change the picker value by emitting the `pick` event. Example: `vm.$emit('pick', new Date())`| function | — | — | ### Events | Event Name | Description | Parameters | |---------|--------|---------| | change | triggers when user confirms the value | component's binding value | | blur | triggers when Input blurs | component instance | | focus | triggers when Input focuses | component instance | ### Methods | Method | Description | Parameters | |------|--------|-------| | focus | focus the Input component | — | ================================================ FILE: examples/docs/en-US/descriptions.md ================================================ ## Descriptions Display multiple fields in list form. ### Basic usage :::demo ```html kooriookami 18100000000 Suzhou School No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province ``` ::: ### Sizes :::demo ```html ``` ::: ### Vertical List :::demo ```html kooriookami 18100000000 Suzhou School No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province kooriookami 18100000000 Suzhou School No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province ``` ::: ### Customized Style :::demo ```html kooriookami 18100000000 Suzhou School No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province ``` ::: ### Descriptions Attributes | Attribute | Description | Type | Accepted Values | Default | |------------- |---------------- |---------------- |---------------------- |-------- | | border | with or without border | boolean | — | false | | column | numbers of `Descriptions Item` in one line | number | — | 3 | | direction | direction of list | string | vertical / horizontal | horizontal | | size | size of list | string | medium / small / mini | — | | title | title text, display on the top left | string | — | — | | extra | extra text, display on the top right | string | — | — | | colon | change default props colon value of Descriptions Item | boolean | — | true | | labelClassName | custom label class name | string | — | — | | contentClassName | custom content class name | string | — | — | | labelStyle | custom label style | object | — | — | | contentStyle | custom content style | object | — | — | ### Descriptions Slots | Name | Description | |------|--------| | title | custom title, display on the top left | | extra | custom extra area, display on the top right | ### Descriptions Item Attributes | Attribute | Description | Type | Accepted Values | Default | |------------- |---------------- |---------------- |---------------------- |-------- | | label | label text | string | — | — | | span | colspan of column | number | — | 1 | | labelClassName | custom label class name | string | — | — | | contentClassName | custom content class name | string | — | — | | labelStyle | custom label style | object | — | — | | contentStyle | custom content style | object | — | — | ### Descriptions Item Slots | Name | Description | |------|--------| | label | custom label | ================================================ FILE: examples/docs/en-US/dialog.md ================================================ ## Dialog Informs users while preserving the current page state. ### Basic usage Dialog pops up a dialog box, and it's quite customizable. :::demo Set the `visible` attribute with a `Boolean`, and Dialog shows when it is `true`. The Dialog has two parts: `body` and `footer`, and the latter requires a `slot` named `footer`. The optional `title` attribute (empty by default) is for defining a title. Finally, this example demonstrates how `before-close` is used. ```html click to open the Dialog This is a message Cancel Confirm ``` ::: :::tip `before-close` only works when user clicks the close icon or the backdrop. If you have buttons that close the Dialog in the `footer` named slot, you can add what you would do with `before-close` in the buttons' click event handler. ::: ### Customizations The content of Dialog can be anything, even a table or a form. This example shows how to use Element Table and Form with Dialog。 :::demo ```html open a Table nested Dialog open a Form nested Dialog Cancel Confirm ``` ::: ### Nested Dialog If a Dialog is nested in another Dialog, `append-to-body` is required. :::demo Normally we do not recommend using nested Dialog. If you need multiple Dialogs rendered on the page, you can simply flat them so that they're siblings to each other. If you must nest a Dialog inside another Dialog, set `append-to-body` of the nested Dialog to true, and it will append to body instead of its parent node, so both Dialogs can be correctly rendered. ```html ``` ::: ### Centered content Dialog's content can be centered. :::demo Setting `center` to `true` will center dialog's header and footer horizontally. `center` only affects Dialog's header and footer. The body of Dialog can be anything, so sometimes it may not look good when centered. You need to write some CSS if you wish to center the body as well. ```html Click to open the Dialog It should be noted that the content will not be aligned in center by default Cancel Confirm ``` ::: :::tip The content of Dialog is lazily rendered, which means the default slot is not rendered onto the DOM until it is firstly opened. Therefore, if you need to perform a DOM manipulation or access a component using `ref`, do it in the `open` event callback. ::: :::tip If the variable bound to `visible` is managed in Vuex store, the `.sync` can not work properly. In this case, please remove the `.sync` modifier, listen to `open` and `close` events of Dialog, and commit Vuex mutations to update the value of that variable in the event handlers. ::: ### Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | visible | visibility of Dialog, supports the .sync modifier | boolean | — | false | | title | title of Dialog. Can also be passed with a named slot (see the following table) | string | — | — | | width | width of Dialog | string | — | 50% | | fullscreen | whether the Dialog takes up full screen | boolean | — | false | | top | value for `margin-top` of Dialog CSS | string | — | 15vh | | modal | whether a mask is displayed | boolean | — | true | | modal-append-to-body | whether to append modal to body element. If false, the modal will be appended to Dialog's parent element | boolean | — | true | | append-to-body | whether to append Dialog itself to body. A nested Dialog should have this attribute set to `true` | boolean | — | false | | lock-scroll | whether scroll of body is disabled while Dialog is displayed | boolean | — | true | | custom-class | custom class names for Dialog | string | — | — | | close-on-click-modal | whether the Dialog can be closed by clicking the mask | boolean | — | true | | close-on-press-escape | whether the Dialog can be closed by pressing ESC | boolean | — | true | | show-close | whether to show a close button | boolean | — | true | | before-close | callback before Dialog closes, and it will prevent Dialog from closing | function(done),done is used to close the Dialog | — | — | | center | whether to align the header and footer in center | boolean | — | false | | destroy-on-close | Destroy elements in Dialog when closed | boolean | — | false | ### Slot | Name | Description | |------|--------| | — | content of Dialog | | title | content of the Dialog title | | footer | content of the Dialog footer | ### Events | Event Name | Description | Parameters | |---------- |-------- |---------- | | open | triggers when the Dialog opens | — | | opened | triggers when the Dialog opening animation ends | — | | close | triggers when the Dialog closes | — | | closed | triggers when the Dialog closing animation ends | — | ================================================ FILE: examples/docs/en-US/divider.md ================================================ ## Divider The dividing line that separates the content. ### Basic usage Divide the text of different paragraphs. :::demo ```html ``` ::: ### Custom content You can customize the content on the divider line. :::demo ```html ``` ::: ### Vertical divider :::demo ```html ``` ::: ### Divider Attributes | Attribute | Description | Type | Accepted Values | Default | |------------- |---------------- |---------------- |---------------------- |-------- | | direction | Set divider's direction | string | horizontal / vertical | horizontal | | content-position | customize the content on the divider line | String | left / right / center | center | ================================================ FILE: examples/docs/en-US/drawer.md ================================================ ## Drawer Sometimes, `Dialog` does not always satisfy our requirements, let's say you have a massive form, or you need space to display something like `terms & conditions`, `Drawer` has almost identical API with `Dialog`, but it introduces different user experience. ### Basic Usage Callout a temporary drawer, from multiple direction :::demo You must set `visible` for `Drawer` like `Dialog` does to control the visibility of `Drawer` itself, it's `boolean` type. `Drawer` has to parts: `title` & `body`, the `title` is a named slot, you can also set the title through attribute named `title`, default to an empty string, the `body` part is the main area of `Drawer`, which contains user defined content. When opening, `Drawer` expand itself from the **right corner to left** which size is **30%** of the browser window by default. You can change that default behavior by setting `direction` and `size` attribute. This show case also demonstrated how to use the `before-close` API, check the Attribute section for more detail ```html left to right right to left top to bottom bottom to top open Hi, there! ``` ::: ### No Title When you no longer need a title, you can remove title from drawer. :::demo Set the `withHeader` attribute to **false**, you can remove the title from drawer, thus your drawer can have more space on screen. If you want to be accessible, make sure to set the `title` attribute. ```html open Hi there! ``` ::: ### Customization Content Like `Dialog`, `Drawer` can do many diverse interaction as you wanted. :::demo ```html Open Drawer with nested table Open Drawer with nested form
``` ::: ### Nested Drawer You can also have multiple layer of `Drawer` just like `Dialog`. :::demo If you need multiple Drawer in different layer, you must set the `append-to-body` attribute to **true** ```html open
Click me!

_(:зゝ∠)_

``` ::: :::tip The content inside Drawer should be lazy rendered, which means that the content inside Drawer will not impact the initial render performance, therefore any DOM operation should be performed through `ref` or after `open` event emitted. ::: :::tip Drawer provides an API called `destroyOnClose`, which is a flag variable that indicates should destroy the children content inside Drawer after Drawer was closed. You can use this API when you need your `mounted` life cycle to be called every time the Drawer opens. ::: :::tip If the variable bound to `visible` is managed in Vuex store, the `.sync` can not work properly. In this case, please remove the `.sync` modifier, listen to `open` and `close` events of Dialog, and commit Vuex mutations to update the value of that variable in the event handlers. ::: ### Drawer Attributes | Parameter| Description | Type | Acceptable Values | Defaults | |---------- |-------------- |---------- |-------------------------------- |-------- | | append-to-body | Controls should Drawer be inserted to DocumentBody Element, nested Drawer must assign this param to **true**| boolean | — | false | | before-close | If set, closing procedure will be halted | function(done), done is function type that accepts a boolean as parameter, calling done with true or without parameter will abort the close procedure | — | — | | close-on-press-escape | Indicates whether Drawer can be closed by pressing ESC | boolean | — | true | | custom-class | Extra class names for Drawer | string | — | — | | destroy-on-close | Indicates whether children should be destroyed after Drawer closed | boolean | - | false | | modal | Should show shadowing layer | boolean | — | true | | modal-append-to-body | Indicates should shadowing layer be insert into DocumentBody element | boolean | — | true | | direction | Drawer's opening direction | Direction | rtl / ltr / ttb / btt | rtl | | show-close | Should show close button at the top right of Drawer | boolean | — | true | | size | Drawer's size, if Drawer is horizontal mode, it effects the width property, otherwise it effects the height property, when size is `number` type, it describes the size by unit of pixels; when size is `string` type, it should be used with `x%` notation, other wise it will be interpreted to pixel unit | number / string | - | '30%' | | title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — | | visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false | | wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true | | withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true | ### Drawer Slot | Name | Description | |------|--------| | — | Drawer's Content | | title | Drawer Title Section | ### Drawer Methods | Name | Description | | ---- | --- | | closeDrawer | In order to close Drawer, this method will call `before-close`. | ### Drawer Events | Event Name | Description | Parameter | |---------- |-------- |---------- | | open | Triggered before Drawer opening animation begins | — | | opened | Triggered after Drawer opening animation ended | — | | close | Triggered before Drawer closing animation begins | — | | closed | Triggered after Drawer closing animation ended | — | ================================================ FILE: examples/docs/en-US/dropdown.md ================================================ ## Dropdown Toggleable menu for displaying lists of links and actions. ### Basic usage Hover on the dropdown menu to unfold it for more actions. :::demo The triggering element is rendered by the default `slot`, and the dropdown part is rendered by the `slot` named `dropdown`. By default, dropdown list shows when you hover on the triggering element without having to click it. ```html Dropdown List Action 1 Action 2 Action 3 Action 4 Action 5 ``` ::: ### Triggering element Use the button to trigger the dropdown list. :::demo Use `split-button` to split the triggering element into a button group with the left button being a normal button and right one the actual triggering target. If you wanna insert a separator line between item three and item four, just add a class `divider` to item four. ```html Dropdown List Action 1 Action 2 Action 3 Action 4 Action 5 Dropdown List Action 1 Action 2 Action 3 Action 4 Action 5 ``` ::: ### How to trigger Click the triggering element or hover on it. :::demo Use the attribute `trigger`. By default, it is `hover`. ```html hover to trigger Dropdown List Action 1 Action 2 Action 3 Action 4 Action 5 click to trigger Dropdown List Action 1 Action 2 Action 3 Action 4 Action 5 ``` ::: ### Menu hiding behavior Use `hide-on-click` to define if menu closes on clicking. :::demo By default menu will close when you click on menu items, and it can be turned off by setting hide-on-click to false. ```html Dropdown List Action 1 Action 2 Action 3 Action 4 Action 5 ``` ::: ### Command event Clicking each dropdown item fires an event whose parameter is assigned by each item. :::demo ```html Dropdown List Action 1 Action 2 Action 3 Action 4 Action 5 ``` ::: ### Sizes Besides default size, Dropdown component provides three additional sizes for you to choose among different scenarios. :::demo Use attribute `size` to set additional sizes with `medium`, `small` or `mini`. ```html Default Action 1 Action 2 Action 3 Action 4 Medium Action 1 Action 2 Action 3 Action 4 Small Action 1 Action 2 Action 3 Action 4 Mini Action 1 Action 2 Action 3 Action 4 ``` ::: ### Dropdown Attributes | Attribute | Description | Type | Accepted Values | Default | |------------- |---------------- |---------------- |---------------------- |-------- | | type | menu button type, refer to `Button` Component, only works when `split-button` is true | string | — | — | | size | menu size, also works on the split button | string | medium / small / mini | — | | split-button | whether a button group is displayed | boolean | — | false | | placement | placement of pop menu | string | top/top-start/top-end/bottom/bottom-start/bottom-end | bottom-end | | trigger | how to trigger | string | hover/click | hover | | hide-on-click | whether to hide menu after clicking menu-item | boolean | — | true | | show-timeout | Delay time before show a dropdown (only works when trigger is `hover`) | number | — | 250 | | hide-timeout | Delay time before hide a dropdown (only works when trigger is `hover`) | number | — | 150 | | tabindex | [tabindex](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of Dropdown | number | — | 0 | | disabled | whether the Dropdown is disabled | boolean | — | false | ### Dropdown Slots | Name | Description | |------|--------| | — | content of Dropdown. Notice: Must be a valid html dom element (ex. `, ); } }, Next: { render(h) { return ( ); } }, Sizes: { mixins: [Locale], props: { pageSizes: Array }, watch: { pageSizes: { immediate: true, handler(newVal, oldVal) { if (valueEquals(newVal, oldVal)) return; if (Array.isArray(newVal)) { this.$parent.internalPageSize = newVal.indexOf(this.$parent.pageSize) > -1 ? this.$parent.pageSize : this.pageSizes[0]; } } } }, render(h) { return ( { this.pageSizes.map(item => ) } ); }, components: { ElSelect, ElOption }, methods: { handleChange(val) { if (val !== this.$parent.internalPageSize) { this.$parent.internalPageSize = val = parseInt(val, 10); this.$parent.userChangePageSize = true; this.$parent.$emit('update:pageSize', val); this.$parent.$emit('size-change', val); } } } }, Jumper: { mixins: [Locale], components: { ElInput }, data() { return { userInput: null }; }, watch: { '$parent.internalCurrentPage'() { this.userInput = null; } }, methods: { handleKeyup({ keyCode, target }) { // Chrome, Safari, Firefox triggers change event on Enter // Hack for IE: https://github.com/ElemeFE/element/issues/11710 // Drop this method when we no longer supports IE if (keyCode === 13) { this.handleChange(target.value); } }, handleInput(value) { this.userInput = value; }, handleChange(value) { this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(value); this.$parent.emitChange(); this.userInput = null; } }, render(h) { return ( { this.t('el.pagination.goto') } { this.t('el.pagination.pageClassifier') } ); } }, Total: { mixins: [Locale], render(h) { return ( typeof this.$parent.total === 'number' ? { this.t('el.pagination.total', { total: this.$parent.total }) } : '' ); } }, Pager }, methods: { handleCurrentChange(val) { this.internalCurrentPage = this.getValidCurrentPage(val); this.userChangePageSize = true; this.emitChange(); }, prev() { if (this.disabled) return; const newVal = this.internalCurrentPage - 1; this.internalCurrentPage = this.getValidCurrentPage(newVal); this.$emit('prev-click', this.internalCurrentPage); this.emitChange(); }, next() { if (this.disabled) return; const newVal = this.internalCurrentPage + 1; this.internalCurrentPage = this.getValidCurrentPage(newVal); this.$emit('next-click', this.internalCurrentPage); this.emitChange(); }, getValidCurrentPage(value) { value = parseInt(value, 10); const havePageCount = typeof this.internalPageCount === 'number'; let resetValue; if (!havePageCount) { if (isNaN(value) || value < 1) resetValue = 1; } else { if (value < 1) { resetValue = 1; } else if (value > this.internalPageCount) { resetValue = this.internalPageCount; } } if (resetValue === undefined && isNaN(value)) { resetValue = 1; } else if (resetValue === 0) { resetValue = 1; } return resetValue === undefined ? value : resetValue; }, emitChange() { this.$nextTick(() => { if (this.internalCurrentPage !== this.lastEmittedPage || this.userChangePageSize) { this.$emit('current-change', this.internalCurrentPage); this.lastEmittedPage = this.internalCurrentPage; this.userChangePageSize = false; } }); } }, computed: { internalPageCount() { if (typeof this.total === 'number') { return Math.max(1, Math.ceil(this.total / this.internalPageSize)); } else if (typeof this.pageCount === 'number') { return Math.max(1, this.pageCount); } return null; } }, watch: { currentPage: { immediate: true, handler(val) { this.internalCurrentPage = this.getValidCurrentPage(val); } }, pageSize: { immediate: true, handler(val) { this.internalPageSize = isNaN(val) ? 10 : val; } }, internalCurrentPage: { immediate: true, handler(newVal) { this.$emit('update:currentPage', newVal); this.lastEmittedPage = -1; } }, internalPageCount(newVal) { /* istanbul ignore if */ const oldPage = this.internalCurrentPage; if (newVal > 0 && oldPage === 0) { this.internalCurrentPage = 1; } else if (oldPage > newVal) { this.internalCurrentPage = newVal === 0 ? 1 : newVal; this.userChangePageSize && this.emitChange(); } this.userChangePageSize = false; } } }; ================================================ FILE: packages/popconfirm/index.js ================================================ import Popconfirm from './src/main'; /* istanbul ignore next */ Popconfirm.install = function(Vue) { Vue.component(Popconfirm.name, Popconfirm); }; export default Popconfirm; ================================================ FILE: packages/popconfirm/src/main.vue ================================================ ================================================ FILE: packages/popover/index.js ================================================ import Popover from './src/main'; import directive from './src/directive'; import Vue from 'vue'; Vue.directive('popover', directive); /* istanbul ignore next */ Popover.install = function(Vue) { Vue.directive('popover', directive); Vue.component(Popover.name, Popover); }; Popover.directive = directive; export default Popover; ================================================ FILE: packages/popover/src/directive.js ================================================ const getReference = (el, binding, vnode) => { const _ref = binding.expression ? binding.value : binding.arg; const popper = vnode.context.$refs[_ref]; if (popper) { if (Array.isArray(popper)) { popper[0].$refs.reference = el; } else { popper.$refs.reference = el; } } }; export default { bind(el, binding, vnode) { getReference(el, binding, vnode); }, inserted(el, binding, vnode) { getReference(el, binding, vnode); } }; ================================================ FILE: packages/popover/src/main.vue ================================================ ================================================ FILE: packages/progress/index.js ================================================ import ElProgress from './src/progress'; /* istanbul ignore next */ ElProgress.install = function(Vue) { Vue.component(ElProgress.name, ElProgress); }; export default ElProgress; ================================================ FILE: packages/progress/src/progress.vue ================================================ ================================================ FILE: packages/radio/index.js ================================================ import Radio from './src/radio'; /* istanbul ignore next */ Radio.install = function(Vue) { Vue.component(Radio.name, Radio); }; export default Radio; ================================================ FILE: packages/radio/src/radio-button.vue ================================================ ================================================ FILE: packages/radio/src/radio-group.vue ================================================ ================================================ FILE: packages/radio/src/radio.vue ================================================ ================================================ FILE: packages/radio-button/index.js ================================================ import RadioButton from '../radio/src/radio-button.vue'; /* istanbul ignore next */ RadioButton.install = function(Vue) { Vue.component(RadioButton.name, RadioButton); }; export default RadioButton; ================================================ FILE: packages/radio-group/index.js ================================================ import RadioGroup from '../radio/src/radio-group.vue'; /* istanbul ignore next */ RadioGroup.install = function(Vue) { Vue.component(RadioGroup.name, RadioGroup); }; export default RadioGroup; ================================================ FILE: packages/rate/index.js ================================================ import Rate from './src/main'; /* istanbul ignore next */ Rate.install = function(Vue) { Vue.component(Rate.name, Rate); }; export default Rate; ================================================ FILE: packages/rate/src/main.vue ================================================ ================================================ FILE: packages/result/index.js ================================================ import Result from './src/index.vue'; /* istanbul ignore next */ Result.install = function(Vue) { Vue.component(Result.name, Result); }; export default Result; ================================================ FILE: packages/result/src/icon-error.vue ================================================ ================================================ FILE: packages/result/src/icon-info.vue ================================================ ================================================ FILE: packages/result/src/icon-success.vue ================================================ ================================================ FILE: packages/result/src/icon-warning.vue ================================================ ================================================ FILE: packages/result/src/index.vue ================================================ ================================================ FILE: packages/row/index.js ================================================ import Row from './src/row'; /* istanbul ignore next */ Row.install = function(Vue) { Vue.component(Row.name, Row); }; export default Row; ================================================ FILE: packages/row/src/row.js ================================================ export default { name: 'ElRow', componentName: 'ElRow', props: { tag: { type: String, default: 'div' }, gutter: Number, type: String, justify: { type: String, default: 'start' }, align: String }, computed: { style() { const ret = {}; if (this.gutter) { ret.marginLeft = `-${this.gutter / 2}px`; ret.marginRight = ret.marginLeft; } return ret; } }, render(h) { return h(this.tag, { class: [ 'el-row', this.justify !== 'start' ? `is-justify-${this.justify}` : '', this.align ? `is-align-${this.align}` : '', { 'el-row--flex': this.type === 'flex' } ], style: this.style }, this.$slots.default); } }; ================================================ FILE: packages/scrollbar/index.js ================================================ import Scrollbar from './src/main'; /* istanbul ignore next */ Scrollbar.install = function(Vue) { Vue.component(Scrollbar.name, Scrollbar); }; export default Scrollbar; ================================================ FILE: packages/scrollbar/src/bar.js ================================================ import { on, off } from 'element-ui/src/utils/dom'; import { renderThumbStyle, BAR_MAP } from './util'; /* istanbul ignore next */ export default { name: 'Bar', props: { vertical: Boolean, size: String, move: Number }, computed: { bar() { return BAR_MAP[this.vertical ? 'vertical' : 'horizontal']; }, wrap() { return this.$parent.wrap; } }, render(h) { const { size, move, bar } = this; return (
); }, methods: { clickThumbHandler(e) { // prevent click event of right button if (e.ctrlKey || e.button === 2) { return; } this.startDrag(e); this[this.bar.axis] = (e.currentTarget[this.bar.offset] - (e[this.bar.client] - e.currentTarget.getBoundingClientRect()[this.bar.direction])); }, clickTrackHandler(e) { const offset = Math.abs(e.target.getBoundingClientRect()[this.bar.direction] - e[this.bar.client]); const thumbHalf = (this.$refs.thumb[this.bar.offset] / 2); const thumbPositionPercentage = ((offset - thumbHalf) * 100 / this.$el[this.bar.offset]); this.wrap[this.bar.scroll] = (thumbPositionPercentage * this.wrap[this.bar.scrollSize] / 100); }, startDrag(e) { e.stopImmediatePropagation(); this.cursorDown = true; on(document, 'mousemove', this.mouseMoveDocumentHandler); on(document, 'mouseup', this.mouseUpDocumentHandler); document.onselectstart = () => false; }, mouseMoveDocumentHandler(e) { if (this.cursorDown === false) return; const prevPage = this[this.bar.axis]; if (!prevPage) return; const offset = ((this.$el.getBoundingClientRect()[this.bar.direction] - e[this.bar.client]) * -1); const thumbClickPosition = (this.$refs.thumb[this.bar.offset] - prevPage); const thumbPositionPercentage = ((offset - thumbClickPosition) * 100 / this.$el[this.bar.offset]); this.wrap[this.bar.scroll] = (thumbPositionPercentage * this.wrap[this.bar.scrollSize] / 100); }, mouseUpDocumentHandler(e) { this.cursorDown = false; this[this.bar.axis] = 0; off(document, 'mousemove', this.mouseMoveDocumentHandler); document.onselectstart = null; } }, destroyed() { off(document, 'mouseup', this.mouseUpDocumentHandler); } }; ================================================ FILE: packages/scrollbar/src/main.js ================================================ // reference https://github.com/noeldelgado/gemini-scrollbar/blob/master/index.js import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'; import scrollbarWidth from 'element-ui/src/utils/scrollbar-width'; import { toObject } from 'element-ui/src/utils/util'; import Bar from './bar'; /* istanbul ignore next */ export default { name: 'ElScrollbar', components: { Bar }, props: { native: Boolean, wrapStyle: {}, wrapClass: {}, viewClass: {}, viewStyle: {}, noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能 tag: { type: String, default: 'div' } }, data() { return { sizeWidth: '0', sizeHeight: '0', moveX: 0, moveY: 0 }; }, computed: { wrap() { return this.$refs.wrap; } }, render(h) { let gutter = scrollbarWidth(); let style = this.wrapStyle; if (gutter) { const gutterWith = `-${gutter}px`; const gutterStyle = `margin-bottom: ${gutterWith}; margin-right: ${gutterWith};`; if (Array.isArray(this.wrapStyle)) { style = toObject(this.wrapStyle); style.marginRight = style.marginBottom = gutterWith; } else if (typeof this.wrapStyle === 'string') { style += gutterStyle; } else { style = gutterStyle; } } const view = h(this.tag, { class: ['el-scrollbar__view', this.viewClass], style: this.viewStyle, ref: 'resize' }, this.$slots.default); const wrap = (
{ [view] }
); let nodes; if (!this.native) { nodes = ([ wrap, , ]); } else { nodes = ([
{ [view] }
]); } return h('div', { class: 'el-scrollbar' }, nodes); }, methods: { handleScroll() { const wrap = this.wrap; this.moveY = ((wrap.scrollTop * 100) / wrap.clientHeight); this.moveX = ((wrap.scrollLeft * 100) / wrap.clientWidth); }, update() { let heightPercentage, widthPercentage; const wrap = this.wrap; if (!wrap) return; heightPercentage = (wrap.clientHeight * 100 / wrap.scrollHeight); widthPercentage = (wrap.clientWidth * 100 / wrap.scrollWidth); this.sizeHeight = (heightPercentage < 100) ? (heightPercentage + '%') : ''; this.sizeWidth = (widthPercentage < 100) ? (widthPercentage + '%') : ''; } }, mounted() { if (this.native) return; this.$nextTick(this.update); !this.noresize && addResizeListener(this.$refs.resize, this.update); }, beforeDestroy() { if (this.native) return; !this.noresize && removeResizeListener(this.$refs.resize, this.update); } }; ================================================ FILE: packages/scrollbar/src/util.js ================================================ export const BAR_MAP = { vertical: { offset: 'offsetHeight', scroll: 'scrollTop', scrollSize: 'scrollHeight', size: 'height', key: 'vertical', axis: 'Y', client: 'clientY', direction: 'top' }, horizontal: { offset: 'offsetWidth', scroll: 'scrollLeft', scrollSize: 'scrollWidth', size: 'width', key: 'horizontal', axis: 'X', client: 'clientX', direction: 'left' } }; export function renderThumbStyle({ move, size, bar }) { const style = {}; const translate = `translate${bar.axis}(${ move }%)`; style[bar.size] = size; style.transform = translate; style.msTransform = translate; style.webkitTransform = translate; return style; }; ================================================ FILE: packages/select/index.js ================================================ import Select from './src/select'; /* istanbul ignore next */ Select.install = function(Vue) { Vue.component(Select.name, Select); }; export default Select; ================================================ FILE: packages/select/src/navigation-mixin.js ================================================ export default { data() { return { hoverOption: -1 }; }, computed: { optionsAllDisabled() { return this.options.filter(option => option.visible).every(option => option.disabled); } }, watch: { hoverIndex(val) { if (typeof val === 'number' && val > -1) { this.hoverOption = this.options[val] || {}; } this.options.forEach(option => { option.hover = this.hoverOption === option; }); } }, methods: { navigateOptions(direction) { if (!this.visible) { this.visible = true; return; } if (this.options.length === 0 || this.filteredOptionsCount === 0) return; if (!this.optionsAllDisabled) { if (direction === 'next') { this.hoverIndex++; if (this.hoverIndex === this.options.length) { this.hoverIndex = 0; } } else if (direction === 'prev') { this.hoverIndex--; if (this.hoverIndex < 0) { this.hoverIndex = this.options.length - 1; } } const option = this.options[this.hoverIndex]; if (option.disabled === true || option.groupDisabled === true || !option.visible) { this.navigateOptions(direction); } this.$nextTick(() => this.scrollToOption(this.hoverOption)); } } } }; ================================================ FILE: packages/select/src/option-group.vue ================================================ ================================================ FILE: packages/select/src/option.vue ================================================ ================================================ FILE: packages/select/src/select-dropdown.vue ================================================ ================================================ FILE: packages/select/src/select.vue ================================================ ================================================ FILE: packages/skeleton/index.js ================================================ import Skeleton from './src/index.vue'; /* istanbul ignore next */ Skeleton.install = function(Vue) { Vue.component(Skeleton.name, Skeleton); }; export default Skeleton; ================================================ FILE: packages/skeleton/src/img-placeholder.vue ================================================ ================================================ FILE: packages/skeleton/src/index.vue ================================================ ================================================ FILE: packages/skeleton/src/item.vue ================================================ ================================================ FILE: packages/skeleton-item/index.js ================================================ import SkeletonItem from '../skeleton/src/item'; /* istanbul ignore next */ SkeletonItem.install = function(Vue) { Vue.component(SkeletonItem.name, SkeletonItem); }; export default SkeletonItem; ================================================ FILE: packages/slider/index.js ================================================ import Slider from './src/main'; /* istanbul ignore next */ Slider.install = function(Vue) { Vue.component(Slider.name, Slider); }; export default Slider; ================================================ FILE: packages/slider/src/button.vue ================================================ ================================================ FILE: packages/slider/src/main.vue ================================================ ================================================ FILE: packages/slider/src/marker.js ================================================ export default { name: 'ElMarker', props: { mark: { type: [String, Object] } }, render() { let label = typeof this.mark === 'string' ? this.mark : this.mark.label; return (
{ label }
); } }; ================================================ FILE: packages/spinner/index.js ================================================ import Spinner from './src/spinner'; /* istanbul ignore next */ Spinner.install = function(Vue) { Vue.component(Spinner.name, Spinner); }; export default Spinner; ================================================ FILE: packages/spinner/src/spinner.vue ================================================ ================================================ FILE: packages/statistic/index.js ================================================ import Statistic from './src/main'; /* istanbul ignore next */ Statistic.install = function(Vue) { Vue.component(Statistic.name, Statistic); }; export default Statistic; ================================================ FILE: packages/statistic/src/main.vue ================================================ ================================================ FILE: packages/step/index.js ================================================ import Step from '../steps/src/step'; /* istanbul ignore next */ Step.install = function(Vue) { Vue.component(Step.name, Step); }; export default Step; ================================================ FILE: packages/steps/README.md ================================================ # element-steps > A element-steps component for Vue.js. ## Demo http://element-component.github.io/element-steps ## Installation ```shell npm i element-steps -D ``` ## Usage ```javascript import Vue from 'vue' import ElStep from 'element-steps' import 'element-theme-chalk/dist/step.css' Vue.use(ElStep) ``` or ```javascript import Vue from 'vue' import { ElSteps, ElStep } from 'element-steps' Vue.component('el-steps', ElSteps) Vue.component('el-step', ElStep) ``` ### Steps Attributes | 参数 | 说明 | 类型 | 可选值 | 默认值 | |---------- |-------- |---------- |------------- |-------- | | space | 每个 step 的间距,不填写将自适应间距 | Number | — | — | | direction | 显示方向 | string | vertical/horizontal | horizontal | | active | 设置当前激活步骤 | number | — | 0 | | process-status | 设置当前步骤的状态 | string | wait/process/finish/error/success | process | | finish-status | 设置结束步骤的状态 | string | wait/process/finish/error/success | finish | | align-center | 标题描述居中对齐 | boolean | - | false | ### Step Attributes | 参数 | 说明 | 类型 | 可选值 | 默认值 | |---------- |-------- |---------- |------------- |-------- | | title | 标题 | string | — | — | | description | 描述性文字 | string | — | — | | icon | 图标 | Element Icon 提供的图标,如果要使用自定义图标可以通过 slot 方式写入 | string | — | ### Step Slot | name | 说明 | |----|----| | icon | 图标 | | title | 标题 | | description | 描述性文字 | ## Development ```shell make dev ## test make test ## build make build ``` # License [MIT](https://opensource.org/licenses/MIT) ================================================ FILE: packages/steps/index.js ================================================ import Steps from './src/steps'; /* istanbul ignore next */ Steps.install = function(Vue) { Vue.component(Steps.name, Steps); }; export default Steps; ================================================ FILE: packages/steps/src/step.vue ================================================ ================================================ FILE: packages/steps/src/steps.vue ================================================ ================================================ FILE: packages/submenu/index.js ================================================ import ElSubmenu from '../menu/src/submenu'; /* istanbul ignore next */ ElSubmenu.install = function(Vue) { Vue.component(ElSubmenu.name, ElSubmenu); }; export default ElSubmenu; ================================================ FILE: packages/switch/index.js ================================================ import Switch from './src/component'; /* istanbul ignore next */ Switch.install = function(Vue) { Vue.component(Switch.name, Switch); }; export default Switch; ================================================ FILE: packages/switch/src/component.vue ================================================ ================================================ FILE: packages/tab-pane/index.js ================================================ import TabPane from '../tabs/src/tab-pane.vue'; /* istanbul ignore next */ TabPane.install = function(Vue) { Vue.component(TabPane.name, TabPane); }; export default TabPane; ================================================ FILE: packages/table/index.js ================================================ import ElTable from './src/table'; /* istanbul ignore next */ ElTable.install = function(Vue) { Vue.component(ElTable.name, ElTable); }; export default ElTable; ================================================ FILE: packages/table/src/config.js ================================================ import { getPropByPath } from 'element-ui/src/utils/util'; export const cellStarts = { default: { order: '' }, selection: { width: 48, minWidth: 48, realWidth: 48, order: '', className: 'el-table-column--selection' }, expand: { width: 48, minWidth: 48, realWidth: 48, order: '' }, index: { width: 48, minWidth: 48, realWidth: 48, order: '' } }; // 这些选项不应该被覆盖 export const cellForced = { selection: { renderHeader: function(h, { store }) { return 0 && !this.isAllSelected } on-input={ this.toggleAllSelection } value={ this.isAllSelected } />; }, renderCell: function(h, { row, column, isSelected, store, $index }) { return event.stopPropagation() } value={ isSelected } disabled={ column.selectable ? !column.selectable.call(null, row, $index) : false } on-input={ () => { store.commit('rowSelectedChanged', row); } } />; }, sortable: false, resizable: false }, index: { renderHeader: function(h, { column }) { return column.label || '#'; }, renderCell: function(h, { $index, column }) { let i = $index + 1; const index = column.index; if (typeof index === 'number') { i = $index + index; } else if (typeof index === 'function') { i = index($index); } return
{ i }
; }, sortable: false }, expand: { renderHeader: function(h, { column }) { return column.label || ''; }, renderCell: function(h, { row, store, isExpanded }) { const classes = ['el-table__expand-icon']; if (isExpanded) { classes.push('el-table__expand-icon--expanded'); } const callback = function(e) { e.stopPropagation(); store.toggleRowExpansion(row); }; return (
); }, sortable: false, resizable: false, className: 'el-table__expand-column' } }; export function defaultRenderCell(h, { row, column, $index }) { const property = column.property; const value = property && getPropByPath(row, property).v; if (column && column.formatter) { return column.formatter(row, column, value, $index); } return value; } export function treeCellPrefix(h, { row, treeNode, store }) { if (!treeNode) return null; const ele = []; const callback = function(e) { e.stopPropagation(); store.loadOrToggle(row); }; if (treeNode.indent) { ele.push(); } if (typeof treeNode.expanded === 'boolean' && !treeNode.noLazyChildren) { const expandClasses = ['el-table__expand-icon', treeNode.expanded ? 'el-table__expand-icon--expanded' : '']; let iconClasses = ['el-icon-arrow-right']; if (treeNode.loading) { iconClasses = ['el-icon-loading']; } ele.push(
); } else { ele.push(); } return ele; } ================================================ FILE: packages/table/src/dropdown.js ================================================ import Vue from 'vue'; var dropdowns = []; !Vue.prototype.$isServer && document.addEventListener('click', function(event) { dropdowns.forEach(function(dropdown) { var target = event.target; if (!dropdown || !dropdown.$el) return; if (target === dropdown.$el || dropdown.$el.contains(target)) { return; } dropdown.handleOutsideClick && dropdown.handleOutsideClick(event); }); }); export default { open(instance) { if (instance) { dropdowns.push(instance); } }, close(instance) { var index = dropdowns.indexOf(instance); if (index !== -1) { dropdowns.splice(instance, 1); } } }; ================================================ FILE: packages/table/src/filter-panel.vue ================================================ ================================================ FILE: packages/table/src/layout-observer.js ================================================ export default { created() { this.tableLayout.addObserver(this); }, destroyed() { this.tableLayout.removeObserver(this); }, computed: { tableLayout() { let layout = this.layout; if (!layout && this.table) { layout = this.table.layout; } if (!layout) { throw new Error('Can not find table layout.'); } return layout; } }, mounted() { this.onColumnsChange(this.tableLayout); this.onScrollableChange(this.tableLayout); }, updated() { if (this.__updated__) return; this.onColumnsChange(this.tableLayout); this.onScrollableChange(this.tableLayout); this.__updated__ = true; }, methods: { onColumnsChange(layout) { const cols = this.$el.querySelectorAll('colgroup > col'); if (!cols.length) return; const flattenColumns = layout.getFlattenColumns(); const columnsMap = {}; flattenColumns.forEach((column) => { columnsMap[column.id] = column; }); for (let i = 0, j = cols.length; i < j; i++) { const col = cols[i]; const name = col.getAttribute('name'); const column = columnsMap[name]; if (column) { col.setAttribute('width', column.realWidth || column.width); } } }, onScrollableChange(layout) { const cols = this.$el.querySelectorAll('colgroup > col[name=gutter]'); for (let i = 0, j = cols.length; i < j; i++) { const col = cols[i]; col.setAttribute('width', layout.scrollY ? layout.gutterWidth : '0'); } const ths = this.$el.querySelectorAll('th.gutter'); for (let i = 0, j = ths.length; i < j; i++) { const th = ths[i]; th.style.width = layout.scrollY ? layout.gutterWidth + 'px' : '0'; th.style.display = layout.scrollY ? '' : 'none'; } } } }; ================================================ FILE: packages/table/src/store/current.js ================================================ import { arrayFind } from 'element-ui/src/utils/util'; import { getRowIdentity } from '../util'; export default { data() { return { states: { // 不可响应的,设置 currentRowKey 时,data 不一定存在,也许无法算出正确的 currentRow // 把该值缓存一下,当用户点击修改 currentRow 时,把该值重置为 null _currentRowKey: null, currentRow: null } }; }, methods: { setCurrentRowKey(key) { this.assertRowKey(); this.states._currentRowKey = key; this.setCurrentRowByKey(key); }, restoreCurrentRowKey() { this.states._currentRowKey = null; }, setCurrentRowByKey(key) { const { states } = this; const { data = [], rowKey } = states; let currentRow = null; if (rowKey) { currentRow = arrayFind(data, item => getRowIdentity(item, rowKey) === key); } states.currentRow = currentRow; }, updateCurrentRow(currentRow) { const { states, table } = this; const oldCurrentRow = states.currentRow; if (currentRow && currentRow !== oldCurrentRow) { states.currentRow = currentRow; table.$emit('current-change', currentRow, oldCurrentRow); return; } if (!currentRow && oldCurrentRow) { states.currentRow = null; table.$emit('current-change', null, oldCurrentRow); } }, updateCurrentRowData() { const { states, table } = this; const { rowKey, _currentRowKey } = states; // data 为 null 时,解构时的默认值会被忽略 const data = states.data || []; const oldCurrentRow = states.currentRow; // 当 currentRow 不在 data 中时尝试更新数据 if (data.indexOf(oldCurrentRow) === -1 && oldCurrentRow) { if (rowKey) { const currentRowKey = getRowIdentity(oldCurrentRow, rowKey); this.setCurrentRowByKey(currentRowKey); } else { states.currentRow = null; } if (states.currentRow === null) { table.$emit('current-change', null, oldCurrentRow); } } else if (_currentRowKey) { // 把初始时下设置的 rowKey 转化成 rowData this.setCurrentRowByKey(_currentRowKey); this.restoreCurrentRowKey(); } } } }; ================================================ FILE: packages/table/src/store/expand.js ================================================ import { toggleRowStatus, getKeysMap, getRowIdentity } from '../util'; export default { data() { return { states: { defaultExpandAll: false, expandRows: [] } }; }, methods: { updateExpandRows() { const { data = [], rowKey, defaultExpandAll, expandRows } = this.states; if (defaultExpandAll) { this.states.expandRows = data.slice(); } else if (rowKey) { // TODO:这里的代码可以优化 const expandRowsMap = getKeysMap(expandRows, rowKey); this.states.expandRows = data.reduce((prev, row) => { const rowId = getRowIdentity(row, rowKey); const rowInfo = expandRowsMap[rowId]; if (rowInfo) { prev.push(row); } return prev; }, []); } else { this.states.expandRows = []; } }, toggleRowExpansion(row, expanded) { const changed = toggleRowStatus(this.states.expandRows, row, expanded); if (changed) { this.table.$emit('expand-change', row, this.states.expandRows.slice()); this.scheduleLayout(); } }, setExpandRowKeys(rowKeys) { this.assertRowKey(); // TODO:这里的代码可以优化 const { data, rowKey } = this.states; const keysMap = getKeysMap(data, rowKey); this.states.expandRows = rowKeys.reduce((prev, cur) => { const info = keysMap[cur]; if (info) { prev.push(info.row); } return prev; }, []); }, isRowExpanded(row) { const { expandRows = [], rowKey } = this.states; if (rowKey) { const expandMap = getKeysMap(expandRows, rowKey); return !!expandMap[getRowIdentity(row, rowKey)]; } return expandRows.indexOf(row) !== -1; } } }; ================================================ FILE: packages/table/src/store/helper.js ================================================ import Store from './index'; import debounce from 'throttle-debounce/debounce'; export function createStore(table, initialState = {}) { if (!table) { throw new Error('Table is required.'); } const store = new Store(); store.table = table; // fix https://github.com/ElemeFE/element/issues/14075 // related pr https://github.com/ElemeFE/element/pull/14146 store.toggleAllSelection = debounce(10, store._toggleAllSelection); Object.keys(initialState).forEach(key => { store.states[key] = initialState[key]; }); return store; } export function mapStates(mapper) { const res = {}; Object.keys(mapper).forEach(key => { const value = mapper[key]; let fn; if (typeof value === 'string') { fn = function() { return this.store.states[value]; }; } else if (typeof value === 'function') { fn = function() { return value.call(this, this.store.states); }; } else { console.error('invalid value type'); } if (fn) { res[key] = fn; } }); return res; }; ================================================ FILE: packages/table/src/store/index.js ================================================ import Vue from 'vue'; import Watcher from './watcher'; import { arrayFind } from 'element-ui/src/utils/util'; Watcher.prototype.mutations = { setData(states, data) { const dataInstanceChanged = states._data !== data; states._data = data; this.execQuery(); // 数据变化,更新部分数据。 // 没有使用 computed,而是手动更新部分数据 https://github.com/vuejs/vue/issues/6660#issuecomment-331417140 this.updateCurrentRowData(); this.updateExpandRows(); if (states.reserveSelection) { this.assertRowKey(); this.updateSelectionByRowKey(); } else { if (dataInstanceChanged) { this.clearSelection(); } else { this.cleanSelection(); } } this.updateAllSelected(); this.updateTableScrollY(); }, insertColumn(states, column, index, parent) { let array = states._columns; if (parent) { array = parent.children; if (!array) array = parent.children = []; } if (typeof index !== 'undefined') { array.splice(index, 0, column); } else { array.push(column); } if (column.type === 'selection') { states.selectable = column.selectable; states.reserveSelection = column.reserveSelection; } if (this.table.$ready) { this.updateColumns(); // hack for dynamics insert column this.scheduleLayout(); } }, removeColumn(states, column, parent) { let array = states._columns; if (parent) { array = parent.children; if (!array) array = parent.children = []; } if (array) { array.splice(array.indexOf(column), 1); } if (this.table.$ready) { this.updateColumns(); // hack for dynamics remove column this.scheduleLayout(); } }, sort(states, options) { const { prop, order, init } = options; if (prop) { const column = arrayFind(states.columns, column => column.property === prop); if (column) { column.order = order; this.updateSort(column, prop, order); this.commit('changeSortCondition', { init }); } } }, changeSortCondition(states, options) { // 修复 pr https://github.com/ElemeFE/element/pull/15012 导致的 bug const { sortingColumn: column, sortProp: prop, sortOrder: order } = states; if (order === null) { states.sortingColumn = null; states.sortProp = null; } const ingore = { filter: true }; this.execQuery(ingore); if (!options || !(options.silent || options.init)) { this.table.$emit('sort-change', { column, prop, order }); } this.updateTableScrollY(); }, filterChange(states, options) { let { column, values, silent } = options; const newFilters = this.updateFilters(column, values); this.execQuery(); if (!silent) { this.table.$emit('filter-change', newFilters); } this.updateTableScrollY(); }, toggleAllSelection() { this.toggleAllSelection(); }, rowSelectedChanged(states, row) { this.toggleRowSelection(row); this.updateAllSelected(); }, setHoverRow(states, row) { states.hoverRow = row; }, setCurrentRow(states, row) { this.updateCurrentRow(row); } }; Watcher.prototype.commit = function(name, ...args) { const mutations = this.mutations; if (mutations[name]) { mutations[name].apply(this, [this.states].concat(args)); } else { throw new Error(`Action not found: ${name}`); } }; Watcher.prototype.updateTableScrollY = function() { Vue.nextTick(this.table.updateScrollY); }; export default Watcher; ================================================ FILE: packages/table/src/store/tree.js ================================================ import { walkTreeNode, getRowIdentity } from '../util'; export default { data() { return { states: { // defaultExpandAll 存在于 expand.js 中,这里不重复添加 // 在展开行中,expandRowKeys 会被转化成 expandRows,expandRowKeys 这个属性只是记录了 TreeTable 行的展开 // TODO: 拆分为独立的 TreeTable,统一用法 expandRowKeys: [], treeData: {}, indent: 16, lazy: false, lazyTreeNodeMap: {}, lazyColumnIdentifier: 'hasChildren', childrenColumnName: 'children' } }; }, computed: { // 嵌入型的数据,watch 无法是检测到变化 https://github.com/ElemeFE/element/issues/14998 // TODO: 使用 computed 解决该问题,是否会造成性能问题? // @return { id: { level, children } } normalizedData() { if (!this.states.rowKey) return {}; const data = this.states.data || []; return this.normalize(data); }, // @return { id: { children } } // 针对懒加载的情形,不处理嵌套数据 normalizedLazyNode() { const { rowKey, lazyTreeNodeMap, lazyColumnIdentifier } = this.states; const keys = Object.keys(lazyTreeNodeMap); const res = {}; if (!keys.length) return res; keys.forEach(key => { if (lazyTreeNodeMap[key].length) { const item = { children: [] }; lazyTreeNodeMap[key].forEach(row => { const currentRowKey = getRowIdentity(row, rowKey); item.children.push(currentRowKey); if (row[lazyColumnIdentifier] && !res[currentRowKey]) { res[currentRowKey] = { children: [] }; } }); res[key] = item; } }); return res; } }, watch: { normalizedData: 'updateTreeData', normalizedLazyNode: 'updateTreeData' }, methods: { normalize(data) { const { childrenColumnName, lazyColumnIdentifier, rowKey, lazy } = this.states; const res = {}; walkTreeNode( data, (parent, children, level) => { const parentId = getRowIdentity(parent, rowKey); if (Array.isArray(children)) { res[parentId] = { children: children.map(row => getRowIdentity(row, rowKey)), level }; } else if (lazy) { // 当 children 不存在且 lazy 为 true,该节点即为懒加载的节点 res[parentId] = { children: [], lazy: true, level }; } }, childrenColumnName, lazyColumnIdentifier ); return res; }, updateTreeData() { const nested = this.normalizedData; const normalizedLazyNode = this.normalizedLazyNode; const keys = Object.keys(nested); const newTreeData = {}; if (keys.length) { const { treeData: oldTreeData, defaultExpandAll, expandRowKeys, lazy } = this.states; const rootLazyRowKeys = []; const getExpanded = (oldValue, key) => { const included = defaultExpandAll || (expandRowKeys && expandRowKeys.indexOf(key) !== -1); return !!((oldValue && oldValue.expanded) || included); }; // 合并 expanded 与 display,确保数据刷新后,状态不变 keys.forEach(key => { const oldValue = oldTreeData[key]; const newValue = { ...nested[key] }; newValue.expanded = getExpanded(oldValue, key); if (newValue.lazy) { const { loaded = false, loading = false } = oldValue || {}; newValue.loaded = !!loaded; newValue.loading = !!loading; rootLazyRowKeys.push(key); } newTreeData[key] = newValue; }); // 根据懒加载数据更新 treeData const lazyKeys = Object.keys(normalizedLazyNode); if (lazy && lazyKeys.length && rootLazyRowKeys.length) { lazyKeys.forEach(key => { const oldValue = oldTreeData[key]; const lazyNodeChildren = normalizedLazyNode[key].children; if (rootLazyRowKeys.indexOf(key) !== -1) { // 懒加载的 root 节点,更新一下原有的数据,原来的 children 一定是空数组 if (newTreeData[key].children.length !== 0) { throw new Error('[ElTable]children must be an empty array.'); } newTreeData[key].children = lazyNodeChildren; } else { const { loaded = false, loading = false } = oldValue || {}; newTreeData[key] = { lazy: true, loaded: !!loaded, loading: !!loading, expanded: getExpanded(oldValue, key), children: lazyNodeChildren, level: '' }; } }); } } this.states.treeData = newTreeData; this.updateTableScrollY(); }, updateTreeExpandKeys(value) { this.states.expandRowKeys = value; this.updateTreeData(); }, toggleTreeExpansion(row, expanded) { this.assertRowKey(); const { rowKey, treeData } = this.states; const id = getRowIdentity(row, rowKey); const data = id && treeData[id]; if (id && data && ('expanded' in data)) { const oldExpanded = data.expanded; expanded = typeof expanded === 'undefined' ? !data.expanded : expanded; treeData[id].expanded = expanded; if (oldExpanded !== expanded) { this.table.$emit('expand-change', row, expanded); } this.updateTableScrollY(); } }, loadOrToggle(row) { this.assertRowKey(); const { lazy, treeData, rowKey } = this.states; const id = getRowIdentity(row, rowKey); const data = treeData[id]; if (lazy && data && 'loaded' in data && !data.loaded) { this.loadData(row, id, data); } else { this.toggleTreeExpansion(row); } }, loadData(row, key, treeNode) { const { load } = this.table; const { treeData: rawTreeData } = this.states; if (load && !rawTreeData[key].loaded) { rawTreeData[key].loading = true; load(row, treeNode, data => { if (!Array.isArray(data)) { throw new Error('[ElTable] data must be an array'); } const { lazyTreeNodeMap, treeData } = this.states; treeData[key].loading = false; treeData[key].loaded = true; treeData[key].expanded = true; if (data.length) { this.$set(lazyTreeNodeMap, key, data); } this.table.$emit('expand-change', row, true); }); } } } }; ================================================ FILE: packages/table/src/store/watcher.js ================================================ import Vue from 'vue'; import merge from 'element-ui/src/utils/merge'; import { getKeysMap, getRowIdentity, getColumnById, getColumnByKey, orderBy, toggleRowStatus } from '../util'; import expand from './expand'; import current from './current'; import tree from './tree'; const sortData = (data, states) => { const sortingColumn = states.sortingColumn; if (!sortingColumn || typeof sortingColumn.sortable === 'string') { return data; } return orderBy(data, states.sortProp, states.sortOrder, sortingColumn.sortMethod, sortingColumn.sortBy); }; const doFlattenColumns = (columns) => { const result = []; columns.forEach((column) => { if (column.children) { result.push.apply(result, doFlattenColumns(column.children)); } else { result.push(column); } }); return result; }; export default Vue.extend({ data() { return { states: { // 3.0 版本后要求必须设置该属性 rowKey: null, // 渲染的数据来源,是对 table 中的 data 过滤排序后的结果 data: [], // 是否包含固定列 isComplex: false, // 列 _columns: [], // 不可响应的 originColumns: [], columns: [], fixedColumns: [], rightFixedColumns: [], leafColumns: [], fixedLeafColumns: [], rightFixedLeafColumns: [], leafColumnsLength: 0, fixedLeafColumnsLength: 0, rightFixedLeafColumnsLength: 0, // 选择 isAllSelected: false, selection: [], reserveSelection: false, selectOnIndeterminate: false, selectable: null, // 过滤 filters: {}, // 不可响应的 filteredData: null, // 排序 sortingColumn: null, sortProp: null, sortOrder: null, hoverRow: null } }; }, mixins: [expand, current, tree], methods: { // 检查 rowKey 是否存在 assertRowKey() { const rowKey = this.states.rowKey; if (!rowKey) throw new Error('[ElTable] prop row-key is required'); }, // 更新列 updateColumns() { const states = this.states; const _columns = states._columns || []; states.fixedColumns = _columns.filter((column) => column.fixed === true || column.fixed === 'left'); states.rightFixedColumns = _columns.filter((column) => column.fixed === 'right'); if (states.fixedColumns.length > 0 && _columns[0] && _columns[0].type === 'selection' && !_columns[0].fixed) { _columns[0].fixed = true; states.fixedColumns.unshift(_columns[0]); } const notFixedColumns = _columns.filter(column => !column.fixed); states.originColumns = [].concat(states.fixedColumns).concat(notFixedColumns).concat(states.rightFixedColumns); const leafColumns = doFlattenColumns(notFixedColumns); const fixedLeafColumns = doFlattenColumns(states.fixedColumns); const rightFixedLeafColumns = doFlattenColumns(states.rightFixedColumns); states.leafColumnsLength = leafColumns.length; states.fixedLeafColumnsLength = fixedLeafColumns.length; states.rightFixedLeafColumnsLength = rightFixedLeafColumns.length; states.columns = [].concat(fixedLeafColumns).concat(leafColumns).concat(rightFixedLeafColumns); states.isComplex = states.fixedColumns.length > 0 || states.rightFixedColumns.length > 0; }, // 更新 DOM scheduleLayout(needUpdateColumns) { if (needUpdateColumns) { this.updateColumns(); } this.table.debouncedUpdateLayout(); }, // 选择 isSelected(row) { const { selection = [] } = this.states; return selection.indexOf(row) > -1; }, clearSelection() { const states = this.states; states.isAllSelected = false; const oldSelection = states.selection; if (oldSelection.length) { states.selection = []; this.table.$emit('selection-change', []); } }, cleanSelection() { const states = this.states; const { data, rowKey, selection } = states; let deleted; if (rowKey) { deleted = []; const selectedMap = getKeysMap(selection, rowKey); const dataMap = getKeysMap(data, rowKey); for (let key in selectedMap) { if (selectedMap.hasOwnProperty(key) && !dataMap[key]) { deleted.push(selectedMap[key].row); } } } else { deleted = selection.filter(item => data.indexOf(item) === -1); } if (deleted.length) { const newSelection = selection.filter(item => deleted.indexOf(item) === -1); states.selection = newSelection; this.table.$emit('selection-change', newSelection.slice()); } }, toggleRowSelection(row, selected, emitChange = true) { const changed = toggleRowStatus(this.states.selection, row, selected); if (changed) { const newSelection = (this.states.selection || []).slice(); // 调用 API 修改选中值,不触发 select 事件 if (emitChange) { this.table.$emit('select', newSelection, row); } this.table.$emit('selection-change', newSelection); } }, _toggleAllSelection() { const states = this.states; const { data = [], selection } = states; // when only some rows are selected (but not all), select or deselect all of them // depending on the value of selectOnIndeterminate const value = states.selectOnIndeterminate ? !states.isAllSelected : !(states.isAllSelected || selection.length); states.isAllSelected = value; let selectionChanged = false; data.forEach((row, index) => { if (states.selectable) { if (states.selectable.call(null, row, index) && toggleRowStatus(selection, row, value)) { selectionChanged = true; } } else { if (toggleRowStatus(selection, row, value)) { selectionChanged = true; } } }); if (selectionChanged) { this.table.$emit('selection-change', selection ? selection.slice() : []); } this.table.$emit('select-all', selection); }, updateSelectionByRowKey() { const states = this.states; const { selection, rowKey, data } = states; const selectedMap = getKeysMap(selection, rowKey); data.forEach(row => { const rowId = getRowIdentity(row, rowKey); const rowInfo = selectedMap[rowId]; if (rowInfo) { selection[rowInfo.index] = row; } }); }, updateAllSelected() { const states = this.states; const { selection, rowKey, selectable } = states; // data 为 null 时,解构时的默认值会被忽略 const data = states.data || []; if (data.length === 0) { states.isAllSelected = false; return; } let selectedMap; if (rowKey) { selectedMap = getKeysMap(selection, rowKey); } const isSelected = function(row) { if (selectedMap) { return !!selectedMap[getRowIdentity(row, rowKey)]; } else { return selection.indexOf(row) !== -1; } }; let isAllSelected = true; let selectedCount = 0; for (let i = 0, j = data.length; i < j; i++) { const item = data[i]; const isRowSelectable = selectable && selectable.call(null, item, i); if (!isSelected(item)) { if (!selectable || isRowSelectable) { isAllSelected = false; break; } } else { selectedCount++; } } if (selectedCount === 0) isAllSelected = false; states.isAllSelected = isAllSelected; }, // 过滤与排序 updateFilters(columns, values) { if (!Array.isArray(columns)) { columns = [columns]; } const states = this.states; const filters = {}; columns.forEach(col => { states.filters[col.id] = values; filters[col.columnKey || col.id] = values; }); return filters; }, updateSort(column, prop, order) { if (this.states.sortingColumn && this.states.sortingColumn !== column) { this.states.sortingColumn.order = null; } this.states.sortingColumn = column; this.states.sortProp = prop; this.states.sortOrder = order; }, execFilter() { const states = this.states; const { _data, filters } = states; let data = _data; Object.keys(filters).forEach((columnId) => { const values = states.filters[columnId]; if (!values || values.length === 0) return; const column = getColumnById(this.states, columnId); if (column && column.filterMethod) { data = data.filter((row) => { return values.some(value => column.filterMethod.call(null, value, row, column)); }); } }); states.filteredData = data; }, execSort() { const states = this.states; states.data = sortData(states.filteredData, states); }, // 根据 filters 与 sort 去过滤 data execQuery(ignore) { if (!(ignore && ignore.filter)) { this.execFilter(); } this.execSort(); }, clearFilter(columnKeys) { const states = this.states; const { tableHeader, fixedTableHeader, rightFixedTableHeader } = this.table.$refs; let panels = {}; if (tableHeader) panels = merge(panels, tableHeader.filterPanels); if (fixedTableHeader) panels = merge(panels, fixedTableHeader.filterPanels); if (rightFixedTableHeader) panels = merge(panels, rightFixedTableHeader.filterPanels); const keys = Object.keys(panels); if (!keys.length) return; if (typeof columnKeys === 'string') { columnKeys = [columnKeys]; } if (Array.isArray(columnKeys)) { const columns = columnKeys.map(key => getColumnByKey(states, key)); keys.forEach(key => { const column = columns.find(col => col.id === key); if (column) { // TODO: 优化这里的代码 panels[key].filteredValue = []; } }); this.commit('filterChange', { column: columns, values: [], silent: true, multi: true }); } else { keys.forEach(key => { // TODO: 优化这里的代码 panels[key].filteredValue = []; }); states.filters = {}; this.commit('filterChange', { column: {}, values: [], silent: true }); } }, clearSort() { const states = this.states; if (!states.sortingColumn) return; this.updateSort(null, null, null); this.commit('changeSortCondition', { silent: true }); }, // 适配层,expand-row-keys 在 Expand 与 TreeTable 中都有使用 setExpandRowKeysAdapter(val) { // 这里会触发额外的计算,但为了兼容性,暂时这么做 this.setExpandRowKeys(val); this.updateTreeExpandKeys(val); }, // 展开行与 TreeTable 都要使用 toggleRowExpansionAdapter(row, expanded) { const hasExpandColumn = this.states.columns.some(({ type }) => type === 'expand'); if (hasExpandColumn) { this.toggleRowExpansion(row, expanded); } else { this.toggleTreeExpansion(row, expanded); } } } }); ================================================ FILE: packages/table/src/table-body.js ================================================ import { arrayFindIndex } from 'element-ui/src/utils/util'; import { getCell, getColumnByCell, getRowIdentity, objectEquals } from './util'; import { getStyle, hasClass, removeClass, addClass } from 'element-ui/src/utils/dom'; import ElCheckbox from 'element-ui/packages/checkbox'; import ElTooltip from 'element-ui/packages/tooltip'; import debounce from 'throttle-debounce/debounce'; import LayoutObserver from './layout-observer'; import { mapStates } from './store/helper'; import TableRow from './table-row.js'; export default { name: 'ElTableBody', mixins: [LayoutObserver], components: { ElCheckbox, ElTooltip, TableRow }, props: { store: { required: true }, stripe: Boolean, context: {}, rowClassName: [String, Function], rowStyle: [Object, Function], fixed: String, highlight: Boolean }, render(h) { const data = this.data || []; return ( { this.columns.map(column => ) } { data.reduce((acc, row) => { return acc.concat(this.wrappedRowRender(row, acc.length)); }, []) }
); }, computed: { table() { return this.$parent; }, ...mapStates({ data: 'data', columns: 'columns', treeIndent: 'indent', leftFixedLeafCount: 'fixedLeafColumnsLength', rightFixedLeafCount: 'rightFixedLeafColumnsLength', columnsCount: states => states.columns.length, leftFixedCount: states => states.fixedColumns.length, rightFixedCount: states => states.rightFixedColumns.length, hasExpandColumn: states => states.columns.some(({ type }) => type === 'expand') }), columnsHidden() { return this.columns.map((column, index) => this.isColumnHidden(index)); }, firstDefaultColumnIndex() { return arrayFindIndex(this.columns, ({ type }) => type === 'default'); } }, watch: { // don't trigger getter of currentRow in getCellClass. see https://jsfiddle.net/oe2b4hqt/ // update DOM manually. see https://github.com/ElemeFE/element/pull/13954/files#diff-9b450c00d0a9dec0ffad5a3176972e40 'store.states.hoverRow'(newVal, oldVal) { if (!this.store.states.isComplex || this.$isServer) return; let raf = window.requestAnimationFrame; if (!raf) { raf = (fn) => setTimeout(fn, 16); } raf(() => { const rows = this.$el.querySelectorAll('.el-table__row'); const oldRow = rows[oldVal]; const newRow = rows[newVal]; if (oldRow) { removeClass(oldRow, 'hover-row'); } if (newRow) { addClass(newRow, 'hover-row'); } }); } }, data() { return { tooltipContent: '' }; }, created() { this.activateTooltip = debounce(50, tooltip => tooltip.handleShowPopper()); }, methods: { getKeyOfRow(row, index) { const rowKey = this.table.rowKey; if (rowKey) { return getRowIdentity(row, rowKey); } return index; }, isColumnHidden(index) { if (this.fixed === true || this.fixed === 'left') { return index >= this.leftFixedLeafCount; } else if (this.fixed === 'right') { return index < this.columnsCount - this.rightFixedLeafCount; } else { return (index < this.leftFixedLeafCount) || (index >= this.columnsCount - this.rightFixedLeafCount); } }, getSpan(row, column, rowIndex, columnIndex) { let rowspan = 1; let colspan = 1; const fn = this.table.spanMethod; if (typeof fn === 'function') { const result = fn({ row, column, rowIndex, columnIndex }); if (Array.isArray(result)) { rowspan = result[0]; colspan = result[1]; } else if (typeof result === 'object') { rowspan = result.rowspan; colspan = result.colspan; } } return { rowspan, colspan }; }, getRowStyle(row, rowIndex) { const rowStyle = this.table.rowStyle; if (typeof rowStyle === 'function') { return rowStyle.call(null, { row, rowIndex }); } return rowStyle || null; }, getRowClass(row, rowIndex) { let selection = this.store.states.selection; const classes = ['el-table__row']; if (this.table.highlightCurrentRow && row === this.store.states.currentRow) { classes.push('current-row'); } if (this.table.highlightSelectionRow) { for (let i = 0; i < selection.length; i++) { if (objectEquals(row, selection[i])) { classes.push('selection-row'); } }; } if (this.stripe && rowIndex % 2 === 1) { classes.push('el-table__row--striped'); } const rowClassName = this.table.rowClassName; if (typeof rowClassName === 'string') { classes.push(rowClassName); } else if (typeof rowClassName === 'function') { classes.push(rowClassName.call(null, { row, rowIndex })); } if (this.store.states.expandRows.indexOf(row) > -1) { classes.push('expanded'); } return classes; }, getCellStyle(rowIndex, columnIndex, row, column) { const cellStyle = this.table.cellStyle; if (typeof cellStyle === 'function') { return cellStyle.call(null, { rowIndex, columnIndex, row, column }); } return cellStyle; }, getCellClass(rowIndex, columnIndex, row, column) { const classes = [column.id, column.align, column.className]; if (this.isColumnHidden(columnIndex)) { classes.push('is-hidden'); } const cellClassName = this.table.cellClassName; if (typeof cellClassName === 'string') { classes.push(cellClassName); } else if (typeof cellClassName === 'function') { classes.push(cellClassName.call(null, { rowIndex, columnIndex, row, column })); } classes.push('el-table__cell'); return classes.join(' '); }, getColspanRealWidth(columns, colspan, index) { if (colspan < 1) { return columns[index].realWidth; } const widthArr = columns.map(({ realWidth }) => realWidth).slice(index, index + colspan); return widthArr.reduce((acc, width) => acc + width, -1); }, handleCellMouseEnter(event, row) { const table = this.table; const cell = getCell(event); if (cell) { const column = getColumnByCell(table, cell); const hoverState = table.hoverState = { cell, column, row }; table.$emit('cell-mouse-enter', hoverState.row, hoverState.column, hoverState.cell, event); } // 判断是否text-overflow, 如果是就显示tooltip const cellChild = event.target.querySelector('.cell'); if (!(hasClass(cellChild, 'el-tooltip') && cellChild.childNodes.length)) { return; } // use range width instead of scrollWidth to determine whether the text is overflowing // to address a potential FireFox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1074543#c3 const range = document.createRange(); range.setStart(cellChild, 0); range.setEnd(cellChild, cellChild.childNodes.length); const rangeWidth = range.getBoundingClientRect().width; const padding = (parseInt(getStyle(cellChild, 'paddingLeft'), 10) || 0) + (parseInt(getStyle(cellChild, 'paddingRight'), 10) || 0); if ((rangeWidth + padding > cellChild.offsetWidth || cellChild.scrollWidth > cellChild.offsetWidth) && this.$refs.tooltip) { const tooltip = this.$refs.tooltip; // TODO 会引起整个 Table 的重新渲染,需要优化 this.tooltipContent = cell.innerText || cell.textContent; tooltip.referenceElm = cell; tooltip.$refs.popper && (tooltip.$refs.popper.style.display = 'none'); tooltip.doDestroy(); tooltip.setExpectedState(true); this.activateTooltip(tooltip); } }, handleCellMouseLeave(event) { const tooltip = this.$refs.tooltip; if (tooltip) { tooltip.setExpectedState(false); tooltip.handleClosePopper(); } const cell = getCell(event); if (!cell) return; const oldHoverState = this.table.hoverState || {}; this.table.$emit('cell-mouse-leave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event); }, handleMouseEnter: debounce(30, function(index) { this.store.commit('setHoverRow', index); }), handleMouseLeave: debounce(30, function() { this.store.commit('setHoverRow', null); }), handleContextMenu(event, row) { this.handleEvent(event, row, 'contextmenu'); }, handleDoubleClick(event, row) { this.handleEvent(event, row, 'dblclick'); }, handleClick(event, row) { this.store.commit('setCurrentRow', row); this.handleEvent(event, row, 'click'); }, handleEvent(event, row, name) { const table = this.table; const cell = getCell(event); let column; if (cell) { column = getColumnByCell(table, cell); if (column) { table.$emit(`cell-${name}`, row, column, cell, event); } } table.$emit(`row-${name}`, row, column, event); }, rowRender(row, $index, treeRowData) { const { treeIndent, columns, firstDefaultColumnIndex } = this; const rowClasses = this.getRowClass(row, $index); let display = true; if (treeRowData) { rowClasses.push('el-table__row--level-' + treeRowData.level); display = treeRowData.display; } // 指令 v-show 会覆盖 row-style 中 display // 使用 :style 代替 v-show https://github.com/ElemeFE/element/issues/16995 let displayStyle = display ? null : { display: 'none' }; return ( this.handleDoubleClick($event, row)} nativeOn-click={($event) => this.handleClick($event, row)} nativeOn-contextmenu={($event) => this.handleContextMenu($event, row)} nativeOn-mouseenter={_ => this.handleMouseEnter($index)} nativeOn-mouseleave={this.handleMouseLeave} columns={columns} row={row} index={$index} store={this.store} context={this.context || this.table.$vnode.context} firstDefaultColumnIndex={firstDefaultColumnIndex} treeRowData={treeRowData} treeIndent={treeIndent} columnsHidden={this.columnsHidden} getSpan={this.getSpan} getColspanRealWidth={this.getColspanRealWidth} getCellStyle={this.getCellStyle} getCellClass={this.getCellClass} handleCellMouseEnter={this.handleCellMouseEnter} handleCellMouseLeave={this.handleCellMouseLeave} isSelected={this.store.isSelected(row)} isExpanded={this.store.states.expandRows.indexOf(row) > -1} fixed={this.fixed} > ); }, wrappedRowRender(row, $index) { const store = this.store; const { isRowExpanded, assertRowKey } = store; const { treeData, lazyTreeNodeMap, childrenColumnName, rowKey } = store.states; if (this.hasExpandColumn && isRowExpanded(row)) { const renderExpanded = this.table.renderExpanded; const tr = this.rowRender(row, $index); if (!renderExpanded) { console.error('[Element Error]renderExpanded is required.'); return tr; } // 使用二维数组,避免修改 $index return [[ tr, { renderExpanded(this.$createElement, { row, $index, store: this.store }) } ]]; } else if (Object.keys(treeData).length) { assertRowKey(); // TreeTable 时,rowKey 必须由用户设定,不使用 getKeyOfRow 计算 // 在调用 rowRender 函数时,仍然会计算 rowKey,不太好的操作 const key = getRowIdentity(row, rowKey); let cur = treeData[key]; let treeRowData = null; if (cur) { treeRowData = { expanded: cur.expanded, level: cur.level, display: true }; if (typeof cur.lazy === 'boolean') { if (typeof cur.loaded === 'boolean' && cur.loaded) { treeRowData.noLazyChildren = !(cur.children && cur.children.length); } treeRowData.loading = cur.loading; } } const tmp = [this.rowRender(row, $index, treeRowData)]; // 渲染嵌套数据 if (cur) { // currentRow 记录的是 index,所以还需主动增加 TreeTable 的 index let i = 0; const traverse = (children, parent) => { if (!(children && children.length && parent)) return; children.forEach(node => { // 父节点的 display 状态影响子节点的显示状态 const innerTreeRowData = { display: parent.display && parent.expanded, level: parent.level + 1 }; const childKey = getRowIdentity(node, rowKey); if (childKey === undefined || childKey === null) { throw new Error('for nested data item, row-key is required.'); } cur = { ...treeData[childKey] }; // 对于当前节点,分成有无子节点两种情况。 // 如果包含子节点的,设置 expanded 属性。 // 对于它子节点的 display 属性由它本身的 expanded 与 display 共同决定。 if (cur) { innerTreeRowData.expanded = cur.expanded; // 懒加载的某些节点,level 未知 cur.level = cur.level || innerTreeRowData.level; cur.display = !!(cur.expanded && innerTreeRowData.display); if (typeof cur.lazy === 'boolean') { if (typeof cur.loaded === 'boolean' && cur.loaded) { innerTreeRowData.noLazyChildren = !(cur.children && cur.children.length); } innerTreeRowData.loading = cur.loading; } } i++; tmp.push(this.rowRender(node, $index + i, innerTreeRowData)); if (cur) { const nodes = lazyTreeNodeMap[childKey] || node[childrenColumnName]; traverse(nodes, cur); } }); }; // 对于 root 节点,display 一定为 true cur.display = true; const nodes = lazyTreeNodeMap[key] || row[childrenColumnName]; traverse(nodes, cur); } return tmp; } else { return this.rowRender(row, $index); } } } }; ================================================ FILE: packages/table/src/table-column.js ================================================ import { cellStarts, cellForced, defaultRenderCell, treeCellPrefix } from './config'; import { mergeOptions, parseWidth, parseMinWidth, compose } from './util'; import ElCheckbox from 'element-ui/packages/checkbox'; let columnIdSeed = 1; export default { name: 'ElTableColumn', props: { type: { type: String, default: 'default' }, label: String, className: String, labelClassName: String, property: String, prop: String, width: {}, minWidth: {}, renderHeader: Function, sortable: { type: [Boolean, String], default: false }, sortMethod: Function, sortBy: [String, Function, Array], resizable: { type: Boolean, default: true }, columnKey: String, align: String, headerAlign: String, showTooltipWhenOverflow: Boolean, showOverflowTooltip: Boolean, fixed: [Boolean, String], formatter: Function, selectable: Function, reserveSelection: Boolean, filterMethod: Function, filteredValue: Array, filters: Array, filterPlacement: String, filterMultiple: { type: Boolean, default: true }, index: [Number, Function], sortOrders: { type: Array, default() { return ['ascending', 'descending', null]; }, validator(val) { return val.every(order => ['ascending', 'descending', null].indexOf(order) > -1); } } }, data() { return { isSubColumn: false, columns: [] }; }, computed: { owner() { let parent = this.$parent; while (parent && !parent.tableId) { parent = parent.$parent; } return parent; }, columnOrTableParent() { let parent = this.$parent; while (parent && !parent.tableId && !parent.columnId) { parent = parent.$parent; } return parent; }, realWidth() { return parseWidth(this.width); }, realMinWidth() { return parseMinWidth(this.minWidth); }, realAlign() { return this.align ? 'is-' + this.align : null; }, realHeaderAlign() { return this.headerAlign ? 'is-' + this.headerAlign : this.realAlign; } }, methods: { getPropsData(...props) { return props.reduce((prev, cur) => { if (Array.isArray(cur)) { cur.forEach((key) => { prev[key] = this[key]; }); } return prev; }, {}); }, getColumnElIndex(children, child) { return [].indexOf.call(children, child); }, setColumnWidth(column) { if (this.realWidth) { column.width = this.realWidth; } if (this.realMinWidth) { column.minWidth = this.realMinWidth; } if (!column.minWidth) { column.minWidth = 80; } column.realWidth = column.width === undefined ? column.minWidth : column.width; return column; }, setColumnForcedProps(column) { // 对于特定类型的 column,某些属性不允许设置 const type = column.type; const source = cellForced[type] || {}; Object.keys(source).forEach(prop => { let value = source[prop]; if (value !== undefined) { column[prop] = prop === 'className' ? `${column[prop]} ${value}` : value; } }); return column; }, setColumnRenders(column) { // renderHeader 属性不推荐使用。 if (this.renderHeader) { console.warn('[Element Warn][TableColumn]Comparing to render-header, scoped-slot header is easier to use. We recommend users to use scoped-slot header.'); } else if (column.type !== 'selection') { column.renderHeader = (h, scope) => { const renderHeader = this.$scopedSlots.header; return renderHeader ? renderHeader(scope) : column.label; }; } let originRenderCell = column.renderCell; // TODO: 这里的实现调整 if (column.type === 'expand') { // 对于展开行,renderCell 不允许配置的。在上一步中已经设置过,这里需要简单封装一下。 column.renderCell = (h, data) => (
{ originRenderCell(h, data) }
); this.owner.renderExpanded = (h, data) => { return this.$scopedSlots.default ? this.$scopedSlots.default(data) : this.$slots.default; }; } else { originRenderCell = originRenderCell || defaultRenderCell; // 对 renderCell 进行包装 column.renderCell = (h, data) => { let children = null; if (this.$scopedSlots.default) { children = this.$scopedSlots.default(data); } else { children = originRenderCell(h, data); } const prefix = treeCellPrefix(h, data); const props = { class: 'cell', style: {} }; if (column.showOverflowTooltip) { props.class += ' el-tooltip'; props.style = {width: (data.column.realWidth || data.column.width) - 1 + 'px'}; } return (
{ prefix } { children }
); }; } return column; }, registerNormalWatchers() { const props = ['label', 'property', 'filters', 'filterMultiple', 'sortable', 'index', 'formatter', 'className', 'labelClassName', 'showOverflowTooltip']; // 一些属性具有别名 const aliases = { prop: 'property', realAlign: 'align', realHeaderAlign: 'headerAlign', realWidth: 'width' }; const allAliases = props.reduce((prev, cur) => { prev[cur] = cur; return prev; }, aliases); Object.keys(allAliases).forEach(key => { const columnKey = aliases[key]; this.$watch(key, (newVal) => { this.columnConfig[columnKey] = newVal; }); }); }, registerComplexWatchers() { const props = ['fixed']; const aliases = { realWidth: 'width', realMinWidth: 'minWidth' }; const allAliases = props.reduce((prev, cur) => { prev[cur] = cur; return prev; }, aliases); Object.keys(allAliases).forEach(key => { const columnKey = aliases[key]; this.$watch(key, (newVal) => { this.columnConfig[columnKey] = newVal; const updateColumns = columnKey === 'fixed'; this.owner.store.scheduleLayout(updateColumns); }); }); } }, components: { ElCheckbox }, beforeCreate() { this.row = {}; this.column = {}; this.$index = 0; this.columnId = ''; }, created() { const parent = this.columnOrTableParent; this.isSubColumn = this.owner !== parent; this.columnId = (parent.tableId || parent.columnId) + '_column_' + columnIdSeed++; const type = this.type || 'default'; const sortable = this.sortable === '' ? true : this.sortable; const defaults = { ...cellStarts[type], id: this.columnId, type: type, property: this.prop || this.property, align: this.realAlign, headerAlign: this.realHeaderAlign, showOverflowTooltip: this.showOverflowTooltip || this.showTooltipWhenOverflow, // filter 相关属性 filterable: this.filters || this.filterMethod, filteredValue: [], filterPlacement: '', isColumnGroup: false, filterOpened: false, // sort 相关属性 sortable: sortable, // index 列 index: this.index }; const basicProps = ['columnKey', 'label', 'className', 'labelClassName', 'type', 'renderHeader', 'formatter', 'fixed', 'resizable']; const sortProps = ['sortMethod', 'sortBy', 'sortOrders']; const selectProps = ['selectable', 'reserveSelection']; const filterProps = ['filterMethod', 'filters', 'filterMultiple', 'filterOpened', 'filteredValue', 'filterPlacement']; let column = this.getPropsData(basicProps, sortProps, selectProps, filterProps); column = mergeOptions(defaults, column); // 注意 compose 中函数执行的顺序是从右到左 const chains = compose(this.setColumnRenders, this.setColumnWidth, this.setColumnForcedProps); column = chains(column); this.columnConfig = column; // 注册 watcher this.registerNormalWatchers(); this.registerComplexWatchers(); }, mounted() { const owner = this.owner; const parent = this.columnOrTableParent; const children = this.isSubColumn ? parent.$el.children : parent.$refs.hiddenColumns.children; const columnIndex = this.getColumnElIndex(children, this.$el); owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null); }, destroyed() { if (!this.$parent) return; const parent = this.$parent; this.owner.store.commit('removeColumn', this.columnConfig, this.isSubColumn ? parent.columnConfig : null); }, render(h) { // slots 也要渲染,需要计算合并表头 return h('div', this.$slots.default); } }; ================================================ FILE: packages/table/src/table-footer.js ================================================ import LayoutObserver from './layout-observer'; import { mapStates } from './store/helper'; export default { name: 'ElTableFooter', mixins: [LayoutObserver], render(h) { let sums = []; if (this.summaryMethod) { sums = this.summaryMethod({ columns: this.columns, data: this.store.states.data }); } else { this.columns.forEach((column, index) => { if (index === 0) { sums[index] = this.sumText; return; } const values = this.store.states.data.map(item => Number(item[column.property])); const precisions = []; let notNumber = true; values.forEach(value => { if (!isNaN(value)) { notNumber = false; let decimal = ('' + value).split('.')[1]; precisions.push(decimal ? decimal.length : 0); } }); const precision = Math.max.apply(null, precisions); if (!notNumber) { sums[index] = values.reduce((prev, curr) => { const value = Number(curr); if (!isNaN(value)) { return parseFloat((prev + curr).toFixed(Math.min(precision, 20))); } else { return prev; } }, 0); } else { sums[index] = ''; } }); } return ( { this.columns.map(column => ) } { this.hasGutter ? : '' } { this.columns.map((column, cellIndex) => ) } { this.hasGutter ? : '' } ); }, props: { fixed: String, store: { required: true }, summaryMethod: Function, sumText: String, border: Boolean, defaultSort: { type: Object, default() { return { prop: '', order: '' }; } } }, computed: { table() { return this.$parent; }, hasGutter() { return !this.fixed && this.tableLayout.gutterWidth; }, ...mapStates({ columns: 'columns', isAllSelected: 'isAllSelected', leftFixedLeafCount: 'fixedLeafColumnsLength', rightFixedLeafCount: 'rightFixedLeafColumnsLength', columnsCount: states => states.columns.length, leftFixedCount: states => states.fixedColumns.length, rightFixedCount: states => states.rightFixedColumns.length }) }, methods: { isCellHidden(index, columns, column) { if (this.fixed === true || this.fixed === 'left') { return index >= this.leftFixedLeafCount; } else if (this.fixed === 'right') { let before = 0; for (let i = 0; i < index; i++) { before += columns[i].colSpan; } return before < this.columnsCount - this.rightFixedLeafCount; } else if (!this.fixed && column.fixed) { // hide cell when footer instance is not fixed and column is fixed return true; } else { return (index < this.leftFixedCount) || (index >= this.columnsCount - this.rightFixedCount); } }, getRowClasses(column, cellIndex) { const classes = [column.id, column.align, column.labelClassName]; if (column.className) { classes.push(column.className); } if (this.isCellHidden(cellIndex, this.columns, column)) { classes.push('is-hidden'); } if (!column.children) { classes.push('is-leaf'); } return classes; } } }; ================================================ FILE: packages/table/src/table-header.js ================================================ import Vue from 'vue'; import { hasClass, addClass, removeClass } from 'element-ui/src/utils/dom'; import ElCheckbox from 'element-ui/packages/checkbox'; import FilterPanel from './filter-panel.vue'; import LayoutObserver from './layout-observer'; import { mapStates } from './store/helper'; const getAllColumns = (columns) => { const result = []; columns.forEach((column) => { if (column.children) { result.push(column); result.push.apply(result, getAllColumns(column.children)); } else { result.push(column); } }); return result; }; const convertToRows = (originColumns) => { let maxLevel = 1; const traverse = (column, parent) => { if (parent) { column.level = parent.level + 1; if (maxLevel < column.level) { maxLevel = column.level; } } if (column.children) { let colSpan = 0; column.children.forEach((subColumn) => { traverse(subColumn, column); colSpan += subColumn.colSpan; }); column.colSpan = colSpan; } else { column.colSpan = 1; } }; originColumns.forEach((column) => { column.level = 1; traverse(column); }); const rows = []; for (let i = 0; i < maxLevel; i++) { rows.push([]); } const allColumns = getAllColumns(originColumns); allColumns.forEach((column) => { if (!column.children) { column.rowSpan = maxLevel - column.level + 1; } else { column.rowSpan = 1; } rows[column.level - 1].push(column); }); return rows; }; export default { name: 'ElTableHeader', mixins: [LayoutObserver], render(h) { const originColumns = this.store.states.originColumns; const columnRows = convertToRows(originColumns, this.columns); // 是否拥有多级表头 const isGroup = columnRows.length > 1; if (isGroup) this.$parent.isGroup = true; return ( { this.columns.map(column => ) } { this.hasGutter ? : '' } { this._l(columnRows, (columns, rowIndex) => { columns.map((column, cellIndex) => ()) } { this.hasGutter ? : '' } ) }
this.handleMouseMove($event, column) } on-mouseout={ this.handleMouseOut } on-mousedown={ ($event) => this.handleMouseDown($event, column) } on-click={ ($event) => this.handleHeaderClick($event, column) } on-contextmenu={ ($event) => this.handleHeaderContextMenu($event, column) } style={ this.getHeaderCellStyle(rowIndex, cellIndex, columns, column) } class={ this.getHeaderCellClass(rowIndex, cellIndex, columns, column) } key={ column.id }>
0 ? 'highlight' : '', column.labelClassName] }> { column.renderHeader ? column.renderHeader.call(this._renderProxy, h, { column, $index: cellIndex, store: this.store, _self: this.$parent.$vnode.context }) : column.label } { column.sortable ? ( this.handleSortClick($event, column) }> this.handleSortClick($event, column, 'ascending') }> this.handleSortClick($event, column, 'descending') }> ) : '' } { column.filterable ? ( this.handleFilterClick($event, column) }> ) : '' }
); }, props: { fixed: String, store: { required: true }, border: Boolean, defaultSort: { type: Object, default() { return { prop: '', order: '' }; } } }, components: { ElCheckbox }, computed: { table() { return this.$parent; }, hasGutter() { return !this.fixed && this.tableLayout.gutterWidth; }, ...mapStates({ columns: 'columns', isAllSelected: 'isAllSelected', leftFixedLeafCount: 'fixedLeafColumnsLength', rightFixedLeafCount: 'rightFixedLeafColumnsLength', columnsCount: states => states.columns.length, leftFixedCount: states => states.fixedColumns.length, rightFixedCount: states => states.rightFixedColumns.length }) }, created() { this.filterPanels = {}; }, mounted() { // nextTick 是有必要的 https://github.com/ElemeFE/element/pull/11311 this.$nextTick(() => { const { prop, order } = this.defaultSort; const init = true; this.store.commit('sort', { prop, order, init }); }); }, beforeDestroy() { const panels = this.filterPanels; for (let prop in panels) { if (panels.hasOwnProperty(prop) && panels[prop]) { panels[prop].$destroy(true); } } }, methods: { isCellHidden(index, columns) { let start = 0; for (let i = 0; i < index; i++) { start += columns[i].colSpan; } const after = start + columns[index].colSpan - 1; if (this.fixed === true || this.fixed === 'left') { return after >= this.leftFixedLeafCount; } else if (this.fixed === 'right') { return start < this.columnsCount - this.rightFixedLeafCount; } else { return (after < this.leftFixedLeafCount) || (start >= this.columnsCount - this.rightFixedLeafCount); } }, getHeaderRowStyle(rowIndex) { const headerRowStyle = this.table.headerRowStyle; if (typeof headerRowStyle === 'function') { return headerRowStyle.call(null, { rowIndex }); } return headerRowStyle; }, getHeaderRowClass(rowIndex) { const classes = []; const headerRowClassName = this.table.headerRowClassName; if (typeof headerRowClassName === 'string') { classes.push(headerRowClassName); } else if (typeof headerRowClassName === 'function') { classes.push(headerRowClassName.call(null, { rowIndex })); } return classes.join(' '); }, getHeaderCellStyle(rowIndex, columnIndex, row, column) { const headerCellStyle = this.table.headerCellStyle; if (typeof headerCellStyle === 'function') { return headerCellStyle.call(null, { rowIndex, columnIndex, row, column }); } return headerCellStyle; }, getHeaderCellClass(rowIndex, columnIndex, row, column) { const classes = [column.id, column.order, column.headerAlign, column.className, column.labelClassName]; if (rowIndex === 0 && this.isCellHidden(columnIndex, row)) { classes.push('is-hidden'); } if (!column.children) { classes.push('is-leaf'); } if (column.sortable) { classes.push('is-sortable'); } const headerCellClassName = this.table.headerCellClassName; if (typeof headerCellClassName === 'string') { classes.push(headerCellClassName); } else if (typeof headerCellClassName === 'function') { classes.push(headerCellClassName.call(null, { rowIndex, columnIndex, row, column })); } classes.push('el-table__cell'); return classes.join(' '); }, toggleAllSelection() { this.store.commit('toggleAllSelection'); }, handleFilterClick(event, column) { event.stopPropagation(); const target = event.target; let cell = target.tagName === 'TH' ? target : target.parentNode; if (hasClass(cell, 'noclick')) return; cell = cell.querySelector('.el-table__column-filter-trigger') || cell; const table = this.$parent; let filterPanel = this.filterPanels[column.id]; if (filterPanel && column.filterOpened) { filterPanel.showPopper = false; return; } if (!filterPanel) { filterPanel = new Vue(FilterPanel); this.filterPanels[column.id] = filterPanel; if (column.filterPlacement) { filterPanel.placement = column.filterPlacement; } filterPanel.table = table; filterPanel.cell = cell; filterPanel.column = column; !this.$isServer && filterPanel.$mount(document.createElement('div')); } setTimeout(() => { filterPanel.showPopper = true; }, 16); }, handleHeaderClick(event, column) { if (!column.filters && column.sortable) { this.handleSortClick(event, column); } else if (column.filterable && !column.sortable) { this.handleFilterClick(event, column); } this.$parent.$emit('header-click', column, event); }, handleHeaderContextMenu(event, column) { this.$parent.$emit('header-contextmenu', column, event); }, handleMouseDown(event, column) { if (this.$isServer) return; if (column.children && column.children.length > 0) return; /* istanbul ignore if */ if (this.draggingColumn && this.border) { this.dragging = true; this.$parent.resizeProxyVisible = true; const table = this.$parent; const tableEl = table.$el; const tableLeft = tableEl.getBoundingClientRect().left; const columnEl = this.$el.querySelector(`th.${column.id}`); const columnRect = columnEl.getBoundingClientRect(); const minLeft = columnRect.left - tableLeft + 30; addClass(columnEl, 'noclick'); this.dragState = { startMouseLeft: event.clientX, startLeft: columnRect.right - tableLeft, startColumnLeft: columnRect.left - tableLeft, tableLeft }; const resizeProxy = table.$refs.resizeProxy; resizeProxy.style.left = this.dragState.startLeft + 'px'; document.onselectstart = function() { return false; }; document.ondragstart = function() { return false; }; const handleMouseMove = (event) => { const deltaLeft = event.clientX - this.dragState.startMouseLeft; const proxyLeft = this.dragState.startLeft + deltaLeft; resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px'; }; const handleMouseUp = () => { if (this.dragging) { const { startColumnLeft, startLeft } = this.dragState; const finalLeft = parseInt(resizeProxy.style.left, 10); const columnWidth = finalLeft - startColumnLeft; column.width = column.realWidth = columnWidth; table.$emit('header-dragend', column.width, startLeft - startColumnLeft, column, event); this.store.scheduleLayout(); document.body.style.cursor = ''; this.dragging = false; this.draggingColumn = null; this.dragState = {}; table.resizeProxyVisible = false; } document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); document.onselectstart = null; document.ondragstart = null; setTimeout(function() { removeClass(columnEl, 'noclick'); }, 0); }; document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); } }, handleMouseMove(event, column) { if (column.children && column.children.length > 0) return; let target = event.target; while (target && target.tagName !== 'TH') { target = target.parentNode; } if (!column || !column.resizable) return; if (!this.dragging && this.border) { let rect = target.getBoundingClientRect(); const bodyStyle = document.body.style; if (rect.width > 12 && rect.right - event.pageX < 8) { bodyStyle.cursor = 'col-resize'; if (hasClass(target, 'is-sortable')) { target.style.cursor = 'col-resize'; } this.draggingColumn = column; } else if (!this.dragging) { bodyStyle.cursor = ''; if (hasClass(target, 'is-sortable')) { target.style.cursor = 'pointer'; } this.draggingColumn = null; } } }, handleMouseOut() { if (this.$isServer) return; document.body.style.cursor = ''; }, toggleOrder({ order, sortOrders }) { if (order === '') return sortOrders[0]; const index = sortOrders.indexOf(order || null); return sortOrders[index > sortOrders.length - 2 ? 0 : index + 1]; }, handleSortClick(event, column, givenOrder) { event.stopPropagation(); let order = column.order === givenOrder ? null : (givenOrder || this.toggleOrder(column)); let target = event.target; while (target && target.tagName !== 'TH') { target = target.parentNode; } if (target && target.tagName === 'TH') { if (hasClass(target, 'noclick')) { removeClass(target, 'noclick'); return; } } if (!column.sortable) return; const states = this.store.states; let sortProp = states.sortProp; let sortOrder; const sortingColumn = states.sortingColumn; if (sortingColumn !== column || (sortingColumn === column && sortingColumn.order === null)) { if (sortingColumn) { sortingColumn.order = null; } states.sortingColumn = column; sortProp = column.property; } if (!order) { sortOrder = column.order = null; } else { sortOrder = column.order = order; } states.sortProp = sortProp; states.sortOrder = sortOrder; this.store.commit('changeSortCondition'); } }, data() { return { draggingColumn: null, dragging: false, dragState: {} }; } }; ================================================ FILE: packages/table/src/table-layout.js ================================================ import Vue from 'vue'; import scrollbarWidth from 'element-ui/src/utils/scrollbar-width'; import { parseHeight } from './util'; class TableLayout { constructor(options) { this.observers = []; this.table = null; this.store = null; this.columns = null; this.fit = true; this.showHeader = true; this.height = null; this.scrollX = false; this.scrollY = false; this.bodyWidth = null; this.fixedWidth = null; this.rightFixedWidth = null; this.tableHeight = null; this.headerHeight = 44; // Table Header Height this.appendHeight = 0; // Append Slot Height this.footerHeight = 44; // Table Footer Height this.viewportHeight = null; // Table Height - Scroll Bar Height this.bodyHeight = null; // Table Height - Table Header Height this.fixedBodyHeight = null; // Table Height - Table Header Height - Scroll Bar Height this.gutterWidth = scrollbarWidth(); for (let name in options) { if (options.hasOwnProperty(name)) { this[name] = options[name]; } } if (!this.table) { throw new Error('table is required for Table Layout'); } if (!this.store) { throw new Error('store is required for Table Layout'); } } updateScrollY() { const height = this.height; if (height === null) return false; const bodyWrapper = this.table.bodyWrapper; if (this.table.$el && bodyWrapper) { const body = bodyWrapper.querySelector('.el-table__body'); const prevScrollY = this.scrollY; const scrollY = body.offsetHeight > this.bodyHeight; this.scrollY = scrollY; return prevScrollY !== scrollY; } return false; } setHeight(value, prop = 'height') { if (Vue.prototype.$isServer) return; const el = this.table.$el; value = parseHeight(value); this.height = value; if (!el && (value || value === 0)) return Vue.nextTick(() => this.setHeight(value, prop)); if (typeof value === 'number') { el.style[prop] = value + 'px'; this.updateElsHeight(); } else if (typeof value === 'string') { el.style[prop] = value; this.updateElsHeight(); } } setMaxHeight(value) { this.setHeight(value, 'max-height'); } getFlattenColumns() { const flattenColumns = []; const columns = this.table.columns; columns.forEach((column) => { if (column.isColumnGroup) { flattenColumns.push.apply(flattenColumns, column.columns); } else { flattenColumns.push(column); } }); return flattenColumns; } updateElsHeight() { if (!this.table.$ready) return Vue.nextTick(() => this.updateElsHeight()); const { headerWrapper, appendWrapper, footerWrapper } = this.table.$refs; this.appendHeight = appendWrapper ? appendWrapper.offsetHeight : 0; if (this.showHeader && !headerWrapper) return; // fix issue (https://github.com/ElemeFE/element/pull/16956) const headerTrElm = headerWrapper ? headerWrapper.querySelector('.el-table__header tr') : null; const noneHeader = this.headerDisplayNone(headerTrElm); const headerHeight = this.headerHeight = !this.showHeader ? 0 : headerWrapper.offsetHeight; if (this.showHeader && !noneHeader && headerWrapper.offsetWidth > 0 && (this.table.columns || []).length > 0 && headerHeight < 2) { return Vue.nextTick(() => this.updateElsHeight()); } const tableHeight = this.tableHeight = this.table.$el.clientHeight; const footerHeight = this.footerHeight = footerWrapper ? footerWrapper.offsetHeight : 0; if (this.height !== null) { this.bodyHeight = tableHeight - headerHeight - footerHeight + (footerWrapper ? 1 : 0); } this.fixedBodyHeight = this.scrollX ? (this.bodyHeight - this.gutterWidth) : this.bodyHeight; const noData = !(this.store.states.data && this.store.states.data.length); this.viewportHeight = this.scrollX ? tableHeight - (noData ? 0 : this.gutterWidth) : tableHeight; this.updateScrollY(); this.notifyObservers('scrollable'); } headerDisplayNone(elm) { if (!elm) return true; let headerChild = elm; while (headerChild.tagName !== 'DIV') { if (getComputedStyle(headerChild).display === 'none') { return true; } headerChild = headerChild.parentElement; } return false; } updateColumnsWidth() { if (Vue.prototype.$isServer) return; const fit = this.fit; const bodyWidth = this.table.$el.clientWidth; let bodyMinWidth = 0; const flattenColumns = this.getFlattenColumns(); let flexColumns = flattenColumns.filter((column) => typeof column.width !== 'number'); flattenColumns.forEach((column) => { // Clean those columns whose width changed from flex to unflex if (typeof column.width === 'number' && column.realWidth) column.realWidth = null; }); if (flexColumns.length > 0 && fit) { flattenColumns.forEach((column) => { bodyMinWidth += column.width || column.minWidth || 80; }); const scrollYWidth = this.scrollY ? this.gutterWidth : 0; if (bodyMinWidth <= bodyWidth - scrollYWidth) { // DON'T HAVE SCROLL BAR this.scrollX = false; const totalFlexWidth = bodyWidth - scrollYWidth - bodyMinWidth; if (flexColumns.length === 1) { flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth; } else { const allColumnsWidth = flexColumns.reduce((prev, column) => prev + (column.minWidth || 80), 0); const flexWidthPerPixel = totalFlexWidth / allColumnsWidth; let noneFirstWidth = 0; flexColumns.forEach((column, index) => { if (index === 0) return; const flexWidth = Math.floor((column.minWidth || 80) * flexWidthPerPixel); noneFirstWidth += flexWidth; column.realWidth = (column.minWidth || 80) + flexWidth; }); flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth - noneFirstWidth; } } else { // HAVE HORIZONTAL SCROLL BAR this.scrollX = true; flexColumns.forEach(function(column) { column.realWidth = column.minWidth; }); } this.bodyWidth = Math.max(bodyMinWidth, bodyWidth); this.table.resizeState.width = this.bodyWidth; } else { flattenColumns.forEach((column) => { if (!column.width && !column.minWidth) { column.realWidth = 80; } else { column.realWidth = column.width || column.minWidth; } bodyMinWidth += column.realWidth; }); this.scrollX = bodyMinWidth > bodyWidth; this.bodyWidth = bodyMinWidth; } const fixedColumns = this.store.states.fixedColumns; if (fixedColumns.length > 0) { let fixedWidth = 0; fixedColumns.forEach(function(column) { fixedWidth += column.realWidth || column.width; }); this.fixedWidth = fixedWidth; } const rightFixedColumns = this.store.states.rightFixedColumns; if (rightFixedColumns.length > 0) { let rightFixedWidth = 0; rightFixedColumns.forEach(function(column) { rightFixedWidth += column.realWidth || column.width; }); this.rightFixedWidth = rightFixedWidth; } this.notifyObservers('columns'); } addObserver(observer) { this.observers.push(observer); } removeObserver(observer) { const index = this.observers.indexOf(observer); if (index !== -1) { this.observers.splice(index, 1); } } notifyObservers(event) { const observers = this.observers; observers.forEach((observer) => { switch (event) { case 'columns': observer.onColumnsChange(this); break; case 'scrollable': observer.onScrollableChange(this); break; default: throw new Error(`Table Layout don't have event ${event}.`); } }); } } export default TableLayout; ================================================ FILE: packages/table/src/table-row.js ================================================ import ElCheckbox from 'element-ui/packages/checkbox'; export default { name: 'ElTableRow', props: [ 'columns', 'row', 'index', 'isSelected', 'isExpanded', 'store', 'context', 'firstDefaultColumnIndex', 'treeRowData', 'treeIndent', 'columnsHidden', 'getSpan', 'getColspanRealWidth', 'getCellStyle', 'getCellClass', 'handleCellMouseLeave', 'handleCellMouseEnter', 'fixed' ], components: { ElCheckbox }, render() { const { columns, row, index: $index, store, context, firstDefaultColumnIndex, treeRowData, treeIndent, columnsHidden = [], isSelected, isExpanded } = this; return ( { columns.map((column, cellIndex) => { const { rowspan, colspan } = this.getSpan(row, column, $index, cellIndex); if (!rowspan || !colspan) { return null; } const columnData = { ...column }; columnData.realWidth = this.getColspanRealWidth(columns, colspan, cellIndex); const data = { store, isSelected, isExpanded, _self: context, column: columnData, row, $index }; if (cellIndex === firstDefaultColumnIndex && treeRowData) { data.treeNode = { indent: treeRowData.level * treeIndent, level: treeRowData.level }; if (typeof treeRowData.expanded === 'boolean') { data.treeNode.expanded = treeRowData.expanded; // 表明是懒加载 if ('loading' in treeRowData) { data.treeNode.loading = treeRowData.loading; } if ('noLazyChildren' in treeRowData) { data.treeNode.noLazyChildren = treeRowData.noLazyChildren; } } } return ( this.handleCellMouseEnter($event, row)} on-mouseleave={this.handleCellMouseLeave} > { column.renderCell.call( this._renderProxy, this.$createElement, data, columnsHidden[cellIndex] ) } ); }) } ); } }; ================================================ FILE: packages/table/src/table.vue ================================================ ================================================ FILE: packages/table/src/util.js ================================================ import { getValueByPath } from 'element-ui/src/utils/util'; export const getCell = function(event) { let cell = event.target; while (cell && cell.tagName.toUpperCase() !== 'HTML') { if (cell.tagName.toUpperCase() === 'TD') { return cell; } cell = cell.parentNode; } return null; }; const isObject = function(obj) { return obj !== null && typeof obj === 'object'; }; export const orderBy = function(array, sortKey, reverse, sortMethod, sortBy) { if (!sortKey && !sortMethod && (!sortBy || Array.isArray(sortBy) && !sortBy.length)) { return array; } if (typeof reverse === 'string') { reverse = reverse === 'descending' ? -1 : 1; } else { reverse = (reverse && reverse < 0) ? -1 : 1; } const getKey = sortMethod ? null : function(value, index) { if (sortBy) { if (!Array.isArray(sortBy)) { sortBy = [sortBy]; } return sortBy.map(function(by) { if (typeof by === 'string') { return getValueByPath(value, by); } else { return by(value, index, array); } }); } if (sortKey !== '$key') { if (isObject(value) && '$value' in value) value = value.$value; } return [isObject(value) ? getValueByPath(value, sortKey) : value]; }; const compare = function(a, b) { if (sortMethod) { return sortMethod(a.value, b.value); } for (let i = 0, len = a.key.length; i < len; i++) { if (a.key[i] < b.key[i]) { return -1; } if (a.key[i] > b.key[i]) { return 1; } } return 0; }; return array.map(function(value, index) { return { value: value, index: index, key: getKey ? getKey(value, index) : null }; }).sort(function(a, b) { let order = compare(a, b); if (!order) { // make stable https://en.wikipedia.org/wiki/Sorting_algorithm#Stability order = a.index - b.index; } return order * reverse; }).map(item => item.value); }; export const getColumnById = function(table, columnId) { let column = null; table.columns.forEach(function(item) { if (item.id === columnId) { column = item; } }); return column; }; export const getColumnByKey = function(table, columnKey) { let column = null; for (let i = 0; i < table.columns.length; i++) { const item = table.columns[i]; if (item.columnKey === columnKey) { column = item; break; } } return column; }; export const getColumnByCell = function(table, cell) { const matches = (cell.className || '').match(/el-table_[^\s]+/gm); if (matches) { return getColumnById(table, matches[0]); } return null; }; export const getRowIdentity = (row, rowKey) => { if (!row) throw new Error('row is required when get row identity'); if (typeof rowKey === 'string') { if (rowKey.indexOf('.') < 0) { return row[rowKey]; } let key = rowKey.split('.'); let current = row; for (let i = 0; i < key.length; i++) { current = current[key[i]]; } return current; } else if (typeof rowKey === 'function') { return rowKey.call(null, row); } }; export const getKeysMap = function(array, rowKey) { const arrayMap = {}; (array || []).forEach((row, index) => { arrayMap[getRowIdentity(row, rowKey)] = { row, index }; }); return arrayMap; }; function hasOwn(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } export function mergeOptions(defaults, config) { const options = {}; let key; for (key in defaults) { options[key] = defaults[key]; } for (key in config) { if (hasOwn(config, key)) { const value = config[key]; if (typeof value !== 'undefined') { options[key] = value; } } } return options; } export function parseWidth(width) { if (width !== undefined) { width = parseInt(width, 10); if (isNaN(width)) { width = null; } } return width; } export function parseMinWidth(minWidth) { if (typeof minWidth !== 'undefined') { minWidth = parseWidth(minWidth); if (isNaN(minWidth)) { minWidth = 80; } } return minWidth; }; export function parseHeight(height) { if (typeof height === 'number') { return height; } if (typeof height === 'string') { if (/^\d+(?:px)?$/.test(height)) { return parseInt(height, 10); } else { return height; } } return null; } // https://github.com/reduxjs/redux/blob/master/src/compose.js export function compose(...funcs) { if (funcs.length === 0) { return arg => arg; } if (funcs.length === 1) { return funcs[0]; } return funcs.reduce((a, b) => (...args) => a(b(...args))); } export function toggleRowStatus(statusArr, row, newVal) { let changed = false; const index = statusArr.indexOf(row); const included = index !== -1; const addRow = () => { statusArr.push(row); changed = true; }; const removeRow = () => { statusArr.splice(index, 1); changed = true; }; if (typeof newVal === 'boolean') { if (newVal && !included) { addRow(); } else if (!newVal && included) { removeRow(); } } else { if (included) { removeRow(); } else { addRow(); } } return changed; } export function walkTreeNode(root, cb, childrenKey = 'children', lazyKey = 'hasChildren') { const isNil = (array) => !(Array.isArray(array) && array.length); function _walker(parent, children, level) { cb(parent, children, level); children.forEach(item => { if (item[lazyKey]) { cb(item, null, level + 1); return; } const children = item[childrenKey]; if (!isNil(children)) { _walker(item, children, level + 1); } }); } root.forEach(item => { if (item[lazyKey]) { cb(item, null, 0); return; } const children = item[childrenKey]; if (!isNil(children)) { _walker(item, children, 0); } }); } export const objectEquals = function(objectA, objectB) { // 取对象a和b的属性名 let aProps = Object.getOwnPropertyNames(objectA); let bProps = Object.getOwnPropertyNames(objectB); // 判断属性名的length是否一致 if (aProps.length !== bProps.length) { return false; } // 循环取出属性名,再判断属性值是否一致 for (let i = 0; i < aProps.length; i++) { let propName = aProps[i]; if (objectA[propName] !== objectB[propName]) { return false; } } return true; }; ================================================ FILE: packages/table-column/index.js ================================================ import ElTableColumn from '../table/src/table-column'; /* istanbul ignore next */ ElTableColumn.install = function(Vue) { Vue.component(ElTableColumn.name, ElTableColumn); }; export default ElTableColumn; ================================================ FILE: packages/tabs/index.js ================================================ import ElTabs from './src/tabs'; /* istanbul ignore next */ ElTabs.install = function(Vue) { Vue.component(ElTabs.name, ElTabs); }; export default ElTabs; ================================================ FILE: packages/tabs/src/tab-bar.vue ================================================ ================================================ FILE: packages/tabs/src/tab-nav.vue ================================================ ================================================ FILE: packages/tabs/src/tab-pane.vue ================================================ ================================================ FILE: packages/tabs/src/tabs.vue ================================================ ================================================ FILE: packages/tag/index.js ================================================ import ElTag from './src/tag'; /* istanbul ignore next */ ElTag.install = function(Vue) { Vue.component(ElTag.name, ElTag); }; export default ElTag; ================================================ FILE: packages/tag/src/tag.vue ================================================ ================================================ FILE: packages/theme-chalk/.gitignore ================================================ node_modules lib npm-debug* ================================================ FILE: packages/theme-chalk/README.md ================================================ # element-theme-chalk > element component chalk theme. ## Installation ```shell npm i element-theme-chalk -S ``` ## Usage Use Sass import ```css @import 'element-theme-chalk'; ``` Or Use webpack ```javascript import 'element-theme-chalk'; ``` Or ```html ``` ## Import on demand ```javascript import 'element-theme-chalk/lib/input.css'; import 'element-theme-chalk/lib/select.css'; // ... ``` ================================================ FILE: packages/theme-chalk/gulpfile.js ================================================ 'use strict'; const { series, src, dest } = require('gulp'); const sass = require('gulp-sass'); const autoprefixer = require('gulp-autoprefixer'); const cssmin = require('gulp-cssmin'); function compile() { return src('./src/*.scss') .pipe(sass.sync()) .pipe(autoprefixer({ browsers: ['ie > 9', 'last 2 versions'], cascade: false })) .pipe(cssmin()) .pipe(dest('./lib')); } function copyfont() { return src('./src/fonts/**') .pipe(cssmin()) .pipe(dest('./lib/fonts')); } exports.build = series(compile, copyfont); ================================================ FILE: packages/theme-chalk/package.json ================================================ { "name": "element-theme-chalk", "version": "2.15.14", "description": "Element component chalk theme.", "main": "lib/index.css", "style": "lib/index.css", "files": [ "lib", "src" ], "scripts": { "build": "gulp build" }, "repository": { "type": "git", "url": "git+https://github.com/ElementUI/theme-chalk.git" }, "keywords": [ "element", "theme" ], "author": "yi.shyang@ele.me", "license": "MIT", "bugs": { "url": "https://github.com/ElementUI/theme-chalk/issues" }, "homepage": "https://github.com/ElementUI/theme-chalk#readme", "devDependencies": { "gulp": "^3.9.1", "gulp-cssmin": "^0.1.7", "gulp-sass": "^3.1.0", "gulp-autoprefixer": "^4.0.0" }, "dependencies": {} } ================================================ FILE: packages/theme-chalk/src/alert.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(alert) { width: 100%; padding: $--alert-padding; margin: 0; box-sizing: border-box; border-radius: $--alert-border-radius; position: relative; background-color: $--color-white; overflow: hidden; opacity: 1; display: flex; align-items: center; transition: opacity .2s; @include when(light) { .el-alert__closebtn { color: $--color-text-placeholder; } } @include when(dark) { .el-alert__closebtn { color: $--color-white; } .el-alert__description { color: $--color-white; } } @include when(center) { justify-content: center; } @include m(success) { &.is-light { background-color: $--alert-success-color; color: $--color-success; .el-alert__description { color: $--color-success; } } &.is-dark { background-color: $--color-success; color: $--color-white; } } @include m(info) { &.is-light { background-color: $--alert-info-color; color: $--color-info; } &.is-dark { background-color: $--color-info; color: $--color-white; } .el-alert__description { color: $--color-info; } } @include m(warning) { &.is-light { background-color: $--alert-warning-color; color: $--color-warning; .el-alert__description { color: $--color-warning; } } &.is-dark { background-color: $--color-warning; color: $--color-white; } } @include m(error) { &.is-light { background-color: $--alert-danger-color; color: $--color-danger; .el-alert__description { color: $--color-danger; } } &.is-dark { background-color: $--color-danger; color: $--color-white; } } @include e(content) { display: table-cell; padding: 0 8px; } @include e(icon) { font-size: $--alert-icon-size; width: $--alert-icon-size; @include when(big) { font-size: $--alert-icon-large-size; width: $--alert-icon-large-size; } } @include e(title) { font-size: $--alert-title-font-size; line-height: 18px; @include when(bold) { font-weight: bold; } } & .el-alert__description { font-size: $--alert-description-font-size; margin: 5px 0 0 0; } @include e(closebtn) { font-size: $--alert-close-font-size; opacity: 1; position: absolute; top: 12px; right: 15px; cursor: pointer; @include when(customed) { font-style: normal; font-size: $--alert-close-customed-font-size; top: 9px; } } } .el-alert-fade-enter, .el-alert-fade-leave-active { opacity: 0; } ================================================ FILE: packages/theme-chalk/src/aside.scss ================================================ @import "mixins/mixins"; @include b(aside) { overflow: auto; box-sizing: border-box; flex-shrink: 0; } ================================================ FILE: packages/theme-chalk/src/autocomplete.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @import "./input.scss"; @import "./scrollbar.scss"; @import "./popper"; @include b(autocomplete) { position: relative; display: inline-block; } @include b(autocomplete-suggestion) { margin: 5px 0; box-shadow: $--box-shadow-light; border-radius: $--border-radius-base; border: 1px solid $--border-color-light; box-sizing: border-box; background-color: $--color-white; @include e(wrap) { max-height: 280px; padding: 10px 0; box-sizing: border-box; } @include e(list) { margin: 0; padding: 0; } & li { padding: 0 20px; margin: 0; line-height: 34px; cursor: pointer; color: $--color-text-regular; font-size: $--font-size-base; list-style: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; &:hover { background-color: $--select-option-hover-background; } &.highlighted { background-color: $--select-option-hover-background; } &.divider { margin-top: 6px; border-top: 1px solid $--color-black; } &.divider:last-child { margin-bottom: -6px; } } @include when(loading) { li { text-align: center; height: 100px; line-height: 100px; font-size: 20px; color: #999; @include utils-vertical-center; &:hover { background-color: $--color-white; } } & .el-icon-loading { vertical-align: middle; } } } ================================================ FILE: packages/theme-chalk/src/avatar.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(avatar) { display: inline-block; box-sizing: border-box; text-align: center; overflow: hidden; color: $--avatar-font-color; background: $--avatar-background-color; width: $--avatar-large-size; height: $--avatar-large-size; line-height: $--avatar-large-size; font-size: $--avatar-text-font-size; >img { display: block; height: 100%; vertical-align: middle; } @include m(circle) { border-radius: 50%; } @include m(square) { border-radius: $--avatar-border-radius; } @include m(icon) { font-size: $--avatar-icon-font-size; } @include m(large) { width: $--avatar-large-size; height: $--avatar-large-size; line-height: $--avatar-large-size; } @include m(medium) { width: $--avatar-medium-size; height: $--avatar-medium-size; line-height: $--avatar-medium-size; } @include m(small) { width: $--avatar-small-size; height: $--avatar-small-size; line-height: $--avatar-small-size; } } ================================================ FILE: packages/theme-chalk/src/backtop.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(backtop) { position: fixed; background-color: $--backtop-background-color; width: 40px; height: 40px; border-radius: 50%; color: $--backtop-font-color; display: flex; align-items: center; justify-content: center; font-size: 20px; box-shadow: 0 0 6px rgba(0,0,0, .12); cursor: pointer; z-index: 5; &:hover { background-color: $--backtop-hover-background-color } } ================================================ FILE: packages/theme-chalk/src/badge.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(badge) { position: relative; vertical-align: middle; display: inline-block; @include e(content) { background-color: $--badge-background-color; border-radius: $--badge-radius; color: $--color-white; display: inline-block; font-size: $--badge-font-size; height: $--badge-size; line-height: $--badge-size; padding: 0 $--badge-padding; text-align: center; white-space: nowrap; border: 1px solid $--color-white; @include when(fixed) { position: absolute; top: 0; right: #{1 + $--badge-size / 2}; transform: translateY(-50%) translateX(100%); @include when(dot) { right: 5px; } } @include when(dot) { height: 8px; width: 8px; padding: 0; right: 0; border-radius: 50%; } @each $type in (primary, success, warning, info, danger) { @include m($type) { @if $type == primary { background-color: $--color-primary; } @else if $type == success { background-color: $--color-success; } @else if $type == warning { background-color: $--color-warning; } @else if $type == info { background-color: $--color-info; } @else { background-color: $--color-danger; } } } } } ================================================ FILE: packages/theme-chalk/src/base.scss ================================================ @import "common/transition.scss"; @import "icon.scss"; ================================================ FILE: packages/theme-chalk/src/breadcrumb-item.scss ================================================ ================================================ FILE: packages/theme-chalk/src/breadcrumb.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @include b(breadcrumb) { font-size: 14px; line-height: 1; @include utils-clearfix; @include e(separator) { margin: 0 9px; font-weight: bold; color: $--color-text-placeholder; &[class*=icon] { margin: 0 6px; font-weight: normal; } } @include e(item) { float: left; @include e(inner) { color: $--color-text-regular; &.is-link, & a { font-weight: bold; text-decoration: none; transition: $--color-transition-base; color: $--color-text-primary; &:hover { color: $--color-primary; cursor: pointer; } } } &:last-child { .el-breadcrumb__inner, .el-breadcrumb__inner a { &, &:hover { font-weight: normal; color: $--color-text-regular; cursor: text; } } .el-breadcrumb__separator { display: none; } } } } ================================================ FILE: packages/theme-chalk/src/button-group.scss ================================================ ================================================ FILE: packages/theme-chalk/src/button.scss ================================================ @charset "UTF-8"; @import "common/var"; @import "mixins/button"; @import "mixins/mixins"; @import "mixins/utils"; @include b(button) { display: inline-block; line-height: 1; white-space: nowrap; cursor: pointer; background: $--button-default-background-color; border: $--border-base; border-color: $--button-default-border-color; color: $--button-default-font-color; -webkit-appearance: none; text-align: center; box-sizing: border-box; outline: none; margin: 0; transition: .1s; font-weight: $--button-font-weight; @include utils-user-select(none); & + & { margin-left: 10px; } @include button-size($--button-padding-vertical, $--button-padding-horizontal, $--button-font-size, $--button-border-radius); &:hover, &:focus { color: $--color-primary; border-color: $--color-primary-light-7; background-color: $--color-primary-light-9; } &:active { color: mix($--color-black, $--color-primary, $--button-active-shade-percent); border-color: mix($--color-black, $--color-primary, $--button-active-shade-percent); outline: none; } &::-moz-focus-inner { border: 0; } & [class*="el-icon-"] { & + span { margin-left: 5px; } } @include when(plain) { &:hover, &:focus { background: $--color-white; border-color: $--color-primary; color: $--color-primary; } &:active { background: $--color-white; border-color: mix($--color-black, $--color-primary, $--button-active-shade-percent); color: mix($--color-black, $--color-primary, $--button-active-shade-percent); outline: none; } } @include when(active) { color: mix($--color-black, $--color-primary, $--button-active-shade-percent); border-color: mix($--color-black, $--color-primary, $--button-active-shade-percent); } @include when(disabled) { &, &:hover, &:focus { color: $--button-disabled-font-color; cursor: not-allowed; background-image: none; background-color: $--button-disabled-background-color; border-color: $--button-disabled-border-color; } &.el-button--text { background-color: transparent; } &.is-plain { &, &:hover, &:focus { background-color: $--color-white; border-color: $--button-disabled-border-color; color: $--button-disabled-font-color; } } } @include when(loading) { position: relative; pointer-events: none; &:before { pointer-events: none; content: ''; position: absolute; left: -1px; top: -1px; right: -1px; bottom: -1px; border-radius: inherit; background-color: rgba(255,255,255,.35); } } @include when(round) { border-radius: 20px; padding: 12px 23px; } @include when(circle) { border-radius: 50%; padding: $--button-padding-vertical; } @include m(primary) { @include button-variant($--button-primary-font-color, $--button-primary-background-color, $--button-primary-border-color); } @include m(success) { @include button-variant($--button-success-font-color, $--button-success-background-color, $--button-success-border-color); } @include m(warning) { @include button-variant($--button-warning-font-color, $--button-warning-background-color, $--button-warning-border-color); } @include m(danger) { @include button-variant($--button-danger-font-color, $--button-danger-background-color, $--button-danger-border-color); } @include m(info) { @include button-variant($--button-info-font-color, $--button-info-background-color, $--button-info-border-color); } @include m(medium) { @include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, $--button-medium-border-radius); @include when(circle) { padding: $--button-medium-padding-vertical; } } @include m(small) { @include button-size($--button-small-padding-vertical, $--button-small-padding-horizontal, $--button-small-font-size, $--button-small-border-radius); @include when(circle) { padding: $--button-small-padding-vertical; } } @include m(mini) { @include button-size($--button-mini-padding-vertical, $--button-mini-padding-horizontal, $--button-mini-font-size, $--button-mini-border-radius); @include when(circle) { padding: $--button-mini-padding-vertical; } } @include m(text) { border-color: transparent; color: $--color-primary; background: transparent; padding-left: 0; padding-right: 0; &:hover, &:focus { color: mix($--color-white, $--color-primary, $--button-hover-tint-percent); border-color: transparent; background-color: transparent; } &:active { color: mix($--color-black, $--color-primary, $--button-active-shade-percent); border-color: transparent; background-color: transparent; } &.is-disabled, &.is-disabled:hover, &.is-disabled:focus { border-color: transparent; } } } @include b(button-group) { @include utils-clearfix; display: inline-block; vertical-align: middle; & > .el-button { float: left; position: relative; & + .el-button { margin-left: 0; } &.is-disabled { z-index: 1; } &:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; } &:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } &:first-child:last-child { border-top-right-radius: $--button-border-radius; border-bottom-right-radius: $--button-border-radius; border-top-left-radius: $--button-border-radius; border-bottom-left-radius: $--button-border-radius; &.is-round { border-radius: 20px; } &.is-circle { border-radius: 50%; } } &:not(:first-child):not(:last-child) { border-radius: 0; } &:not(:last-child) { margin-right: -1px; } &:not(.is-disabled) { &:hover, &:focus, &:active { z-index: 1; } } @include when(active) { z-index: 1; } } & > .el-dropdown { & > .el-button { border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-color: rgba($--color-white, 0.5); } } @each $type in (primary, success, warning, danger, info) { .el-button--#{$type} { &:first-child { border-right-color: rgba($--color-white, 0.5); } &:last-child { border-left-color: rgba($--color-white, 0.5); } &:not(:first-child):not(:last-child) { border-left-color: rgba($--color-white, 0.5); border-right-color: rgba($--color-white, 0.5); } } } } ================================================ FILE: packages/theme-chalk/src/calendar.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "button"; @import "button-group"; @include b(calendar) { background-color:#fff; @include e(header) { display: flex; justify-content: space-between; padding: 12px 20px; border-bottom: $--table-border; } @include e(title) { color: #000000; align-self: center; } @include e(body) { padding: 12px 20px 35px; } } @include b(calendar-table) { table-layout: fixed; width: 100%; thead th { padding: 12px 0; color: $--color-text-regular; font-weight: normal; } &:not(.is-range) { td.prev, td.next { color: $--color-text-placeholder; } } td { border-bottom: $--calendar-border; border-right: $--calendar-border; vertical-align: top; transition: background-color 0.2s ease; @include when(selected) { background-color: $--calendar-selected-background-color; } @include when(today) { color: $--color-primary; } } tr:first-child td { border-top: $--calendar-border; } tr td:first-child { border-left: $--calendar-border; } tr.el-calendar-table__row--hide-border td { border-top: none; } @include b(calendar-day) { box-sizing: border-box; padding: 8px; height: $--calendar-cell-width; &:hover { cursor: pointer; background-color: $--calendar-selected-background-color; } } } ================================================ FILE: packages/theme-chalk/src/card.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(card) { border-radius: $--card-border-radius; border: 1px solid $--card-border-color; background-color: $--color-white; overflow: hidden; color: $--color-text-primary; transition: 0.3s; @include when(always-shadow) { box-shadow: $--box-shadow-light; } @include when(hover-shadow) { &:hover, &:focus { box-shadow: $--box-shadow-light; } } @include e(header) { padding: #{$--card-padding - 2 $--card-padding}; border-bottom: 1px solid $--card-border-color; box-sizing: border-box; } @include e(body) { padding: $--card-padding; } } ================================================ FILE: packages/theme-chalk/src/carousel-item.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(carousel) { @include e(item) { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: inline-block; overflow: hidden; z-index: #{$--index-normal - 1}; @include when(active) { z-index: #{$--index-normal + 1}; } @include when(animating) { transition: transform .4s ease-in-out; } @include m(card) { width: 50%; transition: transform .4s ease-in-out; &.is-in-stage { cursor: pointer; z-index: $--index-normal; &:hover .el-carousel__mask, &.is-hover .el-carousel__mask { opacity: 0.12; } } &.is-active { z-index: #{$--index-normal + 1}; } } } @include e(mask) { position: absolute; width: 100%; height: 100%; top: 0; left: 0; background-color: $--color-white; opacity: 0.24; transition: .2s; } } ================================================ FILE: packages/theme-chalk/src/carousel.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(carousel) { position: relative; @include m(horizontal) { overflow-x: hidden; } @include m(vertical) { overflow-y: hidden; } @include e(container) { position: relative; height: 300px; } @include e(arrow) { border: none; outline: none; padding: 0; margin: 0; height: $--carousel-arrow-size; width: $--carousel-arrow-size; cursor: pointer; transition: .3s; border-radius: 50%; background-color: $--carousel-arrow-background; color: $--color-white; position: absolute; top: 50%; z-index: 10; transform: translateY(-50%); text-align: center; font-size: $--carousel-arrow-font-size; @include m(left) { left: 16px; } @include m(right) { right: 16px; } &:hover { background-color: $--carousel-arrow-hover-background; } & i { cursor: pointer; } } @include e(indicators) { position: absolute; list-style: none; margin: 0; padding: 0; z-index: #{$--index-normal + 1}; @include m(horizontal) { bottom: 0; left: 50%; transform: translateX(-50%); } @include m(vertical) { right: 0; top: 50%; transform: translateY(-50%); } @include m(outside) { bottom: #{$--carousel-indicator-height + $--carousel-indicator-padding-vertical * 2}; text-align: center; position: static; transform: none; .el-carousel__indicator:hover button { opacity: 0.64; } button { background-color: $--carousel-indicator-out-color; opacity: 0.24; } } @include m(labels) { left: 0; right: 0; transform: none; text-align: center; .el-carousel__button { height: auto; width: auto; padding: 2px 18px; font-size: 12px; } .el-carousel__indicator { padding: 6px 4px; } } } @include e(indicator) { background-color: transparent; cursor: pointer; &:hover button { opacity: 0.72; } @include m(horizontal) { display: inline-block; padding: $--carousel-indicator-padding-vertical $--carousel-indicator-padding-horizontal; } @include m(vertical) { padding: $--carousel-indicator-padding-horizontal $--carousel-indicator-padding-vertical; .el-carousel__button { width: $--carousel-indicator-height; height: #{$--carousel-indicator-width / 2}; } } @include when(active) { button { opacity: 1; } } } @include e(button) { display: block; opacity: 0.48; width: $--carousel-indicator-width; height: $--carousel-indicator-height; background-color: $--color-white; border: none; outline: none; padding: 0; margin: 0; cursor: pointer; transition: .3s; } } .carousel-arrow-left-enter, .carousel-arrow-left-leave-active { transform: translateY(-50%) translateX(-10px); opacity: 0; } .carousel-arrow-right-enter, .carousel-arrow-right-leave-active { transform: translateY(-50%) translateX(10px); opacity: 0; } ================================================ FILE: packages/theme-chalk/src/cascader-panel.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "./checkbox"; @import "./radio"; @import "./scrollbar"; @include b(cascader-panel) { display: flex; border-radius: $--cascader-menu-radius; font-size: $--cascader-menu-font-size; @include when(bordered) { border: $--cascader-menu-border; border-radius: $--cascader-menu-radius; } } @include b(cascader-menu) { min-width: 180px; box-sizing: border-box; color: $--cascader-menu-font-color; border-right: $--cascader-menu-border; &:last-child { border-right: none; .el-cascader-node { padding-right: 20px; } } @include e(wrap) { height: 204px; } @include e(list) { position: relative; min-height: 100%; margin: 0; padding: 6px 0; list-style: none; box-sizing: border-box; } @include e(hover-zone) { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } @include e(empty-text) { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: $--cascader-color-empty; } } @include b(cascader-node) { position: relative; display: flex; align-items: center; padding: 0 30px 0 20px; height: 34px; line-height: 34px; outline: none; &.is-selectable.in-active-path { color: $--cascader-menu-font-color; } &.in-active-path, &.is-selectable.in-checked-path, &.is-active { color: $--cascader-menu-selected-font-color; font-weight: bold; } &:not(.is-disabled) { cursor: pointer; &:hover, &:focus { background: $--cascader-node-background-hover; } } @include when(disabled) { color: $--cascader-node-color-disabled; cursor: not-allowed; } @include e(prefix) { position: absolute; left: 10px; } @include e(postfix) { position: absolute; right: 10px; } @include e(label) { flex: 1; padding: 0 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } > .el-radio { margin-right: 0; .el-radio__label { padding-left: 0; } } } ================================================ FILE: packages/theme-chalk/src/cascader.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "./input"; @import "./popper"; @import "./tag"; @import "./cascader-panel"; @include b(cascader) { display: inline-block; position: relative; font-size: $--font-size-base; line-height: $--input-height; &:not(.is-disabled):hover { .el-input__inner { cursor: pointer; border-color: $--input-hover-border; } } .el-input { cursor: pointer; .el-input__inner { text-overflow: ellipsis; &:focus { border-color: $--input-focus-border; } } .el-icon-arrow-down { transition: transform .3s; font-size: 14px; @include when(reverse) { transform: rotateZ(180deg); } } .el-icon-circle-close:hover { color: $--input-clear-hover-color; } @include when(focus) { .el-input__inner { border-color: $--input-focus-border; } } } @include m(medium) { font-size: $--input-medium-font-size; line-height: $--input-medium-height; } @include m(small) { font-size: $--input-small-font-size; line-height: $--input-small-height; } @include m(mini) { font-size: $--input-mini-font-size; line-height: $--input-mini-height; } @include when(disabled) { .el-cascader__label { z-index: #{$--index-normal + 1}; color: $--disabled-color-base; } } @include e(dropdown) { margin: 5px 0; font-size: $--cascader-menu-font-size; background: $--cascader-menu-fill; border: $--cascader-menu-border; border-radius: $--cascader-menu-radius; box-shadow: $--cascader-menu-shadow; } @include e(tags) { position: absolute; left: 0; right: 30px; top: 50%; transform: translateY(-50%); display: flex; flex-wrap: wrap; line-height: normal; text-align: left; box-sizing: border-box; .el-tag { display: inline-flex; align-items: center; max-width: 100%; margin: 2px 0 2px 6px; text-overflow: ellipsis; background: $--cascader-tag-background; &:not(.is-hit) { border-color: transparent; } > span { flex: 1; overflow: hidden; text-overflow: ellipsis; } .el-icon-close { flex: none; background-color: $--color-text-placeholder; color: $--color-white; &:hover { background-color: $--color-text-secondary; } } } } @include e(suggestion-panel) { border-radius: $--cascader-menu-radius; } @include e(suggestion-list) { max-height: 204px; margin: 0; padding: 6px 0; font-size: $--font-size-base; color: $--cascader-menu-font-color; text-align: center; } @include e(suggestion-item) { display: flex; justify-content: space-between; align-items: center; height: 34px; padding: 0 15px; text-align: left; outline: none; cursor: pointer; &:hover, &:focus { background: $--cascader-node-background-hover; } &.is-checked { color: $--cascader-menu-selected-font-color; font-weight: bold; } > span { margin-right: 10px; } } @include e(empty-text) { margin: 10px 0; color: $--cascader-color-empty; } @include e(search-input) { flex: 1; height: 24px; min-width: 60px; margin: 2px 0 2px 15px; padding: 0; color: $--cascader-menu-font-color; border: none; outline: none; box-sizing: border-box; &::placeholder { color: $--color-text-placeholder; } } } ================================================ FILE: packages/theme-chalk/src/checkbox-button.scss ================================================ ================================================ FILE: packages/theme-chalk/src/checkbox-group.scss ================================================ ================================================ FILE: packages/theme-chalk/src/checkbox.scss ================================================ @import "common/var"; @import "mixins/mixins"; @import "mixins/_button"; @import "mixins/utils"; @include b(checkbox) { color: $--checkbox-font-color; font-weight: $--checkbox-font-weight; font-size: $--font-size-base; position: relative; cursor: pointer; display: inline-block; white-space: nowrap; user-select: none; margin-right: 30px; @include when(bordered) { padding: $--checkbox-bordered-padding; border-radius: $--border-radius-base; border: $--border-base; box-sizing: border-box; line-height: normal; height: $--checkbox-bordered-height; &.is-checked { border-color: $--color-primary; } &.is-disabled { border-color: $--border-color-lighter; cursor: not-allowed; } & + .el-checkbox.is-bordered { margin-left: 10px; } &.el-checkbox--medium { padding: $--checkbox-bordered-medium-padding; border-radius: $--button-medium-border-radius; height: $--checkbox-bordered-medium-height; .el-checkbox__label { line-height: 17px; font-size: $--button-medium-font-size; } .el-checkbox__inner { height: $--checkbox-bordered-medium-input-height; width: $--checkbox-bordered-medium-input-width; } } &.el-checkbox--small { padding: $--checkbox-bordered-small-padding; border-radius: $--button-small-border-radius; height: $--checkbox-bordered-small-height; .el-checkbox__label { line-height: 15px; font-size: $--button-small-font-size; } .el-checkbox__inner { height: $--checkbox-bordered-small-input-height; width: $--checkbox-bordered-small-input-width; &::after { height: 6px; width: 2px; } } } &.el-checkbox--mini { padding: $--checkbox-bordered-mini-padding; border-radius: $--button-mini-border-radius; height: $--checkbox-bordered-mini-height; .el-checkbox__label { line-height: 12px; font-size: $--button-mini-font-size; } .el-checkbox__inner { height: $--checkbox-bordered-mini-input-height; width: $--checkbox-bordered-mini-input-width; &::after { height: 6px; width: 2px; } } } } @include e(input) { white-space: nowrap; cursor: pointer; outline: none; display: inline-block; line-height: 1; position: relative; vertical-align: middle; @include when(disabled) { .el-checkbox__inner { background-color: $--checkbox-disabled-input-fill; border-color: $--checkbox-disabled-border-color; cursor: not-allowed; &::after { cursor: not-allowed; border-color: $--checkbox-disabled-icon-color; } & + .el-checkbox__label { cursor: not-allowed; } } &.is-checked { .el-checkbox__inner { background-color: $--checkbox-disabled-checked-input-fill; border-color: $--checkbox-disabled-checked-input-border-color; &::after { border-color: $--checkbox-disabled-checked-icon-color; } } } &.is-indeterminate { .el-checkbox__inner { background-color: $--checkbox-disabled-checked-input-fill; border-color: $--checkbox-disabled-checked-input-border-color; &::before { background-color: $--checkbox-disabled-checked-icon-color; border-color: $--checkbox-disabled-checked-icon-color; } } } & + span.el-checkbox__label { color: $--disabled-color-base; cursor: not-allowed; } } @include when(checked) { .el-checkbox__inner { background-color: $--checkbox-checked-background-color; border-color: $--checkbox-checked-input-border-color; &::after { transform: rotate(45deg) scaleY(1); } } & + .el-checkbox__label { color: $--checkbox-checked-font-color; } } @include when(focus) { /*focus时 视觉上区分*/ .el-checkbox__inner { border-color: $--checkbox-input-border-color-hover; } } @include when(indeterminate) { .el-checkbox__inner { background-color: $--checkbox-checked-background-color; border-color: $--checkbox-checked-input-border-color; &::before { content: ''; position: absolute; display: block; background-color: $--checkbox-checked-icon-color; height: 2px; transform: scale(0.5); left: 0; right: 0; top: 5px; } &::after { display: none; } } } } @include e(inner) { display: inline-block; position: relative; border: $--checkbox-input-border; border-radius: $--checkbox-border-radius; box-sizing: border-box; width: $--checkbox-input-width; height: $--checkbox-input-height; background-color: $--checkbox-background-color; z-index: $--index-normal; transition: border-color .25s cubic-bezier(.71,-.46,.29,1.46), background-color .25s cubic-bezier(.71,-.46,.29,1.46); &:hover { border-color: $--checkbox-input-border-color-hover; } &::after { box-sizing: content-box; content: ""; border: 1px solid $--checkbox-checked-icon-color; border-left: 0; border-top: 0; height: 7px; left: 4px; position: absolute; top: 1px; transform: rotate(45deg) scaleY(0); width: 3px; transition: transform .15s ease-in .05s; transform-origin: center; } } @include e(original) { opacity: 0; outline: none; position: absolute; margin: 0; width: 0; height: 0; z-index: -1; } @include e(label) { display: inline-block; padding-left: 10px; line-height: 19px; font-size: $--checkbox-font-size; } &:last-of-type { margin-right: 0; } } @include b(checkbox-button) { position: relative; display: inline-block; @include e(inner) { display: inline-block; line-height: 1; font-weight: $--checkbox-font-weight; white-space: nowrap; vertical-align: middle; cursor: pointer; background: $--button-default-background-color; border: $--border-base; border-left: 0; color: $--button-default-font-color; -webkit-appearance: none; text-align: center; box-sizing: border-box; outline: none; margin: 0; position: relative; transition: $--all-transition; @include utils-user-select(none); @include button-size($--button-padding-vertical, $--button-padding-horizontal, $--button-font-size, 0); &:hover { color: $--color-primary; } & [class*="el-icon-"] { line-height: 0.9; & + span { margin-left: 5px; } } } @include e(original) { opacity: 0; outline: none; position: absolute; margin: 0; z-index: -1; } &.is-checked { & .el-checkbox-button__inner { color: $--checkbox-button-checked-font-color; background-color: $--checkbox-button-checked-background-color; border-color: $--checkbox-button-checked-border-color; box-shadow: -1px 0 0 0 $--color-primary-light-4; } &:first-child .el-checkbox-button__inner { border-left-color: $--checkbox-button-checked-border-color; } } &.is-disabled { & .el-checkbox-button__inner { color: $--button-disabled-font-color; cursor: not-allowed; background-image: none; background-color: $--button-disabled-background-color; border-color: $--button-disabled-border-color; box-shadow: none; } &:first-child .el-checkbox-button__inner { border-left-color: $--button-disabled-border-color; } } &:first-child { .el-checkbox-button__inner { border-left: $--border-base; border-radius: $--border-radius-base 0 0 $--border-radius-base; box-shadow: none !important; } } &.is-focus { & .el-checkbox-button__inner { border-color: $--checkbox-button-checked-border-color; } } &:last-child { .el-checkbox-button__inner { border-radius: 0 $--border-radius-base $--border-radius-base 0; } } @include m(medium) { .el-checkbox-button__inner { @include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, 0); } } @include m(small) { .el-checkbox-button__inner { @include button-size($--button-small-padding-vertical, $--button-small-padding-horizontal, $--button-small-font-size, 0); } } @include m(mini) { .el-checkbox-button__inner { @include button-size($--button-mini-padding-vertical, $--button-mini-padding-horizontal, $--button-mini-font-size, 0); } } } @include b(checkbox-group) { font-size: 0; } ================================================ FILE: packages/theme-chalk/src/col.scss ================================================ @import "./common/var.scss"; @import "./mixins/mixins.scss"; [class*="el-col-"] { float: left; box-sizing: border-box; } .el-col-0 { display: none; } @for $i from 0 through 24 { .el-col-#{$i} { width: (1 / 24 * $i * 100) * 1%; } .el-col-offset-#{$i} { margin-left: (1 / 24 * $i * 100) * 1%; } .el-col-pull-#{$i} { position: relative; right: (1 / 24 * $i * 100) * 1%; } .el-col-push-#{$i} { position: relative; left: (1 / 24 * $i * 100) * 1%; } } @include res(xs) { .el-col-xs-0 { display: none; } @for $i from 0 through 24 { .el-col-xs-#{$i} { width: (1 / 24 * $i * 100) * 1%; } .el-col-xs-offset-#{$i} { margin-left: (1 / 24 * $i * 100) * 1%; } .el-col-xs-pull-#{$i} { position: relative; right: (1 / 24 * $i * 100) * 1%; } .el-col-xs-push-#{$i} { position: relative; left: (1 / 24 * $i * 100) * 1%; } } } @include res(sm) { .el-col-sm-0 { display: none; } @for $i from 0 through 24 { .el-col-sm-#{$i} { width: (1 / 24 * $i * 100) * 1%; } .el-col-sm-offset-#{$i} { margin-left: (1 / 24 * $i * 100) * 1%; } .el-col-sm-pull-#{$i} { position: relative; right: (1 / 24 * $i * 100) * 1%; } .el-col-sm-push-#{$i} { position: relative; left: (1 / 24 * $i * 100) * 1%; } } } @include res(md) { .el-col-md-0 { display: none; } @for $i from 0 through 24 { .el-col-md-#{$i} { width: (1 / 24 * $i * 100) * 1%; } .el-col-md-offset-#{$i} { margin-left: (1 / 24 * $i * 100) * 1%; } .el-col-md-pull-#{$i} { position: relative; right: (1 / 24 * $i * 100) * 1%; } .el-col-md-push-#{$i} { position: relative; left: (1 / 24 * $i * 100) * 1%; } } } @include res(lg) { .el-col-lg-0 { display: none; } @for $i from 0 through 24 { .el-col-lg-#{$i} { width: (1 / 24 * $i * 100) * 1%; } .el-col-lg-offset-#{$i} { margin-left: (1 / 24 * $i * 100) * 1%; } .el-col-lg-pull-#{$i} { position: relative; right: (1 / 24 * $i * 100) * 1%; } .el-col-lg-push-#{$i} { position: relative; left: (1 / 24 * $i * 100) * 1%; } } } @include res(xl) { .el-col-xl-0 { display: none; } @for $i from 0 through 24 { .el-col-xl-#{$i} { width: (1 / 24 * $i * 100) * 1%; } .el-col-xl-offset-#{$i} { margin-left: (1 / 24 * $i * 100) * 1%; } .el-col-xl-pull-#{$i} { position: relative; right: (1 / 24 * $i * 100) * 1%; } .el-col-xl-push-#{$i} { position: relative; left: (1 / 24 * $i * 100) * 1%; } } } ================================================ FILE: packages/theme-chalk/src/collapse-item.scss ================================================ ================================================ FILE: packages/theme-chalk/src/collapse.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "common/transition"; @include b(collapse) { border-top: 1px solid $--collapse-border-color; border-bottom: 1px solid $--collapse-border-color; } @include b(collapse-item) { @include when(disabled) { .el-collapse-item__header { color: $--font-color-disabled-base; cursor: not-allowed; } } @include e(header) { display: flex; align-items: center; height: $--collapse-header-height; line-height: $--collapse-header-height; background-color: $--collapse-header-background-color; color: $--collapse-header-font-color; cursor: pointer; border-bottom: 1px solid $--collapse-border-color; font-size: $--collapse-header-font-size; font-weight: 500; transition: border-bottom-color .3s; outline: none; @include e(arrow) { margin: 0 8px 0 auto; transition: transform .3s; font-weight: 300; @include when(active) { transform: rotate(90deg); } } &.focusing:focus:not(:hover){ color: $--color-primary; } @include when(active) { border-bottom-color: transparent; } } @include e(wrap) { will-change: height; background-color: $--collapse-content-background-color; overflow: hidden; box-sizing: border-box; border-bottom: 1px solid $--collapse-border-color; } @include e(content) { padding-bottom: 25px; font-size: $--collapse-content-font-size; color: $--collapse-content-font-color; line-height: 1.769230769230769; } &:last-child { margin-bottom: -1px; } } ================================================ FILE: packages/theme-chalk/src/color-picker.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(color-predefine) { display: flex; font-size: 12px; margin-top: 8px; width: 280px; @include e(colors) { display: flex; flex: 1; flex-wrap: wrap; } @include e(color-selector) { margin: 0 0 8px 8px; width: 20px; height: 20px; border-radius: 4px; cursor: pointer; &:nth-child(10n + 1) { margin-left: 0; } &.selected { box-shadow: 0 0 3px 2px $--color-primary; } > div { display: flex; height: 100%; border-radius: 3px; } @include when(alpha) { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); } } } @include b(color-hue-slider) { position: relative; box-sizing: border-box; width: 280px; height: 12px; background-color: #f00; padding: 0 2px; @include e(bar) { position: relative; background: linear-gradient( to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); height: 100%; } @include e(thumb) { position: absolute; cursor: pointer; box-sizing: border-box; left: 0; top: 0; width: 4px; height: 100%; border-radius: 1px; background: #fff; border: 1px solid #f0f0f0; box-shadow: 0 0 2px rgba(0, 0, 0, 0.6); z-index: 1; } @include when(vertical) { width: 12px; height: 180px; padding: 2px 0; .el-color-hue-slider__bar { background: linear-gradient( to bottom, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); } .el-color-hue-slider__thumb { left: 0; top: 0; width: 100%; height: 4px; } } } @include b(color-svpanel) { position: relative; width: 280px; height: 180px; @include e(('white', 'black')) { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } @include e('white') { background: linear-gradient(to right, #fff, rgba(255,255,255,0)); } @include e('black') { background: linear-gradient(to top, #000, rgba(0,0,0,0)); } @include e(cursor) { position: absolute; > div { cursor: head; width: 4px; height: 4px; box-shadow: 0 0 0 1.5px #fff, inset 0 0 1px 1px rgba(0,0,0,0.3), 0 0 1px 2px rgba(0,0,0,0.4); border-radius: 50%; transform: translate(-2px, -2px); } } } @include b(color-alpha-slider) { position: relative; box-sizing: border-box; width: 280px; height: 12px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); @include e(bar) { position: relative; background: linear-gradient( to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%); height: 100%; } @include e(thumb) { position: absolute; cursor: pointer; box-sizing: border-box; left: 0; top: 0; width: 4px; height: 100%; border-radius: 1px; background: #fff; border: 1px solid #f0f0f0; box-shadow: 0 0 2px rgba(0, 0, 0, 0.6); z-index: 1; } @include when(vertical) { width: 20px; height: 180px; .el-color-alpha-slider__bar { background: linear-gradient( to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%); } .el-color-alpha-slider__thumb { left: 0; top: 0; width: 100%; height: 4px; } } } @include b(color-dropdown) { width: 300px; @include e(main-wrapper) { margin-bottom: 6px; &::after { content: ""; display: table; clear: both; } } @include e(btns) { margin-top: 6px; text-align: right; } @include e(value) { float: left; line-height: 26px; font-size: 12px; color: $--color-black; width: 160px; } @include e(btn) { border: 1px solid #dcdcdc; color: #333; line-height: 24px; border-radius: 2px; padding: 0 20px; cursor: pointer; background-color: transparent; outline: none; font-size: 12px; &[disabled] { color: #cccccc; cursor: not-allowed; } &:hover { color: $--color-primary; border-color: $--color-primary; } } @include e(link-btn) { cursor: pointer; color: $--color-primary; text-decoration: none; padding: 15px; font-size: 12px; &:hover { color: tint($--color-primary, $--button-hover-tint-percent); } } } @include b(color-picker) { display: inline-block; position: relative; line-height: normal; height: 40px; @include when(disabled) { .el-color-picker__trigger { cursor: not-allowed; } } @include m(medium) { height: 36px; .el-color-picker__trigger { height: 36px; width: 36px; } .el-color-picker__mask { height: 34px; width: 34px; } } @include m(small) { height: 32px; .el-color-picker__trigger { height: 32px; width: 32px; } .el-color-picker__mask { height: 30px; width: 30px; } .el-color-picker__icon, .el-color-picker__empty { transform: translate3d(-50%, -50%, 0) scale(0.8); } } @include m(mini) { height: 28px; .el-color-picker__trigger { height: 28px; width: 28px; } .el-color-picker__mask { height: 26px; width: 26px; } .el-color-picker__icon, .el-color-picker__empty { transform: translate3d(-50%, -50%, 0) scale(0.8); } } @include e(mask) { height: 38px; width: 38px; border-radius: 4px; position: absolute; top: 1px; left: 1px; z-index: 1; cursor: not-allowed; background-color: rgba(255, 255, 255, .7); } @include e(trigger) { display: inline-block; box-sizing: border-box; height: 40px; width: 40px; padding: 4px; border: 1px solid #e6e6e6; border-radius: 4px; font-size: 0; position: relative; cursor: pointer; } @include e(color) { position: relative; display: block; box-sizing: border-box; border: 1px solid #999; border-radius: $--border-radius-small; width: 100%; height: 100%; text-align: center; @include when(alpha) { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); } } @include e(color-inner) { position: absolute; left: 0; top: 0; right: 0; bottom: 0; } @include e(empty) { font-size: 12px; color: #999; position: absolute; top: 50%; left: 50%; transform: translate3d(-50%, -50%, 0); } @include e(icon) { display: inline-block; position: absolute; width: 100%; top: 50%; left: 50%; transform: translate3d(-50%, -50%, 0); color: $--color-white; text-align: center; font-size: 12px; } @include e(panel) { position: absolute; z-index: 10; padding: 6px; box-sizing: content-box; background-color: $--color-white; border: 1px solid $--border-color-lighter; border-radius: $--border-radius-base; box-shadow: $--dropdown-menu-box-shadow; } } ================================================ FILE: packages/theme-chalk/src/common/popup.scss ================================================ @import "./var.scss"; @import "../mixins/mixins"; .v-modal-enter { animation: v-modal-in .2s ease; } .v-modal-leave { animation: v-modal-out .2s ease forwards; } @keyframes v-modal-in { 0% { opacity: 0; } 100% { } } @keyframes v-modal-out { 0% { } 100% { opacity: 0; } } .v-modal { position: fixed; left: 0; top: 0; width: 100%; height: 100%; opacity: $--popup-modal-opacity; background: $--popup-modal-background-color; } @include b(popup-parent) { @include m(hidden) { overflow: hidden; } } ================================================ FILE: packages/theme-chalk/src/common/transition.scss ================================================ @import "var"; .fade-in-linear-enter-active, .fade-in-linear-leave-active { transition: $--fade-linear-transition; } .fade-in-linear-enter, .fade-in-linear-leave, .fade-in-linear-leave-active { opacity: 0; } .el-fade-in-linear-enter-active, .el-fade-in-linear-leave-active { transition: $--fade-linear-transition; } .el-fade-in-linear-enter, .el-fade-in-linear-leave, .el-fade-in-linear-leave-active { opacity: 0; } .el-fade-in-enter-active, .el-fade-in-leave-active { transition: all .3s cubic-bezier(.55,0,.1,1); } .el-fade-in-enter, .el-fade-in-leave-active { opacity: 0; } .el-zoom-in-center-enter-active, .el-zoom-in-center-leave-active { transition: all .3s cubic-bezier(.55,0,.1,1); } .el-zoom-in-center-enter, .el-zoom-in-center-leave-active { opacity: 0; transform: scaleX(0); } .el-zoom-in-top-enter-active, .el-zoom-in-top-leave-active { opacity: 1; transform: scaleY(1); transition: $--md-fade-transition; transform-origin: center top; } .el-zoom-in-top-enter, .el-zoom-in-top-leave-active { opacity: 0; transform: scaleY(0); } .el-zoom-in-bottom-enter-active, .el-zoom-in-bottom-leave-active { opacity: 1; transform: scaleY(1); transition: $--md-fade-transition; transform-origin: center bottom; } .el-zoom-in-bottom-enter, .el-zoom-in-bottom-leave-active { opacity: 0; transform: scaleY(0); } .el-zoom-in-left-enter-active, .el-zoom-in-left-leave-active { opacity: 1; transform: scale(1, 1); transition: $--md-fade-transition; transform-origin: top left; } .el-zoom-in-left-enter, .el-zoom-in-left-leave-active { opacity: 0; transform: scale(.45, .45); } .collapse-transition { transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out; } .horizontal-collapse-transition { transition: 0.3s width ease-in-out, 0.3s padding-left ease-in-out, 0.3s padding-right ease-in-out; } .el-list-enter-active, .el-list-leave-active { transition: all 1s; } .el-list-enter, .el-list-leave-active { opacity: 0; transform: translateY(-30px); } .el-opacity-transition { transition: opacity .3s cubic-bezier(.55,0,.1,1); } ================================================ FILE: packages/theme-chalk/src/common/var.scss ================================================ /* Element Chalk Variables */ // Special comment for theme configurator // type|skipAutoTranslation|Category|Order // skipAutoTranslation 1 /* Transition -------------------------- */ $--all-transition: all .3s cubic-bezier(.645,.045,.355,1) !default; $--fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default; $--fade-linear-transition: opacity 200ms linear !default; $--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) !default; $--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1) !default; $--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default; /* Color -------------------------- */ /// color|1|Brand Color|0 $--color-primary: #409EFF !default; /// color|1|Background Color|4 $--color-white: #FFFFFF !default; /// color|1|Background Color|4 $--color-black: #000000 !default; $--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */ $--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */ $--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */ $--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */ $--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */ $--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */ $--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */ $--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */ $--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */ /// color|1|Functional Color|1 $--color-success: #67C23A !default; /// color|1|Functional Color|1 $--color-warning: #E6A23C !default; /// color|1|Functional Color|1 $--color-danger: #F56C6C !default; /// color|1|Functional Color|1 $--color-info: #909399 !default; $--color-success-light: mix($--color-white, $--color-success, 80%) !default; $--color-warning-light: mix($--color-white, $--color-warning, 80%) !default; $--color-danger-light: mix($--color-white, $--color-danger, 80%) !default; $--color-info-light: mix($--color-white, $--color-info, 80%) !default; $--color-success-lighter: mix($--color-white, $--color-success, 90%) !default; $--color-warning-lighter: mix($--color-white, $--color-warning, 90%) !default; $--color-danger-lighter: mix($--color-white, $--color-danger, 90%) !default; $--color-info-lighter: mix($--color-white, $--color-info, 90%) !default; /// color|1|Font Color|2 $--color-text-primary: #303133 !default; /// color|1|Font Color|2 $--color-text-regular: #606266 !default; /// color|1|Font Color|2 $--color-text-secondary: #909399 !default; /// color|1|Font Color|2 $--color-text-placeholder: #C0C4CC !default; /// color|1|Border Color|3 $--border-color-base: #DCDFE6 !default; /// color|1|Border Color|3 $--border-color-light: #E4E7ED !default; /// color|1|Border Color|3 $--border-color-lighter: #EBEEF5 !default; /// color|1|Border Color|3 $--border-color-extra-light: #F2F6FC !default; // Background /// color|1|Background Color|4 $--background-color-base: #F5F7FA !default; /* Link -------------------------- */ $--link-color: $--color-primary-light-2 !default; $--link-hover-color: $--color-primary !default; /* Border -------------------------- */ $--border-width-base: 1px !default; $--border-style-base: solid !default; $--border-color-hover: $--color-text-placeholder !default; $--border-base: $--border-width-base $--border-style-base $--border-color-base !default; /// borderRadius|1|Radius|0 $--border-radius-base: 4px !default; /// borderRadius|1|Radius|0 $--border-radius-small: 2px !default; /// borderRadius|1|Radius|0 $--border-radius-circle: 100% !default; /// borderRadius|1|Radius|0 $--border-radius-zero: 0 !default; // Box-shadow /// boxShadow|1|Shadow|1 $--box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) !default; // boxShadow|1|Shadow|1 $--box-shadow-dark: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .12) !default; /// boxShadow|1|Shadow|1 $--box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !default; /* Fill -------------------------- */ $--fill-base: $--color-white !default; /* Typography -------------------------- */ $--font-path: 'fonts' !default; $--font-display: 'auto' !default; /// fontSize|1|Font Size|0 $--font-size-extra-large: 20px !default; /// fontSize|1|Font Size|0 $--font-size-large: 18px !default; /// fontSize|1|Font Size|0 $--font-size-medium: 16px !default; /// fontSize|1|Font Size|0 $--font-size-base: 14px !default; /// fontSize|1|Font Size|0 $--font-size-small: 13px !default; /// fontSize|1|Font Size|0 $--font-size-extra-small: 12px !default; /// fontWeight|1|Font Weight|1 $--font-weight-primary: 500 !default; /// fontWeight|1|Font Weight|1 $--font-weight-secondary: 100 !default; /// fontLineHeight|1|Line Height|2 $--font-line-height-primary: 24px !default; /// fontLineHeight|1|Line Height|2 $--font-line-height-secondary: 16px !default; $--font-color-disabled-base: #bbb !default; /* Size -------------------------- */ $--size-base: 14px !default; /* z-index -------------------------- */ $--index-normal: 1 !default; $--index-top: 1000 !default; $--index-popper: 2000 !default; /* Disable base -------------------------- */ $--disabled-fill-base: $--background-color-base !default; $--disabled-color-base: $--color-text-placeholder !default; $--disabled-border-base: $--border-color-light !default; /* Icon -------------------------- */ $--icon-color: #666 !default; $--icon-color-base: $--color-info !default; /* Checkbox -------------------------- */ /// fontSize||Font|1 $--checkbox-font-size: 14px !default; /// fontWeight||Font|1 $--checkbox-font-weight: $--font-weight-primary !default; /// color||Color|0 $--checkbox-font-color: $--color-text-regular !default; $--checkbox-input-height: 14px !default; $--checkbox-input-width: 14px !default; /// borderRadius||Border|2 $--checkbox-border-radius: $--border-radius-small !default; /// color||Color|0 $--checkbox-background-color: $--color-white !default; $--checkbox-input-border: $--border-base !default; /// color||Color|0 $--checkbox-disabled-border-color: $--border-color-base !default; $--checkbox-disabled-input-fill: #edf2fc !default; $--checkbox-disabled-icon-color: $--color-text-placeholder !default; $--checkbox-disabled-checked-input-fill: $--border-color-extra-light !default; $--checkbox-disabled-checked-input-border-color: $--border-color-base !default; $--checkbox-disabled-checked-icon-color: $--color-text-placeholder !default; /// color||Color|0 $--checkbox-checked-font-color: $--color-primary !default; $--checkbox-checked-input-border-color: $--color-primary !default; /// color||Color|0 $--checkbox-checked-background-color: $--color-primary !default; $--checkbox-checked-icon-color: $--fill-base !default; $--checkbox-input-border-color-hover: $--color-primary !default; /// height||Other|4 $--checkbox-bordered-height: 40px !default; /// padding||Spacing|3 $--checkbox-bordered-padding: 9px 20px 9px 10px !default; /// padding||Spacing|3 $--checkbox-bordered-medium-padding: 7px 20px 7px 10px !default; /// padding||Spacing|3 $--checkbox-bordered-small-padding: 5px 15px 5px 10px !default; /// padding||Spacing|3 $--checkbox-bordered-mini-padding: 3px 15px 3px 10px !default; $--checkbox-bordered-medium-input-height: 14px !default; $--checkbox-bordered-medium-input-width: 14px !default; /// height||Other|4 $--checkbox-bordered-medium-height: 36px !default; $--checkbox-bordered-small-input-height: 12px !default; $--checkbox-bordered-small-input-width: 12px !default; /// height||Other|4 $--checkbox-bordered-small-height: 32px !default; $--checkbox-bordered-mini-input-height: 12px !default; $--checkbox-bordered-mini-input-width: 12px !default; /// height||Other|4 $--checkbox-bordered-mini-height: 28px !default; /// color||Color|0 $--checkbox-button-checked-background-color: $--color-primary !default; /// color||Color|0 $--checkbox-button-checked-font-color: $--color-white !default; /// color||Color|0 $--checkbox-button-checked-border-color: $--color-primary !default; /* Radio -------------------------- */ /// fontSize||Font|1 $--radio-font-size: $--font-size-base !default; /// fontWeight||Font|1 $--radio-font-weight: $--font-weight-primary !default; /// color||Color|0 $--radio-font-color: $--color-text-regular !default; $--radio-input-height: 14px !default; $--radio-input-width: 14px !default; /// borderRadius||Border|2 $--radio-input-border-radius: $--border-radius-circle !default; /// color||Color|0 $--radio-input-background-color: $--color-white !default; $--radio-input-border: $--border-base !default; /// color||Color|0 $--radio-input-border-color: $--border-color-base !default; /// color||Color|0 $--radio-icon-color: $--color-white !default; $--radio-disabled-input-border-color: $--disabled-border-base !default; $--radio-disabled-input-fill: $--disabled-fill-base !default; $--radio-disabled-icon-color: $--disabled-fill-base !default; $--radio-disabled-checked-input-border-color: $--disabled-border-base !default; $--radio-disabled-checked-input-fill: $--disabled-fill-base !default; $--radio-disabled-checked-icon-color: $--color-text-placeholder !default; /// color||Color|0 $--radio-checked-font-color: $--color-primary !default; /// color||Color|0 $--radio-checked-input-border-color: $--color-primary !default; /// color||Color|0 $--radio-checked-input-background-color: $--color-white !default; /// color||Color|0 $--radio-checked-icon-color: $--color-primary !default; $--radio-input-border-color-hover: $--color-primary !default; $--radio-bordered-height: 40px !default; $--radio-bordered-padding: 12px 20px 0 10px !default; $--radio-bordered-medium-padding: 10px 20px 0 10px !default; $--radio-bordered-small-padding: 8px 15px 0 10px !default; $--radio-bordered-mini-padding: 6px 15px 0 10px !default; $--radio-bordered-medium-input-height: 14px !default; $--radio-bordered-medium-input-width: 14px !default; $--radio-bordered-medium-height: 36px !default; $--radio-bordered-small-input-height: 12px !default; $--radio-bordered-small-input-width: 12px !default; $--radio-bordered-small-height: 32px !default; $--radio-bordered-mini-input-height: 12px !default; $--radio-bordered-mini-input-width: 12px !default; $--radio-bordered-mini-height: 28px !default; /// fontSize||Font|1 $--radio-button-font-size: $--font-size-base !default; /// color||Color|0 $--radio-button-checked-background-color: $--color-primary !default; /// color||Color|0 $--radio-button-checked-font-color: $--color-white !default; /// color||Color|0 $--radio-button-checked-border-color: $--color-primary !default; $--radio-button-disabled-checked-fill: $--border-color-extra-light !default; /* Select -------------------------- */ $--select-border-color-hover: $--border-color-hover !default; $--select-disabled-border: $--disabled-border-base !default; /// fontSize||Font|1 $--select-font-size: $--font-size-base !default; $--select-close-hover-color: $--color-text-secondary !default; $--select-input-color: $--color-text-placeholder !default; $--select-multiple-input-color: #666 !default; /// color||Color|0 $--select-input-focus-border-color: $--color-primary !default; /// fontSize||Font|1 $--select-input-font-size: 14px !default; $--select-option-color: $--color-text-regular !default; $--select-option-disabled-color: $--color-text-placeholder !default; $--select-option-disabled-background: $--color-white !default; /// height||Other|4 $--select-option-height: 34px !default; $--select-option-hover-background: $--background-color-base !default; /// color||Color|0 $--select-option-selected-font-color: $--color-primary !default; $--select-option-selected-hover: $--background-color-base !default; $--select-group-color: $--color-info !default; $--select-group-height: 30px !default; $--select-group-font-size: 12px !default; $--select-dropdown-background: $--color-white !default; $--select-dropdown-shadow: $--box-shadow-light !default; $--select-dropdown-empty-color: #999 !default; /// height||Other|4 $--select-dropdown-max-height: 274px !default; $--select-dropdown-padding: 6px 0 !default; $--select-dropdown-empty-padding: 10px 0 !default; $--select-dropdown-border: solid 1px $--border-color-light !default; /* Alert -------------------------- */ $--alert-padding: 8px 16px !default; /// borderRadius||Border|2 $--alert-border-radius: $--border-radius-base !default; /// fontSize||Font|1 $--alert-title-font-size: 13px !default; /// fontSize||Font|1 $--alert-description-font-size: 12px !default; /// fontSize||Font|1 $--alert-close-font-size: 12px !default; /// fontSize||Font|1 $--alert-close-customed-font-size: 13px !default; $--alert-success-color: $--color-success-lighter !default; $--alert-info-color: $--color-info-lighter !default; $--alert-warning-color: $--color-warning-lighter !default; $--alert-danger-color: $--color-danger-lighter !default; /// height||Other|4 $--alert-icon-size: 16px !default; /// height||Other|4 $--alert-icon-large-size: 28px !default; /* MessageBox -------------------------- */ /// color||Color|0 $--messagebox-title-color: $--color-text-primary !default; $--msgbox-width: 420px !default; $--msgbox-border-radius: 4px !default; /// fontSize||Font|1 $--messagebox-font-size: $--font-size-large !default; /// fontSize||Font|1 $--messagebox-content-font-size: $--font-size-base !default; /// color||Color|0 $--messagebox-content-color: $--color-text-regular !default; /// fontSize||Font|1 $--messagebox-error-font-size: 12px !default; $--msgbox-padding-primary: 15px !default; /// color||Color|0 $--messagebox-success-color: $--color-success !default; /// color||Color|0 $--messagebox-info-color: $--color-info !default; /// color||Color|0 $--messagebox-warning-color: $--color-warning !default; /// color||Color|0 $--messagebox-danger-color: $--color-danger !default; /* Message -------------------------- */ $--message-shadow: $--box-shadow-base !default; $--message-min-width: 380px !default; $--message-background-color: #edf2fc !default; $--message-padding: 15px 15px 15px 20px !default; /// color||Color|0 $--message-close-icon-color: $--color-text-placeholder !default; /// height||Other|4 $--message-close-size: 16px !default; /// color||Color|0 $--message-close-hover-color: $--color-text-secondary !default; /// color||Color|0 $--message-success-font-color: $--color-success !default; /// color||Color|0 $--message-info-font-color: $--color-info !default; /// color||Color|0 $--message-warning-font-color: $--color-warning !default; /// color||Color|0 $--message-danger-font-color: $--color-danger !default; /* Notification -------------------------- */ $--notification-width: 330px !default; /// padding||Spacing|3 $--notification-padding: 14px 26px 14px 13px !default; $--notification-radius: 8px !default; $--notification-shadow: $--box-shadow-light !default; /// color||Color|0 $--notification-border-color: $--border-color-lighter !default; $--notification-icon-size: 24px !default; $--notification-close-font-size: $--message-close-size !default; $--notification-group-margin-left: 13px !default; $--notification-group-margin-right: 8px !default; /// fontSize||Font|1 $--notification-content-font-size: $--font-size-base !default; /// color||Color|0 $--notification-content-color: $--color-text-regular !default; /// fontSize||Font|1 $--notification-title-font-size: 16px !default; /// color||Color|0 $--notification-title-color: $--color-text-primary !default; /// color||Color|0 $--notification-close-color: $--color-text-secondary !default; /// color||Color|0 $--notification-close-hover-color: $--color-text-regular !default; /// color||Color|0 $--notification-success-icon-color: $--color-success !default; /// color||Color|0 $--notification-info-icon-color: $--color-info !default; /// color||Color|0 $--notification-warning-icon-color: $--color-warning !default; /// color||Color|0 $--notification-danger-icon-color: $--color-danger !default; /* Input -------------------------- */ $--input-font-size: $--font-size-base !default; /// color||Color|0 $--input-font-color: $--color-text-regular !default; /// height||Other|4 $--input-height: 40px !default; $--input-border: $--border-base !default; $--input-border-color: $--border-color-base !default; /// borderRadius||Border|2 $--input-border-radius: $--border-radius-base !default; $--input-border-color-hover: $--border-color-hover !default; /// color||Color|0 $--input-background-color: $--color-white !default; $--input-fill-disabled: $--disabled-fill-base !default; $--input-color-disabled: $--font-color-disabled-base !default; /// color||Color|0 $--input-icon-color: $--color-text-placeholder !default; /// color||Color|0 $--input-placeholder-color: $--color-text-placeholder !default; $--input-max-width: 314px !default; $--input-hover-border: $--border-color-hover !default; $--input-clear-hover-color: $--color-text-secondary !default; $--input-focus-border: $--color-primary !default; $--input-focus-fill: $--color-white !default; $--input-disabled-fill: $--disabled-fill-base !default; $--input-disabled-border: $--disabled-border-base !default; $--input-disabled-color: $--disabled-color-base !default; $--input-disabled-placeholder-color: $--color-text-placeholder !default; /// fontSize||Font|1 $--input-medium-font-size: 14px !default; /// height||Other|4 $--input-medium-height: 36px !default; /// fontSize||Font|1 $--input-small-font-size: 13px !default; /// height||Other|4 $--input-small-height: 32px !default; /// fontSize||Font|1 $--input-mini-font-size: 12px !default; /// height||Other|4 $--input-mini-height: 28px !default; /* Cascader -------------------------- */ /// color||Color|0 $--cascader-menu-font-color: $--color-text-regular !default; /// color||Color|0 $--cascader-menu-selected-font-color: $--color-primary !default; $--cascader-menu-fill: $--fill-base !default; $--cascader-menu-font-size: $--font-size-base !default; $--cascader-menu-radius: $--border-radius-base !default; $--cascader-menu-border: solid 1px $--border-color-light !default; $--cascader-menu-shadow: $--box-shadow-light !default; $--cascader-node-background-hover: $--background-color-base !default; $--cascader-node-color-disabled:$--color-text-placeholder !default; $--cascader-color-empty:$--color-text-placeholder !default; $--cascader-tag-background: #f0f2f5; /* Group -------------------------- */ $--group-option-flex: 0 0 (1/5) * 100% !default; $--group-option-offset-bottom: 12px !default; $--group-option-fill-hover: rgba($--color-black, 0.06) !default; $--group-title-color: $--color-black !default; $--group-title-font-size: $--font-size-base !default; $--group-title-width: 66px !default; /* Tab -------------------------- */ $--tab-font-size: $--font-size-base !default; $--tab-border-line: 1px solid #e4e4e4 !default; $--tab-header-color-active: $--color-text-secondary !default; $--tab-header-color-hover: $--color-text-regular !default; $--tab-header-color: $--color-text-regular !default; $--tab-header-fill-active: rgba($--color-black, 0.06) !default; $--tab-header-fill-hover: rgba($--color-black, 0.06) !default; $--tab-vertical-header-width: 90px !default; $--tab-vertical-header-count-color: $--color-white !default; $--tab-vertical-header-count-fill: $--color-text-secondary !default; /* Button -------------------------- */ /// fontSize||Font|1 $--button-font-size: $--font-size-base !default; /// fontWeight||Font|1 $--button-font-weight: $--font-weight-primary !default; /// borderRadius||Border|2 $--button-border-radius: $--border-radius-base !default; /// padding||Spacing|3 $--button-padding-vertical: 12px !default; /// padding||Spacing|3 $--button-padding-horizontal: 20px !default; /// fontSize||Font|1 $--button-medium-font-size: $--font-size-base !default; /// borderRadius||Border|2 $--button-medium-border-radius: $--border-radius-base !default; /// padding||Spacing|3 $--button-medium-padding-vertical: 10px !default; /// padding||Spacing|3 $--button-medium-padding-horizontal: 20px !default; /// fontSize||Font|1 $--button-small-font-size: 12px !default; $--button-small-border-radius: #{$--border-radius-base - 1} !default; /// padding||Spacing|3 $--button-small-padding-vertical: 9px !default; /// padding||Spacing|3 $--button-small-padding-horizontal: 15px !default; /// fontSize||Font|1 $--button-mini-font-size: 12px !default; $--button-mini-border-radius: #{$--border-radius-base - 1} !default; /// padding||Spacing|3 $--button-mini-padding-vertical: 7px !default; /// padding||Spacing|3 $--button-mini-padding-horizontal: 15px !default; /// color||Color|0 $--button-default-font-color: $--color-text-regular !default; /// color||Color|0 $--button-default-background-color: $--color-white !default; /// color||Color|0 $--button-default-border-color: $--border-color-base !default; /// color||Color|0 $--button-disabled-font-color: $--color-text-placeholder !default; /// color||Color|0 $--button-disabled-background-color: $--color-white !default; /// color||Color|0 $--button-disabled-border-color: $--border-color-lighter !default; /// color||Color|0 $--button-primary-border-color: $--color-primary !default; /// color||Color|0 $--button-primary-font-color: $--color-white !default; /// color||Color|0 $--button-primary-background-color: $--color-primary !default; /// color||Color|0 $--button-success-border-color: $--color-success !default; /// color||Color|0 $--button-success-font-color: $--color-white !default; /// color||Color|0 $--button-success-background-color: $--color-success !default; /// color||Color|0 $--button-warning-border-color: $--color-warning !default; /// color||Color|0 $--button-warning-font-color: $--color-white !default; /// color||Color|0 $--button-warning-background-color: $--color-warning !default; /// color||Color|0 $--button-danger-border-color: $--color-danger !default; /// color||Color|0 $--button-danger-font-color: $--color-white !default; /// color||Color|0 $--button-danger-background-color: $--color-danger !default; /// color||Color|0 $--button-info-border-color: $--color-info !default; /// color||Color|0 $--button-info-font-color: $--color-white !default; /// color||Color|0 $--button-info-background-color: $--color-info !default; $--button-hover-tint-percent: 20% !default; $--button-active-shade-percent: 10% !default; /* cascader -------------------------- */ $--cascader-height: 200px !default; /* Switch -------------------------- */ /// color||Color|0 $--switch-on-color: $--color-primary !default; /// color||Color|0 $--switch-off-color: $--border-color-base !default; /// fontSize||Font|1 $--switch-font-size: $--font-size-base !default; $--switch-core-border-radius: 10px !default; // height||Other|4 TODO: width 代码写死的40px 所以下面这三个属性都没意义 $--switch-width: 40px !default; // height||Other|4 $--switch-height: 20px !default; // height||Other|4 $--switch-button-size: 16px !default; /* Dialog -------------------------- */ $--dialog-background-color: $--color-white !default; $--dialog-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !default; /// fontSize||Font|1 $--dialog-title-font-size: $--font-size-large !default; /// fontSize||Font|1 $--dialog-content-font-size: 14px !default; /// fontLineHeight||LineHeight|2 $--dialog-font-line-height: $--font-line-height-primary !default; /// padding||Spacing|3 $--dialog-padding-primary: 20px !default; /* Table -------------------------- */ /// color||Color|0 $--table-border-color: $--border-color-lighter !default; $--table-border: 1px solid $--table-border-color !default; /// color||Color|0 $--table-font-color: $--color-text-regular !default; /// color||Color|0 $--table-header-font-color: $--color-text-secondary !default; /// color||Color|0 $--table-row-hover-background-color: $--background-color-base !default; $--table-current-row-background-color: $--color-primary-light-9 !default; /// color||Color|0 $--table-header-background-color: $--color-white !default; $--table-fixed-box-shadow: 0 0 10px rgba(0, 0, 0, .12) !default; /* Pagination -------------------------- */ /// fontSize||Font|1 $--pagination-font-size: 13px !default; /// color||Color|0 $--pagination-background-color: $--color-white !default; /// color||Color|0 $--pagination-font-color: $--color-text-primary !default; $--pagination-border-radius: 3px !default; /// color||Color|0 $--pagination-button-color: $--color-text-primary !default; /// height||Other|4 $--pagination-button-width: 35.5px !default; /// height||Other|4 $--pagination-button-height: 28px !default; /// color||Color|0 $--pagination-button-disabled-color: $--color-text-placeholder !default; /// color||Color|0 $--pagination-button-disabled-background-color: $--color-white !default; /// color||Color|0 $--pagination-hover-color: $--color-primary !default; /* Popup -------------------------- */ /// color||Color|0 $--popup-modal-background-color: $--color-black !default; /// opacity||Other|1 $--popup-modal-opacity: 0.5 !default; /* Popover -------------------------- */ /// color||Color|0 $--popover-background-color: $--color-white !default; /// fontSize||Font|1 $--popover-font-size: $--font-size-base !default; /// color||Color|0 $--popover-border-color: $--border-color-lighter !default; $--popover-arrow-size: 6px !default; /// padding||Spacing|3 $--popover-padding: 12px !default; $--popover-padding-large: 18px 20px !default; /// fontSize||Font|1 $--popover-title-font-size: 16px !default; /// color||Color|0 $--popover-title-font-color: $--color-text-primary !default; /* Tooltip -------------------------- */ /// color|1|Color|0 $--tooltip-fill: $--color-text-primary !default; /// color|1|Color|0 $--tooltip-color: $--color-white !default; /// fontSize||Font|1 $--tooltip-font-size: 12px !default; /// color||Color|0 $--tooltip-border-color: $--color-text-primary !default; $--tooltip-arrow-size: 6px !default; /// padding||Spacing|3 $--tooltip-padding: 10px !default; /* Tag -------------------------- */ /// color||Color|0 $--tag-info-color: $--color-info !default; /// color||Color|0 $--tag-primary-color: $--color-primary !default; /// color||Color|0 $--tag-success-color: $--color-success !default; /// color||Color|0 $--tag-warning-color: $--color-warning !default; /// color||Color|0 $--tag-danger-color: $--color-danger !default; /// fontSize||Font|1 $--tag-font-size: 12px !default; $--tag-border-radius: 4px !default; $--tag-padding: 0 10px !default; /* Tree -------------------------- */ /// color||Color|0 $--tree-node-hover-background-color: $--background-color-base !default; /// color||Color|0 $--tree-font-color: $--color-text-regular !default; /// color||Color|0 $--tree-expand-icon-color: $--color-text-placeholder !default; /* Dropdown -------------------------- */ $--dropdown-menu-box-shadow: $--box-shadow-light !default; $--dropdown-menuItem-hover-fill: $--color-primary-light-9 !default; $--dropdown-menuItem-hover-color: $--link-color !default; /* Badge -------------------------- */ /// color||Color|0 $--badge-background-color: $--color-danger !default; $--badge-radius: 10px !default; /// fontSize||Font|1 $--badge-font-size: 12px !default; /// padding||Spacing|3 $--badge-padding: 6px !default; /// height||Other|4 $--badge-size: 18px !default; /* Card --------------------------*/ /// color||Color|0 $--card-border-color: $--border-color-lighter !default; $--card-border-radius: 4px !default; /// padding||Spacing|3 $--card-padding: 20px !default; /* Slider --------------------------*/ /// color||Color|0 $--slider-main-background-color: $--color-primary !default; /// color||Color|0 $--slider-runway-background-color: $--border-color-light !default; $--slider-button-hover-color: mix($--color-primary, black, 97%) !default; $--slider-stop-background-color: $--color-white !default; $--slider-disable-color: $--color-text-placeholder !default; $--slider-margin: 16px 0 !default; $--slider-border-radius: 3px !default; /// height|1|Other|4 $--slider-height: 6px !default; /// height||Other|4 $--slider-button-size: 16px !default; $--slider-button-wrapper-size: 36px !default; $--slider-button-wrapper-offset: -15px !default; /* Steps --------------------------*/ $--steps-border-color: $--disabled-border-base !default; $--steps-border-radius: 4px !default; $--steps-padding: 20px !default; /* Menu --------------------------*/ /// fontSize||Font|1 $--menu-item-font-size: $--font-size-base !default; /// color||Color|0 $--menu-item-font-color: $--color-text-primary !default; /// color||Color|0 $--menu-background-color: $--color-white !default; $--menu-item-hover-fill: $--color-primary-light-9 !default; /* Rate --------------------------*/ $--rate-height: 20px !default; /// fontSize||Font|1 $--rate-font-size: $--font-size-base !default; /// height||Other|3 $--rate-icon-size: 18px !default; /// margin||Spacing|2 $--rate-icon-margin: 6px !default; $--rate-icon-color: $--color-text-placeholder !default; /* DatePicker --------------------------*/ $--datepicker-font-color: $--color-text-regular !default; /// color|1|Color|0 $--datepicker-off-font-color: $--color-text-placeholder !default; /// color||Color|0 $--datepicker-header-font-color: $--color-text-regular !default; $--datepicker-icon-color: $--color-text-primary !default; $--datepicker-border-color: $--disabled-border-base !default; $--datepicker-inner-border-color: #e4e4e4 !default; /// color||Color|0 $--datepicker-inrange-background-color: $--border-color-extra-light !default; /// color||Color|0 $--datepicker-inrange-hover-background-color: $--border-color-extra-light !default; /// color||Color|0 $--datepicker-active-color: $--color-primary !default; /// color||Color|0 $--datepicker-hover-font-color: $--color-primary !default; $--datepicker-cell-hover-color: #fff !default; /* Loading --------------------------*/ /// height||Other|4 $--loading-spinner-size: 42px !default; /// height||Other|4 $--loading-fullscreen-spinner-size: 50px !default; /* Scrollbar --------------------------*/ $--scrollbar-background-color: rgba($--color-text-secondary, .3) !default; $--scrollbar-hover-background-color: rgba($--color-text-secondary, .5) !default; /* Carousel --------------------------*/ /// fontSize||Font|1 $--carousel-arrow-font-size: 12px !default; $--carousel-arrow-size: 36px !default; $--carousel-arrow-background: rgba(31, 45, 61, 0.11) !default; $--carousel-arrow-hover-background: rgba(31, 45, 61, 0.23) !default; /// width||Other|4 $--carousel-indicator-width: 30px !default; /// height||Other|4 $--carousel-indicator-height: 2px !default; $--carousel-indicator-padding-horizontal: 4px !default; $--carousel-indicator-padding-vertical: 12px !default; $--carousel-indicator-out-color: $--border-color-hover !default; /* Collapse --------------------------*/ /// color||Color|0 $--collapse-border-color: $--border-color-lighter !default; /// height||Other|4 $--collapse-header-height: 48px !default; /// color||Color|0 $--collapse-header-background-color: $--color-white !default; /// color||Color|0 $--collapse-header-font-color: $--color-text-primary !default; /// fontSize||Font|1 $--collapse-header-font-size: 13px !default; /// color||Color|0 $--collapse-content-background-color: $--color-white !default; /// fontSize||Font|1 $--collapse-content-font-size: 13px !default; /// color||Color|0 $--collapse-content-font-color: $--color-text-primary !default; /* Transfer --------------------------*/ $--transfer-border-color: $--border-color-lighter !default; $--transfer-border-radius: $--border-radius-base !default; /// height||Other|4 $--transfer-panel-width: 200px !default; /// height||Other|4 $--transfer-panel-header-height: 40px !default; /// color||Color|0 $--transfer-panel-header-background-color: $--background-color-base !default; /// height||Other|4 $--transfer-panel-footer-height: 40px !default; /// height||Other|4 $--transfer-panel-body-height: 246px !default; /// height||Other|4 $--transfer-item-height: 30px !default; /// height||Other|4 $--transfer-filter-height: 32px !default; /* Header --------------------------*/ $--header-padding: 0 20px !default; /* Footer --------------------------*/ $--footer-padding: 0 20px !default; /* Main --------------------------*/ $--main-padding: 20px !default; /* Timeline --------------------------*/ $--timeline-node-size-normal: 12px !default; $--timeline-node-size-large: 14px !default; $--timeline-node-color: $--border-color-light !default; /* Backtop --------------------------*/ /// color||Color|0 $--backtop-background-color: $--color-white !default; /// color||Color|0 $--backtop-font-color: $--color-primary !default; /// color||Color|0 $--backtop-hover-background-color: $--border-color-extra-light !default; /* Link --------------------------*/ /// fontSize||Font|1 $--link-font-size: $--font-size-base !default; /// fontWeight||Font|1 $--link-font-weight: $--font-weight-primary !default; /// color||Color|0 $--link-default-font-color: $--color-text-regular !default; /// color||Color|0 $--link-default-active-color: $--color-primary !default; /// color||Color|0 $--link-disabled-font-color: $--color-text-placeholder !default; /// color||Color|0 $--link-primary-font-color: $--color-primary !default; /// color||Color|0 $--link-success-font-color: $--color-success !default; /// color||Color|0 $--link-warning-font-color: $--color-warning !default; /// color||Color|0 $--link-danger-font-color: $--color-danger !default; /// color||Color|0 $--link-info-font-color: $--color-info !default; /* Calendar --------------------------*/ /// border||Other|4 $--calendar-border: $--table-border !default; /// color||Other|4 $--calendar-selected-background-color: #F2F8FE !default; $--calendar-cell-width: 85px !default; /* Form -------------------------- */ /// fontSize||Font|1 $--form-label-font-size: $--font-size-base !default; /* Avatar --------------------------*/ /// color||Color|0 $--avatar-font-color: #fff !default; /// color||Color|0 $--avatar-background-color: #C0C4CC !default; /// fontSize||Font Size|1 $--avatar-text-font-size: 14px !default; /// fontSize||Font Size|1 $--avatar-icon-font-size: 18px !default; /// borderRadius||Border|2 $--avatar-border-radius: $--border-radius-base !default; /// size|1|Avatar Size|3 $--avatar-large-size: 40px !default; /// size|1|Avatar Size|3 $--avatar-medium-size: 36px !default; /// size|1|Avatar Size|3 $--avatar-small-size: 28px !default; /* Empty -------------------------- */ $--empty-padding: 40px 0 !default; $--empty-image-width: 160px !default; $--empty-description-margin-top: 20px !default; $--empty-bottom-margin-top: 20px !default; /* Descriptions -------------------------- */ $--descriptions-header-margin-bottom: 20px !default; $--descriptions-title-font-size: 16px !default; $--descriptions-table-border: 1px solid $--border-color-lighter !default; $--descriptions-item-bordered-label-background: #fafafa !default; /* Skeleton --------------------------*/ $--skeleton-color: #f2f2f2 !default; $--skeleton-to-color: #e6e6e6 !default; /* Svg --------------- */ $--svg-monochrome-grey: #DCDDE0 !default; /* Result -------------------------- */ $--result-padding: 40px 30px !default; $--result-icon-font-size: 64px !default; $--result-title-font-size: 20px !default; $--result-title-margin-top: 20px !default; $--result-subtitle-margin-top: 10px !default; $--result-extra-margin-top: 30px !default; $--result-info-color: $--color-info !default; $--result-success-color: $--color-success !default; $--result-warning-color: $--color-warning !default; $--result-danger-color: $--color-danger !default; /* Break-point --------------------------*/ $--sm: 768px !default; $--md: 992px !default; $--lg: 1200px !default; $--xl: 1920px !default; $--breakpoints: ( 'xs' : (max-width: $--sm - 1), 'sm' : (min-width: $--sm), 'md' : (min-width: $--md), 'lg' : (min-width: $--lg), 'xl' : (min-width: $--xl) ); $--breakpoints-spec: ( 'xs-only' : (max-width: $--sm - 1), 'sm-and-up' : (min-width: $--sm), 'sm-only': "(min-width: #{$--sm}) and (max-width: #{$--md - 1})", 'sm-and-down': (max-width: $--md - 1), 'md-and-up' : (min-width: $--md), 'md-only': "(min-width: #{$--md}) and (max-width: #{$--lg - 1})", 'md-and-down': (max-width: $--lg - 1), 'lg-and-up' : (min-width: $--lg), 'lg-only': "(min-width: #{$--lg}) and (max-width: #{$--xl - 1})", 'lg-and-down': (max-width: $--xl - 1), 'xl-only' : (min-width: $--xl), ); ================================================ FILE: packages/theme-chalk/src/container.scss ================================================ @import "mixins/mixins"; @include b(container) { display: flex; flex-direction: row; flex: 1; flex-basis: auto; box-sizing: border-box; min-width: 0; @include when(vertical) { flex-direction: column; } } ================================================ FILE: packages/theme-chalk/src/date-picker/date-picker.scss ================================================ @import "../common/var"; @import "../mixins/mixins"; @import "./picker-panel.scss"; @include b(date-picker) { width: 322px; &.has-sidebar.has-time { width: 434px; } &.has-sidebar { width: 438px; } &.has-time .el-picker-panel__body-wrapper { position: relative; } .el-picker-panel__content { width: 292px; } table { table-layout: fixed; width: 100%; } @include e(editor-wrap) { position: relative; display: table-cell; padding: 0 5px; } @include e(time-header) { position: relative; border-bottom: 1px solid $--datepicker-inner-border-color; font-size: 12px; padding: 8px 5px 5px 5px; display: table; width: 100%; box-sizing: border-box; } @include e(header) { margin: 12px; text-align: center; @include m(bordered) { margin-bottom: 0; padding-bottom: 12px; border-bottom: solid 1px $--border-color-lighter; & + .el-picker-panel__content { margin-top: 0; } } } @include e(header-label) { font-size: 16px; font-weight: 500; padding: 0 5px; line-height: 22px; text-align: center; cursor: pointer; color: $--color-text-regular; &:hover { color: $--datepicker-hover-font-color; } &.active { color: $--datepicker-active-color; } } @include e(prev-btn) { float: left; } @include e(next-btn) { float: right; } @include e(time-wrap) { padding: 10px; text-align: center; } @include e(time-label) { float: left; cursor: pointer; line-height: 30px; margin-left: 10px; } } ================================================ FILE: packages/theme-chalk/src/date-picker/date-range-picker.scss ================================================ @import "../common/var"; @include b(date-range-picker) { width: 646px; &.has-sidebar { width: 756px; } table { table-layout: fixed; width: 100%; } .el-picker-panel__body { min-width: 513px; } .el-picker-panel__content { margin: 0; } @include e(header) { position: relative; text-align: center; height: 28px; [class*=arrow-left] { float: left; } [class*=arrow-right] { float: right; } div { font-size: 16px; font-weight: 500; margin-right: 50px; } } @include e(content) { float: left; width: 50%; box-sizing: border-box; margin: 0; padding: 16px; @include when(left) { border-right: 1px solid $--datepicker-inner-border-color; } .el-date-range-picker__header { div { margin-left: 50px; margin-right: 50px; } } } @include e(editors-wrap) { box-sizing: border-box; display: table-cell; @include when(right) { text-align: right; } } @include e(time-header) { position: relative; border-bottom: 1px solid $--datepicker-inner-border-color; font-size: 12px; padding: 8px 5px 5px 5px; display: table; width: 100%; box-sizing: border-box; > .el-icon-arrow-right { font-size: 20px; vertical-align: middle; display: table-cell; color: $--datepicker-icon-color; } } @include e(time-picker-wrap) { position: relative; display: table-cell; padding: 0 5px; .el-picker-panel { position: absolute; top: 13px; right: 0; z-index: 1; background: $--color-white; } } } ================================================ FILE: packages/theme-chalk/src/date-picker/date-table.scss ================================================ @import "../common/var"; @import "../mixins/mixins"; @include b(date-table) { font-size: 12px; user-select: none; @include when(week-mode) { .el-date-table__row { &:hover { div { background-color: $--datepicker-inrange-background-color; } td.available:hover { color: $--datepicker-font-color; } td:first-child div { margin-left: 5px; border-top-left-radius: 15px; border-bottom-left-radius: 15px; } td:last-child div { margin-right: 5px; border-top-right-radius: 15px; border-bottom-right-radius: 15px; } } &.current div { background-color: $--datepicker-inrange-background-color; } } } td { width: 32px; height: 30px; padding: 4px 0; box-sizing: border-box; text-align: center; cursor: pointer; position: relative; & div { height: 30px; padding: 3px 0; box-sizing: border-box; } & span { width: 24px; height: 24px; display: block; margin: 0 auto; line-height: 24px; position: absolute; left: 50%; transform: translateX(-50%); border-radius: 50%; } &.next-month, &.prev-month { color: $--datepicker-off-font-color; } &.today { position: relative; span { color: $--color-primary; font-weight: bold; } &.start-date span, &.end-date span { color: $--color-white; } } &.available:hover { color: $--datepicker-hover-font-color; } &.in-range div { background-color: $--datepicker-inrange-background-color; &:hover { background-color: $--datepicker-inrange-hover-background-color; } } &.current:not(.disabled) span { color: $--color-white; background-color: $--datepicker-active-color; } &.start-date div, &.end-date div { color: $--color-white; } &.start-date span, &.end-date span { background-color: $--datepicker-active-color; } &.start-date div { margin-left: 5px; border-top-left-radius: 15px; border-bottom-left-radius: 15px; } &.end-date div { margin-right: 5px; border-top-right-radius: 15px; border-bottom-right-radius: 15px; } &.disabled div { background-color: $--background-color-base; opacity: 1; cursor: not-allowed; color: $--color-text-placeholder; } &.selected div { margin-left: 5px; margin-right: 5px; background-color: $--datepicker-inrange-background-color; border-radius: 15px; &:hover { background-color: $--datepicker-inrange-hover-background-color; } } &.selected span { background-color: $--datepicker-active-color; color: $--color-white; border-radius: 15px; } &.week { font-size: 80%; color: $--datepicker-header-font-color; } } th { padding: 5px; color: $--datepicker-header-font-color; font-weight: 400; border-bottom: solid 1px $--border-color-lighter; } } ================================================ FILE: packages/theme-chalk/src/date-picker/month-table.scss ================================================ @import "../common/var"; @include b(month-table) { font-size: 12px; margin: -1px; border-collapse: collapse; td { text-align: center; padding: 8px 0px; cursor: pointer; & div { height: 48px; padding: 6px 0; box-sizing: border-box; } &.today { .cell { color: $--color-primary; font-weight: bold; } &.start-date .cell, &.end-date .cell { color: $--color-white; } } &.disabled .cell { background-color: $--background-color-base; cursor: not-allowed; color: $--color-text-placeholder; &:hover { color: $--color-text-placeholder; } } .cell { width: 60px; height: 36px; display: block; line-height: 36px; color: $--datepicker-font-color; margin: 0 auto; border-radius: 18px; &:hover { color: $--datepicker-hover-font-color; } } &.in-range div { background-color: $--datepicker-inrange-background-color; &:hover { background-color: $--datepicker-inrange-hover-background-color; } } &.start-date div, &.end-date div { color: $--color-white; } &.start-date .cell, &.end-date .cell { color: $--color-white; background-color: $--datepicker-active-color; } &.start-date div { border-top-left-radius: 24px; border-bottom-left-radius: 24px; } &.end-date div { border-top-right-radius: 24px; border-bottom-right-radius: 24px; } &.current:not(.disabled) .cell { color: $--datepicker-active-color; } } } ================================================ FILE: packages/theme-chalk/src/date-picker/picker-panel.scss ================================================ @import "../common/var"; @include b(picker-panel) { color: $--color-text-regular; border: 1px solid $--datepicker-border-color; box-shadow: $--box-shadow-light; background: $--color-white; border-radius: $--border-radius-base; line-height: 30px; margin: 5px 0; @include e((body, body-wrapper)) { &::after { content: ""; display: table; clear: both; } } @include e(content) { position: relative; margin: 15px; } @include e(footer) { border-top: 1px solid $--datepicker-inner-border-color; padding: 4px; text-align: right; background-color: $--color-white; position: relative; font-size: 0; } @include e(shortcut) { display: block; width: 100%; border: 0; background-color: transparent; line-height: 28px; font-size: 14px; color: $--datepicker-font-color; padding-left: 12px; text-align: left; outline: none; cursor: pointer; &:hover { color: $--datepicker-hover-font-color; } &.active { background-color: #e6f1fe; color: $--datepicker-active-color; } } @include e(btn) { border: 1px solid #dcdcdc; color: #333; line-height: 24px; border-radius: 2px; padding: 0 20px; cursor: pointer; background-color: transparent; outline: none; font-size: 12px; &[disabled] { color: #cccccc; cursor: not-allowed; } } @include e(icon-btn) { font-size: 12px; color: $--datepicker-icon-color; border: 0; background: transparent; cursor: pointer; outline: none; margin-top: 8px; &:hover { color: $--datepicker-hover-font-color; } @include when(disabled) { color: $--font-color-disabled-base; &:hover { cursor: not-allowed; } } } @include e(link-btn) { vertical-align: middle; } } .el-picker-panel *[slot=sidebar], .el-picker-panel__sidebar { position: absolute; top: 0; bottom: 0; width: 110px; border-right: 1px solid $--datepicker-inner-border-color; box-sizing: border-box; padding-top: 6px; background-color: $--color-white; overflow: auto; } .el-picker-panel *[slot=sidebar] + .el-picker-panel__body, .el-picker-panel__sidebar + .el-picker-panel__body { margin-left: 110px; } ================================================ FILE: packages/theme-chalk/src/date-picker/picker.scss ================================================ @import "../mixins/mixins"; @import "../common/var"; @import "../common/transition"; @include b(date-editor) { position: relative; display: inline-block; text-align: left; &.el-input, &.el-input__inner { width: 220px; } @include m((monthrange)) { &.el-input, &.el-input__inner { width: 300px; } } @include m((daterange, timerange)) { &.el-input, &.el-input__inner { width: 350px; } } @include m(datetimerange) { &.el-input, &.el-input__inner { width: 400px; } } @include m(dates) { .el-input__inner { text-overflow: ellipsis; white-space: nowrap; } } .el-icon-circle-close { cursor: pointer; } .el-range__icon { font-size: 14px; margin-left: -5px; color: $--color-text-placeholder; float: left; line-height: 32px; } .el-range-input { appearance: none; border: none; outline: none; display: inline-block; height: 100%; margin: 0; padding: 0; width: 39%; text-align: center; font-size: $--font-size-base; color: $--color-text-regular; &::placeholder { color: $--color-text-placeholder; } } .el-range-separator { display: inline-block; height: 100%; padding: 0 5px; margin: 0; text-align: center; line-height: 32px; font-size: 14px; width: 5%; color: $--color-text-primary; } .el-range__close-icon { font-size: 14px; color: $--color-text-placeholder; width: 25px; display: inline-block; float: right; line-height: 32px; } } @include b(range-editor) { &.el-input__inner { display: inline-flex; align-items: center; padding: 3px 10px; } .el-range-input { line-height: 1; } @include when(active) { border-color: $--color-primary; &:hover { border-color: $--color-primary; } } @include m(medium) { &.el-input__inner { height: $--input-medium-height; } .el-range-separator { line-height: 28px; font-size: $--input-medium-font-size; } .el-range-input { font-size: $--input-medium-font-size; } .el-range__icon, .el-range__close-icon { line-height: 28px; } } @include m(small) { &.el-input__inner { height: $--input-small-height; } .el-range-separator { line-height: 24px; font-size: $--input-small-font-size; } .el-range-input { font-size: $--input-small-font-size; } .el-range__icon, .el-range__close-icon { line-height: 24px; } } @include m(mini) { &.el-input__inner { height: $--input-mini-height; } .el-range-separator { line-height: 20px; font-size: $--input-mini-font-size; } .el-range-input { font-size: $--input-mini-font-size; } .el-range__icon, .el-range__close-icon { line-height: 20px; } } @include when(disabled) { background-color: $--input-disabled-fill; border-color: $--input-disabled-border; color: $--input-disabled-color; cursor: not-allowed; &:hover, &:focus { border-color: $--input-disabled-border; } input { background-color: $--input-disabled-fill; color: $--input-disabled-color; cursor: not-allowed; &::placeholder { color: $--input-disabled-placeholder-color; } } .el-range-separator { color: $--input-disabled-color; } } } ================================================ FILE: packages/theme-chalk/src/date-picker/time-picker.scss ================================================ @import "../common/var"; @include b(time-panel) { margin: 5px 0; border: solid 1px $--datepicker-border-color; background-color: $--color-white; box-shadow: $--box-shadow-light; border-radius: 2px; position: absolute; width: 180px; left: 0; z-index: $--index-top; user-select: none; box-sizing: content-box; @include e(content) { font-size: 0; position: relative; overflow: hidden; &::after, &::before { content: ""; top: 50%; position: absolute; margin-top: -15px; height: 32px; z-index: -1; left: 0; right: 0; box-sizing: border-box; padding-top: 6px; text-align: left; border-top: 1px solid $--border-color-light; border-bottom: 1px solid $--border-color-light; } &::after { left: 50%; margin-left: 12%; margin-right: 12%; } &::before { padding-left: 50%; margin-right: 12%; margin-left: 12%; } &.has-seconds { &::after { left: calc(100% / 3 * 2); } &::before { padding-left: calc(100% / 3); } } } @include e(footer) { border-top: 1px solid $--datepicker-inner-border-color; padding: 4px; height: 36px; line-height: 25px; text-align: right; box-sizing: border-box; } @include e(btn) { border: none; line-height: 28px; padding: 0 5px; margin: 0 5px; cursor: pointer; background-color: transparent; outline: none; font-size: 12px; color: $--color-text-primary; &.confirm { font-weight: 800; color: $--datepicker-active-color; } } } ================================================ FILE: packages/theme-chalk/src/date-picker/time-range-picker.scss ================================================ @import "../common/var"; @include b(time-range-picker) { width: 354px; overflow: visible; @include e(content) { position: relative; text-align: center; padding: 10px; } @include e(cell) { box-sizing: border-box; margin: 0; padding: 4px 7px 7px; width: 50%; display: inline-block; } @include e(header) { margin-bottom: 5px; text-align: center; font-size: 14px; } @include e(body) { border-radius:2px; border: 1px solid $--datepicker-border-color; } } ================================================ FILE: packages/theme-chalk/src/date-picker/time-spinner.scss ================================================ @import "../common/var"; @include b(time-spinner) { &.has-seconds { .el-time-spinner__wrapper { width: 33.3%; } } @include e(wrapper) { max-height: 190px; overflow: auto; display: inline-block; width: 50%; vertical-align: top; position: relative; & .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) { padding-bottom: 15px; } @include when(arrow) { box-sizing: border-box; text-align: center; overflow: hidden; .el-time-spinner__list { transform: translateY(-32px); } .el-time-spinner__item:hover:not(.disabled):not(.active) { background: $--color-white; cursor: default; } } } @include e(arrow) { font-size: 12px; color: $--color-text-secondary; position: absolute; left: 0; width: 100%; z-index: $--index-normal; text-align: center; height: 30px; line-height: 30px; cursor: pointer; &:hover { color: $--color-primary; } &.el-icon-arrow-up { top: 10px; } &.el-icon-arrow-down { bottom: 10px; } } @include e(input) { &.el-input { width: 70%; .el-input__inner { padding: 0; text-align: center; } } } @include e(list) { padding: 0; margin: 0; list-style: none; text-align: center; &::after, &::before { content: ''; display: block; width: 100%; height: 80px; } } @include e(item) { height: 32px; line-height: 32px; font-size: 12px; color: $--color-text-regular; &:hover:not(.disabled):not(.active) { background: $--background-color-base; cursor: pointer; } &.active:not(.disabled) { color: $--color-text-primary; font-weight: bold; } &.disabled { color: $--color-text-placeholder; cursor: not-allowed; } } } ================================================ FILE: packages/theme-chalk/src/date-picker/year-table.scss ================================================ @import "../common/var"; @include b(year-table) { font-size: 12px; margin: -1px; border-collapse: collapse; .el-icon { color: $--datepicker-icon-color; } td { text-align: center; padding: 20px 3px; cursor: pointer; &.today { .cell { color: $--color-primary; font-weight: bold; } } &.disabled .cell { background-color: $--background-color-base; cursor: not-allowed; color: $--color-text-placeholder; &:hover { color: $--color-text-placeholder; } } .cell { width: 48px; height: 32px; display: block; line-height: 32px; color: $--datepicker-font-color; margin: 0 auto; &:hover { color: $--datepicker-hover-font-color; } } &.current:not(.disabled) .cell { color: $--datepicker-active-color; } } } ================================================ FILE: packages/theme-chalk/src/date-picker.scss ================================================ @import "./date-picker/date-table.scss"; @import "./date-picker/month-table.scss"; @import "./date-picker/year-table.scss"; @import "./date-picker/time-spinner.scss"; @import "./date-picker/picker.scss"; @import "./date-picker/date-picker.scss"; @import "./date-picker/date-range-picker.scss"; @import "./date-picker/time-range-picker.scss"; @import "./date-picker/time-picker.scss"; @import "./input.scss"; @import "./scrollbar.scss"; @import "./popper"; ================================================ FILE: packages/theme-chalk/src/descriptions-item.scss ================================================ @import 'mixins/mixins'; @import 'common/var'; @include b(descriptions-item) { vertical-align: top; @include e(container) { display: flex; .el-descriptions-item__label, .el-descriptions-item__content { display: inline-flex; align-items: baseline; } .el-descriptions-item__content { flex: 1; } } @include e(label) { &.has-colon { &::after { content: ':'; position: relative; top: -0.5px; } } &.is-bordered-label { font-weight: bold; color: $--color-text-secondary; background: $--descriptions-item-bordered-label-background; } &:not(.is-bordered-label) { margin-right: 10px; } } @include e(content) { word-break: break-word; overflow-wrap: break-word; } } ================================================ FILE: packages/theme-chalk/src/descriptions.scss ================================================ @import 'mixins/mixins'; @import 'common/var'; @import 'descriptions-item'; @include b(descriptions) { box-sizing: border-box; font-size: $--font-size-base; color: $--color-text-primary; @include e(header) { display: flex; justify-content: space-between; align-items: center; margin-bottom: $--descriptions-header-margin-bottom; @include e(title) { font-size: $--descriptions-title-font-size; font-weight: bold; } } @include e(body) { color: $--color-text-regular; background-color: $--color-white; .el-descriptions__table { border-collapse: collapse; width: 100%; table-layout: fixed; .el-descriptions-item__cell { box-sizing: border-box; text-align: left; font-weight: normal; line-height: 1.5; @include when(left) { text-align: left; } @include when(center) { text-align: center; } @include when(right) { text-align: right; } } } } .is-bordered { table-layout: auto; .el-descriptions-item__cell { border: $--descriptions-table-border; padding: 12px 10px; } } :not(.is-bordered) { .el-descriptions-item__cell { padding-bottom: 12px; } } @include m(medium) { &.is-bordered { .el-descriptions-item__cell { padding: 10px; } } &:not(.is-bordered) { .el-descriptions-item__cell { padding-bottom: 10px; } } } @include m(small) { font-size: 12px; &.is-bordered { .el-descriptions-item__cell { padding: 8px 10px; } } &:not(.is-bordered) { .el-descriptions-item__cell { padding-bottom: 8px; } } } @include m(mini) { font-size: 12px; &.is-bordered { .el-descriptions-item__cell { padding: 6px 10px; } } &:not(.is-bordered) { .el-descriptions-item__cell { padding-bottom: 6px; } } } } ================================================ FILE: packages/theme-chalk/src/dialog.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @import "common/popup"; @include b(dialog) { position: relative; margin: 0 auto 50px; background: $--dialog-background-color; border-radius: $--border-radius-small; box-shadow: $--dialog-box-shadow; box-sizing: border-box; width: 50%; @include when(fullscreen) { width: 100%; margin-top: 0; margin-bottom: 0; height: 100%; overflow: auto; } @include e(wrapper) { position: fixed; top: 0; right: 0; bottom: 0; left: 0; overflow: auto; margin: 0; } @include e(header) { padding: $--dialog-padding-primary; padding-bottom: 10px; } @include e(headerbtn) { position: absolute; top: $--dialog-padding-primary; right: $--dialog-padding-primary; padding: 0; background: transparent; border: none; outline: none; cursor: pointer; font-size: $--message-close-size; .el-dialog__close { color: $--color-info; } &:focus, &:hover { .el-dialog__close { color: $--color-primary; } } } @include e(title) { line-height: $--dialog-font-line-height; font-size: $--dialog-title-font-size; color: $--color-text-primary; } @include e(body) { padding: ($--dialog-padding-primary + 10px) $--dialog-padding-primary; color: $--color-text-regular; font-size: $--dialog-content-font-size; word-break: break-all; } @include e(footer) { padding: $--dialog-padding-primary; padding-top: 10px; text-align: right; box-sizing: border-box; } // 内容居中布局 @include m(center) { text-align: center; @include e(body) { text-align: initial; padding: 25px ($--dialog-padding-primary + 5px) 30px; } @include e(footer) { text-align: inherit; } } } .dialog-fade-enter-active { animation: dialog-fade-in .3s; } .dialog-fade-leave-active { animation: dialog-fade-out .3s; } @keyframes dialog-fade-in { 0% { transform: translate3d(0, -20px, 0); opacity: 0; } 100% { transform: translate3d(0, 0, 0); opacity: 1; } } @keyframes dialog-fade-out { 0% { transform: translate3d(0, 0, 0); opacity: 1; } 100% { transform: translate3d(0, -20px, 0); opacity: 0; } } ================================================ FILE: packages/theme-chalk/src/display.scss ================================================ @import "common/var"; @import "mixins/mixins"; .hidden { @each $break-point-name, $value in $--breakpoints-spec { &-#{$break-point-name} { @include res($break-point-name, $--breakpoints-spec) { display: none !important; } } } } ================================================ FILE: packages/theme-chalk/src/divider.scss ================================================ @import "common/var"; @import "mixins/mixins"; @include b(divider) { background-color: $--border-color-base; position: relative; @include m(horizontal) { display: block; height: 1px; width: 100%; margin: 24px 0; } @include m(vertical) { display: inline-block; width: 1px; height: 1em; margin: 0 8px; vertical-align: middle; position: relative; } @include e(text) { position: absolute; background-color: $--color-white; padding: 0 20px; font-weight: 500; color: $--color-text-primary; font-size: 14px; @include when(left) { left: 20px; transform: translateY(-50%); } @include when(center) { left: 50%; transform: translateX(-50%) translateY(-50%); } @include when(right) { right: 20px; transform: translateY(-50%); } } } ================================================ FILE: packages/theme-chalk/src/drawer.scss ================================================ @import "mixins/mixins"; @import "common/var"; @keyframes el-drawer-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } } @mixin drawer-animation($direction) { @keyframes #{$direction}-drawer-in { 0% { @if $direction == ltr { transform: translate(-100%, 0px); } @if $direction == rtl { transform: translate(100%, 0px); } @if $direction == ttb { transform: translate(0px, -100%); } @if $direction == btt { transform: translate(0px, 100%); } } 100% { @if $direction == ltr { transform: translate(0px, 0px); } @if $direction == rtl { transform: translate(0px, 0px); } @if $direction == ttb { transform: translate(0px, 0px); } @if $direction == btt { transform: translate(0px, 0px); } } } @keyframes #{$direction}-drawer-out { 0% { @if $direction == ltr { transform: translate(0px, 0px); } @if $direction == rtl { transform: translate(0px, 0px);; } @if $direction == ttb { transform: translate(0px, 0px); } @if $direction == btt { transform: translate(0px, 0); } } 100% { @if $direction == ltr { transform: translate(-100%, 0px); } @if $direction == rtl { transform: translate(100%, 0px); } @if $direction == ttb { transform: translate(0px, -100%); } @if $direction == btt { transform: translate(0px, 100%); } } } } @mixin animation-in($direction) { .el-drawer__open &.#{$direction} { animation: #{$direction}-drawer-in .3s 1ms; } } @mixin animation-out($direction) { &.#{$direction} { animation: #{$direction}-drawer-out .3s; } } @include drawer-animation(rtl); @include drawer-animation(ltr); @include drawer-animation(ttb); @include drawer-animation(btt); $directions: rtl, ltr, ttb, btt; @include b(drawer) { position: absolute; box-sizing: border-box; background-color: $--dialog-background-color; display: flex; flex-direction: column; box-shadow: 0 8px 10px -5px rgba(0, 0, 0, 0.2), 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12); overflow: hidden; outline: 0; @each $direction in $directions { @include animation-out($direction); @include animation-in($direction); } &__wrapper { position: fixed; top: 0; right: 0; bottom: 0; left: 0; overflow: hidden; margin: 0; } &__header { align-items: center; color: rgb(114, 118, 123); display: flex; margin-bottom: 32px; padding: $--dialog-padding-primary; padding-bottom: 0; & > :first-child { flex: 1; } } &__title { margin: 0; flex: 1; line-height: inherit; font-size: 1rem; } &__close-btn { border: none; cursor: pointer; font-size: $--font-size-extra-large; color: inherit; background-color: transparent; } &__body { flex: 1; overflow: auto; & > * { box-sizing: border-box; } } &.ltr, &.rtl { height: 100%; top: 0; bottom: 0; } &.ttb, &.btt { width: 100%; left: 0; right: 0; } &.ltr { left: 0; } &.rtl { right: 0; } &.ttb { top: 0; } &.btt { bottom: 0; } } .el-drawer__container { position: relative; left: 0; right: 0; top: 0; bottom: 0; height: 100%; width: 100%; } .el-drawer-fade-enter-active { animation: el-drawer-fade-in .3s; } .el-drawer-fade-leave-active { animation: el-drawer-fade-in .3s reverse; } ================================================ FILE: packages/theme-chalk/src/dropdown-item.scss ================================================ ================================================ FILE: packages/theme-chalk/src/dropdown-menu.scss ================================================ ================================================ FILE: packages/theme-chalk/src/dropdown.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "button"; @import "./popper"; @include b(dropdown) { display: inline-block; position: relative; color: $--color-text-regular; font-size: $--font-size-base; .el-button-group { display: block; .el-button { float: none; } } & .el-dropdown__caret-button { padding-left: 5px; padding-right: 5px; position: relative; border-left: none; &::before { $gap: 5px; content: ''; position: absolute; display: block; width: 1px; top: $gap; bottom: $gap; left: 0; background: mix(white, transparent, 50%); } &.el-button--default::before { background: mix($--button-default-border-color, transparent, 50%); } &:hover { &:not(.is-disabled)::before { top: 0; bottom: 0; } } & .el-dropdown__icon { padding-left: 0; } } @include e(icon) { font-size: 12px; margin: 0 3px; } .el-dropdown-selfdefine { // 自定义 &:focus:active, &:focus:not(.focusing) { outline-width: 0; } } [disabled] { cursor: not-allowed; color: $--font-color-disabled-base; } } @include b(dropdown-menu) { position: absolute; top: 0; left: 0; z-index: 10; padding: 10px 0; margin: 5px 0; background-color: $--color-white; border: 1px solid $--border-color-lighter; border-radius: $--border-radius-base; box-shadow: $--dropdown-menu-box-shadow; @include e(item) { list-style: none; line-height: 36px; padding: 0 20px; margin: 0; font-size: $--font-size-base; color: $--color-text-regular; cursor: pointer; outline: none; &:not(.is-disabled):hover, &:focus { background-color: $--dropdown-menuItem-hover-fill; color: $--dropdown-menuItem-hover-color; } i { margin-right: 5px; } @include m(divided) { $divided-offset: 6px; position: relative; margin-top: $divided-offset; border-top: 1px solid $--border-color-lighter; &:before { content: ''; height: $divided-offset; display: block; margin: 0 -20px; background-color: $--color-white; } } @include when(disabled) { cursor: default; color: $--font-color-disabled-base; pointer-events: none; } } @include m(medium) { padding: 6px 0; @include e(item) { line-height: 30px; padding: 0 17px; font-size: 14px; &.el-dropdown-menu__item--divided { $divided-offset: 6px; margin-top: $divided-offset; &:before { height: $divided-offset; margin: 0 -17px; } } } } @include m(small) { padding: 6px 0; @include e(item) { line-height: 27px; padding: 0 15px; font-size: 13px; &.el-dropdown-menu__item--divided { $divided-offset: 4px; margin-top: $divided-offset; &:before { height: $divided-offset; margin: 0 -15px; } } } } @include m(mini) { padding: 3px 0; @include e(item) { line-height: 24px; padding: 0 10px; font-size: 12px; &.el-dropdown-menu__item--divided { $divided-offset: 3px; margin-top: $divided-offset; &:before { height: $divided-offset; margin: 0 -10px; } } } } } ================================================ FILE: packages/theme-chalk/src/empty.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(empty) { display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; box-sizing: border-box; padding: $--empty-padding; @include e(image) { width: $--empty-image-width; img { user-select: none; width: 100%; height: 100%; vertical-align: top; object-fit: contain; } svg { fill: $--svg-monochrome-grey; width: 100%; height: 100%; vertical-align: top; } } @include e(description) { margin-top: $--empty-description-margin-top; p { margin: 0; font-size: $--font-size-base; color: $--color-text-secondary; } } @include e(bottom) { margin-top: $--empty-bottom-margin-top; } } ================================================ FILE: packages/theme-chalk/src/footer.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(footer) { padding: $--footer-padding; box-sizing: border-box; flex-shrink: 0; } ================================================ FILE: packages/theme-chalk/src/form-item.scss ================================================ ================================================ FILE: packages/theme-chalk/src/form.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @include b(form) { @include m(label-left) { & .el-form-item__label { text-align: left; } } @include m(label-top) { & .el-form-item__label { float: none; display: inline-block; text-align: left; padding: 0 0 10px 0; } } @include m(inline) { & .el-form-item { display: inline-block; margin-right: 10px; vertical-align: top; } & .el-form-item__label { float: none; display: inline-block; } & .el-form-item__content { display: inline-block; vertical-align: top; } &.el-form--label-top .el-form-item__content { display: block; } } } @include b(form-item) { margin-bottom: 22px; @include utils-clearfix; & .el-form-item { margin-bottom: 0; } & .el-input__validateIcon { display: none; } @include m(medium) { .el-form-item__label { line-height: 36px; } .el-form-item__content { line-height: 36px; } } @include m(small) { .el-form-item__label { line-height: 32px; } .el-form-item__content { line-height: 32px; } &.el-form-item { margin-bottom: 18px; } .el-form-item__error { padding-top: 2px; } } @include m(mini) { .el-form-item__label { line-height: 28px; } .el-form-item__content { line-height: 28px; } &.el-form-item { margin-bottom: 18px; } .el-form-item__error { padding-top: 1px; } } @include e(label-wrap) { float: left; .el-form-item__label { display: inline-block; float: none; } } @include e(label) { text-align: right; vertical-align: middle; float: left; font-size: $--form-label-font-size; color: $--color-text-regular; line-height: 40px; padding: 0 12px 0 0; box-sizing: border-box; } @include e(content) { line-height: 40px; position: relative; font-size: 14px; @include utils-clearfix; .el-input-group { vertical-align: top; } } @include e(error) { color: $--color-danger; font-size: 12px; line-height: 1; padding-top: 4px; position: absolute; top: 100%; left: 0; @include m(inline) { position: relative; top: auto; left: auto; display: inline-block; margin-left: 10px; } } @include when(required) { @include pseudo('not(.is-no-asterisk)') { & > .el-form-item__label:before, & .el-form-item__label-wrap > .el-form-item__label:before { content: '*'; color: $--color-danger; margin-right: 4px; } } } @include when(error) { & .el-input__inner, & .el-textarea__inner { &, &:focus { border-color: $--color-danger; } } & .el-input-group__append, & .el-input-group__prepend { & .el-input__inner { border-color: transparent; } } .el-input__validateIcon { color: $--color-danger; } } @include m(feedback) { .el-input__validateIcon { display: inline-block; } } } ================================================ FILE: packages/theme-chalk/src/header.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(header) { padding: $--header-padding; box-sizing: border-box; flex-shrink: 0; } ================================================ FILE: packages/theme-chalk/src/icon.scss ================================================ @import "common/var"; @font-face { font-family: 'element-icons'; src: url('#{$--font-path}/element-icons.woff') format('woff'), /* chrome, firefox */ url('#{$--font-path}/element-icons.ttf') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ font-weight: normal; font-display: $--font-display; font-style: normal; } [class^="el-icon-"], [class*=" el-icon-"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'element-icons' !important; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; vertical-align: baseline; display: inline-block; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .el-icon-ice-cream-round:before { content: "\e6a0"; } .el-icon-ice-cream-square:before { content: "\e6a3"; } .el-icon-lollipop:before { content: "\e6a4"; } .el-icon-potato-strips:before { content: "\e6a5"; } .el-icon-milk-tea:before { content: "\e6a6"; } .el-icon-ice-drink:before { content: "\e6a7"; } .el-icon-ice-tea:before { content: "\e6a9"; } .el-icon-coffee:before { content: "\e6aa"; } .el-icon-orange:before { content: "\e6ab"; } .el-icon-pear:before { content: "\e6ac"; } .el-icon-apple:before { content: "\e6ad"; } .el-icon-cherry:before { content: "\e6ae"; } .el-icon-watermelon:before { content: "\e6af"; } .el-icon-grape:before { content: "\e6b0"; } .el-icon-refrigerator:before { content: "\e6b1"; } .el-icon-goblet-square-full:before { content: "\e6b2"; } .el-icon-goblet-square:before { content: "\e6b3"; } .el-icon-goblet-full:before { content: "\e6b4"; } .el-icon-goblet:before { content: "\e6b5"; } .el-icon-cold-drink:before { content: "\e6b6"; } .el-icon-coffee-cup:before { content: "\e6b8"; } .el-icon-water-cup:before { content: "\e6b9"; } .el-icon-hot-water:before { content: "\e6ba"; } .el-icon-ice-cream:before { content: "\e6bb"; } .el-icon-dessert:before { content: "\e6bc"; } .el-icon-sugar:before { content: "\e6bd"; } .el-icon-tableware:before { content: "\e6be"; } .el-icon-burger:before { content: "\e6bf"; } .el-icon-knife-fork:before { content: "\e6c1"; } .el-icon-fork-spoon:before { content: "\e6c2"; } .el-icon-chicken:before { content: "\e6c3"; } .el-icon-food:before { content: "\e6c4"; } .el-icon-dish-1:before { content: "\e6c5"; } .el-icon-dish:before { content: "\e6c6"; } .el-icon-moon-night:before { content: "\e6ee"; } .el-icon-moon:before { content: "\e6f0"; } .el-icon-cloudy-and-sunny:before { content: "\e6f1"; } .el-icon-partly-cloudy:before { content: "\e6f2"; } .el-icon-cloudy:before { content: "\e6f3"; } .el-icon-sunny:before { content: "\e6f6"; } .el-icon-sunset:before { content: "\e6f7"; } .el-icon-sunrise-1:before { content: "\e6f8"; } .el-icon-sunrise:before { content: "\e6f9"; } .el-icon-heavy-rain:before { content: "\e6fa"; } .el-icon-lightning:before { content: "\e6fb"; } .el-icon-light-rain:before { content: "\e6fc"; } .el-icon-wind-power:before { content: "\e6fd"; } .el-icon-baseball:before { content: "\e712"; } .el-icon-soccer:before { content: "\e713"; } .el-icon-football:before { content: "\e715"; } .el-icon-basketball:before { content: "\e716"; } .el-icon-ship:before { content: "\e73f"; } .el-icon-truck:before { content: "\e740"; } .el-icon-bicycle:before { content: "\e741"; } .el-icon-mobile-phone:before { content: "\e6d3"; } .el-icon-service:before { content: "\e6d4"; } .el-icon-key:before { content: "\e6e2"; } .el-icon-unlock:before { content: "\e6e4"; } .el-icon-lock:before { content: "\e6e5"; } .el-icon-watch:before { content: "\e6fe"; } .el-icon-watch-1:before { content: "\e6ff"; } .el-icon-timer:before { content: "\e702"; } .el-icon-alarm-clock:before { content: "\e703"; } .el-icon-map-location:before { content: "\e704"; } .el-icon-delete-location:before { content: "\e705"; } .el-icon-add-location:before { content: "\e706"; } .el-icon-location-information:before { content: "\e707"; } .el-icon-location-outline:before { content: "\e708"; } .el-icon-location:before { content: "\e79e"; } .el-icon-place:before { content: "\e709"; } .el-icon-discover:before { content: "\e70a"; } .el-icon-first-aid-kit:before { content: "\e70b"; } .el-icon-trophy-1:before { content: "\e70c"; } .el-icon-trophy:before { content: "\e70d"; } .el-icon-medal:before { content: "\e70e"; } .el-icon-medal-1:before { content: "\e70f"; } .el-icon-stopwatch:before { content: "\e710"; } .el-icon-mic:before { content: "\e711"; } .el-icon-copy-document:before { content: "\e718"; } .el-icon-full-screen:before { content: "\e719"; } .el-icon-switch-button:before { content: "\e71b"; } .el-icon-aim:before { content: "\e71c"; } .el-icon-crop:before { content: "\e71d"; } .el-icon-odometer:before { content: "\e71e"; } .el-icon-time:before { content: "\e71f"; } .el-icon-bangzhu:before { content: "\e724"; } .el-icon-close-notification:before { content: "\e726"; } .el-icon-microphone:before { content: "\e727"; } .el-icon-turn-off-microphone:before { content: "\e728"; } .el-icon-position:before { content: "\e729"; } .el-icon-postcard:before { content: "\e72a"; } .el-icon-message:before { content: "\e72b"; } .el-icon-chat-line-square:before { content: "\e72d"; } .el-icon-chat-dot-square:before { content: "\e72e"; } .el-icon-chat-dot-round:before { content: "\e72f"; } .el-icon-chat-square:before { content: "\e730"; } .el-icon-chat-line-round:before { content: "\e731"; } .el-icon-chat-round:before { content: "\e732"; } .el-icon-set-up:before { content: "\e733"; } .el-icon-turn-off:before { content: "\e734"; } .el-icon-open:before { content: "\e735"; } .el-icon-connection:before { content: "\e736"; } .el-icon-link:before { content: "\e737"; } .el-icon-cpu:before { content: "\e738"; } .el-icon-thumb:before { content: "\e739"; } .el-icon-female:before { content: "\e73a"; } .el-icon-male:before { content: "\e73b"; } .el-icon-guide:before { content: "\e73c"; } .el-icon-news:before { content: "\e73e"; } .el-icon-price-tag:before { content: "\e744"; } .el-icon-discount:before { content: "\e745"; } .el-icon-wallet:before { content: "\e747"; } .el-icon-coin:before { content: "\e748"; } .el-icon-money:before { content: "\e749"; } .el-icon-bank-card:before { content: "\e74a"; } .el-icon-box:before { content: "\e74b"; } .el-icon-present:before { content: "\e74c"; } .el-icon-sell:before { content: "\e6d5"; } .el-icon-sold-out:before { content: "\e6d6"; } .el-icon-shopping-bag-2:before { content: "\e74d"; } .el-icon-shopping-bag-1:before { content: "\e74e"; } .el-icon-shopping-cart-2:before { content: "\e74f"; } .el-icon-shopping-cart-1:before { content: "\e750"; } .el-icon-shopping-cart-full:before { content: "\e751"; } .el-icon-smoking:before { content: "\e752"; } .el-icon-no-smoking:before { content: "\e753"; } .el-icon-house:before { content: "\e754"; } .el-icon-table-lamp:before { content: "\e755"; } .el-icon-school:before { content: "\e756"; } .el-icon-office-building:before { content: "\e757"; } .el-icon-toilet-paper:before { content: "\e758"; } .el-icon-notebook-2:before { content: "\e759"; } .el-icon-notebook-1:before { content: "\e75a"; } .el-icon-files:before { content: "\e75b"; } .el-icon-collection:before { content: "\e75c"; } .el-icon-receiving:before { content: "\e75d"; } .el-icon-suitcase-1:before { content: "\e760"; } .el-icon-suitcase:before { content: "\e761"; } .el-icon-film:before { content: "\e763"; } .el-icon-collection-tag:before { content: "\e765"; } .el-icon-data-analysis:before { content: "\e766"; } .el-icon-pie-chart:before { content: "\e767"; } .el-icon-data-board:before { content: "\e768"; } .el-icon-data-line:before { content: "\e76d"; } .el-icon-reading:before { content: "\e769"; } .el-icon-magic-stick:before { content: "\e76a"; } .el-icon-coordinate:before { content: "\e76b"; } .el-icon-mouse:before { content: "\e76c"; } .el-icon-brush:before { content: "\e76e"; } .el-icon-headset:before { content: "\e76f"; } .el-icon-umbrella:before { content: "\e770"; } .el-icon-scissors:before { content: "\e771"; } .el-icon-mobile:before { content: "\e773"; } .el-icon-attract:before { content: "\e774"; } .el-icon-monitor:before { content: "\e775"; } .el-icon-search:before { content: "\e778"; } .el-icon-takeaway-box:before { content: "\e77a"; } .el-icon-paperclip:before { content: "\e77d"; } .el-icon-printer:before { content: "\e77e"; } .el-icon-document-add:before { content: "\e782"; } .el-icon-document:before { content: "\e785"; } .el-icon-document-checked:before { content: "\e786"; } .el-icon-document-copy:before { content: "\e787"; } .el-icon-document-delete:before { content: "\e788"; } .el-icon-document-remove:before { content: "\e789"; } .el-icon-tickets:before { content: "\e78b"; } .el-icon-folder-checked:before { content: "\e77f"; } .el-icon-folder-delete:before { content: "\e780"; } .el-icon-folder-remove:before { content: "\e781"; } .el-icon-folder-add:before { content: "\e783"; } .el-icon-folder-opened:before { content: "\e784"; } .el-icon-folder:before { content: "\e78a"; } .el-icon-edit-outline:before { content: "\e764"; } .el-icon-edit:before { content: "\e78c"; } .el-icon-date:before { content: "\e78e"; } .el-icon-c-scale-to-original:before { content: "\e7c6"; } .el-icon-view:before { content: "\e6ce"; } .el-icon-loading:before { content: "\e6cf"; } .el-icon-rank:before { content: "\e6d1"; } .el-icon-sort-down:before { content: "\e7c4"; } .el-icon-sort-up:before { content: "\e7c5"; } .el-icon-sort:before { content: "\e6d2"; } .el-icon-finished:before { content: "\e6cd"; } .el-icon-refresh-left:before { content: "\e6c7"; } .el-icon-refresh-right:before { content: "\e6c8"; } .el-icon-refresh:before { content: "\e6d0"; } .el-icon-video-play:before { content: "\e7c0"; } .el-icon-video-pause:before { content: "\e7c1"; } .el-icon-d-arrow-right:before { content: "\e6dc"; } .el-icon-d-arrow-left:before { content: "\e6dd"; } .el-icon-arrow-up:before { content: "\e6e1"; } .el-icon-arrow-down:before { content: "\e6df"; } .el-icon-arrow-right:before { content: "\e6e0"; } .el-icon-arrow-left:before { content: "\e6de"; } .el-icon-top-right:before { content: "\e6e7"; } .el-icon-top-left:before { content: "\e6e8"; } .el-icon-top:before { content: "\e6e6"; } .el-icon-bottom:before { content: "\e6eb"; } .el-icon-right:before { content: "\e6e9"; } .el-icon-back:before { content: "\e6ea"; } .el-icon-bottom-right:before { content: "\e6ec"; } .el-icon-bottom-left:before { content: "\e6ed"; } .el-icon-caret-top:before { content: "\e78f"; } .el-icon-caret-bottom:before { content: "\e790"; } .el-icon-caret-right:before { content: "\e791"; } .el-icon-caret-left:before { content: "\e792"; } .el-icon-d-caret:before { content: "\e79a"; } .el-icon-share:before { content: "\e793"; } .el-icon-menu:before { content: "\e798"; } .el-icon-s-grid:before { content: "\e7a6"; } .el-icon-s-check:before { content: "\e7a7"; } .el-icon-s-data:before { content: "\e7a8"; } .el-icon-s-opportunity:before { content: "\e7aa"; } .el-icon-s-custom:before { content: "\e7ab"; } .el-icon-s-claim:before { content: "\e7ad"; } .el-icon-s-finance:before { content: "\e7ae"; } .el-icon-s-comment:before { content: "\e7af"; } .el-icon-s-flag:before { content: "\e7b0"; } .el-icon-s-marketing:before { content: "\e7b1"; } .el-icon-s-shop:before { content: "\e7b4"; } .el-icon-s-open:before { content: "\e7b5"; } .el-icon-s-management:before { content: "\e7b6"; } .el-icon-s-ticket:before { content: "\e7b7"; } .el-icon-s-release:before { content: "\e7b8"; } .el-icon-s-home:before { content: "\e7b9"; } .el-icon-s-promotion:before { content: "\e7ba"; } .el-icon-s-operation:before { content: "\e7bb"; } .el-icon-s-unfold:before { content: "\e7bc"; } .el-icon-s-fold:before { content: "\e7a9"; } .el-icon-s-platform:before { content: "\e7bd"; } .el-icon-s-order:before { content: "\e7be"; } .el-icon-s-cooperation:before { content: "\e7bf"; } .el-icon-bell:before { content: "\e725"; } .el-icon-message-solid:before { content: "\e799"; } .el-icon-video-camera:before { content: "\e772"; } .el-icon-video-camera-solid:before { content: "\e796"; } .el-icon-camera:before { content: "\e779"; } .el-icon-camera-solid:before { content: "\e79b"; } .el-icon-download:before { content: "\e77c"; } .el-icon-upload2:before { content: "\e77b"; } .el-icon-upload:before { content: "\e7c3"; } .el-icon-picture-outline-round:before { content: "\e75f"; } .el-icon-picture-outline:before { content: "\e75e"; } .el-icon-picture:before { content: "\e79f"; } .el-icon-close:before { content: "\e6db"; } .el-icon-check:before { content: "\e6da"; } .el-icon-plus:before { content: "\e6d9"; } .el-icon-minus:before { content: "\e6d8"; } .el-icon-help:before { content: "\e73d"; } .el-icon-s-help:before { content: "\e7b3"; } .el-icon-circle-close:before { content: "\e78d"; } .el-icon-circle-check:before { content: "\e720"; } .el-icon-circle-plus-outline:before { content: "\e723"; } .el-icon-remove-outline:before { content: "\e722"; } .el-icon-zoom-out:before { content: "\e776"; } .el-icon-zoom-in:before { content: "\e777"; } .el-icon-error:before { content: "\e79d"; } .el-icon-success:before { content: "\e79c"; } .el-icon-circle-plus:before { content: "\e7a0"; } .el-icon-remove:before { content: "\e7a2"; } .el-icon-info:before { content: "\e7a1"; } .el-icon-question:before { content: "\e7a4"; } .el-icon-warning-outline:before { content: "\e6c9"; } .el-icon-warning:before { content: "\e7a3"; } .el-icon-goods:before { content: "\e7c2"; } .el-icon-s-goods:before { content: "\e7b2"; } .el-icon-star-off:before { content: "\e717"; } .el-icon-star-on:before { content: "\e797"; } .el-icon-more-outline:before { content: "\e6cc"; } .el-icon-more:before { content: "\e794"; } .el-icon-phone-outline:before { content: "\e6cb"; } .el-icon-phone:before { content: "\e795"; } .el-icon-user:before { content: "\e6e3"; } .el-icon-user-solid:before { content: "\e7a5"; } .el-icon-setting:before { content: "\e6ca"; } .el-icon-s-tools:before { content: "\e7ac"; } .el-icon-delete:before { content: "\e6d7"; } .el-icon-delete-solid:before { content: "\e7c9"; } .el-icon-eleme:before { content: "\e7c7"; } .el-icon-platform-eleme:before { content: "\e7ca"; } .el-icon-loading { animation: rotating 2s linear infinite; } .el-icon--right { margin-left: 5px; } .el-icon--left { margin-right: 5px; } @keyframes rotating { 0% { transform: rotateZ(0deg); } 100% { transform: rotateZ(360deg); } } ================================================ FILE: packages/theme-chalk/src/image.scss ================================================ @import "mixins/mixins"; @import "common/var"; %size { width: 100%; height: 100%; } @include b(image) { position: relative; display: inline-block; overflow: hidden; @include e(inner) { @extend %size; vertical-align: top; @include m(center) { position: relative; top: 50%; left: 50%; transform: translate(-50%, -50%); display: block; } } @include e(placeholder) { @extend %size; background: $--background-color-base; } @include e(error) { @extend %size; display: flex; justify-content: center; align-items: center; font-size: 14px; background: $--background-color-base; color: $--color-text-placeholder; vertical-align: middle; } @include e(preview) { cursor: pointer; } } @include b(image-viewer) { @include e(wrapper) { position: fixed; top: 0; right: 0; bottom: 0; left: 0; } @include e(btn) { position: absolute; z-index: 1; display: flex; align-items: center; justify-content: center; border-radius: 50%; opacity: .8; cursor: pointer; box-sizing: border-box; user-select: none; } @include e(close) { top: 40px; right: 40px; width: 40px; height: 40px; font-size: 24px; color: #fff; background-color: #606266; } @include e(canvas) { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } @include e(actions) { left: 50%; bottom: 30px; transform: translateX(-50%); width: 282px; height: 44px; padding: 0 23px; background-color: #606266; border-color: #fff; border-radius: 22px; @include e(actions__inner) { width: 100%; height: 100%; text-align: justify; cursor: default; font-size: 23px; color: #fff; display: flex; align-items: center; justify-content: space-around; } } @include e(prev){ top: 50%; transform: translateY(-50%); width: 44px; height: 44px; font-size: 24px; color: #fff; background-color: #606266; border-color: #fff; left: 40px; } @include e(next){ top: 50%; transform: translateY(-50%); width: 44px; height: 44px; font-size: 24px; color: #fff; background-color: #606266; border-color: #fff; right: 40px; text-indent: 2px; } @include e(mask) { position: absolute; width: 100%; height: 100%; top: 0; left: 0; opacity: .5; background: #000; } } .viewer-fade-enter-active { animation: viewer-fade-in .3s; } .viewer-fade-leave-active { animation: viewer-fade-out .3s; } @keyframes viewer-fade-in { 0% { transform: translate3d(0, -20px, 0); opacity: 0; } 100% { transform: translate3d(0, 0, 0); opacity: 1; } } @keyframes viewer-fade-out { 0% { transform: translate3d(0, 0, 0); opacity: 1; } 100% { transform: translate3d(0, -20px, 0); opacity: 0; } } ================================================ FILE: packages/theme-chalk/src/index.scss ================================================ @import "./base.scss"; @import "./pagination.scss"; @import "./dialog.scss"; @import "./autocomplete.scss"; @import "./dropdown.scss"; @import "./dropdown-menu.scss"; @import "./dropdown-item.scss"; @import "./menu.scss"; @import "./submenu.scss"; @import "./menu-item.scss"; @import "./menu-item-group.scss"; @import "./input.scss"; @import "./input-number.scss"; @import "./radio.scss"; @import "./radio-group.scss"; @import "./radio-button.scss"; @import "./checkbox.scss"; @import "./checkbox-button.scss"; @import "./checkbox-group.scss"; @import "./switch.scss"; @import "./select.scss"; @import "./button.scss"; @import "./button-group.scss"; @import "./table.scss"; @import "./table-column.scss"; @import "./date-picker.scss"; @import "./time-select.scss"; @import "./time-picker.scss"; @import "./popover.scss"; @import "./tooltip.scss"; @import "./message-box.scss"; @import "./breadcrumb.scss"; @import "./breadcrumb-item.scss"; @import "./form.scss"; @import "./form-item.scss"; @import "./tabs.scss"; @import "./tab-pane.scss"; @import "./tag.scss"; @import "./tree.scss"; @import "./alert.scss"; @import "./notification.scss"; @import "./slider.scss"; @import "./loading.scss"; @import "./row.scss"; @import "./col.scss"; @import "./upload.scss"; @import "./progress.scss"; @import "./spinner.scss"; @import "./message.scss"; @import "./badge.scss"; @import "./card.scss"; @import "./rate.scss"; @import "./steps.scss"; @import "./step.scss"; @import "./carousel.scss"; @import "./scrollbar.scss"; @import "./carousel-item.scss"; @import "./collapse.scss"; @import "./collapse-item.scss"; @import "./cascader.scss"; @import "./color-picker.scss"; @import "./transfer.scss"; @import "./container.scss"; @import "./header.scss"; @import "./aside.scss"; @import "./main.scss"; @import "./footer.scss"; @import "./timeline.scss"; @import "./timeline-item.scss"; @import "./link.scss"; @import "./divider.scss"; @import "./image.scss"; @import "./calendar.scss"; @import "./backtop.scss"; @import "./infinite-scroll.scss"; @import "./page-header.scss"; @import "./cascader-panel.scss"; @import "./avatar.scss"; @import "./drawer.scss"; @import "./statistic.scss"; @import "./popconfirm.scss"; @import "./skeleton.scss"; @import "./skeleton-item.scss"; @import "./empty.scss"; @import "./descriptions.scss"; @import "./descriptions-item.scss"; @import "./result.scss"; ================================================ FILE: packages/theme-chalk/src/infinite-scroll.scss ================================================ ================================================ FILE: packages/theme-chalk/src/infiniteScroll.scss ================================================ ================================================ FILE: packages/theme-chalk/src/input-number.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "input"; @include b(input-number) { position: relative; display: inline-block; width: 180px; line-height: #{$--input-height - 2}; .el-input { display: block; &__inner { -webkit-appearance: none; padding-left: #{$--input-height + 10}; padding-right: #{$--input-height + 10}; text-align: center; } } @include e((increase, decrease)) { position: absolute; z-index: 1; top: 1px; width: $--input-height; height: auto; text-align: center; background: $--background-color-base; color: $--color-text-regular; cursor: pointer; font-size: 13px; &:hover { color: $--color-primary; &:not(.is-disabled) ~ .el-input .el-input__inner:not(.is-disabled) { border-color: $--input-focus-border; } } &.is-disabled { color: $--disabled-color-base; cursor: not-allowed; } } @include e(increase) { right: 1px; border-radius: 0 $--border-radius-base $--border-radius-base 0; border-left: $--border-base; } @include e(decrease) { left: 1px; border-radius: $--border-radius-base 0 0 $--border-radius-base; border-right: $--border-base; } @include when(disabled) { @include e((increase, decrease)) { border-color: $--disabled-border-base; color: $--disabled-border-base; &:hover { color: $--disabled-border-base; cursor: not-allowed; } } } @include m(medium) { width: 200px; line-height: #{$--input-medium-height - 2}; @include e((increase, decrease)) { width: $--input-medium-height; font-size: $--input-medium-font-size; } .el-input__inner { padding-left: #{$--input-medium-height + 7}; padding-right: #{$--input-medium-height + 7}; } } @include m(small) { width: 130px; line-height: #{$--input-small-height - 2}; @include e((increase, decrease)) { width: $--input-small-height; font-size: $--input-small-font-size; [class*=el-icon] { transform: scale(.9); } } .el-input__inner { padding-left: #{$--input-small-height + 7}; padding-right: #{$--input-small-height + 7}; } } @include m(mini) { width: 130px; line-height: #{$--input-mini-height - 2}; @include e((increase, decrease)) { width: $--input-mini-height; font-size: $--input-mini-font-size; [class*=el-icon] { transform: scale(.8); } } .el-input__inner { padding-left: #{$--input-mini-height + 7}; padding-right: #{$--input-mini-height + 7}; } } @include when(without-controls) { .el-input__inner { padding-left: 15px; padding-right: 15px; } } @include when(controls-right) { .el-input__inner { padding-left: 15px; padding-right: #{$--input-height + 10}; } @include e((increase, decrease)) { height: auto; line-height: #{($--input-height - 2) / 2}; [class*=el-icon] { transform: scale(.8); } } @include e(increase) { border-radius: 0 $--border-radius-base 0 0; border-bottom: $--border-base; } @include e(decrease) { right: 1px; bottom: 1px; top: auto; left: auto; border-right: none; border-left: $--border-base; border-radius: 0 0 $--border-radius-base 0; } &[class*=medium] { [class*=increase], [class*=decrease] { line-height: #{($--input-medium-height - 2) / 2}; } } &[class*=small] { [class*=increase], [class*=decrease] { line-height: #{($--input-small-height - 2) / 2}; } } &[class*=mini] { [class*=increase], [class*=decrease] { line-height: #{($--input-mini-height - 2) / 2}; } } } } ================================================ FILE: packages/theme-chalk/src/input.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(textarea) { position: relative; display: inline-block; width: 100%; vertical-align: bottom; font-size: $--font-size-base; @include e(inner) { display: block; resize: vertical; padding: 5px 15px; line-height: 1.5; box-sizing: border-box; width: 100%; font-size: inherit; color: $--input-font-color; background-color: $--input-background-color; background-image: none; border: $--input-border; border-radius: $--input-border-radius; transition: $--border-transition-base; &::placeholder { color: $--input-placeholder-color; } &:hover { border-color: $--input-hover-border; } &:focus { outline: none; border-color: $--input-focus-border; } } & .el-input__count { color: $--color-info; background: $--color-white; position: absolute; font-size: 12px; bottom: 5px; right: 10px; } @include when(disabled) { .el-textarea__inner { background-color: $--input-disabled-fill; border-color: $--input-disabled-border; color: $--input-disabled-color; cursor: not-allowed; &::placeholder { color: $--input-disabled-placeholder-color; } } } @include when(exceed) { .el-textarea__inner { border-color: $--color-danger; } .el-input__count { color: $--color-danger; } } } @include b(input) { position: relative; font-size: $--font-size-base; display: inline-block; width: 100%; @include scroll-bar; & .el-input__clear { color: $--input-icon-color; font-size: $--input-font-size; cursor: pointer; transition: $--color-transition-base; &:hover { color: $--input-clear-hover-color; } } & .el-input__count { height: 100%; display: inline-flex; align-items: center; color: $--color-info; font-size: 12px; .el-input__count-inner { background: $--color-white; line-height: initial; display: inline-block; padding: 0 5px; } } @include e(inner) { -webkit-appearance: none; background-color: $--input-background-color; background-image: none; border-radius: $--input-border-radius; border: $--input-border; box-sizing: border-box; color: $--input-font-color; display: inline-block; font-size: inherit; height: $--input-height; line-height: $--input-height; outline: none; padding: 0 15px; transition: $--border-transition-base; width: 100%; &::-ms-reveal { display: none; } &::placeholder { color: $--input-placeholder-color; } &:hover { border-color: $--input-hover-border; } &:focus { outline: none; border-color: $--input-focus-border; } } @include e(suffix) { position: absolute; height: 100%; right: 5px; top: 0; text-align: center; color: $--input-icon-color; transition: all .3s; pointer-events: none; } @include e(suffix-inner) { pointer-events: all; } @include e(prefix) { position: absolute; height: 100%; left: 5px; top: 0; text-align: center; color: $--input-icon-color; transition: all .3s; } @include e(icon) { height: 100%; width: 25px; text-align: center; transition: all .3s; line-height: $--input-height; &:after { content: ''; height: 100%; width: 0; display: inline-block; vertical-align: middle; } } @include e(validateIcon) { pointer-events: none; } @include when(active) { .el-input__inner { outline: none; border-color: $--input-focus-border; } } @include when(disabled) { .el-input__inner { background-color: $--input-disabled-fill; border-color: $--input-disabled-border; color: $--input-disabled-color; cursor: not-allowed; &::placeholder { color: $--input-disabled-placeholder-color; } } .el-input__icon { cursor: not-allowed; } } @include when(exceed) { .el-input__inner { border-color: $--color-danger; } .el-input__suffix { .el-input__count { color: $--color-danger; } } } @include m(suffix) { .el-input__inner { padding-right: 30px; } } @include m(prefix) { .el-input__inner { padding-left: 30px; } } @include m(medium) { font-size: $--input-medium-font-size; @include e(inner) { height: $--input-medium-height; line-height: $--input-medium-height; } .el-input__icon { line-height: $--input-medium-height; } } @include m(small) { font-size: $--input-small-font-size; @include e(inner) { height: $--input-small-height; line-height: $--input-small-height; } .el-input__icon { line-height: $--input-small-height; } } @include m(mini) { font-size: $--input-mini-font-size; @include e(inner) { height: $--input-mini-height; line-height: $--input-mini-height; } .el-input__icon { line-height: $--input-mini-height; } } } @include b(input-group) { line-height: normal; display: inline-table; width: 100%; border-collapse: separate; border-spacing:0; > .el-input__inner { vertical-align: middle; display: table-cell; } @include e((append, prepend)) { background-color: $--background-color-base; color: $--color-info; vertical-align: middle; display: table-cell; position: relative; border: $--border-base; border-radius: $--input-border-radius; padding: 0 20px; width: 1px; white-space: nowrap; &:focus { outline: none; } .el-select, .el-button { display: inline-block; margin: -10px -20px; } button.el-button, div.el-select .el-input__inner, div.el-select:hover .el-input__inner { border-color: transparent; background-color: transparent; color: inherit; border-top: 0; border-bottom: 0; } .el-button, .el-input { font-size: inherit; } } @include e(prepend) { border-right: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; } @include e(append) { border-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; } @include m(prepend) { .el-input__inner { border-top-left-radius: 0; border-bottom-left-radius: 0; } .el-select .el-input.is-focus .el-input__inner { border-color: transparent; } } @include m(append) { .el-input__inner { border-top-right-radius: 0; border-bottom-right-radius: 0; } .el-select .el-input.is-focus .el-input__inner { border-color: transparent; } } } /** disalbe default clear on IE */ .el-input__inner::-ms-clear { display: none; width: 0; height: 0; } ================================================ FILE: packages/theme-chalk/src/link.scss ================================================ @import "mixins/mixins"; @import "common/var"; $typeMap: ( primary: $--link-primary-font-color, danger: $--link-danger-font-color, success: $--link-success-font-color, warning: $--link-warning-font-color, info: $--link-info-font-color); @include b(link) { display: inline-flex; flex-direction: row; align-items: center; justify-content: center; vertical-align: middle; position: relative; text-decoration: none; outline: none; cursor: pointer; padding: 0; font-size: $--link-font-size; font-weight: $--link-font-weight; @include when(underline) { &:hover:after { content: ""; position: absolute; left: 0; right: 0; height: 0; bottom: 0; border-bottom: 1px solid $--link-default-active-color } } @include when(disabled) { cursor: not-allowed; } & [class*="el-icon-"] { & + span { margin-left: 5px; } } &.el-link--default { color: $--link-default-font-color; &:hover { color: $--link-default-active-color } &:after { border-color: $--link-default-active-color } @include when(disabled) { color: $--link-disabled-font-color } } @each $type, $primaryColor in $typeMap { &.el-link--#{$type} { color: $primaryColor; &:hover { color: mix($primaryColor, $--color-white, 80%) } &:after { border-color: $primaryColor } @include when(disabled) { color: mix($primaryColor, $--color-white, 50%) } @include when(underline) { &:hover:after { border-color: $primaryColor } } } } } ================================================ FILE: packages/theme-chalk/src/loading.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(loading-parent) { @include m(relative) { position: relative !important; } @include m(hidden) { overflow: hidden !important; } } @include b(loading-mask) { position: absolute; z-index: 2000; background-color: rgba(255, 255, 255, .9); margin: 0; top: 0; right: 0; bottom: 0; left: 0; transition: opacity 0.3s; @include when(fullscreen) { position: fixed; .el-loading-spinner { margin-top: #{- $--loading-fullscreen-spinner-size / 2}; .circular { height: $--loading-fullscreen-spinner-size; width: $--loading-fullscreen-spinner-size; } } } } @include b(loading-spinner) { top: 50%; margin-top: #{- $--loading-spinner-size / 2}; width: 100%; text-align: center; position: absolute; .el-loading-text { color: $--color-primary; margin: 3px 0; font-size: 14px; } .circular { height: $--loading-spinner-size; width: $--loading-spinner-size; animation: loading-rotate 2s linear infinite; } .path { animation: loading-dash 1.5s ease-in-out infinite; stroke-dasharray: 90, 150; stroke-dashoffset: 0; stroke-width: 2; stroke: $--color-primary; stroke-linecap: round; } i { color: $--color-primary; } } .el-loading-fade-enter, .el-loading-fade-leave-active { opacity: 0; } @keyframes loading-rotate { 100% { transform: rotate(360deg); } } @keyframes loading-dash { 0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -40px; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -120px; } } ================================================ FILE: packages/theme-chalk/src/main.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(main) { // IE11 supports the
element partially https://caniuse.com/#search=main display: block; flex: 1; flex-basis: auto; overflow: auto; box-sizing: border-box; padding: $--main-padding; } ================================================ FILE: packages/theme-chalk/src/menu-item-group.scss ================================================ ================================================ FILE: packages/theme-chalk/src/menu-item.scss ================================================ ================================================ FILE: packages/theme-chalk/src/menu.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @import "common/transition"; @mixin menu-item { height: 56px; line-height: 56px; font-size: $--menu-item-font-size; color: $--menu-item-font-color; padding: 0 20px; list-style: none; cursor: pointer; position: relative; transition: border-color .3s, background-color .3s, color .3s; box-sizing: border-box; white-space: nowrap; * { vertical-align: middle; } i { color: $--color-text-secondary; } &:hover, &:focus { outline: none; background-color: $--menu-item-hover-fill; } @include when(disabled) { opacity: 0.25; cursor: not-allowed; background: none !important; } } @include b(menu) { border-right: solid 1px #e6e6e6; list-style: none; position: relative; margin: 0; padding-left: 0; background-color: $--menu-background-color; @include utils-clearfix; &.el-menu--horizontal { border-bottom: solid 1px #e6e6e6; } @include m(horizontal) { border-right: none; & > .el-menu-item { float: left; height: 60px; line-height: 60px; margin: 0; border-bottom: 2px solid transparent; color: $--color-text-secondary; a, a:hover { color: inherit; } &:not(.is-disabled):hover, &:not(.is-disabled):focus{ background-color: #fff; } } & > .el-submenu { float: left; &:focus, &:hover { outline: none; .el-submenu__title { color: $--color-text-primary; } } &.is-active { .el-submenu__title { border-bottom: 2px solid $--color-primary; color: $--color-text-primary; } } & .el-submenu__title { height: 60px; line-height: 60px; border-bottom: 2px solid transparent; color: $--color-text-secondary; &:hover { background-color: #fff; } } & .el-submenu__icon-arrow { position: static; vertical-align: middle; margin-left: 8px; margin-top: -3px; } } & .el-menu { & .el-menu-item, & .el-submenu__title { background-color: $--color-white; float: none; height: 36px; line-height: 36px; padding: 0 10px; color: $--color-text-secondary; } & .el-menu-item.is-active, & .el-submenu.is-active > .el-submenu__title { color: $--color-text-primary; } } & .el-menu-item:not(.is-disabled):hover, & .el-menu-item:not(.is-disabled):focus { outline: none; color: $--color-text-primary; } & > .el-menu-item.is-active { border-bottom: 2px solid $--color-primary; color: $--color-text-primary; } } @include m(collapse) { width: 64px; > .el-menu-item, > .el-submenu > .el-submenu__title { [class^="el-icon-"] { margin: 0; vertical-align: middle; width: 24px; text-align: center; } .el-submenu__icon-arrow { display: none; } span { height: 0; width: 0; overflow: hidden; visibility: hidden; display: inline-block; } } > .el-menu-item.is-active i { color: inherit; } .el-menu .el-submenu { min-width: 200px; } .el-submenu { position: relative; & .el-menu { position: absolute; margin-left: 5px; top: 0; left: 100%; z-index: 10; border: 1px solid $--border-color-light; border-radius: $--border-radius-small; box-shadow: $--box-shadow-light; } &.is-opened { > .el-submenu__title .el-submenu__icon-arrow { transform: none; } } } } @include m(popup) { z-index: 100; min-width: 200px; border: none; padding: 5px 0; border-radius: $--border-radius-small; box-shadow: $--box-shadow-light; &-bottom-start { margin-top: 5px; } &-right-start { margin-left: 5px; margin-right: 5px; } } } @include b(menu-item) { @include menu-item; & [class^="el-icon-"] { margin-right: 5px; width: 24px; text-align: center; font-size: 18px; vertical-align: middle; } @include when(active) { color: $--color-primary; i { color: inherit; } } } @include b(submenu) { list-style: none; margin: 0; padding-left: 0; @include e(title) { @include menu-item; &:hover { background-color: $--menu-item-hover-fill; } } & .el-menu { border: none; } & .el-menu-item { height: 50px; line-height: 50px; padding: 0 45px; min-width: 200px; } @include e(icon-arrow) { position: absolute; top: 50%; right: 20px; margin-top: -7px; transition: transform .3s; font-size: 12px; } @include when(active) { .el-submenu__title { border-bottom-color: $--color-primary; } } @include when(opened) { > .el-submenu__title .el-submenu__icon-arrow { transform: rotateZ(180deg); } } @include when(disabled) { .el-submenu__title, .el-menu-item { opacity: 0.25; cursor: not-allowed; background: none !important; } } [class^="el-icon-"] { vertical-align: middle; margin-right: 5px; width: 24px; text-align: center; font-size: 18px; } } @include b(menu-item-group) { > ul { padding: 0; } @include e(title) { padding: 7px 0 7px 20px; line-height: normal; font-size: 12px; color: $--color-text-secondary; } } .horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow { transition: .2s; opacity: 0; } ================================================ FILE: packages/theme-chalk/src/message-box.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "common/popup"; @import "button"; @import "input"; @include b(message-box) { display: inline-block; width: $--msgbox-width; padding-bottom: 10px; vertical-align: middle; background-color: $--color-white; border-radius: $--msgbox-border-radius; border: 1px solid $--border-color-lighter; font-size: $--messagebox-font-size; box-shadow: $--box-shadow-light; text-align: left; overflow: hidden; backface-visibility: hidden; @include e(wrapper) { position: fixed; top: 0; bottom: 0; left: 0; right: 0; text-align: center; &::after { content: ""; display: inline-block; height: 100%; width: 0; vertical-align: middle; } } @include e(header) { position: relative; padding: $--msgbox-padding-primary; padding-bottom: 10px; } @include e(title) { padding-left: 0; margin-bottom: 0; font-size: $--messagebox-font-size; line-height: 1; color: $--messagebox-title-color; } @include e(headerbtn) { position: absolute; top: $--msgbox-padding-primary; right: $--msgbox-padding-primary; padding: 0; border: none; outline: none; background: transparent; font-size: $--message-close-size; cursor: pointer; .el-message-box__close { color: $--color-info; } &:focus, &:hover { .el-message-box__close { color: $--color-primary; } } } @include e(content) { padding: 10px $--msgbox-padding-primary; color: $--messagebox-content-color; font-size: $--messagebox-content-font-size; } @include e(container) { position: relative; } @include e(input) { padding-top: 15px; & input.invalid { border-color: $--color-danger; &:focus { border-color: $--color-danger; } } } @include e(status) { position: absolute; top: 50%; transform: translateY(-50%); font-size: 24px !important; &::before { // 防止图标切割 padding-left: 1px; } + .el-message-box__message { padding-left: 36px; padding-right: 12px; } &.el-icon-success { color: $--messagebox-success-color; } &.el-icon-info { color: $--messagebox-info-color; } &.el-icon-warning { color: $--messagebox-warning-color; } &.el-icon-error { color: $--messagebox-danger-color; } } @include e(message) { margin: 0; & p { margin: 0; line-height: 24px; } } @include e(errormsg) { color: $--color-danger; font-size: $--messagebox-error-font-size; min-height: 18px; margin-top: 2px; } @include e(btns) { padding: 5px 15px 0; text-align: right; & button:nth-child(2) { margin-left: 10px; } } @include e(btns-reverse) { flex-direction: row-reverse; } // centerAlign 布局 @include m(center) { padding-bottom: 30px; @include e(header) { padding-top: 30px; } @include e(title) { position: relative; display: flex; align-items: center; justify-content: center; } @include e(status) { position: relative; top: auto; padding-right: 5px; text-align: center; transform: translateY(-1px); } @include e(message) { margin-left: 0; } @include e((btns, content)) { text-align: center; } @include e(content) { $padding-horizontal: $--msgbox-padding-primary + 12px; padding-left: $padding-horizontal; padding-right: $padding-horizontal; } } } .msgbox-fade-enter-active { animation: msgbox-fade-in .3s; } .msgbox-fade-leave-active { animation: msgbox-fade-out .3s; } @keyframes msgbox-fade-in { 0% { transform: translate3d(0, -20px, 0); opacity: 0; } 100% { transform: translate3d(0, 0, 0); opacity: 1; } } @keyframes msgbox-fade-out { 0% { transform: translate3d(0, 0, 0); opacity: 1; } 100% { transform: translate3d(0, -20px, 0); opacity: 0; } } ================================================ FILE: packages/theme-chalk/src/message.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(message) { min-width: $--message-min-width; box-sizing: border-box; border-radius: $--border-radius-base; border-width: $--border-width-base; border-style: $--border-style-base; border-color: $--border-color-lighter; position: fixed; left: 50%; top: 20px; transform: translateX(-50%); background-color: $--message-background-color; transition: opacity 0.3s, transform .4s, top 0.4s; overflow: hidden; padding: $--message-padding; display: flex; align-items: center; @include when(center) { justify-content: center; } @include when(closable) { .el-message__content { padding-right: 16px; } } p { margin: 0; } @include m(info) { .el-message__content { color: $--message-info-font-color; } } @include m(success) { background-color: $--color-success-lighter; border-color: $--color-success-light; .el-message__content { color: $--message-success-font-color; } } @include m(warning) { background-color: $--color-warning-lighter; border-color: $--color-warning-light; .el-message__content { color: $--message-warning-font-color; } } @include m(error) { background-color: $--color-danger-lighter; border-color: $--color-danger-light; .el-message__content { color: $--message-danger-font-color; } } @include e(icon) { margin-right: 10px; } @include e(content) { padding: 0; font-size: 14px; line-height: 1; &:focus { outline-width: 0; } } @include e(closeBtn) { position: absolute; top: 50%; right: 15px; transform: translateY(-50%); cursor: pointer; color: $--message-close-icon-color; font-size: $--message-close-size; &:focus { outline-width: 0; } &:hover { color: $--message-close-hover-color; } } & .el-icon-success { color: $--message-success-font-color; } & .el-icon-error { color: $--message-danger-font-color; } & .el-icon-info { color: $--message-info-font-color; } & .el-icon-warning { color: $--message-warning-font-color; } } .el-message-fade-enter, .el-message-fade-leave-active { opacity: 0; transform: translate(-50%, -100%); } ================================================ FILE: packages/theme-chalk/src/mixins/_button.scss ================================================ @import "../common/var"; @mixin button-plain($color) { color: $color; background: mix($--color-white, $color, 90%); border-color: mix($--color-white, $color, 60%); &:hover, &:focus { background: $color; border-color: $color; color: $--color-white; } &:active { background: mix($--color-black, $color, $--button-active-shade-percent); border-color: mix($--color-black, $color, $--button-active-shade-percent); color: $--color-white; outline: none; } &.is-disabled { &, &:hover, &:focus, &:active { color: mix($--color-white, $color, 40%); background-color: mix($--color-white, $color, 90%); border-color: mix($--color-white, $color, 80%); } } } @mixin button-variant($color, $background-color, $border-color) { color: $color; background-color: $background-color; border-color: $border-color; &:hover, &:focus { background: mix($--color-white, $background-color, $--button-hover-tint-percent); border-color: mix($--color-white, $border-color, $--button-hover-tint-percent); color: $color; } &:active { background: mix($--color-black, $background-color, $--button-active-shade-percent); border-color: mix($--color-black, $border-color, $--button-active-shade-percent); color: $color; outline: none; } &.is-active { background: mix($--color-black, $background-color, $--button-active-shade-percent); border-color: mix($--color-black, $border-color, $--button-active-shade-percent); color: $color; } &.is-disabled { &, &:hover, &:focus, &:active { color: $--color-white; background-color: mix($background-color, $--color-white); border-color: mix($border-color, $--color-white); } } &.is-plain { @include button-plain($background-color); } } @mixin button-size($padding-vertical, $padding-horizontal, $font-size, $border-radius) { padding: $padding-vertical $padding-horizontal; font-size: $font-size; border-radius: $border-radius; &.is-round { padding: $padding-vertical $padding-horizontal; } } ================================================ FILE: packages/theme-chalk/src/mixins/config.scss ================================================ $namespace: 'el'; $element-separator: '__'; $modifier-separator: '--'; $state-prefix: 'is-'; ================================================ FILE: packages/theme-chalk/src/mixins/function.scss ================================================ @import "config"; /* BEM support Func -------------------------- */ @function selectorToString($selector) { $selector: inspect($selector); $selector: str-slice($selector, 2, -2); @return $selector; } @function containsModifier($selector) { $selector: selectorToString($selector); @if str-index($selector, $modifier-separator) { @return true; } @else { @return false; } } @function containWhenFlag($selector) { $selector: selectorToString($selector); @if str-index($selector, '.' + $state-prefix) { @return true } @else { @return false } } @function containPseudoClass($selector) { $selector: selectorToString($selector); @if str-index($selector, ':') { @return true } @else { @return false } } @function hitAllSpecialNestRule($selector) { @return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector); } ================================================ FILE: packages/theme-chalk/src/mixins/mixins.scss ================================================ @import "function"; @import "../common/var"; /* Break-points -------------------------- */ @mixin res($key, $map: $--breakpoints) { // 循环断点Map,如果存在则返回 @if map-has-key($map, $key) { @media only screen and #{inspect(map-get($map, $key))} { @content; } } @else { @warn "Undefeined points: `#{$map}`"; } } /* Scrollbar -------------------------- */ @mixin scroll-bar { $--scrollbar-thumb-background: #b4bccc; $--scrollbar-track-background: #fff; &::-webkit-scrollbar { z-index: 11; width: 6px; &:horizontal { height: 6px; } &-thumb { border-radius: 5px; width: 6px; background: $--scrollbar-thumb-background; } &-corner { background: $--scrollbar-track-background; } &-track { background: $--scrollbar-track-background; &-piece { background: $--scrollbar-track-background; width: 6px; } } } } /* Placeholder -------------------------- */ @mixin placeholder { &::-webkit-input-placeholder { @content } &::-moz-placeholder { @content } &:-ms-input-placeholder { @content } } /* BEM -------------------------- */ @mixin b($block) { $B: $namespace+'-'+$block !global; .#{$B} { @content; } } @mixin e($element) { $E: $element !global; $selector: &; $currentSelector: ""; @each $unit in $element { $currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","}; } @if hitAllSpecialNestRule($selector) { @at-root { #{$selector} { #{$currentSelector} { @content; } } } } @else { @at-root { #{$currentSelector} { @content; } } } } @mixin m($modifier) { $selector: &; $currentSelector: ""; @each $unit in $modifier { $currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","}; } @at-root { #{$currentSelector} { @content; } } } @mixin configurable-m($modifier, $E-flag: false) { $selector: &; $interpolation: ''; @if $E-flag { $interpolation: $element-separator + $E-flag; } @at-root { #{$selector} { .#{$B+$interpolation+$modifier-separator+$modifier} { @content; } } } } @mixin spec-selector($specSelector: '', $element: $E, $modifier: false, $block: $B) { $modifierCombo: ''; @if $modifier { $modifierCombo: $modifier-separator + $modifier; } @at-root { #{&}#{$specSelector}.#{$block+$element-separator+$element+$modifierCombo} { @content } } } @mixin meb($modifier: false, $element: $E, $block: $B) { $selector: &; $modifierCombo: ''; @if $modifier { $modifierCombo: $modifier-separator + $modifier; } @at-root { #{$selector} { .#{$block+$element-separator+$element+$modifierCombo} { @content } } } } @mixin when($state) { @at-root { &.#{$state-prefix + $state} { @content; } } } @mixin extend-rule($name) { @extend #{'%shared-'+$name}; } @mixin share-rule($name) { $rule-name: '%shared-'+$name; @at-root #{$rule-name} { @content } } @mixin pseudo($pseudo) { @at-root #{&}#{':#{$pseudo}'} { @content } } ================================================ FILE: packages/theme-chalk/src/mixins/utils.scss ================================================ @mixin utils-user-select($value) { -moz-user-select: $value; -webkit-user-select: $value; -ms-user-select: $value; } @mixin utils-clearfix { $selector: &; @at-root { #{$selector}::before, #{$selector}::after { display: table; content: ""; } #{$selector}::after { clear: both } } } @mixin utils-vertical-center { $selector: &; @at-root { #{$selector}::after { display: inline-block; content: ""; height: 100%; vertical-align: middle } } } @mixin utils-ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } ================================================ FILE: packages/theme-chalk/src/notification.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(notification) { display: flex; width: $--notification-width; padding: $--notification-padding; border-radius: $--notification-radius; box-sizing: border-box; border: 1px solid $--notification-border-color; position: fixed; background-color: $--color-white; box-shadow: $--notification-shadow; transition: opacity .3s, transform .3s, left .3s, right .3s, top 0.4s, bottom .3s; overflow: hidden; &.right { right: 16px; } &.left { left: 16px; } @include e(group) { margin-left: $--notification-group-margin-left; margin-right: $--notification-group-margin-right; } @include e(title) { font-weight: bold; font-size: $--notification-title-font-size; color: $--notification-title-color; margin: 0; } @include e(content) { font-size: $--notification-content-font-size; line-height: 21px; margin: 6px 0 0 0; color: $--notification-content-color; text-align: justify; p { margin: 0; } } @include e(icon) { height: $--notification-icon-size; width: $--notification-icon-size; font-size: $--notification-icon-size; } @include e(closeBtn) { position: absolute; top: 18px; right: 15px; cursor: pointer; color: $--notification-close-color; font-size: $--notification-close-font-size; &:hover { color: $--notification-close-hover-color; } } .el-icon-success { color: $--notification-success-icon-color; } .el-icon-error { color: $--notification-danger-icon-color; } .el-icon-info { color: $--notification-info-icon-color; } .el-icon-warning { color: $--notification-warning-icon-color; } } .el-notification-fade-enter { &.right { right: 0; transform: translateX(100%); } &.left { left: 0; transform: translateX(-100%); } } .el-notification-fade-leave-active { opacity: 0; } ================================================ FILE: packages/theme-chalk/src/option-group.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(select-group) { $gap: 20px; margin: 0; padding: 0; @include e(wrap) { position: relative; list-style: none; margin: 0; padding: 0; &:not(:last-of-type) { padding-bottom: 24px; &::after { content: ''; position: absolute; display: block; left: $gap; right: $gap; bottom: 12px; height: 1px; background: $--border-color-light; } } } @include e(title) { padding-left: $gap; font-size: $--select-group-font-size; color: $--select-group-color; line-height: $--select-group-height; } & .el-select-dropdown__item { padding-left: $gap; } } ================================================ FILE: packages/theme-chalk/src/option.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(select-dropdown) { @include e(item) { font-size: $--select-font-size; padding: 0 20px; position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: $--select-option-color; height: $--select-option-height; line-height: $--select-option-height; box-sizing: border-box; cursor: pointer; @include when(disabled) { color: $--select-option-disabled-color; cursor: not-allowed; &:hover { background-color: $--color-white; } } &.hover, &:hover { background-color: $--select-option-hover-background; } &.selected { color: $--select-option-selected-font-color; font-weight: bold; } } } ================================================ FILE: packages/theme-chalk/src/page-header.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(page-header) { display: flex; line-height: 24px; @include e(left) { display: flex; cursor: pointer; margin-right: 40px; position: relative; &::after { content: ""; position: absolute; width: 1px; height: 16px; right: -20px; top: 50%; transform: translateY(-50%); background-color: $--border-color-base; } .el-icon-back { font-size: 18px; margin-right: 6px; align-self: center; } @include e(title) { font-size: 14px; font-weight: 500; } } @include e(content) { font-size: 18px; color: $--color-text-primary; } } ================================================ FILE: packages/theme-chalk/src/pagination.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @import "select"; @include b(pagination) { white-space: nowrap; padding: 2px 5px; color: $--pagination-font-color; font-weight: bold; @include utils-clearfix; span:not([class*=suffix]), button { display: inline-block; font-size: $--pagination-font-size; min-width: $--pagination-button-width; height: $--pagination-button-height; line-height: $--pagination-button-height; vertical-align: top; box-sizing: border-box; } .el-input__inner { text-align: center; -moz-appearance: textfield; line-height: normal; } // pagesize 的下拉 icon .el-input__suffix { right: 0; transform: scale(.8); } .el-select .el-input { width: 100px; margin: 0 5px; .el-input__inner { padding-right: 25px; border-radius: $--pagination-border-radius; } } button { border: none; padding: 0 6px; background: transparent; &:focus { outline: none; } &:hover { color: $--pagination-hover-color; } &:disabled { color: $--pagination-button-disabled-color; background-color: $--pagination-button-disabled-background-color; cursor: not-allowed; } } .btn-prev, .btn-next { background: center center no-repeat; background-size: 16px; background-color: $--pagination-background-color; cursor: pointer; margin: 0; color: $--pagination-button-color; .el-icon { display: block; font-size: 12px; font-weight: bold; } } .btn-prev { padding-right: 12px; } .btn-next { padding-left: 12px; } .el-pager li.disabled { color: $--color-text-placeholder; cursor: not-allowed; } @include m(small) { .btn-prev, .btn-next, .el-pager li, .el-pager li.btn-quicknext, .el-pager li.btn-quickprev, .el-pager li:last-child { border-color: transparent; font-size: 12px; line-height: 22px; height: 22px; min-width: 22px; } .arrow.disabled { visibility: hidden; } .more::before, li.more::before { line-height: 24px; } span:not([class*=suffix]), button { height: 22px; line-height: 22px; } @include e(editor) { height: 22px; &.el-input .el-input__inner { height: 22px; } } } @include e(sizes) { margin: 0 10px 0 0; font-weight: normal; color: $--color-text-regular; .el-input .el-input__inner { font-size: $--pagination-font-size; padding-left: 8px; &:hover { border-color: $--pagination-hover-color; } } } @include e(total) { margin-right: 10px; font-weight: normal; color: $--color-text-regular; } @include e(jump) { margin-left: 24px; font-weight: normal; color: $--color-text-regular; .el-input__inner { padding: 0 3px; } } @include e(rightwrapper) { float: right; } @include e(editor) { line-height: 18px; padding: 0 2px; height: $--pagination-button-height; text-align: center; margin: 0 2px; box-sizing: border-box; border-radius: $--pagination-border-radius; &.el-input { width: 50px; } &.el-input .el-input__inner { height: $--pagination-button-height; } .el-input__inner::-webkit-inner-spin-button, .el-input__inner::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } } @include when(background) { .btn-prev, .btn-next, .el-pager li { margin: 0 5px; background-color: $--color-info-lighter; color: $--color-text-regular; min-width: 30px; border-radius: 2px; &.disabled { color: $--color-text-placeholder; } } .btn-prev, .btn-next { padding: 0; &:disabled { color: $--color-text-placeholder; } } .el-pager li:not(.disabled) { &:hover { color: $--pagination-hover-color; } &.active { background-color: $--color-primary; color: $--color-white; } } &.el-pagination--small { .btn-prev, .btn-next, .el-pager li { margin: 0 3px; min-width: 22px; } } } } @include b(pager) { user-select: none; list-style: none; display: inline-block; vertical-align: top; font-size: 0; padding: 0; margin: 0; .more::before { line-height: 30px; } li { padding: 0 4px; background: $--pagination-background-color; vertical-align: top; display: inline-block; font-size: $--pagination-font-size; min-width: $--pagination-button-width; height: $--pagination-button-height; line-height: $--pagination-button-height; cursor: pointer; box-sizing: border-box; text-align: center; margin: 0; &.btn-quicknext, &.btn-quickprev { line-height: 28px; color: $--pagination-button-color; &.disabled { color: $--color-text-placeholder; } } &.btn-quickprev:hover { cursor: pointer; } &.btn-quicknext:hover { cursor: pointer; } &.active + li { border-left: 0; } &:hover { color: $--pagination-hover-color; } &.active { color: $--pagination-hover-color; cursor: default; } } } ================================================ FILE: packages/theme-chalk/src/popconfirm.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(popconfirm) { @include e(main) { display: flex; align-items: center; } @include e(icon) { margin-right: 5px; } @include e(action) { text-align: right; margin: 0 } } ================================================ FILE: packages/theme-chalk/src/popover.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "./popper"; @include b(popover) { position: absolute; background: $--popover-background-color; min-width: 150px; border-radius: 4px; border: 1px solid $--popover-border-color; padding: $--popover-padding; z-index: $--index-popper; color: $--color-text-regular; line-height: 1.4; text-align: justify; font-size: $--popover-font-size; box-shadow: $--box-shadow-light; word-break: break-all; @include m(plain) { padding: $--popover-padding-large; } @include e(title) { color: $--popover-title-font-color; font-size: $--popover-title-font-size; line-height: 1; margin-bottom: 12px; } @include e(reference) { &:focus:not(.focusing), &:focus:hover { outline-width: 0; } } &:focus:active, &:focus { outline-width: 0; } } ================================================ FILE: packages/theme-chalk/src/popper.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(popper) { .popper__arrow, .popper__arrow::after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid; } .popper__arrow { border-width: $--popover-arrow-size; filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03)) } .popper__arrow::after { content: " "; border-width: $--popover-arrow-size; } &[x-placement^="top"] { margin-bottom: #{$--popover-arrow-size + 6}; } &[x-placement^="top"] .popper__arrow { bottom: -$--popover-arrow-size; left: 50%; margin-right: #{$--tooltip-arrow-size / 2}; border-top-color: $--popover-border-color; border-bottom-width: 0; &::after { bottom: 1px; margin-left: -$--popover-arrow-size; border-top-color: $--popover-background-color; border-bottom-width: 0; } } &[x-placement^="bottom"] { margin-top: #{$--popover-arrow-size + 6}; } &[x-placement^="bottom"] .popper__arrow { top: -$--popover-arrow-size; left: 50%; margin-right: #{$--tooltip-arrow-size / 2}; border-top-width: 0; border-bottom-color: $--popover-border-color; &::after { top: 1px; margin-left: -$--popover-arrow-size; border-top-width: 0; border-bottom-color: $--popover-background-color; } } &[x-placement^="right"] { margin-left: #{$--popover-arrow-size + 6}; } &[x-placement^="right"] .popper__arrow { top: 50%; left: -$--popover-arrow-size; margin-bottom: #{$--tooltip-arrow-size / 2}; border-right-color: $--popover-border-color; border-left-width: 0; &::after { bottom: -$--popover-arrow-size; left: 1px; border-right-color: $--popover-background-color; border-left-width: 0; } } &[x-placement^="left"] { margin-right: #{$--popover-arrow-size + 6}; } &[x-placement^="left"] .popper__arrow { top: 50%; right: -$--popover-arrow-size; margin-bottom: #{$--tooltip-arrow-size / 2}; border-right-width: 0; border-left-color: $--popover-border-color; &::after { right: 1px; bottom: -$--popover-arrow-size; margin-left: -$--popover-arrow-size; border-right-width: 0; border-left-color: $--popover-background-color; } } } ================================================ FILE: packages/theme-chalk/src/progress.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @include b(progress) { position: relative; line-height: 1; @include e(text) { font-size:14px; color: $--color-text-regular; display: inline-block; vertical-align: middle; margin-left: 10px; line-height: 1; i { vertical-align: middle; display: block; } } @include m((circle,dashboard)) { display: inline-block; .el-progress__text { position: absolute; top: 50%; left: 0; width: 100%; text-align: center; margin: 0; transform: translate(0, -50%); i { vertical-align: middle; display: inline-block; } } } @include m(without-text) { .el-progress__text { display: none; } .el-progress-bar { padding-right: 0; margin-right: 0; display: block; } } @include m(text-inside) { .el-progress-bar { padding-right: 0; margin-right: 0; } } @include when(success) { .el-progress-bar__inner { background-color: $--color-success; } .el-progress__text { color: $--color-success; } } @include when(warning) { .el-progress-bar__inner { background-color: $--color-warning; } .el-progress__text { color: $--color-warning; } } @include when(exception) { .el-progress-bar__inner { background-color: $--color-danger; } .el-progress__text { color: $--color-danger; } } } @include b(progress-bar) { padding-right: 50px; display: inline-block; vertical-align: middle; width: 100%; margin-right: -55px; box-sizing: border-box; @include e(outer) { height: 6px; border-radius: 100px; background-color: $--border-color-lighter; overflow: hidden; position: relative; vertical-align: middle; } @include e(inner) { position: absolute; left: 0; top: 0; height: 100%; background-color: $--color-primary; text-align: right; border-radius: 100px; line-height: 1; white-space: nowrap; transition: width 0.6s ease; @include utils-vertical-center; } @include e(innerText) { display: inline-block; vertical-align: middle; color: $--color-white; font-size: 12px; margin: 0 5px; } } @keyframes progress { 0% { background-position: 0 0; } 100% { background-position: 32px 0; } } ================================================ FILE: packages/theme-chalk/src/radio-button.scss ================================================ @import "mixins/mixins"; @import "mixins/_button"; @import "common/var"; @include b(radio-button) { position: relative; display: inline-block; outline: none; @include e(inner) { display: inline-block; line-height: 1; white-space: nowrap; vertical-align: middle; background: $--button-default-background-color; border: $--border-base; font-weight: $--button-font-weight; border-left: 0; color: $--button-default-font-color; -webkit-appearance: none; text-align: center; box-sizing: border-box; outline: none; margin: 0; position: relative; cursor: pointer; transition: $--all-transition; @include button-size($--button-padding-vertical, $--button-padding-horizontal, $--button-font-size, 0); &:hover { color: $--color-primary; } & [class*="el-icon-"] { line-height: 0.9; & + span { margin-left: 5px; } } } &:first-child { .el-radio-button__inner { border-left: $--border-base; border-radius: $--border-radius-base 0 0 $--border-radius-base; box-shadow: none !important; } } @include e(orig-radio) { opacity: 0; outline: none; position: absolute; z-index: -1; &:checked { & + .el-radio-button__inner { color: $--radio-button-checked-font-color; background-color: $--radio-button-checked-background-color; border-color: $--radio-button-checked-border-color; box-shadow: -1px 0 0 0 $--radio-button-checked-border-color; } } &:disabled { & + .el-radio-button__inner { color: $--button-disabled-font-color; cursor: not-allowed; background-image: none; background-color: $--button-disabled-background-color; border-color: $--button-disabled-border-color; box-shadow: none; } &:checked + .el-radio-button__inner { background-color: $--radio-button-disabled-checked-fill; } } } &:last-child { .el-radio-button__inner { border-radius: 0 $--border-radius-base $--border-radius-base 0; } } &:first-child:last-child { .el-radio-button__inner { border-radius: $--border-radius-base; } } @include m(medium) { & .el-radio-button__inner { @include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, 0); } } @include m(small) { & .el-radio-button__inner { @include button-size($--button-small-padding-vertical, $--button-small-padding-horizontal, $--button-small-font-size, 0); } } @include m(mini) { & .el-radio-button__inner { @include button-size($--button-mini-padding-vertical, $--button-mini-padding-horizontal, $--button-mini-font-size, 0); } } &:focus:not(.is-focus):not(:active):not(.is-disabled){ /*获得焦点时 样式提醒*/ box-shadow: 0 0 2px 2px $--radio-button-checked-border-color; } } ================================================ FILE: packages/theme-chalk/src/radio-group.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(radio-group) { display: inline-block; line-height: 1; vertical-align: middle; font-size: 0; } ================================================ FILE: packages/theme-chalk/src/radio.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import 'mixins/button'; @import "common/var"; @include b(radio) { color: $--radio-font-color; font-weight: $--radio-font-weight; line-height: 1; position: relative; cursor: pointer; display: inline-block; white-space: nowrap; outline: none; font-size: $--font-size-base; margin-right: 30px; @include utils-user-select(none); @include when(bordered) { padding: $--radio-bordered-padding; border-radius: $--border-radius-base; border: $--border-base; box-sizing: border-box; height: $--radio-bordered-height; &.is-checked { border-color: $--color-primary; } &.is-disabled { cursor: not-allowed; border-color: $--border-color-lighter; } & + .el-radio.is-bordered { margin-left: 10px; } } @include m(medium) { &.is-bordered { padding: $--radio-bordered-medium-padding; border-radius: $--button-medium-border-radius; height: $--radio-bordered-medium-height; .el-radio__label { font-size: $--button-medium-font-size; } .el-radio__inner { height: $--radio-bordered-medium-input-height; width: $--radio-bordered-medium-input-width; } } } @include m(small) { &.is-bordered { padding: $--radio-bordered-small-padding; border-radius: $--button-small-border-radius; height: $--radio-bordered-small-height; .el-radio__label { font-size: $--button-small-font-size; } .el-radio__inner { height: $--radio-bordered-small-input-height; width: $--radio-bordered-small-input-width; } } } @include m(mini) { &.is-bordered { padding: $--radio-bordered-mini-padding; border-radius: $--button-mini-border-radius; height: $--radio-bordered-mini-height; .el-radio__label { font-size: $--button-mini-font-size; } .el-radio__inner { height: $--radio-bordered-mini-input-height; width: $--radio-bordered-mini-input-width; } } } &:last-child { margin-right: 0; } @include e(input) { white-space: nowrap; cursor: pointer; outline: none; display: inline-block; line-height: 1; position: relative; vertical-align: middle; @include when(disabled) { .el-radio__inner { background-color: $--radio-disabled-input-fill; border-color: $--radio-disabled-input-border-color; cursor: not-allowed; &::after { cursor: not-allowed; background-color: $--radio-disabled-icon-color; } & + .el-radio__label { cursor: not-allowed; } } &.is-checked { .el-radio__inner { background-color: $--radio-disabled-checked-input-fill; border-color: $--radio-disabled-checked-input-border-color; &::after { background-color: $--radio-disabled-checked-icon-color; } } } & + span.el-radio__label { color: $--color-text-placeholder; cursor: not-allowed; } } @include when(checked) { .el-radio__inner { border-color: $--radio-checked-input-border-color; background: $--radio-checked-icon-color; &::after { transform: translate(-50%, -50%) scale(1); } } & + .el-radio__label { color: $--radio-checked-font-color; } } @include when(focus) { .el-radio__inner { border-color: $--radio-input-border-color-hover; } } } @include e(inner) { border: $--radio-input-border; border-radius: $--radio-input-border-radius; width: $--radio-input-width; height: $--radio-input-height; background-color: $--radio-input-background-color; position: relative; cursor: pointer; display: inline-block; box-sizing: border-box; &:hover { border-color: $--radio-input-border-color-hover; } &::after { width: 4px; height: 4px; border-radius: $--radio-input-border-radius; background-color: $--color-white; content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0); transition: transform .15s ease-in; } } @include e(original) { opacity: 0; outline: none; position: absolute; z-index: -1; top: 0; left: 0; right: 0; bottom: 0; margin: 0; } &:focus:not(.is-focus):not(:active):not(.is-disabled) { /*获得焦点时 样式提醒*/ .el-radio__inner { box-shadow: 0 0 2px 2px $--radio-input-border-color-hover; } } @include e(label) { font-size: $--radio-font-size; padding-left: 10px; } } ================================================ FILE: packages/theme-chalk/src/rate.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(rate) { height: $--rate-height; line-height: 1; &:focus, &:active { outline-width: 0; } @include e(item) { display: inline-block; position: relative; font-size: 0; vertical-align: middle; } @include e(icon) { position: relative; display: inline-block; font-size: $--rate-icon-size; margin-right: $--rate-icon-margin; color: $--rate-icon-color; transition: .3s; &.hover { transform: scale(1.15); } .path2 { position: absolute; left: 0; top: 0; } } @include e(decimal) { position: absolute; top: 0; left: 0; display: inline-block; overflow: hidden; } @include e(text) { font-size: $--rate-font-size; vertical-align: middle; } } ================================================ FILE: packages/theme-chalk/src/reset.scss ================================================ @import 'common/var'; body { font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; font-weight: 400; font-size: $--font-size-base; color: $--color-black; -webkit-font-smoothing: antialiased; } a { color: $--color-primary; text-decoration: none; &:hover, &:focus { color: mix($--color-white, $--color-primary, $--button-hover-tint-percent); } &:active { color: mix($--color-black, $--color-primary, $--button-active-shade-percent); } } h1, h2, h3, h4, h5, h6 { color: $--color-text-regular; font-weight: inherit; &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } } h1 { font-size: #{$--font-size-base + 6px}; } h2 { font-size: #{$--font-size-base + 4px}; } h3 { font-size: #{$--font-size-base + 2px}; } h4, h5, h6, p { font-size: inherit; } p { line-height: 1.8; &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } } sup, sub { font-size: #{$--font-size-base - 1px}; } small { font-size: #{$--font-size-base - 2px}; } hr { margin-top: 20px; margin-bottom: 20px; border: 0; border-top: 1px solid #eeeeee; } ================================================ FILE: packages/theme-chalk/src/result.scss ================================================ @import 'mixins/mixins'; @import 'common/var'; @include b(result) { display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; box-sizing: border-box; padding: $--result-padding; @include e(icon) { svg { width: $--result-icon-font-size; height: $--result-icon-font-size; } } @include e(title) { margin-top: $--result-title-margin-top; p { margin: 0; font-size: $--result-title-font-size; color: $--color-text-primary; line-height: 1.3; } } @include e(subtitle) { margin-top: $--result-subtitle-margin-top; p { margin: 0; font-size: $--font-size-base; color: $--color-text-regular; line-height: 1.3; } } @include e(extra) { margin-top: $--result-extra-margin-top; } .icon-success { fill: $--result-success-color; } .icon-error { fill: $--result-danger-color; } .icon-info { fill: $--result-info-color; } .icon-warning { fill: $--result-warning-color; } } ================================================ FILE: packages/theme-chalk/src/row.scss ================================================ @import "common/var"; @import "mixins/mixins"; @import "mixins/utils"; @include b(row) { position: relative; box-sizing: border-box; @include utils-clearfix; @include m(flex) { display: flex; &:before, &:after { display: none; } @include when(justify-center) { justify-content: center; } @include when(justify-end) { justify-content: flex-end; } @include when(justify-space-between) { justify-content: space-between; } @include when(justify-space-around) { justify-content: space-around; } @include when(align-top) { align-items: flex-start; } @include when(align-middle) { align-items: center; } @include when(align-bottom) { align-items: flex-end; } } } ================================================ FILE: packages/theme-chalk/src/scrollbar.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(scrollbar) { overflow: hidden; position: relative; &:hover, &:active, &:focus { > .el-scrollbar__bar { opacity: 1; transition: opacity 340ms ease-out; } } @include e(wrap) { overflow: scroll; height: 100%; @include m(hidden-default) { scrollbar-width: none; &::-webkit-scrollbar { width: 0; height: 0; } } } @include e(thumb) { position: relative; display: block; width: 0; height: 0; cursor: pointer; border-radius: inherit; background-color: $--scrollbar-background-color; transition: .3s background-color; &:hover { background-color: $--scrollbar-hover-background-color; } } @include e(bar) { position: absolute; right: 2px; bottom: 2px; z-index: 1; border-radius: 4px; opacity: 0; transition: opacity 120ms ease-out; @include when(vertical) { width: 6px; top: 2px; > div { width: 100%; } } @include when(horizontal) { height: 6px; left: 2px; > div { height: 100%; } } } } ================================================ FILE: packages/theme-chalk/src/select-dropdown.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "./popper"; @include b(select-dropdown) { position: absolute; z-index: #{$--index-top + 1}; border: $--select-dropdown-border; border-radius: $--border-radius-base; background-color: $--select-dropdown-background; box-shadow: $--select-dropdown-shadow; box-sizing: border-box; margin: 5px 0; @include when(multiple) { & .el-select-dropdown__item { padding-right: 40px; } & .el-select-dropdown__item.selected { color: $--select-option-selected-font-color; background-color: $--select-dropdown-background; &.hover { background-color: $--select-option-hover-background; } &::after { position: absolute; right: 20px; font-family: 'element-icons'; content: "\e6da"; font-size: 12px; font-weight: bold; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } } } .el-scrollbar.is-empty .el-select-dropdown__list{ padding: 0; } } @include b(select-dropdown__empty) { padding: $--select-dropdown-empty-padding; margin: 0; text-align: center; color: $--select-dropdown-empty-color; font-size: $--select-font-size; } @include b(select-dropdown__wrap) { max-height: $--select-dropdown-max-height; } @include b(select-dropdown__list) { list-style: none; padding: $--select-dropdown-padding; margin: 0; box-sizing: border-box; } ================================================ FILE: packages/theme-chalk/src/select.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @import "select-dropdown"; @import "input"; @import "tag"; @import "option"; @import "option-group"; @import "scrollbar"; @include b(select) { display: inline-block; position: relative; .el-select__tags >span { display: contents; } &:hover { .el-input__inner { border-color: $--select-border-color-hover; } } .el-input__inner { cursor: pointer; padding-right: 35px; &:focus { border-color: $--select-input-focus-border-color; } } .el-input { & .el-select__caret { color: $--select-input-color; font-size: $--select-input-font-size; transition: transform .3s; transform: rotateZ(180deg); cursor: pointer; @include when(reverse) { transform: rotateZ(0deg); } @include when(show-close) { font-size: $--select-font-size; text-align: center; transform: rotateZ(180deg); border-radius: $--border-radius-circle; color: $--select-input-color; transition: $--color-transition-base; &:hover { color: $--select-close-hover-color; } } } &.is-disabled { & .el-input__inner { cursor: not-allowed; &:hover { border-color: $--select-disabled-border; } } } &.is-focus .el-input__inner { border-color: $--select-input-focus-border-color; } } > .el-input { display: block; } @include e(input) { border: none; outline: none; padding: 0; margin-left: 15px; color: $--select-multiple-input-color; font-size: $--select-font-size; appearance: none; height: 28px; background-color: transparent; @include when(mini) { height: 14px; } } @include e(close) { cursor: pointer; position: absolute; top: 8px; z-index: $--index-top; right: 25px; color: $--select-input-color; line-height: 18px; font-size: $--select-input-font-size; &:hover { color: $--select-close-hover-color; } } @include e(tags) { position: absolute; line-height: normal; white-space: normal; z-index: $--index-normal; top: 50%; transform: translateY(-50%); display: flex; align-items: center; flex-wrap: wrap; } @include e(tags-text) { overflow: hidden; text-overflow: ellipsis; } .el-tag { box-sizing: border-box; border-color: transparent; margin: 2px 0 2px 6px; background-color: #f0f2f5; display: flex; max-width: 100%; align-items: center; &__close.el-icon-close { background-color: $--color-text-placeholder; top: 0; color: $--color-white; flex-shrink: 0; &:hover { background-color: $--color-text-secondary; } &::before { display: block; transform: translate(0, .5px); } } } } ================================================ FILE: packages/theme-chalk/src/skeleton-item.scss ================================================ @import 'mixins/mixins'; @import 'common/var'; @mixin circle-size($size) { width: $size; height: $size; line-height: $size; } @include b(skeleton) { @include e(item) { background: $--skeleton-color; display: inline-block; height: 16px; border-radius: $--border-radius-base; width: 100%; } @include e(circle) { border-radius: 50%; @include circle-size($--avatar-medium-size); @include m(lg) { @include circle-size($--avatar-large-size); } @include m(md) { @include circle-size($--avatar-small-size); } } @include e(button) { height: 40px; width: 64px; border-radius: 4px; } @include e(p) { width: 100%; @include when(last) { width: 61%; } @include when(first) { width: 33%; } } @include e(text) { width: 100%; height: $--font-size-small; } @include e(caption) { height: $--font-size-extra-small; } @include e(h1) { height: $--font-size-extra-large; } @include e(h3) { height: $--font-size-large; } @include e(h5) { height: $--font-size-medium; } @include e(image) { width: unset; display: flex; align-items: center; justify-content: center; border-radius: 0; svg { fill: $--svg-monochrome-grey; width: 22%; height: 22%; } } } ================================================ FILE: packages/theme-chalk/src/skeleton.scss ================================================ @import 'mixins/mixins'; @import 'common/var'; @import "./skeleton-item.scss"; @mixin skeleton-color() { background: linear-gradient( 90deg, $--skeleton-color 25%, $--skeleton-to-color 37%, $--skeleton-color 63% ); background-size: 400% 100%; animation: #{$namespace}-skeleton-loading 1.4s ease infinite; } @keyframes #{$namespace}-skeleton-loading { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } } @include b(skeleton) { width: 100%; @each $unit in (first-line, paragraph) { @include e($unit) { height: 16px; margin-top: 16px; background: $--skeleton-color; } } @include when(animated) { .#{$namespace}-skeleton__item { @include skeleton-color(); } } } ================================================ FILE: packages/theme-chalk/src/slider.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "input-number"; @import "tooltip"; @import "common/var"; @include b(slider) { @include utils-clearfix; @include e(runway) { width: 100%; height: $--slider-height; margin: $--slider-margin; background-color: $--slider-runway-background-color; border-radius: $--slider-border-radius; position: relative; cursor: pointer; vertical-align: middle; &.show-input { margin-right: 160px; width: auto; } &.disabled { cursor: default; .el-slider__bar { background-color: $--slider-disable-color; } .el-slider__button { border-color: $--slider-disable-color; } .el-slider__button-wrapper { &:hover, &.hover { cursor: not-allowed; } &.dragging { cursor: not-allowed; } } .el-slider__button { &:hover, &.hover, &.dragging { transform: scale(1); } &:hover, &.hover { cursor: not-allowed; } &.dragging { cursor: not-allowed; } } } } @include e(input) { float: right; margin-top: 3px; width: 130px; &.el-input-number--mini { margin-top: 5px; } &.el-input-number--medium { margin-top: 0; } &.el-input-number--large { margin-top: -2px; } } @include e(bar) { height: $--slider-height; background-color: $--slider-main-background-color; border-top-left-radius: $--slider-border-radius; border-bottom-left-radius: $--slider-border-radius; position: absolute; } @include e(button-wrapper) { height: $--slider-button-wrapper-size; width: $--slider-button-wrapper-size; position: absolute; z-index: 1001; top: $--slider-button-wrapper-offset; transform: translateX(-50%); background-color: transparent; text-align: center; user-select: none; line-height: normal; @include utils-vertical-center; .el-tooltip { vertical-align: middle; display: inline-block; } &:hover, &.hover { cursor: grab; } &.dragging { cursor: grabbing; } } @include e(button) { width: $--slider-button-size; height: $--slider-button-size; border: solid 2px $--slider-main-background-color; background-color: $--color-white; border-radius: 50%; transition: .2s; user-select: none; &:hover, &.hover, &.dragging { transform: scale(1.2); } &:hover, &.hover { cursor: grab; } &.dragging { cursor: grabbing; } } @include e(stop) { position: absolute; height: $--slider-height; width: $--slider-height; border-radius: $--border-radius-circle; background-color: $--slider-stop-background-color; transform: translateX(-50%); } @include e(marks) { top: 0; left: 12px; width: 18px; height: 100%; @include e(marks-text) { position: absolute; transform: translateX(-50%); font-size: 14px; color: $--color-info; margin-top: 15px; } } @include when(vertical) { position: relative; .el-slider__runway { width: $--slider-height; height: 100%; margin: 0 16px; } .el-slider__bar { width: $--slider-height; height: auto; border-radius: 0 0 3px 3px; } .el-slider__button-wrapper { top: auto; left: $--slider-button-wrapper-offset; transform: translateY(50%); } .el-slider__stop { transform: translateY(50%); } &.el-slider--with-input { padding-bottom: #{$--input-medium-height + 22px}; .el-slider__input { overflow: visible; float: none; position: absolute; bottom: 22px; width: 36px; margin-top: 15px; .el-input__inner { text-align: center; padding-left: 5px; padding-right: 5px; } .el-input-number__decrease, .el-input-number__increase { top: $--input-small-height; margin-top: -1px; border: $--input-border; line-height: 20px; box-sizing: border-box; transition: $--border-transition-base; } .el-input-number__decrease { width: 18px; right: 18px; border-bottom-left-radius: $--input-border-radius; } .el-input-number__increase { width: 19px; border-bottom-right-radius: $--input-border-radius; & ~ .el-input .el-input__inner { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } } &:hover { .el-input-number__decrease, .el-input-number__increase { border-color: $--input-hover-border; } } &:active { .el-input-number__decrease, .el-input-number__increase { border-color: $--input-focus-border; } } } } @include e(marks-text) { margin-top: 0; left: 15px; transform: translateY(50%); } } } ================================================ FILE: packages/theme-chalk/src/spinner.scss ================================================ @import "mixins/mixins"; @include b(time-spinner) { width: 100%; white-space: nowrap; } @include b(spinner) { display: inline-block; vertical-align: middle; } @include b(spinner-inner) { animation: rotate 2s linear infinite; width: 50px; height: 50px; & .path { stroke: #ececec; stroke-linecap: round; animation: dash 1.5s ease-in-out infinite; } } @keyframes rotate { 100% { transform: rotate(360deg); } } @keyframes dash { 0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; } } ================================================ FILE: packages/theme-chalk/src/statistic.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(statistic) { $statistic-justify: center; $statistic-align: center; width: 100%; box-sizing: border-box; margin: 0; padding: 0; color: $--color-black; font-variant: tabular-nums; list-style: none; font-feature-settings: "tnum"; text-align: center; .head { margin-bottom: 4px; color: $--color-text-regular; font-size: $--font-size-small; } .con { font-family: Sans-serif; display: flex; justify-content: $statistic-justify; align-items: $statistic-align; color: $--color-text-primary; .number { font-size: $--font-size-extra-large; padding: 0 4px; } span { display: inline-block; margin: 0; line-height: 100%; } } } ================================================ FILE: packages/theme-chalk/src/step.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(step) { position: relative; flex-shrink: 1; @include pseudo(last-of-type) { @include e(line) { display: none; } // 只有未设置 space 的情况下才自适应宽度 @include when(flex) { flex-basis: auto !important; flex-shrink: 0; flex-grow: 0; } @include e((main, description)) { padding-right: 0; } } @include e(head) { position: relative; width: 100%; @include when(process) { color: $--color-text-primary; border-color: $--color-text-primary; } @include when(wait) { color: $--color-text-placeholder; border-color: $--color-text-placeholder; } @include when(success) { color: $--color-success; border-color: $--color-success; } @include when(error) { color: $--color-danger; border-color: $--color-danger; } @include when(finish) { color: $--color-primary; border-color: $--color-primary; } } @include e(icon) { position: relative; z-index: 1; display: inline-flex; justify-content: center; align-items: center; width: 24px; height: 24px; font-size: 14px; box-sizing: border-box; background: $--color-white; transition: .15s ease-out; @include when(text) { border-radius: 50%; border: 2px solid; border-color: inherit; } @include when(icon) { width: 40px; } } @include e(icon-inner) { display: inline-block; user-select: none; text-align: center; font-weight: bold; line-height: 1; color: inherit; &[class*=el-icon]:not(.is-status) { font-size: 25px; font-weight: normal; } // 组件自身表示状态的图标 @include when(status) { transform: translateY(1px); } } @include e(line) { position: absolute; border-color: inherit; background-color: $--color-text-placeholder; } @include e(line-inner) { display: block; border-width: 1px; border-style: solid; border-color: inherit; transition: .15s ease-out; box-sizing: border-box; width: 0; height: 0; } @include e(main) { white-space: normal; text-align: left; } @include e(title) { font-size: 16px; line-height: 38px; @include when(process) { font-weight: bold; color: $--color-text-primary; } @include when(wait) { color: $--color-text-placeholder; } @include when(success) { color: $--color-success; } @include when(error) { color: $--color-danger; } @include when(finish) { color: $--color-primary; } } @include e(description) { padding-right: 10%; margin-top: -5px; font-size: 12px; line-height: 20px; font-weight: normal; @include when(process) { color: $--color-text-primary; } @include when(wait) { color: $--color-text-placeholder; } @include when(success) { color: $--color-success; } @include when(error) { color: $--color-danger; } @include when(finish) { color: $--color-primary; } } @include when(horizontal) { display: inline-block; @include e(line) { height: 2px; top: 11px; left: 0; right: 0; } } @include when(vertical) { display: flex; @include e(head) { flex-grow: 0; width: 24px; } @include e(main) { padding-left: 10px; flex-grow: 1; } @include e(title) { line-height: 24px; padding-bottom: 8px; } @include e(line) { width: 2px; top: 0; bottom: 0; left: 11px; } @include e(icon) { @include when(icon) { width: 24px; } } } @include when(center) { @include e(head) { text-align: center; } @include e(main) { text-align: center; } @include e(description) { padding-left: 20%; padding-right: 20%; } @include e(line) { left: 50%; right: -50%; } } @include when(simple) { display: flex; align-items: center; @include e(head) { width: auto; font-size: 0; padding-right: 10px; } @include e(icon) { background: transparent; width: 16px; height: 16px; font-size: 12px; } @include e(icon-inner) { &[class*=el-icon]:not(.is-status) { font-size: 18px; } &.is-status { transform: scale(.8) translateY(1px); } } @include e(main) { position: relative; display: flex; align-items: stretch; flex-grow: 1; } @include e(title) { font-size: 16px; line-height: 20px; } @include pseudo('not(:last-of-type)') { @include e(title) { max-width: 50%; word-break: break-all; } } @include e(arrow) { flex-grow: 1; display: flex; align-items: center; justify-content: center; &::before, &::after { content: ''; display: inline-block; position: absolute; height: 15px; width: 1px; background: $--color-text-placeholder; } &::before { transform: rotate(-45deg) translateY(-4px); transform-origin: 0 0; } &::after { transform: rotate(45deg) translateY(4px); transform-origin: 100% 100%; } } @include pseudo(last-of-type) { @include e(arrow) { display: none; } } } } ================================================ FILE: packages/theme-chalk/src/steps.scss ================================================ @import "mixins/mixins"; @include b(steps) { display: flex; @include m(simple) { padding: 13px 8%; border-radius: 4px; background: $--background-color-base; } @include m(horizontal) { white-space: nowrap; } @include m(vertical) { height: 100%; flex-flow: column; } } ================================================ FILE: packages/theme-chalk/src/submenu.scss ================================================ ================================================ FILE: packages/theme-chalk/src/switch.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(switch) { display: inline-flex; align-items: center; position: relative; font-size: $--switch-font-size; line-height: $--switch-height; height: $--switch-height; vertical-align: middle; @include when(disabled) { & .el-switch__core, & .el-switch__label { cursor: not-allowed; } } @include e(label) { transition: .2s; height: $--switch-height; display: inline-block; font-size: $--switch-font-size; font-weight: 500; cursor: pointer; vertical-align: middle; color: $--color-text-primary; @include when(active) { color: $--color-primary; } @include m(left) { margin-right: 10px; } @include m(right) { margin-left: 10px; } & * { line-height: 1; font-size: $--switch-font-size; display: inline-block; } } @include e(input) { position: absolute; width: 0; height: 0; opacity: 0; margin: 0; } @include e(core) { margin: 0; display: inline-block; position: relative; width: $--switch-width; height: $--switch-height; border: 1px solid $--switch-off-color; outline: none; border-radius: $--switch-core-border-radius; box-sizing: border-box; background: $--switch-off-color; cursor: pointer; transition: border-color .3s, background-color .3s; vertical-align: middle; &:after { content: ""; position: absolute; top: 1px; left: 1px; border-radius: $--border-radius-circle; transition: all .3s; width: $--switch-button-size; height: $--switch-button-size; background-color: $--color-white; } } @include when(checked) { .el-switch__core { border-color: $--switch-on-color; background-color: $--switch-on-color; &::after { left: 100%; margin-left: -$--switch-button-size - 1px; } } } @include when(disabled) { opacity: 0.6; } @include m(wide) { .el-switch__label { &.el-switch__label--left { span { left: 10px; } } &.el-switch__label--right { span { right: 10px; } } } } & .label-fade-enter, & .label-fade-leave-active { opacity: 0; } } ================================================ FILE: packages/theme-chalk/src/tab-pane.scss ================================================ ================================================ FILE: packages/theme-chalk/src/table-column.scss ================================================ @import "mixins/mixins"; @import "checkbox"; @import "tag"; @import "common/var"; @include b(table-column) { @include m(selection) { .cell { padding-left: 14px; padding-right: 14px; } } } @include b(table-filter) { border: solid 1px $--border-color-lighter; border-radius: 2px; background-color: $--color-white; box-shadow: $--dropdown-menu-box-shadow; box-sizing: border-box; margin: 2px 0; /** used for dropdown mode */ @include e(list) { padding: 5px 0; margin: 0; list-style: none; min-width: 100px; } @include e(list-item) { line-height: 36px; padding: 0 10px; cursor: pointer; font-size: $--font-size-base; &:hover { background-color: $--dropdown-menuItem-hover-fill; color: $--dropdown-menuItem-hover-color; } @include when(active) { background-color: $--color-primary; color: $--color-white; } } @include e(content) { min-width: 100px; } @include e(bottom) { border-top: 1px solid $--border-color-lighter; padding: 8px; button { background: transparent; border: none; color: $--color-text-regular; cursor: pointer; font-size: $--font-size-small; padding: 0 3px; &:hover { color: $--color-primary; } &:focus { outline: none; } &.is-disabled { color: $--disabled-color-base; cursor: not-allowed; } } } @include e(wrap) { max-height: 280px; } @include e(checkbox-group) { padding: 10px; label.el-checkbox { display: block; margin-right: 5px; margin-bottom: 8px; margin-left: 5px; } .el-checkbox:last-child { margin-bottom: 0; } } } ================================================ FILE: packages/theme-chalk/src/table.scss ================================================ @import "mixins/mixins"; @import "checkbox"; @import "tag"; @import "tooltip"; @import "common/var"; @include b(table) { position: relative; overflow: hidden; box-sizing: border-box; flex: 1; width: 100%; max-width: 100%; background-color: $--color-white; font-size: 14px; color: $--table-font-color; // 数据为空 @include e(empty-block) { min-height: 60px; text-align: center; width: 100%; display: flex; justify-content: center; align-items: center; } @include e(empty-text) { // min-height doesn't work in IE10 and IE11 https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items // set empty text line height up to contrainer min-height as workaround. line-height: 60px; width: 50%; color: $--color-text-secondary; } // 展开行 @include e(expand-column) { .cell { padding: 0; text-align: center; } } @include e(expand-icon) { position: relative; cursor: pointer; color: #666; font-size: 12px; transition: transform 0.2s ease-in-out; height: 20px; @include m(expanded) { transform: rotate(90deg); } > .el-icon { position: absolute; left: 50%; top: 50%; margin-left: -5px; margin-top: -5px; } } @include e(expanded-cell) { background-color: $--color-white; // 纯属为了增加权重 &[class*=cell] { padding: 20px 50px; } &:hover { background-color: transparent !important; } } @include e(placeholder) { display: inline-block; width: 20px; } @include e(append-wrapper) { // 避免外边距重合 https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing overflow: hidden; } @include m(fit) { border-right: 0; border-bottom: 0; .el-table__cell.gutter { border-right-width: 1px; } } @include m(scrollable-x) { .el-table__body-wrapper { overflow-x: auto; } } @include m(scrollable-y) { .el-table__body-wrapper { overflow-y: auto; } } thead { color: $--table-header-font-color; font-weight: 500; &.is-group { th.el-table__cell { background: $--background-color-base; } } } .el-table__cell { padding: 12px 0; min-width: 0; box-sizing: border-box; text-overflow: ellipsis; vertical-align: middle; position: relative; text-align: left; @include when(center) { text-align: center; } @include when(right) { text-align: right; } &.gutter { width: 15px; border-right-width: 0; border-bottom-width: 0; padding: 0; } &.is-hidden { > * { visibility: hidden; } } } @include m(medium) { .el-table__cell { padding: 10px 0; } } @include m(small) { font-size: 12px; .el-table__cell { padding: 8px 0; } } @include m(mini) { font-size: 12px; .el-table__cell { padding: 6px 0; } } tr { background-color: $--color-white; input[type="checkbox"] { margin: 0; } } th.el-table__cell.is-leaf, td.el-table__cell { border-bottom: $--table-border; } th.el-table__cell.is-sortable { cursor: pointer; } th.el-table__cell { overflow: hidden; user-select: none; background-color: $--table-header-background-color; > .cell { display: inline-block; box-sizing: border-box; position: relative; vertical-align: middle; padding-left: 10px; padding-right: 10px; width: 100%; &.highlight { color: $--color-primary; } } &.required > div::before { display: inline-block; content: ""; width: 8px; height: 8px; border-radius: 50%; background: #ff4d51; margin-right: 5px; vertical-align: middle; } } td.el-table__cell { div { box-sizing: border-box; } &.gutter { width: 0; } } .cell { box-sizing: border-box; overflow: hidden; text-overflow: ellipsis; white-space: normal; word-break: break-all; line-height: 23px; padding-left: 10px; padding-right: 10px; &.el-tooltip { white-space: nowrap; min-width: 50px; } } // 拥有多级表头 @include m((group, border)) { border: $--table-border; @include share-rule(border-pseudo) { content: ''; position: absolute; background-color: $--table-border-color; z-index: 1; } // 表格右部伪 border &::after { @include extend-rule(border-pseudo); top: 0; right: 0; width: 1px; height: 100%; } } // 表格底部伪 border,总是有的 &::before { @include extend-rule(border-pseudo); left: 0; bottom: 0; width: 100%; height: 1px; } // table--border @include m(border) { border-right: none; border-bottom: none; &.el-loading-parent--relative { border-color: transparent; } .el-table__cell { border-right: $--table-border; &:first-child .cell { padding-left: 10px; } } th.el-table__cell.gutter:last-of-type { border-bottom: $--table-border; border-bottom-width: 1px; } & th.el-table__cell { border-bottom: $--table-border; } } @include m(hidden) { visibility: hidden; } @include e((fixed, fixed-right)) { position: absolute; top: 0; left: 0; overflow-x: hidden; overflow-y: hidden; box-shadow: $--table-fixed-box-shadow; &::before { content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background-color: $--border-color-lighter; z-index: 4; } } @include e(fixed-right-patch) { position: absolute; top: -1px; right: 0; background-color: $--color-white; border-bottom: $--table-border; } @include e(fixed-right) { top: 0; left: auto; right: 0; .el-table__fixed-header-wrapper, .el-table__fixed-body-wrapper, .el-table__fixed-footer-wrapper { left: auto; right: 0; } } @include e(fixed-header-wrapper) { position: absolute; left: 0; top: 0; z-index: 3; } @include e(fixed-footer-wrapper) { position: absolute; left: 0; bottom: 0; z-index: 3; & tbody td.el-table__cell { border-top: $--table-border; background-color: $--table-row-hover-background-color; color: $--table-font-color; } } @include e(fixed-body-wrapper) { position: absolute; left: 0; top: 37px; overflow: hidden; z-index: 3; } @include e((header-wrapper, body-wrapper, footer-wrapper)) { width: 100%; } @include e(footer-wrapper) { margin-top: -1px; td.el-table__cell { border-top: $--table-border; } } @include e((header, body, footer)) { table-layout: fixed; border-collapse: separate; } @include e((header-wrapper, footer-wrapper)) { overflow: hidden; & tbody td.el-table__cell { background-color: $--table-row-hover-background-color; color: $--table-font-color; } } @include e(body-wrapper) { overflow: hidden; position: relative; @include when(scrolling-none) { ~ .el-table__fixed, ~ .el-table__fixed-right { box-shadow: none; } } @include when(scrolling-left) { ~ .el-table__fixed { box-shadow: none; } } @include when(scrolling-right) { ~ .el-table__fixed-right { box-shadow: none; } } .el-table--border { @include when(scrolling-right) { ~ .el-table__fixed-right { border-left: $--table-border; } } @include when(scrolling-left) { ~ .el-table__fixed { border-right: $--table-border; } } } } .caret-wrapper { display: inline-flex; flex-direction: column; align-items: center; height: 34px; width: 24px; vertical-align: middle; cursor: pointer; overflow: initial; position: relative; } .sort-caret { width: 0; height: 0; border: solid 5px transparent; position: absolute; left: 7px; &.ascending { border-bottom-color: $--color-text-placeholder; top: 5px; } &.descending { border-top-color: $--color-text-placeholder; bottom: 7px; } } .ascending .sort-caret.ascending { border-bottom-color: $--color-primary; } .descending .sort-caret.descending { border-top-color: $--color-primary; } .hidden-columns { visibility: hidden; position: absolute; z-index: -1; } @include m(striped) { & .el-table__body { & tr.el-table__row--striped { td.el-table__cell { background: #FAFAFA; } &.current-row td.el-table__cell, &.selection-row td.el-table__cell { background-color: $--table-current-row-background-color; } } } } @include e(body) { tr.hover-row { &, &.el-table__row--striped { &, &.current-row, &.selection-row { > td.el-table__cell { background-color: $--table-row-hover-background-color; } } } } tr.current-row > td.el-table__cell, tr.selection-row > td.el-table__cell { background-color: $--table-current-row-background-color; } } @include e(column-resize-proxy) { position: absolute; left: 200px; top: 0; bottom: 0; width: 0; border-left: $--table-border; z-index: 10; } @include e(column-filter-trigger) { display: inline-block; line-height: 34px; cursor: pointer; & i { color: $--color-info; font-size: 12px; transform: scale(.75); } } @include m(enable-row-transition) { .el-table__body td.el-table__cell { transition: background-color .25s ease; } } @include m(enable-row-hover) { .el-table__body tr:hover > td.el-table__cell { background-color: $--table-row-hover-background-color; } } @include m(fluid-height) { .el-table__fixed, .el-table__fixed-right { bottom: 0; overflow: hidden; } } [class*=el-table__row--level] { .el-table__expand-icon { display: inline-block; width: 20px; line-height: 20px; height: 20px; text-align: center; margin-right: 3px; } } } ================================================ FILE: packages/theme-chalk/src/tabs.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(tabs) { @include e(header) { padding: 0; position: relative; margin: 0 0 15px; } @include e(active-bar) { position: absolute; bottom: 0; left: 0; height: 2px; background-color: $--color-primary; z-index: 1; transition: transform .3s cubic-bezier(.645,.045,.355,1); list-style: none; } @include e(new-tab) { float: right; border: 1px solid #d3dce6; height: 18px; width: 18px; line-height: 18px; margin: 12px 0 9px 10px; border-radius: 3px; text-align: center; font-size: 12px; color: #d3dce6; cursor: pointer; transition: all .15s; .el-icon-plus { transform: scale(0.8, 0.8); } &:hover { color: $--color-primary; } } @include e(nav-wrap) { overflow: hidden; margin-bottom: -1px; position: relative; &::after { content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 2px; background-color: $--border-color-light; z-index: $--index-normal; } @include when(scrollable) { padding: 0 20px; box-sizing: border-box; } } @include e(nav-scroll) { overflow: hidden; } @include e((nav-next, nav-prev)) { position: absolute; cursor: pointer; line-height: 44px; font-size: 12px; color: $--color-text-secondary; } @include e(nav-next) { right: 0; } @include e(nav-prev) { left: 0; } @include e(nav) { white-space: nowrap; position: relative; transition: transform .3s; float: left; z-index: #{$--index-normal + 1}; @include when(stretch) { min-width: 100%; display: flex; & > * { flex: 1; text-align: center; } } } @include e(item) { padding: 0 20px; height: 40px; box-sizing: border-box; line-height: 40px; display: inline-block; list-style: none; font-size: 14px; font-weight: 500; color: $--color-text-primary; position: relative; &:focus, &:focus:active { outline: none; } &:focus.is-active.is-focus:not(:active) { box-shadow: 0 0 2px 2px $--color-primary inset; border-radius: 3px; } & .el-icon-close { border-radius: 50%; text-align: center; transition: all .3s cubic-bezier(.645,.045,.355,1); margin-left: 5px; &:before { transform: scale(.9); display: inline-block; } &:hover { background-color: $--color-text-placeholder; color: $--color-white; } } @include when(active) { color: $--color-primary; } &:hover { color: $--color-primary; cursor: pointer; } @include when(disabled) { color: $--disabled-color-base; cursor: default; } } @include e(content) { overflow: hidden; position: relative; } @include m(card) { > .el-tabs__header { border-bottom: 1px solid $--border-color-light; } > .el-tabs__header .el-tabs__nav-wrap::after { content: none; } > .el-tabs__header .el-tabs__nav { border: 1px solid $--border-color-light; border-bottom: none; border-radius: 4px 4px 0 0; box-sizing: border-box; } > .el-tabs__header .el-tabs__active-bar { display: none; } > .el-tabs__header .el-tabs__item .el-icon-close { position: relative; font-size: 12px; width: 0; height: 14px; vertical-align: middle; line-height: 15px; overflow: hidden; top: -1px; right: -2px; transform-origin: 100% 50%; } > .el-tabs__header .el-tabs__item { border-bottom: 1px solid transparent; border-left: 1px solid $--border-color-light; transition: color .3s cubic-bezier(.645,.045,.355,1), padding .3s cubic-bezier(.645,.045,.355,1); &:first-child { border-left: none; } &.is-closable { &:hover { padding-left: 13px; padding-right: 13px; & .el-icon-close { width: 14px; } } } &.is-active { border-bottom-color: $--color-white; &.is-closable { padding-left: 20px; padding-right: 20px; .el-icon-close { width: 14px; } } } } } @include m(border-card) { background: $--color-white; border: 1px solid $--border-color-base; box-shadow: 0 2px 4px 0 rgba(0,0,0,0.12), 0 0 6px 0 rgba(0,0,0,0.04); > .el-tabs__content { padding: 15px; } > .el-tabs__header { background-color: $--background-color-base; border-bottom: 1px solid $--border-color-light; margin: 0; } > .el-tabs__header .el-tabs__nav-wrap::after { content: none; } > .el-tabs__header .el-tabs__item { transition: all .3s cubic-bezier(.645,.045,.355,1); border: 1px solid transparent; margin-top: -1px; color: $--color-text-secondary; &:first-child { margin-left: -1px; } & + .el-tabs__item { margin-left: -1px; } &.is-active { color: $--color-primary; background-color: $--color-white; border-right-color: $--border-color-base; border-left-color: $--border-color-base; } &:not(.is-disabled):hover { color: $--color-primary; } &.is-disabled { color: $--disabled-color-base; } } > .el-tabs__header .is-scrollable .el-tabs__item:first-child { margin-left: 0; } } @include m((top, bottom)) { .el-tabs__item.is-top:nth-child(2), .el-tabs__item.is-bottom:nth-child(2) { padding-left: 0; } .el-tabs__item.is-top:last-child, .el-tabs__item.is-bottom:last-child { padding-right: 0; } &.el-tabs--border-card, &.el-tabs--card, .el-tabs--left, .el-tabs--right { > .el-tabs__header { .el-tabs__item:nth-child(2) { padding-left: 20px; } .el-tabs__item:last-child { padding-right: 20px; } } } } @include m(bottom) { .el-tabs__header.is-bottom { margin-bottom: 0; margin-top: 10px; } &.el-tabs--border-card { .el-tabs__header.is-bottom { border-bottom: 0; border-top: 1px solid $--border-color-base; } .el-tabs__nav-wrap.is-bottom { margin-top: -1px; margin-bottom: 0; } .el-tabs__item.is-bottom:not(.is-active) { border: 1px solid transparent; } .el-tabs__item.is-bottom { margin: 0 -1px -1px -1px; } } } @include m((left, right)) { overflow: hidden; .el-tabs__header.is-left, .el-tabs__header.is-right, .el-tabs__nav-wrap.is-left, .el-tabs__nav-wrap.is-right, .el-tabs__nav-scroll { height: 100%; } .el-tabs__active-bar.is-left, .el-tabs__active-bar.is-right { top: 0; bottom: auto; width: 2px; height: auto; } .el-tabs__nav-wrap.is-left, .el-tabs__nav-wrap.is-right { margin-bottom: 0; > .el-tabs__nav-prev, > .el-tabs__nav-next { height: 30px; line-height: 30px; width: 100%; text-align: center; cursor: pointer; i { transform: rotateZ(90deg); } } > .el-tabs__nav-prev { left: auto; top: 0; } > .el-tabs__nav-next { right: auto; bottom: 0; } &.is-scrollable { padding: 30px 0; } &::after { height: 100%; width: 2px; bottom: auto; top: 0; } } .el-tabs__nav.is-left, .el-tabs__nav.is-right { float: none; } .el-tabs__item.is-left, .el-tabs__item.is-right { display: block; } } @include m(left) { .el-tabs__header.is-left { float: left; margin-bottom: 0; margin-right: 10px; } .el-tabs__nav-wrap.is-left { margin-right: -1px; &::after { left: auto; right: 0; } } .el-tabs__active-bar.is-left { right: 0; left: auto; } .el-tabs__item.is-left { text-align: right; } &.el-tabs--card { .el-tabs__active-bar.is-left { display: none; } .el-tabs__item.is-left { border-left: none; border-right: 1px solid $--border-color-light; border-bottom: none; border-top: 1px solid $--border-color-light; text-align: left; } .el-tabs__item.is-left:first-child { border-right: 1px solid $--border-color-light; border-top: none; } .el-tabs__item.is-left.is-active { border: 1px solid $--border-color-light; border-right-color: #fff; border-left: none; border-bottom: none; &:first-child { border-top: none; } &:last-child { border-bottom: none; } } .el-tabs__nav { border-radius: 4px 0 0 4px; border-bottom: 1px solid $--border-color-light; border-right: none; } .el-tabs__new-tab { float: none; } } &.el-tabs--border-card { .el-tabs__header.is-left { border-right: 1px solid #dfe4ed; } .el-tabs__item.is-left { border: 1px solid transparent; margin: -1px 0 -1px -1px; &.is-active { border-color: transparent; border-top-color: rgb(209, 219, 229); border-bottom-color: rgb(209, 219, 229); } } } } @include m(right) { .el-tabs__header.is-right { float: right; margin-bottom: 0; margin-left: 10px; } .el-tabs__nav-wrap.is-right { margin-left: -1px; &::after { left: 0; right: auto; } } .el-tabs__active-bar.is-right { left: 0; } &.el-tabs--card { .el-tabs__active-bar.is-right { display: none; } .el-tabs__item.is-right { border-bottom: none; border-top: 1px solid $--border-color-light; } .el-tabs__item.is-right:first-child { border-left: 1px solid $--border-color-light; border-top: none; } .el-tabs__item.is-right.is-active { border: 1px solid $--border-color-light; border-left-color: #fff; border-right: none; border-bottom: none; &:first-child { border-top: none; } &:last-child { border-bottom: none; } } .el-tabs__nav { border-radius: 0 4px 4px 0; border-bottom: 1px solid $--border-color-light; border-left: none; } } &.el-tabs--border-card { .el-tabs__header.is-right { border-left: 1px solid #dfe4ed; } .el-tabs__item.is-right { border: 1px solid transparent; margin: -1px -1px -1px 0; &.is-active { border-color: transparent; border-top-color: rgb(209, 219, 229); border-bottom-color: rgb(209, 219, 229); } } } } } .slideInRight-transition, .slideInLeft-transition { display: inline-block; } .slideInRight-enter { animation: slideInRight-enter .3s; } .slideInRight-leave { position: absolute; left: 0; right: 0; animation: slideInRight-leave .3s; } .slideInLeft-enter { animation: slideInLeft-enter .3s; } .slideInLeft-leave { position: absolute; left: 0; right: 0; animation: slideInLeft-leave .3s; } @keyframes slideInRight-enter { 0% { opacity: 0; -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(100%); transform: translateX(100%) } to { opacity: 1; -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(0); transform: translateX(0) } } @keyframes slideInRight-leave { 0% { -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(0); transform: translateX(0); opacity: 1 } 100% { -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(100%); transform: translateX(100%); opacity: 0 } } @keyframes slideInLeft-enter { 0% { opacity: 0; -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(-100%); transform: translateX(-100%) } to { opacity: 1; -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(0); transform: translateX(0) } } @keyframes slideInLeft-leave { 0% { -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(0); transform: translateX(0); opacity: 1 } 100% { -webkit-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: translateX(-100%); transform: translateX(-100%); opacity: 0 } } ================================================ FILE: packages/theme-chalk/src/tag.scss ================================================ @import "mixins/mixins"; @import "common/var"; @mixin genTheme($backgroundColorWeight, $borderColorWeight, $fontColorWeight, $hoverColorWeight) { background-color: mix($--tag-primary-color, $--color-white, $backgroundColorWeight); border-color: mix($--tag-primary-color, $--color-white, $borderColorWeight); color: mix($--tag-primary-color, $--color-white, $fontColorWeight); @include when(hit) { border-color: $--tag-primary-color; } .el-tag__close { color: mix($--tag-primary-color, $--color-white, $fontColorWeight); &:hover { color: $--color-white; background-color: mix($--tag-primary-color, $--color-white, $hoverColorWeight); } } &.el-tag--info { background-color: mix($--tag-info-color, $--color-white, $backgroundColorWeight); border-color: mix($--tag-info-color, $--color-white, $borderColorWeight); color: mix($--tag-info-color, $--color-white, $fontColorWeight); @include when(hit) { border-color: $--tag-info-color; } .el-tag__close { color: mix($--tag-info-color, $--color-white, $fontColorWeight); &:hover { color: $--color-white; background-color: mix($--tag-info-color, $--color-white, $hoverColorWeight); } } } &.el-tag--success { background-color: mix($--tag-success-color, $--color-white, $backgroundColorWeight); border-color: mix($--tag-success-color, $--color-white, $borderColorWeight); color: mix($--tag-success-color, $--color-white, $fontColorWeight); @include when(hit) { border-color: $--tag-success-color; } .el-tag__close { color: mix($--tag-success-color, $--color-white, $fontColorWeight); &:hover { color: $--color-white; background-color: mix($--tag-success-color, $--color-white, $hoverColorWeight); } } } &.el-tag--warning { background-color: mix($--tag-warning-color, $--color-white, $backgroundColorWeight); border-color: mix($--tag-warning-color, $--color-white, $borderColorWeight); color: mix($--tag-warning-color, $--color-white, $fontColorWeight); @include when(hit) { border-color: $--tag-warning-color; } .el-tag__close { color: mix($--tag-warning-color, $--color-white, $fontColorWeight); &:hover { color: $--color-white; background-color: mix($--tag-warning-color, $--color-white, $hoverColorWeight); } } } &.el-tag--danger { background-color: mix($--tag-danger-color, $--color-white, $backgroundColorWeight); border-color: mix($--tag-danger-color, $--color-white, $borderColorWeight); color: mix($--tag-danger-color, $--color-white, $fontColorWeight); @include when(hit) { border-color: $--tag-danger-color; } .el-tag__close { color: mix($--tag-danger-color, $--color-white, $fontColorWeight); &:hover { color: $--color-white; background-color: mix($--tag-danger-color, $--color-white, $hoverColorWeight); } } } } @include b(tag) { @include genTheme(10%, 20%, 100%, 100%); display: inline-block; height: 32px; padding: $--tag-padding; line-height: 30px; font-size: $--tag-font-size; color: $--tag-primary-color; border-width: 1px; border-style: solid; border-radius: $--tag-border-radius; box-sizing: border-box; white-space: nowrap; .el-icon-close { border-radius: 50%; text-align: center; position: relative; cursor: pointer; font-size: 12px; height: 16px; width: 16px; line-height: 16px; vertical-align: middle; top: -1px; right: -5px; &::before { display: block; } } @include m(dark) { @include genTheme(100%, 100%, 0, 80%); } @include m(plain) { @include genTheme(0, 40%, 100%, 100%); } @include m(medium) { height: 28px; line-height: 26px; .el-icon-close { transform: scale(.8); } } @include m(small) { height: 24px; padding: 0 8px; line-height: 22px; .el-icon-close { transform: scale(.8); } } @include m(mini) { height: 20px; padding: 0 5px; line-height: 19px; .el-icon-close { margin-left: -3px; transform: scale(.7); } } } ================================================ FILE: packages/theme-chalk/src/time-picker.scss ================================================ @import "./date-picker/picker.scss"; @import "./date-picker/picker-panel.scss"; @import "./date-picker/time-spinner.scss"; @import "./date-picker/time-picker.scss"; @import "./date-picker/time-range-picker.scss"; @import "./input.scss"; @import "./scrollbar.scss"; @import "./popper"; ================================================ FILE: packages/theme-chalk/src/time-select.scss ================================================ @import "common/var"; @import "./date-picker/picker.scss"; @import "./date-picker/date-picker.scss"; @import "./scrollbar.scss"; @import "./popper"; .time-select { margin: 5px 0; min-width: 0; } .time-select .el-picker-panel__content { max-height: 200px; margin: 0; } .time-select-item { padding: 8px 10px; font-size: 14px; line-height: 20px; } .time-select-item.selected:not(.disabled) { color: $--color-primary; font-weight: bold; } .time-select-item.disabled { color: $--datepicker-border-color; cursor: not-allowed; } .time-select-item:hover { background-color: $--background-color-base; font-weight: bold; cursor: pointer; } ================================================ FILE: packages/theme-chalk/src/timeline-item.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(timeline-item) { position: relative; padding-bottom: 20px; @include e(wrapper) { position: relative; padding-left: 28px; top: -3px; } @include e(tail) { position: absolute; left: 4px; height: 100%; border-left: 2px solid $--timeline-node-color; } @include e(icon) { color: $--color-white; font-size: $--font-size-small; } @include e(node) { position: absolute; background-color: $--timeline-node-color; border-radius: 50%; display: flex; justify-content: center; align-items: center; @include m(normal) { left: -1px; width: $--timeline-node-size-normal; height: $--timeline-node-size-normal; } @include m(large) { left: -2px; width: $--timeline-node-size-large; height: $--timeline-node-size-large; } @include m(primary) { background-color: $--color-primary; } @include m(success) { background-color: $--color-success; } @include m(warning) { background-color: $--color-warning; } @include m(danger) { background-color: $--color-danger; } @include m(info) { background-color: $--color-info; } } @include e(dot) { position: absolute; display: flex; justify-content: center; align-items: center; } @include e(content) { color: $--color-text-primary; } @include e(timestamp) { color: $--color-text-secondary; line-height: 1; font-size: $--font-size-small; @include when(top) { margin-bottom: 8px; padding-top: 4px; } @include when(bottom) { margin-top: 8px; } } } ================================================ FILE: packages/theme-chalk/src/timeline.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(timeline) { margin: 0; font-size: $--font-size-base; list-style: none; & .el-timeline-item:last-child { & .el-timeline-item__tail { display: none; } } } ================================================ FILE: packages/theme-chalk/src/tooltip.scss ================================================ @import "mixins/mixins"; @import "common/var"; @include b(tooltip) { &:focus:not(.focusing), &:focus:hover { outline-width: 0; } @include e(popper) { position: absolute; border-radius: 4px; padding: $--tooltip-padding; z-index: $--index-popper; font-size: $--tooltip-font-size; line-height: 1.2; min-width: 10px; word-wrap: break-word; .popper__arrow, .popper__arrow::after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid; } .popper__arrow { border-width: $--tooltip-arrow-size; } .popper__arrow::after { content: " "; border-width: 5px; } &[x-placement^="top"] { margin-bottom: #{$--tooltip-arrow-size + 6px}; } &[x-placement^="top"] .popper__arrow { bottom: -$--tooltip-arrow-size; border-top-color: $--tooltip-border-color; border-bottom-width: 0; &::after { bottom: 1px; margin-left: -5px; border-top-color: $--tooltip-fill; border-bottom-width: 0; } } &[x-placement^="bottom"] { margin-top: #{$--tooltip-arrow-size + 6px}; } &[x-placement^="bottom"] .popper__arrow { top: -$--tooltip-arrow-size; border-top-width: 0; border-bottom-color: $--tooltip-border-color; &::after { top: 1px; margin-left: -5px; border-top-width: 0; border-bottom-color: $--tooltip-fill; } } &[x-placement^="right"] { margin-left: #{$--tooltip-arrow-size + 6px}; } &[x-placement^="right"] .popper__arrow { left: -$--tooltip-arrow-size; border-right-color: $--tooltip-border-color; border-left-width: 0; &::after { bottom: -5px; left: 1px; border-right-color: $--tooltip-fill; border-left-width: 0; } } &[x-placement^="left"] { margin-right: #{$--tooltip-arrow-size + 6px}; } &[x-placement^="left"] .popper__arrow { right: -$--tooltip-arrow-size; border-right-width: 0; border-left-color: $--tooltip-border-color; &::after { right: 1px; bottom: -5px; margin-left: -5px; border-right-width: 0; border-left-color: $--tooltip-fill; } } @include when(dark) { background: $--tooltip-fill; color: $--tooltip-color; } @include when(light) { background: $--tooltip-color; border: 1px solid $--tooltip-fill; &[x-placement^="top"] .popper__arrow { border-top-color: $--tooltip-fill; &::after { border-top-color: $--tooltip-color; } } &[x-placement^="bottom"] .popper__arrow { border-bottom-color: $--tooltip-fill; &::after { border-bottom-color: $--tooltip-color; } } &[x-placement^="left"] .popper__arrow { border-left-color: $--tooltip-fill; &::after { border-left-color: $--tooltip-color; } } &[x-placement^="right"] .popper__arrow { border-right-color: $--tooltip-fill; &::after { border-right-color: $--tooltip-color; } } } } } ================================================ FILE: packages/theme-chalk/src/transfer.scss ================================================ @import "mixins/mixins"; @import "mixins/utils"; @import "common/var"; @import "input"; @import "button"; @import "checkbox"; @import "checkbox-group"; @include b(transfer) { font-size: $--font-size-base; @include e(buttons) { display: inline-block; vertical-align: middle; padding: 0 30px; } @include e(button) { display: block; margin: 0 auto; padding: 10px; border-radius: 50%; color: $--color-white; background-color: $--color-primary; font-size: 0; @include when(with-texts) { border-radius: $--border-radius-base; } @include when(disabled) { border: $--border-base; background-color: $--background-color-base; color: $--color-text-placeholder; &:hover { border: $--border-base; background-color: $--background-color-base; color: $--color-text-placeholder; } } &:first-child { margin-bottom: 10px; } &:nth-child(2) { margin: 0; } i, span { font-size: 14px; } & [class*="el-icon-"] + span { margin-left: 0; } } } @include b(transfer-panel) { border: 1px solid $--transfer-border-color; border-radius: $--transfer-border-radius; overflow: hidden; background: $--color-white; display: inline-block; vertical-align: middle; width: $--transfer-panel-width; max-height: 100%; box-sizing: border-box; position: relative; @include e(body) { height: $--transfer-panel-body-height; @include when(with-footer) { padding-bottom: $--transfer-panel-footer-height; } } @include e(list) { margin: 0; padding: 6px 0; list-style: none; height: $--transfer-panel-body-height; overflow: auto; box-sizing: border-box; @include when(filterable) { height: #{$--transfer-panel-body-height - $--transfer-filter-height - 20px}; padding-top: 0; } } @include e(item) { height: $--transfer-item-height; line-height: $--transfer-item-height; padding-left: 15px; display: block !important; & + .el-transfer-panel__item { margin-left: 0; } &.el-checkbox { color: $--color-text-regular; } &:hover { color: $--color-primary; } &.el-checkbox .el-checkbox__label { width: 100%; @include utils-ellipsis; display: block; box-sizing: border-box; padding-left: 24px; line-height: $--transfer-item-height; } .el-checkbox__input { position: absolute; top: 8px; } } @include e(filter) { text-align: center; margin: 15px; box-sizing: border-box; display: block; width: auto; .el-input__inner { height: $--transfer-filter-height; width: 100%; font-size: 12px; display: inline-block; box-sizing: border-box; border-radius: #{$--transfer-filter-height / 2}; padding-right: 10px; padding-left: 30px; } .el-input__icon { margin-left: 5px; } .el-icon-circle-close { cursor: pointer; } } .el-transfer-panel__header { height: $--transfer-panel-header-height; line-height: $--transfer-panel-header-height; background: $--transfer-panel-header-background-color; margin: 0; padding-left: 15px; border-bottom: 1px solid $--transfer-border-color; box-sizing: border-box; color: $--color-black; .el-checkbox { display: block; line-height: 40px; .el-checkbox__label { font-size: 16px; color: $--color-text-primary; font-weight: normal; span { position: absolute; right: 15px; color: $--color-text-secondary; font-size: 12px; font-weight: normal; } } } } .el-transfer-panel__footer { height: $--transfer-panel-footer-height; background: $--color-white; margin: 0; padding: 0; border-top: 1px solid $--transfer-border-color; position: absolute; bottom: 0; left: 0; width: 100%; z-index: $--index-normal; @include utils-vertical-center; .el-checkbox { padding-left: 20px; color: $--color-text-regular; } } .el-transfer-panel__empty { margin: 0; height: $--transfer-item-height; line-height: $--transfer-item-height; padding: 6px 15px 0; color: $--color-text-secondary; text-align: center; } .el-checkbox__label { padding-left: 8px; } .el-checkbox__inner { height: 14px; width: 14px; border-radius: 3px; &::after { height: 6px; width: 3px; left: 4px; } } } ================================================ FILE: packages/theme-chalk/src/tree.scss ================================================ @import "mixins/mixins"; @import "common/var"; @import "common/transition"; @import "checkbox"; @include b(tree) { position: relative; cursor: default; background: $--color-white; color: $--tree-font-color; @include e(empty-block) { position: relative; min-height: 60px; text-align: center; width: 100%; height: 100%; } @include e(empty-text) { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: $--color-text-secondary; font-size: $--font-size-base; } @include e(drop-indicator) { position: absolute; left: 0; right: 0; height: 1px; background-color: $--color-primary; } } @include b(tree-node) { white-space: nowrap; outline: none; &:focus { /* focus */ > .el-tree-node__content { background-color: $--tree-node-hover-background-color; } } @include when(drop-inner) { > .el-tree-node__content .el-tree-node__label { background-color: $--color-primary; color: #fff; } } @include e(content) { display: flex; align-items: center; height: 26px; cursor: pointer; & > .el-tree-node__expand-icon { padding: 6px; } & > label.el-checkbox { margin-right: 8px; } &:hover { background-color: $--tree-node-hover-background-color; } .el-tree.is-dragging & { cursor: move; & * { pointer-events: none; } } .el-tree.is-dragging.is-drop-not-allow & { cursor: not-allowed; } } @include e(expand-icon) { cursor: pointer; color: $--tree-expand-icon-color; font-size: 12px; transform: rotate(0deg); transition: transform 0.3s ease-in-out; &.expanded { transform: rotate(90deg); } &.is-leaf { color: transparent; cursor: default; } } @include e(label) { font-size: $--font-size-base; } @include e(loading-icon) { margin-right: 8px; font-size: $--font-size-base; color: $--tree-expand-icon-color; } & > .el-tree-node__children { overflow: hidden; background-color: transparent; } &.is-expanded > .el-tree-node__children { display: block; } } .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content { background-color: mix($--color-white, $--color-primary, 92%); } ================================================ FILE: packages/theme-chalk/src/upload.scss ================================================ @import "mixins/mixins"; @import "progress"; @import "common/var"; @include b(upload) { display: inline-block; text-align: center; cursor: pointer; outline: none; @include e(input) { display: none; } @include e(tip) { font-size: 12px; color: $--color-text-regular; margin-top: 7px; } iframe { position: absolute; z-index: -1; top: 0; left: 0; opacity: 0; filter: alpha(opacity=0); } /* 照片墙模式 */ @include m(picture-card) { background-color: #fbfdff; border: 1px dashed #c0ccda; border-radius: 6px; box-sizing: border-box; width: 148px; height: 148px; cursor: pointer; line-height: 146px; vertical-align: top; i { font-size: 28px; color: #8c939d; } &:hover { border-color: $--color-primary; color: $--color-primary; } } &:focus { border-color: $--color-primary; color: $--color-primary; .el-upload-dragger { border-color: $--color-primary; } } } @include b(upload-dragger) { background-color: #fff; border: 1px dashed #d9d9d9; border-radius: 6px; box-sizing: border-box; width: 360px; height: 180px; text-align: center; cursor: pointer; position: relative; overflow: hidden; .el-icon-upload { font-size: 67px; color: $--color-text-placeholder; margin: 40px 0 16px; line-height: 50px; } + .el-upload__tip { text-align: center; } ~ .el-upload__files { border-top: $--border-base; margin-top: 7px; padding-top: 5px; } .el-upload__text { color: $--color-text-regular; font-size: 14px; text-align: center; em { color: $--color-primary; font-style: normal; } } &:hover { border-color: $--color-primary; } @include when(dragover) { background-color: rgba(32, 159, 255, .06); border: 2px dashed $--color-primary; } } @include b(upload-list) { margin: 0; padding: 0; list-style: none; @include e(item) { transition: all .5s cubic-bezier(.55,0,.1,1); font-size: 14px; color: $--color-text-regular; line-height: 1.8; margin-top: 5px; position: relative; box-sizing: border-box; border-radius: 4px; width: 100%; .el-progress { position: absolute; top: 20px; width: 100%; } .el-progress__text { position: absolute; right: 0; top: -13px; } .el-progress-bar { margin-right: 0; padding-right: 0; } &:first-child { margin-top: 10px; } & .el-icon-upload-success { color: $--color-success; } .el-icon-close { display: none; position: absolute; top: 5px; right: 5px; cursor: pointer; opacity: .75; color: $--color-text-regular; //transform: scale(.7); &:hover { opacity: 1; } } & .el-icon-close-tip { display: none; position: absolute; top: 5px; right: 5px; font-size: 12px; cursor: pointer; opacity: 1; color: $--color-primary; } &:hover { background-color: $--background-color-base; .el-icon-close { display: inline-block; } .el-progress__text { display: none; } } @include when(success) { .el-upload-list__item-status-label { display: block; } .el-upload-list__item-name:hover, .el-upload-list__item-name:focus { color: $--link-hover-color; cursor: pointer; } &:focus:not(:hover) { /* 键盘focus */ .el-icon-close-tip { display: inline-block; } } &:not(.focusing):focus, &:active { /* click时 */ outline-width: 0; .el-icon-close-tip { display: none; } } &:hover, &:focus { .el-upload-list__item-status-label { display: none; } } } } @include when(disabled) { .el-upload-list__item:hover .el-upload-list__item-status-label { display: block; } } @include e(item-name) { color: $--color-text-regular; display: block; margin-right: 40px; overflow: hidden; padding-left: 4px; text-overflow: ellipsis; transition: color .3s; white-space: nowrap; [class^="el-icon"] { height: 100%; margin-right: 7px; color: $--color-text-secondary; line-height: inherit; } } @include e(item-status-label) { position: absolute; right: 5px; top: 0; line-height: inherit; display: none; } @include e(item-delete) { position: absolute; right: 10px; top: 0; font-size: 12px; color: $--color-text-regular; display: none; &:hover { color: $--color-primary; } } @include m(picture-card) { margin: 0; display: inline; vertical-align: top; .el-upload-list__item { overflow: hidden; background-color: #fff; border: 1px solid #c0ccda; border-radius: 6px; box-sizing: border-box; width: 148px; height: 148px; margin: 0 8px 8px 0; display: inline-block; .el-icon-check, .el-icon-circle-check { color: $--color-white; } .el-icon-close { display: none; } &:hover { .el-upload-list__item-status-label { display: none; } .el-progress__text { display: block; } } } .el-upload-list__item-name { display: none; } .el-upload-list__item-thumbnail { width: 100%; height: 100%; } .el-upload-list__item-status-label { position: absolute; right: -15px; top: -6px; width: 40px; height: 24px; background: #13ce66; text-align: center; transform: rotate(45deg); box-shadow: 0 0 1pc 1px rgba(0,0,0,0.2); i { font-size: 12px; margin-top: 11px; transform: rotate(-45deg); } } .el-upload-list__item-actions { position: absolute; width: 100%; height: 100%; left: 0; top: 0; cursor: default; text-align: center; color: #fff; opacity: 0; font-size: 20px; background-color: rgba(0, 0, 0, .5); transition: opacity .3s; &::after { display: inline-block; content: ""; height: 100%; vertical-align: middle } span { display: none; cursor: pointer; } span + span { margin-left: 15px; } .el-upload-list__item-delete { position: static; font-size: inherit; color: inherit; } &:hover { opacity: 1; span { display: inline-block; } } } .el-progress { top: 50%; left: 50%; transform: translate(-50%, -50%); bottom: auto; width: 126px; .el-progress__text { top: 50%; } } } @include m(picture) { .el-upload-list__item { overflow: hidden; z-index: 0; background-color: #fff; border: 1px solid #c0ccda; border-radius: 6px; box-sizing: border-box; margin-top: 10px; padding: 10px 10px 10px 90px; height: 92px; .el-icon-check, .el-icon-circle-check { color: $--color-white; } &:hover { .el-upload-list__item-status-label { background: transparent; box-shadow: none; top: -2px; right: -12px; } .el-progress__text { display: block; } } &.is-success { .el-upload-list__item-name { line-height: 70px; margin-top: 0; i { display: none; } } } } .el-upload-list__item-thumbnail { vertical-align: middle; display: inline-block; width: 70px; height: 70px; float: left; position: relative; z-index: 1; margin-left: -80px; background-color: $--color-white } .el-upload-list__item-name { display: block; margin-top: 20px; i { font-size: 70px; line-height: 1; position: absolute; left: 9px; top: 10px; } } .el-upload-list__item-status-label { position: absolute; right: -17px; top: -7px; width: 46px; height: 26px; background: #13ce66; text-align: center; transform: rotate(45deg); box-shadow: 0 1px 1px #ccc; i { font-size: 12px; margin-top: 12px; transform: rotate(-45deg); } } .el-progress { position: relative; top: -7px; } } } @include b(upload-cover) { position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: hidden; z-index: 10; cursor: default; @include utils-vertical-center; img { display: block; width: 100%; height: 100%; } @include e(label) { position: absolute; right: -15px; top: -6px; width: 40px; height: 24px; background: #13ce66; text-align: center; transform: rotate(45deg); box-shadow: 0 0 1pc 1px rgba(0,0,0,0.2); i { font-size: 12px; margin-top: 11px; transform: rotate(-45deg); color: #fff; } } @include e(progress) { display: inline-block; vertical-align: middle; position: static; width: 243px; + .el-upload__inner { opacity: 0; } } @include e(content) { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } @include e(interact) { position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; background-color: rgba(#000, .72); text-align: center; .btn { display: inline-block; color: $--color-white; font-size: 14px; cursor: pointer; vertical-align: middle; transition: $--md-fade-transition; margin-top: 60px; i { margin-top: 0; } span { opacity: 0; transition: opacity .15s linear; } &:not(:first-child) { margin-left: 35px; } &:hover { transform: translateY(-13px); span { opacity: 1; } } i { color: $--color-white; display: block; font-size: 24px; line-height: inherit; margin: 0 auto 5px; } } } @include e(title) { position: absolute; bottom: 0; left: 0; background-color: $--color-white; height: 36px; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: normal; text-align: left; padding: 0 10px; margin: 0; line-height: 36px; font-size: 14px; color: $--color-text-primary; } + .el-upload__inner { opacity: 0; position: relative; z-index: 1; } } ================================================ FILE: packages/time-picker/index.js ================================================ import TimePicker from '../date-picker/src/picker/time-picker'; /* istanbul ignore next */ TimePicker.install = function(Vue) { Vue.component(TimePicker.name, TimePicker); }; export default TimePicker; ================================================ FILE: packages/time-select/index.js ================================================ import TimeSelect from '../date-picker/src/picker/time-select'; /* istanbul ignore next */ TimeSelect.install = function(Vue) { Vue.component(TimeSelect.name, TimeSelect); }; export default TimeSelect; ================================================ FILE: packages/timeline/index.js ================================================ import Timeline from './src/main'; /* istanbul ignore next */ Timeline.install = function(Vue) { Vue.component(Timeline.name, Timeline); }; export default Timeline; ================================================ FILE: packages/timeline/src/item.vue ================================================ ================================================ FILE: packages/timeline/src/main.vue ================================================ ================================================ FILE: packages/timeline-item/index.js ================================================ import ElTimelineItem from '../timeline/src/item'; /* istanbul ignore next */ ElTimelineItem.install = function(Vue) { Vue.component(ElTimelineItem.name, ElTimelineItem); }; export default ElTimelineItem; ================================================ FILE: packages/tooltip/index.js ================================================ import Tooltip from './src/main'; /* istanbul ignore next */ Tooltip.install = function(Vue) { Vue.component(Tooltip.name, Tooltip); }; export default Tooltip; ================================================ FILE: packages/tooltip/src/main.js ================================================ import Popper from 'element-ui/src/utils/vue-popper'; import debounce from 'throttle-debounce/debounce'; import { addClass, removeClass, on, off } from 'element-ui/src/utils/dom'; import { generateId } from 'element-ui/src/utils/util'; import Vue from 'vue'; export default { name: 'ElTooltip', mixins: [Popper], props: { openDelay: { type: Number, default: 0 }, disabled: Boolean, manual: Boolean, effect: { type: String, default: 'dark' }, arrowOffset: { type: Number, default: 0 }, popperClass: String, content: String, visibleArrow: { default: true }, transition: { type: String, default: 'el-fade-in-linear' }, popperOptions: { default() { return { boundariesPadding: 10, gpuAcceleration: false }; } }, enterable: { type: Boolean, default: true }, hideAfter: { type: Number, default: 0 }, tabindex: { type: Number, default: 0 } }, data() { return { tooltipId: `el-tooltip-${generateId()}`, timeoutPending: null, focusing: false }; }, beforeCreate() { if (this.$isServer) return; this.popperVM = new Vue({ data: { node: '' }, render(h) { return this.node; } }).$mount(); this.debounceClose = debounce(200, () => this.handleClosePopper()); }, render(h) { if (this.popperVM) { this.popperVM.node = (
{ this.setExpectedState(false); this.debounceClose(); } } onMouseenter= { () => { this.setExpectedState(true); } } ref="popper" role="tooltip" id={this.tooltipId} aria-hidden={ (this.disabled || !this.showPopper) ? 'true' : 'false' } v-show={!this.disabled && this.showPopper} class={ ['el-tooltip__popper', 'is-' + this.effect, this.popperClass] }> { this.$slots.content || this.content }
); } const firstElement = this.getFirstElement(); if (!firstElement) return null; const data = firstElement.data = firstElement.data || {}; data.staticClass = this.addTooltipClass(data.staticClass); return firstElement; }, mounted() { this.referenceElm = this.$el; if (this.$el.nodeType === 1) { this.$el.setAttribute('aria-describedby', this.tooltipId); this.$el.setAttribute('tabindex', this.tabindex); on(this.referenceElm, 'mouseenter', this.show); on(this.referenceElm, 'mouseleave', this.hide); on(this.referenceElm, 'focus', () => { if (!this.$slots.default || !this.$slots.default.length) { this.handleFocus(); return; } const instance = this.$slots.default[0].componentInstance; if (instance && instance.focus) { instance.focus(); } else { this.handleFocus(); } }); on(this.referenceElm, 'blur', this.handleBlur); on(this.referenceElm, 'click', this.removeFocusing); } // fix issue https://github.com/ElemeFE/element/issues/14424 if (this.value && this.popperVM) { this.popperVM.$nextTick(() => { if (this.value) { this.updatePopper(); } }); } }, watch: { focusing(val) { if (val) { addClass(this.referenceElm, 'focusing'); } else { removeClass(this.referenceElm, 'focusing'); } } }, methods: { show() { this.setExpectedState(true); this.handleShowPopper(); }, hide() { this.setExpectedState(false); this.debounceClose(); }, handleFocus() { this.focusing = true; this.show(); }, handleBlur() { this.focusing = false; this.hide(); }, removeFocusing() { this.focusing = false; }, addTooltipClass(prev) { if (!prev) { return 'el-tooltip'; } else { return 'el-tooltip ' + prev.replace('el-tooltip', ''); } }, handleShowPopper() { if (!this.expectedState || this.manual) return; clearTimeout(this.timeout); this.timeout = setTimeout(() => { this.showPopper = true; }, this.openDelay); if (this.hideAfter > 0) { this.timeoutPending = setTimeout(() => { this.showPopper = false; }, this.hideAfter); } }, handleClosePopper() { if (this.enterable && this.expectedState || this.manual) return; clearTimeout(this.timeout); if (this.timeoutPending) { clearTimeout(this.timeoutPending); } this.showPopper = false; if (this.disabled) { this.doDestroy(); } }, setExpectedState(expectedState) { if (expectedState === false) { clearTimeout(this.timeoutPending); } this.expectedState = expectedState; }, getFirstElement() { const slots = this.$slots.default; if (!Array.isArray(slots)) return null; let element = null; for (let index = 0; index < slots.length; index++) { if (slots[index] && slots[index].tag) { element = slots[index]; break; }; } return element; } }, beforeDestroy() { this.popperVM && this.popperVM.$destroy(); }, destroyed() { const reference = this.referenceElm; if (reference.nodeType === 1) { off(reference, 'mouseenter', this.show); off(reference, 'mouseleave', this.hide); off(reference, 'focus', this.handleFocus); off(reference, 'blur', this.handleBlur); off(reference, 'click', this.removeFocusing); } } }; ================================================ FILE: packages/transfer/index.js ================================================ import Transfer from './src/main'; /* istanbul ignore next */ Transfer.install = function(Vue) { Vue.component(Transfer.name, Transfer); }; export default Transfer; ================================================ FILE: packages/transfer/src/main.vue ================================================ ================================================ FILE: packages/transfer/src/transfer-panel.vue ================================================ ================================================ FILE: packages/tree/index.js ================================================ import Tree from './src/tree.vue'; /* istanbul ignore next */ Tree.install = function(Vue) { Vue.component(Tree.name, Tree); }; export default Tree; ================================================ FILE: packages/tree/src/model/node.js ================================================ import objectAssign from 'element-ui/src/utils/merge'; import { markNodeData, NODE_KEY } from './util'; import { arrayFindIndex } from 'element-ui/src/utils/util'; export const getChildState = node => { let all = true; let none = true; let allWithoutDisable = true; for (let i = 0, j = node.length; i < j; i++) { const n = node[i]; if (n.checked !== true || n.indeterminate) { all = false; if (!n.disabled) { allWithoutDisable = false; } } if (n.checked !== false || n.indeterminate) { none = false; } } return { all, none, allWithoutDisable, half: !all && !none }; }; const reInitChecked = function(node) { if (node.childNodes.length === 0 || node.loading) return; const {all, none, half} = getChildState(node.childNodes); if (all) { node.checked = true; node.indeterminate = false; } else if (half) { node.checked = false; node.indeterminate = true; } else if (none) { node.checked = false; node.indeterminate = false; } const parent = node.parent; if (!parent || parent.level === 0) return; if (!node.store.checkStrictly) { reInitChecked(parent); } }; const getPropertyFromData = function(node, prop) { const props = node.store.props; const data = node.data || {}; const config = props[prop]; if (typeof config === 'function') { return config(data, node); } else if (typeof config === 'string') { return data[config]; } else if (typeof config === 'undefined') { const dataProp = data[prop]; return dataProp === undefined ? '' : dataProp; } }; let nodeIdSeed = 0; export default class Node { constructor(options) { this.id = nodeIdSeed++; this.text = null; this.checked = false; this.indeterminate = false; this.data = null; this.expanded = false; this.parent = null; this.visible = true; this.isCurrent = false; for (let name in options) { if (options.hasOwnProperty(name)) { this[name] = options[name]; } } // internal this.level = 0; this.loaded = false; this.childNodes = []; this.loading = false; if (this.parent) { this.level = this.parent.level + 1; } const store = this.store; if (!store) { throw new Error('[Node]store is required!'); } store.registerNode(this); const props = store.props; if (props && typeof props.isLeaf !== 'undefined') { const isLeaf = getPropertyFromData(this, 'isLeaf'); if (typeof isLeaf === 'boolean') { this.isLeafByUser = isLeaf; } } if (store.lazy !== true && this.data) { this.setData(this.data); if (store.defaultExpandAll) { this.expanded = true; } } else if (this.level > 0 && store.lazy && store.defaultExpandAll) { this.expand(); } if (!Array.isArray(this.data)) { markNodeData(this, this.data); } if (!this.data) return; const defaultExpandedKeys = store.defaultExpandedKeys; const key = store.key; if (key && defaultExpandedKeys && defaultExpandedKeys.indexOf(this.key) !== -1) { this.expand(null, store.autoExpandParent); } if (key && store.currentNodeKey !== undefined && this.key === store.currentNodeKey) { store.currentNode = this; store.currentNode.isCurrent = true; } if (store.lazy) { store._initDefaultCheckedNode(this); } this.updateLeafState(); } setData(data) { if (!Array.isArray(data)) { markNodeData(this, data); } this.data = data; this.childNodes = []; let children; if (this.level === 0 && this.data instanceof Array) { children = this.data; } else { children = getPropertyFromData(this, 'children') || []; } for (let i = 0, j = children.length; i < j; i++) { this.insertChild({ data: children[i] }); } } get label() { return getPropertyFromData(this, 'label'); } get key() { const nodeKey = this.store.key; if (this.data) return this.data[nodeKey]; return null; } get disabled() { return getPropertyFromData(this, 'disabled'); } get nextSibling() { const parent = this.parent; if (parent) { const index = parent.childNodes.indexOf(this); if (index > -1) { return parent.childNodes[index + 1]; } } return null; } get previousSibling() { const parent = this.parent; if (parent) { const index = parent.childNodes.indexOf(this); if (index > -1) { return index > 0 ? parent.childNodes[index - 1] : null; } } return null; } contains(target, deep = true) { const walk = function(parent) { const children = parent.childNodes || []; let result = false; for (let i = 0, j = children.length; i < j; i++) { const child = children[i]; if (child === target || (deep && walk(child))) { result = true; break; } } return result; }; return walk(this); } remove() { const parent = this.parent; if (parent) { parent.removeChild(this); } } insertChild(child, index, batch) { if (!child) throw new Error('insertChild error: child is required.'); if (!(child instanceof Node)) { if (!batch) { const children = this.getChildren(true) || []; if (children.indexOf(child.data) === -1) { if (typeof index === 'undefined' || index < 0) { children.push(child.data); } else { children.splice(index, 0, child.data); } } } objectAssign(child, { parent: this, store: this.store }); child = new Node(child); } child.level = this.level + 1; if (typeof index === 'undefined' || index < 0) { this.childNodes.push(child); } else { this.childNodes.splice(index, 0, child); } this.updateLeafState(); } insertBefore(child, ref) { let index; if (ref) { index = this.childNodes.indexOf(ref); } this.insertChild(child, index); } insertAfter(child, ref) { let index; if (ref) { index = this.childNodes.indexOf(ref); if (index !== -1) index += 1; } this.insertChild(child, index); } removeChild(child) { const children = this.getChildren() || []; const dataIndex = children.indexOf(child.data); if (dataIndex > -1) { children.splice(dataIndex, 1); } const index = this.childNodes.indexOf(child); if (index > -1) { this.store && this.store.deregisterNode(child); child.parent = null; this.childNodes.splice(index, 1); } this.updateLeafState(); } removeChildByData(data) { let targetNode = null; for (let i = 0; i < this.childNodes.length; i++) { if (this.childNodes[i].data === data) { targetNode = this.childNodes[i]; break; } } if (targetNode) { this.removeChild(targetNode); } } expand(callback, expandParent) { const done = () => { if (expandParent) { let parent = this.parent; while (parent.level > 0) { parent.expanded = true; parent = parent.parent; } } this.expanded = true; if (callback) callback(); }; if (this.shouldLoadData()) { this.loadData((data) => { if (data instanceof Array) { if (this.checked) { this.setChecked(true, true); } else if (!this.store.checkStrictly) { reInitChecked(this); } done(); } }); } else { done(); } } doCreateChildren(array, defaultProps = {}) { array.forEach((item) => { this.insertChild(objectAssign({ data: item }, defaultProps), undefined, true); }); } collapse() { this.expanded = false; } shouldLoadData() { return this.store.lazy === true && this.store.load && !this.loaded; } updateLeafState() { if (this.store.lazy === true && this.loaded !== true && typeof this.isLeafByUser !== 'undefined') { this.isLeaf = this.isLeafByUser; return; } const childNodes = this.childNodes; if (!this.store.lazy || (this.store.lazy === true && this.loaded === true)) { this.isLeaf = !childNodes || childNodes.length === 0; return; } this.isLeaf = false; } setChecked(value, deep, recursion, passValue) { this.indeterminate = value === 'half'; this.checked = value === true; if (this.store.checkStrictly) return; if (!(this.shouldLoadData() && !this.store.checkDescendants)) { let { all, allWithoutDisable } = getChildState(this.childNodes); if (!this.isLeaf && (!all && allWithoutDisable)) { this.checked = false; value = false; } const handleDescendants = () => { if (deep) { const childNodes = this.childNodes; for (let i = 0, j = childNodes.length; i < j; i++) { const child = childNodes[i]; passValue = passValue || value !== false; const isCheck = child.disabled ? child.checked : passValue; child.setChecked(isCheck, deep, true, passValue); } const { half, all } = getChildState(childNodes); if (!all) { this.checked = all; this.indeterminate = half; } } }; if (this.shouldLoadData()) { // Only work on lazy load data. this.loadData(() => { handleDescendants(); reInitChecked(this); }, { checked: value !== false }); return; } else { handleDescendants(); } } const parent = this.parent; if (!parent || parent.level === 0) return; if (!recursion) { reInitChecked(parent); } } getChildren(forceInit = false) { // this is data if (this.level === 0) return this.data; const data = this.data; if (!data) return null; const props = this.store.props; let children = 'children'; if (props) { children = props.children || 'children'; } if (data[children] === undefined) { data[children] = null; } if (forceInit && !data[children]) { data[children] = []; } return data[children]; } updateChildren() { const newData = this.getChildren() || []; const oldData = this.childNodes.map((node) => node.data); const newDataMap = {}; const newNodes = []; newData.forEach((item, index) => { const key = item[NODE_KEY]; const isNodeExists = !!key && arrayFindIndex(oldData, data => data[NODE_KEY] === key) >= 0; if (isNodeExists) { newDataMap[key] = { index, data: item }; } else { newNodes.push({ index, data: item }); } }); if (!this.store.lazy) { oldData.forEach((item) => { if (!newDataMap[item[NODE_KEY]]) this.removeChildByData(item); }); } newNodes.forEach(({ index, data }) => { this.insertChild({ data }, index); }); this.updateLeafState(); } loadData(callback, defaultProps = {}) { if (this.store.lazy === true && this.store.load && !this.loaded && (!this.loading || Object.keys(defaultProps).length)) { this.loading = true; const resolve = (children) => { this.childNodes = []; this.doCreateChildren(children, defaultProps); this.loaded = true; this.loading = false; this.updateLeafState(); if (callback) { callback.call(this, children); } }; this.store.load(this, resolve); } else { if (callback) { callback.call(this); } } } } ================================================ FILE: packages/tree/src/model/tree-store.js ================================================ import Node from './node'; import { getNodeKey } from './util'; export default class TreeStore { constructor(options) { this.currentNode = null; this.currentNodeKey = null; for (let option in options) { if (options.hasOwnProperty(option)) { this[option] = options[option]; } } this.nodesMap = {}; this.root = new Node({ data: this.data, store: this }); if (this.lazy && this.load) { const loadFn = this.load; loadFn(this.root, (data) => { this.root.doCreateChildren(data); this._initDefaultCheckedNodes(); }); } else { this._initDefaultCheckedNodes(); } } filter(value) { const filterNodeMethod = this.filterNodeMethod; const lazy = this.lazy; const traverse = function(node) { const childNodes = node.root ? node.root.childNodes : node.childNodes; childNodes.forEach((child) => { child.visible = filterNodeMethod.call(child, value, child.data, child); traverse(child); }); if (!node.visible && childNodes.length) { let allHidden = true; allHidden = !childNodes.some(child => child.visible); if (node.root) { node.root.visible = allHidden === false; } else { node.visible = allHidden === false; } } if (!value) return; if (node.visible && !node.isLeaf && !lazy) node.expand(); }; traverse(this); } setData(newVal) { const instanceChanged = newVal !== this.root.data; if (instanceChanged) { this.root.setData(newVal); this._initDefaultCheckedNodes(); } else { this.root.updateChildren(); } } getNode(data) { if (data instanceof Node) return data; const key = typeof data !== 'object' ? data : getNodeKey(this.key, data); return this.nodesMap[key] || null; } insertBefore(data, refData) { const refNode = this.getNode(refData); refNode.parent.insertBefore({ data }, refNode); } insertAfter(data, refData) { const refNode = this.getNode(refData); refNode.parent.insertAfter({ data }, refNode); } remove(data) { const node = this.getNode(data); if (node && node.parent) { if (node === this.currentNode) { this.currentNode = null; } node.parent.removeChild(node); } } append(data, parentData) { const parentNode = parentData ? this.getNode(parentData) : this.root; if (parentNode) { parentNode.insertChild({ data }); } } _initDefaultCheckedNodes() { const defaultCheckedKeys = this.defaultCheckedKeys || []; const nodesMap = this.nodesMap; defaultCheckedKeys.forEach((checkedKey) => { const node = nodesMap[checkedKey]; if (node) { node.setChecked(true, !this.checkStrictly); } }); } _initDefaultCheckedNode(node) { const defaultCheckedKeys = this.defaultCheckedKeys || []; if (defaultCheckedKeys.indexOf(node.key) !== -1) { node.setChecked(true, !this.checkStrictly); } } setDefaultCheckedKey(newVal) { if (newVal !== this.defaultCheckedKeys) { this.defaultCheckedKeys = newVal; this._initDefaultCheckedNodes(); } } registerNode(node) { const key = this.key; if (!key || !node || !node.data) return; const nodeKey = node.key; if (nodeKey !== undefined) this.nodesMap[node.key] = node; } deregisterNode(node) { const key = this.key; if (!key || !node || !node.data) return; node.childNodes.forEach(child => { this.deregisterNode(child); }); delete this.nodesMap[node.key]; } getCheckedNodes(leafOnly = false, includeHalfChecked = false) { const checkedNodes = []; const traverse = function(node) { const childNodes = node.root ? node.root.childNodes : node.childNodes; childNodes.forEach((child) => { if ((child.checked || (includeHalfChecked && child.indeterminate)) && (!leafOnly || (leafOnly && child.isLeaf))) { checkedNodes.push(child.data); } traverse(child); }); }; traverse(this); return checkedNodes; } getCheckedKeys(leafOnly = false) { return this.getCheckedNodes(leafOnly).map((data) => (data || {})[this.key]); } getHalfCheckedNodes() { const nodes = []; const traverse = function(node) { const childNodes = node.root ? node.root.childNodes : node.childNodes; childNodes.forEach((child) => { if (child.indeterminate) { nodes.push(child.data); } traverse(child); }); }; traverse(this); return nodes; } getHalfCheckedKeys() { return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]); } _getAllNodes() { const allNodes = []; const nodesMap = this.nodesMap; for (let nodeKey in nodesMap) { if (nodesMap.hasOwnProperty(nodeKey)) { allNodes.push(nodesMap[nodeKey]); } } return allNodes; } updateChildren(key, data) { const node = this.nodesMap[key]; if (!node) return; const childNodes = node.childNodes; for (let i = childNodes.length - 1; i >= 0; i--) { const child = childNodes[i]; this.remove(child.data); } for (let i = 0, j = data.length; i < j; i++) { const child = data[i]; this.append(child, node.data); } } _setCheckedKeys(key, leafOnly = false, checkedKeys) { const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level); const cache = Object.create(null); const keys = Object.keys(checkedKeys); allNodes.forEach(node => node.setChecked(false, false)); for (let i = 0, j = allNodes.length; i < j; i++) { const node = allNodes[i]; const nodeKey = node.data[key].toString(); let checked = keys.indexOf(nodeKey) > -1; if (!checked) { if (node.checked && !cache[nodeKey]) { node.setChecked(false, false); } continue; } let parent = node.parent; while (parent && parent.level > 0) { cache[parent.data[key]] = true; parent = parent.parent; } if (node.isLeaf || this.checkStrictly) { node.setChecked(true, false); continue; } node.setChecked(true, true); if (leafOnly) { node.setChecked(false, false); const traverse = function(node) { const childNodes = node.childNodes; childNodes.forEach((child) => { if (!child.isLeaf) { child.setChecked(false, false); } traverse(child); }); }; traverse(node); } } } setCheckedNodes(array, leafOnly = false) { const key = this.key; const checkedKeys = {}; array.forEach((item) => { checkedKeys[(item || {})[key]] = true; }); this._setCheckedKeys(key, leafOnly, checkedKeys); } setCheckedKeys(keys, leafOnly = false) { this.defaultCheckedKeys = keys; const key = this.key; const checkedKeys = {}; keys.forEach((key) => { checkedKeys[key] = true; }); this._setCheckedKeys(key, leafOnly, checkedKeys); } setDefaultExpandedKeys(keys) { keys = keys || []; this.defaultExpandedKeys = keys; keys.forEach((key) => { const node = this.getNode(key); if (node) node.expand(null, this.autoExpandParent); }); } setChecked(data, checked, deep) { const node = this.getNode(data); if (node) { node.setChecked(!!checked, deep); } } getCurrentNode() { return this.currentNode; } setCurrentNode(currentNode) { const prevCurrentNode = this.currentNode; if (prevCurrentNode) { prevCurrentNode.isCurrent = false; } this.currentNode = currentNode; this.currentNode.isCurrent = true; } setUserCurrentNode(node) { const key = node[this.key]; const currNode = this.nodesMap[key]; this.setCurrentNode(currNode); } setCurrentNodeKey(key) { if (key === null || key === undefined) { this.currentNode && (this.currentNode.isCurrent = false); this.currentNode = null; return; } const node = this.getNode(key); if (node) { this.setCurrentNode(node); } } }; ================================================ FILE: packages/tree/src/model/util.js ================================================ export const NODE_KEY = '$treeNodeId'; export const markNodeData = function(node, data) { if (!data || data[NODE_KEY]) return; Object.defineProperty(data, NODE_KEY, { value: node.id, enumerable: false, configurable: false, writable: false }); }; export const getNodeKey = function(key, data) { if (!key) return data[NODE_KEY]; return data[key]; }; export const findNearestComponent = (element, componentName) => { let target = element; while (target && target.tagName !== 'BODY') { if (target.__vue__ && target.__vue__.$options.name === componentName) { return target.__vue__; } target = target.parentNode; } return null; }; ================================================ FILE: packages/tree/src/tree-node.vue ================================================ ================================================ FILE: packages/tree/src/tree.vue ================================================ ================================================ FILE: packages/upload/index.js ================================================ import Upload from './src'; /* istanbul ignore next */ Upload.install = function(Vue) { Vue.component(Upload.name, Upload); }; export default Upload; ================================================ FILE: packages/upload/src/ajax.js ================================================ function getError(action, option, xhr) { let msg; if (xhr.response) { msg = `${xhr.response.error || xhr.response}`; } else if (xhr.responseText) { msg = `${xhr.responseText}`; } else { msg = `fail to post ${action} ${xhr.status}`; } const err = new Error(msg); err.status = xhr.status; err.method = 'post'; err.url = action; return err; } function getBody(xhr) { const text = xhr.responseText || xhr.response; if (!text) { return text; } try { return JSON.parse(text); } catch (e) { return text; } } export default function upload(option) { if (typeof XMLHttpRequest === 'undefined') { return; } const xhr = new XMLHttpRequest(); const action = option.action; if (xhr.upload) { xhr.upload.onprogress = function progress(e) { if (e.total > 0) { e.percent = e.loaded / e.total * 100; } option.onProgress(e); }; } const formData = new FormData(); if (option.data) { Object.keys(option.data).forEach(key => { formData.append(key, option.data[key]); }); } formData.append(option.filename, option.file, option.file.name); xhr.onerror = function error(e) { option.onError(e); }; xhr.onload = function onload() { if (xhr.status < 200 || xhr.status >= 300) { return option.onError(getError(action, option, xhr)); } option.onSuccess(getBody(xhr)); }; xhr.open('post', action, true); if (option.withCredentials && 'withCredentials' in xhr) { xhr.withCredentials = true; } const headers = option.headers || {}; for (let item in headers) { if (headers.hasOwnProperty(item) && headers[item] !== null) { xhr.setRequestHeader(item, headers[item]); } } xhr.send(formData); return xhr; } ================================================ FILE: packages/upload/src/index.vue ================================================ ================================================ FILE: packages/upload/src/upload-dragger.vue ================================================ ================================================ FILE: packages/upload/src/upload-list.vue ================================================ ================================================ FILE: packages/upload/src/upload.vue ================================================ ================================================ FILE: src/directives/mousewheel.js ================================================ import normalizeWheel from 'normalize-wheel'; const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1; const mousewheel = function(element, callback) { if (element && element.addEventListener) { element.addEventListener(isFirefox ? 'DOMMouseScroll' : 'mousewheel', function(event) { const normalized = normalizeWheel(event); callback && callback.apply(this, [event, normalized]); }); } }; export default { bind(el, binding) { mousewheel(el, binding.value); } }; ================================================ FILE: src/directives/repeat-click.js ================================================ import { once, on } from 'element-ui/src/utils/dom'; import { isMac } from 'element-ui/src/utils/util'; export default { bind(el, binding, vnode) { let interval = null; let startTime; const maxIntervals = isMac() ? 100 : 200; const handler = () => vnode.context[binding.expression].apply(); const clear = () => { if (Date.now() - startTime < maxIntervals) { handler(); } clearInterval(interval); interval = null; }; on(el, 'mousedown', (e) => { if (e.button !== 0) return; startTime = Date.now(); once(document, 'mouseup', clear); clearInterval(interval); interval = setInterval(handler, maxIntervals); }); } }; ================================================ FILE: src/index.js ================================================ /* Automatically generated by './build/bin/build-entry.js' */ import Pagination from '../packages/pagination/index.js'; import Dialog from '../packages/dialog/index.js'; import Autocomplete from '../packages/autocomplete/index.js'; import Dropdown from '../packages/dropdown/index.js'; import DropdownMenu from '../packages/dropdown-menu/index.js'; import DropdownItem from '../packages/dropdown-item/index.js'; import Menu from '../packages/menu/index.js'; import Submenu from '../packages/submenu/index.js'; import MenuItem from '../packages/menu-item/index.js'; import MenuItemGroup from '../packages/menu-item-group/index.js'; import Input from '../packages/input/index.js'; import InputNumber from '../packages/input-number/index.js'; import Radio from '../packages/radio/index.js'; import RadioGroup from '../packages/radio-group/index.js'; import RadioButton from '../packages/radio-button/index.js'; import Checkbox from '../packages/checkbox/index.js'; import CheckboxButton from '../packages/checkbox-button/index.js'; import CheckboxGroup from '../packages/checkbox-group/index.js'; import Switch from '../packages/switch/index.js'; import Select from '../packages/select/index.js'; import Option from '../packages/option/index.js'; import OptionGroup from '../packages/option-group/index.js'; import Button from '../packages/button/index.js'; import ButtonGroup from '../packages/button-group/index.js'; import Table from '../packages/table/index.js'; import TableColumn from '../packages/table-column/index.js'; import DatePicker from '../packages/date-picker/index.js'; import TimeSelect from '../packages/time-select/index.js'; import TimePicker from '../packages/time-picker/index.js'; import Popover from '../packages/popover/index.js'; import Tooltip from '../packages/tooltip/index.js'; import MessageBox from '../packages/message-box/index.js'; import Breadcrumb from '../packages/breadcrumb/index.js'; import BreadcrumbItem from '../packages/breadcrumb-item/index.js'; import Form from '../packages/form/index.js'; import FormItem from '../packages/form-item/index.js'; import Tabs from '../packages/tabs/index.js'; import TabPane from '../packages/tab-pane/index.js'; import Tag from '../packages/tag/index.js'; import Tree from '../packages/tree/index.js'; import Alert from '../packages/alert/index.js'; import Notification from '../packages/notification/index.js'; import Slider from '../packages/slider/index.js'; import Loading from '../packages/loading/index.js'; import Icon from '../packages/icon/index.js'; import Row from '../packages/row/index.js'; import Col from '../packages/col/index.js'; import Upload from '../packages/upload/index.js'; import Progress from '../packages/progress/index.js'; import Spinner from '../packages/spinner/index.js'; import Message from '../packages/message/index.js'; import Badge from '../packages/badge/index.js'; import Card from '../packages/card/index.js'; import Rate from '../packages/rate/index.js'; import Steps from '../packages/steps/index.js'; import Step from '../packages/step/index.js'; import Carousel from '../packages/carousel/index.js'; import Scrollbar from '../packages/scrollbar/index.js'; import CarouselItem from '../packages/carousel-item/index.js'; import Collapse from '../packages/collapse/index.js'; import CollapseItem from '../packages/collapse-item/index.js'; import Cascader from '../packages/cascader/index.js'; import ColorPicker from '../packages/color-picker/index.js'; import Transfer from '../packages/transfer/index.js'; import Container from '../packages/container/index.js'; import Header from '../packages/header/index.js'; import Aside from '../packages/aside/index.js'; import Main from '../packages/main/index.js'; import Footer from '../packages/footer/index.js'; import Timeline from '../packages/timeline/index.js'; import TimelineItem from '../packages/timeline-item/index.js'; import Link from '../packages/link/index.js'; import Divider from '../packages/divider/index.js'; import Image from '../packages/image/index.js'; import Calendar from '../packages/calendar/index.js'; import Backtop from '../packages/backtop/index.js'; import InfiniteScroll from '../packages/infinite-scroll/index.js'; import PageHeader from '../packages/page-header/index.js'; import CascaderPanel from '../packages/cascader-panel/index.js'; import Avatar from '../packages/avatar/index.js'; import Drawer from '../packages/drawer/index.js'; import Statistic from '../packages/statistic/index.js'; import Popconfirm from '../packages/popconfirm/index.js'; import Skeleton from '../packages/skeleton/index.js'; import SkeletonItem from '../packages/skeleton-item/index.js'; import Empty from '../packages/empty/index.js'; import Descriptions from '../packages/descriptions/index.js'; import DescriptionsItem from '../packages/descriptions-item/index.js'; import Result from '../packages/result/index.js'; import locale from 'element-ui/src/locale'; import CollapseTransition from 'element-ui/src/transitions/collapse-transition'; const components = [ Pagination, Dialog, Autocomplete, Dropdown, DropdownMenu, DropdownItem, Menu, Submenu, MenuItem, MenuItemGroup, Input, InputNumber, Radio, RadioGroup, RadioButton, Checkbox, CheckboxButton, CheckboxGroup, Switch, Select, Option, OptionGroup, Button, ButtonGroup, Table, TableColumn, DatePicker, TimeSelect, TimePicker, Popover, Tooltip, Breadcrumb, BreadcrumbItem, Form, FormItem, Tabs, TabPane, Tag, Tree, Alert, Slider, Icon, Row, Col, Upload, Progress, Spinner, Badge, Card, Rate, Steps, Step, Carousel, Scrollbar, CarouselItem, Collapse, CollapseItem, Cascader, ColorPicker, Transfer, Container, Header, Aside, Main, Footer, Timeline, TimelineItem, Link, Divider, Image, Calendar, Backtop, PageHeader, CascaderPanel, Avatar, Drawer, Statistic, Popconfirm, Skeleton, SkeletonItem, Empty, Descriptions, DescriptionsItem, Result, CollapseTransition ]; const install = function(Vue, opts = {}) { locale.use(opts.locale); locale.i18n(opts.i18n); components.forEach(component => { Vue.component(component.name, component); }); Vue.use(InfiniteScroll); Vue.use(Loading.directive); Vue.prototype.$ELEMENT = { size: opts.size || '', zIndex: opts.zIndex || 2000 }; Vue.prototype.$loading = Loading.service; Vue.prototype.$msgbox = MessageBox; Vue.prototype.$alert = MessageBox.alert; Vue.prototype.$confirm = MessageBox.confirm; Vue.prototype.$prompt = MessageBox.prompt; Vue.prototype.$notify = Notification; Vue.prototype.$message = Message; }; /* istanbul ignore if */ if (typeof window !== 'undefined' && window.Vue) { install(window.Vue); } export default { version: '2.15.14', locale: locale.use, i18n: locale.i18n, install, CollapseTransition, Loading, Pagination, Dialog, Autocomplete, Dropdown, DropdownMenu, DropdownItem, Menu, Submenu, MenuItem, MenuItemGroup, Input, InputNumber, Radio, RadioGroup, RadioButton, Checkbox, CheckboxButton, CheckboxGroup, Switch, Select, Option, OptionGroup, Button, ButtonGroup, Table, TableColumn, DatePicker, TimeSelect, TimePicker, Popover, Tooltip, MessageBox, Breadcrumb, BreadcrumbItem, Form, FormItem, Tabs, TabPane, Tag, Tree, Alert, Notification, Slider, Icon, Row, Col, Upload, Progress, Spinner, Message, Badge, Card, Rate, Steps, Step, Carousel, Scrollbar, CarouselItem, Collapse, CollapseItem, Cascader, ColorPicker, Transfer, Container, Header, Aside, Main, Footer, Timeline, TimelineItem, Link, Divider, Image, Calendar, Backtop, InfiniteScroll, PageHeader, CascaderPanel, Avatar, Drawer, Statistic, Popconfirm, Skeleton, SkeletonItem, Empty, Descriptions, DescriptionsItem, Result }; ================================================ FILE: src/locale/format.js ================================================ import { hasOwn } from 'element-ui/src/utils/util'; const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g; /** * String format template * - Inspired: * https://github.com/Matt-Esch/string-template/index.js */ export default function(Vue) { /** * template * * @param {String} string * @param {Array} ...args * @return {String} */ function template(string, ...args) { if (args.length === 1 && typeof args[0] === 'object') { args = args[0]; } if (!args || !args.hasOwnProperty) { args = {}; } return string.replace(RE_NARGS, (match, prefix, i, index) => { let result; if (string[index - 1] === '{' && string[index + match.length] === '}') { return i; } else { result = hasOwn(args, i) ? args[i] : null; if (result === null || result === undefined) { return ''; } return result; } }); } return template; } ================================================ FILE: src/locale/index.js ================================================ import defaultLang from 'element-ui/src/locale/lang/zh-CN'; import Vue from 'vue'; import deepmerge from 'deepmerge'; import Format from './format'; const format = Format(Vue); let lang = defaultLang; let merged = false; let i18nHandler = function() { const vuei18n = Object.getPrototypeOf(this || Vue).$t; if (typeof vuei18n === 'function' && !!Vue.locale) { if (!merged) { merged = true; Vue.locale( Vue.config.lang, deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true }) ); } return vuei18n.apply(this, arguments); } }; export const t = function(path, options) { let value = i18nHandler.apply(this, arguments); if (value !== null && value !== undefined) return value; const array = path.split('.'); let current = lang; for (let i = 0, j = array.length; i < j; i++) { const property = array[i]; value = current[property]; if (i === j - 1) return format(value, options); if (!value) return ''; current = value; } return ''; }; export const use = function(l) { lang = l || lang; }; export const i18n = function(fn) { i18nHandler = fn || i18nHandler; }; export default { use, t, i18n }; ================================================ FILE: src/locale/lang/af-ZA.js ================================================ export default { el: { colorpicker: { confirm: 'Bevestig', clear: 'Maak skoon' }, datepicker: { now: 'Nou', today: 'Vandag', cancel: 'Kanselleer', clear: 'Maak skoon', confirm: 'Bevestig', selectDate: 'Kies datum', selectTime: 'Kies tyd', startDate: 'Begindatum', startTime: 'Begintyd', endDate: 'Einddatum', endTime: 'Eindtyd', prevYear: 'Previous Year', // to be translated nextYear: 'Next Year', // to be translated prevMonth: 'Previous Month', // to be translated nextMonth: 'Next Month', // to be translated year: 'Jaar', month1: 'Jan', month2: 'Feb', month3: 'Mrt', month4: 'Apr', month5: 'Mei', month6: 'Jun', month7: 'Jul', month8: 'Aug', month9: 'Sep', month10: 'Okt', month11: 'Nov', month12: 'Des', // week: 'week', weeks: { sun: 'So', mon: 'Ma', tue: 'Di', wed: 'Wo', thu: 'Do', fri: 'Vr', sat: 'Sa' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mrt', apr: 'Apr', may: 'Mei', jun: 'Jun', jul: 'Jul', aug: 'Aug', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Des' } }, select: { loading: 'Laai', noMatch: 'Geen toepaslike data', noData: 'Geen data', placeholder: 'Kies' }, cascader: { noMatch: 'Geen toepaslike data', loading: 'Laai', placeholder: 'Kies', noData: 'Geen data' }, pagination: { goto: 'Gaan na', pagesize: '/page', total: 'Totaal {total}', pageClassifier: '' }, messagebox: { title: 'Boodskap', confirm: 'Bevestig', cancel: 'Kanselleer', error: 'Ongeldige invoer' }, upload: { deleteTip: 'press delete to remove', // to be translated delete: 'Verwyder', preview: 'Voorskou', continue: 'Gaan voort' }, table: { emptyText: 'Geen Data', confirmFilter: 'Bevestig', resetFilter: 'Herstel', clearFilter: 'Alles', sumText: 'Som' }, tree: { emptyText: 'Geen Data' }, transfer: { noMatch: 'Geen toepaslike data', noData: 'Geen data', titles: ['Lys 1', 'Lys 2'], filterPlaceholder: 'Voer sleutelwoord in', noCheckedFormat: '{total} items', hasCheckedFormat: '{checked}/{total} gekies' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Geen Data' } } }; ================================================ FILE: src/locale/lang/ar.js ================================================ export default { el: { colorpicker: { confirm: 'موافق', clear: 'إزالة' }, datepicker: { now: 'الآن', today: 'اليوم', cancel: 'إلغاء', clear: 'إزالة', confirm: 'موافق', selectDate: 'إختر التاريخ', selectTime: 'إختر الوقت', startDate: 'تاريخ البدء', startTime: 'وقت البدء', endDate: 'تاريخ الإنتهاء', endTime: 'وقت الإنتهاء', prevYear: 'السنة السابقة', nextYear: 'السنة التالية', prevMonth: 'الشهر السابق', nextMonth: 'الشهر التالي', year: 'سنة', month1: 'يناير', month2: 'فبراير', month3: 'مارس', month4: 'ابريل', month5: 'مايو', month6: 'يونيو', month7: 'يوليو', month8: 'أغسطس', month9: 'سبتمبر', month10: 'أكتوبر', month11: 'نوفمبر', month12: 'ديسمبر', week: 'أسبوع', weeks: { sun: 'الأحد', mon: 'الأثنين', tue: 'الثلاثاء', wed: 'الأربعاء', thu: 'الخميس', fri: 'الجمعة', sat: 'السبت' }, months: { jan: 'يناير', feb: 'فبراير', mar: 'مارس', apr: 'أبريل', may: 'مايو', jun: 'يونيو', jul: 'يوليو', aug: 'أغسطس', sep: 'سبتمبر', oct: 'أكتوبر', nov: 'نوفمبر', dec: 'ديسمبر' } }, select: { loading: 'جار التحميل', noMatch: 'لايوجد بيانات مطابقة', noData: 'لايوجد بيانات', placeholder: 'إختر' }, cascader: { noMatch: 'لايوجد بيانات مطابقة', loading: 'جار التحميل', placeholder: 'إختر', noData: 'لايوجد بيانات' }, pagination: { goto: 'أذهب إلى', pagesize: '/صفحة', total: 'الكل {total}', pageClassifier: '' }, messagebox: { title: 'العنوان', confirm: 'موافق', cancel: 'إلغاء', error: 'مدخل غير صحيح' }, upload: { delete: 'حذف', preview: 'عرض', continue: 'إستمرار' }, table: { emptyText: 'لايوجد بيانات', confirmFilter: 'تأكيد', resetFilter: 'حذف', clearFilter: 'الكل', sumText: 'المجموع' }, tree: { emptyText: 'لايوجد بيانات' }, transfer: { noMatch: 'لايوجد بيانات مطابقة', noData: 'لايوجد بيانات', titles: ['قائمة 1', 'قائمة 2'], filterPlaceholder: 'ادخل كلمة', noCheckedFormat: '{total} عناصر', hasCheckedFormat: '{checked}/{total} مختار' }, image: { error: 'فشل' }, pageHeader: { title: 'عودة' }, popconfirm: { confirmButtonText: 'تأكيد', cancelButtonText: 'إلغاء' }, empty: { description: 'لايوجد بيانات' } } }; ================================================ FILE: src/locale/lang/az.js ================================================ 'use strict'; exports.__esModule = true; exports.default = { el: { colorpicker: { confirm: 'Təsdiqlə', clear: 'Təmizlə' }, datepicker: { now: 'İndi', today: 'Bugün', cancel: 'İmtina', clear: 'Təmizlə', confirm: 'Təsdiqlə', selectDate: 'Taxir seç', selectTime: 'Saat seç', startDate: 'Başlanğıc Tarixi', startTime: 'Başlanğıc Saatı', endDate: 'Bitmə Tarixi', endTime: 'Bitmə Saatı', prevYear: 'Öncəki il', nextYear: 'Sonrakı il', prevMonth: 'Öncəki ay', nextMonth: 'Sonrakı ay', year: '', month1: 'Yanvar', month2: 'Fevral', month3: 'Mart', month4: 'Aprel', month5: 'May', month6: 'İyun', month7: 'İyul', month8: 'Avqust', month9: 'Sentyabr', month10: 'Oktyabr', month11: 'Noyabr', month12: 'Dekabr', // week: 'week', weeks: { sun: 'Baz', mon: 'B.e', tue: 'Ç.a', wed: 'Çər', thu: 'C.a', fri: 'Cüm', sat: 'Şən' }, months: { jan: 'Yan', feb: 'Fev', mar: 'Mar', apr: 'Apr', may: 'May', jun: 'İyn', jul: 'İyl', aug: 'Avq', sep: 'Sen', oct: 'Okt', nov: 'Noy', dec: 'Dek' } }, select: { loading: 'Yüklənir', noMatch: 'Nəticə tapılmadı', noData: 'Məlumat yoxdur', placeholder: 'Seç' }, cascader: { noMatch: 'Nəticə tapılmadı', loading: 'Yüklənir', placeholder: 'Seç', noData: 'Məlumat yoxdur' }, pagination: { goto: 'Get', pagesize: '/səhifə', total: 'Toplam {total}', pageClassifier: '' }, messagebox: { title: 'Mesaj', confirm: 'Təsdiqlə', cancel: 'İmtina', error: 'Səhv' }, upload: { deleteTip: 'Sürüşdürmədən sonra sil', delete: 'Sil', preview: 'Ön izlə', continue: 'Davam et' }, table: { emptyText: 'Məlumat yoxdur', confirmFilter: 'Təsdiqlə', resetFilter: 'Sıfırla', clearFilter: 'Bütün', sumText: 'Cəmi' }, tree: { emptyText: 'Məlumat yoxdur' }, transfer: { noMatch: 'Nəticə tapılmadı', noData: 'Məlumat yoxdur', titles: ['List 1', 'List 2'], filterPlaceholder: 'Kəliməliri daxil et', noCheckedFormat: '{total} ədəd', hasCheckedFormat: '{checked}/{total} seçildi' }, image: { error: 'SƏHV' // to be translated }, pageHeader: { title: 'Geri' // to be translated }, popconfirm: { confirmButtonText: 'Bəli', // to be translated cancelButtonText: 'Xeyr' // to be translated }, empty: { description: 'Məlumat yoxdur' } } }; ================================================ FILE: src/locale/lang/bg.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Изчисти' }, datepicker: { now: 'Сега', today: 'Днес', cancel: 'Откажи', clear: 'Изчисти', confirm: 'ОК', selectDate: 'Избери дата', selectTime: 'Избери час', startDate: 'Начална дата', startTime: 'Начален час', endDate: 'Крайна дата', endTime: 'Краен час', prevYear: 'Previous Year', // to be translated nextYear: 'Next Year', // to be translated prevMonth: 'Previous Month', // to be translated nextMonth: 'Next Month', // to be translated year: '', month1: 'Януари', month2: 'Февруари', month3: 'Март', month4: 'Април', month5: 'Май', month6: 'Юни', month7: 'Юли', month8: 'Август', month9: 'Септември', month10: 'Октомври', month11: 'Ноември', month12: 'Декември', // week: 'Седмица', weeks: { sun: 'Нед', mon: 'Пон', tue: 'Вто', wed: 'Сря', thu: 'Чет', fri: 'Пет', sat: 'Съб' }, months: { jan: 'Яну', feb: 'Фев', mar: 'Мар', apr: 'Апр', may: 'Май', jun: 'Юни', jul: 'Юли', aug: 'Авг', sep: 'Сеп', oct: 'Окт', nov: 'Ное', dec: 'Дек' } }, select: { loading: 'Зареждане', noMatch: 'Няма намерени', noData: 'Няма данни', placeholder: 'Избери' }, cascader: { noMatch: 'Няма намерени', loading: 'Зареждане', placeholder: 'Избери', noData: 'Няма данни' }, pagination: { goto: 'Иди на', pagesize: '/страница', total: 'Общо {total}', pageClassifier: '' }, messagebox: { title: 'Съобщение', confirm: 'ОК', cancel: 'Откажи', error: 'Невалидни данни' }, upload: { deleteTip: 'press delete to remove', // to be translated delete: 'Изтрий', preview: 'Прегледай', continue: 'Продължи' }, table: { emptyText: 'Няма данни', confirmFilter: 'Потвърди', resetFilter: 'Изчисти', clearFilter: 'Всички', sumText: 'Sum' // to be translated }, tree: { emptyText: 'Няма данни' }, transfer: { noMatch: 'Няма намерени', noData: 'Няма данни', titles: ['List 1', 'List 2'], // to be translated filterPlaceholder: 'Enter keyword', // to be translated noCheckedFormat: '{total} items', // to be translated hasCheckedFormat: '{checked}/{total} checked' // to be translated }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Няма данни' } } }; ================================================ FILE: src/locale/lang/bn.js ================================================ 'use strict'; exports.__esModule = true; exports.default = { el: { colorpicker: { confirm: 'নিশ্চিত', clear: 'খালি' }, datepicker: { now: 'এখন', today: 'আজকাল', cancel: 'বাতিল করুন', clear: 'খালি', confirm: 'নিশ্চিত', selectDate: 'তারিখ নির্বাচন করুন', selectTime: 'নির্বাচনের সময়কাল', startDate: 'শুরুর তারিখ', startTime: 'শুরুর সময়', endDate: 'শেষ তারিখ', endTime: 'শেষ সময়', prevYear: 'গত বছর', nextYear: 'আগামী বছর', prevMonth: 'গত মাসে', nextMonth: 'পরের মাসে', year: 'বছর', month1: 'জানুয়ারি', month2: 'ফেব্রুয়ারি', month3: 'মার্চ', month4: 'এপ্রিল', month5: 'মে', month6: 'জুন', month7: 'জুলাই', month8: 'আগস্ট', month9: 'সেপ্টেম্বর', month10: 'অক্টোবর', month11: 'নভেম্বর', month12: 'ডিসেম্বর', // week: '周次', weeks: { sun: 'রবিবার', mon: 'সোমবারে', tue: 'মঙ্গলবার', wed: 'বুধবার', thu: 'বৃহস্পতিবার', fri: 'শুক্রবার', sat: 'শনিবার' }, months: { jan: 'জানুয়ারি', feb: 'ফেব্রুয়ারি', mar: 'মার্চ', apr: 'এপ্রিল', may: 'মে', jun: 'জুন', jul: 'জুলাই', aug: 'আগস্ট', sep: 'সেপ্টেম্বর', oct: 'অক্টোবর', nov: 'নভেম্বর', dec: 'ডিসেম্বর' } }, select: { loading: 'লোড হচ্ছে', noMatch: 'কোন মিল তথ্য', noData: 'কোন তথ্য নেই', placeholder: 'পছন্দ কর' }, cascader: { noMatch: 'কোন মিল তথ্য', loading: 'লোড হচ্ছে', placeholder: 'পছন্দ কর', noData: 'কোন তথ্য নেই' }, pagination: { goto: 'যাও', pagesize: 'প্রবন্ধ/পৃষ্ঠা', total: 'সর্বমোট {total} ফালা', pageClassifier: 'পাতা' }, messagebox: { title: 'ইঙ্গিত', confirm: 'নিশ্চিত', cancel: 'বাতিল করুন', error: 'প্রবেশ করা তথ্য অবৈধ!' }, upload: { deleteTip: 'অনুসারে delete মুছে ফেলা', delete: 'মুছে ফেলা', preview: 'ভিউ ইমেজ', continue: 'আপলোড চালিয়ে যান' }, table: { emptyText: 'কোন তথ্য নেই', confirmFilter: 'ছাঁকনি', resetFilter: 'রিসেট', clearFilter: 'সব', sumText: 'মোট' }, tree: { emptyText: 'কোন তথ্য নেই' }, transfer: { noMatch: 'কোন মিল তথ্য', noData: 'কোন তথ্য নেই', titles: ['তালিকা 1', 'তালিকা 2'], filterPlaceholder: 'অনুসন্ধান বিষয়বস্তু লিখুন', noCheckedFormat: 'মোট {total} আইটেম', hasCheckedFormat: 'নির্বাচিত {checked}/{total} আইটেম' }, image: { error: 'লোড করতে ব্যর্থ' }, pageHeader: { title: 'প্রত্যাবর্তন' }, popconfirm: { confirmButtonText: 'নিশ্চিত', cancelButtonText: 'বাতিল করুন' }, empty: { description: 'কোন তথ্য নেই' } } }; ================================================ FILE: src/locale/lang/ca.js ================================================ export default { el: { colorpicker: { confirm: 'Confirmar', clear: 'Netejar' }, datepicker: { now: 'Ara', today: 'Avui', cancel: 'Cancel·lar', clear: 'Netejar', confirm: 'Confirmar', selectDate: 'Seleccionar data', selectTime: 'Seleccionar hora', startDate: 'Data Inici', startTime: 'Hora Inici', endDate: 'Data Final', endTime: 'Hora Final', prevYear: 'Any anterior', nextYear: 'Pròxim Any', prevMonth: 'Mes anterior', nextMonth: 'Pròxim Mes', year: '', month1: 'Gener', month2: 'Febrer', month3: 'Març', month4: 'Abril', month5: 'Maig', month6: 'Juny', month7: 'Juliol', month8: 'Agost', month9: 'Setembre', month10: 'Octubre', month11: 'Novembre', month12: 'Desembre', // week: 'setmana', weeks: { sun: 'Dg', mon: 'Dl', tue: 'Dt', wed: 'Dc', thu: 'Dj', fri: 'Dv', sat: 'Ds' }, months: { jan: 'Gen', feb: 'Febr', mar: 'Març', apr: 'Abr', may: 'Maig', jun: 'Juny', jul: 'Jul', aug: 'Ag', sep: 'Set', oct: 'Oct', nov: 'Nov', dec: 'Des' } }, select: { loading: 'Carregant', noMatch: 'No hi ha dades que coincideixin', noData: 'Sense Dades', placeholder: 'Seleccionar' }, cascader: { noMatch: 'No hi ha dades que coincideixin', loading: 'Carregant', placeholder: 'Seleccionar', noData: 'Sense Dades' }, pagination: { goto: 'Anar a', pagesize: '/pagina', total: 'Total {total}', pageClassifier: '' }, messagebox: { confirm: 'Acceptar', cancel: 'Cancel·lar', error: 'Entrada invàlida' }, upload: { deleteTip: 'premi eliminar per descartar', delete: 'Eliminar', preview: 'Vista Prèvia', continue: 'Continuar' }, table: { emptyText: 'Sense Dades', confirmFilter: 'Confirmar', resetFilter: 'Netejar', clearFilter: 'Tot', sumText: 'Tot' }, tree: { emptyText: 'Sense Dades' }, transfer: { noMatch: 'No hi ha dades que coincideixin', noData: 'Sense Dades', titles: ['Llista 1', 'Llista 2'], filterPlaceholder: 'Introdueix la paraula clau', noCheckedFormat: '{total} ítems', hasCheckedFormat: '{checked}/{total} seleccionats' }, image: { error: 'HA FALLAT' }, pageHeader: { title: 'Tornar' }, popconfirm: { confirmButtonText: 'Si', cancelButtonText: 'No' }, empty: { description: 'Sense Dades' } } }; ================================================ FILE: src/locale/lang/cs-CZ.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Vymazat' }, datepicker: { now: 'Teď', today: 'Dnes', cancel: 'Zrušit', clear: 'Vymazat', confirm: 'OK', selectDate: 'Vybrat datum', selectTime: 'Vybrat čas', startDate: 'Datum začátku', startTime: 'Čas začátku', endDate: 'Datum konce', endTime: 'Čas konce', prevYear: 'Předchozí rok', nextYear: 'Příští rok', prevMonth: 'Předchozí měsíc', nextMonth: 'Příští měsíc', day: 'Den', week: 'Týden', month: 'Měsíc', year: 'Rok', month1: 'Leden', month2: 'Únor', month3: 'Březen', month4: 'Duben', month5: 'Květen', month6: 'Červen', month7: 'Červenec', month8: 'Srpen', month9: 'Září', month10: 'Říjen', month11: 'Listopad', month12: 'Prosinec', weeks: { sun: 'Ne', mon: 'Po', tue: 'Út', wed: 'St', thu: 'Čt', fri: 'Pá', sat: 'So' }, months: { jan: 'Led', feb: 'Úno', mar: 'Bře', apr: 'Dub', may: 'Kvě', jun: 'Čer', jul: 'Čvc', aug: 'Srp', sep: 'Zář', oct: 'Říj', nov: 'Lis', dec: 'Pro' } }, select: { loading: 'Načítání', noMatch: 'Žádná shoda', noData: 'Žádná data', placeholder: 'Vybrat' }, cascader: { noMatch: 'Žádná shoda', loading: 'Načítání', placeholder: 'Vybrat', noData: 'Žádná data' }, pagination: { goto: 'Jít na', pagesize: 'na stranu', total: 'Celkem {total}', pageClassifier: '' }, messagebox: { title: 'Zpráva', confirm: 'OK', cancel: 'Zrušit', error: 'Neplatný vstup' }, upload: { deleteTip: 'Stisknout pro smazání', delete: 'Vymazat', preview: 'Náhled', continue: 'Pokračovat' }, table: { emptyText: 'Žádná data', confirmFilter: 'Potvrdit', resetFilter: 'Resetovat', clearFilter: 'Vše', sumText: 'Celkem' }, tree: { emptyText: 'Žádná data' }, transfer: { noMatch: 'Žádná shoda', noData: 'Žádná data', titles: ['Seznam 1', 'Seznam 2'], filterPlaceholder: 'Klíčové slovo', noCheckedFormat: '{total} položek', hasCheckedFormat: '{checked}/{total} vybráno' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Žádná data' } } }; ================================================ FILE: src/locale/lang/da.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Ryd' }, datepicker: { now: 'Nu', today: 'I dag', cancel: 'Annuller', clear: 'Ryd', confirm: 'OK', selectDate: 'Vælg dato', selectTime: 'Vælg tidspunkt', startDate: 'Startdato', startTime: 'Starttidspunkt', endDate: 'Slutdato', endTime: 'Sluttidspunkt', prevYear: 'Forrige år', nextYear: 'Næste år', prevMonth: 'Forrige måned', nextMonth: 'Næste måned', year: '', month1: 'Januar', month2: 'Februar', month3: 'Marts', month4: 'April', month5: 'Maj', month6: 'Juni', month7: 'Juli', month8: 'August', month9: 'September', month10: 'Oktober', month11: 'November', month12: 'December', week: 'uge', weeks: { sun: 'Søn', mon: 'Man', tue: 'Tir', wed: 'Ons', thu: 'Tor', fri: 'Fre', sat: 'Lør' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Maj', jun: 'Jun', jul: 'Jul', aug: 'Aug', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Henter', noMatch: 'Ingen matchende data', noData: 'Ingen data', placeholder: 'Vælg' }, cascader: { noMatch: 'Ingen matchende data', loading: 'Henter', placeholder: 'Vælg', noData: 'Ingen data' }, pagination: { goto: 'Gå til', pagesize: '/side', total: 'Total {total}', pageClassifier: '' }, messagebox: { confirm: 'OK', cancel: 'Annuller', error: 'Ugyldig input' }, upload: { deleteTip: 'tryk slet for at fjerne', delete: 'Slet', preview: 'Forhåndsvisning', continue: 'Fortsæt' }, table: { emptyText: 'Ingen data', confirmFilter: 'Bekræft', resetFilter: 'Nulstil', clearFilter: 'Alle', sumText: 'Sum' }, tree: { emptyText: 'Ingen data' }, transfer: { noMatch: 'Ingen matchende data', noData: 'Ingen data', titles: ['Liste 1', 'Liste 2'], filterPlaceholder: 'Indtast søgeord', noCheckedFormat: '{total} emner', hasCheckedFormat: '{checked}/{total} valgt' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Ingen data' } } }; ================================================ FILE: src/locale/lang/de.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Leeren' }, datepicker: { now: 'Jetzt', today: 'Heute', cancel: 'Abbrechen', clear: 'Leeren', confirm: 'OK', selectDate: 'Datum wählen', selectTime: 'Uhrzeit wählen', startDate: 'Startdatum', startTime: 'Startzeit', endDate: 'Enddatum', endTime: 'Endzeit', prevYear: 'Letztes Jahr', nextYear: 'Nächtes Jahr', prevMonth: 'Letzter Monat', nextMonth: 'Nächster Monat', day: 'Tag', week: 'Woche', month: 'Monat', year: '', month1: 'Januar', month2: 'Februar', month3: 'März', month4: 'April', month5: 'Mai', month6: 'Juni', month7: 'Juli', month8: 'August', month9: 'September', month10: 'Oktober', month11: 'November', month12: 'Dezember', weeks: { sun: 'So', mon: 'Mo', tue: 'Di', wed: 'Mi', thu: 'Do', fri: 'Fr', sat: 'Sa' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mär', apr: 'Apr', may: 'Mai', jun: 'Jun', jul: 'Jul', aug: 'Aug', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dez' } }, select: { loading: 'Lädt.', noMatch: 'Nichts gefunden.', noData: 'Keine Daten', placeholder: 'Daten wählen' }, cascader: { noMatch: 'Nichts gefunden.', loading: 'Lädt.', placeholder: 'Daten wählen', noData: 'Keine Daten' }, pagination: { goto: 'Gehe zu', pagesize: ' pro Seite', total: 'Gesamt {total}', pageClassifier: '' }, messagebox: { confirm: 'OK', cancel: 'Abbrechen', error: 'Fehler' }, upload: { deleteTip: 'Klicke löschen zum entfernen', delete: 'Löschen', preview: 'Vorschau', continue: 'Fortsetzen' }, table: { emptyText: 'Keine Daten', confirmFilter: 'Anwenden', resetFilter: 'Zurücksetzen', clearFilter: 'Alles ', sumText: 'Summe' }, tree: { emptyText: 'Keine Einträge' }, transfer: { noMatch: 'Nichts gefunden.', noData: 'Keine Einträge', titles: ['Liste 1', 'Liste 2'], filterPlaceholder: 'Einträge filtern', noCheckedFormat: '{total} Einträge', hasCheckedFormat: '{checked}/{total} ausgewählt' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Keine Daten' } } }; ================================================ FILE: src/locale/lang/ee.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Tühjenda' }, datepicker: { now: 'Praegu', today: 'Täna', cancel: 'Tühista', clear: 'Tühjenda', confirm: 'OK', selectDate: 'Vali kuupäev', selectTime: 'Vali kellaaeg', startDate: 'Alguskuupäev', startTime: 'Algusaeg', endDate: 'Lõpukuupäev', endTime: 'Lõpuaeg', prevYear: 'Eelmine aasta', nextYear: 'Järgmine aasta', prevMonth: 'Eelmine kuu', nextMonth: 'Järgmine kuu', year: '', month1: 'Jaanuar', month2: 'Veebruar', month3: 'Märts', month4: 'Aprill', month5: 'Mai', month6: 'Juuni', month7: 'Juuli', month8: 'August', month9: 'September', month10: 'Oktoober', month11: 'November', month12: 'Detsember', // week: 'nädal', weeks: { sun: 'P', mon: 'E', tue: 'T', wed: 'K', thu: 'N', fri: 'R', sat: 'L' }, months: { jan: 'Jaan', feb: 'Veeb', mar: 'Mär', apr: 'Apr', may: 'Mai', jun: 'Juun', jul: 'Juul', aug: 'Aug', sep: 'Sept', oct: 'Okt', nov: 'Nov', dec: 'Dets' } }, select: { loading: 'Laadimine', noMatch: 'Sobivad andmed puuduvad', noData: 'Andmed puuduvad', placeholder: 'Vali' }, cascader: { noMatch: 'Sobivad andmed puuduvad', loading: 'Laadimine', placeholder: 'Vali', noData: 'Andmed puuduvad' }, pagination: { goto: 'Mine lehele', pagesize: '/page', total: 'Kokku {total}', pageClassifier: '' }, messagebox: { title: 'Teade', confirm: 'OK', cancel: 'Tühista', error: 'Vigane sisend' }, upload: { deleteTip: 'Vajuta "Kustuta", et eemaldada', delete: 'Kustuta', preview: 'Eelvaate', continue: 'Jätka' }, table: { emptyText: 'Andmed puuduvad', confirmFilter: 'Kinnita', resetFilter: 'Taasta', clearFilter: 'Kõik', sumText: 'Summa' }, tree: { emptyText: 'Andmed puuduvad' }, transfer: { noMatch: 'Sobivad andmed puuduvad', noData: 'Andmed puuduvad', titles: ['Loend 1', 'Loend 2'], filterPlaceholder: 'Sisesta märksõna', noCheckedFormat: '{total} objekti', hasCheckedFormat: '{checked}/{total} valitud' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Andmed puuduvad' } } }; ================================================ FILE: src/locale/lang/el.js ================================================ export default { el: { colorpicker: { confirm: 'Εντάξει', clear: 'Καθαρισμός' }, datepicker: { now: 'Τώρα', today: 'Σήμερα', cancel: 'Ακύρωση', clear: 'Καθαρισμός', confirm: 'Εντάξει', selectDate: 'Επιλέξτε ημέρα', selectTime: 'Επιλέξτε ώρα', startDate: 'Ημερομηνία Έναρξης', startTime: 'Ωρα Έναρξης', endDate: 'Ημερομηνία Λήξης', endTime: 'Ωρα Λήξης', prevYear: 'Προηγούμενο Έτος', nextYear: 'Επόμενο Έτος', prevMonth: 'Προηγούμενος Μήνας', nextMonth: 'Επόμενος Μήνας', year: 'Έτος', month1: 'Ιανουάριος', month2: 'Φεβρουάριος', month3: 'Μάρτιος', month4: 'Απρίλιος', month5: 'Μάιος', month6: 'Ιούνιος', month7: 'Ιούλιος', month8: 'Αύγουστος', month9: 'Σεπτέμβριος', month10: 'Οκτώβριος', month11: 'Νοέμβριος', month12: 'Δεκέμβριος', // week: 'εβδομάδα', weeks: { sun: 'Κυρ', mon: 'Δευ', tue: 'Τρι', wed: 'Τετ', thu: 'Πεμ', fri: 'Παρ', sat: 'Σαβ' }, months: { jan: 'Ιαν', feb: 'Φεβ', mar: 'Μαρ', apr: 'Απρ', may: 'Μαϊ', jun: 'Ιουν', jul: 'Ιουλ', aug: 'Αυγ', sep: 'Σεπ', oct: 'Οκτ', nov: 'Νοε', dec: 'Δεκ' } }, select: { loading: 'Φόρτωση', noMatch: 'Δεν βρέθηκαν αποτελέσματα', noData: 'Χωρίς δεδομένα', placeholder: 'Επιλογή' }, cascader: { noMatch: 'Δεν βρέθηκαν αποτελέσματα', loading: 'Φόρτωση', placeholder: 'Επιλογή', noData: 'Χωρίς δεδομένα' }, pagination: { goto: 'Μετάβαση σε', pagesize: '/σελίδα', total: 'Σύνολο {total}', pageClassifier: '' }, messagebox: { title: 'Μήνυμα', confirm: 'Εντάξει', cancel: 'Ακύρωση', error: 'Άκυρη εισαγωγή' }, upload: { deleteTip: 'Πάτησε Διαγραφή για αφαίρεση', delete: 'Διαγραφή', preview: 'Προεπισκόπηση', continue: 'Συνέχεια' }, table: { emptyText: 'Χωρίς Δεδομένα', confirmFilter: 'Επιβεβαίωση', resetFilter: 'Επαναφορά', clearFilter: 'Όλα', sumText: 'Σύνολο' }, tree: { emptyText: 'Χωρίς Δεδομένα' }, transfer: { noMatch: 'Δεν βρέθηκαν αποτελέσματα', noData: 'Χωρίς δεδομένα', titles: ['Λίστα 1', 'Λίστα 2'], filterPlaceholder: 'Αναζήτηση', noCheckedFormat: '{total} Αντικείμενα', hasCheckedFormat: '{checked}/{total} επιλεγμένα' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Χωρίς Δεδομένα' } } }; ================================================ FILE: src/locale/lang/en.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Clear' }, datepicker: { now: 'Now', today: 'Today', cancel: 'Cancel', clear: 'Clear', confirm: 'OK', selectDate: 'Select date', selectTime: 'Select time', startDate: 'Start Date', startTime: 'Start Time', endDate: 'End Date', endTime: 'End Time', prevYear: 'Previous Year', nextYear: 'Next Year', prevMonth: 'Previous Month', nextMonth: 'Next Month', year: '', month1: 'January', month2: 'February', month3: 'March', month4: 'April', month5: 'May', month6: 'June', month7: 'July', month8: 'August', month9: 'September', month10: 'October', month11: 'November', month12: 'December', week: 'week', weeks: { sun: 'Sun', mon: 'Mon', tue: 'Tue', wed: 'Wed', thu: 'Thu', fri: 'Fri', sat: 'Sat' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'May', jun: 'Jun', jul: 'Jul', aug: 'Aug', sep: 'Sep', oct: 'Oct', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Loading', noMatch: 'No matching data', noData: 'No data', placeholder: 'Select' }, cascader: { noMatch: 'No matching data', loading: 'Loading', placeholder: 'Select', noData: 'No data' }, pagination: { goto: 'Go to', pagesize: '/page', total: 'Total {total}', pageClassifier: '' }, messagebox: { title: 'Message', confirm: 'OK', cancel: 'Cancel', error: 'Illegal input' }, upload: { deleteTip: 'press delete to remove', delete: 'Delete', preview: 'Preview', continue: 'Continue' }, table: { emptyText: 'No Data', confirmFilter: 'Confirm', resetFilter: 'Reset', clearFilter: 'All', sumText: 'Sum' }, tree: { emptyText: 'No Data' }, transfer: { noMatch: 'No matching data', noData: 'No data', titles: ['List 1', 'List 2'], // to be translated filterPlaceholder: 'Enter keyword', // to be translated noCheckedFormat: '{total} items', // to be translated hasCheckedFormat: '{checked}/{total} checked' // to be translated }, image: { error: 'FAILED' }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', cancelButtonText: 'No' }, empty: { description: 'No Data' } } }; ================================================ FILE: src/locale/lang/eo.js ================================================ export default { el: { colorpicker: { confirm: 'Bone', clear: 'Malplenigi' }, datepicker: { now: 'Nun', today: 'Hodiaŭ', cancel: 'Nuligi', clear: 'Malplenigi', confirm: 'Bone', selectDate: 'Elektu daton', selectTime: 'Elektu horon', startDate: 'Komenca Dato', startTime: 'Komenca Horo', endDate: 'Fina Dato', endTime: 'Fina Horo', prevYear: 'Antaŭa Jaro', nextYear: 'Sekva Jaro', prevMonth: 'Antaŭa Monato', nextMonth: 'Sekva Monato', year: 'Jaro', month1: 'Januaro', month2: 'Februaro', month3: 'Marto', month4: 'Aprilo', month5: 'Majo', month6: 'Junio', month7: 'Julio', month8: 'Aŭgusto', month9: 'Septembro', month10: 'Oktobro', month11: 'Novembro', month12: 'Decembro', week: 'Semajno', weeks: { sun: 'Dim', mon: 'Lun', tue: 'Mar', wed: 'Mer', thu: 'Ĵaŭ', fri: 'Ven', sat: 'Sab' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Maj', jun: 'Jun', jul: 'Jul', aug: 'Aŭg', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Ŝarĝante', noMatch: 'Neniuj kongruaj datumoj', noData: 'Neniuj datumoj', placeholder: 'Bonvolu elekti' }, cascader: { noMatch: 'Neniuj kongruaj datumoj', loading: 'Ŝarĝante', placeholder: 'Bonvolu elekti', noData: 'Neniuj datumoj' }, pagination: { goto: 'Iru al', pagesize: '/ paĝo', total: 'Entute {total}', pageClassifier: '' }, messagebox: { title: 'Mesaĝo', confirm: 'Bone', cancel: 'Nuligi', error: 'Nevalida Enigo!' }, upload: { deleteTip: 'Premu "Delete" por forigi', delete: 'Forigi', preview: 'Antaŭrigardi', continue: 'Daŭrigi' }, table: { emptyText: 'Neniuj datumoj', confirmFilter: 'Konfirmi', resetFilter: 'Restarigi', clearFilter: 'Ĉiuj', sumText: 'Sumo' }, tree: { emptyText: 'Neniuj datumoj' }, transfer: { noMatch: 'Neniuj kongruaj datumoj', noData: 'Neniuj datumoj', titles: ['Listo 1', 'Listo 2'], filterPlaceholder: 'Enigu ŝlosilvorton', noCheckedFormat: '{total} elementoj', hasCheckedFormat: '{checked}/{total} elektitaj' }, image: { error: 'MALSUKCESIS' }, pageHeader: { title: 'Reen' }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Neniuj datumoj' } } }; ================================================ FILE: src/locale/lang/es.js ================================================ export default { el: { colorpicker: { confirm: 'Confirmar', clear: 'Limpiar' }, datepicker: { now: 'Ahora', today: 'Hoy', cancel: 'Cancelar', clear: 'Limpiar', confirm: 'Confirmar', selectDate: 'Seleccionar fecha', selectTime: 'Seleccionar hora', startDate: 'Fecha Incial', startTime: 'Hora Inicial', endDate: 'Fecha Final', endTime: 'Hora Final', prevYear: 'Año Anterior', nextYear: 'Próximo Año', prevMonth: 'Mes Anterior', nextMonth: 'Próximo Mes', year: '', month1: 'enero', month2: 'febrero', month3: 'marzo', month4: 'abril', month5: 'mayo', month6: 'junio', month7: 'julio', month8: 'agosto', month9: 'septiembre', month10: 'octubre', month11: 'noviembre', month12: 'diciembre', // week: 'semana', weeks: { sun: 'dom', mon: 'lun', tue: 'mar', wed: 'mié', thu: 'jue', fri: 'vie', sat: 'sáb' }, months: { jan: 'ene', feb: 'feb', mar: 'mar', apr: 'abr', may: 'may', jun: 'jun', jul: 'jul', aug: 'ago', sep: 'sep', oct: 'oct', nov: 'nov', dec: 'dic' } }, select: { loading: 'Cargando', noMatch: 'No hay datos que coincidan', noData: 'Sin datos', placeholder: 'Seleccionar' }, cascader: { noMatch: 'No hay datos que coincidan', loading: 'Cargando', placeholder: 'Seleccionar', noData: 'Sin datos' }, pagination: { goto: 'Ir a', pagesize: '/página', total: 'Total {total}', pageClassifier: '' }, messagebox: { confirm: 'Aceptar', cancel: 'Cancelar', error: 'Entrada inválida' }, upload: { deleteTip: 'Pulse Eliminar para retirar', delete: 'Eliminar', preview: 'Vista Previa', continue: 'Continuar' }, table: { emptyText: 'Sin Datos', confirmFilter: 'Confirmar', resetFilter: 'Reiniciar', clearFilter: 'Limpiar', sumText: 'Suma' }, tree: { emptyText: 'Sin Datos' }, transfer: { noMatch: 'No hay datos que coincidan', noData: 'Sin datos', titles: ['Lista 1', 'Lista 2'], filterPlaceholder: 'Ingresar palabra clave', noCheckedFormat: '{total} artículos', hasCheckedFormat: '{checked}/{total} revisados' }, image: { error: 'HA FALLADO' }, pageHeader: { title: 'Volver' }, popconfirm: { confirmButtonText: 'Si', cancelButtonText: 'No' }, empty: { description: 'Sin Datos' } } }; ================================================ FILE: src/locale/lang/eu.js ================================================ export default { el: { colorpicker: { confirm: 'Ados', clear: 'Garbitu' }, datepicker: { now: 'Orain', today: 'Gaur', cancel: 'Utzi', clear: 'Garbitu', confirm: 'Ados', selectDate: 'Hautatu data', selectTime: 'Hautatu ordua', startDate: 'Hasierako data', startTime: 'Hasierako ordua', endDate: 'Amaierako data', endTime: 'Amaierako ordua', prevYear: 'Aurreko urtea', nextYear: 'Hurrengo urtea', prevMonth: 'Aurreko hilabetea', nextMonth: 'Hurrengo hilabetea', year: '', month1: 'Urtarrila', month2: 'Otsaila', month3: 'Martxoa', month4: 'Apirila', month5: 'Maiatza', month6: 'Ekaina', month7: 'Uztaila', month8: 'Abuztua', month9: 'Iraila', month10: 'Urria', month11: 'Azaroa', month12: 'Abendua', // week: 'astea', weeks: { sun: 'ig.', mon: 'al.', tue: 'ar.', wed: 'az.', thu: 'og.', fri: 'ol.', sat: 'lr.' }, months: { jan: 'urt', feb: 'ots', mar: 'mar', apr: 'api', may: 'mai', jun: 'eka', jul: 'uzt', aug: 'abu', sep: 'ira', oct: 'urr', nov: 'aza', dec: 'abe' } }, select: { loading: 'Kargatzen', noMatch: 'Bat datorren daturik ez', noData: 'Daturik ez', placeholder: 'Hautatu' }, cascader: { noMatch: 'Bat datorren daturik ez', loading: 'Kargatzen', placeholder: 'Hautatu', noData: 'Daturik ez' }, pagination: { goto: 'Joan', pagesize: '/orria', total: 'Guztira {total}', pageClassifier: '' }, messagebox: { title: 'Mezua', confirm: 'Ados', cancel: 'Utzi', error: 'Sarrera baliogabea' }, upload: { deleteTip: 'sakatu Ezabatu kentzeko', delete: 'Ezabatu', preview: 'Aurrebista', continue: 'Jarraitu' }, table: { emptyText: 'Daturik ez', confirmFilter: 'Baieztatu', resetFilter: 'Berrezarri', clearFilter: 'Guztia', sumText: 'Batura' }, tree: { emptyText: 'Daturik ez' }, transfer: { noMatch: 'Bat datorren daturik ez', noData: 'Daturik ez', titles: ['Zerrenda 1', 'Zerrenda 2'], // to be translated filterPlaceholder: 'Sartu gako-hitza', // to be translated noCheckedFormat: '{total} elementu', // to be translated hasCheckedFormat: '{checked}/{total} hautatuta' // to be translated }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Daturik ez' } } }; ================================================ FILE: src/locale/lang/fa.js ================================================ export default { el: { colorpicker: { confirm: 'باشد', clear: 'حذف' }, datepicker: { now: 'اکنون', today: 'امروز', cancel: 'لغو', clear: 'حذف', confirm: 'باشه', selectDate: 'انتخاب تاریخ', selectTime: 'انتخاب زمان', startDate: 'تاریخ شروع', startTime: 'زمان شروع', endDate: 'تاریخ پایان', endTime: 'زمان پایان', prevYear: 'سال قبل', nextYear: 'سال بعد', prevMonth: 'ماه قبل', nextMonth: 'ماه بعد', year: 'سال', month1: 'ژانویه', month2: 'فوریه', month3: 'مارس', month4: 'آوریل', month5: 'مه', month6: 'ژوئن', month7: 'جولای', month8: 'اوت', month9: 'سپتامبر', month10: 'اکتبر', month11: 'نوامبر', month12: 'دسامبر', // week: 'week', weeks: { sun: 'یکشنبه', mon: 'دوشنبه', tue: 'سه​شنبه', wed: 'چهارشنبه', thu: 'پنج​شنبه', fri: 'جمعه', sat: 'شنبه' }, months: { jan: 'ژانویه', feb: 'فوریه', mar: 'مارس', apr: 'آوریل', may: 'مه', jun: 'ژوئن', jul: 'جولای', aug: 'اوت', sep: 'سپتامبر', oct: 'اکتبر', nov: 'نوامبر', dec: 'دسامبر' } }, select: { loading: 'بارگیری', noMatch: 'هیچ داده‌ای پیدا نشد', noData: 'اطلاعاتی وجود ندارد', placeholder: 'انتخاب کنید' }, cascader: { noMatch: 'هیچ داده‌ای پیدا نشد', loading: 'بارگیری', placeholder: 'انتخاب کنید', noData: 'اطلاعاتی وجود ندارد' }, pagination: { goto: 'برو به', pagesize: '/صفحه', total: 'مجموع {total}', pageClassifier: '' }, messagebox: { title: 'پیام', confirm: 'باشه', cancel: 'لغو', error: 'ورودی غیر مجاز' }, upload: { deleteTip: 'برای پاک کردن حذف را فشار دهید', delete: 'حذف', preview: 'پیش‌نمایش', continue: 'ادامه' }, table: { emptyText: 'اطلاعاتی وجود ندارد', confirmFilter: 'تایید', resetFilter: 'حذف', clearFilter: 'همه', sumText: 'جمع' }, tree: { emptyText: 'اطلاعاتی وجود ندارد' }, transfer: { noMatch: 'هیچ داده‌ای پیدا نشد', noData: 'اطلاعاتی وجود ندارد', titles: ['لیست 1', 'لیست 2'], filterPlaceholder: 'کلید واژه هارو وارد کن', noCheckedFormat: '{total} مورد', hasCheckedFormat: '{checked} مورد از {total} مورد انتخاب شده است' }, image: { error: 'خطا در بارگیری تصویر' }, pageHeader: { title: 'بازگشت' }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'اطلاعاتی وجود ندارد' } } }; ================================================ FILE: src/locale/lang/fi.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Tyhjennä' }, datepicker: { now: 'Nyt', today: 'Tänään', cancel: 'Peruuta', clear: 'Tyhjennä', confirm: 'OK', selectDate: 'Valitse päivä', selectTime: 'Valitse aika', startDate: 'Aloituspäivä', startTime: 'Aloitusaika', endDate: 'Lopetuspäivä', endTime: 'Lopetusaika', prevYear: 'Edellinen vuosi', nextYear: 'Seuraava vuosi', prevMonth: 'Edellinen kuukausi', nextMonth: 'Seuraava kuukausi', year: '', month1: 'tammikuu', month2: 'helmikuu', month3: 'maaliskuu', month4: 'huhtikuu', month5: 'toukokuu', month6: 'kesäkuu', month7: 'heinäkuu', month8: 'elokuu', month9: 'syyskuu', month10: 'lokakuu', month11: 'marraskuu', month12: 'joulukuu', // week: 'week', weeks: { sun: 'su', mon: 'ma', tue: 'ti', wed: 'ke', thu: 'to', fri: 'pe', sat: 'la' }, months: { jan: 'tammi', feb: 'helmi', mar: 'maalis', apr: 'huhti', may: 'touko', jun: 'kesä', jul: 'heinä', aug: 'elo', sep: 'syys', oct: 'loka', nov: 'marras', dec: 'joulu' } }, select: { loading: 'Lataa', noMatch: 'Ei vastaavia tietoja', noData: 'Ei tietoja', placeholder: 'Valitse' }, cascader: { noMatch: 'Ei vastaavia tietoja', loading: 'Lataa', placeholder: 'Valitse', noData: 'Ei tietoja' }, pagination: { goto: 'Mene', pagesize: '/sivu', total: 'Yhteensä {total}', pageClassifier: '' }, messagebox: { title: 'Viesti', confirm: 'OK', cancel: 'Peruuta', error: 'Virheellinen syöte' }, upload: { deleteTip: 'Poista Delete-näppäimellä', delete: 'Poista', preview: 'Esikatsele', continue: 'Jatka' }, table: { emptyText: 'Ei tietoja', confirmFilter: 'Vahvista', resetFilter: 'Tyhjennä', clearFilter: 'Kaikki', sumText: 'Summa' }, tree: { emptyText: 'Ei tietoja' }, transfer: { noMatch: 'Ei vastaavia tietoja', noData: 'Ei tietoja', titles: ['Luettelo 1', 'Luettelo 2'], filterPlaceholder: 'Syötä hakusana', noCheckedFormat: '{total} kohdetta', hasCheckedFormat: '{checked}/{total} valittu' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Ei tietoja' } } }; ================================================ FILE: src/locale/lang/fr.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Effacer' }, datepicker: { now: 'Maintenant', today: 'Auj.', cancel: 'Annuler', clear: 'Effacer', confirm: 'OK', selectDate: 'Choisir date', selectTime: 'Choisir horaire', startDate: 'Date début', startTime: 'Horaire début', endDate: 'Date fin', endTime: 'Horaire fin', prevYear: 'Année précédente', nextYear: 'Année suivante', prevMonth: 'Mois précédent', nextMonth: 'Mois suivant', year: '', // In french, like in english, we don't say "Année" after the year number. month1: 'Janvier', month2: 'Février', month3: 'Mars', month4: 'Avril', month5: 'Mai', month6: 'Juin', month7: 'Juillet', month8: 'Août', month9: 'Septembre', month10: 'Octobre', month11: 'Novembre', month12: 'Décembre', // week: 'Semaine', weeks: { sun: 'Dim', mon: 'Lun', tue: 'Mar', wed: 'Mer', thu: 'Jeu', fri: 'Ven', sat: 'Sam' }, months: { jan: 'Jan', feb: 'Fév', mar: 'Mar', apr: 'Avr', may: 'Mai', jun: 'Jun', jul: 'Jul', aug: 'Aoû', sep: 'Sep', oct: 'Oct', nov: 'Nov', dec: 'Déc' } }, select: { loading: 'Chargement', noMatch: 'Aucune correspondance', noData: 'Aucune donnée', placeholder: 'Choisir' }, cascader: { noMatch: 'Aucune correspondance', loading: 'Chargement', placeholder: 'Choisir', noData: 'Aucune donnée' }, pagination: { goto: 'Aller à', pagesize: '/page', total: 'Total {total}', pageClassifier: '' }, messagebox: { confirm: 'Confirmer', cancel: 'Annuler', error: 'Erreur' }, upload: { deleteTip: 'Cliquer sur supprimer pour retirer le fichier', delete: 'Supprimer', preview: 'Aperçu', continue: 'Continuer' }, table: { emptyText: 'Aucune donnée', confirmFilter: 'Confirmer', resetFilter: 'Réinitialiser', clearFilter: 'Tous', sumText: 'Somme' }, tree: { emptyText: 'Aucune donnée' }, transfer: { noMatch: 'Aucune correspondance', noData: 'Aucune donnée', titles: ['Liste 1', 'Liste 2'], filterPlaceholder: 'Entrer un mot clef', noCheckedFormat: '{total} elements', hasCheckedFormat: '{checked}/{total} coché(s)' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Aucune donnée' } } }; ================================================ FILE: src/locale/lang/he.js ================================================ export default { el: { colorpicker: { confirm: 'אישור', clear: 'נקה' }, datepicker: { now: 'כעת', today: 'היום', cancel: 'בטל', clear: 'נקה', confirm: 'אישור', selectDate: 'בחר תאריך', selectTime: 'בחר זמן', startDate: 'תאריך התחלה', startTime: 'זמן התחלה', endDate: 'תאריך סיום', endTime: 'זמן סיום', prevYear: 'Previous Year', // to be translated nextYear: 'Next Year', // to be translated prevMonth: 'Previous Month', // to be translated nextMonth: 'Next Month', // to be translated year: '', month1: 'ינואר', month2: 'פברואר', month3: 'מרץ', month4: 'אפריל', month5: 'מאי', month6: 'יוני', month7: 'יולי', month8: 'אוגוסט', month9: 'ספטמבר', month10: 'אוקטובר', month11: 'נובמבר', month12: 'דצמבר', // week: 'week', weeks: { sun: 'א׳', mon: 'ב׳', tue: 'ג׳', wed: 'ד׳', thu: 'ה׳', fri: 'ו׳', sat: 'שבת' }, months: { jan: 'ינואר', feb: 'פברואר', mar: 'מרץ', apr: 'אפריל', may: 'מאי', jun: 'יוני', jul: 'יולי', aug: 'אוגוסט', sep: 'ספטמבר', oct: 'אוקטובר', nov: 'נובמבר', dec: 'דצמבר' } }, select: { loading: 'טוען', noMatch: 'לא נמצאו נתונים', noData: 'ללא נתונים', placeholder: 'בחר' }, cascader: { noMatch: 'ללא נתונים מתאימים', loading: 'טוען', placeholder: 'בחר', noData: 'ללא נתונים' }, pagination: { goto: 'עבור ל', pagesize: '/page', total: 'כולל {total}', pageClassifier: '' }, messagebox: { title: 'הודעה', confirm: 'אישור', cancel: 'בטל', error: 'קלט לא תקין' }, upload: { deleteTip: 'press delete to remove', // to be translated delete: 'מחק', preview: 'תצוגה מקדימה', continue: 'המשך' }, table: { emptyText: 'אין נתונים', confirmFilter: 'אישור', resetFilter: 'נקה', clearFilter: 'הכל', sumText: 'סך' }, tree: { emptyText: 'אין נתונים' }, transfer: { noMatch: 'אין נתונים מתאימים', noData: 'ללא נתונים', titles: ['רשימה 1', 'רשימה 2'], filterPlaceholder: 'הקלד', noCheckedFormat: 'פריטים {total}', hasCheckedFormat: ' אישור {checked}/{total}' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'אין נתונים' } } }; ================================================ FILE: src/locale/lang/hr.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Očisti' }, datepicker: { now: 'Sada', today: 'Danas', cancel: 'Otkaži', clear: 'Očisti', confirm: 'OK', selectDate: 'Odaberi datum', selectTime: 'Odaberi vrijeme', startDate: 'Datum početka', startTime: 'Vrijeme početka', endDate: 'Datum završetka', endTime: 'Vrijeme završetka', prevYear: 'Prethodna godina', nextYear: 'Sljedeća godina', prevMonth: 'Prethodni mjesec', nextMonth: 'Sljedeći mjesec', year: '', month1: 'Siječanj', month2: 'Veljača', month3: 'Ožujak', month4: 'Travanj', month5: 'Svibanj', month6: 'Lipanj', month7: 'Srpanj', month8: 'Kolovoz', month9: 'Rujan', month10: 'Listopad', month11: 'Studeni', month12: 'Prosinac', week: 'tjedan', weeks: { sun: 'Ned', mon: 'Pon', tue: 'Uto', wed: 'Sri', thu: 'Čet', fri: 'Pet', sat: 'Sub' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'May', jun: 'Jun', jul: 'Jul', aug: 'Aug', sep: 'Sep', oct: 'Oct', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Učitavanje', noMatch: 'Nema pronađenih podataka', noData: 'Nema podataka', placeholder: 'Izaberi' }, cascader: { noMatch: 'Nema pronađenih podataka', loading: 'Učitavanje', placeholder: 'Izaberi', noData: 'Nema podataka' }, pagination: { goto: 'Idi na', pagesize: '/stranica', total: 'Ukupno {total}', pageClassifier: '' }, messagebox: { title: 'Poruka', confirm: 'OK', cancel: 'Otkaži', error: 'Pogrešan unos' }, upload: { deleteTip: 'pritisnite izbriši za brisanje', delete: 'Izbriši', preview: 'Pregled', continue: 'Nastavak' }, table: { emptyText: 'Nema podataka', confirmFilter: 'Potvrdi', resetFilter: 'Resetiraj', clearFilter: 'Sve', sumText: 'Suma' }, tree: { emptyText: 'Nema podataka' }, transfer: { noMatch: 'Nema pronađenih podataka', noData: 'Nema podataka', titles: ['Lista 1', 'Lista 2'], // to be translated filterPlaceholder: 'Unesite ključnu riječ', // to be translated noCheckedFormat: '{total} stavki', // to be translated hasCheckedFormat: '{checked}/{total} checked' // to be translated }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Nema podataka' } } }; ================================================ FILE: src/locale/lang/hu.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Törlés' }, datepicker: { now: 'Most', today: 'Ma', cancel: 'Mégse', clear: 'Törlés', confirm: 'OK', selectDate: 'Dátum', selectTime: 'Időpont', startDate: 'Dátum-tól', startTime: 'Időpont-tól', endDate: 'Dátum-ig', endTime: 'Időpont-ig', prevYear: 'Előző év', nextYear: 'Következő év', prevMonth: 'Előző hónap', nextMonth: 'Következő hónap', year: '', month1: 'Január', month2: 'Február', month3: 'Március', month4: 'Április', month5: 'Május', month6: 'Június', month7: 'Július', month8: 'Augusztus', month9: 'Szeptember', month10: 'Október', month11: 'November', month12: 'December', weeks: { sun: 'Vas', mon: 'Hét', tue: 'Ked', wed: 'Sze', thu: 'Csü', fri: 'Pén', sat: 'Szo' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Már', apr: 'Ápr', may: 'Máj', jun: 'Jún', jul: 'Júl', aug: 'Aug', sep: 'Szep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Betöltés', noMatch: 'Nincs találat', noData: 'Nincs adat', placeholder: 'Válassz' }, cascader: { noMatch: 'Nincs találat', loading: 'Betöltés', placeholder: 'Válassz', noData: 'Nincs adat' }, pagination: { goto: 'Ugrás', pagesize: '/oldal', total: 'Össz {total}', pageClassifier: '' }, messagebox: { title: 'Üzenet', confirm: 'OK', cancel: 'Mégse', error: 'Hibás adat' }, upload: { deleteTip: 'kattints a törléshez', delete: 'Törlés', preview: 'Előnézet', continue: 'Tovább' }, table: { emptyText: 'Nincs adat', confirmFilter: 'Megerősít', resetFilter: 'Alaphelyet', clearFilter: 'Mind', sumText: 'Összeg' }, tree: { emptyText: 'Nincs adat' }, transfer: { noMatch: 'Nincs találat', noData: 'Nincs adat', titles: ['Lista 1', 'Lista 2'], filterPlaceholder: 'Kulcsszó', noCheckedFormat: '{total} elem', hasCheckedFormat: '{checked}/{total} kiválasztva' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Nincs adat' } } }; ================================================ FILE: src/locale/lang/hy-AM.js ================================================ export default { el: { colorpicker: { confirm: 'Լաւ', clear: 'Մաքրել' }, datepicker: { now: 'Հիմա', today: 'Այսօր', cancel: 'Չեղարկել', clear: 'Մաքրել', confirm: 'Լաւ', selectDate: 'Ընտրեք ամսաթիւը', selectTime: 'Ընտրեք ժամանակը', startDate: 'Սկզբ. ամսաթիւը', startTime: 'Սկզբ. ժամանակը', endDate: 'Վերջ. ամսաթիվը', endTime: 'Վերջ. ժամանակը', prevYear: 'Նախորդ տարի', nextYear: 'Յաջորդ տարի', prevMonth: 'Նախորդ ամիս', nextMonth: 'Յաջորդ ամիս', year: 'Տարի', month1: 'Յունուար', month2: 'Փետրուար', month3: 'Մարտ', month4: 'Ապրիլ', month5: 'Մայիս', month6: 'Յունիս', month7: 'Յուլիս', month8: 'Օգոստոս', month9: 'Սեպտեմբեր', month10: 'Յոկտեմբեր', month11: 'Նոյեմբեր', month12: 'Դեկտեմբեր', week: 'Շաբաթ', weeks: { sun: 'Կիր', mon: 'Երկ', tue: 'Եր', wed: 'Չոր', thu: 'Հինգ', fri: 'Ուրբ', sat: 'Շաբ' }, months: { jan: 'Յունվ', feb: 'Փետ', mar: 'Մար', apr: 'Ապր', may: 'Մայ', jun: 'Յուն', jul: 'Յուլ', aug: 'Օգ', sep: 'Սեպտ', oct: 'Յոկ', nov: 'Նոյ', dec: 'Դեկ' } }, select: { loading: 'Բեռնում', noMatch: 'Համապատասխան տուեալներ չկան', noData: 'Տվյալներ չկան', placeholder: 'Ընտրել' }, cascader: { noMatch: 'Համապատասխան տուեալներ չկան', loading: 'Բեռնում', placeholder: 'Ընտրել', noData: 'Տվյալներ չկան' }, pagination: { goto: 'Անցնել', pagesize: ' էջում', total: 'Ընդամենը {total}', pageClassifier: '' }, messagebox: { title: 'Հաղորդագրութիւն', confirm: 'Լաւ', cancel: 'Չեղարկել', error: 'Անվաւեր տուեալների մուտք' }, upload: { deleteTip: 'Սեղմեք [Ջնջել] ջնջելու համար', delete: 'Ջնջել', preview: 'Նախադիտում', continue: 'Շարունակել' }, table: { emptyText: 'Տուեալներ չկան', confirmFilter: 'Յաստատել', resetFilter: 'Վերագործարկել', clearFilter: 'Բոլորը', sumText: 'Գումարը' }, tree: { emptyText: 'Տուեալներ չկան' }, transfer: { noMatch: 'Համապատասխան տուեալներ չկան', noData: 'Տուեալներ չկան', titles: ['Ցուցակ 1', 'Ցուցակ 2'], filterPlaceholder: 'Մուտքագրեք բանալի բառ', noCheckedFormat: '{total} միաւոր', hasCheckedFormat: '{checked}/{total} ընտրուած է' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Տուեալներ չկան' } } }; ================================================ FILE: src/locale/lang/id.js ================================================ export default { el: { colorpicker: { confirm: 'Pilih', clear: 'Kosongkan' }, datepicker: { now: 'Sekarang', today: 'Hari ini', cancel: 'Batal', clear: 'Kosongkan', confirm: 'Ya', selectDate: 'Pilih tanggal', selectTime: 'Pilih waktu', startDate: 'Tanggal Mulai', startTime: 'Waktu Mulai', endDate: 'Tanggal Selesai', endTime: 'Waktu Selesai', prevYear: 'Tahun Sebelumnya', nextYear: 'Tahun Selanjutnya', prevMonth: 'Bulan Sebelumnya', nextMonth: 'Bulan Selanjutnya', year: 'Tahun', month1: 'Januari', month2: 'Februari', month3: 'Maret', month4: 'April', month5: 'Mei', month6: 'Juni', month7: 'Juli', month8: 'Agustus', month9: 'September', month10: 'Oktober', month11: 'November', month12: 'Desember', // week: 'minggu', weeks: { sun: 'Min', mon: 'Sen', tue: 'Sel', wed: 'Rab', thu: 'Kam', fri: 'Jum', sat: 'Sab' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Mei', jun: 'Jun', jul: 'Jul', aug: 'Agu', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Des' } }, select: { loading: 'Memuat', noMatch: 'Tidak ada data yg cocok', noData: 'Tidak ada data', placeholder: 'Pilih' }, cascader: { noMatch: 'Tidak ada data yg cocok', loading: 'Memuat', placeholder: 'Pilih', noData: 'Tidak ada data' }, pagination: { goto: 'Pergi ke', pagesize: '/laman', total: 'Total {total}', pageClassifier: '' }, messagebox: { title: 'Pesan', confirm: 'Ya', cancel: 'Batal', error: 'Masukan ilegal' }, upload: { deleteTip: 'Tekan hapus untuk melanjutkan', delete: 'Hapus', preview: 'Pratinjau', continue: 'Lanjutkan' }, table: { emptyText: 'Tidak ada data', confirmFilter: 'Konfirmasi', resetFilter: 'Atur ulang', clearFilter: 'Semua', sumText: 'Jml' }, tree: { emptyText: 'Tidak ada data' }, transfer: { noMatch: 'Tidak ada data yg cocok', noData: 'Tidak ada data', titles: ['Senarai 1', 'Senarai 2'], filterPlaceholder: 'Masukan kata kunci', noCheckedFormat: '{total} butir', hasCheckedFormat: '{checked}/{total} terpilih' }, image: { error: 'GAGAL' }, pageHeader: { title: 'Kembali' }, popconfirm: { confirmButtonText: 'Ya', cancelButtonText: 'Tidak' }, empty: { description: 'Tidak ada data' } } }; ================================================ FILE: src/locale/lang/is.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Hreinsa' }, datepicker: { now: 'Núna', today: 'Í dag', cancel: 'Hætta við', clear: 'Hreinsa', confirm: 'OK', selectDate: 'Velja dagsetningu', selectTime: 'Velja tíma', startDate: 'Upphafsdagsetning', startTime: 'Upphafstími', endDate: 'Lokadagsetning', endTime: 'Lokatími', prevYear: 'Síðasta ár', nextYear: 'Næsta ár', prevMonth: 'Síðasti mánuður', nextMonth: 'Næsti mánuður', year: 'Ár', month1: 'Janúar', month2: 'Febrúar', month3: 'Mars', month4: 'Apríl', month5: 'Maí', month6: 'Júní', month7: 'Júlí', month8: 'Ágúst', month9: 'September', month10: 'Október', month11: 'Nóvember', month12: 'Desember', week: 'Vika', weeks: { sun: 'Sun', mon: 'Mán', tue: 'Þri', wed: 'Mið', thu: 'Fim', fri: 'Fös', sat: 'Lau' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Maí', jun: 'Jún', jul: 'Júl', aug: 'Ágú', sep: 'Sep', oct: 'Okt', nov: 'Nóv', dec: 'Des' } }, select: { loading: 'Hleð', noMatch: 'Ekkert fannst', noData: 'Engin gögn', placeholder: 'Velja' }, cascader: { noMatch: 'Ekkert fannst', loading: 'Hleð', placeholder: 'Velja', noData: 'Engin gögn' }, pagination: { goto: 'Fara á', pagesize: '/sida', total: 'Samtals {total}', pageClassifier: '' }, messagebox: { title: 'Skilaboð', confirm: 'OK', cancel: 'Hætta við', error: 'Rangt innslegið' }, upload: { deleteTip: 'smelltu á eyða til að eyða', delete: 'Eyða', preview: 'Skoða', continue: 'Halda áfram' }, table: { emptyText: 'Engin gögn', confirmFilter: 'Staðfesta', resetFilter: 'Endurstilla', clearFilter: 'Allt', sumText: 'Summa' }, tree: { emptyText: 'Engin gögn' }, transfer: { noMatch: 'Engin gögn fundust', noData: 'Engin gögn', titles: ['Listi 1', 'Listi 2'], filterPlaceholder: 'Slá inn orð', noCheckedFormat: '{total} atriði', hasCheckedFormat: '{checked}/{total} valin' }, image: { error: 'VILLA' }, pageHeader: { title: 'Til baka' }, popconfirm: { confirmButtonText: 'Já', cancelButtonText: 'Nei' }, empty: { description: 'Engin gögn' } } }; ================================================ FILE: src/locale/lang/it.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Pulisci' }, datepicker: { now: 'Ora', today: 'Oggi', cancel: 'Cancella', clear: 'Pulisci', confirm: 'OK', selectDate: 'Seleziona data', selectTime: 'Seleziona ora', startDate: 'Data inizio', startTime: 'Ora inizio', endDate: 'Data fine', endTime: 'Ora fine', prevYear: 'Anno precedente', nextYear: 'Anno successivo', prevMonth: 'Mese precedente', nextMonth: 'Mese successivo', year: 'anno', month1: 'Gennaio', month2: 'Febbraio', month3: 'Marzo', month4: 'Aprile', month5: 'Maggio', month6: 'Giugno', month7: 'Luglio', month8: 'Agosto', month9: 'Settembre', month10: 'Ottobre', month11: 'Novembre', month12: 'Dicembre', // week: 'settimana', weeks: { sun: 'Dom', mon: 'Lun', tue: 'Mar', wed: 'Mer', thu: 'Gio', fri: 'Ven', sat: 'Sab' }, months: { jan: 'Gen', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Mag', jun: 'Giu', jul: 'Lug', aug: 'Ago', sep: 'Set', oct: 'Ott', nov: 'Nov', dec: 'Dic' } }, select: { loading: 'Caricamento', noMatch: 'Nessuna corrispondenza', noData: 'Nessun dato', placeholder: 'Seleziona' }, cascader: { noMatch: 'Nessuna corrispondenza', loading: 'Caricamento', placeholder: 'Seleziona', noData: 'Nessun dato' }, pagination: { goto: 'Vai a', pagesize: '/pagina', total: 'Totale {total}', pageClassifier: '' }, messagebox: { confirm: 'OK', cancel: 'Annulla', error: 'Input non valido' }, upload: { deleteTip: 'Premi cancella per rimuovere', delete: 'Cancella', preview: 'Anteprima', continue: 'Continua' }, table: { emptyText: 'Nessun dato', confirmFilter: 'Conferma', resetFilter: 'Reset', clearFilter: 'Tutti', sumText: 'Somma' }, tree: { emptyText: 'Nessun dato' }, transfer: { noMatch: 'Nessuna corrispondenza', noData: 'Nessun dato', titles: ['Lista 1', 'Lista 2'], filterPlaceholder: 'Inserisci filtro', noCheckedFormat: '{total} elementi', hasCheckedFormat: '{checked}/{total} selezionati' }, image: { error: 'ERRORE' }, pageHeader: { title: 'Indietro' }, popconfirm: { confirmButtonText: 'Sì', cancelButtonText: 'No' }, empty: { description: 'Nessun dato' } } }; ================================================ FILE: src/locale/lang/ja.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'クリア' }, datepicker: { now: '現在', today: '今日', cancel: 'キャンセル', clear: 'クリア', confirm: 'OK', selectDate: '日付を選択', selectTime: '時間を選択', startDate: '開始日', startTime: '開始時間', endDate: '終了日', endTime: '終了時間', prevYear: '前年', nextYear: '翌年', prevMonth: '前月', nextMonth: '翌月', year: '年', month1: '1月', month2: '2月', month3: '3月', month4: '4月', month5: '5月', month6: '6月', month7: '7月', month8: '8月', month9: '9月', month10: '10月', month11: '11月', month12: '12月', // week: '週次', weeks: { sun: '日', mon: '月', tue: '火', wed: '水', thu: '木', fri: '金', sat: '土' }, months: { jan: '1月', feb: '2月', mar: '3月', apr: '4月', may: '5月', jun: '6月', jul: '7月', aug: '8月', sep: '9月', oct: '10月', nov: '11月', dec: '12月' } }, select: { loading: 'ロード中', noMatch: 'データなし', noData: 'データなし', placeholder: '選択してください' }, cascader: { noMatch: 'データなし', loading: 'ロード中', placeholder: '選択してください', noData: 'データなし' }, pagination: { goto: '', pagesize: '件/ページ', total: '総計 {total} 件', pageClassifier: 'ページ目へ' }, messagebox: { title: 'メッセージ', confirm: 'OK', cancel: 'キャンセル', error: '正しくない入力' }, upload: { deleteTip: 'Delキーを押して削除する', delete: '削除する', preview: 'プレビュー', continue: '続行する' }, table: { emptyText: 'データなし', confirmFilter: '確認', resetFilter: '初期化', clearFilter: 'すべて', sumText: '合計' }, tree: { emptyText: 'データなし' }, transfer: { noMatch: 'データなし', noData: 'データなし', titles: ['リスト 1', 'リスト 2'], filterPlaceholder: 'キーワードを入力', noCheckedFormat: '総計 {total} 件', hasCheckedFormat: '{checked}/{total} を選択した' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'データなし' } } }; ================================================ FILE: src/locale/lang/kg.js ================================================ export default { el: { colorpicker: { confirm: 'Мурунку', clear: 'ачык' }, datepicker: { now: 'азыр', today: 'бүгүн', cancel: 'жокко чыгарылды', clear: 'ачык', confirm: 'белгилөө', selectDate: 'дата', selectTime: 'тандоо убактысы', startDate: 'Башталган датасы', startTime: 'Start убакыт', endDate: 'Бүткөн датасы', endTime: 'End убакыт', prevYear: 'өткөн жылы', nextYear: 'бир жылдан кийин', prevMonth: 'Өткөн айда', nextMonth: 'Кийинки ай', year: 'жыл', month1: 'биринчи ай', month2: 'Экинчи айда', month3: 'Үчүнчү айда', month4: 'Төртүнчү айда', month5: 'бешинчи айда', month6: 'Алгачкы алты ай', month7: 'жетинчи айда', month8: 'сегизинчи ай', month9: 'Алгачкы тогуз ай', month10: 'онунчу айда', month11: 'он биринчи ай', month12: 'он экинчи айда', // week: '周次', weeks: { sun: 'жети жума', mon: 'дүйшөмбү', tue: 'шейшемби', wed: 'шаршемби', thu: 'бейшемби', fri: 'жума', sat: 'ишемби' }, months: { jan: 'биринчи ай', feb: 'Экинчи айда', mar: 'Үчүнчү айда', apr: 'Төртүнчү айда', may: 'бешинчи айда', jun: 'Алгачкы алты ай', jul: 'жетинчи айда', aug: 'сегизинчи ай', sep: 'Алгачкы тогуз ай', oct: 'онунчу айда', nov: 'он биринчи ай', dec: 'он экинчи айда' } }, select: { loading: 'Жүктөлүүдө', noMatch: 'Дал келген маалыматтар', noData: 'маалымат жок', placeholder: 'тандоо' }, cascader: { noMatch: 'Дал келген маалыматтар', loading: 'Жүктөлүүдө', placeholder: 'тандоо', noData: 'маалымат жок' }, pagination: { goto: 'Мурунку', pagesize: 'бир', total: 'бүтүндөй {total} сан ', pageClassifier: 'бет' }, messagebox: { title: 'тез', confirm: 'белгилөө', cancel: 'жокко чыгарылды', error: 'Маалыматтарды киргизүү мыйзамдуу эмес!' }, upload: { deleteTip: 'Жок кылуу баскычын басуу жок', delete: 'жок кылуу', preview: 'ЖМКнын картинки', continue: 'жүктөп бер' }, table: { emptyText: 'маалымат жок', confirmFilter: 'чыпка', resetFilter: 'кайра орнотуу', clearFilter: 'бүткөн', sumText: 'Бардыгы болуп' }, tree: { emptyText: 'маалымат жок' }, transfer: { noMatch: 'Дал келген маалыматтар', noData: 'маалымат жок', titles: ['1 тизмеси', '2 тизмеси'], filterPlaceholder: 'Сураныч, издөө кирет', noCheckedFormat: 'бүтүндөй {total} сан', hasCheckedFormat: 'Тандалган {checked}/{total} сан' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'маалымат жок' } } }; ================================================ FILE: src/locale/lang/km.js ================================================ export default { el: { colorpicker: { confirm: 'យល់ព្រម', clear: 'លុប' }, datepicker: { now: 'ឥឡូវនេះ', today: 'ថ្ងៃនេះ', cancel: 'បោះបង់', clear: 'លុប', confirm: 'យល់ព្រម', selectDate: 'ជ្រើសរើសថ្ងៃ', selectTime: 'ជ្រើសរើសម៉ោង', startDate: 'ថ្ងៃចាប់ផ្តើម', startTime: 'ម៉ោងចាប់ផ្តើម', endDate: 'ថ្ងៃបញ្ចប់', endTime: 'ម៉ោងបញ្ចប់', prevYear: 'ឆ្នាំមុន', nextYear: 'ឆ្នាំក្រោយ', prevMonth: 'ខែមុន', nextMonth: 'ខែក្រោយ', year: 'ឆ្នាំ', month1: 'មករា', month2: 'កុម្ភៈ', month3: 'មីនា', month4: 'មេសា', month5: 'ឧសភា', month6: 'មិថុនា', month7: 'កក្កដា', month8: 'សីហា', month9: 'កញ្ញា', month10: 'តុលា', month11: 'វិច្ឆកា', month12: 'ធ្នូ', week: 'សប្តាហ៍', weeks: { sun: 'អាទិត្យ', mon: 'ច័ន្ទ', tue: 'អង្គារ', wed: 'ពុធ', thu: 'ព្រ.ហ', fri: 'សុក្រ', sat: 'សៅរ៏' }, months: { jan: 'មករា', feb: 'កុម្ភៈ', mar: 'មីនា', apr: 'មេសា', may: 'ឧសភា', jun: 'មិថុនា', jul: 'កក្កដា', aug: 'សីហា', sep: 'កញ្ញា', oct: 'តុលា', nov: 'វិច្ឆកា', dec: 'ធ្នូ' } }, select: { loading: 'កំពុងផ្ទុក', noMatch: 'គ្មានទិន្ន័យដូច', noData: 'គ្មានទិន្ន័យ', placeholder: 'ជ្រើសរើស' }, cascader: { noMatch: 'គ្មានទិន្ន័យដូច', loading: 'កំពុងផ្ទុក', placeholder: 'ជ្រើសរើស', noData: 'គ្មានទិន្ន័យ' }, pagination: { goto: 'ទៅកាន់', pagesize: '/ទំព័រ', total: 'សរុប {total}', pageClassifier: '' }, messagebox: { title: 'សារ', confirm: 'យល់ព្រម', cancel: 'បោះបង់', error: 'ការបញ្ចូលមិនអនុញ្ញាត' }, upload: { deleteTip: 'ចុចលុបដើម្បីដកចេញ', delete: 'លុប', preview: 'មើល', continue: 'បន្ត' }, table: { emptyText: 'គ្មានទិន្ន័យ', confirmFilter: 'យល់ព្រម', resetFilter: 'កំណត់ឡើងវិញ', clearFilter: 'ទាំងអស់', sumText: 'បូក' }, tree: { emptyText: 'គ្មានទិន្ន័យ' }, transfer: { noMatch: 'គ្មានទិន្ន័យដូច', noData: 'គ្មានទិន្ន័យ', titles: ['បញ្ជី ១', 'បញ្ជី ២'], filterPlaceholder: 'បញ្ចូលពាក្យ', noCheckedFormat: '{total} ធាតុ', hasCheckedFormat: '{checked}/{total} បានគូសធីក' }, image: { error: 'បរាជ័យ' }, pageHeader: { title: 'Back' }, popconfirm: { confirmButtonText: 'ព្រម', cancelButtonText: 'មិនព្រម' }, empty: { description: 'គ្មានទិន្ន័យ' } } }; ================================================ FILE: src/locale/lang/ko.js ================================================ export default { el: { colorpicker: { confirm: '확인', clear: '초기화' }, datepicker: { now: '지금', today: '오늘', cancel: '취소', clear: '초기화', confirm: '확인', selectDate: '날짜 선택', selectTime: '시간 선택', startDate: '시작 날짜', startTime: '시작 시간', endDate: '종료 날짜', endTime: '종료 시간', prevYear: '지난해', nextYear: '다음해', prevMonth: '지난달', nextMonth: '다음달', year: '년', month1: '1월', month2: '2월', month3: '3월', month4: '4월', month5: '5월', month6: '6월', month7: '7월', month8: '8월', month9: '9월', month10: '10월', month11: '11월', month12: '12월', // week: 'week', weeks: { sun: '일', mon: '월', tue: '화', wed: '수', thu: '목', fri: '금', sat: '토' }, months: { jan: '1월', feb: '2월', mar: '3월', apr: '4월', may: '5월', jun: '6월', jul: '7월', aug: '8월', sep: '9월', oct: '10월', nov: '11월', dec: '12월' } }, select: { loading: '불러오는 중', noMatch: '맞는 데이터가 없습니다', noData: '데이터 없음', placeholder: '선택' }, cascader: { noMatch: '맞는 데이터가 없습니다', loading: '불러오는 중', placeholder: '선택', noData: '데이터 없음' }, pagination: { goto: '이동', pagesize: '/page', total: '총 {total}', pageClassifier: '' }, messagebox: { title: '메시지', confirm: '확인', cancel: '취소', error: '올바르지 않은 입력' }, upload: { deleteTip: '클릭시 삭제됩니다', delete: '삭제', preview: '미리보기', continue: '계속하기' }, table: { emptyText: '데이터 없음', confirmFilter: '확인', resetFilter: '초기화', clearFilter: '전체', sumText: '합' }, tree: { emptyText: '데이터 없음' }, transfer: { noMatch: '맞는 데이터가 없습니다', noData: '데이터 없음', titles: ['리스트 1', '리스트 2'], filterPlaceholder: ' 입력하세요', noCheckedFormat: '{total} 항목', hasCheckedFormat: '{checked}/{total} 선택됨' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: '데이터 없음' } } }; ================================================ FILE: src/locale/lang/ku.js ================================================ export default { el: { colorpicker: { confirm: 'Temam', clear: 'Paqij bike' }, datepicker: { now: 'Niha', today: 'Îro', cancel: 'Betal bike', clear: 'Paqij bike', confirm: 'Temam', selectDate: 'Dîrokê bibijêre', selectTime: 'Demê bibijêre', startDate: 'Dîroka Destpêkê', startTime: 'Dema Destpêkê', endDate: 'Dîroka Dawî', endTime: 'Dema Dawî', prevYear: 'Sala Pêş', nextYear: 'Sala Paş', prevMonth: 'Meha Pêş', nextMonth: 'Meha Paş', year: 'Sal', month1: 'Rêbendan', month2: 'Reşemeh', month3: 'Adar', month4: 'Avrêl', month5: 'Gulan', month6: 'Pûşber', month7: 'Tîrmeh', month8: 'Gilavêj', month9: 'Rezber', month10: 'Kewçêr', month11: 'Sarmawaz', month12: 'Berfanbar', // week: 'week', weeks: { sun: 'Yek', mon: 'Duş', tue: 'Sêş', wed: 'Çar', thu: 'Pên', fri: 'În', sat: 'Şem' }, months: { jan: 'Rêb', feb: 'Reş', mar: 'Ada', apr: 'Avr', may: 'Gul', jun: 'Pûş', jul: 'Tîr', aug: 'Gil', sep: 'Rez', oct: 'Kew', nov: 'Sar', dec: 'Ber' } }, select: { loading: 'Bardibe', noMatch: 'Li hembere ve agahî tune', noData: 'Agahî tune', placeholder: 'Bibijêre' }, cascader: { noMatch: 'Li hembere ve agahî tune', loading: 'Bardibe', placeholder: 'Bibijêre', noData: 'Agahî tune' }, pagination: { goto: 'Biçe', pagesize: '/rupel', total: 'Tevahî {total}', pageClassifier: '' }, messagebox: { title: 'Peyam', confirm: 'Temam', cancel: 'Betal bike', error: 'Beyana çewt' }, upload: { deleteTip: 'ji bo rake pêl "delete" bike', delete: 'Rake', preview: 'Pêşdîtin', continue: 'Berdewam' }, table: { emptyText: 'Agahî tune', confirmFilter: 'Piştrast bike', resetFilter: 'Jê bibe', clearFilter: 'Hemû', sumText: 'Kom' }, tree: { emptyText: 'Agahî tune' }, transfer: { noMatch: 'Li hembere ve agahî tune', noData: 'Agahî tune', titles: ['Lîste 1', 'Lîste 2'], filterPlaceholder: 'Binivîse', noCheckedFormat: '{total} lib', hasCheckedFormat: '{checked}/{total} bijartin' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Agahî tune' } } }; ================================================ FILE: src/locale/lang/kz.js ================================================ export default { el: { colorpicker: { confirm: 'Қабылдау', clear: 'Тазалау' }, datepicker: { now: 'Қазір', today: 'Бүгін', cancel: 'Болдырмау', clear: 'Тазалау', confirm: 'Қабылдау', selectDate: 'Күнді таңдаңыз', selectTime: 'Сағатты таңдаңыз', startDate: 'Басталу күні', startTime: 'Басталу сағаты', endDate: 'Аяқталу күні', endTime: 'Аяқталу сағаты', prevYear: 'Алдыңғы жыл', nextYear: 'Келесі жыл', prevMonth: 'Алдыңғы ай', nextMonth: 'Келесі ай', year: 'Жыл', month1: 'Қаңтар', month2: 'Ақпан', month3: 'Наурыз', month4: 'Сәуір', month5: 'Мамыр', month6: 'Маусым', month7: 'Шілде', month8: 'Тамыз', month9: 'Қыркүйек', month10: 'Қазан', month11: 'Қараша', month12: 'Желтоқсан', week: 'Апта', weeks: { sun: 'Жек', mon: 'Дүй', tue: 'Сей', wed: 'Сәр', thu: 'Бей', fri: 'Жұм', sat: 'Сен' }, months: { jan: 'Қаң', feb: 'Ақп', mar: 'Нау', apr: 'Сәу', may: 'Мам', jun: 'Мау', jul: 'Шіл', aug: 'Там', sep: 'Қыр', oct: 'Қаз', nov: 'Қар', dec: 'Жел' } }, select: { loading: 'Жүктелуде', noMatch: 'Сәйкес деректер жоқ', noData: 'Деректер жоқ', placeholder: 'Таңдаңыз' }, cascader: { noMatch: 'Сәйкес деректер жоқ', loading: 'Жүктелуде', placeholder: 'Таңдаңыз', noData: 'Деректер жоқ' }, pagination: { goto: 'Бару', pagesize: '/page', total: 'Барлығы {total}', pageClassifier: '' }, messagebox: { title: 'Хабар', confirm: 'Қабылдау', cancel: 'Болдырмау', error: 'Жарамсыз енгізулер' }, upload: { deleteTip: 'Өшіруді басып өшіріңіз', delete: 'Өшіру', preview: 'Алдын ала қарау', continue: 'Жалғастыру' }, table: { emptyText: 'Деректер жоқ', confirmFilter: 'Қабылдау', resetFilter: 'Қалпына келтіру', clearFilter: 'Барлығы', sumText: 'Сомасы' }, tree: { emptyText: 'Деректер жоқ' }, transfer: { noMatch: 'Сәйкес деректер жоқ', noData: 'Деректер жоқ', titles: ['List 1', 'List 2'], filterPlaceholder: 'Кілт сөзді енгізіңіз', noCheckedFormat: '{total} элэмэнт', hasCheckedFormat: '{checked}/{total} құсбелгісі қойылды' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Деректер жоқ' } } }; ================================================ FILE: src/locale/lang/lo-LA.js ================================================ 'use strict'; exports.__esModule = true; exports.default = { el: { colorpicker: { confirm: 'ຢືນຢັນ', clear: 'ເປົ່າ' }, datepicker: { now: 'ດຽວນີ້', today: 'ມື້ນີ້', cancel: 'ຍົກເລີກ', clear: 'ເປົ່າ', confirm: 'ຢືນຢັນ', selectDate: 'ເລືອກ ວັນທີ', selectTime: 'ເລືອກ ເວລາ', startDate: 'ວັນ​ທີ່​ເລີ່ມ', startTime: 'ເວລາເລີ່ມຕົ້ນ', endDate: 'ວັນສິ້ນສຸດ', endTime: 'ສິ້ນສຸດເວລາ', prevYear: 'ປີກ່ອນ', nextYear: 'ປີ ຕໍ່ມາ', prevMonth: 'ເດືອນກ່ອນ', nextMonth: 'ເດືອນ ຖັດ ໄປ', year: 'ປີ', month1: 'ມັງກອນ', month2: 'ເດືອນ ກຸມພາ', month3: 'ເດືອນມີນາ', month4: 'ເດືອນເມສາ', month5: 'ເດືອນພຶດສະພາ', month6: 'ມິຖຸນາ', month7: 'ເດືອນກໍລະກົດ', month8: 'ເດືອນ ສິງຫາ', month9: 'ເດືອນ ກັນຍາ', month10: 'ເດືອນ ຕຸລາ', month11: 'ເດືອນພະຈິກ', month12: 'ທັນວາ', // week: '周次', weeks: { sun: 'ວັນ', mon: 'ກ', tue: 'ສອງ', wed: 'ສາມ', thu: 'ສີ່', fri: 'ຫ້າ', sat: 'ຫົກ' }, months: { jan: 'ມັງກອນ', feb: 'ເດືອນ ກຸມພາ', mar: 'ເດືອນມີນາ', apr: 'ເດືອນເມສາ', may: 'ເດືອນພຶດສະພາ', jun: 'ມິຖຸນາ', jul: 'ເດືອນກໍລະກົດ', aug: 'ເດືອນ ສິງຫາ', sep: 'ເດືອນ ກັນຍາ', oct: 'ເດືອນ ຕຸລາ', nov: 'ເດືອນພະຈິກ', dec: 'ທັນວາ' } }, select: { loading: 'ກຳລັງອອກ...', noMatch: 'ບໍ່ມີຂໍ້ມູນທີ່ກົງກັນ', noData: 'ບໍ່​ມີ​ຂໍ້​ມູນ', placeholder: 'ກະລຸນາເລືອກ' }, cascader: { noMatch: 'ບໍ່ມີຂໍ້ມູນທີ່ກົງກັນ', loading: 'ກຳລັງອອກ...', placeholder: 'ກະລຸນາເລືອກ', noData: 'ບໍ່​ມີ​ຂໍ້​ມູນ' }, pagination: { goto: 'ໄປທີ່', pagesize: 'ແຖບ/ໜ້າ', total: 'ປົກຕ່າງໆ {total} ກະລຸນາປັດ', pageClassifier: 'ຫມາຍເລກຫນ້າ' }, messagebox: { title: 'ຄຳ ແນະ ນຳ', confirm: 'ຢືນຢັນ', cancel: 'ຍົກເລີກ', error: 'ຂໍ້ມູນການປ້ອນຂໍ້ມູນແມ່ນຜິດກົດຫມາຍ!' }, upload: { deleteTip: 'ກະລຸນາໃສເພື່ອລຶບ', delete: 'ລຶບ', preview: 'ເບິ່ງຮູບພາບ', continue: 'ສືບຕໍ່ອັບໂຫລດ' }, table: { emptyText: 'ບໍ່​ມີ​ຂໍ້​ມູນ', confirmFilter: 'ການ ຄັດເລືອກ', resetFilter: 'ເລີ່ມ​ຕົ້ນ​ໃຫມ່', clearFilter: 'ທັງຫມົດ', sumText: 'ທັງຫມົດ' }, tree: { emptyText: 'ບໍ່​ມີ​ຂໍ້​ມູນ' }, transfer: { noMatch: 'ບໍ່ມີຂໍ້ມູນທີ່ກົງກັນ', noData: 'ບໍ່​ມີ​ຂໍ້​ມູນ', titles: ['ລາຍຊື່ 1', 'ລາຍຊື່ 2'], filterPlaceholder: 'ໃສ່ເນື້ອຫາຄົ້ນຫາ', noCheckedFormat: 'ປົກຕ່າງໆ {total} ຄໍາສຸດ', hasCheckedFormat: 'ໂຕເລືອກ {checked}/{total} ຄໍາສຸດ' }, image: { error: 'ລົ້ມເຫລວໃນການໂຫຼດ' }, pageHeader: { title: 'ກັບ ຄືນ' }, popconfirm: { confirmButtonText: 'ຢືນຢັນ', cancelButtonText: 'ຍົກເລີກ' }, empty: { description: 'ບໍ່​ມີ​ຂໍ້​ມູນ' } } }; ================================================ FILE: src/locale/lang/lt.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Valyti' }, datepicker: { now: 'Dabar', today: 'Šiandien', cancel: 'Atšaukti', clear: 'Valyti', confirm: 'OK', selectDate: 'Pasirink datą', selectTime: 'Pasirink laiką', startDate: 'Data nuo', startTime: 'Laikas nuo', endDate: 'Data iki', endTime: 'Laikas iki', prevYear: 'Metai atgal', nextYear: 'Metai į priekį', prevMonth: 'Mėn. atgal', nextMonth: 'Mėn. į priekį', year: '', month1: 'Sausis', month2: 'Vasaris', month3: 'Kovas', month4: 'Balandis', month5: 'Gegužė', month6: 'Birželis', month7: 'Liepa', month8: 'Rugpjūtis', month9: 'Rugsėjis', month10: 'Spalis', month11: 'Lapkritis', month12: 'Gruodis', // week: 'savaitė', weeks: { sun: 'S.', mon: 'Pr.', tue: 'A.', wed: 'T.', thu: 'K.', fri: 'Pn.', sat: 'Š.' }, months: { jan: 'Sau', feb: 'Vas', mar: 'Kov', apr: 'Bal', may: 'Geg', jun: 'Bir', jul: 'Lie', aug: 'Rugp', sep: 'Rugs', oct: 'Spa', nov: 'Lap', dec: 'Gruo' } }, select: { loading: 'Kraunasi', noMatch: 'Duomenų nerasta', noData: 'Nėra duomenų', placeholder: 'Pasirink' }, cascader: { noMatch: 'Duomenų nerasta', loading: 'Kraunasi', placeholder: 'Pasirink', noData: 'Nėra duomenų' }, pagination: { goto: 'Eiti į', pagesize: '/p', total: 'Viso {total}', pageClassifier: '' }, messagebox: { title: 'Žinutė', confirm: 'OK', cancel: 'Atšaukti', error: 'Klaida įvestuose duomenyse' }, upload: { deleteTip: 'spauskite "Trinti" norėdami pašalinti', delete: 'Trinti', preview: 'Peržiūrėti', continue: 'Toliau' }, table: { emptyText: 'Duomenų nerasta', confirmFilter: 'Patvirtinti', resetFilter: 'Atstatyti', clearFilter: 'Išvalyti', sumText: 'Suma' }, tree: { emptyText: 'Nėra duomenų' }, transfer: { noMatch: 'Duomenų nerasta', noData: 'Nėra duomenų', titles: ['Sąrašas 1', 'Sąrašas 2'], filterPlaceholder: 'Įvesk raktažodį', noCheckedFormat: 'Viso: {total}', hasCheckedFormat: 'Pažymėta {checked} iš {total}' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Duomenų nerasta' } } }; ================================================ FILE: src/locale/lang/lv.js ================================================ export default { el: { colorpicker: { confirm: 'Labi', clear: 'Notīrīt' }, datepicker: { now: 'Tagad', today: 'Šodien', cancel: 'Atcelt', clear: 'Notīrīt', confirm: 'Labi', selectDate: 'Izvēlēties datumu', selectTime: 'Izvēlēties laiku', startDate: 'Sākuma datums', startTime: 'Sākuma laiks', endDate: 'Beigu datums', endTime: 'Beigu laiks', prevYear: 'Iepriekšējais gads', nextYear: 'Nākamais gads', prevMonth: 'Iepriekšējais mēnesis', nextMonth: 'Nākamais mēnesis', year: '', month1: 'Janvāris', month2: 'Februāris', month3: 'Marts', month4: 'Aprīlis', month5: 'Maijs', month6: 'Jūnijs', month7: 'Jūlijs', month8: 'Augusts', month9: 'Septembris', month10: 'Oktobris', month11: 'Novembris', month12: 'Decembris', // week: 'nedēļa', weeks: { sun: 'Sv', mon: 'Pr', tue: 'Ot', wed: 'Tr', thu: 'Ce', fri: 'Pk', sat: 'Se' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Mai', jun: 'Jūn', jul: 'Jūl', aug: 'Aug', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Ielādē', noMatch: 'Nav atbilstošu datu', noData: 'Nav datu', placeholder: 'Izvēlēties' }, cascader: { noMatch: 'Nav atbilstošu datu', loading: 'Ielādē', placeholder: 'Izvēlēties', noData: 'Nav datu' }, pagination: { goto: 'Iet uz', pagesize: '/lapa', total: 'Kopā {total}', pageClassifier: '' }, messagebox: { title: 'Paziņojums', confirm: 'Labi', cancel: 'Atcelt', error: 'Nederīga ievade' }, upload: { deleteTip: 'Nospiediet dzēst lai izņemtu', delete: 'Dzēst', preview: 'Priekšskatīt', continue: 'Turpināt' }, table: { emptyText: 'Nav datu', confirmFilter: 'Apstiprināt', resetFilter: 'Atiestatīt', clearFilter: 'Visi', sumText: 'Summa' }, tree: { emptyText: 'Nav datu' }, transfer: { noMatch: 'Nav atbilstošu datu', noData: 'Nav datu', titles: ['Saraksts 1', 'Saraksts 2'], filterPlaceholder: 'Ievadīt atslēgvārdu', noCheckedFormat: '{total} vienības', hasCheckedFormat: '{checked}/{total} atzīmēti' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Nav datu' } } }; ================================================ FILE: src/locale/lang/mn.js ================================================ export default { el: { colorpicker: { confirm: 'Тийм', clear: 'Цэвэрлэх' }, datepicker: { now: 'Одоо', today: 'Өнөөдөр', cancel: 'Болих', clear: 'Цэвэрлэх', confirm: 'Тийм', selectDate: 'Огноог сонго', selectTime: 'Цагийг сонго', startDate: 'Эхлэх огноо', startTime: 'Эхлэх цаг', endDate: 'Дуусах огноо', endTime: 'Дуусах цаг', prevYear: 'Өмнөх жил', nextYear: 'Дараа жил', prevMonth: 'Өмнөх сар', nextMonth: 'Дараа сар', year: 'он', month1: '1 сар', month2: '2 сар', month3: '3 сар', month4: '4 сар', month5: '5 сар', month6: '6 сар', month7: '7 сар', month8: '8 сар', month9: '9 сар', month10: '10 сар', month11: '11 сар', month12: '12 сар', week: 'Долоо хоног', weeks: { sun: 'Ням', mon: 'Дав', tue: 'Мяг', wed: 'Лха', thu: 'Пүр', fri: 'Баа', sat: 'Бям' }, months: { jan: '1 сар', feb: '2 сар', mar: '3 сар', apr: '4 сар', may: '5 сар', jun: '6 сар', jul: '7 сар', aug: '8 сар', sep: '9 сар', oct: '10 сар', nov: '11 сар', dec: '12 сар' } }, select: { loading: 'Ачаалж байна', noMatch: 'Тохирох өгөгдөл байхгүй', noData: 'Өгөгдөл байхгүй', placeholder: 'Сонгох' }, cascader: { noMatch: 'Тохирох өгөгдөл байхгүй', loading: 'Ачаалж байна', placeholder: 'Сонгох', noData: 'Өгөгдөл байхгүй' }, pagination: { goto: 'Очих', pagesize: '/хуудас', total: 'Нийт {total}', pageClassifier: '' }, messagebox: { title: 'Зурвас', confirm: 'Тийм', cancel: 'Болих', error: 'Буруу утга' }, upload: { deleteTip: 'Устгахын дарж арилга', delete: 'Устгах', preview: 'Өмнөх', continue: 'Үргэлжлүүлэх' }, table: { emptyText: 'Өгөгдөл байхгүй', confirmFilter: 'Зөвшөөрөх', resetFilter: 'Цэвэрлэх', clearFilter: 'Бүгд', sumText: 'Нийт' }, tree: { emptyText: 'Өгөгдөл байхгүй' }, transfer: { noMatch: 'Тохирох өгөгдөл байхгүй', noData: 'Өгөгдөл байхгүй', titles: ['Жагсаалт 1', 'Жагсаалт 2'], filterPlaceholder: 'Утга оруул', noCheckedFormat: '{total} өгөгдөл', hasCheckedFormat: '{checked}/{total} сонгосон' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Өгөгдөл байхгүй' } } }; ================================================ FILE: src/locale/lang/ms.js ================================================ export default { el: { colorpicker: { confirm: 'Sah', clear: 'Padam' }, datepicker: { now: 'Sekarang', today: 'Hari ini', cancel: 'Batal', clear: 'Padam', confirm: 'Sah', selectDate: 'Pilih Tarikh', selectTime: 'Pilih Masa', startDate: 'Tarikh Mula', startTime: 'Masa Mula', endDate: 'Tarikh Tamat', endTime: 'Masa Tamat', prevYear: 'Tahun Lepas', nextYear: 'Tahun Depan', prevMonth: 'Bulan Lepas', nextMonth: 'Bulan Depan', year: 'Tahun', month1: 'Januari', month2: 'Febuari', month3: 'Mac', month4: 'April', month5: 'Mei', month6: 'Jun', month7: 'Julai', month8: 'Ogos', month9: 'September', month10: 'Oktober', month11: 'November', month12: 'Disember', weeks: { sun: 'Ahad', mon: 'Isnin', tue: 'Selasa', wed: 'Rabu', thu: 'Khamis', fri: 'Jumaat', sat: 'Sabtu' }, months: { jan: 'Januari', feb: 'Febuari', mar: 'Mac', apr: 'April', may: 'Mei', jun: 'Jun', jul: 'Julai', aug: 'Ogos', sep: 'September', oct: 'Oktober', nov: 'November', dec: 'Disember' } }, select: { loading: 'Sedang dimuat turun', noMatch: 'Tiada maklumat yang sepadan', noData: 'Tiada maklumat', placeholder: 'Sila pilih' }, cascader: { noMatch: 'Tiada maklumat yang sepadan', loading: 'Sedang dimuat turun', placeholder: 'Sila pilih', noData: 'Tiada maklumat' }, pagination: { goto: 'Seterusnya', pagesize: 'x/Halaman', total: 'Jumlah {total} ', pageClassifier: 'Halaman' }, messagebox: { title: 'Tip', confirm: 'Sah', cancel: 'Batal', error: 'Data yang diisi tidak sah!' }, upload: { deleteTip: 'Tekan "Padam" untuk memadam', delete: 'Padam', preview: 'Pratonton gambar', continue: 'Meneruskan muat naik' }, table: { emptyText: 'Tiada maklumat', confirmFilter: 'Tapis', resetFilter: 'Set Semula', clearFilter: 'Semua', sumText: 'Jumlah' }, tree: { emptyText: 'Tiada maklumat' }, transfer: { noMatch: 'Tiada maklumat yang sepadan', noData: 'Tiada maklumat', titles: ['Senarai 1', 'Senarai 2'], filterPlaceholder: 'Masukkan kandungan carian', noCheckedFormat: 'Jumlah {total} item', hasCheckedFormat: 'Telah memilih {checked}/{total} item' }, image: { error: 'Muat turun gagal' }, pageHeader: { title: 'Kembali' }, popconfirm: { confirmButtonText: 'Sah', cancelButtonText: 'Batal' }, empty: { description: 'Tiada maklumat' } } }; ================================================ FILE: src/locale/lang/nb-NO.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Tøm' }, datepicker: { now: 'Nå', today: 'I dag', cancel: 'Avbryt', clear: 'Tøm', confirm: 'OK', selectDate: 'Velg dato', selectTime: 'Velg tidspunkt', startDate: 'Start Dato', startTime: 'Start Tidspunkt', endDate: 'Sluttdato', endTime: 'Sluttidspunkt', prevYear: 'Forrige År', nextYear: 'Neste År', prevMonth: 'Forrige Måned', nextMonth: 'Neste Måned', year: '', month1: 'Januar', month2: 'Februar', month3: 'Mars', month4: 'April', month5: 'Mai', month6: 'Juni', month7: 'Juli', month8: 'August', month9: 'September', month10: 'Oktober', month11: 'November', month12: 'Desember', // week: 'week', weeks: { sun: 'Søn', mon: 'Man', tue: 'Tir', wed: 'Ons', thu: 'Tor', fri: 'Fre', sat: 'Lør' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Mai', jun: 'Jun', jul: 'Jul', aug: 'Aug', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Des' } }, select: { loading: 'Laster', noMatch: 'Ingen samsvarende data', noData: 'Ingen data', placeholder: 'Velg' }, cascader: { noMatch: 'Ingen samsvarende data', loading: 'Laster', placeholder: 'Velg', noData: 'Ingen data' }, pagination: { goto: 'Gå til', pagesize: '/side', total: 'Total {total}', pageClassifier: '' }, messagebox: { confirm: 'OK', cancel: 'Avbryt', error: 'Ugyldig input' }, upload: { deleteTip: 'trykk slett for å ta bort', delete: 'Slett', preview: 'Forhåndsvisning', continue: 'Fortsett' }, table: { emptyText: 'Ingen Data', confirmFilter: 'Bekreft', resetFilter: 'Tilbakestill', clearFilter: 'Alle', sumText: 'Sum' }, tree: { emptyText: 'Ingen Data' }, transfer: { noMatch: 'Ingen samsvarende data', noData: 'Ingen data', titles: ['Liste 1', 'Liste 2'], filterPlaceholder: 'Tast inn nøkkelord', noCheckedFormat: '{total} gjenstander', hasCheckedFormat: '{checked}/{total} sjekket' }, image: { error: 'MISLYKTES' }, pageHeader: { title: 'Tilbake' }, popconfirm: { confirmButtonText: 'Ja', cancelButtonText: 'Nei' }, empty: { description: 'Ingen Data' } } }; ================================================ FILE: src/locale/lang/nl.js ================================================ export default { el: { colorpicker: { confirm: 'Bevestig', clear: 'Wissen' }, datepicker: { now: 'Nu', today: 'Vandaag', cancel: 'Annuleren', clear: 'Legen', confirm: 'Bevestig', selectDate: 'Selecteer datum', selectTime: 'Selecteer tijd', startDate: 'Startdatum', startTime: 'Starttijd', endDate: 'Einddatum', endTime: 'Eindtijd', prevYear: 'Vorig jaar', nextYear: 'Volgend jaar', prevMonth: 'Vorige maand', nextMonth: 'Volgende maand', year: '', month1: 'januari', month2: 'februari', month3: 'maart', month4: 'april', month5: 'mei', month6: 'juni', month7: 'juli', month8: 'augustus', month9: 'september', month10: 'oktober', month11: 'november', month12: 'december', // week: 'week', weeks: { sun: 'Zo', mon: 'Ma', tue: 'Di', wed: 'Wo', thu: 'Do', fri: 'Vr', sat: 'Za' }, months: { jan: 'jan', feb: 'feb', mar: 'maa', apr: 'apr', may: 'mei', jun: 'jun', jul: 'jul', aug: 'aug', sep: 'sep', oct: 'okt', nov: 'nov', dec: 'dec' } }, select: { loading: 'Laden', noMatch: 'Geen overeenkomende resultaten', noData: 'Geen data', placeholder: 'Selecteer' }, cascader: { noMatch: 'Geen overeenkomende resultaten', loading: 'Laden', placeholder: 'Selecteer', noData: 'Geen data' }, pagination: { goto: 'Ga naar', pagesize: '/pagina', total: 'Totaal {total}', pageClassifier: '' }, messagebox: { title: 'Bericht', confirm: 'Bevestig', cancel: 'Annuleren', error: 'Ongeldige invoer' }, upload: { deleteTip: 'Kies verwijder om te wissen', delete: 'Verwijder', preview: 'Voorbeeld', continue: 'Doorgaan' }, table: { emptyText: 'Geen data', confirmFilter: 'Bevestigen', resetFilter: 'Reset', clearFilter: 'Alles', sumText: 'Som' }, tree: { emptyText: 'Geen data' }, transfer: { noMatch: 'Geen overeenkomende resultaten', noData: 'Geen data', titles: ['Lijst 1', 'Lijst 2'], filterPlaceholder: 'Geef zoekwoerd', noCheckedFormat: '{total} items', hasCheckedFormat: '{checked}/{total} geselecteerd' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Geen data' } } }; ================================================ FILE: src/locale/lang/pl.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Wyczyść' }, datepicker: { now: 'Teraz', today: 'Dzisiaj', cancel: 'Anuluj', clear: 'Wyczyść', confirm: 'OK', selectDate: 'Wybierz datę', selectTime: 'Wybierz godzinę', startDate: 'Data początkowa', startTime: 'Godzina początkowa', endDate: 'Data końcowa', endTime: 'Czas końcowa', prevYear: 'Poprzedni rok', nextYear: 'Następny rok', prevMonth: 'Poprzedni miesiąc', nextMonth: 'Następny miesiąc', year: 'rok', month1: 'styczeń', month2: 'luty', month3: 'marzec', month4: 'kwiecień', month5: 'maj', month6: 'czerwiec', month7: 'lipiec', month8: 'sierpień', month9: 'wrzesień', month10: 'październik', month11: 'listopad', month12: 'grudzień', week: 'tydzień', weeks: { sun: 'niedz.', mon: 'pon.', tue: 'wt.', wed: 'śr.', thu: 'czw.', fri: 'pt.', sat: 'sob.' }, months: { jan: 'STY', feb: 'LUT', mar: 'MAR', apr: 'KWI', may: 'MAJ', jun: 'CZE', jul: 'LIP', aug: 'SIE', sep: 'WRZ', oct: 'PAŹ', nov: 'LIS', dec: 'GRU' } }, select: { loading: 'Ładowanie', noMatch: 'Brak dopasowań', noData: 'Brak danych', placeholder: 'Wybierz' }, cascader: { noMatch: 'Brak dopasowań', loading: 'Ładowanie', placeholder: 'Wybierz', noData: 'Brak danych' }, pagination: { goto: 'Idź do', pagesize: '/strona', total: 'Wszystkich {total}', pageClassifier: '' }, messagebox: { title: 'Wiadomość', confirm: 'OK', cancel: 'Anuluj', error: 'Wiadomość zawiera niedozwolone znaki' }, upload: { deleteTip: 'kliknij kasuj aby usunąć', delete: 'Kasuj', preview: 'Podgląd', continue: 'Kontynuuj' }, table: { emptyText: 'Brak danych', confirmFilter: 'Potwierdź', resetFilter: 'Resetuj', clearFilter: 'Wszystko', sumText: 'Razem' }, tree: { emptyText: 'Brak danych' }, transfer: { noMatch: 'Brak dopasowań', noData: 'Brak danych', titles: ['Lista 1', 'Lista 2'], filterPlaceholder: 'Wpisz szukaną frazę', noCheckedFormat: 'razem: {total}', hasCheckedFormat: 'wybranych: {checked}/{total}' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Brak danych' } } }; ================================================ FILE: src/locale/lang/pt-br.js ================================================ export default { el: { colorpicker: { confirm: 'Confirmar', clear: 'Limpar' }, datepicker: { now: 'Agora', today: 'Hoje', cancel: 'Cancelar', clear: 'Limpar', confirm: 'Confirmar', selectDate: 'Selecione a data', selectTime: 'Selecione a hora', startDate: 'Data inicial', startTime: 'Hora inicial', endDate: 'Data final', endTime: 'Hora final', prevYear: 'Ano anterior', nextYear: 'Próximo ano', prevMonth: 'Mês anterior', nextMonth: 'Próximo mês', year: '', month1: 'Janeiro', month2: 'Fevereiro', month3: 'Março', month4: 'Abril', month5: 'Maio', month6: 'Junho', month7: 'Julho', month8: 'Agosto', month9: 'Setembro', month10: 'Outubro', month11: 'Novembro', month12: 'Dezembro', // week: 'semana', weeks: { sun: 'Dom', mon: 'Seg', tue: 'Ter', wed: 'Qua', thu: 'Qui', fri: 'Sex', sat: 'Sab' }, months: { jan: 'Jan', feb: 'Fev', mar: 'Mar', apr: 'Abr', may: 'Mai', jun: 'Jun', jul: 'Jul', aug: 'Ago', sep: 'Set', oct: 'Out', nov: 'Nov', dec: 'Dez' } }, select: { loading: 'Carregando', noMatch: 'Sem resultados', noData: 'Sem dados', placeholder: 'Selecione' }, cascader: { noMatch: 'Sem resultados', loading: 'Carregando', placeholder: 'Selecione', noData: 'Sem dados' }, pagination: { goto: 'Ir para', pagesize: '/página', total: 'Total {total}', pageClassifier: '' }, messagebox: { title: 'Mensagem', confirm: 'Confirmar', cancel: 'Cancelar', error: 'Erro!' }, upload: { deleteTip: 'aperte delete para apagar', delete: 'Apagar', preview: 'Pré-visualizar', continue: 'Continuar' }, table: { emptyText: 'Sem dados', confirmFilter: 'Confirmar', resetFilter: 'Limpar', clearFilter: 'Todos', sumText: 'Total' }, tree: { emptyText: 'Sem dados' }, transfer: { noMatch: 'Sem resultados', noData: 'Sem dados', titles: ['Lista 1', 'Lista 2'], filterPlaceholder: 'Digite uma palavra-chave', noCheckedFormat: '{total} itens', hasCheckedFormat: '{checked}/{total} selecionados' }, image: { error: 'Erro ao carregar imagem' }, pageHeader: { title: 'Voltar' }, popconfirm: { confirmButtonText: 'Sim', cancelButtonText: 'Não' }, empty: { description: 'Sem dados' } } }; ================================================ FILE: src/locale/lang/pt.js ================================================ export default { el: { colorpicker: { confirm: 'Confirmar', clear: 'Limpar' }, datepicker: { now: 'Agora', today: 'Hoje', cancel: 'Cancelar', clear: 'Limpar', confirm: 'Confirmar', selectDate: 'Selecione a data', selectTime: 'Selecione a hora', startDate: 'Data de inicio', startTime: 'Hora de inicio', endDate: 'Data de fim', endTime: 'Hora de fim', prevYear: 'Previous Year', // to be translated nextYear: 'Next Year', // to be translated prevMonth: 'Previous Month', // to be translated nextMonth: 'Next Month', // to be translated year: '', month1: 'Janeiro', month2: 'Fevereiro', month3: 'Março', month4: 'Abril', month5: 'Maio', month6: 'Junho', month7: 'Julho', month8: 'Agosto', month9: 'Setembro', month10: 'Outubro', month11: 'Novembro', month12: 'Dezembro', // week: 'semana', weeks: { sun: 'Dom', mon: 'Seg', tue: 'Ter', wed: 'Qua', thu: 'Qui', fri: 'Sex', sat: 'Sab' }, months: { jan: 'Jan', feb: 'Fev', mar: 'Mar', apr: 'Abr', may: 'Mai', jun: 'Jun', jul: 'Jul', aug: 'Ago', sep: 'Set', oct: 'Out', nov: 'Nov', dec: 'Dez' } }, select: { loading: 'A carregar', noMatch: 'Sem correspondência', noData: 'Sem dados', placeholder: 'Selecione' }, cascader: { noMatch: 'Sem correspondência', loading: 'A carregar', placeholder: 'Selecione', noData: 'Sem dados' }, pagination: { goto: 'Ir para', pagesize: '/pagina', total: 'Total {total}', pageClassifier: '' }, messagebox: { title: 'Mensagem', confirm: 'Confirmar', cancel: 'Cancelar', error: 'Erro!' }, upload: { deleteTip: 'press delete to remove', // to be translated delete: 'Apagar', preview: 'Previsualizar', continue: 'Continuar' }, table: { emptyText: 'Sem dados', confirmFilter: 'Confirmar', resetFilter: 'Limpar', clearFilter: 'Todos', sumText: 'Sum' // to be translated }, tree: { emptyText: 'Sem dados' }, transfer: { noMatch: 'Sem correspondência', noData: 'Sem dados', titles: ['List 1', 'List 2'], // to be translated filterPlaceholder: 'Enter keyword', // to be translated noCheckedFormat: '{total} items', // to be translated hasCheckedFormat: '{checked}/{total} checked' // to be translated }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Sem dados' } } }; ================================================ FILE: src/locale/lang/ro.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Șterge' }, datepicker: { now: 'Acum', today: 'Azi', cancel: 'Anulează', clear: 'Șterge', confirm: 'OK', selectDate: 'Selectează data', selectTime: 'Selectează ora', startDate: 'Data de început', startTime: 'Ora de început', endDate: 'Data de sfârșit', endTime: 'Ora de sfârșit', prevYear: 'Anul trecut', nextYear: 'Anul următor', prevMonth: 'Luna trecută', nextMonth: 'Luna următoare', year: '', month1: 'Ianuarie', month2: 'Februarie', month3: 'Martie', month4: 'Aprilie', month5: 'Mai', month6: 'Iunie', month7: 'Iulie', month8: 'August', month9: 'Septembrie', month10: 'Octombrie', month11: 'Noiembrie', month12: 'Decembrie', // week: 'week', weeks: { sun: 'Du', mon: 'Lu', tue: 'Ma', wed: 'Mi', thu: 'Jo', fri: 'Vi', sat: 'Sâ' }, months: { jan: 'Ian', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Mai', jun: 'Iun', jul: 'Iul', aug: 'Aug', sep: 'Sep', oct: 'Oct', nov: 'Noi', dec: 'Dec' } }, select: { loading: 'Se încarcă', noMatch: 'Nu există date potrivite', noData: 'Nu există date', placeholder: 'Selectează' }, cascader: { noMatch: 'Nu există date potrivite', loading: 'Se încarcă', placeholder: 'Selectează', noData: 'Nu există date' }, pagination: { goto: 'Go to', pagesize: '/pagina', total: 'Total {total}', pageClassifier: '' }, messagebox: { title: 'Mesaj', confirm: 'OK', cancel: 'Anulează', error: 'Date introduse eronate' }, upload: { deleteTip: 'apăsați pe ștergeți pentru a elimina', delete: 'șterge', preview: 'previzualizare', continue: 'continuă' }, table: { emptyText: 'Nu există date', confirmFilter: 'Confirmă', resetFilter: 'Resetează', clearFilter: 'Tot', sumText: 'Suma' }, tree: { emptyText: 'Nu există date' }, transfer: { noMatch: 'Nu există date potrivite', noData: 'Nu există date', titles: ['Lista 1', 'Lista 2'], filterPlaceholder: 'Introduceți cuvântul cheie', noCheckedFormat: '{total} elemente', hasCheckedFormat: '{checked}/{total} verificate' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Nu există date' } } }; ================================================ FILE: src/locale/lang/ru-RU.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Очистить' }, datepicker: { now: 'Сейчас', today: 'Сегодня', cancel: 'Отмена', clear: 'Очистить', confirm: 'OK', selectDate: 'Выбрать дату', selectTime: 'Выбрать время', startDate: 'Дата начала', startTime: 'Время начала', endDate: 'Дата окончания', endTime: 'Время окончания', prevYear: 'Предыдущий год', nextYear: 'Следующий год', prevMonth: 'Предыдущий месяц', nextMonth: 'Следующий месяц', year: '', month1: 'Январь', month2: 'Февраль', month3: 'Март', month4: 'Апрель', month5: 'Май', month6: 'Июнь', month7: 'Июль', month8: 'Август', month9: 'Сентябрь', month10: 'Октябрь', month11: 'Ноябрь', month12: 'Декабрь', week: 'неделя', weeks: { sun: 'Вс', mon: 'Пн', tue: 'Вт', wed: 'Ср', thu: 'Чт', fri: 'Пт', sat: 'Сб' }, months: { jan: 'Янв', feb: 'Фев', mar: 'Мар', apr: 'Апр', may: 'Май', jun: 'Июн', jul: 'Июл', aug: 'Авг', sep: 'Сен', oct: 'Окт', nov: 'Ноя', dec: 'Дек' } }, select: { loading: 'Загрузка', noMatch: 'Совпадений не найдено', noData: 'Нет данных', placeholder: 'Выбрать' }, cascader: { noMatch: 'Совпадений не найдено', loading: 'Загрузка', placeholder: 'Выбрать', noData: 'Нет данных' }, pagination: { goto: 'Перейти', pagesize: ' на странице', total: 'Всего {total}', pageClassifier: '' }, messagebox: { title: 'Сообщение', confirm: 'OK', cancel: 'Отмена', error: 'Недопустимый ввод данных' }, upload: { deleteTip: 'Нажмите [Удалить] для удаления', delete: 'Удалить', preview: 'Предпросмотр', continue: 'Продолжить' }, table: { emptyText: 'Нет данных', confirmFilter: 'Подтвердить', resetFilter: 'Сбросить', clearFilter: 'Все', sumText: 'Сумма' }, tree: { emptyText: 'Нет данных' }, transfer: { noMatch: 'Совпадений не найдено', noData: 'Нет данных', titles: ['Список 1', 'Список 2'], filterPlaceholder: 'Введите ключевое слово', noCheckedFormat: '{total} пунктов', hasCheckedFormat: '{checked}/{total} выбрано' }, image: { error: 'Произошла ошибка' }, pageHeader: { title: 'Назад' }, popconfirm: { confirmButtonText: 'OK', cancelButtonText: 'Отмена' }, empty: { description: 'Нет данных' } } }; ================================================ FILE: src/locale/lang/si.js ================================================ export default { el: { colorpicker: { confirm: 'හරි', clear: 'හිස් කරන්න' }, datepicker: { now: 'දැන්', today: 'අද', cancel: 'අවලංගු කරන්න', clear: 'හිස් කරන්න', confirm: 'හරි', selectDate: 'දිනය තෝරන්න', selectTime: 'වේලාව තෝරන්න', startDate: 'ආරම්භක දිනය', startTime: 'ආරම්භක වේලාව', endDate: 'අවසන් වන දිනය', endTime: 'අවසන් වන වේලාව', prevYear: 'කලින් අවුරුද්ද', nextYear: 'ඊළඟ අවුරුද්ද', prevMonth: 'කලින් මාසය', nextMonth: 'ඊළඟ මාසය', year: '', month1: 'දුරුතු', month2: 'නවම්', month3: 'මැදින්', month4: 'බක්', month5: 'වෙසක්', month6: 'පොසොන්', month7: 'ඇසළ', month8: 'නිකිණි', month9: 'බිනර', month10: 'වප්', month11: 'ඉල්', month12: 'උඳුවප්', week: 'සතිය', weeks: { sun: 'ඉරිදා', mon: 'සඳුදා', tue: 'අඟහ', wed: 'බදාදා', thu: 'බ්‍රහස්', fri: 'සිකු', sat: 'සෙන' }, months: { jan: 'දුරුතු', feb: 'නවම්', mar: 'මැදින්', apr: 'බක්', may: 'වෙසක්', jun: 'පොසොන්', jul: 'ඇසළ', aug: 'නිකිණි', sep: 'බිනර', oct: 'වප්', nov: 'ඉල්', dec: 'උඳුව' } }, select: { loading: 'පූරණය වෙමින්', noMatch: 'ගැළපෙන දත්ත නැත', noData: 'දත්ත නැත', placeholder: 'තෝරන්න' }, cascader: { noMatch: 'ගැළපෙන දත්ත නැත', loading: 'පූරණය වෙමින්', placeholder: 'තෝරන්න', noData: 'දත්ත නැත' }, pagination: { goto: 'වෙත යන්න', pagesize: '/පිටුව', total: 'මුළු {total}', pageClassifier: '' }, messagebox: { title: 'පණිවිඩය', confirm: 'හරි', cancel: 'අවලංගු කරන්න', error: 'අනීතික ආදානයකි' }, upload: { deleteTip: 'ඉවතලීමට මකන්න ඔබන්න', delete: 'මකන්න', preview: 'පෙරදසුන', continue: 'ඉදිරියට' }, table: { emptyText: 'දත්ත නැත', confirmFilter: 'තහවුරු', resetFilter: 'යළි සකසන්න', clearFilter: 'සියල්ල', sumText: 'එකතුව' }, tree: { emptyText: 'දත්ත නැත' }, transfer: { noMatch: 'ගැළපෙන දත්ත නැත', noData: 'තෝරන්න', titles: ['ලේඛනය 1', 'ලේඛනය 2'], // to be translated filterPlaceholder: 'මූලපදය යොදන්න', // to be translated noCheckedFormat: 'අථක {total}', // to be translated hasCheckedFormat: '{checked}/{total} පරීක්‍ෂා විය' // to be translated }, image: { error: 'අසමත් විය' }, pageHeader: { title: 'ආපසු' // to be translated }, popconfirm: { confirmButtonText: 'ඔව්', cancelButtonText: 'නැහැ' }, empty: { description: 'දත්ත නැත' } } }; ================================================ FILE: src/locale/lang/sk.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Zmazať' }, datepicker: { now: 'Teraz', today: 'Dnes', cancel: 'Zrušiť', clear: 'Zmazať', confirm: 'OK', selectDate: 'Vybrať dátum', selectTime: 'Vybrať čas', startDate: 'Dátum začiatku', startTime: 'Čas začiatku', endDate: 'Dátum konca', endTime: 'Čas konca', prevYear: 'Predošlý rok', nextYear: 'Ďalší rok', prevMonth: 'Predošlý mesiac', nextMonth: 'Ďalší mesiac', day: 'Deň', week: 'Týždeň', month: 'Mesiac', year: 'Rok', month1: 'Január', month2: 'Február', month3: 'Marec', month4: 'Apríl', month5: 'Máj', month6: 'Jún', month7: 'Júl', month8: 'August', month9: 'September', month10: 'Október', month11: 'November', month12: 'December', weeks: { sun: 'Ne', mon: 'Po', tue: 'Ut', wed: 'St', thu: 'Št', fri: 'Pi', sat: 'So' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Máj', jun: 'Jún', jul: 'Júl', aug: 'Aug', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Načítavanie', noMatch: 'Žiadna zhoda', noData: 'Žiadne dáta', placeholder: 'Vybrať' }, cascader: { noMatch: 'Žiadna zhoda', loading: 'Načítavanie', placeholder: 'Vybrať', noData: 'Žiadne dáta' }, pagination: { goto: 'Choď na', pagesize: 'na stranu', total: 'Všetko {total}', pageClassifier: '' }, messagebox: { title: 'Správa', confirm: 'OK', cancel: 'Zrušiť', error: 'Neplatný vstup' }, upload: { deleteTip: 'pre odstránenie stisni klávesu Delete', delete: 'Vymazať', preview: 'Prehliadať', continue: 'Pokračovať' }, table: { emptyText: 'Žiadne dáta', confirmFilter: 'Potvrdiť', resetFilter: 'Zresetovať', clearFilter: 'Všetko', sumText: 'Spolu' }, tree: { emptyText: 'Žiadne dáta' }, transfer: { noMatch: 'Žiadna zhoda', noData: 'Žiadne dáta', titles: ['Zoznam 1', 'Zoznam 2'], filterPlaceholder: 'Filtrovať podľa', noCheckedFormat: '{total} položiek', hasCheckedFormat: '{checked}/{total} označených' }, image: { error: 'Chyba načítania' }, pageHeader: { title: 'Späť' }, popconfirm: { confirmButtonText: 'Potvrdiť', cancelButtonText: 'Zrušiť' }, empty: { description: 'Žiadne dáta' } } }; ================================================ FILE: src/locale/lang/sl.js ================================================ export default { el: { colorpicker: { confirm: 'V redu', clear: 'Počisti' }, datepicker: { now: 'Zdaj', today: 'Danes', cancel: 'Prekliči', clear: 'Počisti', confirm: 'Potrdi', selectDate: 'Izberi datum', selectTime: 'Izberi čas', startDate: 'Začetni datum', startTime: 'Začetni čas', endDate: 'Končni datum', endTime: 'Končni čas', prevYear: 'Prejšnje leto', nextYear: 'Naslednje leto', prevMonth: 'Prejšnji mesec', nextMonth: 'Naslednji mesec', year: '', month1: 'Jan', month2: 'Feb', month3: 'Mar', month4: 'Apr', month5: 'Maj', month6: 'Jun', month7: 'Jul', month8: 'Avg', month9: 'Sep', month10: 'Okt', month11: 'Nov', month12: 'Dec', week: 'teden', weeks: { sun: 'Ned', mon: 'Pon', tue: 'Tor', wed: 'Sre', thu: 'Čet', fri: 'Pet', sat: 'Sob' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Maj', jun: 'Jun', jul: 'Jul', aug: 'Avg', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Nalaganje', noMatch: 'Ni ustreznih podatkov', noData: 'Ni podatkov', placeholder: 'Izberi' }, cascader: { noMatch: 'Ni ustreznih podatkov', loading: 'Nalaganje', placeholder: 'Izberi', noData: 'Ni podatkov' }, pagination: { goto: 'Pojdi na', pagesize: '/stran', total: 'Skupno {total}', pageClassifier: '' }, messagebox: { title: 'Sporočilo', confirm: 'V redu', cancel: 'Prekliči', error: 'Nedovoljen vnos' }, upload: { deleteTip: 'press delete to remove', // to be translated delete: 'Izbriši', preview: 'Predogled', continue: 'Nadaljuj' }, table: { emptyText: 'Ni podatkov', confirmFilter: 'Potrdi', resetFilter: 'Ponastavi', clearFilter: 'Vse', sumText: 'Skupno' }, tree: { emptyText: 'Ni podatkov' }, transfer: { noMatch: 'Ni ustreznih podatkov', noData: 'Ni podatkov', titles: ['Seznam 1', 'Seznam 2'], filterPlaceholder: 'Vnesi ključno besedo', noCheckedFormat: '{total} elementov', hasCheckedFormat: '{checked}/{total} izbranih' }, image: { error: 'NEUSPELO' }, pageHeader: { title: 'Nazaj' }, popconfirm: { confirmButtonText: 'Da', cancelButtonText: 'Ne' }, empty: { description: 'Ni podatkov' } } }; ================================================ FILE: src/locale/lang/sr-Latn.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Poništi' }, datepicker: { now: 'Sad', today: 'Danas', cancel: 'Otkaži', clear: 'Briši', confirm: 'OK', selectDate: 'Izaberi datum', selectTime: 'Izaberi vreme', startDate: 'Datum početka', startTime: 'Vreme početka', endDate: 'Datum završetka', endTime: 'Vreme završetka', prevYear: 'Prethodna godina', nextYear: 'Sledeća godina', prevMonth: 'Prethodni mesec', nextMonth: 'Sledeći mesec', year: 'godina', month1: 'januar', month2: 'februar', month3: 'mart', month4: 'april', month5: 'maj', month6: 'jun', month7: 'jul', month8: 'avgust', month9: 'septembar', month10: 'oktobar', month11: 'novembar', month12: 'decembar', week: 'sedmica', weeks: { sun: 'Ned', mon: 'Pon', tue: 'Uto', wed: 'Sre', thu: 'Čet', fri: 'Pet', sat: 'Sub' }, months: { jan: 'jan', feb: 'feb', mar: 'mar', apr: 'apr', may: 'maj', jun: 'jun', jul: 'jul', aug: 'avg', sep: 'sep', oct: 'okt', nov: 'nov', dec: 'dev' } }, select: { loading: 'Učitavanje', noMatch: 'Nema rezultata', noData: 'Nema podataka', placeholder: 'Izaberi' }, cascader: { noMatch: 'Nema rezultata', loading: 'Učitavanje', placeholder: 'Izaberi', noData: 'Nema podataka' }, pagination: { goto: 'Idi na', pagesize: '/strani', total: 'Ukupno {total}', pageClassifier: '' }, messagebox: { title: 'Poruka', confirm: 'OK', cancel: 'Otkaži', error: 'Neisravan unos' }, upload: { deleteTip: 'pritisni BRIŠI da obrišeš', delete: 'Briši', preview: 'Vidi', continue: 'Nastavi' }, table: { emptyText: 'Nema podataka', confirmFilter: 'Potvrdi', resetFilter: 'Resetuj', clearFilter: 'Sve', sumText: 'Zbir' }, tree: { emptyText: 'Nema podataka' }, transfer: { noMatch: 'Nema rezultata', noData: 'Nema podataka', titles: ['Lista 1', 'Lista 2'], filterPlaceholder: 'Unesi ključnu reč', noCheckedFormat: '{total} stavki', hasCheckedFormat: '{checked}/{total} obeleženih' }, image: { error: 'NEUSPEŠNO' }, pageHeader: { title: 'Nazad' }, popconfirm: { confirmButtonText: 'Da', cancelButtonText: 'Ne' }, empty: { description: 'Nema podataka' } } }; ================================================ FILE: src/locale/lang/sr.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Поништи' }, datepicker: { now: 'Сад', today: 'Данас', cancel: 'Откажи', clear: 'Бриши', confirm: 'OK', selectDate: 'Изабери датум', selectTime: 'Изабери време', startDate: 'Датум почетка', startTime: 'Време почетка', endDate: 'Датум завршетка', endTime: 'Време завршетка', prevYear: 'Претходна година', nextYear: 'Следећа година', prevMonth: 'Претходни месец', nextMonth: 'Следећи месец', year: 'година', month1: 'јануар', month2: 'фебруар', month3: 'март', month4: 'април', month5: 'мај', month6: 'јун', month7: 'јул', month8: 'август', month9: 'септембар', month10: 'октобар', month11: 'новембар', month12: 'децембар', week: 'седмица', weeks: { sun: 'Нед', mon: 'Пон', tue: 'Уто', wed: 'Сре', thu: 'Чет', fri: 'Пет', sat: 'Суб' }, months: { jan: 'јан', feb: 'феб', mar: 'мар', apr: 'апр', may: 'мај', jun: 'јун', jul: 'јул', aug: 'авг', sep: 'сеп', oct: 'окт', nov: 'нов', dec: 'дец' } }, select: { loading: 'Учитавање', noMatch: 'Нема резултата', noData: 'Нема података', placeholder: 'Изабери' }, cascader: { noMatch: 'Нема резултата', loading: 'Учитавање', placeholder: 'Изабери', noData: 'Нема података' }, pagination: { goto: 'Иди на', pagesize: '/страни', total: 'Укупно {total}', pageClassifier: '' }, messagebox: { title: 'Порука', confirm: 'OK', cancel: 'Откажи', error: 'Неисправан унос' }, upload: { deleteTip: 'притисни БРИШИ да обришеш', delete: 'Бриши', preview: 'Види', continue: 'Настави' }, table: { emptyText: 'Нема података', confirmFilter: 'Потврди', resetFilter: 'Ресетуј', clearFilter: 'Све', sumText: 'Збир' }, tree: { emptyText: 'Нема података' }, transfer: { noMatch: 'Нема резултата', noData: 'Нема података', titles: ['Листа 1', 'Листа 2'], // to be translated filterPlaceholder: 'Унеси кључну реч', // to be translated noCheckedFormat: '{total} ставки', // to be translated hasCheckedFormat: '{checked}/{total} обележених' // to be translated }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Нема података' } } }; ================================================ FILE: src/locale/lang/sv-SE.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Töm' }, datepicker: { now: 'Nu', today: 'Idag', cancel: 'Avbryt', clear: 'Töm', confirm: 'OK', selectDate: 'Välj datum', selectTime: 'Välj tid', startDate: 'Startdatum', startTime: 'Starttid', endDate: 'Slutdatum', endTime: 'Sluttid', prevYear: 'Föregående år', nextYear: 'Nästa år', prevMonth: 'Föregående månad', nextMonth: 'Nästa månad', year: '', month1: 'Januari', month2: 'Februari', month3: 'Mars', month4: 'April', month5: 'Maj', month6: 'Juni', month7: 'Juli', month8: 'Augusti', month9: 'September', month10: 'Oktober', month11: 'November', month12: 'December', // week: 'week', weeks: { sun: 'Sön', mon: 'Mån', tue: 'Tis', wed: 'Ons', thu: 'Tor', fri: 'Fre', sat: 'Lör' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Maj', jun: 'Jun', jul: 'Jul', aug: 'Aug', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Laddar', noMatch: 'Hittade inget', noData: 'Ingen data', placeholder: 'Välj' }, cascader: { noMatch: 'Hittade inget', loading: 'Laddar', placeholder: 'Välj', noData: 'Ingen data' }, pagination: { goto: 'Gå till', pagesize: '/sida', total: 'Totalt {total}', pageClassifier: '' }, messagebox: { title: 'Meddelande', confirm: 'OK', cancel: 'Avbryt', error: 'Felaktig inmatning' }, upload: { deleteTip: 'press delete to remove', // to be translated delete: 'Radera', preview: 'Förhandsvisa', continue: 'Fortsätt' }, table: { emptyText: 'Inga Data', confirmFilter: 'Bekräfta', resetFilter: 'Återställ', clearFilter: 'Alla', sumText: 'Summa' }, tree: { emptyText: 'Ingen data' }, transfer: { noMatch: 'Hittade inget', noData: 'Ingen data', titles: ['List 1', 'List 2'], // to be translated filterPlaceholder: 'Enter keyword', // to be translated noCheckedFormat: '{total} items', // to be translated hasCheckedFormat: '{checked}/{total} checked' // to be translated }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Bakåt' // to be translated }, popconfirm: { confirmButtonText: 'Ja', cancelButtonText: 'Nej' }, empty: { description: 'Inga Data' } } }; ================================================ FILE: src/locale/lang/sw.js ================================================ export default { el: { colorpicker: { confirm: 'Sawa', clear: 'Futa' }, datepicker: { now: 'Hivi Punde', today: 'Leo', cancel: 'Katisha', clear: 'Futa', confirm: 'Sawa', selectDate: 'Chagua tarehe', selectTime: 'Chagua Muda', startDate: 'Kuanzia Tarehe', startTime: 'Kuanzia Saa', endDate: 'Mpaka Tarehe', endTime: 'Mpaka Saa', prevYear: 'Mwaka uliopita', nextYear: 'Mwaka ujao', prevMonth: 'Mwezi uliopita', nextMonth: 'Mwezi ujao', year: '', month1: 'Januari', month2: 'Februari', month3: 'Machi', month4: 'Aprili', month5: 'Mei', month6: 'Juni', month7: 'Julai', month8: 'Agosti', month9: 'Septemba', month10: 'Oktoba', month11: 'Novemba', month12: 'Disemba', week: 'wiki', weeks: { sun: 'J2', mon: 'J3', tue: 'J4', wed: 'J5', thu: 'Alhamisi', fri: 'Ijumaa', sat: 'J1' }, months: { jan: 'Jan', feb: 'Feb', mar: 'Mar', apr: 'Apr', may: 'Mei', jun: 'Jun', jul: 'Jul', aug: 'Ago', sep: 'Sep', oct: 'Okt', nov: 'Nov', dec: 'Dec' } }, select: { loading: 'Inapakia', noMatch: 'Hakuna Matokeo yaliyofanana', noData: 'Hakuna Matokeo', placeholder: 'Chagua' }, cascader: { noMatch: 'Hakuna Matokeo yaliyofanana', loading: 'Inapakia', placeholder: 'Chagua', noData: 'Hakuna Matokeo' }, pagination: { goto: 'Nenda', pagesize: '/page', total: 'Jumla {total}', pageClassifier: '' }, messagebox: { title: 'Ujumbe', confirm: 'Sawa', cancel: 'Katisha', error: 'Maingizo yasiyo sahihi' }, upload: { deleteTip: 'bonyeza futa kuondoa', delete: 'Futa', preview: 'Onyesha', continue: 'Endelea' }, table: { emptyText: 'Hakuna Data', confirmFilter: 'Hakikisha', resetFilter: 'Ondoa Kichujio', clearFilter: 'Zote', sumText: 'Jumla' }, tree: { emptyText: 'Hakuna Data' }, transfer: { noMatch: 'Hakuna Matokeo yaliyofanana', noData: 'Hakuna Data', titles: ['List 1', 'List 2'], // to be translated filterPlaceholder: 'Enter keyword', // to be translated noCheckedFormat: '{total} ya zote', // to be translated hasCheckedFormat: '{checked}/{total} zilizochaguliwa' // to be translated }, image: { error: 'IMEFELI' }, pageHeader: { title: 'Nyuma' // to be translated }, popconfirm: { confirmButtonText: 'Ndio', cancelButtonText: 'Hapana' }, empty: { description: 'Hakuna Data' } } }; ================================================ FILE: src/locale/lang/ta.js ================================================ export default { el: { colorpicker: { confirm: 'உறுதி செய்', clear: 'தெளிவாக்கு' }, datepicker: { now: 'தற்போது', today: 'இன்று', cancel: 'ரத்து செய்', clear: 'சரி', confirm: 'உறுதி செய்', selectDate: 'தேதியை தேர்வு செய்', selectTime: 'நேரத்தை தேர்வு செய்', startDate: 'தொடங்கும் நாள்', startTime: 'தொடங்கும் நேரம்', endDate: 'முடியும் தேதி', endTime: 'முடியும் நேரம்', prevYear: 'Previous Year', // to be translated nextYear: 'Next Year', // to be translated prevMonth: 'Previous Month', // to be translated nextMonth: 'Next Month', // to be translated year: 'வருடம்', month1: 'ஜனவரி', month2: 'பிப்ரவரி', month3: 'மார்ச்', month4: 'ஏப்ரல்', month5: 'மே', month6: 'ஜூன்', month7: 'ஜூலை', month8: 'ஆகஸ்ட்', month9: 'செப்டம்பர்', month10: 'அக்டோபர்', month11: 'நவம்பர்', month12: 'டிசம்பர்', weeks: { sun: 'ஞாயிறு', mon: 'திங்கள்', tue: 'செவ்வாய்', wed: 'புதன்', thu: 'வியாழன்', fri: 'வெள்ளி', sat: 'சனி' }, months: { jan: 'ஜனவரி', feb: 'பிப்ரவரி', mar: 'மார்ச்', apr: 'ஏப்ரல்', may: 'மே', jun: 'ஜூன்', jul: 'ஜூலை', aug: 'ஆகஸ்ட்', sep: 'செப்டம்பர்', oct: 'அக்டோபர்', nov: 'நவம்பர்', dec: 'டிசம்பர்' } }, select: { loading: 'தயாராகிக்கொண்டிருக்கிறது', noMatch: 'பொருத்தமான தரவு கிடைக்கவில்லை', noData: 'தரவு இல்லை', placeholder: 'தேர்வு செய்' }, cascader: { noMatch: 'பொருத்தமான தரவு கிடைக்கவில்லை', loading: 'தயாராகிக்கொண்டிருக்கிறது', placeholder: 'தேர்வு செய்', noData: 'தரவு இல்லை' }, pagination: { goto: 'தேவையான் பகுதிக்கு செல்', pagesize: '/page', total: 'மொத்தம் {total}', pageClassifier: '' }, messagebox: { title: 'செய்தி', confirm: 'உறுதி செய்', cancel: 'ரத்து செய்', error: 'பொருத்தாமில்லாத உள்ளீடு' }, upload: { deleteTip: 'press delete to remove', // to be translated delete: 'நீக்கு', preview: 'முன்னோட்டம் பார்', continue: 'தொடரு' }, table: { emptyText: 'தரவு இல்லை', confirmFilter: 'உறுதி செய்', resetFilter: 'புதுமாற்றம் செய்', clearFilter: 'அனைத்தும்', sumText: 'கூட்டு' }, tree: { emptyText: 'தரவு இல்லை' }, transfer: { noMatch: 'பொருத்தமான தரவு கிடைக்கவில்லை', noData: 'தரவு இல்லை', titles: ['பட்டியல் 1', 'பட்டியல் 2'], filterPlaceholder: 'சொல்லை உள்ளீடு செய்', noCheckedFormat: '{total} items', // to be translated hasCheckedFormat: '{checked}/{total} தேர்வு செய்யப்பட்டவைகள்' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'தரவு இல்லை' } } }; ================================================ FILE: src/locale/lang/th.js ================================================ export default { el: { colorpicker: { confirm: 'ตกลง', clear: 'ล้างข้อมูล' }, datepicker: { now: 'ตอนนี้', today: 'วันนี้', cancel: 'ยกเลิก', clear: 'ล้างข้อมูล', confirm: 'ตกลง', selectDate: 'เลือกวันที่', selectTime: 'เลือกเวลา', startDate: 'วันที่เริ่มต้น', startTime: 'เวลาเริ่มต้น', endDate: 'วันที่สิ้นสุด', endTime: 'เวลาสิ้นสุด', prevYear: 'ปีก่อนหน้า', nextYear: 'ปีถัดไป', prevMonth: 'เดือนก่อนหน้า', nextMonth: 'เดือนถัดไป', year: 'ปี', month1: 'มกราคม', month2: 'กุมภาพันธ์', month3: 'มีนาคม', month4: 'เมษายน', month5: 'พฤษภาคม', month6: 'มิถุนายน', month7: 'กรกฎาคม', month8: 'สิงหาคม', month9: 'กันยายน', month10: 'ตุลาคม', month11: 'พฤศจิกายน', month12: 'ธันวาคม', // week: 'week', weeks: { sun: 'อา', mon: 'จ', tue: 'อ', wed: 'พ', thu: 'พฤ', fri: 'ศ', sat: 'ส' }, months: { jan: 'มกรา', feb: 'กุมภา', mar: 'มีนา', apr: 'เมษา', may: 'พฤษภา', jun: 'มิถุนา', jul: 'กรกฎา', aug: 'สิงหา', sep: 'กันยา', oct: 'ตุลา', nov: 'พฤศจิกา', dec: 'ธันวา' } }, select: { loading: 'กำลังโหลด', noMatch: 'ไม่พบข้อมูลที่ตรงกัน', noData: 'ไม่พบข้อมูล', placeholder: 'เลือก' }, cascader: { noMatch: 'ไม่พบข้อมูลที่ตรงกัน', loading: 'กำลังโหลด', placeholder: 'เลือก', noData: 'ไม่พบข้อมูล' }, pagination: { goto: 'ไปที่', pagesize: '/หน้า', total: 'ทั้งหมด {total}', pageClassifier: '' }, messagebox: { title: 'ข้อความ', confirm: 'ตกลง', cancel: 'ยกเลิก', error: 'คุณป้อนข้อมูลไม่ถูกต้อง' }, upload: { deleteTip: 'กดปุ่ม "ลบ" เพื่อลบออก', delete: 'ลบ', preview: 'ตัวอย่าง', continue: 'ทำต่อ' }, table: { emptyText: 'ไม่พบข้อมูล', confirmFilter: 'ยืนยัน', resetFilter: 'รีเซ็ต', clearFilter: 'ทั้งหมด', sumText: 'รวม' }, tree: { emptyText: 'ไม่พบข้อมูล' }, transfer: { noMatch: 'ไม่พบข้อมูลที่ตรงกัน', noData: 'ไม่พบข้อมูล', titles: ['List 1', 'List 2'], // to be translated filterPlaceholder: 'กรอกคีย์เวิร์ด', noCheckedFormat: '{total} items', // to be translated hasCheckedFormat: '{checked}/{total} checked' // to be translated }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'ย้อนกลับ' }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'ไม่พบข้อมูล' } } }; ================================================ FILE: src/locale/lang/tk.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Arassala' }, datepicker: { now: 'Şuwagt', today: 'Şügün', cancel: 'Bes et', clear: 'Arassala', confirm: 'OK', selectDate: 'Güni saýlaň', selectTime: 'Wagty saýlaň', startDate: 'Başlaýan güni', startTime: 'Başlaýan wagty', endDate: 'Gutarýan güni', endTime: 'Gutarýan wagty', prevYear: 'Previous Year', // to be translated nextYear: 'Next Year', // to be translated prevMonth: 'Previous Month', // to be translated nextMonth: 'Next Month', // to be translated year: '', month1: 'Ýan', month2: 'Few', month3: 'Mar', month4: 'Apr', month5: 'Maý', month6: 'Iýn', month7: 'Iýl', month8: 'Awg', month9: 'Sen', month10: 'Okt', month11: 'Noý', month12: 'Dek', // week: 'week', weeks: { sun: 'Ýek', mon: 'Duş', tue: 'Siş', wed: 'Çar', thu: 'Pen', fri: 'Ann', sat: 'Şen' }, months: { jan: 'Ýan', feb: 'Few', mar: 'Mar', apr: 'Apr', may: 'Maý', jun: 'Iýn', jul: 'Iýl', aug: 'Awg', sep: 'Sep', oct: 'Okt', nov: 'Noý', dec: 'Dek' } }, select: { loading: 'Indirilýär', noMatch: 'Hiçzat tapylmady', noData: 'Hiçzat ýok', placeholder: 'Saýla' }, cascader: { noMatch: 'Hiçzat tapylmady', loading: 'Indirilýär', placeholder: 'Saýlaň', noData: 'Hiçzat ýok' }, pagination: { goto: 'Git', pagesize: '/sahypa', total: 'Umumy {total}', pageClassifier: '' }, messagebox: { title: 'Hat', confirm: 'OK', cancel: 'Bes et', error: 'Ýalňyş girizme' }, upload: { deleteTip: 'Pozmak üçin "poz" düwmä basyň', delete: 'Poz', preview: 'Gör', continue: 'Dowam et' }, table: { emptyText: 'Maglumat ýok', confirmFilter: 'Tassykla', resetFilter: 'Arassala', clearFilter: 'Hemmesi', sumText: 'Jemi' }, tree: { emptyText: 'Maglumat ýok' }, transfer: { noMatch: 'Hiçzat tapylmady', noData: 'Hiçzat ýok', titles: ['Sanaw 1', 'Sanaw 2'], filterPlaceholder: 'Gözleg sözlerini giriziň', noCheckedFormat: '{total} sany', hasCheckedFormat: '{checked}/{total} saýlanan' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Maglumat ýok' } } }; ================================================ FILE: src/locale/lang/tr-TR.js ================================================ export default { el: { colorpicker: { confirm: 'Onayla', clear: 'Temizle' }, datepicker: { now: 'Şimdi', today: 'Bugün', cancel: 'İptal', clear: 'Temizle', confirm: 'Onayla', selectDate: 'Tarih seç', selectTime: 'Saat seç', startDate: 'Başlangıç Tarihi', startTime: 'Başlangıç Saati', endDate: 'Bitiş Tarihi', endTime: 'Bitiş Saati', prevYear: 'Önceki Yıl', nextYear: 'Sonraki Yıl', prevMonth: 'Önceki Ay', nextMonth: 'Sonraki Ay', year: '', month1: 'Ocak', month2: 'Şubat', month3: 'Mart', month4: 'Nisan', month5: 'Mayıs', month6: 'Haziran', month7: 'Temmuz', month8: 'Ağustos', month9: 'Eylül', month10: 'Ekim', month11: 'Kasım', month12: 'Aralık', // week: 'week', weeks: { sun: 'Paz', mon: 'Pzt', tue: 'Sal', wed: 'Çar', thu: 'Per', fri: 'Cum', sat: 'Cmt' }, months: { jan: 'Oca', feb: 'Şub', mar: 'Mar', apr: 'Nis', may: 'May', jun: 'Haz', jul: 'Tem', aug: 'Ağu', sep: 'Eyl', oct: 'Eki', nov: 'Kas', dec: 'Ara' } }, select: { loading: 'Yükleniyor', noMatch: 'Eşleşen veri bulunamadı', noData: 'Veri yok', placeholder: 'Seç' }, cascader: { noMatch: 'Eşleşen veri bulunamadı', loading: 'Yükleniyor', placeholder: 'Seç', noData: 'Veri yok' }, pagination: { goto: 'Git', pagesize: '/sayfa', total: 'Toplam {total}', pageClassifier: '' }, messagebox: { title: 'Mesaj', confirm: 'Onayla', cancel: 'İptal', error: 'İllegal giriş' }, upload: { deleteTip: 'kaldırmak için delete tuşuna bas', delete: 'Sil', preview: 'Görüntüle', continue: 'Devam' }, table: { emptyText: 'Veri yok', confirmFilter: 'Onayla', resetFilter: 'Sıfırla', clearFilter: 'Hepsi', sumText: 'Sum' }, tree: { emptyText: 'Veri yok' }, transfer: { noMatch: 'Eşleşen veri bulunamadı', noData: 'Veri yok', titles: ['Liste 1', 'Liste 2'], filterPlaceholder: 'Anahtar kelimeleri gir', noCheckedFormat: '{total} adet', hasCheckedFormat: '{checked}/{total} seçildi' }, image: { error: 'FAILED' // to be translated }, pageHeader: { title: 'Back' // to be translated }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: 'Veri yok' } } }; ================================================ FILE: src/locale/lang/ua.js ================================================ export default { el: { colorpicker: { confirm: 'Обрати', clear: 'Очистити' }, datepicker: { now: 'Зараз', today: 'Сьогодні', cancel: 'Відміна', clear: 'Очистити', confirm: 'OK', selectDate: 'Вибрати дату', selectTime: 'Вибрати час', startDate: 'Дата початку', startTime: 'Час початку', endDate: 'Дата завершення', endTime: 'Час завершення', prevYear: 'Попередній Рік', nextYear: 'Наступний Рік', prevMonth: 'Попередній Місяць', nextMonth: 'Наступний Місяць', year: '', month1: 'Січень', month2: 'Лютий', month3: 'Березень', month4: 'Квітень', month5: 'Травень', month6: 'Червень', month7: 'Липень', month8: 'Серпень', month9: 'Вересень', month10: 'Жовтень', month11: 'Листопад', month12: 'Грудень', week: 'тиждень', weeks: { sun: 'Нд', mon: 'Пн', tue: 'Вт', wed: 'Ср', thu: 'Чт', fri: 'Пт', sat: 'Сб' }, months: { jan: 'Січ', feb: 'Лют', mar: 'Бер', apr: 'Кві', may: 'Тра', jun: 'Чер', jul: 'Лип', aug: 'Сер', sep: 'Вер', oct: 'Жов', nov: 'Лис', dec: 'Гру' } }, select: { loading: 'Завантаження', noMatch: 'Співпадінь не знайдено', noData: 'Немає даних', placeholder: 'Обрати' }, cascader: { noMatch: 'Співпадінь не знайдено', loading: 'Завантаження', placeholder: 'Обрати', noData: 'Немає даних' }, pagination: { goto: 'Перейти', pagesize: 'на сторінці', total: 'Всього {total}', pageClassifier: '' }, messagebox: { title: 'Повідомлення', confirm: 'OK', cancel: 'Відміна', error: 'Неприпустимий ввід даних' }, upload: { deleteTip: 'натисніть кнопку щоб видалити', delete: 'Видалити', preview: 'Перегляд', continue: 'Продовжити' }, table: { emptyText: 'Немає даних', confirmFilter: 'Підтвердити', resetFilter: 'Скинути', clearFilter: 'Все', sumText: 'Сума' }, tree: { emptyText: 'Немає даних' }, transfer: { noMatch: 'Співпадінь не знайдено', noData: 'Обрати', titles: ['Список 1', 'Список 2'], filterPlaceholder: 'Введіть ключове слово', noCheckedFormat: '{total} пунктів', hasCheckedFormat: '{checked}/{total} вибрано' }, image: { error: 'ПОМИЛКА' }, pageHeader: { title: 'Назад' }, popconfirm: { confirmButtonText: 'Так', cancelButtonText: 'Ні' }, empty: { description: 'Немає даних' } } }; ================================================ FILE: src/locale/lang/ug-CN.js ================================================ export default { el: { colorpicker: { confirm: 'جەزملەش', clear: 'قۇرۇقداش' }, datepicker: { now: 'ھازىرقى ۋاقىت', today: 'بۈگۈن', cancel: 'بىكار قىلىش', clear: 'قۇرۇقداش', confirm: 'جەزملەش', selectDate: 'چىسلا تاللاڭ', selectTime: 'ۋاقىت تاللاڭ', startDate: 'باشلانغان چىسلا', startTime: 'باشلانغان ۋاقىت', endDate: 'ئاخىرلاشقان چىسلا', endTime: 'ئاخىرلاشقان ۋاقىت', prevYear: 'ئالدىنقى يىل', nextYear: 'كىيىنكى يىل', prevMonth: 'ئالدىنقى ئاي', nextMonth: 'كىيىنكى ئاي', year: '- يىل', month1: '1-ئاي', month2: '2-ئاي', month3: '3-ئاي', month4: '4-ئاي', month5: '5-ئاي', month6: '6-ئاي', month7: '7-ئاي', month8: '8-ئاي', month9: '9-ئاي', month10: '10-ئاي', month11: '11-ئاي', month12: '12-ئاي', // week: '周次', weeks: { sun: 'يەكشەنبە', mon: 'دۈشەنبە', tue: 'سەيشەنبە', wed: 'چارشەنبە', thu: 'پەيشەنبە', fri: 'جۈمە', sat: 'شەنبە' }, months: { jan: '1-ئاي', feb: '2-ئاي', mar: '3-ئاي', apr: '4-ئاي', may: '5-ئاي', jun: '6-ئاي', jul: '7-ئاي', aug: '8-ئاي', sep: '9-ئاي', oct: '10-ئاي', nov: '11-ئاي', dec: '12-ئاي' } }, select: { loading: 'يۈكلىنىۋاتىدۇ', noMatch: 'ئۇچۇر تېپىلمىدى', noData: 'ئۇچۇر يوق', placeholder: 'تاللاڭ' }, cascader: { noMatch: 'ئۇچۇر تېپىلمىدى', loading: 'يۈكلىنىۋاتىدۇ', placeholder: 'تاللاڭ', noData: 'ئۇچۇر يوق' }, pagination: { goto: 'كىيىنكى بەت', pagesize: 'تال/بەت', total: 'جەمئىي {total} تال', pageClassifier: 'بەت' }, messagebox: { title: 'ئەسكەرتىش', confirm: 'جەزملەش', cancel: 'بىكار قىلىش', error: 'كىرگۈزگەن ئۇچۇرىڭىزدا خاتالىق بار!' }, upload: { deleteTip: 'delete كۇنپكىسىنى بېسىپ ئۆچۈرەلەيسىز', delete: 'ئۆچۈرۈش', preview: 'رەسىمنى كۆرۈش', continue: 'رەسىم يوللاش' }, table: { emptyText: 'ئۇچۇر يوق', confirmFilter: 'سۈزگۈچ', resetFilter: 'قايتا تولدۇرۇش', clearFilter: 'ھەممە', sumText: 'جەمئىي' }, tree: { emptyText: 'ئۇچۇر يوق' }, transfer: { noMatch: 'ئۇچۇر تېپىلمىدى', noData: 'ئۇچۇر يوق', titles: ['جەدۋەل 1', 'جەدۋەل 2'], filterPlaceholder: 'ئىزدىمەكچى بولغان مەزمۇننى كىرگۈزۈڭ', noCheckedFormat: 'جەمئىي {total} تۈر', hasCheckedFormat: 'تاللانغىنى {checked}/{total} تۈر' }, image: { error: 'مەغلۇب بولدى' }, pageHeader: { title: 'قايتىش' }, popconfirm: { confirmButtonText: 'ھەئە', cancelButtonText: 'ياق' }, empty: { description: 'ئۇچۇر يوق' } } }; ================================================ FILE: src/locale/lang/uz-UZ.js ================================================ export default { el: { colorpicker: { confirm: 'Qabul qilish', clear: 'Tozalash' }, datepicker: { now: 'Hozir', today: 'Bugun', cancel: 'Bekor qilish', clear: 'Tozalash', confirm: 'Qabul qilish', selectDate: 'Kunni tanlash', selectTime: 'Soatni tanlash', startDate: 'Boshlanish sanasi', startTime: 'Boshlanish vaqti', endDate: 'Tugash sanasi', endTime: 'Tugash vaqti', prevYear: 'Oʻtgan yil', nextYear: 'Kelgusi yil', prevMonth: 'Oʻtgan oy', nextMonth: 'Kelgusi oy', year: 'Yil', month1: 'Yanvar', month2: 'Fevral', month3: 'Mart', month4: 'Aprel', month5: 'May', month6: 'Iyun', month7: 'Iyul', month8: 'Avgust', month9: 'Sentabr', month10: 'Oktabr', month11: 'Noyabr', month12: 'Dekabr', week: 'Hafta', weeks: { sun: 'Yak', mon: 'Dush', tue: 'Sesh', wed: 'Chor', thu: 'Pay', fri: 'Jum', sat: 'Shan' }, months: { jan: 'Yan', feb: 'Fev', mar: 'Mar', apr: 'Apr', may: 'May', jun: 'Iyun', jul: 'Iyul', aug: 'Avg', sep: 'Sen', oct: 'Okt', nov: 'Noy', dec: 'Dek' } }, select: { loading: 'Yuklanmoqda', noMatch: 'Mos maʼlumot yoʻq', noData: 'Maʼlumot yoʻq', placeholder: 'Tanlang' }, cascader: { noMatch: 'Mos maʼlumot topilmadi', loading: 'Yuklanmoqda', placeholder: 'Tanlash', noData: 'Maʼlumot yoʻq' }, pagination: { goto: 'Oʻtish', pagesize: '/sahifa', total: 'Barchasi {total} ta', pageClassifier: '' }, messagebox: { title: 'Xabar', confirm: 'Qabul qilish', cancel: 'Bekor qilish', error: 'Xatolik' }, upload: { deleteTip: 'Oʻchirish tugmasini bosib oʻchiring', delete: 'Oʻchirish', preview: 'Oldindan koʻrish', continue: 'Davom etish' }, table: { emptyText: 'Boʻsh', confirmFilter: 'Qabul qilish', resetFilter: 'Oldingi holatga qaytarish', clearFilter: 'Jami', sumText: 'Summasi' }, tree: { emptyText: 'Maʼlumot yoʻq' }, transfer: { noMatch: 'Mos maʼlumot topilmadi', noData: 'Maʼlumot yoʻq', titles: ['1-jadval', '2-jadval'], filterPlaceholder: 'Kalit soʻzni kiriting', noCheckedFormat: '{total} ta element', hasCheckedFormat: '{checked}/{total} ta belgilandi' }, image: { error: 'Xatolik' }, pageHeader: { title: 'Orqaga' }, popconfirm: { confirmButtonText: 'Tasdiqlash', cancelButtonText: 'Bekor qilish' }, empty: { description: 'Boʻsh' } } }; ================================================ FILE: src/locale/lang/vi.js ================================================ export default { el: { colorpicker: { confirm: 'OK', clear: 'Xóa' }, datepicker: { now: 'Hiện tại', today: 'Hôm nay', cancel: 'Hủy', clear: 'Xóa', confirm: 'OK', selectDate: 'Chọn ngày', selectTime: 'Chọn giờ', startDate: 'Ngày bắt đầu', startTime: 'Thời gian bắt đầu', endDate: 'Ngày kết thúc', endTime: 'Thời gian kết thúc', prevYear: 'Năm trước', nextYear: 'Năm tới', prevMonth: 'Tháng trước', nextMonth: 'Tháng tới', year: 'Năm', month1: 'Tháng 1', month2: 'Tháng 2', month3: 'Tháng 3', month4: 'Tháng 4', month5: 'Tháng 5', month6: 'Tháng 6', month7: 'Tháng 7', month8: 'Tháng 8', month9: 'Tháng 9', month10: 'Tháng 10', month11: 'Tháng 11', month12: 'Tháng 12', // week: 'week', weeks: { sun: 'CN', mon: 'T2', tue: 'T3', wed: 'T4', thu: 'T5', fri: 'T6', sat: 'T7' }, months: { jan: 'Th.1', feb: 'Th.2', mar: 'Th.3', apr: 'Th.4', may: 'Th.5', jun: 'Th.6', jul: 'Th.7', aug: 'Th.8', sep: 'Th.9', oct: 'Th.10', nov: 'Th.11', dec: 'Th.12' } }, select: { loading: 'Đang tải', noMatch: 'Dữ liệu không phù hợp', noData: 'Không tìm thấy dữ liệu', placeholder: 'Chọn' }, cascader: { noMatch: 'Dữ liệu không phù hợp', loading: 'Đang tải', placeholder: 'Chọn', noData: 'Không tìm thấy dữ liệu' }, pagination: { goto: 'Nhảy tới', pagesize: '/trang', total: 'Tổng {total}', pageClassifier: '' }, messagebox: { title: 'Thông báo', confirm: 'OK', cancel: 'Hủy', error: 'Dữ liệu không hợp lệ' }, upload: { deleteTip: 'Nhấn xoá để xoá', delete: 'Xóa', preview: 'Xem trước', continue: 'Tiếp tục' }, table: { emptyText: 'Không có dữ liệu', confirmFilter: 'Xác nhận', resetFilter: 'Làm mới', clearFilter: 'Xóa hết', sumText: 'Tổng' }, tree: { emptyText: 'Không có dữ liệu' }, transfer: { noMatch: 'Dữ liệu không phù hợp', noData: 'Không tìm thấy dữ liệu', titles: ['Danh sách 1', 'Danh sách 2'], filterPlaceholder: 'Nhập từ khóa', noCheckedFormat: '{total} mục', hasCheckedFormat: '{checked}/{total} đã chọn ' }, image: { error: 'LỖI' }, pageHeader: { title: 'Quay lại' }, popconfirm: { confirmButtonText: 'Ok', cancelButtonText: 'Huỷ' }, empty: { description: 'Không có dữ liệu' } } }; ================================================ FILE: src/locale/lang/zh-CN.js ================================================ export default { el: { colorpicker: { confirm: '确定', clear: '清空' }, datepicker: { now: '此刻', today: '今天', cancel: '取消', clear: '清空', confirm: '确定', selectDate: '选择日期', selectTime: '选择时间', startDate: '开始日期', startTime: '开始时间', endDate: '结束日期', endTime: '结束时间', prevYear: '前一年', nextYear: '后一年', prevMonth: '上个月', nextMonth: '下个月', year: '年', month1: '1 月', month2: '2 月', month3: '3 月', month4: '4 月', month5: '5 月', month6: '6 月', month7: '7 月', month8: '8 月', month9: '9 月', month10: '10 月', month11: '11 月', month12: '12 月', // week: '周次', weeks: { sun: '日', mon: '一', tue: '二', wed: '三', thu: '四', fri: '五', sat: '六' }, months: { jan: '一月', feb: '二月', mar: '三月', apr: '四月', may: '五月', jun: '六月', jul: '七月', aug: '八月', sep: '九月', oct: '十月', nov: '十一月', dec: '十二月' } }, select: { loading: '加载中', noMatch: '无匹配数据', noData: '无数据', placeholder: '请选择' }, cascader: { noMatch: '无匹配数据', loading: '加载中', placeholder: '请选择', noData: '暂无数据' }, pagination: { goto: '前往', pagesize: '条/页', total: '共 {total} 条', pageClassifier: '页' }, messagebox: { title: '提示', confirm: '确定', cancel: '取消', error: '输入的数据不合法!' }, upload: { deleteTip: '按 delete 键可删除', delete: '删除', preview: '查看图片', continue: '继续上传' }, table: { emptyText: '暂无数据', confirmFilter: '筛选', resetFilter: '重置', clearFilter: '全部', sumText: '合计' }, tree: { emptyText: '暂无数据' }, transfer: { noMatch: '无匹配数据', noData: '无数据', titles: ['列表 1', '列表 2'], filterPlaceholder: '请输入搜索内容', noCheckedFormat: '共 {total} 项', hasCheckedFormat: '已选 {checked}/{total} 项' }, image: { error: '加载失败' }, pageHeader: { title: '返回' }, popconfirm: { confirmButtonText: '确定', cancelButtonText: '取消' }, empty: { description: '暂无数据' } } }; ================================================ FILE: src/locale/lang/zh-TW.js ================================================ export default { el: { colorpicker: { confirm: '確認', clear: '清空' }, datepicker: { now: '現在', today: '今天', cancel: '取消', clear: '清空', confirm: '確認', selectDate: '選擇日期', selectTime: '選擇時間', startDate: '開始日期', startTime: '開始時間', endDate: '結束日期', endTime: '結束時間', prevYear: '前一年', nextYear: '後一年', prevMonth: '上個月', nextMonth: '下個月', year: '年', month1: '1 月', month2: '2 月', month3: '3 月', month4: '4 月', month5: '5 月', month6: '6 月', month7: '7 月', month8: '8 月', month9: '9 月', month10: '10 月', month11: '11 月', month12: '12 月', // week: '周次', weeks: { sun: '日', mon: '一', tue: '二', wed: '三', thu: '四', fri: '五', sat: '六' }, months: { jan: '一月', feb: '二月', mar: '三月', apr: '四月', may: '五月', jun: '六月', jul: '七月', aug: '八月', sep: '九月', oct: '十月', nov: '十一月', dec: '十二月' } }, select: { loading: '加載中', noMatch: '無匹配資料', noData: '無資料', placeholder: '請選擇' }, cascader: { noMatch: '無匹配資料', loading: '加載中', placeholder: '請選擇', noData: '無資料' }, pagination: { goto: '前往', pagesize: '項/頁', total: '共 {total} 項', pageClassifier: '頁' }, messagebox: { title: '提示', confirm: '確定', cancel: '取消', error: '輸入的資料不符規定!' }, upload: { deleteTip: '按 delete 鍵可刪除', delete: '刪除', preview: '查看圖片', continue: '繼續上傳' }, table: { emptyText: '暫無資料', confirmFilter: '篩選', resetFilter: '重置', clearFilter: '全部', sumText: 'Sum' // to be translated }, tree: { emptyText: '暫無資料' }, transfer: { noMatch: '無匹配資料', noData: '無資料', titles: ['List 1', 'List 2'], // to be translated filterPlaceholder: 'Enter keyword', // to be translated noCheckedFormat: '{total} items', // to be translated hasCheckedFormat: '{checked}/{total} checked' // to be translated }, image: { error: '加載失敗' }, pageHeader: { title: '返回' }, popconfirm: { confirmButtonText: 'Yes', // to be translated cancelButtonText: 'No' // to be translated }, empty: { description: '暫無資料' } } }; ================================================ FILE: src/mixins/emitter.js ================================================ function broadcast(componentName, eventName, params) { this.$children.forEach(child => { var name = child.$options.componentName; if (name === componentName) { child.$emit.apply(child, [eventName].concat(params)); } else { broadcast.apply(child, [componentName, eventName].concat([params])); } }); } export default { methods: { dispatch(componentName, eventName, params) { var parent = this.$parent || this.$root; var name = parent.$options.componentName; while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.componentName; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, broadcast(componentName, eventName, params) { broadcast.call(this, componentName, eventName, params); } } }; ================================================ FILE: src/mixins/focus.js ================================================ export default function(ref) { return { methods: { focus() { this.$refs[ref].focus(); } } }; }; ================================================ FILE: src/mixins/locale.js ================================================ import { t } from 'element-ui/src/locale'; export default { methods: { t(...args) { return t.apply(this, args); } } }; ================================================ FILE: src/mixins/migrating.js ================================================ import { kebabCase } from 'element-ui/src/utils/util'; /** * Show migrating guide in browser console. * * Usage: * import Migrating from 'element-ui/src/mixins/migrating'; * * mixins: [Migrating] * * add getMigratingConfig method for your component. * getMigratingConfig() { * return { * props: { * 'allow-no-selection': 'allow-no-selection is removed.', * 'selection-mode': 'selection-mode is removed.' * }, * events: { * selectionchange: 'selectionchange is renamed to selection-change.' * } * }; * }, */ export default { mounted() { if (process.env.NODE_ENV === 'production') return; if (!this.$vnode) return; const { props = {}, events = {} } = this.getMigratingConfig(); const { data, componentOptions } = this.$vnode; const definedProps = data.attrs || {}; const definedEvents = componentOptions.listeners || {}; for (let propName in definedProps) { propName = kebabCase(propName); // compatible with camel case if (props[propName]) { console.warn(`[Element Migrating][${this.$options.name}][Attribute]: ${props[propName]}`); } } for (let eventName in definedEvents) { eventName = kebabCase(eventName); // compatible with camel case if (events[eventName]) { console.warn(`[Element Migrating][${this.$options.name}][Event]: ${events[eventName]}`); } } }, methods: { getMigratingConfig() { return { props: {}, events: {} }; } } }; ================================================ FILE: src/transitions/collapse-transition.js ================================================ import { addClass, removeClass } from 'element-ui/src/utils/dom'; class Transition { beforeEnter(el) { addClass(el, 'collapse-transition'); if (!el.dataset) el.dataset = {}; el.dataset.oldPaddingTop = el.style.paddingTop; el.dataset.oldPaddingBottom = el.style.paddingBottom; el.style.height = '0'; el.style.paddingTop = 0; el.style.paddingBottom = 0; } enter(el) { el.dataset.oldOverflow = el.style.overflow; if (el.scrollHeight !== 0) { el.style.height = el.scrollHeight + 'px'; el.style.paddingTop = el.dataset.oldPaddingTop; el.style.paddingBottom = el.dataset.oldPaddingBottom; } else { el.style.height = ''; el.style.paddingTop = el.dataset.oldPaddingTop; el.style.paddingBottom = el.dataset.oldPaddingBottom; } el.style.overflow = 'hidden'; } afterEnter(el) { // for safari: remove class then reset height is necessary removeClass(el, 'collapse-transition'); el.style.height = ''; el.style.overflow = el.dataset.oldOverflow; } beforeLeave(el) { if (!el.dataset) el.dataset = {}; el.dataset.oldPaddingTop = el.style.paddingTop; el.dataset.oldPaddingBottom = el.style.paddingBottom; el.dataset.oldOverflow = el.style.overflow; el.style.height = el.scrollHeight + 'px'; el.style.overflow = 'hidden'; } leave(el) { if (el.scrollHeight !== 0) { // for safari: add class after set height, or it will jump to zero height suddenly, weired addClass(el, 'collapse-transition'); el.style.height = 0; el.style.paddingTop = 0; el.style.paddingBottom = 0; } } afterLeave(el) { removeClass(el, 'collapse-transition'); el.style.height = ''; el.style.overflow = el.dataset.oldOverflow; el.style.paddingTop = el.dataset.oldPaddingTop; el.style.paddingBottom = el.dataset.oldPaddingBottom; } } export default { name: 'ElCollapseTransition', functional: true, render(h, { children }) { const data = { on: new Transition() }; return h('transition', data, children); } }; ================================================ FILE: src/utils/after-leave.js ================================================ /** * Bind after-leave event for vue instance. Make sure after-leave is called in any browsers. * * @param {Vue} instance Vue instance. * @param {Function} callback callback of after-leave event * @param {Number} speed the speed of transition, default value is 300ms * @param {Boolean} once weather bind after-leave once. default value is false. */ export default function(instance, callback, speed = 300, once = false) { if (!instance || !callback) throw new Error('instance & callback is required'); let called = false; const afterLeaveCallback = function() { if (called) return; called = true; if (callback) { callback.apply(null, arguments); } }; if (once) { instance.$once('after-leave', afterLeaveCallback); } else { instance.$on('after-leave', afterLeaveCallback); } setTimeout(() => { afterLeaveCallback(); }, speed + 100); }; ================================================ FILE: src/utils/aria-dialog.js ================================================ import Utils from './aria-utils'; /** * @constructor * @desc Dialog object providing modal focus management. * * Assumptions: The element serving as the dialog container is present in the * DOM and hidden. The dialog container has role='dialog'. * * @param dialogId * The ID of the element serving as the dialog container. * @param focusAfterClosed * Either the DOM node or the ID of the DOM node to focus when the * dialog closes. * @param focusFirst * Optional parameter containing either the DOM node or the ID of the * DOM node to focus when the dialog opens. If not specified, the * first focusable element in the dialog will receive focus. */ var aria = aria || {}; var tabEvent; aria.Dialog = function(dialog, focusAfterClosed, focusFirst) { this.dialogNode = dialog; if (this.dialogNode === null || this.dialogNode.getAttribute('role') !== 'dialog') { throw new Error('Dialog() requires a DOM element with ARIA role of dialog.'); } if (typeof focusAfterClosed === 'string') { this.focusAfterClosed = document.getElementById(focusAfterClosed); } else if (typeof focusAfterClosed === 'object') { this.focusAfterClosed = focusAfterClosed; } else { this.focusAfterClosed = null; } if (typeof focusFirst === 'string') { this.focusFirst = document.getElementById(focusFirst); } else if (typeof focusFirst === 'object') { this.focusFirst = focusFirst; } else { this.focusFirst = null; } if (this.focusFirst) { this.focusFirst.focus(); } else { Utils.focusFirstDescendant(this.dialogNode); } this.lastFocus = document.activeElement; tabEvent = (e) => { this.trapFocus(e); }; this.addListeners(); }; aria.Dialog.prototype.addListeners = function() { document.addEventListener('focus', tabEvent, true); }; aria.Dialog.prototype.removeListeners = function() { document.removeEventListener('focus', tabEvent, true); }; aria.Dialog.prototype.closeDialog = function() { this.removeListeners(); if (this.focusAfterClosed) { setTimeout(() => { this.focusAfterClosed.focus(); }); } }; aria.Dialog.prototype.trapFocus = function(event) { if (Utils.IgnoreUtilFocusChanges) { return; } if (this.dialogNode.contains(event.target)) { this.lastFocus = event.target; } else { Utils.focusFirstDescendant(this.dialogNode); if (this.lastFocus === document.activeElement) { Utils.focusLastDescendant(this.dialogNode); } this.lastFocus = document.activeElement; } }; export default aria.Dialog; ================================================ FILE: src/utils/aria-utils.js ================================================ var aria = aria || {}; aria.Utils = aria.Utils || {}; /** * @desc Set focus on descendant nodes until the first focusable element is * found. * @param element * DOM node for which to find the first focusable descendant. * @returns * true if a focusable element is found and focus is set. */ aria.Utils.focusFirstDescendant = function(element) { for (var i = 0; i < element.childNodes.length; i++) { var child = element.childNodes[i]; if (aria.Utils.attemptFocus(child) || aria.Utils.focusFirstDescendant(child)) { return true; } } return false; }; /** * @desc Find the last descendant node that is focusable. * @param element * DOM node for which to find the last focusable descendant. * @returns * true if a focusable element is found and focus is set. */ aria.Utils.focusLastDescendant = function(element) { for (var i = element.childNodes.length - 1; i >= 0; i--) { var child = element.childNodes[i]; if (aria.Utils.attemptFocus(child) || aria.Utils.focusLastDescendant(child)) { return true; } } return false; }; /** * @desc Set Attempt to set focus on the current node. * @param element * The node to attempt to focus on. * @returns * true if element is focused. */ aria.Utils.attemptFocus = function(element) { if (!aria.Utils.isFocusable(element)) { return false; } aria.Utils.IgnoreUtilFocusChanges = true; try { element.focus(); } catch (e) { } aria.Utils.IgnoreUtilFocusChanges = false; return (document.activeElement === element); }; aria.Utils.isFocusable = function(element) { if (element.tabIndex > 0 || (element.tabIndex === 0 && element.getAttribute('tabIndex') !== null)) { return true; } if (element.disabled) { return false; } switch (element.nodeName) { case 'A': return !!element.href && element.rel !== 'ignore'; case 'INPUT': return element.type !== 'hidden' && element.type !== 'file'; case 'BUTTON': case 'SELECT': case 'TEXTAREA': return true; default: return false; } }; /** * 触发一个事件 * mouseenter, mouseleave, mouseover, keyup, change, click 等 * @param {Element} elm * @param {String} name * @param {*} opts */ aria.Utils.triggerEvent = function(elm, name, ...opts) { let eventName; if (/^mouse|click/.test(name)) { eventName = 'MouseEvents'; } else if (/^key/.test(name)) { eventName = 'KeyboardEvent'; } else { eventName = 'HTMLEvents'; } const evt = document.createEvent(eventName); evt.initEvent(name, ...opts); elm.dispatchEvent ? elm.dispatchEvent(evt) : elm.fireEvent('on' + name, evt); return elm; }; aria.Utils.keys = { tab: 9, enter: 13, space: 32, left: 37, up: 38, right: 39, down: 40, esc: 27 }; export default aria.Utils; ================================================ FILE: src/utils/clickoutside.js ================================================ import Vue from 'vue'; import { on } from 'element-ui/src/utils/dom'; const nodeList = []; const ctx = '@@clickoutsideContext'; let startClick; let seed = 0; !Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e)); !Vue.prototype.$isServer && on(document, 'mouseup', e => { nodeList.forEach(node => node[ctx].documentHandler(e, startClick)); }); function createDocumentHandler(el, binding, vnode) { return function(mouseup = {}, mousedown = {}) { if (!vnode || !vnode.context || !mouseup.target || !mousedown.target || el.contains(mouseup.target) || el.contains(mousedown.target) || el === mouseup.target || (vnode.context.popperElm && (vnode.context.popperElm.contains(mouseup.target) || vnode.context.popperElm.contains(mousedown.target)))) return; if (binding.expression && el[ctx].methodName && vnode.context[el[ctx].methodName]) { vnode.context[el[ctx].methodName](); } else { el[ctx].bindingFn && el[ctx].bindingFn(); } }; } /** * v-clickoutside * @desc 点击元素外面才会触发的事件 * @example * ```vue *
* ``` */ export default { bind(el, binding, vnode) { nodeList.push(el); const id = seed++; el[ctx] = { id, documentHandler: createDocumentHandler(el, binding, vnode), methodName: binding.expression, bindingFn: binding.value }; }, update(el, binding, vnode) { el[ctx].documentHandler = createDocumentHandler(el, binding, vnode); el[ctx].methodName = binding.expression; el[ctx].bindingFn = binding.value; }, unbind(el) { let len = nodeList.length; for (let i = 0; i < len; i++) { if (nodeList[i][ctx].id === el[ctx].id) { nodeList.splice(i, 1); break; } } delete el[ctx]; } }; ================================================ FILE: src/utils/date-util.js ================================================ import fecha from 'element-ui/src/utils/date'; import { t } from 'element-ui/src/locale'; const weeks = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']; const newArray = function(start, end) { let result = []; for (let i = start; i <= end; i++) { result.push(i); } return result; }; export const getI18nSettings = () => { return { dayNamesShort: weeks.map(week => t(`el.datepicker.weeks.${ week }`)), dayNames: weeks.map(week => t(`el.datepicker.weeks.${ week }`)), monthNamesShort: months.map(month => t(`el.datepicker.months.${ month }`)), monthNames: months.map((month, index) => t(`el.datepicker.month${ index + 1 }`)), amPm: ['am', 'pm'] }; }; export const toDate = function(date) { return isDate(date) ? new Date(date) : null; }; export const isDate = function(date) { if (date === null || date === undefined) return false; if (isNaN(new Date(date).getTime())) return false; if (Array.isArray(date)) return false; // deal with `new Date([ new Date() ]) -> new Date()` return true; }; export const isDateObject = function(val) { return val instanceof Date; }; export const formatDate = function(date, format) { date = toDate(date); if (!date) return ''; return fecha.format(date, format || 'yyyy-MM-dd', getI18nSettings()); }; export const parseDate = function(string, format) { return fecha.parse(string, format || 'yyyy-MM-dd', getI18nSettings()); }; export const getDayCountOfMonth = function(year, month) { if (isNaN(+month)) return 31; return new Date(year, +month + 1, 0).getDate(); }; export const getDayCountOfYear = function(year) { const isLeapYear = year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0); return isLeapYear ? 366 : 365; }; export const getFirstDayOfMonth = function(date) { const temp = new Date(date.getTime()); temp.setDate(1); return temp.getDay(); }; // see: https://stackoverflow.com/questions/3674539/incrementing-a-date-in-javascript // {prev, next} Date should work for Daylight Saving Time // Adding 24 * 60 * 60 * 1000 does not work in the above scenario export const prevDate = function(date, amount = 1) { return new Date(date.getFullYear(), date.getMonth(), date.getDate() - amount); }; export const nextDate = function(date, amount = 1) { return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount); }; export const getStartDateOfMonth = function(year, month) { const result = new Date(year, month, 1); const day = result.getDay(); if (day === 0) { return prevDate(result, 7); } else { return prevDate(result, day); } }; export const getWeekNumber = function(src) { if (!isDate(src)) return null; const date = new Date(src.getTime()); date.setHours(0, 0, 0, 0); // Thursday in current week decides the year. date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7); // January 4 is always in week 1. const week1 = new Date(date.getFullYear(), 0, 4); // Adjust to Thursday in week 1 and count number of weeks from date to week 1. // Rounding should be fine for Daylight Saving Time. Its shift should never be more than 12 hours. return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7); }; export const getRangeHours = function(ranges) { const hours = []; let disabledHours = []; (ranges || []).forEach(range => { const value = range.map(date => date.getHours()); disabledHours = disabledHours.concat(newArray(value[0], value[1])); }); if (disabledHours.length) { for (let i = 0; i < 24; i++) { hours[i] = disabledHours.indexOf(i) === -1; } } else { for (let i = 0; i < 24; i++) { hours[i] = false; } } return hours; }; export const getPrevMonthLastDays = (date, amount) => { if (amount <= 0) return []; const temp = new Date(date.getTime()); temp.setDate(0); const lastDay = temp.getDate(); return range(amount).map((_, index) => lastDay - (amount - index - 1)); }; export const getMonthDays = (date) => { const temp = new Date(date.getFullYear(), date.getMonth() + 1, 0); const days = temp.getDate(); return range(days).map((_, index) => index + 1); }; function setRangeData(arr, start, end, value) { for (let i = start; i < end; i++) { arr[i] = value; } } export const getRangeMinutes = function(ranges, hour) { const minutes = new Array(60); if (ranges.length > 0) { ranges.forEach(range => { const start = range[0]; const end = range[1]; const startHour = start.getHours(); const startMinute = start.getMinutes(); const endHour = end.getHours(); const endMinute = end.getMinutes(); if (startHour === hour && endHour !== hour) { setRangeData(minutes, startMinute, 60, true); } else if (startHour === hour && endHour === hour) { setRangeData(minutes, startMinute, endMinute + 1, true); } else if (startHour !== hour && endHour === hour) { setRangeData(minutes, 0, endMinute + 1, true); } else if (startHour < hour && endHour > hour) { setRangeData(minutes, 0, 60, true); } }); } else { setRangeData(minutes, 0, 60, true); } return minutes; }; export const range = function(n) { // see https://stackoverflow.com/questions/3746725/create-a-javascript-array-containing-1-n return Array.apply(null, {length: n}).map((_, n) => n); }; export const modifyDate = function(date, y, m, d) { return new Date(y, m, d, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); }; export const modifyTime = function(date, h, m, s) { return new Date(date.getFullYear(), date.getMonth(), date.getDate(), h, m, s, date.getMilliseconds()); }; export const modifyWithTimeString = (date, time) => { if (date == null || !time) { return date; } time = parseDate(time, 'HH:mm:ss'); return modifyTime(date, time.getHours(), time.getMinutes(), time.getSeconds()); }; export const clearTime = function(date) { return new Date(date.getFullYear(), date.getMonth(), date.getDate()); }; export const clearMilliseconds = function(date) { return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0); }; export const limitTimeRange = function(date, ranges, format = 'HH:mm:ss') { // TODO: refactory a more elegant solution if (ranges.length === 0) return date; const normalizeDate = date => fecha.parse(fecha.format(date, format), format); const ndate = normalizeDate(date); const nranges = ranges.map(range => range.map(normalizeDate)); if (nranges.some(nrange => ndate >= nrange[0] && ndate <= nrange[1])) return date; let minDate = nranges[0][0]; let maxDate = nranges[0][0]; nranges.forEach(nrange => { minDate = new Date(Math.min(nrange[0], minDate)); maxDate = new Date(Math.max(nrange[1], minDate)); }); const ret = ndate < minDate ? minDate : maxDate; // preserve Year/Month/Date return modifyDate( ret, date.getFullYear(), date.getMonth(), date.getDate() ); }; export const timeWithinRange = function(date, selectableRange, format) { const limitedDate = limitTimeRange(date, selectableRange, format); return limitedDate.getTime() === date.getTime(); }; export const changeYearMonthAndClampDate = function(date, year, month) { // clamp date to the number of days in `year`, `month` // eg: (2010-1-31, 2010, 2) => 2010-2-28 const monthDate = Math.min(date.getDate(), getDayCountOfMonth(year, month)); return modifyDate(date, year, month, monthDate); }; export const prevMonth = function(date) { const year = date.getFullYear(); const month = date.getMonth(); return month === 0 ? changeYearMonthAndClampDate(date, year - 1, 11) : changeYearMonthAndClampDate(date, year, month - 1); }; export const nextMonth = function(date) { const year = date.getFullYear(); const month = date.getMonth(); return month === 11 ? changeYearMonthAndClampDate(date, year + 1, 0) : changeYearMonthAndClampDate(date, year, month + 1); }; export const prevYear = function(date, amount = 1) { const year = date.getFullYear(); const month = date.getMonth(); return changeYearMonthAndClampDate(date, year - amount, month); }; export const nextYear = function(date, amount = 1) { const year = date.getFullYear(); const month = date.getMonth(); return changeYearMonthAndClampDate(date, year + amount, month); }; export const extractDateFormat = function(format) { return format .replace(/\W?m{1,2}|\W?ZZ/g, '') .replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi, '') .trim(); }; export const extractTimeFormat = function(format) { return format .replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g, '') .trim(); }; export const validateRangeInOneMonth = function(start, end) { return (start.getMonth() === end.getMonth()) && (start.getFullYear() === end.getFullYear()); }; ================================================ FILE: src/utils/date.js ================================================ /* Modified from https://github.com/taylorhakes/fecha * * The MIT License (MIT) * * Copyright (c) 2015 Taylor Hakes * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /*eslint-disable*/ // 把 YYYY-MM-DD 改成了 yyyy-MM-dd (function (main) { 'use strict'; /** * Parse or format dates * @class fecha */ var fecha = {}; var token = /d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g; var twoDigits = '\\d\\d?'; var threeDigits = '\\d{3}'; var fourDigits = '\\d{4}'; var word = '[^\\s]+'; var literal = /\[([^]*?)\]/gm; var noop = function () { }; function regexEscape(str) { return str.replace( /[|\\{()[^$+*?.-]/g, '\\$&'); } function shorten(arr, sLen) { var newArr = []; for (var i = 0, len = arr.length; i < len; i++) { newArr.push(arr[i].substr(0, sLen)); } return newArr; } function monthUpdate(arrName) { return function (d, v, i18n) { var index = i18n[arrName].indexOf(v.charAt(0).toUpperCase() + v.substr(1).toLowerCase()); if (~index) { d.month = index; } }; } function pad(val, len) { val = String(val); len = len || 2; while (val.length < len) { val = '0' + val; } return val; } var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; var monthNamesShort = shorten(monthNames, 3); var dayNamesShort = shorten(dayNames, 3); fecha.i18n = { dayNamesShort: dayNamesShort, dayNames: dayNames, monthNamesShort: monthNamesShort, monthNames: monthNames, amPm: ['am', 'pm'], DoFn: function DoFn(D) { return D + ['th', 'st', 'nd', 'rd'][D % 10 > 3 ? 0 : (D - D % 10 !== 10) * D % 10]; } }; var formatFlags = { D: function(dateObj) { return dateObj.getDay(); }, DD: function(dateObj) { return pad(dateObj.getDay()); }, Do: function(dateObj, i18n) { return i18n.DoFn(dateObj.getDate()); }, d: function(dateObj) { return dateObj.getDate(); }, dd: function(dateObj) { return pad(dateObj.getDate()); }, ddd: function(dateObj, i18n) { return i18n.dayNamesShort[dateObj.getDay()]; }, dddd: function(dateObj, i18n) { return i18n.dayNames[dateObj.getDay()]; }, M: function(dateObj) { return dateObj.getMonth() + 1; }, MM: function(dateObj) { return pad(dateObj.getMonth() + 1); }, MMM: function(dateObj, i18n) { return i18n.monthNamesShort[dateObj.getMonth()]; }, MMMM: function(dateObj, i18n) { return i18n.monthNames[dateObj.getMonth()]; }, yy: function(dateObj) { return pad(String(dateObj.getFullYear()), 4).substr(2); }, yyyy: function(dateObj) { return pad(dateObj.getFullYear(), 4); }, h: function(dateObj) { return dateObj.getHours() % 12 || 12; }, hh: function(dateObj) { return pad(dateObj.getHours() % 12 || 12); }, H: function(dateObj) { return dateObj.getHours(); }, HH: function(dateObj) { return pad(dateObj.getHours()); }, m: function(dateObj) { return dateObj.getMinutes(); }, mm: function(dateObj) { return pad(dateObj.getMinutes()); }, s: function(dateObj) { return dateObj.getSeconds(); }, ss: function(dateObj) { return pad(dateObj.getSeconds()); }, S: function(dateObj) { return Math.round(dateObj.getMilliseconds() / 100); }, SS: function(dateObj) { return pad(Math.round(dateObj.getMilliseconds() / 10), 2); }, SSS: function(dateObj) { return pad(dateObj.getMilliseconds(), 3); }, a: function(dateObj, i18n) { return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1]; }, A: function(dateObj, i18n) { return dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase(); }, ZZ: function(dateObj) { var o = dateObj.getTimezoneOffset(); return (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4); } }; var parseFlags = { d: [twoDigits, function (d, v) { d.day = v; }], Do: [twoDigits + word, function (d, v) { d.day = parseInt(v, 10); }], M: [twoDigits, function (d, v) { d.month = v - 1; }], yy: [twoDigits, function (d, v) { var da = new Date(), cent = +('' + da.getFullYear()).substr(0, 2); d.year = '' + (v > 68 ? cent - 1 : cent) + v; }], h: [twoDigits, function (d, v) { d.hour = v; }], m: [twoDigits, function (d, v) { d.minute = v; }], s: [twoDigits, function (d, v) { d.second = v; }], yyyy: [fourDigits, function (d, v) { d.year = v; }], S: ['\\d', function (d, v) { d.millisecond = v * 100; }], SS: ['\\d{2}', function (d, v) { d.millisecond = v * 10; }], SSS: [threeDigits, function (d, v) { d.millisecond = v; }], D: [twoDigits, noop], ddd: [word, noop], MMM: [word, monthUpdate('monthNamesShort')], MMMM: [word, monthUpdate('monthNames')], a: [word, function (d, v, i18n) { var val = v.toLowerCase(); if (val === i18n.amPm[0]) { d.isPm = false; } else if (val === i18n.amPm[1]) { d.isPm = true; } }], ZZ: ['[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z', function (d, v) { var parts = (v + '').match(/([+-]|\d\d)/gi), minutes; if (parts) { minutes = +(parts[1] * 60) + parseInt(parts[2], 10); d.timezoneOffset = parts[0] === '+' ? minutes : -minutes; } }] }; parseFlags.dd = parseFlags.d; parseFlags.dddd = parseFlags.ddd; parseFlags.DD = parseFlags.D; parseFlags.mm = parseFlags.m; parseFlags.hh = parseFlags.H = parseFlags.HH = parseFlags.h; parseFlags.MM = parseFlags.M; parseFlags.ss = parseFlags.s; parseFlags.A = parseFlags.a; // Some common format strings fecha.masks = { default: 'ddd MMM dd yyyy HH:mm:ss', shortDate: 'M/D/yy', mediumDate: 'MMM d, yyyy', longDate: 'MMMM d, yyyy', fullDate: 'dddd, MMMM d, yyyy', shortTime: 'HH:mm', mediumTime: 'HH:mm:ss', longTime: 'HH:mm:ss.SSS' }; /*** * Format a date * @method format * @param {Date|number} dateObj * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate' */ fecha.format = function (dateObj, mask, i18nSettings) { var i18n = i18nSettings || fecha.i18n; if (typeof dateObj === 'number') { dateObj = new Date(dateObj); } if (Object.prototype.toString.call(dateObj) !== '[object Date]' || isNaN(dateObj.getTime())) { throw new Error('Invalid Date in fecha.format'); } mask = fecha.masks[mask] || mask || fecha.masks['default']; var literals = []; // Make literals inactive by replacing them with ?? mask = mask.replace(literal, function($0, $1) { literals.push($1); return '@@@'; }); // Apply formatting rules mask = mask.replace(token, function ($0) { return $0 in formatFlags ? formatFlags[$0](dateObj, i18n) : $0.slice(1, $0.length - 1); }); // Inline literal values back into the formatted value return mask.replace(/@@@/g, function() { return literals.shift(); }); }; /** * Parse a date string into an object, changes - into / * @method parse * @param {string} dateStr Date string * @param {string} format Date parse format * @returns {Date|boolean} */ fecha.parse = function (dateStr, format, i18nSettings) { var i18n = i18nSettings || fecha.i18n; if (typeof format !== 'string') { throw new Error('Invalid format in fecha.parse'); } format = fecha.masks[format] || format; // Avoid regular expression denial of service, fail early for really long strings // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS if (dateStr.length > 1000) { return null; } var dateInfo = {}; var parseInfo = []; var literals = []; format = format.replace(literal, function($0, $1) { literals.push($1); return '@@@'; }); var newFormat = regexEscape(format).replace(token, function ($0) { if (parseFlags[$0]) { var info = parseFlags[$0]; parseInfo.push(info[1]); return '(' + info[0] + ')'; } return $0; }); newFormat = newFormat.replace(/@@@/g, function() { return literals.shift(); }); var matches = dateStr.match(new RegExp(newFormat, 'i')); if (!matches) { return null; } for (var i = 1; i < matches.length; i++) { parseInfo[i - 1](dateInfo, matches[i], i18n); } var today = new Date(); if (dateInfo.isPm === true && dateInfo.hour != null && +dateInfo.hour !== 12) { dateInfo.hour = +dateInfo.hour + 12; } else if (dateInfo.isPm === false && +dateInfo.hour === 12) { dateInfo.hour = 0; } var date; if (dateInfo.timezoneOffset != null) { dateInfo.minute = +(dateInfo.minute || 0) - +dateInfo.timezoneOffset; date = new Date(Date.UTC(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0)); } else { date = new Date(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0); } return date; }; /* istanbul ignore next */ if (typeof module !== 'undefined' && module.exports) { module.exports = fecha; } else if (typeof define === 'function' && define.amd) { define(function () { return fecha; }); } else { main.fecha = fecha; } })(this); ================================================ FILE: src/utils/dom.js ================================================ /* istanbul ignore next */ import Vue from 'vue'; const isServer = Vue.prototype.$isServer; const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g; const MOZ_HACK_REGEXP = /^moz([A-Z])/; const ieVersion = isServer ? 0 : Number(document.documentMode); /* istanbul ignore next */ const trim = function(string) { return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, ''); }; /* istanbul ignore next */ const camelCase = function(name) { return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { return offset ? letter.toUpperCase() : letter; }).replace(MOZ_HACK_REGEXP, 'Moz$1'); }; /* istanbul ignore next */ export const on = (function() { if (!isServer && document.addEventListener) { return function(element, event, handler) { if (element && event && handler) { element.addEventListener(event, handler, false); } }; } else { return function(element, event, handler) { if (element && event && handler) { element.attachEvent('on' + event, handler); } }; } })(); /* istanbul ignore next */ export const off = (function() { if (!isServer && document.removeEventListener) { return function(element, event, handler) { if (element && event) { element.removeEventListener(event, handler, false); } }; } else { return function(element, event, handler) { if (element && event) { element.detachEvent('on' + event, handler); } }; } })(); /* istanbul ignore next */ export const once = function(el, event, fn) { var listener = function() { if (fn) { fn.apply(this, arguments); } off(el, event, listener); }; on(el, event, listener); }; /* istanbul ignore next */ export function hasClass(el, cls) { if (!el || !cls) return false; if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.'); if (el.classList) { return el.classList.contains(cls); } else { return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1; } }; /* istanbul ignore next */ export function addClass(el, cls) { if (!el) return; var curClass = el.className; var classes = (cls || '').split(' '); for (var i = 0, j = classes.length; i < j; i++) { var clsName = classes[i]; if (!clsName) continue; if (el.classList) { el.classList.add(clsName); } else if (!hasClass(el, clsName)) { curClass += ' ' + clsName; } } if (!el.classList) { el.setAttribute('class', curClass); } }; /* istanbul ignore next */ export function removeClass(el, cls) { if (!el || !cls) return; var classes = cls.split(' '); var curClass = ' ' + el.className + ' '; for (var i = 0, j = classes.length; i < j; i++) { var clsName = classes[i]; if (!clsName) continue; if (el.classList) { el.classList.remove(clsName); } else if (hasClass(el, clsName)) { curClass = curClass.replace(' ' + clsName + ' ', ' '); } } if (!el.classList) { el.setAttribute('class', trim(curClass)); } }; /* istanbul ignore next */ export const getStyle = ieVersion < 9 ? function(element, styleName) { if (isServer) return; if (!element || !styleName) return null; styleName = camelCase(styleName); if (styleName === 'float') { styleName = 'styleFloat'; } try { switch (styleName) { case 'opacity': try { return element.filters.item('alpha').opacity / 100; } catch (e) { return 1.0; } default: return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null); } } catch (e) { return element.style[styleName]; } } : function(element, styleName) { if (isServer) return; if (!element || !styleName) return null; styleName = camelCase(styleName); if (styleName === 'float') { styleName = 'cssFloat'; } try { var computed = document.defaultView.getComputedStyle(element, ''); return element.style[styleName] || computed ? computed[styleName] : null; } catch (e) { return element.style[styleName]; } }; /* istanbul ignore next */ export function setStyle(element, styleName, value) { if (!element || !styleName) return; if (typeof styleName === 'object') { for (var prop in styleName) { if (styleName.hasOwnProperty(prop)) { setStyle(element, prop, styleName[prop]); } } } else { styleName = camelCase(styleName); if (styleName === 'opacity' && ieVersion < 9) { element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')'; } else { element.style[styleName] = value; } } }; export const isScroll = (el, vertical) => { if (isServer) return; const determinedDirection = vertical !== null && vertical !== undefined; const overflow = determinedDirection ? vertical ? getStyle(el, 'overflow-y') : getStyle(el, 'overflow-x') : getStyle(el, 'overflow'); return overflow.match(/(scroll|auto|overlay)/); }; export const getScrollContainer = (el, vertical) => { if (isServer) return; let parent = el; while (parent) { if ([window, document, document.documentElement].includes(parent)) { return window; } if (isScroll(parent, vertical)) { return parent; } parent = parent.parentNode; } return parent; }; export const isInContainer = (el, container) => { if (isServer || !el || !container) return false; const elRect = el.getBoundingClientRect(); let containerRect; if ([window, document, document.documentElement, null, undefined].includes(container)) { containerRect = { top: 0, right: window.innerWidth, bottom: window.innerHeight, left: 0 }; } else { containerRect = container.getBoundingClientRect(); } return elRect.top < containerRect.bottom && elRect.bottom > containerRect.top && elRect.right > containerRect.left && elRect.left < containerRect.right; }; ================================================ FILE: src/utils/lodash.js ================================================ /** * @license * Lodash * Copyright JS Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /*eslint-disable*/ (function() { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ var undefined; /** Used as the semantic version number. */ var VERSION = '4.17.10'; /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** Error message constants. */ var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', FUNC_ERROR_TEXT = 'Expected a function'; /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** Used as the maximum memoize cache size. */ var MAX_MEMOIZE_SIZE = 500; /** Used as the internal argument placeholder. */ var PLACEHOLDER = '__lodash_placeholder__'; /** Used to compose bitmasks for cloning. */ var CLONE_DEEP_FLAG = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG = 4; /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256, WRAP_FLIP_FLAG = 512; /** Used as default options for `_.truncate`. */ var DEFAULT_TRUNC_LENGTH = 30, DEFAULT_TRUNC_OMISSION = '...'; /** Used to detect hot functions by number of calls within a span of milliseconds. */ var HOT_COUNT = 800, HOT_SPAN = 16; /** Used to indicate the type of lazy iteratees. */ var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2, LAZY_WHILE_FLAG = 3; /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0, MAX_SAFE_INTEGER = 9007199254740991, MAX_INTEGER = 1.7976931348623157e308, NAN = 0 / 0; /** Used as references for the maximum length and index of an array. */ var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; /** Used to associate wrap methods with their bit flags. */ var wrapFlags = [ ['ary', WRAP_ARY_FLAG], ['bind', WRAP_BIND_FLAG], ['bindKey', WRAP_BIND_KEY_FLAG], ['curry', WRAP_CURRY_FLAG], ['curryRight', WRAP_CURRY_RIGHT_FLAG], ['flip', WRAP_FLIP_FLAG], ['partial', WRAP_PARTIAL_FLAG], ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], ['rearg', WRAP_REARG_FLAG] ]; /** `Object#toString` result references. */ var argsTag = '[object Arguments]', arrayTag = '[object Array]', asyncTag = '[object AsyncFunction]', boolTag = '[object Boolean]', dateTag = '[object Date]', domExcTag = '[object DOMException]', errorTag = '[object Error]', funcTag = '[object Function]', genTag = '[object GeneratorFunction]', mapTag = '[object Map]', numberTag = '[object Number]', nullTag = '[object Null]', objectTag = '[object Object]', promiseTag = '[object Promise]', proxyTag = '[object Proxy]', regexpTag = '[object RegExp]', setTag = '[object Set]', stringTag = '[object String]', symbolTag = '[object Symbol]', undefinedTag = '[object Undefined]', weakMapTag = '[object WeakMap]', weakSetTag = '[object WeakSet]'; var arrayBufferTag = '[object ArrayBuffer]', dataViewTag = '[object DataView]', float32Tag = '[object Float32Array]', float64Tag = '[object Float64Array]', int8Tag = '[object Int8Array]', int16Tag = '[object Int16Array]', int32Tag = '[object Int32Array]', uint8Tag = '[object Uint8Array]', uint8ClampedTag = '[object Uint8ClampedArray]', uint16Tag = '[object Uint16Array]', uint32Tag = '[object Uint32Array]'; /** Used to match empty string literals in compiled template source. */ var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; /** Used to match HTML entities and HTML characters. */ var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, reUnescapedHtml = /[&<>"']/g, reHasEscapedHtml = RegExp(reEscapedHtml.source), reHasUnescapedHtml = RegExp(reUnescapedHtml.source); /** Used to match template delimiters. */ var reEscape = /<%-([\s\S]+?)%>/g, reEvaluate = /<%([\s\S]+?)%>/g, reInterpolate = /<%=([\s\S]+?)%>/g; /** Used to match property names within property paths. */ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; /** * Used to match `RegExp` * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar.source); /** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g, reTrimStart = /^\s+/, reTrimEnd = /\s+$/; /** Used to match wrap detail comments. */ var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, reSplitDetails = /,? & /; /** Used to match words composed of alphanumeric characters. */ var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; /** Used to match backslashes in property paths. */ var reEscapeChar = /\\(\\)?/g; /** * Used to match * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). */ var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; /** Used to match `RegExp` flags from their coerced string values. */ var reFlags = /\w*$/; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect host constructors (Safari). */ var reIsHostCtor = /^\[object .+?Constructor\]$/; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Used to detect unsigned integer values. */ var reIsUint = /^(?:0|[1-9]\d*)$/; /** Used to match Latin Unicode letters (excluding mathematical operators). */ var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; /** Used to ensure capturing order of template delimiters. */ var reNoMatch = /($^)/; /** Used to match unescaped characters in compiled string literals. */ var reUnescapedString = /['\n\r\u2028\u2029\\]/g; /** Used to compose unicode character classes. */ var rsAstralRange = '\\ud800-\\udfff', rsComboMarksRange = '\\u0300-\\u036f', reComboHalfMarksRange = '\\ufe20-\\ufe2f', rsComboSymbolsRange = '\\u20d0-\\u20ff', rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, rsDingbatRange = '\\u2700-\\u27bf', rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', rsPunctuationRange = '\\u2000-\\u206f', rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', rsVarRange = '\\ufe0e\\ufe0f', rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; /** Used to compose unicode capture groups. */ var rsApos = "['\u2019]", rsAstral = '[' + rsAstralRange + ']', rsBreak = '[' + rsBreakRange + ']', rsCombo = '[' + rsComboRange + ']', rsDigits = '\\d+', rsDingbat = '[' + rsDingbatRange + ']', rsLower = '[' + rsLowerRange + ']', rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', rsFitz = '\\ud83c[\\udffb-\\udfff]', rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', rsNonAstral = '[^' + rsAstralRange + ']', rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', rsUpper = '[' + rsUpperRange + ']', rsZWJ = '\\u200d'; /** Used to compose unicode regexes. */ var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', reOptMod = rsModifier + '?', rsOptVar = '[' + rsVarRange + ']?', rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', rsSeq = rsOptVar + reOptMod + rsOptJoin, rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, rsSymbol = '(?:' + [ rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral ].join('|') + ')'; /** Used to match apostrophes. */ var reApos = RegExp(rsApos, 'g'); /** * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). */ var reComboMark = RegExp(rsCombo, 'g'); /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ var reUnicode = RegExp( rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g' ); /** Used to match complex or compound words. */ var reUnicodeWord = RegExp( [ rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, rsUpper + '+' + rsOptContrUpper, rsOrdUpper, rsOrdLower, rsDigits, rsEmoji ].join('|'), 'g' ); /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ var reHasUnicode = RegExp( '[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']' ); /** Used to detect strings that need a more robust regexp to match words. */ var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; /** Used to assign default `context` object properties. */ var contextProps = [ 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' ]; /** Used to make template sourceURLs easier to identify. */ var templateCounter = -1; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags = {}; typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[ int8Tag ] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[ uint8Tag ] = typedArrayTags[uint8ClampedTag] = typedArrayTags[ uint16Tag ] = typedArrayTags[uint32Tag] = true; typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[ arrayBufferTag ] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[ dateTag ] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[ mapTag ] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[ regexpTag ] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[ weakMapTag ] = false; /** Used to identify `toStringTag` values supported by `_.clone`. */ var cloneableTags = {}; cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[ arrayBufferTag ] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[ dateTag ] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[ int8Tag ] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[ mapTag ] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[ regexpTag ] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[ symbolTag ] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[ uint16Tag ] = cloneableTags[uint32Tag] = true; cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[ weakMapTag ] = false; /** Used to map Latin Unicode letters to basic Latin letters. */ var deburredLetters = { // Latin-1 Supplement block. À: 'A', Á: 'A', Â: 'A', Ã: 'A', Ä: 'A', Å: 'A', à: 'a', á: 'a', â: 'a', ã: 'a', ä: 'a', å: 'a', Ç: 'C', ç: 'c', Ð: 'D', ð: 'd', È: 'E', É: 'E', Ê: 'E', Ë: 'E', è: 'e', é: 'e', ê: 'e', ë: 'e', Ì: 'I', Í: 'I', Î: 'I', Ï: 'I', ì: 'i', í: 'i', î: 'i', ï: 'i', Ñ: 'N', ñ: 'n', Ò: 'O', Ó: 'O', Ô: 'O', Õ: 'O', Ö: 'O', Ø: 'O', ò: 'o', ó: 'o', ô: 'o', õ: 'o', ö: 'o', ø: 'o', Ù: 'U', Ú: 'U', Û: 'U', Ü: 'U', ù: 'u', ú: 'u', û: 'u', ü: 'u', Ý: 'Y', ý: 'y', ÿ: 'y', Æ: 'Ae', æ: 'ae', Þ: 'Th', þ: 'th', ß: 'ss', // Latin Extended-A block. Ā: 'A', Ă: 'A', Ą: 'A', ā: 'a', ă: 'a', ą: 'a', Ć: 'C', Ĉ: 'C', Ċ: 'C', Č: 'C', ć: 'c', ĉ: 'c', ċ: 'c', č: 'c', Ď: 'D', Đ: 'D', ď: 'd', đ: 'd', Ē: 'E', Ĕ: 'E', Ė: 'E', Ę: 'E', Ě: 'E', ē: 'e', ĕ: 'e', ė: 'e', ę: 'e', ě: 'e', Ĝ: 'G', Ğ: 'G', Ġ: 'G', Ģ: 'G', ĝ: 'g', ğ: 'g', ġ: 'g', ģ: 'g', Ĥ: 'H', Ħ: 'H', ĥ: 'h', ħ: 'h', Ĩ: 'I', Ī: 'I', Ĭ: 'I', Į: 'I', İ: 'I', ĩ: 'i', ī: 'i', ĭ: 'i', į: 'i', ı: 'i', Ĵ: 'J', ĵ: 'j', Ķ: 'K', ķ: 'k', ĸ: 'k', Ĺ: 'L', Ļ: 'L', Ľ: 'L', Ŀ: 'L', Ł: 'L', ĺ: 'l', ļ: 'l', ľ: 'l', ŀ: 'l', ł: 'l', Ń: 'N', Ņ: 'N', Ň: 'N', Ŋ: 'N', ń: 'n', ņ: 'n', ň: 'n', ŋ: 'n', Ō: 'O', Ŏ: 'O', Ő: 'O', ō: 'o', ŏ: 'o', ő: 'o', Ŕ: 'R', Ŗ: 'R', Ř: 'R', ŕ: 'r', ŗ: 'r', ř: 'r', Ś: 'S', Ŝ: 'S', Ş: 'S', Š: 'S', ś: 's', ŝ: 's', ş: 's', š: 's', Ţ: 'T', Ť: 'T', Ŧ: 'T', ţ: 't', ť: 't', ŧ: 't', Ũ: 'U', Ū: 'U', Ŭ: 'U', Ů: 'U', Ű: 'U', Ų: 'U', ũ: 'u', ū: 'u', ŭ: 'u', ů: 'u', ű: 'u', ų: 'u', Ŵ: 'W', ŵ: 'w', Ŷ: 'Y', ŷ: 'y', Ÿ: 'Y', Ź: 'Z', Ż: 'Z', Ž: 'Z', ź: 'z', ż: 'z', ž: 'z', IJ: 'IJ', ij: 'ij', Œ: 'Oe', œ: 'oe', ʼn: "'n", ſ: 's' }; /** Used to map characters to HTML entities. */ var htmlEscapes = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; /** Used to map HTML entities to characters. */ var htmlUnescapes = { '&': '&', '<': '<', '>': '>', '"': '"', ''': "'" }; /** Used to escape characters for inclusion in compiled string literals. */ var stringEscapes = { '\\': '\\', "'": "'", '\n': 'n', '\r': 'r', '\u2028': 'u2028', '\u2029': 'u2029' }; /** Built-in method references without a dependency on `root`. */ var freeParseFloat = parseFloat, freeParseInt = parseInt; /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global === 'object' && global && global.Object === Object && global; /** Detect free variable `self`. */ var freeSelf = typeof self === 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); /** Detect free variable `exports`. */ var freeExports = typeof exports === 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule = freeExports && typeof module === 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports; /** Detect free variable `process` from Node.js. */ var freeProcess = moduleExports && freeGlobal.process; /** Used to access faster Node.js helpers. */ var nodeUtil = (function() { try { // Use `util.types` for Node.js 10+. var types = freeModule && freeModule.require && freeModule.require('util').types; if (types) { return types; } // Legacy `process.binding('util')` for Node.js < 10. return freeProcess && freeProcess.binding && freeProcess.binding('util'); } catch (e) { } })(); /* Node.js helper references. */ var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, nodeIsDate = nodeUtil && nodeUtil.isDate, nodeIsMap = nodeUtil && nodeUtil.isMap, nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, nodeIsSet = nodeUtil && nodeUtil.isSet, nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; /* --------------------------------------------------------------------------*/ /** * A faster alternative to `Function#apply`, this function invokes `func` * with the `this` binding of `thisArg` and the arguments of `args`. * * @private * @param {Function} func The function to invoke. * @param {*} thisArg The `this` binding of `func`. * @param {Array} args The arguments to invoke `func` with. * @returns {*} Returns the result of `func`. */ function apply(func, thisArg, args) { switch (args.length) { case 0: return func.call(thisArg); case 1: return func.call(thisArg, args[0]); case 2: return func.call(thisArg, args[0], args[1]); case 3: return func.call(thisArg, args[0], args[1], args[2]); } return func.apply(thisArg, args); } /** * A specialized version of `baseAggregator` for arrays. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. * @returns {Function} Returns `accumulator`. */ function arrayAggregator(array, setter, iteratee, accumulator) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { var value = array[index]; setter(accumulator, value, iteratee(value), array); } return accumulator; } /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach(array, iteratee) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (iteratee(array[index], index, array) === false) { break; } } return array; } /** * A specialized version of `_.forEachRight` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEachRight(array, iteratee) { var length = array == null ? 0 : array.length; while (length--) { if (iteratee(array[length], length, array) === false) { break; } } return array; } /** * A specialized version of `_.every` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false`. */ function arrayEvery(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (!predicate(array[index], index, array)) { return false; } } return true; } /** * A specialized version of `_.filter` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter(array, predicate) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result[resIndex++] = value; } } return result; } /** * A specialized version of `_.includes` for arrays without support for * specifying an index to search from. * * @private * @param {Array} [array] The array to inspect. * @param {*} target The value to search for. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludes(array, value) { var length = array == null ? 0 : array.length; return !!length && baseIndexOf(array, value, 0) > -1; } /** * This function is like `arrayIncludes` except that it accepts a comparator. * * @private * @param {Array} [array] The array to inspect. * @param {*} target The value to search for. * @param {Function} comparator The comparator invoked per element. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludesWith(array, value, comparator) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (comparator(value, array[index])) { return true; } } return false; } /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, length = array == null ? 0 : array.length, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } /** * Appends the elements of `values` to `array`. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to append. * @returns {Array} Returns `array`. */ function arrayPush(array, values) { var index = -1, length = values.length, offset = array.length; while (++index < length) { array[offset + index] = values[index]; } return array; } /** * A specialized version of `_.reduce` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} [accumulator] The initial value. * @param {boolean} [initAccum] Specify using the first element of `array` as * the initial value. * @returns {*} Returns the accumulated value. */ function arrayReduce(array, iteratee, accumulator, initAccum) { var index = -1, length = array == null ? 0 : array.length; if (initAccum && length) { accumulator = array[++index]; } while (++index < length) { accumulator = iteratee(accumulator, array[index], index, array); } return accumulator; } /** * A specialized version of `_.reduceRight` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} [accumulator] The initial value. * @param {boolean} [initAccum] Specify using the last element of `array` as * the initial value. * @returns {*} Returns the accumulated value. */ function arrayReduceRight(array, iteratee, accumulator, initAccum) { var length = array == null ? 0 : array.length; if (initAccum && length) { accumulator = array[--length]; } while (length--) { accumulator = iteratee(accumulator, array[length], length, array); } return accumulator; } /** * A specialized version of `_.some` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function arraySome(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (predicate(array[index], index, array)) { return true; } } return false; } /** * Gets the size of an ASCII `string`. * * @private * @param {string} string The string inspect. * @returns {number} Returns the string size. */ var asciiSize = baseProperty('length'); /** * Converts an ASCII `string` to an array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the converted array. */ function asciiToArray(string) { return string.split(''); } /** * Splits an ASCII `string` into an array of its words. * * @private * @param {string} The string to inspect. * @returns {Array} Returns the words of `string`. */ function asciiWords(string) { return string.match(reAsciiWord) || []; } /** * The base implementation of methods like `_.findKey` and `_.findLastKey`, * without support for iteratee shorthands, which iterates over `collection` * using `eachFunc`. * * @private * @param {Array|Object} collection The collection to inspect. * @param {Function} predicate The function invoked per iteration. * @param {Function} eachFunc The function to iterate over `collection`. * @returns {*} Returns the found element or its key, else `undefined`. */ function baseFindKey(collection, predicate, eachFunc) { var result; eachFunc(collection, function(value, key, collection) { if (predicate(value, key, collection)) { result = key; return false; } }); return result; } /** * The base implementation of `_.findIndex` and `_.findLastIndex` without * support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} predicate The function invoked per iteration. * @param {number} fromIndex The index to search from. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseFindIndex(array, predicate, fromIndex, fromRight) { var length = array.length, index = fromIndex + (fromRight ? 1 : -1); while (fromRight ? index-- : ++index < length) { if (predicate(array[index], index, array)) { return index; } } return -1; } /** * The base implementation of `_.indexOf` without `fromIndex` bounds checks. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseIndexOf(array, value, fromIndex) { return value === value ? strictIndexOf(array, value, fromIndex) : baseFindIndex(array, baseIsNaN, fromIndex); } /** * This function is like `baseIndexOf` except that it accepts a comparator. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @param {Function} comparator The comparator invoked per element. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseIndexOfWith(array, value, fromIndex, comparator) { var index = fromIndex - 1, length = array.length; while (++index < length) { if (comparator(array[index], value)) { return index; } } return -1; } /** * The base implementation of `_.isNaN` without support for number objects. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. */ function baseIsNaN(value) { return value !== value; } /** * The base implementation of `_.mean` and `_.meanBy` without support for * iteratee shorthands. * * @private * @param {Array} array The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {number} Returns the mean. */ function baseMean(array, iteratee) { var length = array == null ? 0 : array.length; return length ? baseSum(array, iteratee) / length : NAN; } /** * The base implementation of `_.property` without support for deep paths. * * @private * @param {string} key The key of the property to get. * @returns {Function} Returns the new accessor function. */ function baseProperty(key) { return function(object) { return object == null ? undefined : object[key]; }; } /** * The base implementation of `_.propertyOf` without support for deep paths. * * @private * @param {Object} object The object to query. * @returns {Function} Returns the new accessor function. */ function basePropertyOf(object) { return function(key) { return object == null ? undefined : object[key]; }; } /** * The base implementation of `_.reduce` and `_.reduceRight`, without support * for iteratee shorthands, which iterates over `collection` using `eachFunc`. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {*} accumulator The initial value. * @param {boolean} initAccum Specify using the first or last element of * `collection` as the initial value. * @param {Function} eachFunc The function to iterate over `collection`. * @returns {*} Returns the accumulated value. */ function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { eachFunc(collection, function(value, index, collection) { accumulator = initAccum ? ((initAccum = false), value) : iteratee(accumulator, value, index, collection); }); return accumulator; } /** * The base implementation of `_.sortBy` which uses `comparer` to define the * sort order of `array` and replaces criteria objects with their corresponding * values. * * @private * @param {Array} array The array to sort. * @param {Function} comparer The function to define sort order. * @returns {Array} Returns `array`. */ function baseSortBy(array, comparer) { var length = array.length; array.sort(comparer); while (length--) { array[length] = array[length].value; } return array; } /** * The base implementation of `_.sum` and `_.sumBy` without support for * iteratee shorthands. * * @private * @param {Array} array The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {number} Returns the sum. */ function baseSum(array, iteratee) { var result, index = -1, length = array.length; while (++index < length) { var current = iteratee(array[index]); if (current !== undefined) { result = result === undefined ? current : result + current; } } return result; } /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } /** * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array * of key-value pairs for `object` corresponding to the property names of `props`. * * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. * @returns {Object} Returns the key-value pairs. */ function baseToPairs(object, props) { return arrayMap(props, function(key) { return [key, object[key]]; }); } /** * The base implementation of `_.unary` without support for storing metadata. * * @private * @param {Function} func The function to cap arguments for. * @returns {Function} Returns the new capped function. */ function baseUnary(func) { return function(value) { return func(value); }; } /** * The base implementation of `_.values` and `_.valuesIn` which creates an * array of `object` property values corresponding to the property names * of `props`. * * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. * @returns {Object} Returns the array of property values. */ function baseValues(object, props) { return arrayMap(props, function(key) { return object[key]; }); } /** * Checks if a `cache` value for `key` exists. * * @private * @param {Object} cache The cache to query. * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function cacheHas(cache, key) { return cache.has(key); } /** * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol * that is not found in the character symbols. * * @private * @param {Array} strSymbols The string symbols to inspect. * @param {Array} chrSymbols The character symbols to find. * @returns {number} Returns the index of the first unmatched string symbol. */ function charsStartIndex(strSymbols, chrSymbols) { var index = -1, length = strSymbols.length; while ( ++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1 ) { } return index; } /** * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol * that is not found in the character symbols. * * @private * @param {Array} strSymbols The string symbols to inspect. * @param {Array} chrSymbols The character symbols to find. * @returns {number} Returns the index of the last unmatched string symbol. */ function charsEndIndex(strSymbols, chrSymbols) { var index = strSymbols.length; while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) { } return index; } /** * Gets the number of `placeholder` occurrences in `array`. * * @private * @param {Array} array The array to inspect. * @param {*} placeholder The placeholder to search for. * @returns {number} Returns the placeholder count. */ function countHolders(array, placeholder) { var length = array.length, result = 0; while (length--) { if (array[length] === placeholder) { ++result; } } return result; } /** * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A * letters to basic Latin letters. * * @private * @param {string} letter The matched letter to deburr. * @returns {string} Returns the deburred letter. */ var deburrLetter = basePropertyOf(deburredLetters); /** * Used by `_.escape` to convert characters to HTML entities. * * @private * @param {string} chr The matched character to escape. * @returns {string} Returns the escaped character. */ var escapeHtmlChar = basePropertyOf(htmlEscapes); /** * Used by `_.template` to escape characters for inclusion in compiled string literals. * * @private * @param {string} chr The matched character to escape. * @returns {string} Returns the escaped character. */ function escapeStringChar(chr) { return '\\' + stringEscapes[chr]; } /** * Gets the value at `key` of `object`. * * @private * @param {Object} [object] The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function getValue(object, key) { return object == null ? undefined : object[key]; } /** * Checks if `string` contains Unicode symbols. * * @private * @param {string} string The string to inspect. * @returns {boolean} Returns `true` if a symbol is found, else `false`. */ function hasUnicode(string) { return reHasUnicode.test(string); } /** * Checks if `string` contains a word composed of Unicode symbols. * * @private * @param {string} string The string to inspect. * @returns {boolean} Returns `true` if a word is found, else `false`. */ function hasUnicodeWord(string) { return reHasUnicodeWord.test(string); } /** * Converts `iterator` to an array. * * @private * @param {Object} iterator The iterator to convert. * @returns {Array} Returns the converted array. */ function iteratorToArray(iterator) { var data, result = []; while (!(data = iterator.next()).done) { result.push(data.value); } return result; } /** * Converts `map` to its key-value pairs. * * @private * @param {Object} map The map to convert. * @returns {Array} Returns the key-value pairs. */ function mapToArray(map) { var index = -1, result = Array(map.size); map.forEach(function(value, key) { result[++index] = [key, value]; }); return result; } /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function(arg) { return func(transform(arg)); }; } /** * Replaces all `placeholder` elements in `array` with an internal placeholder * and returns an array of their indexes. * * @private * @param {Array} array The array to modify. * @param {*} placeholder The placeholder to replace. * @returns {Array} Returns the new array of placeholder indexes. */ function replaceHolders(array, placeholder) { var index = -1, length = array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value === placeholder || value === PLACEHOLDER) { array[index] = PLACEHOLDER; result[resIndex++] = index; } } return result; } /** * Gets the value at `key`, unless `key` is "__proto__". * * @private * @param {Object} object The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function safeGet(object, key) { return key == '__proto__' ? undefined : object[key]; } /** * Converts `set` to an array of its values. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the values. */ function setToArray(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = value; }); return result; } /** * Converts `set` to its value-value pairs. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the value-value pairs. */ function setToPairs(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = [value, value]; }); return result; } /** * A specialized version of `_.indexOf` which performs strict equality * comparisons of values, i.e. `===`. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function strictIndexOf(array, value, fromIndex) { var index = fromIndex - 1, length = array.length; while (++index < length) { if (array[index] === value) { return index; } } return -1; } /** * A specialized version of `_.lastIndexOf` which performs strict equality * comparisons of values, i.e. `===`. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function strictLastIndexOf(array, value, fromIndex) { var index = fromIndex + 1; while (index--) { if (array[index] === value) { return index; } } return index; } /** * Gets the number of symbols in `string`. * * @private * @param {string} string The string to inspect. * @returns {number} Returns the string size. */ function stringSize(string) { return hasUnicode(string) ? unicodeSize(string) : asciiSize(string); } /** * Converts `string` to an array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the converted array. */ function stringToArray(string) { return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string); } /** * Used by `_.unescape` to convert HTML entities to characters. * * @private * @param {string} chr The matched character to unescape. * @returns {string} Returns the unescaped character. */ var unescapeHtmlChar = basePropertyOf(htmlUnescapes); /** * Gets the size of a Unicode `string`. * * @private * @param {string} string The string inspect. * @returns {number} Returns the string size. */ function unicodeSize(string) { var result = (reUnicode.lastIndex = 0); while (reUnicode.test(string)) { ++result; } return result; } /** * Converts a Unicode `string` to an array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the converted array. */ function unicodeToArray(string) { return string.match(reUnicode) || []; } /** * Splits a Unicode `string` into an array of its words. * * @private * @param {string} The string to inspect. * @returns {Array} Returns the words of `string`. */ function unicodeWords(string) { return string.match(reUnicodeWord) || []; } /* --------------------------------------------------------------------------*/ /** * Create a new pristine `lodash` function using the `context` object. * * @static * @memberOf _ * @since 1.1.0 * @category Util * @param {Object} [context=root] The context object. * @returns {Function} Returns a new `lodash` function. * @example * * _.mixin({ 'foo': _.constant('foo') }); * * var lodash = _.runInContext(); * lodash.mixin({ 'bar': lodash.constant('bar') }); * * _.isFunction(_.foo); * // => true * _.isFunction(_.bar); * // => false * * lodash.isFunction(lodash.foo); * // => false * lodash.isFunction(lodash.bar); * // => true * * // Create a suped-up `defer` in Node.js. * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; */ var runInContext = function runInContext(context) { context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); /** Built-in constructor references. */ var Array = context.Array, Date = context.Date, Error = context.Error, Function = context.Function, Math = context.Math, Object = context.Object, RegExp = context.RegExp, String = context.String, TypeError = context.TypeError; /** Used for built-in method references. */ var arrayProto = Array.prototype, funcProto = Function.prototype, objectProto = Object.prototype; /** Used to detect overreaching core-js shims. */ var coreJsData = context['__core-js_shared__']; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** Used to generate unique IDs. */ var idCounter = 0; /** Used to detect methods masquerading as native. */ var maskSrcKey = (function() { var uid = /[^.]+$/.exec( (coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO) || '' ); return uid ? 'Symbol(src)_1.' + uid : ''; })(); /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** Used to infer the `Object` constructor. */ var objectCtorString = funcToString.call(Object); /** Used to restore the original `_` reference in `_.noConflict`. */ var oldDash = root._; /** Used to detect if a method is native. */ var reIsNative = RegExp( '^' + funcToString .call(hasOwnProperty) .replace(reRegExpChar, '\\$&') .replace( /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?' ) + '$' ); /** Built-in value references. */ var Buffer = moduleExports ? context.Buffer : undefined, Symbol = context.Symbol, Uint8Array = context.Uint8Array, allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, getPrototype = overArg(Object.getPrototypeOf, Object), objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, splice = arrayProto.splice, spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, symIterator = Symbol ? Symbol.iterator : undefined, symToStringTag = Symbol ? Symbol.toStringTag : undefined; var defineProperty = (function() { try { var func = getNative(Object, 'defineProperty'); func({}, '', {}); return func; } catch (e) { } })(); /** Mocked built-ins. */ var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, ctxNow = Date && Date.now !== root.Date.now && Date.now, ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeCeil = Math.ceil, nativeFloor = Math.floor, nativeGetSymbols = Object.getOwnPropertySymbols, nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, nativeIsFinite = context.isFinite, nativeJoin = arrayProto.join, nativeKeys = overArg(Object.keys, Object), nativeMax = Math.max, nativeMin = Math.min, nativeNow = Date.now, nativeParseInt = context.parseInt, nativeRandom = Math.random, nativeReverse = arrayProto.reverse; /* Built-in method references that are verified to be native. */ var DataView = getNative(context, 'DataView'), Map = getNative(context, 'Map'), Promise = getNative(context, 'Promise'), Set = getNative(context, 'Set'), WeakMap = getNative(context, 'WeakMap'), nativeCreate = getNative(Object, 'create'); /** Used to store function metadata. */ var metaMap = WeakMap && new WeakMap(); /** Used to lookup unminified function names. */ var realNames = {}; /** Used to detect maps, sets, and weakmaps. */ var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map), promiseCtorString = toSource(Promise), setCtorString = toSource(Set), weakMapCtorString = toSource(WeakMap); /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, symbolToString = symbolProto ? symbolProto.toString : undefined; /* ------------------------------------------------------------------------*/ /** * Creates a `lodash` object which wraps `value` to enable implicit method * chain sequences. Methods that operate on and return arrays, collections, * and functions can be chained together. Methods that retrieve a single value * or may return a primitive value will automatically end the chain sequence * and return the unwrapped value. Otherwise, the value must be unwrapped * with `_#value`. * * Explicit chain sequences, which must be unwrapped with `_#value`, may be * enabled using `_.chain`. * * The execution of chained methods is lazy, that is, it's deferred until * `_#value` is implicitly or explicitly called. * * Lazy evaluation allows several methods to support shortcut fusion. * Shortcut fusion is an optimization to merge iteratee calls; this avoids * the creation of intermediate arrays and can greatly reduce the number of * iteratee executions. Sections of a chain sequence qualify for shortcut * fusion if the section is applied to an array and iteratees accept only * one argument. The heuristic for whether a section qualifies for shortcut * fusion is subject to change. * * Chaining is supported in custom builds as long as the `_#value` method is * directly or indirectly included in the build. * * In addition to lodash methods, wrappers have `Array` and `String` methods. * * The wrapper `Array` methods are: * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` * * The wrapper `String` methods are: * `replace` and `split` * * The wrapper methods that support shortcut fusion are: * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` * * The chainable wrapper methods are: * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, * `zipObject`, `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, * `upperFirst`, `value`, and `words` * * @name _ * @constructor * @category Seq * @param {*} value The value to wrap in a `lodash` instance. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * function square(n) { * return n * n; * } * * var wrapped = _([1, 2, 3]); * * // Returns an unwrapped value. * wrapped.reduce(_.add); * // => 6 * * // Returns a wrapped value. * var squares = wrapped.map(square); * * _.isArray(squares); * // => false * * _.isArray(squares.value()); * // => true */ function lodash(value) { if ( isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper) ) { if (value instanceof LodashWrapper) { return value; } if (hasOwnProperty.call(value, '__wrapped__')) { return wrapperClone(value); } } return new LodashWrapper(value); } /** * The base implementation of `_.create` without support for assigning * properties to the created object. * * @private * @param {Object} proto The object to inherit from. * @returns {Object} Returns the new object. */ var baseCreate = (function() { function object() { } return function(proto) { if (!isObject(proto)) { return {}; } if (objectCreate) { return objectCreate(proto); } object.prototype = proto; var result = new object(); object.prototype = undefined; return result; }; })(); /** * The function whose prototype chain sequence wrappers inherit from. * * @private */ function baseLodash() { // No operation performed. } /** * The base constructor for creating `lodash` wrapper objects. * * @private * @param {*} value The value to wrap. * @param {boolean} [chainAll] Enable explicit method chain sequences. */ function LodashWrapper(value, chainAll) { this.__wrapped__ = value; this.__actions__ = []; this.__chain__ = !!chainAll; this.__index__ = 0; this.__values__ = undefined; } /** * By default, the template delimiters used by lodash are like those in * embedded Ruby (ERB) as well as ES2015 template strings. Change the * following template settings to use alternative delimiters. * * @static * @memberOf _ * @type {Object} */ lodash.templateSettings = { /** * Used to detect `data` property values to be HTML-escaped. * * @memberOf _.templateSettings * @type {RegExp} */ escape: reEscape, /** * Used to detect code to be evaluated. * * @memberOf _.templateSettings * @type {RegExp} */ evaluate: reEvaluate, /** * Used to detect `data` property values to inject. * * @memberOf _.templateSettings * @type {RegExp} */ interpolate: reInterpolate, /** * Used to reference the data object in the template text. * * @memberOf _.templateSettings * @type {string} */ variable: '', /** * Used to import variables into the compiled template. * * @memberOf _.templateSettings * @type {Object} */ imports: { /** * A reference to the `lodash` function. * * @memberOf _.templateSettings.imports * @type {Function} */ _: lodash } }; // Ensure wrappers are instances of `baseLodash`. lodash.prototype = baseLodash.prototype; lodash.prototype.constructor = lodash; LodashWrapper.prototype = baseCreate(baseLodash.prototype); LodashWrapper.prototype.constructor = LodashWrapper; /* ------------------------------------------------------------------------*/ /** * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. * * @private * @constructor * @param {*} value The value to wrap. */ function LazyWrapper(value) { this.__wrapped__ = value; this.__actions__ = []; this.__dir__ = 1; this.__filtered__ = false; this.__iteratees__ = []; this.__takeCount__ = MAX_ARRAY_LENGTH; this.__views__ = []; } /** * Creates a clone of the lazy wrapper object. * * @private * @name clone * @memberOf LazyWrapper * @returns {Object} Returns the cloned `LazyWrapper` object. */ function lazyClone() { var result = new LazyWrapper(this.__wrapped__); result.__actions__ = copyArray(this.__actions__); result.__dir__ = this.__dir__; result.__filtered__ = this.__filtered__; result.__iteratees__ = copyArray(this.__iteratees__); result.__takeCount__ = this.__takeCount__; result.__views__ = copyArray(this.__views__); return result; } /** * Reverses the direction of lazy iteration. * * @private * @name reverse * @memberOf LazyWrapper * @returns {Object} Returns the new reversed `LazyWrapper` object. */ function lazyReverse() { if (this.__filtered__) { var result = new LazyWrapper(this); result.__dir__ = -1; result.__filtered__ = true; } else { result = this.clone(); result.__dir__ *= -1; } return result; } /** * Extracts the unwrapped value from its lazy wrapper. * * @private * @name value * @memberOf LazyWrapper * @returns {*} Returns the unwrapped value. */ function lazyValue() { var array = this.__wrapped__.value(), dir = this.__dir__, isArr = isArray(array), isRight = dir < 0, arrLength = isArr ? array.length : 0, view = getView(0, arrLength, this.__views__), start = view.start, end = view.end, length = end - start, index = isRight ? end : start - 1, iteratees = this.__iteratees__, iterLength = iteratees.length, resIndex = 0, takeCount = nativeMin(length, this.__takeCount__); if (!isArr || (!isRight && arrLength == length && takeCount == length)) { return baseWrapperValue(array, this.__actions__); } var result = []; outer: while (length-- && resIndex < takeCount) { index += dir; var iterIndex = -1, value = array[index]; while (++iterIndex < iterLength) { var data = iteratees[iterIndex], iteratee = data.iteratee, type = data.type, computed = iteratee(value); if (type == LAZY_MAP_FLAG) { value = computed; } else if (!computed) { if (type == LAZY_FILTER_FLAG) { continue outer; } else { break outer; } } } result[resIndex++] = value; } return result; } // Ensure `LazyWrapper` is an instance of `baseLodash`. LazyWrapper.prototype = baseCreate(baseLodash.prototype); LazyWrapper.prototype.constructor = LazyWrapper; /* ------------------------------------------------------------------------*/ /** * Creates a hash object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the hash. * * @private * @name clear * @memberOf Hash */ function hashClear() { this.__data__ = nativeCreate ? nativeCreate(null) : {}; this.size = 0; } /** * Removes `key` and its value from the hash. * * @private * @name delete * @memberOf Hash * @param {Object} hash The hash to modify. * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function hashDelete(key) { var result = this.has(key) && delete this.__data__[key]; this.size -= result ? 1 : 0; return result; } /** * Gets the hash value for `key`. * * @private * @name get * @memberOf Hash * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function hashGet(key) { var data = this.__data__; if (nativeCreate) { var result = data[key]; return result === HASH_UNDEFINED ? undefined : result; } return hasOwnProperty.call(data, key) ? data[key] : undefined; } /** * Checks if a hash value for `key` exists. * * @private * @name has * @memberOf Hash * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function hashHas(key) { var data = this.__data__; return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); } /** * Sets the hash `key` to `value`. * * @private * @name set * @memberOf Hash * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the hash instance. */ function hashSet(key, value) { var data = this.__data__; this.size += this.has(key) ? 0 : 1; data[key] = nativeCreate && value === undefined ? HASH_UNDEFINED : value; return this; } // Add methods to `Hash`. Hash.prototype.clear = hashClear; Hash.prototype['delete'] = hashDelete; Hash.prototype.get = hashGet; Hash.prototype.has = hashHas; Hash.prototype.set = hashSet; /* ------------------------------------------------------------------------*/ /** * Creates an list cache object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the list cache. * * @private * @name clear * @memberOf ListCache */ function listCacheClear() { this.__data__ = []; this.size = 0; } /** * Removes `key` and its value from the list cache. * * @private * @name delete * @memberOf ListCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function listCacheDelete(key) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { return false; } var lastIndex = data.length - 1; if (index == lastIndex) { data.pop(); } else { splice.call(data, index, 1); } --this.size; return true; } /** * Gets the list cache value for `key`. * * @private * @name get * @memberOf ListCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function listCacheGet(key) { var data = this.__data__, index = assocIndexOf(data, key); return index < 0 ? undefined : data[index][1]; } /** * Checks if a list cache value for `key` exists. * * @private * @name has * @memberOf ListCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function listCacheHas(key) { return assocIndexOf(this.__data__, key) > -1; } /** * Sets the list cache `key` to `value`. * * @private * @name set * @memberOf ListCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the list cache instance. */ function listCacheSet(key, value) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { ++this.size; data.push([key, value]); } else { data[index][1] = value; } return this; } // Add methods to `ListCache`. ListCache.prototype.clear = listCacheClear; ListCache.prototype['delete'] = listCacheDelete; ListCache.prototype.get = listCacheGet; ListCache.prototype.has = listCacheHas; ListCache.prototype.set = listCacheSet; /* ------------------------------------------------------------------------*/ /** * Creates a map cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } /** * Removes all key-value entries from the map. * * @private * @name clear * @memberOf MapCache */ function mapCacheClear() { this.size = 0; this.__data__ = { hash: new Hash(), map: new (Map || ListCache)(), string: new Hash() }; } /** * Removes `key` and its value from the map. * * @private * @name delete * @memberOf MapCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapCacheDelete(key) { var result = getMapData(this, key)['delete'](key); this.size -= result ? 1 : 0; return result; } /** * Gets the map value for `key`. * * @private * @name get * @memberOf MapCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function mapCacheGet(key) { return getMapData(this, key).get(key); } /** * Checks if a map value for `key` exists. * * @private * @name has * @memberOf MapCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapCacheHas(key) { return getMapData(this, key).has(key); } /** * Sets the map `key` to `value`. * * @private * @name set * @memberOf MapCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the map cache instance. */ function mapCacheSet(key, value) { var data = getMapData(this, key), size = data.size; data.set(key, value); this.size += data.size == size ? 0 : 1; return this; } // Add methods to `MapCache`. MapCache.prototype.clear = mapCacheClear; MapCache.prototype['delete'] = mapCacheDelete; MapCache.prototype.get = mapCacheGet; MapCache.prototype.has = mapCacheHas; MapCache.prototype.set = mapCacheSet; /* ------------------------------------------------------------------------*/ /** * * Creates an array cache object to store unique values. * * @private * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { var index = -1, length = values == null ? 0 : values.length; this.__data__ = new MapCache(); while (++index < length) { this.add(values[index]); } } /** * Adds `value` to the array cache. * * @private * @name add * @memberOf SetCache * @alias push * @param {*} value The value to cache. * @returns {Object} Returns the cache instance. */ function setCacheAdd(value) { this.__data__.set(value, HASH_UNDEFINED); return this; } /** * Checks if `value` is in the array cache. * * @private * @name has * @memberOf SetCache * @param {*} value The value to search for. * @returns {number} Returns `true` if `value` is found, else `false`. */ function setCacheHas(value) { return this.__data__.has(value); } // Add methods to `SetCache`. SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; SetCache.prototype.has = setCacheHas; /* ------------------------------------------------------------------------*/ /** * Creates a stack cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { var data = (this.__data__ = new ListCache(entries)); this.size = data.size; } /** * Removes all key-value entries from the stack. * * @private * @name clear * @memberOf Stack */ function stackClear() { this.__data__ = new ListCache(); this.size = 0; } /** * Removes `key` and its value from the stack. * * @private * @name delete * @memberOf Stack * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { var data = this.__data__, result = data['delete'](key); this.size = data.size; return result; } /** * Gets the stack value for `key`. * * @private * @name get * @memberOf Stack * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function stackGet(key) { return this.__data__.get(key); } /** * Checks if a stack value for `key` exists. * * @private * @name has * @memberOf Stack * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { return this.__data__.has(key); } /** * Sets the stack `key` to `value`. * * @private * @name set * @memberOf Stack * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { var data = this.__data__; if (data instanceof ListCache) { var pairs = data.__data__; if (!Map || pairs.length < LARGE_ARRAY_SIZE - 1) { pairs.push([key, value]); this.size = ++data.size; return this; } data = this.__data__ = new MapCache(pairs); } data.set(key, value); this.size = data.size; return this; } // Add methods to `Stack`. Stack.prototype.clear = stackClear; Stack.prototype['delete'] = stackDelete; Stack.prototype.get = stackGet; Stack.prototype.has = stackHas; Stack.prototype.set = stackSet; /* ------------------------------------------------------------------------*/ /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length; for (var key in value) { if ( (inherited || hasOwnProperty.call(value, key)) && !( skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode. (key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. (isBuff && (key == 'offset' || key == 'parent')) || // PhantomJS 2 has enumerable non-index properties on typed arrays. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || // Skip index properties. isIndex(key, length)) ) ) { result.push(key); } } return result; } /** * A specialized version of `_.sample` for arrays. * * @private * @param {Array} array The array to sample. * @returns {*} Returns the random element. */ function arraySample(array) { var length = array.length; return length ? array[baseRandom(0, length - 1)] : undefined; } /** * A specialized version of `_.sampleSize` for arrays. * * @private * @param {Array} array The array to sample. * @param {number} n The number of elements to sample. * @returns {Array} Returns the random elements. */ function arraySampleSize(array, n) { return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); } /** * A specialized version of `_.shuffle` for arrays. * * @private * @param {Array} array The array to shuffle. * @returns {Array} Returns the new shuffled array. */ function arrayShuffle(array) { return shuffleSelf(copyArray(array)); } /** * This function is like `assignValue` except that it doesn't assign * `undefined` values. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignMergeValue(object, key, value) { if ( (value !== undefined && !eq(object[key], value)) || (value === undefined && !(key in object)) ) { baseAssignValue(object, key, value); } } /** * Assigns `value` to `key` of `object` if the existing value is not equivalent * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignValue(object, key, value) { var objValue = object[key]; if ( !(hasOwnProperty.call(object, key) && eq(objValue, value)) || (value === undefined && !(key in object)) ) { baseAssignValue(object, key, value); } } /** * Gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {Array} array The array to inspect. * @param {*} key The key to search for. * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { var length = array.length; while (length--) { if (eq(array[length][0], key)) { return length; } } return -1; } /** * Aggregates elements of `collection` on `accumulator` with keys transformed * by `iteratee` and values set by `setter`. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. * @returns {Function} Returns `accumulator`. */ function baseAggregator(collection, setter, iteratee, accumulator) { baseEach(collection, function(value, key, collection) { setter(accumulator, value, iteratee(value), collection); }); return accumulator; } /** * The base implementation of `_.assign` without support for multiple sources * or `customizer` functions. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @returns {Object} Returns `object`. */ function baseAssign(object, source) { return object && copyObject(source, keys(source), object); } /** * The base implementation of `_.assignIn` without support for multiple sources * or `customizer` functions. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @returns {Object} Returns `object`. */ function baseAssignIn(object, source) { return object && copyObject(source, keysIn(source), object); } /** * The base implementation of `assignValue` and `assignMergeValue` without * value checks. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function baseAssignValue(object, key, value) { if (key == '__proto__' && defineProperty) { defineProperty(object, key, { configurable: true, enumerable: true, value: value, writable: true }); } else { object[key] = value; } } /** * The base implementation of `_.at` without support for individual paths. * * @private * @param {Object} object The object to iterate over. * @param {string[]} paths The property paths to pick. * @returns {Array} Returns the picked elements. */ function baseAt(object, paths) { var index = -1, length = paths.length, result = Array(length), skip = object == null; while (++index < length) { result[index] = skip ? undefined : get(object, paths[index]); } return result; } /** * The base implementation of `_.clamp` which doesn't coerce arguments. * * @private * @param {number} number The number to clamp. * @param {number} [lower] The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the clamped number. */ function baseClamp(number, lower, upper) { if (number === number) { if (upper !== undefined) { number = number <= upper ? number : upper; } if (lower !== undefined) { number = number >= lower ? number : lower; } } return number; } /** * The base implementation of `_.clone` and `_.cloneDeep` which tracks * traversed objects. * * @private * @param {*} value The value to clone. * @param {boolean} bitmask The bitmask flags. * 1 - Deep clone * 2 - Flatten inherited properties * 4 - Clone symbols * @param {Function} [customizer] The function to customize cloning. * @param {string} [key] The key of `value`. * @param {Object} [object] The parent object of `value`. * @param {Object} [stack] Tracks traversed objects and their clone counterparts. * @returns {*} Returns the cloned value. */ function baseClone(value, bitmask, customizer, key, object, stack) { var result, isDeep = bitmask & CLONE_DEEP_FLAG, isFlat = bitmask & CLONE_FLAT_FLAG, isFull = bitmask & CLONE_SYMBOLS_FLAG; if (customizer) { result = object ? customizer(value, key, object, stack) : customizer(value); } if (result !== undefined) { return result; } if (!isObject(value)) { return value; } var isArr = isArray(value); if (isArr) { result = initCloneArray(value); if (!isDeep) { return copyArray(value, result); } } else { var tag = getTag(value), isFunc = tag == funcTag || tag == genTag; if (isBuffer(value)) { return cloneBuffer(value, isDeep); } if (tag == objectTag || tag == argsTag || (isFunc && !object)) { result = isFlat || isFunc ? {} : initCloneObject(value); if (!isDeep) { return isFlat ? copySymbolsIn(value, baseAssignIn(result, value)) : copySymbols(value, baseAssign(result, value)); } } else { if (!cloneableTags[tag]) { return object ? value : {}; } result = initCloneByTag(value, tag, isDeep); } } // Check for circular references and return its corresponding clone. stack || (stack = new Stack()); var stacked = stack.get(value); if (stacked) { return stacked; } stack.set(value, result); if (isSet(value)) { value.forEach(function(subValue) { result.add( baseClone(subValue, bitmask, customizer, subValue, value, stack) ); }); return result; } if (isMap(value)) { value.forEach(function(subValue, key) { result.set( key, baseClone(subValue, bitmask, customizer, key, value, stack) ); }); return result; } var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys : isFlat ? keysIn : keys; var props = isArr ? undefined : keysFunc(value); arrayEach(props || value, function(subValue, key) { if (props) { key = subValue; subValue = value[key]; } // Recursively populate clone (susceptible to call stack limits). assignValue( result, key, baseClone(subValue, bitmask, customizer, key, value, stack) ); }); return result; } /** * The base implementation of `_.conforms` which doesn't clone `source`. * * @private * @param {Object} source The object of property predicates to conform to. * @returns {Function} Returns the new spec function. */ function baseConforms(source) { var props = keys(source); return function(object) { return baseConformsTo(object, source, props); }; } /** * The base implementation of `_.conformsTo` which accepts `props` to check. * * @private * @param {Object} object The object to inspect. * @param {Object} source The object of property predicates to conform to. * @returns {boolean} Returns `true` if `object` conforms, else `false`. */ function baseConformsTo(object, source, props) { var length = props.length; if (object == null) { return !length; } object = Object(object); while (length--) { var key = props[length], predicate = source[key], value = object[key]; if ((value === undefined && !(key in object)) || !predicate(value)) { return false; } } return true; } /** * The base implementation of `_.delay` and `_.defer` which accepts `args` * to provide to `func`. * * @private * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. * @param {Array} args The arguments to provide to `func`. * @returns {number|Object} Returns the timer id or timeout object. */ function baseDelay(func, wait, args) { if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } return setTimeout(function() { func.apply(undefined, args); }, wait); } /** * The base implementation of methods like `_.difference` without support * for excluding multiple arrays or iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Array} values The values to exclude. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. */ function baseDifference(array, values, iteratee, comparator) { var index = -1, includes = arrayIncludes, isCommon = true, length = array.length, result = [], valuesLength = values.length; if (!length) { return result; } if (iteratee) { values = arrayMap(values, baseUnary(iteratee)); } if (comparator) { includes = arrayIncludesWith; isCommon = false; } else if (values.length >= LARGE_ARRAY_SIZE) { includes = cacheHas; isCommon = false; values = new SetCache(values); } outer: while (++index < length) { var value = array[index], computed = iteratee == null ? value : iteratee(value); value = comparator || value !== 0 ? value : 0; if (isCommon && computed === computed) { var valuesIndex = valuesLength; while (valuesIndex--) { if (values[valuesIndex] === computed) { continue outer; } } result.push(value); } else if (!includes(values, computed, comparator)) { result.push(value); } } return result; } /** * The base implementation of `_.forEach` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object} Returns `collection`. */ var baseEach = createBaseEach(baseForOwn); /** * The base implementation of `_.forEachRight` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object} Returns `collection`. */ var baseEachRight = createBaseEach(baseForOwnRight, true); /** * The base implementation of `_.every` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false` */ function baseEvery(collection, predicate) { var result = true; baseEach(collection, function(value, index, collection) { result = !!predicate(value, index, collection); return result; }); return result; } /** * The base implementation of methods like `_.max` and `_.min` which accepts a * `comparator` to determine the extremum value. * * @private * @param {Array} array The array to iterate over. * @param {Function} iteratee The iteratee invoked per iteration. * @param {Function} comparator The comparator used to compare values. * @returns {*} Returns the extremum value. */ function baseExtremum(array, iteratee, comparator) { var index = -1, length = array.length; while (++index < length) { var value = array[index], current = iteratee(value); if ( current != null && (computed === undefined ? current === current && !isSymbol(current) : comparator(current, computed)) ) { var computed = current, result = value; } } return result; } /** * The base implementation of `_.fill` without an iteratee call guard. * * @private * @param {Array} array The array to fill. * @param {*} value The value to fill `array` with. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns `array`. */ function baseFill(array, value, start, end) { var length = array.length; start = toInteger(start); if (start < 0) { start = -start > length ? 0 : length + start; } end = end === undefined || end > length ? length : toInteger(end); if (end < 0) { end += length; } end = start > end ? 0 : toLength(end); while (start < end) { array[start++] = value; } return array; } /** * The base implementation of `_.filter` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function baseFilter(collection, predicate) { var result = []; baseEach(collection, function(value, index, collection) { if (predicate(value, index, collection)) { result.push(value); } }); return result; } /** * The base implementation of `_.flatten` with support for restricting flattening. * * @private * @param {Array} array The array to flatten. * @param {number} depth The maximum recursion depth. * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ function baseFlatten(array, depth, predicate, isStrict, result) { var index = -1, length = array.length; predicate || (predicate = isFlattenable); result || (result = []); while (++index < length) { var value = array[index]; if (depth > 0 && predicate(value)) { if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). baseFlatten(value, depth - 1, predicate, isStrict, result); } else { arrayPush(result, value); } } else if (!isStrict) { result[result.length] = value; } } return result; } /** * The base implementation of `baseForOwn` which iterates over `object` * properties returned by `keysFunc` and invokes `iteratee` for each property. * Iteratee functions may exit iteration early by explicitly returning `false`. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ var baseFor = createBaseFor(); /** * This function is like `baseFor` except that it iterates over properties * in the opposite order. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ var baseForRight = createBaseFor(true); /** * The base implementation of `_.forOwn` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Object} Returns `object`. */ function baseForOwn(object, iteratee) { return object && baseFor(object, iteratee, keys); } /** * The base implementation of `_.forOwnRight` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Object} Returns `object`. */ function baseForOwnRight(object, iteratee) { return object && baseForRight(object, iteratee, keys); } /** * The base implementation of `_.functions` which creates an array of * `object` function property names filtered from `props`. * * @private * @param {Object} object The object to inspect. * @param {Array} props The property names to filter. * @returns {Array} Returns the function names. */ function baseFunctions(object, props) { return arrayFilter(props, function(key) { return isFunction(object[key]); }); } /** * The base implementation of `_.get` without support for default values. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @returns {*} Returns the resolved value. */ function baseGet(object, path) { path = castPath(path, object); var index = 0, length = path.length; while (object != null && index < length) { object = object[toKey(path[index++])]; } return index && index == length ? object : undefined; } /** * The base implementation of `getAllKeys` and `getAllKeysIn` which uses * `keysFunc` and `symbolsFunc` to get the enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @param {Function} keysFunc The function to get the keys of `object`. * @param {Function} symbolsFunc The function to get the symbols of `object`. * @returns {Array} Returns the array of property names and symbols. */ function baseGetAllKeys(object, keysFunc, symbolsFunc) { var result = keysFunc(object); return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); } /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); } /** * The base implementation of `_.gt` which doesn't coerce arguments. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than `other`, * else `false`. */ function baseGt(value, other) { return value > other; } /** * The base implementation of `_.has` without support for deep paths. * * @private * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ function baseHas(object, key) { return object != null && hasOwnProperty.call(object, key); } /** * The base implementation of `_.hasIn` without support for deep paths. * * @private * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ function baseHasIn(object, key) { return object != null && key in Object(object); } /** * The base implementation of `_.inRange` which doesn't coerce arguments. * * @private * @param {number} number The number to check. * @param {number} start The start of the range. * @param {number} end The end of the range. * @returns {boolean} Returns `true` if `number` is in the range, else `false`. */ function baseInRange(number, start, end) { return number >= nativeMin(start, end) && number < nativeMax(start, end); } /** * The base implementation of methods like `_.intersection`, without support * for iteratee shorthands, that accepts an array of arrays to inspect. * * @private * @param {Array} arrays The arrays to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of shared values. */ function baseIntersection(arrays, iteratee, comparator) { var includes = comparator ? arrayIncludesWith : arrayIncludes, length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array(othLength), maxLength = Infinity, result = []; while (othIndex--) { var array = arrays[othIndex]; if (othIndex && iteratee) { array = arrayMap(array, baseUnary(iteratee)); } maxLength = nativeMin(array.length, maxLength); caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) ? new SetCache(othIndex && array) : undefined; } array = arrays[0]; var index = -1, seen = caches[0]; outer: while (++index < length && result.length < maxLength) { var value = array[index], computed = iteratee ? iteratee(value) : value; value = comparator || value !== 0 ? value : 0; if ( !(seen ? cacheHas(seen, computed) : includes(result, computed, comparator)) ) { othIndex = othLength; while (--othIndex) { var cache = caches[othIndex]; if ( !(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator)) ) { continue outer; } } if (seen) { seen.push(computed); } result.push(value); } } return result; } /** * The base implementation of `_.invert` and `_.invertBy` which inverts * `object` with values transformed by `iteratee` and set by `setter`. * * @private * @param {Object} object The object to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform values. * @param {Object} accumulator The initial inverted object. * @returns {Function} Returns `accumulator`. */ function baseInverter(object, setter, iteratee, accumulator) { baseForOwn(object, function(value, key, object) { setter(accumulator, iteratee(value), key, object); }); return accumulator; } /** * The base implementation of `_.invoke` without support for individual * method arguments. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path of the method to invoke. * @param {Array} args The arguments to invoke the method with. * @returns {*} Returns the result of the invoked method. */ function baseInvoke(object, path, args) { path = castPath(path, object); object = parent(object, path); var func = object == null ? object : object[toKey(last(path))]; return func == null ? undefined : apply(func, object, args); } /** * The base implementation of `_.isArguments`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, */ function baseIsArguments(value) { return isObjectLike(value) && baseGetTag(value) == argsTag; } /** * The base implementation of `_.isArrayBuffer` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. */ function baseIsArrayBuffer(value) { return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; } /** * The base implementation of `_.isDate` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a date object, else `false`. */ function baseIsDate(value) { return isObjectLike(value) && baseGetTag(value) == dateTag; } /** * The base implementation of `_.isEqual` which supports partial comparisons * and tracks traversed objects. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {boolean} bitmask The bitmask flags. * 1 - Unordered comparison * 2 - Partial comparison * @param {Function} [customizer] The function to customize comparisons. * @param {Object} [stack] Tracks traversed `value` and `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ function baseIsEqual(value, other, bitmask, customizer, stack) { if (value === other) { return true; } if ( value == null || other == null || (!isObjectLike(value) && !isObjectLike(other)) ) { return value !== value && other !== other; } return baseIsEqualDeep( value, other, bitmask, customizer, baseIsEqual, stack ); } /** * A specialized version of `baseIsEqual` for arrays and objects which performs * deep comparisons and tracks traversed objects enabling objects with circular * references to be compared. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function baseIsEqualDeep( object, other, bitmask, customizer, equalFunc, stack ) { var objIsArr = isArray(object), othIsArr = isArray(other), objTag = objIsArr ? arrayTag : getTag(object), othTag = othIsArr ? arrayTag : getTag(other); objTag = objTag == argsTag ? objectTag : objTag; othTag = othTag == argsTag ? objectTag : othTag; var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; if (isSameTag && isBuffer(object)) { if (!isBuffer(other)) { return false; } objIsArr = true; objIsObj = false; } if (isSameTag && !objIsObj) { stack || (stack = new Stack()); return objIsArr || isTypedArray(object) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag( object, other, objTag, bitmask, customizer, equalFunc, stack ); } if (!(bitmask & COMPARE_PARTIAL_FLAG)) { var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (objIsWrapped || othIsWrapped) { var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; stack || (stack = new Stack()); return equalFunc( objUnwrapped, othUnwrapped, bitmask, customizer, stack ); } } if (!isSameTag) { return false; } stack || (stack = new Stack()); return equalObjects(object, other, bitmask, customizer, equalFunc, stack); } /** * The base implementation of `_.isMap` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a map, else `false`. */ function baseIsMap(value) { return isObjectLike(value) && getTag(value) == mapTag; } /** * The base implementation of `_.isMatch` without support for iteratee shorthands. * * @private * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @param {Array} matchData The property names, values, and compare flags to match. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ function baseIsMatch(object, source, matchData, customizer) { var index = matchData.length, length = index, noCustomizer = !customizer; if (object == null) { return !length; } object = Object(object); while (index--) { var data = matchData[index]; if ( noCustomizer && data[2] ? data[1] !== object[data[0]] : !(data[0] in object) ) { return false; } } while (++index < length) { data = matchData[index]; var key = data[0], objValue = object[key], srcValue = data[1]; if (noCustomizer && data[2]) { if (objValue === undefined && !(key in object)) { return false; } } else { var stack = new Stack(); if (customizer) { var result = customizer( objValue, srcValue, key, object, source, stack ); } if ( !(result === undefined ? baseIsEqual( srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack ) : result) ) { return false; } } } return true; } /** * The base implementation of `_.isNative` without bad shim checks. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. */ function baseIsNative(value) { if (!isObject(value) || isMasked(value)) { return false; } var pattern = isFunction(value) ? reIsNative : reIsHostCtor; return pattern.test(toSource(value)); } /** * The base implementation of `_.isRegExp` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. */ function baseIsRegExp(value) { return isObjectLike(value) && baseGetTag(value) == regexpTag; } /** * The base implementation of `_.isSet` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a set, else `false`. */ function baseIsSet(value) { return isObjectLike(value) && getTag(value) == setTag; } /** * The base implementation of `_.isTypedArray` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ function baseIsTypedArray(value) { return ( isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)] ); } /** * The base implementation of `_.iteratee`. * * @private * @param {*} [value=_.identity] The value to convert to an iteratee. * @returns {Function} Returns the iteratee. */ function baseIteratee(value) { // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. if (typeof value === 'function') { return value; } if (value == null) { return identity; } if (typeof value === 'object') { return isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value); } return property(value); } /** * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeys(object) { if (!isPrototype(object)) { return nativeKeys(object); } var result = []; for (var key in Object(object)) { if (hasOwnProperty.call(object, key) && key != 'constructor') { result.push(key); } } return result; } /** * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeysIn(object) { if (!isObject(object)) { return nativeKeysIn(object); } var isProto = isPrototype(object), result = []; for (var key in object) { if ( !( key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)) ) ) { result.push(key); } } return result; } /** * The base implementation of `_.lt` which doesn't coerce arguments. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than `other`, * else `false`. */ function baseLt(value, other) { return value < other; } /** * The base implementation of `_.map` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function baseMap(collection, iteratee) { var index = -1, result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value, key, collection) { result[++index] = iteratee(value, key, collection); }); return result; } /** * The base implementation of `_.matches` which doesn't clone `source`. * * @private * @param {Object} source The object of property values to match. * @returns {Function} Returns the new spec function. */ function baseMatches(source) { var matchData = getMatchData(source); if (matchData.length == 1 && matchData[0][2]) { return matchesStrictComparable(matchData[0][0], matchData[0][1]); } return function(object) { return object === source || baseIsMatch(object, source, matchData); }; } /** * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. * * @private * @param {string} path The path of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function baseMatchesProperty(path, srcValue) { if (isKey(path) && isStrictComparable(srcValue)) { return matchesStrictComparable(toKey(path), srcValue); } return function(object) { var objValue = get(object, path); return objValue === undefined && objValue === srcValue ? hasIn(object, path) : baseIsEqual( srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG ); }; } /** * The base implementation of `_.merge` without support for multiple sources. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @param {number} srcIndex The index of `source`. * @param {Function} [customizer] The function to customize merged values. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. */ function baseMerge(object, source, srcIndex, customizer, stack) { if (object === source) { return; } baseFor( source, function(srcValue, key) { if (isObject(srcValue)) { stack || (stack = new Stack()); baseMergeDeep( object, source, key, srcIndex, baseMerge, customizer, stack ); } else { var newValue = customizer ? customizer( safeGet(object, key), srcValue, key + '', object, source, stack ) : undefined; if (newValue === undefined) { newValue = srcValue; } assignMergeValue(object, key, newValue); } }, keysIn ); } /** * A specialized version of `baseMerge` for arrays and objects which performs * deep merges and tracks traversed objects enabling objects with circular * references to be merged. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @param {string} key The key of the value to merge. * @param {number} srcIndex The index of `source`. * @param {Function} mergeFunc The function to merge values. * @param {Function} [customizer] The function to customize assigned values. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. */ function baseMergeDeep( object, source, key, srcIndex, mergeFunc, customizer, stack ) { var objValue = safeGet(object, key), srcValue = safeGet(source, key), stacked = stack.get(srcValue); if (stacked) { assignMergeValue(object, key, stacked); return; } var newValue = customizer ? customizer(objValue, srcValue, key + '', object, source, stack) : undefined; var isCommon = newValue === undefined; if (isCommon) { var isArr = isArray(srcValue), isBuff = !isArr && isBuffer(srcValue), isTyped = !isArr && !isBuff && isTypedArray(srcValue); newValue = srcValue; if (isArr || isBuff || isTyped) { if (isArray(objValue)) { newValue = objValue; } else if (isArrayLikeObject(objValue)) { newValue = copyArray(objValue); } else if (isBuff) { isCommon = false; newValue = cloneBuffer(srcValue, true); } else if (isTyped) { isCommon = false; newValue = cloneTypedArray(srcValue, true); } else { newValue = []; } } else if (isPlainObject(srcValue) || isArguments(srcValue)) { newValue = objValue; if (isArguments(objValue)) { newValue = toPlainObject(objValue); } else if ( !isObject(objValue) || (srcIndex && isFunction(objValue)) ) { newValue = initCloneObject(srcValue); } } else { isCommon = false; } } if (isCommon) { // Recursively merge objects and arrays (susceptible to call stack limits). stack.set(srcValue, newValue); mergeFunc(newValue, srcValue, srcIndex, customizer, stack); stack['delete'](srcValue); } assignMergeValue(object, key, newValue); } /** * The base implementation of `_.nth` which doesn't coerce arguments. * * @private * @param {Array} array The array to query. * @param {number} n The index of the element to return. * @returns {*} Returns the nth element of `array`. */ function baseNth(array, n) { var length = array.length; if (!length) { return; } n += n < 0 ? length : 0; return isIndex(n, length) ? array[n] : undefined; } /** * The base implementation of `_.orderBy` without param guards. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. * @param {string[]} orders The sort orders of `iteratees`. * @returns {Array} Returns the new sorted array. */ function baseOrderBy(collection, iteratees, orders) { var index = -1; iteratees = arrayMap( iteratees.length ? iteratees : [identity], baseUnary(getIteratee()) ); var result = baseMap(collection, function(value, key, collection) { var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); return { criteria: criteria, index: ++index, value: value }; }); return baseSortBy(result, function(object, other) { return compareMultiple(object, other, orders); }); } /** * The base implementation of `_.pick` without support for individual * property identifiers. * * @private * @param {Object} object The source object. * @param {string[]} paths The property paths to pick. * @returns {Object} Returns the new object. */ function basePick(object, paths) { return basePickBy(object, paths, function(value, path) { return hasIn(object, path); }); } /** * The base implementation of `_.pickBy` without support for iteratee shorthands. * * @private * @param {Object} object The source object. * @param {string[]} paths The property paths to pick. * @param {Function} predicate The function invoked per property. * @returns {Object} Returns the new object. */ function basePickBy(object, paths, predicate) { var index = -1, length = paths.length, result = {}; while (++index < length) { var path = paths[index], value = baseGet(object, path); if (predicate(value, path)) { baseSet(result, castPath(path, object), value); } } return result; } /** * A specialized version of `baseProperty` which supports deep paths. * * @private * @param {Array|string} path The path of the property to get. * @returns {Function} Returns the new accessor function. */ function basePropertyDeep(path) { return function(object) { return baseGet(object, path); }; } /** * The base implementation of `_.pullAllBy` without support for iteratee * shorthands. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns `array`. */ function basePullAll(array, values, iteratee, comparator) { var indexOf = comparator ? baseIndexOfWith : baseIndexOf, index = -1, length = values.length, seen = array; if (array === values) { values = copyArray(values); } if (iteratee) { seen = arrayMap(array, baseUnary(iteratee)); } while (++index < length) { var fromIndex = 0, value = values[index], computed = iteratee ? iteratee(value) : value; while ( (fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1 ) { if (seen !== array) { splice.call(seen, fromIndex, 1); } splice.call(array, fromIndex, 1); } } return array; } /** * The base implementation of `_.pullAt` without support for individual * indexes or capturing the removed elements. * * @private * @param {Array} array The array to modify. * @param {number[]} indexes The indexes of elements to remove. * @returns {Array} Returns `array`. */ function basePullAt(array, indexes) { var length = array ? indexes.length : 0, lastIndex = length - 1; while (length--) { var index = indexes[length]; if (length == lastIndex || index !== previous) { var previous = index; if (isIndex(index)) { splice.call(array, index, 1); } else { baseUnset(array, index); } } } return array; } /** * The base implementation of `_.random` without support for returning * floating-point numbers. * * @private * @param {number} lower The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the random number. */ function baseRandom(lower, upper) { return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); } /** * The base implementation of `_.range` and `_.rangeRight` which doesn't * coerce arguments. * * @private * @param {number} start The start of the range. * @param {number} end The end of the range. * @param {number} step The value to increment or decrement by. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Array} Returns the range of numbers. */ function baseRange(start, end, step, fromRight) { var index = -1, length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result = Array(length); while (length--) { result[fromRight ? length : ++index] = start; start += step; } return result; } /** * The base implementation of `_.repeat` which doesn't coerce arguments. * * @private * @param {string} string The string to repeat. * @param {number} n The number of times to repeat the string. * @returns {string} Returns the repeated string. */ function baseRepeat(string, n) { var result = ''; if (!string || n < 1 || n > MAX_SAFE_INTEGER) { return result; } // Leverage the exponentiation by squaring algorithm for a faster repeat. // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. do { if (n % 2) { result += string; } n = nativeFloor(n / 2); if (n) { string += string; } } while (n); return result; } /** * The base implementation of `_.rest` which doesn't validate or coerce arguments. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @returns {Function} Returns the new function. */ function baseRest(func, start) { return setToString(overRest(func, start, identity), func + ''); } /** * The base implementation of `_.sample`. * * @private * @param {Array|Object} collection The collection to sample. * @returns {*} Returns the random element. */ function baseSample(collection) { return arraySample(values(collection)); } /** * The base implementation of `_.sampleSize` without param guards. * * @private * @param {Array|Object} collection The collection to sample. * @param {number} n The number of elements to sample. * @returns {Array} Returns the random elements. */ function baseSampleSize(collection, n) { var array = values(collection); return shuffleSelf(array, baseClamp(n, 0, array.length)); } /** * The base implementation of `_.set`. * * @private * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {*} value The value to set. * @param {Function} [customizer] The function to customize path creation. * @returns {Object} Returns `object`. */ function baseSet(object, path, value, customizer) { if (!isObject(object)) { return object; } path = castPath(path, object); var index = -1, length = path.length, lastIndex = length - 1, nested = object; while (nested != null && ++index < length) { var key = toKey(path[index]), newValue = value; if (index != lastIndex) { var objValue = nested[key]; newValue = customizer ? customizer(objValue, key, nested) : undefined; if (newValue === undefined) { newValue = isObject(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {}; } } assignValue(nested, key, newValue); nested = nested[key]; } return object; } /** * The base implementation of `setData` without support for hot loop shorting. * * @private * @param {Function} func The function to associate metadata with. * @param {*} data The metadata. * @returns {Function} Returns `func`. */ var baseSetData = !metaMap ? identity : function(func, data) { metaMap.set(func, data); return func; }; /** * The base implementation of `setToString` without support for hot loop shorting. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var baseSetToString = !defineProperty ? identity : function(func, string) { return defineProperty(func, 'toString', { configurable: true, enumerable: false, value: constant(string), writable: true }); }; /** * The base implementation of `_.shuffle`. * * @private * @param {Array|Object} collection The collection to shuffle. * @returns {Array} Returns the new shuffled array. */ function baseShuffle(collection) { return shuffleSelf(values(collection)); } /** * The base implementation of `_.slice` without an iteratee call guard. * * @private * @param {Array} array The array to slice. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns the slice of `array`. */ function baseSlice(array, start, end) { var index = -1, length = array.length; if (start < 0) { start = -start > length ? 0 : length + start; } end = end > length ? length : end; if (end < 0) { end += length; } length = start > end ? 0 : (end - start) >>> 0; start >>>= 0; var result = Array(length); while (++index < length) { result[index] = array[index + start]; } return result; } /** * The base implementation of `_.some` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function baseSome(collection, predicate) { var result; baseEach(collection, function(value, index, collection) { result = predicate(value, index, collection); return !result; }); return !!result; } /** * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which * performs a binary search of `array` to determine the index at which `value` * should be inserted into `array` in order to maintain its sort order. * * @private * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {boolean} [retHighest] Specify returning the highest qualified index. * @returns {number} Returns the index at which `value` should be inserted * into `array`. */ function baseSortedIndex(array, value, retHighest) { var low = 0, high = array == null ? low : array.length; if ( typeof value === 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH ) { while (low < high) { var mid = (low + high) >>> 1, computed = array[mid]; if ( computed !== null && !isSymbol(computed) && (retHighest ? computed <= value : computed < value) ) { low = mid + 1; } else { high = mid; } } return high; } return baseSortedIndexBy(array, value, identity, retHighest); } /** * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` * which invokes `iteratee` for `value` and each element of `array` to compute * their sort ranking. The iteratee is invoked with one argument; (value). * * @private * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {Function} iteratee The iteratee invoked per element. * @param {boolean} [retHighest] Specify returning the highest qualified index. * @returns {number} Returns the index at which `value` should be inserted * into `array`. */ function baseSortedIndexBy(array, value, iteratee, retHighest) { value = iteratee(value); var low = 0, high = array == null ? 0 : array.length, valIsNaN = value !== value, valIsNull = value === null, valIsSymbol = isSymbol(value), valIsUndefined = value === undefined; while (low < high) { var mid = nativeFloor((low + high) / 2), computed = iteratee(array[mid]), othIsDefined = computed !== undefined, othIsNull = computed === null, othIsReflexive = computed === computed, othIsSymbol = isSymbol(computed); if (valIsNaN) { var setLow = retHighest || othIsReflexive; } else if (valIsUndefined) { setLow = othIsReflexive && (retHighest || othIsDefined); } else if (valIsNull) { setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); } else if (valIsSymbol) { setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); } else if (othIsNull || othIsSymbol) { setLow = false; } else { setLow = retHighest ? computed <= value : computed < value; } if (setLow) { low = mid + 1; } else { high = mid; } } return nativeMin(high, MAX_ARRAY_INDEX); } /** * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without * support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @returns {Array} Returns the new duplicate free array. */ function baseSortedUniq(array, iteratee) { var index = -1, length = array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index], computed = iteratee ? iteratee(value) : value; if (!index || !eq(computed, seen)) { var seen = computed; result[resIndex++] = value === 0 ? 0 : value; } } return result; } /** * The base implementation of `_.toNumber` which doesn't ensure correct * conversions of binary, hexadecimal, or octal string values. * * @private * @param {*} value The value to process. * @returns {number} Returns the number. */ function baseToNumber(value) { if (typeof value === 'number') { return value; } if (isSymbol(value)) { return NAN; } return +value; } /** * The base implementation of `_.toString` which doesn't convert nullish * values to empty strings. * * @private * @param {*} value The value to process. * @returns {string} Returns the string. */ function baseToString(value) { // Exit early for strings to avoid a performance hit in some environments. if (typeof value === 'string') { return value; } if (isArray(value)) { // Recursively convert values (susceptible to call stack limits). return arrayMap(value, baseToString) + ''; } if (isSymbol(value)) { return symbolToString ? symbolToString.call(value) : ''; } var result = value + ''; return result == '0' && 1 / value == -INFINITY ? '-0' : result; } /** * The base implementation of `_.uniqBy` without support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new duplicate free array. */ function baseUniq(array, iteratee, comparator) { var index = -1, includes = arrayIncludes, length = array.length, isCommon = true, result = [], seen = result; if (comparator) { isCommon = false; includes = arrayIncludesWith; } else if (length >= LARGE_ARRAY_SIZE) { var set = iteratee ? null : createSet(array); if (set) { return setToArray(set); } isCommon = false; includes = cacheHas; seen = new SetCache(); } else { seen = iteratee ? [] : result; } outer: while (++index < length) { var value = array[index], computed = iteratee ? iteratee(value) : value; value = comparator || value !== 0 ? value : 0; if (isCommon && computed === computed) { var seenIndex = seen.length; while (seenIndex--) { if (seen[seenIndex] === computed) { continue outer; } } if (iteratee) { seen.push(computed); } result.push(value); } else if (!includes(seen, computed, comparator)) { if (seen !== result) { seen.push(computed); } result.push(value); } } return result; } /** * The base implementation of `_.unset`. * * @private * @param {Object} object The object to modify. * @param {Array|string} path The property path to unset. * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ function baseUnset(object, path) { path = castPath(path, object); object = parent(object, path); return object == null || delete object[toKey(last(path))]; } /** * The base implementation of `_.update`. * * @private * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to update. * @param {Function} updater The function to produce the updated value. * @param {Function} [customizer] The function to customize path creation. * @returns {Object} Returns `object`. */ function baseUpdate(object, path, updater, customizer) { return baseSet(object, path, updater(baseGet(object, path)), customizer); } /** * The base implementation of methods like `_.dropWhile` and `_.takeWhile` * without support for iteratee shorthands. * * @private * @param {Array} array The array to query. * @param {Function} predicate The function invoked per iteration. * @param {boolean} [isDrop] Specify dropping elements instead of taking them. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Array} Returns the slice of `array`. */ function baseWhile(array, predicate, isDrop, fromRight) { var length = array.length, index = fromRight ? length : -1; while ( (fromRight ? index-- : ++index < length) && predicate(array[index], index, array) ) { } return isDrop ? baseSlice( array, fromRight ? 0 : index, fromRight ? index + 1 : length ) : baseSlice( array, fromRight ? index + 1 : 0, fromRight ? length : index ); } /** * The base implementation of `wrapperValue` which returns the result of * performing a sequence of actions on the unwrapped `value`, where each * successive action is supplied the return value of the previous. * * @private * @param {*} value The unwrapped value. * @param {Array} actions Actions to perform to resolve the unwrapped value. * @returns {*} Returns the resolved value. */ function baseWrapperValue(value, actions) { var result = value; if (result instanceof LazyWrapper) { result = result.value(); } return arrayReduce( actions, function(result, action) { return action.func.apply( action.thisArg, arrayPush([result], action.args) ); }, result ); } /** * The base implementation of methods like `_.xor`, without support for * iteratee shorthands, that accepts an array of arrays to inspect. * * @private * @param {Array} arrays The arrays to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of values. */ function baseXor(arrays, iteratee, comparator) { var length = arrays.length; if (length < 2) { return length ? baseUniq(arrays[0]) : []; } var index = -1, result = Array(length); while (++index < length) { var array = arrays[index], othIndex = -1; while (++othIndex < length) { if (othIndex != index) { result[index] = baseDifference( result[index] || array, arrays[othIndex], iteratee, comparator ); } } } return baseUniq(baseFlatten(result, 1), iteratee, comparator); } /** * This base implementation of `_.zipObject` which assigns values using `assignFunc`. * * @private * @param {Array} props The property identifiers. * @param {Array} values The property values. * @param {Function} assignFunc The function to assign values. * @returns {Object} Returns the new object. */ function baseZipObject(props, values, assignFunc) { var index = -1, length = props.length, valsLength = values.length, result = {}; while (++index < length) { var value = index < valsLength ? values[index] : undefined; assignFunc(result, props[index], value); } return result; } /** * Casts `value` to an empty array if it's not an array like object. * * @private * @param {*} value The value to inspect. * @returns {Array|Object} Returns the cast array-like object. */ function castArrayLikeObject(value) { return isArrayLikeObject(value) ? value : []; } /** * Casts `value` to `identity` if it's not a function. * * @private * @param {*} value The value to inspect. * @returns {Function} Returns cast function. */ function castFunction(value) { return typeof value === 'function' ? value : identity; } /** * Casts `value` to a path array if it's not one. * * @private * @param {*} value The value to inspect. * @param {Object} [object] The object to query keys on. * @returns {Array} Returns the cast property path array. */ function castPath(value, object) { if (isArray(value)) { return value; } return isKey(value, object) ? [value] : stringToPath(toString(value)); } /** * A `baseRest` alias which can be replaced with `identity` by module * replacement plugins. * * @private * @type {Function} * @param {Function} func The function to apply a rest parameter to. * @returns {Function} Returns the new function. */ var castRest = baseRest; /** * Casts `array` to a slice if it's needed. * * @private * @param {Array} array The array to inspect. * @param {number} start The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns the cast slice. */ function castSlice(array, start, end) { var length = array.length; end = end === undefined ? length : end; return !start && end >= length ? array : baseSlice(array, start, end); } /** * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). * * @private * @param {number|Object} id The timer id or timeout object of the timer to clear. */ var clearTimeout = ctxClearTimeout || function(id) { return root.clearTimeout(id); }; /** * Creates a clone of `buffer`. * * @private * @param {Buffer} buffer The buffer to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Buffer} Returns the cloned buffer. */ function cloneBuffer(buffer, isDeep) { if (isDeep) { return buffer.slice(); } var length = buffer.length, result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); buffer.copy(result); return result; } /** * Creates a clone of `arrayBuffer`. * * @private * @param {ArrayBuffer} arrayBuffer The array buffer to clone. * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneArrayBuffer(arrayBuffer) { var result = new arrayBuffer.constructor(arrayBuffer.byteLength); new Uint8Array(result).set(new Uint8Array(arrayBuffer)); return result; } /** * Creates a clone of `dataView`. * * @private * @param {Object} dataView The data view to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned data view. */ function cloneDataView(dataView, isDeep) { var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; return new dataView.constructor( buffer, dataView.byteOffset, dataView.byteLength ); } /** * Creates a clone of `regexp`. * * @private * @param {Object} regexp The regexp to clone. * @returns {Object} Returns the cloned regexp. */ function cloneRegExp(regexp) { var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); result.lastIndex = regexp.lastIndex; return result; } /** * Creates a clone of the `symbol` object. * * @private * @param {Object} symbol The symbol object to clone. * @returns {Object} Returns the cloned symbol object. */ function cloneSymbol(symbol) { return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; } /** * Creates a clone of `typedArray`. * * @private * @param {Object} typedArray The typed array to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; return new typedArray.constructor( buffer, typedArray.byteOffset, typedArray.length ); } /** * Compares values to sort them in ascending order. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {number} Returns the sort order indicator for `value`. */ function compareAscending(value, other) { if (value !== other) { var valIsDefined = value !== undefined, valIsNull = value === null, valIsReflexive = value === value, valIsSymbol = isSymbol(value); var othIsDefined = other !== undefined, othIsNull = other === null, othIsReflexive = other === other, othIsSymbol = isSymbol(other); if ( (!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || (valIsNull && othIsDefined && othIsReflexive) || (!valIsDefined && othIsReflexive) || !valIsReflexive ) { return 1; } if ( (!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || (othIsNull && valIsDefined && valIsReflexive) || (!othIsDefined && valIsReflexive) || !othIsReflexive ) { return -1; } } return 0; } /** * Used by `_.orderBy` to compare multiple properties of a value to another * and stable sort them. * * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, * specify an order of "desc" for descending or "asc" for ascending sort order * of corresponding values. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {boolean[]|string[]} orders The order to sort by for each property. * @returns {number} Returns the sort order indicator for `object`. */ function compareMultiple(object, other, orders) { var index = -1, objCriteria = object.criteria, othCriteria = other.criteria, length = objCriteria.length, ordersLength = orders.length; while (++index < length) { var result = compareAscending(objCriteria[index], othCriteria[index]); if (result) { if (index >= ordersLength) { return result; } var order = orders[index]; return result * (order == 'desc' ? -1 : 1); } } // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications // that causes it, under certain circumstances, to provide the same value for // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 // for more details. // // This also ensures a stable sort in V8 and other engines. // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. return object.index - other.index; } /** * Creates an array that is the composition of partially applied arguments, * placeholders, and provided arguments into a single array of arguments. * * @private * @param {Array} args The provided arguments. * @param {Array} partials The arguments to prepend to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ function composeArgs(args, partials, holders, isCurried) { var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result = Array(leftLength + rangeLength), isUncurried = !isCurried; while (++leftIndex < leftLength) { result[leftIndex] = partials[leftIndex]; } while (++argsIndex < holdersLength) { if (isUncurried || argsIndex < argsLength) { result[holders[argsIndex]] = args[argsIndex]; } } while (rangeLength--) { result[leftIndex++] = args[argsIndex++]; } return result; } /** * This function is like `composeArgs` except that the arguments composition * is tailored for `_.partialRight`. * * @private * @param {Array} args The provided arguments. * @param {Array} partials The arguments to append to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ function composeArgsRight(args, partials, holders, isCurried) { var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result = Array(rangeLength + rightLength), isUncurried = !isCurried; while (++argsIndex < rangeLength) { result[argsIndex] = args[argsIndex]; } var offset = argsIndex; while (++rightIndex < rightLength) { result[offset + rightIndex] = partials[rightIndex]; } while (++holdersIndex < holdersLength) { if (isUncurried || argsIndex < argsLength) { result[offset + holders[holdersIndex]] = args[argsIndex++]; } } return result; } /** * Copies the values of `source` to `array`. * * @private * @param {Array} source The array to copy values from. * @param {Array} [array=[]] The array to copy values to. * @returns {Array} Returns `array`. */ function copyArray(source, array) { var index = -1, length = source.length; array || (array = Array(length)); while (++index < length) { array[index] = source[index]; } return array; } /** * Copies properties of `source` to `object`. * * @private * @param {Object} source The object to copy properties from. * @param {Array} props The property identifiers to copy. * @param {Object} [object={}] The object to copy properties to. * @param {Function} [customizer] The function to customize copied values. * @returns {Object} Returns `object`. */ function copyObject(source, props, object, customizer) { var isNew = !object; object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; if (newValue === undefined) { newValue = source[key]; } if (isNew) { baseAssignValue(object, key, newValue); } else { assignValue(object, key, newValue); } } return object; } /** * Copies own symbols of `source` to `object`. * * @private * @param {Object} source The object to copy symbols from. * @param {Object} [object={}] The object to copy symbols to. * @returns {Object} Returns `object`. */ function copySymbols(source, object) { return copyObject(source, getSymbols(source), object); } /** * Copies own and inherited symbols of `source` to `object`. * * @private * @param {Object} source The object to copy symbols from. * @param {Object} [object={}] The object to copy symbols to. * @returns {Object} Returns `object`. */ function copySymbolsIn(source, object) { return copyObject(source, getSymbolsIn(source), object); } /** * Creates a function like `_.groupBy`. * * @private * @param {Function} setter The function to set accumulator values. * @param {Function} [initializer] The accumulator object initializer. * @returns {Function} Returns the new aggregator function. */ function createAggregator(setter, initializer) { return function(collection, iteratee) { var func = isArray(collection) ? arrayAggregator : baseAggregator, accumulator = initializer ? initializer() : {}; return func(collection, setter, getIteratee(iteratee, 2), accumulator); }; } /** * Creates a function like `_.assign`. * * @private * @param {Function} assigner The function to assign values. * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { return baseRest(function(object, sources) { var index = -1, length = sources.length, customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; customizer = assigner.length > 3 && typeof customizer === 'function' ? (length--, customizer) : undefined; if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; } object = Object(object); while (++index < length) { var source = sources[index]; if (source) { assigner(object, source, index, customizer); } } return object; }); } /** * Creates a `baseEach` or `baseEachRight` function. * * @private * @param {Function} eachFunc The function to iterate over a collection. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseEach(eachFunc, fromRight) { return function(collection, iteratee) { if (collection == null) { return collection; } if (!isArrayLike(collection)) { return eachFunc(collection, iteratee); } var length = collection.length, index = fromRight ? length : -1, iterable = Object(collection); while (fromRight ? index-- : ++index < length) { if (iteratee(iterable[index], index, iterable) === false) { break; } } return collection; }; } /** * Creates a base function for methods like `_.forIn` and `_.forOwn`. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseFor(fromRight) { return function(object, iteratee, keysFunc) { var index = -1, iterable = Object(object), props = keysFunc(object), length = props.length; while (length--) { var key = props[fromRight ? length : ++index]; if (iteratee(iterable[key], key, iterable) === false) { break; } } return object; }; } /** * Creates a function that wraps `func` to invoke it with the optional `this` * binding of `thisArg`. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new wrapped function. */ function createBind(func, bitmask, thisArg) { var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func); function wrapper() { var fn = this && this !== root && this instanceof wrapper ? Ctor : func; return fn.apply(isBind ? thisArg : this, arguments); } return wrapper; } /** * Creates a function like `_.lowerFirst`. * * @private * @param {string} methodName The name of the `String` case method to use. * @returns {Function} Returns the new case function. */ function createCaseFirst(methodName) { return function(string) { string = toString(string); var strSymbols = hasUnicode(string) ? stringToArray(string) : undefined; var chr = strSymbols ? strSymbols[0] : string.charAt(0); var trailing = strSymbols ? castSlice(strSymbols, 1).join('') : string.slice(1); return chr[methodName]() + trailing; }; } /** * Creates a function like `_.camelCase`. * * @private * @param {Function} callback The function to combine each word. * @returns {Function} Returns the new compounder function. */ function createCompounder(callback) { return function(string) { return arrayReduce( words(deburr(string).replace(reApos, '')), callback, '' ); }; } /** * Creates a function that produces an instance of `Ctor` regardless of * whether it was invoked as part of a `new` expression or by `call` or `apply`. * * @private * @param {Function} Ctor The constructor to wrap. * @returns {Function} Returns the new wrapped function. */ function createCtor(Ctor) { return function() { // Use a `switch` statement to work with class constructors. See // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist // for more details. var args = arguments; switch (args.length) { case 0: return new Ctor(); case 1: return new Ctor(args[0]); case 2: return new Ctor(args[0], args[1]); case 3: return new Ctor(args[0], args[1], args[2]); case 4: return new Ctor(args[0], args[1], args[2], args[3]); case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); case 6: return new Ctor( args[0], args[1], args[2], args[3], args[4], args[5] ); case 7: return new Ctor( args[0], args[1], args[2], args[3], args[4], args[5], args[6] ); } var thisBinding = baseCreate(Ctor.prototype), result = Ctor.apply(thisBinding, args); // Mimic the constructor's `return` behavior. // See https://es5.github.io/#x13.2.2 for more details. return isObject(result) ? result : thisBinding; }; } /** * Creates a function that wraps `func` to enable currying. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {number} arity The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createCurry(func, bitmask, arity) { var Ctor = createCtor(func); function wrapper() { var length = arguments.length, args = Array(length), index = length, placeholder = getHolder(wrapper); while (index--) { args[index] = arguments[index]; } var holders = length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder ? [] : replaceHolders(args, placeholder); length -= holders.length; if (length < arity) { return createRecurry( func, bitmask, createHybrid, wrapper.placeholder, undefined, args, holders, undefined, undefined, arity - length ); } var fn = this && this !== root && this instanceof wrapper ? Ctor : func; return apply(fn, this, args); } return wrapper; } /** * Creates a `_.find` or `_.findLast` function. * * @private * @param {Function} findIndexFunc The function to find the collection index. * @returns {Function} Returns the new find function. */ function createFind(findIndexFunc) { return function(collection, predicate, fromIndex) { var iterable = Object(collection); if (!isArrayLike(collection)) { var iteratee = getIteratee(predicate, 3); collection = keys(collection); predicate = function(key) { return iteratee(iterable[key], key, iterable); }; } var index = findIndexFunc(collection, predicate, fromIndex); return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; }; } /** * Creates a `_.flow` or `_.flowRight` function. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new flow function. */ function createFlow(fromRight) { return flatRest(function(funcs) { var length = funcs.length, index = length, prereq = LodashWrapper.prototype.thru; if (fromRight) { funcs.reverse(); } while (index--) { var func = funcs[index]; if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } if (prereq && !wrapper && getFuncName(func) == 'wrapper') { var wrapper = new LodashWrapper([], true); } } index = wrapper ? index : length; while (++index < length) { func = funcs[index]; var funcName = getFuncName(func), data = funcName == 'wrapper' ? getData(func) : undefined; if ( data && isLaziable(data[0]) && data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && !data[4].length && data[9] == 1 ) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); } else { wrapper = func.length == 1 && isLaziable(func) ? wrapper[funcName]() : wrapper.thru(func); } } return function() { var args = arguments, value = args[0]; if (wrapper && args.length == 1 && isArray(value)) { return wrapper.plant(value).value(); } var index = 0, result = length ? funcs[index].apply(this, args) : value; while (++index < length) { result = funcs[index].call(this, result); } return result; }; }); } /** * Creates a function that wraps `func` to invoke it with optional `this` * binding of `thisArg`, partial application, and currying. * * @private * @param {Function|string} func The function or method name to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to prepend to those provided to * the new function. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [partialsRight] The arguments to append to those provided * to the new function. * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createHybrid( func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity ) { var isAry = bitmask & WRAP_ARY_FLAG, isBind = bitmask & WRAP_BIND_FLAG, isBindKey = bitmask & WRAP_BIND_KEY_FLAG, isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), isFlip = bitmask & WRAP_FLIP_FLAG, Ctor = isBindKey ? undefined : createCtor(func); function wrapper() { var length = arguments.length, args = Array(length), index = length; while (index--) { args[index] = arguments[index]; } if (isCurried) { var placeholder = getHolder(wrapper), holdersCount = countHolders(args, placeholder); } if (partials) { args = composeArgs(args, partials, holders, isCurried); } if (partialsRight) { args = composeArgsRight(args, partialsRight, holdersRight, isCurried); } length -= holdersCount; if (isCurried && length < arity) { var newHolders = replaceHolders(args, placeholder); return createRecurry( func, bitmask, createHybrid, wrapper.placeholder, thisArg, args, newHolders, argPos, ary, arity - length ); } var thisBinding = isBind ? thisArg : this, fn = isBindKey ? thisBinding[func] : func; length = args.length; if (argPos) { args = reorder(args, argPos); } else if (isFlip && length > 1) { args.reverse(); } if (isAry && ary < length) { args.length = ary; } if (this && this !== root && this instanceof wrapper) { fn = Ctor || createCtor(fn); } return fn.apply(thisBinding, args); } return wrapper; } /** * Creates a function like `_.invertBy`. * * @private * @param {Function} setter The function to set accumulator values. * @param {Function} toIteratee The function to resolve iteratees. * @returns {Function} Returns the new inverter function. */ function createInverter(setter, toIteratee) { return function(object, iteratee) { return baseInverter(object, setter, toIteratee(iteratee), {}); }; } /** * Creates a function that performs a mathematical operation on two values. * * @private * @param {Function} operator The function to perform the operation. * @param {number} [defaultValue] The value used for `undefined` arguments. * @returns {Function} Returns the new mathematical operation function. */ function createMathOperation(operator, defaultValue) { return function(value, other) { var result; if (value === undefined && other === undefined) { return defaultValue; } if (value !== undefined) { result = value; } if (other !== undefined) { if (result === undefined) { return other; } if (typeof value === 'string' || typeof other === 'string') { value = baseToString(value); other = baseToString(other); } else { value = baseToNumber(value); other = baseToNumber(other); } result = operator(value, other); } return result; }; } /** * Creates a function like `_.over`. * * @private * @param {Function} arrayFunc The function to iterate over iteratees. * @returns {Function} Returns the new over function. */ function createOver(arrayFunc) { return flatRest(function(iteratees) { iteratees = arrayMap(iteratees, baseUnary(getIteratee())); return baseRest(function(args) { var thisArg = this; return arrayFunc(iteratees, function(iteratee) { return apply(iteratee, thisArg, args); }); }); }); } /** * Creates the padding for `string` based on `length`. The `chars` string * is truncated if the number of characters exceeds `length`. * * @private * @param {number} length The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padding for `string`. */ function createPadding(length, chars) { chars = chars === undefined ? ' ' : baseToString(chars); var charsLength = chars.length; if (charsLength < 2) { return charsLength ? baseRepeat(chars, length) : chars; } var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); return hasUnicode(chars) ? castSlice(stringToArray(result), 0, length).join('') : result.slice(0, length); } /** * Creates a function that wraps `func` to invoke it with the `this` binding * of `thisArg` and `partials` prepended to the arguments it receives. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} thisArg The `this` binding of `func`. * @param {Array} partials The arguments to prepend to those provided to * the new function. * @returns {Function} Returns the new wrapped function. */ function createPartial(func, bitmask, thisArg, partials) { var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func); function wrapper() { var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array(leftLength + argsLength), fn = this && this !== root && this instanceof wrapper ? Ctor : func; while (++leftIndex < leftLength) { args[leftIndex] = partials[leftIndex]; } while (argsLength--) { args[leftIndex++] = arguments[++argsIndex]; } return apply(fn, isBind ? thisArg : this, args); } return wrapper; } /** * Creates a `_.range` or `_.rangeRight` function. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new range function. */ function createRange(fromRight) { return function(start, end, step) { if ( step && typeof step !== 'number' && isIterateeCall(start, end, step) ) { end = step = undefined; } // Ensure the sign of `-0` is preserved. start = toFinite(start); if (end === undefined) { end = start; start = 0; } else { end = toFinite(end); } step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); return baseRange(start, end, step, fromRight); }; } /** * Creates a function that performs a relational operation on two values. * * @private * @param {Function} operator The function to perform the operation. * @returns {Function} Returns the new relational operation function. */ function createRelationalOperation(operator) { return function(value, other) { if (!(typeof value === 'string' && typeof other === 'string')) { value = toNumber(value); other = toNumber(other); } return operator(value, other); }; } /** * Creates a function that wraps `func` to continue currying. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {Function} wrapFunc The function to create the `func` wrapper. * @param {*} placeholder The placeholder value. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to prepend to those provided to * the new function. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createRecurry( func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity ) { var isCurry = bitmask & WRAP_CURRY_FLAG, newHolders = isCurry ? holders : undefined, newHoldersRight = isCurry ? undefined : holders, newPartials = isCurry ? partials : undefined, newPartialsRight = isCurry ? undefined : partials; bitmask |= isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG; bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); } var newData = [ func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, newHoldersRight, argPos, ary, arity ]; var result = wrapFunc.apply(undefined, newData); if (isLaziable(func)) { setData(result, newData); } result.placeholder = placeholder; return setWrapToString(result, func, bitmask); } /** * Creates a function like `_.round`. * * @private * @param {string} methodName The name of the `Math` method to use when rounding. * @returns {Function} Returns the new round function. */ function createRound(methodName) { var func = Math[methodName]; return function(number, precision) { number = toNumber(number); precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); if (precision) { // Shift with exponential notation to avoid floating-point issues. // See [MDN](https://mdn.io/round#Examples) for more details. var pair = (toString(number) + 'e').split('e'), value = func(pair[0] + 'e' + (+pair[1] + precision)); pair = (toString(value) + 'e').split('e'); return +(pair[0] + 'e' + (+pair[1] - precision)); } return func(number); }; } /** * Creates a set object of `values`. * * @private * @param {Array} values The values to add to the set. * @returns {Object} Returns the new set. */ var createSet = !(Set && 1 / setToArray(new Set([, -0]))[1] == INFINITY) ? noop : function(values) { return new Set(values); }; /** * Creates a `_.toPairs` or `_.toPairsIn` function. * * @private * @param {Function} keysFunc The function to get the keys of a given object. * @returns {Function} Returns the new pairs function. */ function createToPairs(keysFunc) { return function(object) { var tag = getTag(object); if (tag == mapTag) { return mapToArray(object); } if (tag == setTag) { return setToPairs(object); } return baseToPairs(object, keysFunc(object)); }; } /** * Creates a function that either curries or invokes `func` with optional * `this` binding and partially applied arguments. * * @private * @param {Function|string} func The function or method name to wrap. * @param {number} bitmask The bitmask flags. * 1 - `_.bind` * 2 - `_.bindKey` * 4 - `_.curry` or `_.curryRight` of a bound function * 8 - `_.curry` * 16 - `_.curryRight` * 32 - `_.partial` * 64 - `_.partialRight` * 128 - `_.rearg` * 256 - `_.ary` * 512 - `_.flip` * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to be partially applied. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createWrap( func, bitmask, thisArg, partials, holders, argPos, ary, arity ) { var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; if (!isBindKey && typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } var length = partials ? partials.length : 0; if (!length) { bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); partials = holders = undefined; } ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); arity = arity === undefined ? arity : toInteger(arity); length -= holders ? holders.length : 0; if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { var partialsRight = partials, holdersRight = holders; partials = holders = undefined; } var data = isBindKey ? undefined : getData(func); var newData = [ func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity ]; if (data) { mergeData(newData, data); } func = newData[0]; bitmask = newData[1]; thisArg = newData[2]; partials = newData[3]; holders = newData[4]; arity = newData[9] = newData[9] === undefined ? isBindKey ? 0 : func.length : nativeMax(newData[9] - length, 0); if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); } if (!bitmask || bitmask == WRAP_BIND_FLAG) { var result = createBind(func, bitmask, thisArg); } else if ( bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG ) { result = createCurry(func, bitmask, arity); } else if ( (bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length ) { result = createPartial(func, bitmask, thisArg, partials); } else { result = createHybrid.apply(undefined, newData); } var setter = data ? baseSetData : setData; return setWrapToString(setter(result, newData), func, bitmask); } /** * Used by `_.defaults` to customize its `_.assignIn` use to assign properties * of source objects to the destination object for all destination properties * that resolve to `undefined`. * * @private * @param {*} objValue The destination value. * @param {*} srcValue The source value. * @param {string} key The key of the property to assign. * @param {Object} object The parent object of `objValue`. * @returns {*} Returns the value to assign. */ function customDefaultsAssignIn(objValue, srcValue, key, object) { if ( objValue === undefined || (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key)) ) { return srcValue; } return objValue; } /** * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source * objects into destination objects that are passed thru. * * @private * @param {*} objValue The destination value. * @param {*} srcValue The source value. * @param {string} key The key of the property to merge. * @param {Object} object The parent object of `objValue`. * @param {Object} source The parent object of `srcValue`. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. * @returns {*} Returns the value to assign. */ function customDefaultsMerge( objValue, srcValue, key, object, source, stack ) { if (isObject(objValue) && isObject(srcValue)) { // Recursively merge objects and arrays (susceptible to call stack limits). stack.set(srcValue, objValue); baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); stack['delete'](srcValue); } return objValue; } /** * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain * objects. * * @private * @param {*} value The value to inspect. * @param {string} key The key of the property to inspect. * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. */ function customOmitClone(value) { return isPlainObject(value) ? undefined : value; } /** * A specialized version of `baseIsEqualDeep` for arrays with support for * partial deep comparisons. * * @private * @param {Array} array The array to compare. * @param {Array} other The other array to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `array` and `other` objects. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length; if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } // Assume cyclic values are equal. var stacked = stack.get(array); if (stacked && stack.get(other)) { return stacked == other; } var index = -1, result = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache() : undefined; stack.set(array, other); stack.set(other, array); // Ignore non-index properties. while (++index < arrLength) { var arrValue = array[index], othValue = other[index]; if (customizer) { var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); } if (compared !== undefined) { if (compared) { continue; } result = false; break; } // Recursively compare arrays (susceptible to call stack limits). if (seen) { if ( !arraySome(other, function(othValue, othIndex) { if ( !cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack)) ) { return seen.push(othIndex); } }) ) { result = false; break; } } else if ( !( arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack) ) ) { result = false; break; } } stack['delete'](array); stack['delete'](other); return result; } /** * A specialized version of `baseIsEqualDeep` for comparing objects of * the same `toStringTag`. * * **Note:** This function only supports comparing values with tags of * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalByTag( object, other, tag, bitmask, customizer, equalFunc, stack ) { switch (tag) { case dataViewTag: if ( object.byteLength != other.byteLength || object.byteOffset != other.byteOffset ) { return false; } object = object.buffer; other = other.buffer; case arrayBufferTag: if ( object.byteLength != other.byteLength || !equalFunc(new Uint8Array(object), new Uint8Array(other)) ) { return false; } return true; case boolTag: case dateTag: case numberTag: // Coerce booleans to `1` or `0` and dates to milliseconds. // Invalid dates are coerced to `NaN`. return eq(+object, +other); case errorTag: return object.name == other.name && object.message == other.message; case regexpTag: case stringTag: // Coerce regexes to strings and treat strings, primitives and objects, // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring // for more details. return object == other + ''; case mapTag: var convert = mapToArray; case setTag: var isPartial = bitmask & COMPARE_PARTIAL_FLAG; convert || (convert = setToArray); if (object.size != other.size && !isPartial) { return false; } // Assume cyclic values are equal. var stacked = stack.get(object); if (stacked) { return stacked == other; } bitmask |= COMPARE_UNORDERED_FLAG; // Recursively compare objects (susceptible to call stack limits). stack.set(object, other); var result = equalArrays( convert(object), convert(other), bitmask, customizer, equalFunc, stack ); stack['delete'](object); return result; case symbolTag: if (symbolValueOf) { return symbolValueOf.call(object) == symbolValueOf.call(other); } } return false; } /** * A specialized version of `baseIsEqualDeep` for objects with support for * partial deep comparisons. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalObjects( object, other, bitmask, customizer, equalFunc, stack ) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; if (objLength != othLength && !isPartial) { return false; } var index = objLength; while (index--) { var key = objProps[index]; if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { return false; } } // Assume cyclic values are equal. var stacked = stack.get(object); if (stacked && stack.get(other)) { return stacked == other; } var result = true; stack.set(object, other); stack.set(other, object); var skipCtor = isPartial; while (++index < objLength) { key = objProps[index]; var objValue = object[key], othValue = other[key]; if (customizer) { var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); } // Recursively compare objects (susceptible to call stack limits). if ( !(compared === undefined ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared) ) { result = false; break; } skipCtor || (skipCtor = key == 'constructor'); } if (result && !skipCtor) { var objCtor = object.constructor, othCtor = other.constructor; // Non `Object` object instances with different constructors are not equal. if ( objCtor != othCtor && ('constructor' in object && 'constructor' in other) && !( typeof objCtor === 'function' && objCtor instanceof objCtor && typeof othCtor === 'function' && othCtor instanceof othCtor ) ) { result = false; } } stack['delete'](object); stack['delete'](other); return result; } /** * A specialized version of `baseRest` which flattens the rest array. * * @private * @param {Function} func The function to apply a rest parameter to. * @returns {Function} Returns the new function. */ function flatRest(func) { return setToString(overRest(func, undefined, flatten), func + ''); } /** * Creates an array of own enumerable property names and symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeys(object) { return baseGetAllKeys(object, keys, getSymbols); } /** * Creates an array of own and inherited enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeysIn(object) { return baseGetAllKeys(object, keysIn, getSymbolsIn); } /** * Gets metadata for `func`. * * @private * @param {Function} func The function to query. * @returns {*} Returns the metadata for `func`. */ var getData = !metaMap ? noop : function(func) { return metaMap.get(func); }; /** * Gets the name of `func`. * * @private * @param {Function} func The function to query. * @returns {string} Returns the function name. */ function getFuncName(func) { var result = func.name + '', array = realNames[result], length = hasOwnProperty.call(realNames, result) ? array.length : 0; while (length--) { var data = array[length], otherFunc = data.func; if (otherFunc == null || otherFunc == func) { return data.name; } } return result; } /** * Gets the argument placeholder value for `func`. * * @private * @param {Function} func The function to inspect. * @returns {*} Returns the placeholder value. */ function getHolder(func) { var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; return object.placeholder; } /** * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, * this function returns the custom method, otherwise it returns `baseIteratee`. * If arguments are provided, the chosen function is invoked with them and * its result is returned. * * @private * @param {*} [value] The value to convert to an iteratee. * @param {number} [arity] The arity of the created iteratee. * @returns {Function} Returns the chosen function or its result. */ function getIteratee() { var result = lodash.iteratee || iteratee; result = result === iteratee ? baseIteratee : result; return arguments.length ? result(arguments[0], arguments[1]) : result; } /** * Gets the data for `map`. * * @private * @param {Object} map The map to query. * @param {string} key The reference key. * @returns {*} Returns the map data. */ function getMapData(map, key) { var data = map.__data__; return isKeyable(key) ? data[typeof key === 'string' ? 'string' : 'hash'] : data.map; } /** * Gets the property names, values, and compare flags of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the match data of `object`. */ function getMatchData(object) { var result = keys(object), length = result.length; while (length--) { var key = result[length], value = object[key]; result[length] = [key, value, isStrictComparable(value)]; } return result; } /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; try { value[symToStringTag] = undefined; var unmasked = true; } catch (e) { } var result = nativeObjectToString.call(value); if (unmasked) { if (isOwn) { value[symToStringTag] = tag; } else { delete value[symToStringTag]; } } return result; } /** * Creates an array of the own enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbols = !nativeGetSymbols ? stubArray : function(object) { if (object == null) { return []; } object = Object(object); return arrayFilter(nativeGetSymbols(object), function(symbol) { return propertyIsEnumerable.call(object, symbol); }); }; /** * Creates an array of the own and inherited enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { var result = []; while (object) { arrayPush(result, getSymbols(object)); object = getPrototype(object); } return result; }; /** * Gets the `toStringTag` of `value`. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ var getTag = baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. if ( (DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || (Map && getTag(new Map()) != mapTag) || (Promise && getTag(Promise.resolve()) != promiseTag) || (Set && getTag(new Set()) != setTag) || (WeakMap && getTag(new WeakMap()) != weakMapTag) ) { getTag = function(value) { var result = baseGetTag(value), Ctor = result == objectTag ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : ''; if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag; case mapCtorString: return mapTag; case promiseCtorString: return promiseTag; case setCtorString: return setTag; case weakMapCtorString: return weakMapTag; } } return result; }; } /** * Gets the view, applying any `transforms` to the `start` and `end` positions. * * @private * @param {number} start The start of the view. * @param {number} end The end of the view. * @param {Array} transforms The transformations to apply to the view. * @returns {Object} Returns an object containing the `start` and `end` * positions of the view. */ function getView(start, end, transforms) { var index = -1, length = transforms.length; while (++index < length) { var data = transforms[index], size = data.size; switch (data.type) { case 'drop': start += size; break; case 'dropRight': end -= size; break; case 'take': end = nativeMin(end, start + size); break; case 'takeRight': start = nativeMax(start, end - size); break; } } return { start: start, end: end }; } /** * Extracts wrapper details from the `source` body comment. * * @private * @param {string} source The source to inspect. * @returns {Array} Returns the wrapper details. */ function getWrapDetails(source) { var match = source.match(reWrapDetails); return match ? match[1].split(reSplitDetails) : []; } /** * Checks if `path` exists on `object`. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @param {Function} hasFunc The function to check properties. * @returns {boolean} Returns `true` if `path` exists, else `false`. */ function hasPath(object, path, hasFunc) { path = castPath(path, object); var index = -1, length = path.length, result = false; while (++index < length) { var key = toKey(path[index]); if (!(result = object != null && hasFunc(object, key))) { break; } object = object[key]; } if (result || ++index != length) { return result; } length = object == null ? 0 : object.length; return ( !!length && isLength(length) && isIndex(key, length) && (isArray(object) || isArguments(object)) ); } /** * Initializes an array clone. * * @private * @param {Array} array The array to clone. * @returns {Array} Returns the initialized clone. */ function initCloneArray(array) { var length = array.length, result = new array.constructor(length); // Add properties assigned by `RegExp#exec`. if ( length && typeof array[0] === 'string' && hasOwnProperty.call(array, 'index') ) { result.index = array.index; result.input = array.input; } return result; } /** * Initializes an object clone. * * @private * @param {Object} object The object to clone. * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { return typeof object.constructor === 'function' && !isPrototype(object) ? baseCreate(getPrototype(object)) : {}; } /** * Initializes an object clone based on its `toStringTag`. * * **Note:** This function only supports cloning values with tags of * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. * * @private * @param {Object} object The object to clone. * @param {string} tag The `toStringTag` of the object to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the initialized clone. */ function initCloneByTag(object, tag, isDeep) { var Ctor = object.constructor; switch (tag) { case arrayBufferTag: return cloneArrayBuffer(object); case boolTag: case dateTag: return new Ctor(+object); case dataViewTag: return cloneDataView(object, isDeep); case float32Tag: case float64Tag: case int8Tag: case int16Tag: case int32Tag: case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: return cloneTypedArray(object, isDeep); case mapTag: return new Ctor(); case numberTag: case stringTag: return new Ctor(object); case regexpTag: return cloneRegExp(object); case setTag: return new Ctor(); case symbolTag: return cloneSymbol(object); } } /** * Inserts wrapper `details` in a comment at the top of the `source` body. * * @private * @param {string} source The source to modify. * @returns {Array} details The details to insert. * @returns {string} Returns the modified source. */ function insertWrapDetails(source, details) { var length = details.length; if (!length) { return source; } var lastIndex = length - 1; details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; details = details.join(length > 2 ? ', ' : ' '); return source.replace( reWrapComment, '{\n/* [wrapped with ' + details + '] */\n' ); } /** * Checks if `value` is a flattenable `arguments` object or array. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. */ function isFlattenable(value) { return ( isArray(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]) ); } /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { var type = typeof value; length = length == null ? MAX_SAFE_INTEGER : length; return ( !!length && (type == 'number' || (type != 'symbol' && reIsUint.test(value))) && (value > -1 && value % 1 == 0 && value < length) ); } /** * Checks if the given arguments are from an iteratee call. * * @private * @param {*} value The potential iteratee value argument. * @param {*} index The potential iteratee index or key argument. * @param {*} object The potential iteratee object argument. * @returns {boolean} Returns `true` if the arguments are from an iteratee call, * else `false`. */ function isIterateeCall(value, index, object) { if (!isObject(object)) { return false; } var type = typeof index; if ( type == 'number' ? isArrayLike(object) && isIndex(index, object.length) : type == 'string' && index in object ) { return eq(object[index], value); } return false; } /** * Checks if `value` is a property name and not a property path. * * @private * @param {*} value The value to check. * @param {Object} [object] The object to query keys on. * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ function isKey(value, object) { if (isArray(value)) { return false; } var type = typeof value; if ( type == 'number' || type == 'symbol' || type == 'boolean' || value == null || isSymbol(value) ) { return true; } return ( reIsPlainProp.test(value) || !reIsDeepProp.test(value) || (object != null && value in Object(object)) ); } /** * Checks if `value` is suitable for use as unique object key. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is suitable, else `false`. */ function isKeyable(value) { var type = typeof value; return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null; } /** * Checks if `func` has a lazy counterpart. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` has a lazy counterpart, * else `false`. */ function isLaziable(func) { var funcName = getFuncName(func), other = lodash[funcName]; if (typeof other !== 'function' || !(funcName in LazyWrapper.prototype)) { return false; } if (func === other) { return true; } var data = getData(other); return !!data && func === data[0]; } /** * Checks if `func` has its source masked. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` is masked, else `false`. */ function isMasked(func) { return !!maskSrcKey && maskSrcKey in func; } /** * Checks if `func` is capable of being masked. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `func` is maskable, else `false`. */ var isMaskable = coreJsData ? isFunction : stubFalse; /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { var Ctor = value && value.constructor, proto = (typeof Ctor === 'function' && Ctor.prototype) || objectProto; return value === proto; } /** * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` if suitable for strict * equality comparisons, else `false`. */ function isStrictComparable(value) { return value === value && !isObject(value); } /** * A specialized version of `matchesProperty` for source values suitable * for strict equality comparisons, i.e. `===`. * * @private * @param {string} key The key of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function matchesStrictComparable(key, srcValue) { return function(object) { if (object == null) { return false; } return ( object[key] === srcValue && (srcValue !== undefined || key in Object(object)) ); }; } /** * A specialized version of `_.memoize` which clears the memoized function's * cache when it exceeds `MAX_MEMOIZE_SIZE`. * * @private * @param {Function} func The function to have its output memoized. * @returns {Function} Returns the new memoized function. */ function memoizeCapped(func) { var result = memoize(func, function(key) { if (cache.size === MAX_MEMOIZE_SIZE) { cache.clear(); } return key; }); var cache = result.cache; return result; } /** * Merges the function metadata of `source` into `data`. * * Merging metadata reduces the number of wrappers used to invoke a function. * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` * may be applied regardless of execution order. Methods like `_.ary` and * `_.rearg` modify function arguments, making the order in which they are * executed important, preventing the merging of metadata. However, we make * an exception for a safe combined case where curried functions have `_.ary` * and or `_.rearg` applied. * * @private * @param {Array} data The destination metadata. * @param {Array} source The source metadata. * @returns {Array} Returns `data`. */ function mergeData(data, source) { var bitmask = data[1], srcBitmask = source[1], newBitmask = bitmask | srcBitmask, isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); var isCombo = (srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_CURRY_FLAG) || (srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_REARG_FLAG && data[7].length <= source[8]) || (srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG) && source[7].length <= source[8] && bitmask == WRAP_CURRY_FLAG); // Exit early if metadata can't be merged. if (!(isCommon || isCombo)) { return data; } // Use source `thisArg` if available. if (srcBitmask & WRAP_BIND_FLAG) { data[2] = source[2]; // Set when currying a bound function. newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; } // Compose partial arguments. var value = source[3]; if (value) { var partials = data[3]; data[3] = partials ? composeArgs(partials, value, source[4]) : value; data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; } // Compose partial right arguments. value = source[5]; if (value) { partials = data[5]; data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; } // Use source `argPos` if available. value = source[7]; if (value) { data[7] = value; } // Use source `ary` if it's smaller. if (srcBitmask & WRAP_ARY_FLAG) { data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); } // Use source `arity` if one is not provided. if (data[9] == null) { data[9] = source[9]; } // Use source `func` and merge bitmasks. data[0] = source[0]; data[1] = newBitmask; return data; } /** * This function is like * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * except that it includes inherited enumerable properties. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function nativeKeysIn(object) { var result = []; if (object != null) { for (var key in Object(object)) { result.push(key); } } return result; } /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString.call(value); } /** * A specialized version of `baseRest` which transforms the rest array. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @param {Function} transform The rest array transform. * @returns {Function} Returns the new function. */ function overRest(func, start, transform) { start = nativeMax(start === undefined ? func.length - 1 : start, 0); return function() { var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array(length); while (++index < length) { array[index] = args[start + index]; } index = -1; var otherArgs = Array(start + 1); while (++index < start) { otherArgs[index] = args[index]; } otherArgs[start] = transform(array); return apply(func, this, otherArgs); }; } /** * Gets the parent value at `path` of `object`. * * @private * @param {Object} object The object to query. * @param {Array} path The path to get the parent value of. * @returns {*} Returns the parent value. */ function parent(object, path) { return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); } /** * Reorder `array` according to the specified indexes where the element at * the first index is assigned as the first element, the element at * the second index is assigned as the second element, and so on. * * @private * @param {Array} array The array to reorder. * @param {Array} indexes The arranged array indexes. * @returns {Array} Returns `array`. */ function reorder(array, indexes) { var arrLength = array.length, length = nativeMin(indexes.length, arrLength), oldArray = copyArray(array); while (length--) { var index = indexes[length]; array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; } return array; } /** * Sets metadata for `func`. * * **Note:** If this function becomes hot, i.e. is invoked a lot in a short * period of time, it will trip its breaker and transition to an identity * function to avoid garbage collection pauses in V8. See * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) * for more details. * * @private * @param {Function} func The function to associate metadata with. * @param {*} data The metadata. * @returns {Function} Returns `func`. */ var setData = shortOut(baseSetData); /** * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). * * @private * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. * @returns {number|Object} Returns the timer id or timeout object. */ var setTimeout = ctxSetTimeout || function(func, wait) { return root.setTimeout(func, wait); }; /** * Sets the `toString` method of `func` to return `string`. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var setToString = shortOut(baseSetToString); /** * Sets the `toString` method of `wrapper` to mimic the source of `reference` * with wrapper details in a comment at the top of the source body. * * @private * @param {Function} wrapper The function to modify. * @param {Function} reference The reference function. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @returns {Function} Returns `wrapper`. */ function setWrapToString(wrapper, reference, bitmask) { var source = reference + ''; return setToString( wrapper, insertWrapDetails( source, updateWrapDetails(getWrapDetails(source), bitmask) ) ); } /** * Creates a function that'll short out and invoke `identity` instead * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` * milliseconds. * * @private * @param {Function} func The function to restrict. * @returns {Function} Returns the new shortable function. */ function shortOut(func) { var count = 0, lastCalled = 0; return function() { var stamp = nativeNow(), remaining = HOT_SPAN - (stamp - lastCalled); lastCalled = stamp; if (remaining > 0) { if (++count >= HOT_COUNT) { return arguments[0]; } } else { count = 0; } return func.apply(undefined, arguments); }; } /** * A specialized version of `_.shuffle` which mutates and sets the size of `array`. * * @private * @param {Array} array The array to shuffle. * @param {number} [size=array.length] The size of `array`. * @returns {Array} Returns `array`. */ function shuffleSelf(array, size) { var index = -1, length = array.length, lastIndex = length - 1; size = size === undefined ? length : size; while (++index < size) { var rand = baseRandom(index, lastIndex), value = array[rand]; array[rand] = array[index]; array[index] = value; } array.length = size; return array; } /** * Converts `string` to a property path array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the property path array. */ var stringToPath = memoizeCapped(function(string) { var result = []; if (string.charCodeAt(0) === 46 /* . */) { result.push(''); } string.replace(rePropName, function(match, number, quote, subString) { result.push( quote ? subString.replace(reEscapeChar, '$1') : number || match ); }); return result; }); /** * Converts `value` to a string key if it's not a string or symbol. * * @private * @param {*} value The value to inspect. * @returns {string|symbol} Returns the key. */ function toKey(value) { if (typeof value === 'string' || isSymbol(value)) { return value; } var result = value + ''; return result == '0' && 1 / value == -INFINITY ? '-0' : result; } /** * Converts `func` to its source code. * * @private * @param {Function} func The function to convert. * @returns {string} Returns the source code. */ function toSource(func) { if (func != null) { try { return funcToString.call(func); } catch (e) { } try { return func + ''; } catch (e) { } } return ''; } /** * Updates wrapper `details` based on `bitmask` flags. * * @private * @returns {Array} details The details to modify. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @returns {Array} Returns `details`. */ function updateWrapDetails(details, bitmask) { arrayEach(wrapFlags, function(pair) { var value = '_.' + pair[0]; if (bitmask & pair[1] && !arrayIncludes(details, value)) { details.push(value); } }); return details.sort(); } /** * Creates a clone of `wrapper`. * * @private * @param {Object} wrapper The wrapper to clone. * @returns {Object} Returns the cloned wrapper. */ function wrapperClone(wrapper) { if (wrapper instanceof LazyWrapper) { return wrapper.clone(); } var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); result.__actions__ = copyArray(wrapper.__actions__); result.__index__ = wrapper.__index__; result.__values__ = wrapper.__values__; return result; } /* ------------------------------------------------------------------------*/ /** * Creates an array of elements split into groups the length of `size`. * If `array` can't be split evenly, the final chunk will be the remaining * elements. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to process. * @param {number} [size=1] The length of each chunk * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the new array of chunks. * @example * * _.chunk(['a', 'b', 'c', 'd'], 2); * // => [['a', 'b'], ['c', 'd']] * * _.chunk(['a', 'b', 'c', 'd'], 3); * // => [['a', 'b', 'c'], ['d']] */ function chunk(array, size, guard) { if (guard ? isIterateeCall(array, size, guard) : size === undefined) { size = 1; } else { size = nativeMax(toInteger(size), 0); } var length = array == null ? 0 : array.length; if (!length || size < 1) { return []; } var index = 0, resIndex = 0, result = Array(nativeCeil(length / size)); while (index < length) { result[resIndex++] = baseSlice(array, index, (index += size)); } return result; } /** * Creates an array with all falsey values removed. The values `false`, `null`, * `0`, `""`, `undefined`, and `NaN` are falsey. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to compact. * @returns {Array} Returns the new array of filtered values. * @example * * _.compact([0, 1, false, 2, '', 3]); * // => [1, 2, 3] */ function compact(array) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value) { result[resIndex++] = value; } } return result; } /** * Creates a new array concatenating `array` with any additional arrays * and/or values. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to concatenate. * @param {...*} [values] The values to concatenate. * @returns {Array} Returns the new concatenated array. * @example * * var array = [1]; * var other = _.concat(array, 2, [3], [[4]]); * * console.log(other); * // => [1, 2, 3, [4]] * * console.log(array); * // => [1] */ function concat() { var length = arguments.length; if (!length) { return []; } var args = Array(length - 1), array = arguments[0], index = length; while (index--) { args[index - 1] = arguments[index]; } return arrayPush( isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1) ); } /** * Creates an array of `array` values not included in the other given arrays * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. The order and references of result values are * determined by the first array. * * **Note:** Unlike `_.pullAll`, this method returns a new array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {...Array} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. * @see _.without, _.xor * @example * * _.difference([2, 1], [2, 3]); * // => [1] */ var difference = baseRest(function(array, values) { return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) : []; }); /** * This method is like `_.difference` except that it accepts `iteratee` which * is invoked for each element of `array` and `values` to generate the criterion * by which they're compared. The order and references of result values are * determined by the first array. The iteratee is invoked with one argument: * (value). * * **Note:** Unlike `_.pullAllBy`, this method returns a new array. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {...Array} [values] The values to exclude. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [1.2] * * // The `_.property` iteratee shorthand. * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); * // => [{ 'x': 2 }] */ var differenceBy = baseRest(function(array, values) { var iteratee = last(values); if (isArrayLikeObject(iteratee)) { iteratee = undefined; } return isArrayLikeObject(array) ? baseDifference( array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2) ) : []; }); /** * This method is like `_.difference` except that it accepts `comparator` * which is invoked to compare elements of `array` to `values`. The order and * references of result values are determined by the first array. The comparator * is invoked with two arguments: (arrVal, othVal). * * **Note:** Unlike `_.pullAllWith`, this method returns a new array. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {...Array} [values] The values to exclude. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); * // => [{ 'x': 2, 'y': 1 }] */ var differenceWith = baseRest(function(array, values) { var comparator = last(values); if (isArrayLikeObject(comparator)) { comparator = undefined; } return isArrayLikeObject(array) ? baseDifference( array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator ) : []; }); /** * Creates a slice of `array` with `n` elements dropped from the beginning. * * @static * @memberOf _ * @since 0.5.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.drop([1, 2, 3]); * // => [2, 3] * * _.drop([1, 2, 3], 2); * // => [3] * * _.drop([1, 2, 3], 5); * // => [] * * _.drop([1, 2, 3], 0); * // => [1, 2, 3] */ function drop(array, n, guard) { var length = array == null ? 0 : array.length; if (!length) { return []; } n = guard || n === undefined ? 1 : toInteger(n); return baseSlice(array, n < 0 ? 0 : n, length); } /** * Creates a slice of `array` with `n` elements dropped from the end. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to drop. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.dropRight([1, 2, 3]); * // => [1, 2] * * _.dropRight([1, 2, 3], 2); * // => [1] * * _.dropRight([1, 2, 3], 5); * // => [] * * _.dropRight([1, 2, 3], 0); * // => [1, 2, 3] */ function dropRight(array, n, guard) { var length = array == null ? 0 : array.length; if (!length) { return []; } n = guard || n === undefined ? 1 : toInteger(n); n = length - n; return baseSlice(array, 0, n < 0 ? 0 : n); } /** * Creates a slice of `array` excluding elements dropped from the end. * Elements are dropped until `predicate` returns falsey. The predicate is * invoked with three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * * _.dropRightWhile(users, function(o) { return !o.active; }); * // => objects for ['barney'] * * // The `_.matches` iteratee shorthand. * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); * // => objects for ['barney', 'fred'] * * // The `_.matchesProperty` iteratee shorthand. * _.dropRightWhile(users, ['active', false]); * // => objects for ['barney'] * * // The `_.property` iteratee shorthand. * _.dropRightWhile(users, 'active'); * // => objects for ['barney', 'fred', 'pebbles'] */ function dropRightWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3), true, true) : []; } /** * Creates a slice of `array` excluding elements dropped from the beginning. * Elements are dropped until `predicate` returns falsey. The predicate is * invoked with three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.dropWhile(users, function(o) { return !o.active; }); * // => objects for ['pebbles'] * * // The `_.matches` iteratee shorthand. * _.dropWhile(users, { 'user': 'barney', 'active': false }); * // => objects for ['fred', 'pebbles'] * * // The `_.matchesProperty` iteratee shorthand. * _.dropWhile(users, ['active', false]); * // => objects for ['pebbles'] * * // The `_.property` iteratee shorthand. * _.dropWhile(users, 'active'); * // => objects for ['barney', 'fred', 'pebbles'] */ function dropWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3), true) : []; } /** * Fills elements of `array` with `value` from `start` up to, but not * including, `end`. * * **Note:** This method mutates `array`. * * @static * @memberOf _ * @since 3.2.0 * @category Array * @param {Array} array The array to fill. * @param {*} value The value to fill `array` with. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns `array`. * @example * * var array = [1, 2, 3]; * * _.fill(array, 'a'); * console.log(array); * // => ['a', 'a', 'a'] * * _.fill(Array(3), 2); * // => [2, 2, 2] * * _.fill([4, 6, 8, 10], '*', 1, 3); * // => [4, '*', '*', 10] */ function fill(array, value, start, end) { var length = array == null ? 0 : array.length; if (!length) { return []; } if ( start && typeof start !== 'number' && isIterateeCall(array, value, start) ) { start = 0; end = length; } return baseFill(array, value, start, end); } /** * This method is like `_.find` except that it returns the index of the first * element `predicate` returns truthy for instead of the element itself. * * @static * @memberOf _ * @since 1.1.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=0] The index to search from. * @returns {number} Returns the index of the found element, else `-1`. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.findIndex(users, function(o) { return o.user == 'barney'; }); * // => 0 * * // The `_.matches` iteratee shorthand. * _.findIndex(users, { 'user': 'fred', 'active': false }); * // => 1 * * // The `_.matchesProperty` iteratee shorthand. * _.findIndex(users, ['active', false]); * // => 0 * * // The `_.property` iteratee shorthand. * _.findIndex(users, 'active'); * // => 2 */ function findIndex(array, predicate, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = fromIndex == null ? 0 : toInteger(fromIndex); if (index < 0) { index = nativeMax(length + index, 0); } return baseFindIndex(array, getIteratee(predicate, 3), index); } /** * This method is like `_.findIndex` except that it iterates over elements * of `collection` from right to left. * * @static * @memberOf _ * @since 2.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=array.length-1] The index to search from. * @returns {number} Returns the index of the found element, else `-1`. * @example * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); * // => 2 * * // The `_.matches` iteratee shorthand. * _.findLastIndex(users, { 'user': 'barney', 'active': true }); * // => 0 * * // The `_.matchesProperty` iteratee shorthand. * _.findLastIndex(users, ['active', false]); * // => 2 * * // The `_.property` iteratee shorthand. * _.findLastIndex(users, 'active'); * // => 0 */ function findLastIndex(array, predicate, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = length - 1; if (fromIndex !== undefined) { index = toInteger(fromIndex); index = fromIndex < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); } return baseFindIndex(array, getIteratee(predicate, 3), index, true); } /** * Flattens `array` a single level deep. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * * _.flatten([1, [2, [3, [4]], 5]]); * // => [1, 2, [3, [4]], 5] */ function flatten(array) { var length = array == null ? 0 : array.length; return length ? baseFlatten(array, 1) : []; } /** * Recursively flattens `array`. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * * _.flattenDeep([1, [2, [3, [4]], 5]]); * // => [1, 2, 3, 4, 5] */ function flattenDeep(array) { var length = array == null ? 0 : array.length; return length ? baseFlatten(array, INFINITY) : []; } /** * Recursively flatten `array` up to `depth` times. * * @static * @memberOf _ * @since 4.4.0 * @category Array * @param {Array} array The array to flatten. * @param {number} [depth=1] The maximum recursion depth. * @returns {Array} Returns the new flattened array. * @example * * var array = [1, [2, [3, [4]], 5]]; * * _.flattenDepth(array, 1); * // => [1, 2, [3, [4]], 5] * * _.flattenDepth(array, 2); * // => [1, 2, 3, [4], 5] */ function flattenDepth(array, depth) { var length = array == null ? 0 : array.length; if (!length) { return []; } depth = depth === undefined ? 1 : toInteger(depth); return baseFlatten(array, depth); } /** * The inverse of `_.toPairs`; this method returns an object composed * from key-value `pairs`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} pairs The key-value pairs. * @returns {Object} Returns the new object. * @example * * _.fromPairs([['a', 1], ['b', 2]]); * // => { 'a': 1, 'b': 2 } */ function fromPairs(pairs) { var index = -1, length = pairs == null ? 0 : pairs.length, result = {}; while (++index < length) { var pair = pairs[index]; result[pair[0]] = pair[1]; } return result; } /** * Gets the first element of `array`. * * @static * @memberOf _ * @since 0.1.0 * @alias first * @category Array * @param {Array} array The array to query. * @returns {*} Returns the first element of `array`. * @example * * _.head([1, 2, 3]); * // => 1 * * _.head([]); * // => undefined */ function head(array) { return array && array.length ? array[0] : undefined; } /** * Gets the index at which the first occurrence of `value` is found in `array` * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. If `fromIndex` is negative, it's used as the * offset from the end of `array`. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} [fromIndex=0] The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.indexOf([1, 2, 1, 2], 2); * // => 1 * * // Search from the `fromIndex`. * _.indexOf([1, 2, 1, 2], 2, 2); * // => 3 */ function indexOf(array, value, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = fromIndex == null ? 0 : toInteger(fromIndex); if (index < 0) { index = nativeMax(length + index, 0); } return baseIndexOf(array, value, index); } /** * Gets all but the last element of `array`. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to query. * @returns {Array} Returns the slice of `array`. * @example * * _.initial([1, 2, 3]); * // => [1, 2] */ function initial(array) { var length = array == null ? 0 : array.length; return length ? baseSlice(array, 0, -1) : []; } /** * Creates an array of unique values that are included in all given arrays * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. The order and references of result values are * determined by the first array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of intersecting values. * @example * * _.intersection([2, 1], [2, 3]); * // => [2] */ var intersection = baseRest(function(arrays) { var mapped = arrayMap(arrays, castArrayLikeObject); return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped) : []; }); /** * This method is like `_.intersection` except that it accepts `iteratee` * which is invoked for each element of each `arrays` to generate the criterion * by which they're compared. The order and references of result values are * determined by the first array. The iteratee is invoked with one argument: * (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of intersecting values. * @example * * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [2.1] * * // The `_.property` iteratee shorthand. * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }] */ var intersectionBy = baseRest(function(arrays) { var iteratee = last(arrays), mapped = arrayMap(arrays, castArrayLikeObject); if (iteratee === last(mapped)) { iteratee = undefined; } else { mapped.pop(); } return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, getIteratee(iteratee, 2)) : []; }); /** * This method is like `_.intersection` except that it accepts `comparator` * which is invoked to compare elements of `arrays`. The order and references * of result values are determined by the first array. The comparator is * invoked with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of intersecting values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.intersectionWith(objects, others, _.isEqual); * // => [{ 'x': 1, 'y': 2 }] */ var intersectionWith = baseRest(function(arrays) { var comparator = last(arrays), mapped = arrayMap(arrays, castArrayLikeObject); comparator = typeof comparator === 'function' ? comparator : undefined; if (comparator) { mapped.pop(); } return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined, comparator) : []; }); /** * Converts all elements in `array` into a string separated by `separator`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to convert. * @param {string} [separator=','] The element separator. * @returns {string} Returns the joined string. * @example * * _.join(['a', 'b', 'c'], '~'); * // => 'a~b~c' */ function join(array, separator) { return array == null ? '' : nativeJoin.call(array, separator); } /** * Gets the last element of `array`. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to query. * @returns {*} Returns the last element of `array`. * @example * * _.last([1, 2, 3]); * // => 3 */ function last(array) { var length = array == null ? 0 : array.length; return length ? array[length - 1] : undefined; } /** * This method is like `_.indexOf` except that it iterates over elements of * `array` from right to left. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} [fromIndex=array.length-1] The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.lastIndexOf([1, 2, 1, 2], 2); * // => 3 * * // Search from the `fromIndex`. * _.lastIndexOf([1, 2, 1, 2], 2, 2); * // => 1 */ function lastIndexOf(array, value, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = length; if (fromIndex !== undefined) { index = toInteger(fromIndex); index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); } return value === value ? strictLastIndexOf(array, value, index) : baseFindIndex(array, baseIsNaN, index, true); } /** * Gets the element at index `n` of `array`. If `n` is negative, the nth * element from the end is returned. * * @static * @memberOf _ * @since 4.11.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=0] The index of the element to return. * @returns {*} Returns the nth element of `array`. * @example * * var array = ['a', 'b', 'c', 'd']; * * _.nth(array, 1); * // => 'b' * * _.nth(array, -2); * // => 'c'; */ function nth(array, n) { return array && array.length ? baseNth(array, toInteger(n)) : undefined; } /** * Removes all given values from `array` using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` * to remove elements from an array by predicate. * * @static * @memberOf _ * @since 2.0.0 * @category Array * @param {Array} array The array to modify. * @param {...*} [values] The values to remove. * @returns {Array} Returns `array`. * @example * * var array = ['a', 'b', 'c', 'a', 'b', 'c']; * * _.pull(array, 'a', 'c'); * console.log(array); * // => ['b', 'b'] */ var pull = baseRest(pullAll); /** * This method is like `_.pull` except that it accepts an array of values to remove. * * **Note:** Unlike `_.difference`, this method mutates `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @returns {Array} Returns `array`. * @example * * var array = ['a', 'b', 'c', 'a', 'b', 'c']; * * _.pullAll(array, ['a', 'c']); * console.log(array); * // => ['b', 'b'] */ function pullAll(array, values) { return array && array.length && values && values.length ? basePullAll(array, values) : array; } /** * This method is like `_.pullAll` except that it accepts `iteratee` which is * invoked for each element of `array` and `values` to generate the criterion * by which they're compared. The iteratee is invoked with one argument: (value). * * **Note:** Unlike `_.differenceBy`, this method mutates `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns `array`. * @example * * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; * * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); * console.log(array); * // => [{ 'x': 2 }] */ function pullAllBy(array, values, iteratee) { return array && array.length && values && values.length ? basePullAll(array, values, getIteratee(iteratee, 2)) : array; } /** * This method is like `_.pullAll` except that it accepts `comparator` which * is invoked to compare elements of `array` to `values`. The comparator is * invoked with two arguments: (arrVal, othVal). * * **Note:** Unlike `_.differenceWith`, this method mutates `array`. * * @static * @memberOf _ * @since 4.6.0 * @category Array * @param {Array} array The array to modify. * @param {Array} values The values to remove. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns `array`. * @example * * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; * * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); * console.log(array); * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] */ function pullAllWith(array, values, comparator) { return array && array.length && values && values.length ? basePullAll(array, values, undefined, comparator) : array; } /** * Removes elements from `array` corresponding to `indexes` and returns an * array of removed elements. * * **Note:** Unlike `_.at`, this method mutates `array`. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to modify. * @param {...(number|number[])} [indexes] The indexes of elements to remove. * @returns {Array} Returns the new array of removed elements. * @example * * var array = ['a', 'b', 'c', 'd']; * var pulled = _.pullAt(array, [1, 3]); * * console.log(array); * // => ['a', 'c'] * * console.log(pulled); * // => ['b', 'd'] */ var pullAt = flatRest(function(array, indexes) { var length = array == null ? 0 : array.length, result = baseAt(array, indexes); basePullAt( array, arrayMap(indexes, function(index) { return isIndex(index, length) ? +index : index; }).sort(compareAscending) ); return result; }); /** * Removes all elements from `array` that `predicate` returns truthy for * and returns an array of the removed elements. The predicate is invoked * with three arguments: (value, index, array). * * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` * to pull elements from an array by value. * * @static * @memberOf _ * @since 2.0.0 * @category Array * @param {Array} array The array to modify. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new array of removed elements. * @example * * var array = [1, 2, 3, 4]; * var evens = _.remove(array, function(n) { * return n % 2 == 0; * }); * * console.log(array); * // => [1, 3] * * console.log(evens); * // => [2, 4] */ function remove(array, predicate) { var result = []; if (!(array && array.length)) { return result; } var index = -1, indexes = [], length = array.length; predicate = getIteratee(predicate, 3); while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result.push(value); indexes.push(index); } } basePullAt(array, indexes); return result; } /** * Reverses `array` so that the first element becomes the last, the second * element becomes the second to last, and so on. * * **Note:** This method mutates `array` and is based on * [`Array#reverse`](https://mdn.io/Array/reverse). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to modify. * @returns {Array} Returns `array`. * @example * * var array = [1, 2, 3]; * * _.reverse(array); * // => [3, 2, 1] * * console.log(array); * // => [3, 2, 1] */ function reverse(array) { return array == null ? array : nativeReverse.call(array); } /** * Creates a slice of `array` from `start` up to, but not including, `end`. * * **Note:** This method is used instead of * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are * returned. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to slice. * @param {number} [start=0] The start position. * @param {number} [end=array.length] The end position. * @returns {Array} Returns the slice of `array`. */ function slice(array, start, end) { var length = array == null ? 0 : array.length; if (!length) { return []; } if (end && typeof end !== 'number' && isIterateeCall(array, start, end)) { start = 0; end = length; } else { start = start == null ? 0 : toInteger(start); end = end === undefined ? length : toInteger(end); } return baseSlice(array, start, end); } /** * Uses a binary search to determine the lowest index at which `value` * should be inserted into `array` in order to maintain its sort order. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * _.sortedIndex([30, 50], 40); * // => 1 */ function sortedIndex(array, value) { return baseSortedIndex(array, value); } /** * This method is like `_.sortedIndex` except that it accepts `iteratee` * which is invoked for `value` and each element of `array` to compute their * sort ranking. The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * var objects = [{ 'x': 4 }, { 'x': 5 }]; * * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); * // => 0 * * // The `_.property` iteratee shorthand. * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); * // => 0 */ function sortedIndexBy(array, value, iteratee) { return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); } /** * This method is like `_.indexOf` except that it performs a binary * search on a sorted `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.sortedIndexOf([4, 5, 5, 5, 6], 5); * // => 1 */ function sortedIndexOf(array, value) { var length = array == null ? 0 : array.length; if (length) { var index = baseSortedIndex(array, value); if (index < length && eq(array[index], value)) { return index; } } return -1; } /** * This method is like `_.sortedIndex` except that it returns the highest * index at which `value` should be inserted into `array` in order to * maintain its sort order. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * _.sortedLastIndex([4, 5, 5, 5, 6], 5); * // => 4 */ function sortedLastIndex(array, value) { return baseSortedIndex(array, value, true); } /** * This method is like `_.sortedLastIndex` except that it accepts `iteratee` * which is invoked for `value` and each element of `array` to compute their * sort ranking. The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The sorted array to inspect. * @param {*} value The value to evaluate. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {number} Returns the index at which `value` should be inserted * into `array`. * @example * * var objects = [{ 'x': 4 }, { 'x': 5 }]; * * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); * // => 1 * * // The `_.property` iteratee shorthand. * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); * // => 1 */ function sortedLastIndexBy(array, value, iteratee) { return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); } /** * This method is like `_.lastIndexOf` except that it performs a binary * search on a sorted `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @returns {number} Returns the index of the matched value, else `-1`. * @example * * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); * // => 3 */ function sortedLastIndexOf(array, value) { var length = array == null ? 0 : array.length; if (length) { var index = baseSortedIndex(array, value, true) - 1; if (eq(array[index], value)) { return index; } } return -1; } /** * This method is like `_.uniq` except that it's designed and optimized * for sorted arrays. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @returns {Array} Returns the new duplicate free array. * @example * * _.sortedUniq([1, 1, 2]); * // => [1, 2] */ function sortedUniq(array) { return array && array.length ? baseSortedUniq(array) : []; } /** * This method is like `_.uniqBy` except that it's designed and optimized * for sorted arrays. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @returns {Array} Returns the new duplicate free array. * @example * * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); * // => [1.1, 2.3] */ function sortedUniqBy(array, iteratee) { return array && array.length ? baseSortedUniq(array, getIteratee(iteratee, 2)) : []; } /** * Gets all but the first element of `array`. * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to query. * @returns {Array} Returns the slice of `array`. * @example * * _.tail([1, 2, 3]); * // => [2, 3] */ function tail(array) { var length = array == null ? 0 : array.length; return length ? baseSlice(array, 1, length) : []; } /** * Creates a slice of `array` with `n` elements taken from the beginning. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.take([1, 2, 3]); * // => [1] * * _.take([1, 2, 3], 2); * // => [1, 2] * * _.take([1, 2, 3], 5); * // => [1, 2, 3] * * _.take([1, 2, 3], 0); * // => [] */ function take(array, n, guard) { if (!(array && array.length)) { return []; } n = guard || n === undefined ? 1 : toInteger(n); return baseSlice(array, 0, n < 0 ? 0 : n); } /** * Creates a slice of `array` with `n` elements taken from the end. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {number} [n=1] The number of elements to take. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the slice of `array`. * @example * * _.takeRight([1, 2, 3]); * // => [3] * * _.takeRight([1, 2, 3], 2); * // => [2, 3] * * _.takeRight([1, 2, 3], 5); * // => [1, 2, 3] * * _.takeRight([1, 2, 3], 0); * // => [] */ function takeRight(array, n, guard) { var length = array == null ? 0 : array.length; if (!length) { return []; } n = guard || n === undefined ? 1 : toInteger(n); n = length - n; return baseSlice(array, n < 0 ? 0 : n, length); } /** * Creates a slice of `array` with elements taken from the end. Elements are * taken until `predicate` returns falsey. The predicate is invoked with * three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': false } * ]; * * _.takeRightWhile(users, function(o) { return !o.active; }); * // => objects for ['fred', 'pebbles'] * * // The `_.matches` iteratee shorthand. * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); * // => objects for ['pebbles'] * * // The `_.matchesProperty` iteratee shorthand. * _.takeRightWhile(users, ['active', false]); * // => objects for ['fred', 'pebbles'] * * // The `_.property` iteratee shorthand. * _.takeRightWhile(users, 'active'); * // => [] */ function takeRightWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3), false, true) : []; } /** * Creates a slice of `array` with elements taken from the beginning. Elements * are taken until `predicate` returns falsey. The predicate is invoked with * three arguments: (value, index, array). * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to query. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the slice of `array`. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.takeWhile(users, function(o) { return !o.active; }); * // => objects for ['barney', 'fred'] * * // The `_.matches` iteratee shorthand. * _.takeWhile(users, { 'user': 'barney', 'active': false }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.takeWhile(users, ['active', false]); * // => objects for ['barney', 'fred'] * * // The `_.property` iteratee shorthand. * _.takeWhile(users, 'active'); * // => [] */ function takeWhile(array, predicate) { return array && array.length ? baseWhile(array, getIteratee(predicate, 3)) : []; } /** * Creates an array of unique values, in order, from all given arrays using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of combined values. * @example * * _.union([2], [1, 2]); * // => [2, 1] */ var union = baseRest(function(arrays) { return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); }); /** * This method is like `_.union` except that it accepts `iteratee` which is * invoked for each element of each `arrays` to generate the criterion by * which uniqueness is computed. Result values are chosen from the first * array in which the value occurs. The iteratee is invoked with one argument: * (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of combined values. * @example * * _.unionBy([2.1], [1.2, 2.3], Math.floor); * // => [2.1, 1.2] * * // The `_.property` iteratee shorthand. * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ var unionBy = baseRest(function(arrays) { var iteratee = last(arrays); if (isArrayLikeObject(iteratee)) { iteratee = undefined; } return baseUniq( baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2) ); }); /** * This method is like `_.union` except that it accepts `comparator` which * is invoked to compare elements of `arrays`. Result values are chosen from * the first array in which the value occurs. The comparator is invoked * with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of combined values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.unionWith(objects, others, _.isEqual); * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] */ var unionWith = baseRest(function(arrays) { var comparator = last(arrays); comparator = typeof comparator === 'function' ? comparator : undefined; return baseUniq( baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator ); }); /** * Creates a duplicate-free version of an array, using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons, in which only the first occurrence of each element * is kept. The order of result values is determined by the order they occur * in the array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @returns {Array} Returns the new duplicate free array. * @example * * _.uniq([2, 1, 2]); * // => [2, 1] */ function uniq(array) { return array && array.length ? baseUniq(array) : []; } /** * This method is like `_.uniq` except that it accepts `iteratee` which is * invoked for each element in `array` to generate the criterion by which * uniqueness is computed. The order of result values is determined by the * order they occur in the array. The iteratee is invoked with one argument: * (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new duplicate free array. * @example * * _.uniqBy([2.1, 1.2, 2.3], Math.floor); * // => [2.1, 1.2] * * // The `_.property` iteratee shorthand. * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ function uniqBy(array, iteratee) { return array && array.length ? baseUniq(array, getIteratee(iteratee, 2)) : []; } /** * This method is like `_.uniq` except that it accepts `comparator` which * is invoked to compare elements of `array`. The order of result values is * determined by the order they occur in the array.The comparator is invoked * with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new duplicate free array. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.uniqWith(objects, _.isEqual); * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] */ function uniqWith(array, comparator) { comparator = typeof comparator === 'function' ? comparator : undefined; return array && array.length ? baseUniq(array, undefined, comparator) : []; } /** * This method is like `_.zip` except that it accepts an array of grouped * elements and creates an array regrouping the elements to their pre-zip * configuration. * * @static * @memberOf _ * @since 1.2.0 * @category Array * @param {Array} array The array of grouped elements to process. * @returns {Array} Returns the new array of regrouped elements. * @example * * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); * // => [['a', 1, true], ['b', 2, false]] * * _.unzip(zipped); * // => [['a', 'b'], [1, 2], [true, false]] */ function unzip(array) { if (!(array && array.length)) { return []; } var length = 0; array = arrayFilter(array, function(group) { if (isArrayLikeObject(group)) { length = nativeMax(group.length, length); return true; } }); return baseTimes(length, function(index) { return arrayMap(array, baseProperty(index)); }); } /** * This method is like `_.unzip` except that it accepts `iteratee` to specify * how regrouped values should be combined. The iteratee is invoked with the * elements of each group: (...group). * * @static * @memberOf _ * @since 3.8.0 * @category Array * @param {Array} array The array of grouped elements to process. * @param {Function} [iteratee=_.identity] The function to combine * regrouped values. * @returns {Array} Returns the new array of regrouped elements. * @example * * var zipped = _.zip([1, 2], [10, 20], [100, 200]); * // => [[1, 10, 100], [2, 20, 200]] * * _.unzipWith(zipped, _.add); * // => [3, 30, 300] */ function unzipWith(array, iteratee) { if (!(array && array.length)) { return []; } var result = unzip(array); if (iteratee == null) { return result; } return arrayMap(result, function(group) { return apply(iteratee, undefined, group); }); } /** * Creates an array excluding all given values using * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * **Note:** Unlike `_.pull`, this method returns a new array. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {Array} array The array to inspect. * @param {...*} [values] The values to exclude. * @returns {Array} Returns the new array of filtered values. * @see _.difference, _.xor * @example * * _.without([2, 1, 2, 3], 1, 2); * // => [3] */ var without = baseRest(function(array, values) { return isArrayLikeObject(array) ? baseDifference(array, values) : []; }); /** * Creates an array of unique values that is the * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) * of the given arrays. The order of result values is determined by the order * they occur in the arrays. * * @static * @memberOf _ * @since 2.4.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of filtered values. * @see _.difference, _.without * @example * * _.xor([2, 1], [2, 3]); * // => [1, 3] */ var xor = baseRest(function(arrays) { return baseXor(arrayFilter(arrays, isArrayLikeObject)); }); /** * This method is like `_.xor` except that it accepts `iteratee` which is * invoked for each element of each `arrays` to generate the criterion by * which by which they're compared. The order of result values is determined * by the order they occur in the arrays. The iteratee is invoked with one * argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); * // => [1.2, 3.4] * * // The `_.property` iteratee shorthand. * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 2 }] */ var xorBy = baseRest(function(arrays) { var iteratee = last(arrays); if (isArrayLikeObject(iteratee)) { iteratee = undefined; } return baseXor( arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2) ); }); /** * This method is like `_.xor` except that it accepts `comparator` which is * invoked to compare elements of `arrays`. The order of result values is * determined by the order they occur in the arrays. The comparator is invoked * with two arguments: (arrVal, othVal). * * @static * @memberOf _ * @since 4.0.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. * @example * * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; * * _.xorWith(objects, others, _.isEqual); * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] */ var xorWith = baseRest(function(arrays) { var comparator = last(arrays); comparator = typeof comparator === 'function' ? comparator : undefined; return baseXor( arrayFilter(arrays, isArrayLikeObject), undefined, comparator ); }); /** * Creates an array of grouped elements, the first of which contains the * first elements of the given arrays, the second of which contains the * second elements of the given arrays, and so on. * * @static * @memberOf _ * @since 0.1.0 * @category Array * @param {...Array} [arrays] The arrays to process. * @returns {Array} Returns the new array of grouped elements. * @example * * _.zip(['a', 'b'], [1, 2], [true, false]); * // => [['a', 1, true], ['b', 2, false]] */ var zip = baseRest(unzip); /** * This method is like `_.fromPairs` except that it accepts two arrays, * one of property identifiers and one of corresponding values. * * @static * @memberOf _ * @since 0.4.0 * @category Array * @param {Array} [props=[]] The property identifiers. * @param {Array} [values=[]] The property values. * @returns {Object} Returns the new object. * @example * * _.zipObject(['a', 'b'], [1, 2]); * // => { 'a': 1, 'b': 2 } */ function zipObject(props, values) { return baseZipObject(props || [], values || [], assignValue); } /** * This method is like `_.zipObject` except that it supports property paths. * * @static * @memberOf _ * @since 4.1.0 * @category Array * @param {Array} [props=[]] The property identifiers. * @param {Array} [values=[]] The property values. * @returns {Object} Returns the new object. * @example * * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } */ function zipObjectDeep(props, values) { return baseZipObject(props || [], values || [], baseSet); } /** * This method is like `_.zip` except that it accepts `iteratee` to specify * how grouped values should be combined. The iteratee is invoked with the * elements of each group: (...group). * * @static * @memberOf _ * @since 3.8.0 * @category Array * @param {...Array} [arrays] The arrays to process. * @param {Function} [iteratee=_.identity] The function to combine * grouped values. * @returns {Array} Returns the new array of grouped elements. * @example * * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { * return a + b + c; * }); * // => [111, 222] */ var zipWith = baseRest(function(arrays) { var length = arrays.length, iteratee = length > 1 ? arrays[length - 1] : undefined; iteratee = typeof iteratee === 'function' ? (arrays.pop(), iteratee) : undefined; return unzipWith(arrays, iteratee); }); /* ------------------------------------------------------------------------*/ /** * Creates a `lodash` wrapper instance that wraps `value` with explicit method * chain sequences enabled. The result of such sequences must be unwrapped * with `_#value`. * * @static * @memberOf _ * @since 1.3.0 * @category Seq * @param {*} value The value to wrap. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var users = [ * { 'user': 'barney', 'age': 36 }, * { 'user': 'fred', 'age': 40 }, * { 'user': 'pebbles', 'age': 1 } * ]; * * var youngest = _ * .chain(users) * .sortBy('age') * .map(function(o) { * return o.user + ' is ' + o.age; * }) * .head() * .value(); * // => 'pebbles is 1' */ function chain(value) { var result = lodash(value); result.__chain__ = true; return result; } /** * This method invokes `interceptor` and returns `value`. The interceptor * is invoked with one argument; (value). The purpose of this method is to * "tap into" a method chain sequence in order to modify intermediate results. * * @static * @memberOf _ * @since 0.1.0 * @category Seq * @param {*} value The value to provide to `interceptor`. * @param {Function} interceptor The function to invoke. * @returns {*} Returns `value`. * @example * * _([1, 2, 3]) * .tap(function(array) { * // Mutate input array. * array.pop(); * }) * .reverse() * .value(); * // => [2, 1] */ function tap(value, interceptor) { interceptor(value); return value; } /** * This method is like `_.tap` except that it returns the result of `interceptor`. * The purpose of this method is to "pass thru" values replacing intermediate * results in a method chain sequence. * * @static * @memberOf _ * @since 3.0.0 * @category Seq * @param {*} value The value to provide to `interceptor`. * @param {Function} interceptor The function to invoke. * @returns {*} Returns the result of `interceptor`. * @example * * _(' abc ') * .chain() * .trim() * .thru(function(value) { * return [value]; * }) * .value(); * // => ['abc'] */ function thru(value, interceptor) { return interceptor(value); } /** * This method is the wrapper version of `_.at`. * * @name at * @memberOf _ * @since 1.0.0 * @category Seq * @param {...(string|string[])} [paths] The property paths to pick. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; * * _(object).at(['a[0].b.c', 'a[1]']).value(); * // => [3, 4] */ var wrapperAt = flatRest(function(paths) { var length = paths.length, start = length ? paths[0] : 0, value = this.__wrapped__, interceptor = function(object) { return baseAt(object, paths); }; if ( length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start) ) { return this.thru(interceptor); } value = value.slice(start, +start + (length ? 1 : 0)); value.__actions__.push({ func: thru, args: [interceptor], thisArg: undefined }); return new LodashWrapper(value, this.__chain__).thru(function(array) { if (length && !array.length) { array.push(undefined); } return array; }); }); /** * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. * * @name chain * @memberOf _ * @since 0.1.0 * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var users = [ * { 'user': 'barney', 'age': 36 }, * { 'user': 'fred', 'age': 40 } * ]; * * // A sequence without explicit chaining. * _(users).head(); * // => { 'user': 'barney', 'age': 36 } * * // A sequence with explicit chaining. * _(users) * .chain() * .head() * .pick('user') * .value(); * // => { 'user': 'barney' } */ function wrapperChain() { return chain(this); } /** * Executes the chain sequence and returns the wrapped result. * * @name commit * @memberOf _ * @since 3.2.0 * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var array = [1, 2]; * var wrapped = _(array).push(3); * * console.log(array); * // => [1, 2] * * wrapped = wrapped.commit(); * console.log(array); * // => [1, 2, 3] * * wrapped.last(); * // => 3 * * console.log(array); * // => [1, 2, 3] */ function wrapperCommit() { return new LodashWrapper(this.value(), this.__chain__); } /** * Gets the next value on a wrapped object following the * [iterator protocol](https://mdn.io/iteration_protocols#iterator). * * @name next * @memberOf _ * @since 4.0.0 * @category Seq * @returns {Object} Returns the next iterator value. * @example * * var wrapped = _([1, 2]); * * wrapped.next(); * // => { 'done': false, 'value': 1 } * * wrapped.next(); * // => { 'done': false, 'value': 2 } * * wrapped.next(); * // => { 'done': true, 'value': undefined } */ function wrapperNext() { if (this.__values__ === undefined) { this.__values__ = toArray(this.value()); } var done = this.__index__ >= this.__values__.length, value = done ? undefined : this.__values__[this.__index__++]; return { done: done, value: value }; } /** * Enables the wrapper to be iterable. * * @name Symbol.iterator * @memberOf _ * @since 4.0.0 * @category Seq * @returns {Object} Returns the wrapper object. * @example * * var wrapped = _([1, 2]); * * wrapped[Symbol.iterator]() === wrapped; * // => true * * Array.from(wrapped); * // => [1, 2] */ function wrapperToIterator() { return this; } /** * Creates a clone of the chain sequence planting `value` as the wrapped value. * * @name plant * @memberOf _ * @since 3.2.0 * @category Seq * @param {*} value The value to plant. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * function square(n) { * return n * n; * } * * var wrapped = _([1, 2]).map(square); * var other = wrapped.plant([3, 4]); * * other.value(); * // => [9, 16] * * wrapped.value(); * // => [1, 4] */ function wrapperPlant(value) { var result, parent = this; while (parent instanceof baseLodash) { var clone = wrapperClone(parent); clone.__index__ = 0; clone.__values__ = undefined; if (result) { previous.__wrapped__ = clone; } else { result = clone; } var previous = clone; parent = parent.__wrapped__; } previous.__wrapped__ = value; return result; } /** * This method is the wrapper version of `_.reverse`. * * **Note:** This method mutates the wrapped array. * * @name reverse * @memberOf _ * @since 0.1.0 * @category Seq * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * var array = [1, 2, 3]; * * _(array).reverse().value() * // => [3, 2, 1] * * console.log(array); * // => [3, 2, 1] */ function wrapperReverse() { var value = this.__wrapped__; if (value instanceof LazyWrapper) { var wrapped = value; if (this.__actions__.length) { wrapped = new LazyWrapper(this); } wrapped = wrapped.reverse(); wrapped.__actions__.push({ func: thru, args: [reverse], thisArg: undefined }); return new LodashWrapper(wrapped, this.__chain__); } return this.thru(reverse); } /** * Executes the chain sequence to resolve the unwrapped value. * * @name value * @memberOf _ * @since 0.1.0 * @alias toJSON, valueOf * @category Seq * @returns {*} Returns the resolved unwrapped value. * @example * * _([1, 2, 3]).value(); * // => [1, 2, 3] */ function wrapperValue() { return baseWrapperValue(this.__wrapped__, this.__actions__); } /* ------------------------------------------------------------------------*/ /** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The corresponding value of * each key is the number of times the key was returned by `iteratee`. The * iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 0.5.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * _.countBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': 1, '6': 2 } * * // The `_.property` iteratee shorthand. * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ var countBy = createAggregator(function(result, value, key) { if (hasOwnProperty.call(result, key)) { ++result[key]; } else { baseAssignValue(result, key, 1); } }); /** * Checks if `predicate` returns truthy for **all** elements of `collection`. * Iteration is stopped once `predicate` returns falsey. The predicate is * invoked with three arguments: (value, index|key, collection). * * **Note:** This method returns `true` for * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of * elements of empty collections. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {boolean} Returns `true` if all elements pass the predicate check, * else `false`. * @example * * _.every([true, 1, null, 'yes'], Boolean); * // => false * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': false } * ]; * * // The `_.matches` iteratee shorthand. * _.every(users, { 'user': 'barney', 'active': false }); * // => false * * // The `_.matchesProperty` iteratee shorthand. * _.every(users, ['active', false]); * // => true * * // The `_.property` iteratee shorthand. * _.every(users, 'active'); * // => false */ function every(collection, predicate, guard) { var func = isArray(collection) ? arrayEvery : baseEvery; if (guard && isIterateeCall(collection, predicate, guard)) { predicate = undefined; } return func(collection, getIteratee(predicate, 3)); } /** * Iterates over elements of `collection`, returning an array of all elements * `predicate` returns truthy for. The predicate is invoked with three * arguments: (value, index|key, collection). * * **Note:** Unlike `_.remove`, this method returns a new array. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new filtered array. * @see _.reject * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': true }, * { 'user': 'fred', 'age': 40, 'active': false } * ]; * * _.filter(users, function(o) { return !o.active; }); * // => objects for ['fred'] * * // The `_.matches` iteratee shorthand. * _.filter(users, { 'age': 36, 'active': true }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.filter(users, ['active', false]); * // => objects for ['fred'] * * // The `_.property` iteratee shorthand. * _.filter(users, 'active'); * // => objects for ['barney'] */ function filter(collection, predicate) { var func = isArray(collection) ? arrayFilter : baseFilter; return func(collection, getIteratee(predicate, 3)); } /** * Iterates over elements of `collection`, returning the first element * `predicate` returns truthy for. The predicate is invoked with three * arguments: (value, index|key, collection). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=0] The index to search from. * @returns {*} Returns the matched element, else `undefined`. * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': true }, * { 'user': 'fred', 'age': 40, 'active': false }, * { 'user': 'pebbles', 'age': 1, 'active': true } * ]; * * _.find(users, function(o) { return o.age < 40; }); * // => object for 'barney' * * // The `_.matches` iteratee shorthand. * _.find(users, { 'age': 1, 'active': true }); * // => object for 'pebbles' * * // The `_.matchesProperty` iteratee shorthand. * _.find(users, ['active', false]); * // => object for 'fred' * * // The `_.property` iteratee shorthand. * _.find(users, 'active'); * // => object for 'barney' */ var find = createFind(findIndex); /** * This method is like `_.find` except that it iterates over elements of * `collection` from right to left. * * @static * @memberOf _ * @since 2.0.0 * @category Collection * @param {Array|Object} collection The collection to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=collection.length-1] The index to search from. * @returns {*} Returns the matched element, else `undefined`. * @example * * _.findLast([1, 2, 3, 4], function(n) { * return n % 2 == 1; * }); * // => 3 */ var findLast = createFind(findLastIndex); /** * Creates a flattened array of values by running each element in `collection` * thru `iteratee` and flattening the mapped results. The iteratee is invoked * with three arguments: (value, index|key, collection). * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new flattened array. * @example * * function duplicate(n) { * return [n, n]; * } * * _.flatMap([1, 2], duplicate); * // => [1, 1, 2, 2] */ function flatMap(collection, iteratee) { return baseFlatten(map(collection, iteratee), 1); } /** * This method is like `_.flatMap` except that it recursively flattens the * mapped results. * * @static * @memberOf _ * @since 4.7.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new flattened array. * @example * * function duplicate(n) { * return [[[n, n]]]; * } * * _.flatMapDeep([1, 2], duplicate); * // => [1, 1, 2, 2] */ function flatMapDeep(collection, iteratee) { return baseFlatten(map(collection, iteratee), INFINITY); } /** * This method is like `_.flatMap` except that it recursively flattens the * mapped results up to `depth` times. * * @static * @memberOf _ * @since 4.7.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {number} [depth=1] The maximum recursion depth. * @returns {Array} Returns the new flattened array. * @example * * function duplicate(n) { * return [[[n, n]]]; * } * * _.flatMapDepth([1, 2], duplicate, 2); * // => [[1, 1], [2, 2]] */ function flatMapDepth(collection, iteratee, depth) { depth = depth === undefined ? 1 : toInteger(depth); return baseFlatten(map(collection, iteratee), depth); } /** * Iterates over elements of `collection` and invokes `iteratee` for each element. * The iteratee is invoked with three arguments: (value, index|key, collection). * Iteratee functions may exit iteration early by explicitly returning `false`. * * **Note:** As with other "Collections" methods, objects with a "length" * property are iterated like arrays. To avoid this behavior use `_.forIn` * or `_.forOwn` for object iteration. * * @static * @memberOf _ * @since 0.1.0 * @alias each * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array|Object} Returns `collection`. * @see _.forEachRight * @example * * _.forEach([1, 2], function(value) { * console.log(value); * }); * // => Logs `1` then `2`. * * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { * console.log(key); * }); * // => Logs 'a' then 'b' (iteration order is not guaranteed). */ function forEach(collection, iteratee) { var func = isArray(collection) ? arrayEach : baseEach; return func(collection, getIteratee(iteratee, 3)); } /** * This method is like `_.forEach` except that it iterates over elements of * `collection` from right to left. * * @static * @memberOf _ * @since 2.0.0 * @alias eachRight * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array|Object} Returns `collection`. * @see _.forEach * @example * * _.forEachRight([1, 2], function(value) { * console.log(value); * }); * // => Logs `2` then `1`. */ function forEachRight(collection, iteratee) { var func = isArray(collection) ? arrayEachRight : baseEachRight; return func(collection, getIteratee(iteratee, 3)); } /** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The order of grouped values * is determined by the order they occur in `collection`. The corresponding * value of each key is an array of elements responsible for generating the * key. The iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * _.groupBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': [4.2], '6': [6.1, 6.3] } * * // The `_.property` iteratee shorthand. * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ var groupBy = createAggregator(function(result, value, key) { if (hasOwnProperty.call(result, key)) { result[key].push(value); } else { baseAssignValue(result, key, [value]); } }); /** * Checks if `value` is in `collection`. If `collection` is a string, it's * checked for a substring of `value`, otherwise * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * is used for equality comparisons. If `fromIndex` is negative, it's used as * the offset from the end of `collection`. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object|string} collection The collection to inspect. * @param {*} value The value to search for. * @param {number} [fromIndex=0] The index to search from. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. * @returns {boolean} Returns `true` if `value` is found, else `false`. * @example * * _.includes([1, 2, 3], 1); * // => true * * _.includes([1, 2, 3], 1, 2); * // => false * * _.includes({ 'a': 1, 'b': 2 }, 1); * // => true * * _.includes('abcd', 'bc'); * // => true */ function includes(collection, value, fromIndex, guard) { collection = isArrayLike(collection) ? collection : values(collection); fromIndex = fromIndex && !guard ? toInteger(fromIndex) : 0; var length = collection.length; if (fromIndex < 0) { fromIndex = nativeMax(length + fromIndex, 0); } return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1; } /** * Invokes the method at `path` of each element in `collection`, returning * an array of the results of each invoked method. Any additional arguments * are provided to each invoked method. If `path` is a function, it's invoked * for, and `this` bound to, each element in `collection`. * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Array|Function|string} path The path of the method to invoke or * the function invoked per iteration. * @param {...*} [args] The arguments to invoke each method with. * @returns {Array} Returns the array of results. * @example * * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); * // => [[1, 5, 7], [1, 2, 3]] * * _.invokeMap([123, 456], String.prototype.split, ''); * // => [['1', '2', '3'], ['4', '5', '6']] */ var invokeMap = baseRest(function(collection, path, args) { var index = -1, isFunc = typeof path === 'function', result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value) { result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); }); return result; }); /** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The corresponding value of * each key is the last element responsible for generating the key. The * iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * var array = [ * { 'dir': 'left', 'code': 97 }, * { 'dir': 'right', 'code': 100 } * ]; * * _.keyBy(array, function(o) { * return String.fromCharCode(o.code); * }); * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } * * _.keyBy(array, 'dir'); * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } */ var keyBy = createAggregator(function(result, value, key) { baseAssignValue(result, key, value); }); /** * Creates an array of values by running each element in `collection` thru * `iteratee`. The iteratee is invoked with three arguments: * (value, index|key, collection). * * Many lodash methods are guarded to work as iteratees for methods like * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. * * The guarded methods are: * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, * `template`, `trim`, `trimEnd`, `trimStart`, and `words` * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new mapped array. * @example * * function square(n) { * return n * n; * } * * _.map([4, 8], square); * // => [16, 64] * * _.map({ 'a': 4, 'b': 8 }, square); * // => [16, 64] (iteration order is not guaranteed) * * var users = [ * { 'user': 'barney' }, * { 'user': 'fred' } * ]; * * // The `_.property` iteratee shorthand. * _.map(users, 'user'); * // => ['barney', 'fred'] */ function map(collection, iteratee) { var func = isArray(collection) ? arrayMap : baseMap; return func(collection, getIteratee(iteratee, 3)); } /** * This method is like `_.sortBy` except that it allows specifying the sort * orders of the iteratees to sort by. If `orders` is unspecified, all values * are sorted in ascending order. Otherwise, specify an order of "desc" for * descending or "asc" for ascending sort order of corresponding values. * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] * The iteratees to sort by. * @param {string[]} [orders] The sort orders of `iteratees`. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. * @returns {Array} Returns the new sorted array. * @example * * var users = [ * { 'user': 'fred', 'age': 48 }, * { 'user': 'barney', 'age': 34 }, * { 'user': 'fred', 'age': 40 }, * { 'user': 'barney', 'age': 36 } * ]; * * // Sort by `user` in ascending order and by `age` in descending order. * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] */ function orderBy(collection, iteratees, orders, guard) { if (collection == null) { return []; } if (!isArray(iteratees)) { iteratees = iteratees == null ? [] : [iteratees]; } orders = guard ? undefined : orders; if (!isArray(orders)) { orders = orders == null ? [] : [orders]; } return baseOrderBy(collection, iteratees, orders); } /** * Creates an array of elements split into two groups, the first of which * contains elements `predicate` returns truthy for, the second of which * contains elements `predicate` returns falsey for. The predicate is * invoked with one argument: (value). * * @static * @memberOf _ * @since 3.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the array of grouped elements. * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': true }, * { 'user': 'pebbles', 'age': 1, 'active': false } * ]; * * _.partition(users, function(o) { return o.active; }); * // => objects for [['fred'], ['barney', 'pebbles']] * * // The `_.matches` iteratee shorthand. * _.partition(users, { 'age': 1, 'active': false }); * // => objects for [['pebbles'], ['barney', 'fred']] * * // The `_.matchesProperty` iteratee shorthand. * _.partition(users, ['active', false]); * // => objects for [['barney', 'pebbles'], ['fred']] * * // The `_.property` iteratee shorthand. * _.partition(users, 'active'); * // => objects for [['fred'], ['barney', 'pebbles']] */ var partition = createAggregator( function(result, value, key) { result[key ? 0 : 1].push(value); }, function() { return [[], []]; } ); /** * Reduces `collection` to a value which is the accumulated result of running * each element in `collection` thru `iteratee`, where each successive * invocation is supplied the return value of the previous. If `accumulator` * is not given, the first element of `collection` is used as the initial * value. The iteratee is invoked with four arguments: * (accumulator, value, index|key, collection). * * Many lodash methods are guarded to work as iteratees for methods like * `_.reduce`, `_.reduceRight`, and `_.transform`. * * The guarded methods are: * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, * and `sortBy` * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The initial value. * @returns {*} Returns the accumulated value. * @see _.reduceRight * @example * * _.reduce([1, 2], function(sum, n) { * return sum + n; * }, 0); * // => 3 * * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { * (result[value] || (result[value] = [])).push(key); * return result; * }, {}); * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) */ function reduce(collection, iteratee, accumulator) { var func = isArray(collection) ? arrayReduce : baseReduce, initAccum = arguments.length < 3; return func( collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach ); } /** * This method is like `_.reduce` except that it iterates over elements of * `collection` from right to left. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The initial value. * @returns {*} Returns the accumulated value. * @see _.reduce * @example * * var array = [[0, 1], [2, 3], [4, 5]]; * * _.reduceRight(array, function(flattened, other) { * return flattened.concat(other); * }, []); * // => [4, 5, 2, 3, 0, 1] */ function reduceRight(collection, iteratee, accumulator) { var func = isArray(collection) ? arrayReduceRight : baseReduce, initAccum = arguments.length < 3; return func( collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight ); } /** * The opposite of `_.filter`; this method returns the elements of `collection` * that `predicate` does **not** return truthy for. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new filtered array. * @see _.filter * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': true } * ]; * * _.reject(users, function(o) { return !o.active; }); * // => objects for ['fred'] * * // The `_.matches` iteratee shorthand. * _.reject(users, { 'age': 40, 'active': true }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.reject(users, ['active', false]); * // => objects for ['fred'] * * // The `_.property` iteratee shorthand. * _.reject(users, 'active'); * // => objects for ['barney'] */ function reject(collection, predicate) { var func = isArray(collection) ? arrayFilter : baseFilter; return func(collection, negate(getIteratee(predicate, 3))); } /** * Gets a random element from `collection`. * * @static * @memberOf _ * @since 2.0.0 * @category Collection * @param {Array|Object} collection The collection to sample. * @returns {*} Returns the random element. * @example * * _.sample([1, 2, 3, 4]); * // => 2 */ function sample(collection) { var func = isArray(collection) ? arraySample : baseSample; return func(collection); } /** * Gets `n` random elements at unique keys from `collection` up to the * size of `collection`. * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to sample. * @param {number} [n=1] The number of elements to sample. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Array} Returns the random elements. * @example * * _.sampleSize([1, 2, 3], 2); * // => [3, 1] * * _.sampleSize([1, 2, 3], 4); * // => [2, 3, 1] */ function sampleSize(collection, n, guard) { if (guard ? isIterateeCall(collection, n, guard) : n === undefined) { n = 1; } else { n = toInteger(n); } var func = isArray(collection) ? arraySampleSize : baseSampleSize; return func(collection, n); } /** * Creates an array of shuffled values, using a version of the * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to shuffle. * @returns {Array} Returns the new shuffled array. * @example * * _.shuffle([1, 2, 3, 4]); * // => [4, 1, 3, 2] */ function shuffle(collection) { var func = isArray(collection) ? arrayShuffle : baseShuffle; return func(collection); } /** * Gets the size of `collection` by returning its length for array-like * values or the number of own enumerable string keyed properties for objects. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object|string} collection The collection to inspect. * @returns {number} Returns the collection size. * @example * * _.size([1, 2, 3]); * // => 3 * * _.size({ 'a': 1, 'b': 2 }); * // => 2 * * _.size('pebbles'); * // => 7 */ function size(collection) { if (collection == null) { return 0; } if (isArrayLike(collection)) { return isString(collection) ? stringSize(collection) : collection.length; } var tag = getTag(collection); if (tag == mapTag || tag == setTag) { return collection.size; } return baseKeys(collection).length; } /** * Checks if `predicate` returns truthy for **any** element of `collection`. * Iteration is stopped once `predicate` returns truthy. The predicate is * invoked with three arguments: (value, index|key, collection). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. * @example * * _.some([null, 0, 'yes', false], Boolean); * // => true * * var users = [ * { 'user': 'barney', 'active': true }, * { 'user': 'fred', 'active': false } * ]; * * // The `_.matches` iteratee shorthand. * _.some(users, { 'user': 'barney', 'active': false }); * // => false * * // The `_.matchesProperty` iteratee shorthand. * _.some(users, ['active', false]); * // => true * * // The `_.property` iteratee shorthand. * _.some(users, 'active'); * // => true */ function some(collection, predicate, guard) { var func = isArray(collection) ? arraySome : baseSome; if (guard && isIterateeCall(collection, predicate, guard)) { predicate = undefined; } return func(collection, getIteratee(predicate, 3)); } /** * Creates an array of elements, sorted in ascending order by the results of * running each element in a collection thru each iteratee. This method * performs a stable sort, that is, it preserves the original sort order of * equal elements. The iteratees are invoked with one argument: (value). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {...(Function|Function[])} [iteratees=[_.identity]] * The iteratees to sort by. * @returns {Array} Returns the new sorted array. * @example * * var users = [ * { 'user': 'fred', 'age': 48 }, * { 'user': 'barney', 'age': 36 }, * { 'user': 'fred', 'age': 40 }, * { 'user': 'barney', 'age': 34 } * ]; * * _.sortBy(users, [function(o) { return o.user; }]); * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] * * _.sortBy(users, ['user', 'age']); * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] */ var sortBy = baseRest(function(collection, iteratees) { if (collection == null) { return []; } var length = iteratees.length; if ( length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1]) ) { iteratees = []; } else if ( length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2]) ) { iteratees = [iteratees[0]]; } return baseOrderBy(collection, baseFlatten(iteratees, 1), []); }); /* ------------------------------------------------------------------------*/ /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = ctxNow || function() { return root.Date.now(); }; /* ------------------------------------------------------------------------*/ /** * The opposite of `_.before`; this method creates a function that invokes * `func` once it's called `n` or more times. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {number} n The number of calls before `func` is invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * var saves = ['profile', 'settings']; * * var done = _.after(saves.length, function() { * console.log('done saving!'); * }); * * _.forEach(saves, function(type) { * asyncSave({ 'type': type, 'complete': done }); * }); * // => Logs 'done saving!' after the two async saves have completed. */ function after(n, func) { if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } n = toInteger(n); return function() { if (--n < 1) { return func.apply(this, arguments); } }; } /** * Creates a function that invokes `func`, with up to `n` arguments, * ignoring any additional arguments. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} func The function to cap arguments for. * @param {number} [n=func.length] The arity cap. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the new capped function. * @example * * _.map(['6', '8', '10'], _.ary(parseInt, 1)); * // => [6, 8, 10] */ function ary(func, n, guard) { n = guard ? undefined : n; n = func && n == null ? func.length : n; return createWrap( func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n ); } /** * Creates a function that invokes `func`, with the `this` binding and arguments * of the created function, while it's called less than `n` times. Subsequent * calls to the created function return the result of the last `func` invocation. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {number} n The number of calls at which `func` is no longer invoked. * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * jQuery(element).on('click', _.before(5, addContactToList)); * // => Allows adding up to 4 contacts to the list. */ function before(n, func) { var result; if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } n = toInteger(n); return function() { if (--n > 0) { result = func.apply(this, arguments); } if (n <= 1) { func = undefined; } return result; }; } /** * Creates a function that invokes `func` with the `this` binding of `thisArg` * and `partials` prepended to the arguments it receives. * * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for partially applied arguments. * * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" * property of bound functions. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to bind. * @param {*} thisArg The `this` binding of `func`. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * * function greet(greeting, punctuation) { * return greeting + ' ' + this.user + punctuation; * } * * var object = { 'user': 'fred' }; * * var bound = _.bind(greet, object, 'hi'); * bound('!'); * // => 'hi fred!' * * // Bound with placeholders. * var bound = _.bind(greet, object, _, '!'); * bound('hi'); * // => 'hi fred!' */ var bind = baseRest(function(func, thisArg, partials) { var bitmask = WRAP_BIND_FLAG; if (partials.length) { var holders = replaceHolders(partials, getHolder(bind)); bitmask |= WRAP_PARTIAL_FLAG; } return createWrap(func, bitmask, thisArg, partials, holders); }); /** * Creates a function that invokes the method at `object[key]` with `partials` * prepended to the arguments it receives. * * This method differs from `_.bind` by allowing bound functions to reference * methods that may be redefined or don't yet exist. See * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) * for more details. * * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * * @static * @memberOf _ * @since 0.10.0 * @category Function * @param {Object} object The object to invoke the method on. * @param {string} key The key of the method. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * * var object = { * 'user': 'fred', * 'greet': function(greeting, punctuation) { * return greeting + ' ' + this.user + punctuation; * } * }; * * var bound = _.bindKey(object, 'greet', 'hi'); * bound('!'); * // => 'hi fred!' * * object.greet = function(greeting, punctuation) { * return greeting + 'ya ' + this.user + punctuation; * }; * * bound('!'); * // => 'hiya fred!' * * // Bound with placeholders. * var bound = _.bindKey(object, 'greet', _, '!'); * bound('hi'); * // => 'hiya fred!' */ var bindKey = baseRest(function(object, key, partials) { var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; if (partials.length) { var holders = replaceHolders(partials, getHolder(bindKey)); bitmask |= WRAP_PARTIAL_FLAG; } return createWrap(key, bitmask, object, partials, holders); }); /** * Creates a function that accepts arguments of `func` and either invokes * `func` returning its result, if at least `arity` number of arguments have * been provided, or returns a function that accepts the remaining `func` * arguments, and so on. The arity of `func` may be specified if `func.length` * is not sufficient. * * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for provided arguments. * * **Note:** This method doesn't set the "length" property of curried functions. * * @static * @memberOf _ * @since 2.0.0 * @category Function * @param {Function} func The function to curry. * @param {number} [arity=func.length] The arity of `func`. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the new curried function. * @example * * var abc = function(a, b, c) { * return [a, b, c]; * }; * * var curried = _.curry(abc); * * curried(1)(2)(3); * // => [1, 2, 3] * * curried(1, 2)(3); * // => [1, 2, 3] * * curried(1, 2, 3); * // => [1, 2, 3] * * // Curried with placeholders. * curried(1)(_, 3)(2); * // => [1, 2, 3] */ function curry(func, arity, guard) { arity = guard ? undefined : arity; var result = createWrap( func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity ); result.placeholder = curry.placeholder; return result; } /** * This method is like `_.curry` except that arguments are applied to `func` * in the manner of `_.partialRight` instead of `_.partial`. * * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for provided arguments. * * **Note:** This method doesn't set the "length" property of curried functions. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} func The function to curry. * @param {number} [arity=func.length] The arity of `func`. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the new curried function. * @example * * var abc = function(a, b, c) { * return [a, b, c]; * }; * * var curried = _.curryRight(abc); * * curried(3)(2)(1); * // => [1, 2, 3] * * curried(2, 3)(1); * // => [1, 2, 3] * * curried(1, 2, 3); * // => [1, 2, 3] * * // Curried with placeholders. * curried(3)(1, _)(2); * // => [1, 2, 3] */ function curryRight(func, arity, guard) { arity = guard ? undefined : arity; var result = createWrap( func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity ); result.placeholder = curryRight.placeholder; return result; } /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time; // Start the timer for the trailing edge. timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return ( lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || (maxing && timeSinceLastInvoke >= maxWait) ); } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } // Restart the timer. timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { // Handle invocations in a tight loop. timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } /** * Defers invoking the `func` until the current call stack has cleared. Any * additional arguments are provided to `func` when it's invoked. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to defer. * @param {...*} [args] The arguments to invoke `func` with. * @returns {number} Returns the timer id. * @example * * _.defer(function(text) { * console.log(text); * }, 'deferred'); * // => Logs 'deferred' after one millisecond. */ var defer = baseRest(function(func, args) { return baseDelay(func, 1, args); }); /** * Invokes `func` after `wait` milliseconds. Any additional arguments are * provided to `func` when it's invoked. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to delay. * @param {number} wait The number of milliseconds to delay invocation. * @param {...*} [args] The arguments to invoke `func` with. * @returns {number} Returns the timer id. * @example * * _.delay(function(text) { * console.log(text); * }, 1000, 'later'); * // => Logs 'later' after one second. */ var delay = baseRest(function(func, wait, args) { return baseDelay(func, toNumber(wait) || 0, args); }); /** * Creates a function that invokes `func` with arguments reversed. * * @static * @memberOf _ * @since 4.0.0 * @category Function * @param {Function} func The function to flip arguments for. * @returns {Function} Returns the new flipped function. * @example * * var flipped = _.flip(function() { * return _.toArray(arguments); * }); * * flipped('a', 'b', 'c', 'd'); * // => ['d', 'c', 'b', 'a'] */ function flip(func) { return createWrap(func, WRAP_FLIP_FLAG); } /** * Creates a function that memoizes the result of `func`. If `resolver` is * provided, it determines the cache key for storing the result based on the * arguments provided to the memoized function. By default, the first argument * provided to the memoized function is used as the map cache key. The `func` * is invoked with the `this` binding of the memoized function. * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` * constructor with one whose instances implement the * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) * method interface of `clear`, `delete`, `get`, `has`, and `set`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to have its output memoized. * @param {Function} [resolver] The function to resolve the cache key. * @returns {Function} Returns the new memoized function. * @example * * var object = { 'a': 1, 'b': 2 }; * var other = { 'c': 3, 'd': 4 }; * * var values = _.memoize(_.values); * values(object); * // => [1, 2] * * values(other); * // => [3, 4] * * object.a = 2; * values(object); * // => [1, 2] * * // Modify the result cache. * values.cache.set(object, ['a', 'b']); * values(object); * // => ['a', 'b'] * * // Replace `_.memoize.Cache`. * _.memoize.Cache = WeakMap; */ function memoize(func, resolver) { if ( typeof func !== 'function' || (resolver != null && typeof resolver !== 'function') ) { throw new TypeError(FUNC_ERROR_TEXT); } var memoized = function() { var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache = memoized.cache; if (cache.has(key)) { return cache.get(key); } var result = func.apply(this, args); memoized.cache = cache.set(key, result) || cache; return result; }; memoized.cache = new (memoize.Cache || MapCache)(); return memoized; } // Expose `MapCache`. memoize.Cache = MapCache; /** * Creates a function that negates the result of the predicate `func`. The * `func` predicate is invoked with the `this` binding and arguments of the * created function. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} predicate The predicate to negate. * @returns {Function} Returns the new negated function. * @example * * function isEven(n) { * return n % 2 == 0; * } * * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); * // => [1, 3, 5] */ function negate(predicate) { if (typeof predicate !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } return function() { var args = arguments; switch (args.length) { case 0: return !predicate.call(this); case 1: return !predicate.call(this, args[0]); case 2: return !predicate.call(this, args[0], args[1]); case 3: return !predicate.call(this, args[0], args[1], args[2]); } return !predicate.apply(this, args); }; } /** * Creates a function that is restricted to invoking `func` once. Repeat calls * to the function return the value of the first invocation. The `func` is * invoked with the `this` binding and arguments of the created function. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to restrict. * @returns {Function} Returns the new restricted function. * @example * * var initialize = _.once(createApplication); * initialize(); * initialize(); * // => `createApplication` is invoked once */ function once(func) { return before(2, func); } /** * Creates a function that invokes `func` with its arguments transformed. * * @static * @since 4.0.0 * @memberOf _ * @category Function * @param {Function} func The function to wrap. * @param {...(Function|Function[])} [transforms=[_.identity]] * The argument transforms. * @returns {Function} Returns the new function. * @example * * function doubled(n) { * return n * 2; * } * * function square(n) { * return n * n; * } * * var func = _.overArgs(function(x, y) { * return [x, y]; * }, [square, doubled]); * * func(9, 3); * // => [81, 6] * * func(10, 5); * // => [100, 10] */ var overArgs = castRest(function(func, transforms) { transforms = transforms.length == 1 && isArray(transforms[0]) ? arrayMap(transforms[0], baseUnary(getIteratee())) : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); var funcsLength = transforms.length; return baseRest(function(args) { var index = -1, length = nativeMin(args.length, funcsLength); while (++index < length) { args[index] = transforms[index].call(this, args[index]); } return apply(func, this, args); }); }); /** * Creates a function that invokes `func` with `partials` prepended to the * arguments it receives. This method is like `_.bind` except it does **not** * alter the `this` binding. * * The `_.partial.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * * **Note:** This method doesn't set the "length" property of partially * applied functions. * * @static * @memberOf _ * @since 0.2.0 * @category Function * @param {Function} func The function to partially apply arguments to. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. * @example * * function greet(greeting, name) { * return greeting + ' ' + name; * } * * var sayHelloTo = _.partial(greet, 'hello'); * sayHelloTo('fred'); * // => 'hello fred' * * // Partially applied with placeholders. * var greetFred = _.partial(greet, _, 'fred'); * greetFred('hi'); * // => 'hi fred' */ var partial = baseRest(function(func, partials) { var holders = replaceHolders(partials, getHolder(partial)); return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); }); /** * This method is like `_.partial` except that partially applied arguments * are appended to the arguments it receives. * * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic * builds, may be used as a placeholder for partially applied arguments. * * **Note:** This method doesn't set the "length" property of partially * applied functions. * * @static * @memberOf _ * @since 1.0.0 * @category Function * @param {Function} func The function to partially apply arguments to. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new partially applied function. * @example * * function greet(greeting, name) { * return greeting + ' ' + name; * } * * var greetFred = _.partialRight(greet, 'fred'); * greetFred('hi'); * // => 'hi fred' * * // Partially applied with placeholders. * var sayHelloTo = _.partialRight(greet, 'hello', _); * sayHelloTo('fred'); * // => 'hello fred' */ var partialRight = baseRest(function(func, partials) { var holders = replaceHolders(partials, getHolder(partialRight)); return createWrap( func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders ); }); /** * Creates a function that invokes `func` with arguments arranged according * to the specified `indexes` where the argument value at the first index is * provided as the first argument, the argument value at the second index is * provided as the second argument, and so on. * * @static * @memberOf _ * @since 3.0.0 * @category Function * @param {Function} func The function to rearrange arguments for. * @param {...(number|number[])} indexes The arranged argument indexes. * @returns {Function} Returns the new function. * @example * * var rearged = _.rearg(function(a, b, c) { * return [a, b, c]; * }, [2, 0, 1]); * * rearged('b', 'c', 'a') * // => ['a', 'b', 'c'] */ var rearg = flatRest(function(func, indexes) { return createWrap( func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes ); }); /** * Creates a function that invokes `func` with the `this` binding of the * created function and arguments from `start` and beyond provided as * an array. * * **Note:** This method is based on the * [rest parameter](https://mdn.io/rest_parameters). * * @static * @memberOf _ * @since 4.0.0 * @category Function * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @returns {Function} Returns the new function. * @example * * var say = _.rest(function(what, names) { * return what + ' ' + _.initial(names).join(', ') + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); * }); * * say('hello', 'fred', 'barney', 'pebbles'); * // => 'hello fred, barney, & pebbles' */ function rest(func, start) { if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } start = start === undefined ? start : toInteger(start); return baseRest(func, start); } /** * Creates a function that invokes `func` with the `this` binding of the * create function and an array of arguments much like * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). * * **Note:** This method is based on the * [spread operator](https://mdn.io/spread_operator). * * @static * @memberOf _ * @since 3.2.0 * @category Function * @param {Function} func The function to spread arguments over. * @param {number} [start=0] The start position of the spread. * @returns {Function} Returns the new function. * @example * * var say = _.spread(function(who, what) { * return who + ' says ' + what; * }); * * say(['fred', 'hello']); * // => 'fred says hello' * * var numbers = Promise.all([ * Promise.resolve(40), * Promise.resolve(36) * ]); * * numbers.then(_.spread(function(x, y) { * return x + y; * })); * // => a Promise of 76 */ function spread(func, start) { if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } start = start == null ? 0 : nativeMax(toInteger(start), 0); return baseRest(function(args) { var array = args[start], otherArgs = castSlice(args, 0, start); if (array) { arrayPush(otherArgs, array); } return apply(func, this, otherArgs); }); } /** * Creates a throttled function that only invokes `func` at most once per * every `wait` milliseconds. The throttled function comes with a `cancel` * method to cancel delayed `func` invocations and a `flush` method to * immediately invoke them. Provide `options` to indicate whether `func` * should be invoked on the leading and/or trailing edge of the `wait` * timeout. The `func` is invoked with the last arguments provided to the * throttled function. Subsequent calls to the throttled function return the * result of the last `func` invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the throttled function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.throttle` and `_.debounce`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to throttle. * @param {number} [wait=0] The number of milliseconds to throttle invocations to. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=true] * Specify invoking on the leading edge of the timeout. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new throttled function. * @example * * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); * jQuery(element).on('click', throttled); * * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel); */ function throttle(func, wait, options) { var leading = true, trailing = true; if (typeof func !== 'function') { throw new TypeError(FUNC_ERROR_TEXT); } if (isObject(options)) { leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } return debounce(func, wait, { leading: leading, maxWait: wait, trailing: trailing }); } /** * Creates a function that accepts up to one argument, ignoring any * additional arguments. * * @static * @memberOf _ * @since 4.0.0 * @category Function * @param {Function} func The function to cap arguments for. * @returns {Function} Returns the new capped function. * @example * * _.map(['6', '8', '10'], _.unary(parseInt)); * // => [6, 8, 10] */ function unary(func) { return ary(func, 1); } /** * Creates a function that provides `value` to `wrapper` as its first * argument. Any additional arguments provided to the function are appended * to those provided to the `wrapper`. The wrapper is invoked with the `this` * binding of the created function. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {*} value The value to wrap. * @param {Function} [wrapper=identity] The wrapper function. * @returns {Function} Returns the new function. * @example * * var p = _.wrap(_.escape, function(func, text) { * return '

' + func(text) + '

'; * }); * * p('fred, barney, & pebbles'); * // => '

fred, barney, & pebbles

' */ function wrap(value, wrapper) { return partial(castFunction(wrapper), value); } /* ------------------------------------------------------------------------*/ /** * Casts `value` as an array if it's not one. * * @static * @memberOf _ * @since 4.4.0 * @category Lang * @param {*} value The value to inspect. * @returns {Array} Returns the cast array. * @example * * _.castArray(1); * // => [1] * * _.castArray({ 'a': 1 }); * // => [{ 'a': 1 }] * * _.castArray('abc'); * // => ['abc'] * * _.castArray(null); * // => [null] * * _.castArray(undefined); * // => [undefined] * * _.castArray(); * // => [] * * var array = [1, 2, 3]; * console.log(_.castArray(array) === array); * // => true */ function castArray() { if (!arguments.length) { return []; } var value = arguments[0]; return isArray(value) ? value : [value]; } /** * Creates a shallow clone of `value`. * * **Note:** This method is loosely based on the * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) * and supports cloning arrays, array buffers, booleans, date objects, maps, * numbers, `Object` objects, regexes, sets, strings, symbols, and typed * arrays. The own enumerable properties of `arguments` objects are cloned * as plain objects. An empty object is returned for uncloneable values such * as error objects, functions, DOM nodes, and WeakMaps. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to clone. * @returns {*} Returns the cloned value. * @see _.cloneDeep * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; * * var shallow = _.clone(objects); * console.log(shallow[0] === objects[0]); * // => true */ function clone(value) { return baseClone(value, CLONE_SYMBOLS_FLAG); } /** * This method is like `_.clone` except that it accepts `customizer` which * is invoked to produce the cloned value. If `customizer` returns `undefined`, * cloning is handled by the method instead. The `customizer` is invoked with * up to four arguments; (value [, index|key, object, stack]). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to clone. * @param {Function} [customizer] The function to customize cloning. * @returns {*} Returns the cloned value. * @see _.cloneDeepWith * @example * * function customizer(value) { * if (_.isElement(value)) { * return value.cloneNode(false); * } * } * * var el = _.cloneWith(document.body, customizer); * * console.log(el === document.body); * // => false * console.log(el.nodeName); * // => 'BODY' * console.log(el.childNodes.length); * // => 0 */ function cloneWith(value, customizer) { customizer = typeof customizer === 'function' ? customizer : undefined; return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); } /** * This method is like `_.clone` except that it recursively clones `value`. * * @static * @memberOf _ * @since 1.0.0 * @category Lang * @param {*} value The value to recursively clone. * @returns {*} Returns the deep cloned value. * @see _.clone * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; * * var deep = _.cloneDeep(objects); * console.log(deep[0] === objects[0]); * // => false */ function cloneDeep(value) { return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); } /** * This method is like `_.cloneWith` except that it recursively clones `value`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to recursively clone. * @param {Function} [customizer] The function to customize cloning. * @returns {*} Returns the deep cloned value. * @see _.cloneWith * @example * * function customizer(value) { * if (_.isElement(value)) { * return value.cloneNode(true); * } * } * * var el = _.cloneDeepWith(document.body, customizer); * * console.log(el === document.body); * // => false * console.log(el.nodeName); * // => 'BODY' * console.log(el.childNodes.length); * // => 20 */ function cloneDeepWith(value, customizer) { customizer = typeof customizer === 'function' ? customizer : undefined; return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); } /** * Checks if `object` conforms to `source` by invoking the predicate * properties of `source` with the corresponding property values of `object`. * * **Note:** This method is equivalent to `_.conforms` when `source` is * partially applied. * * @static * @memberOf _ * @since 4.14.0 * @category Lang * @param {Object} object The object to inspect. * @param {Object} source The object of property predicates to conform to. * @returns {boolean} Returns `true` if `object` conforms, else `false`. * @example * * var object = { 'a': 1, 'b': 2 }; * * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); * // => true * * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); * // => false */ function conformsTo(object, source) { return source == null || baseConformsTo(object, source, keys(source)); } /** * Performs a * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', Object('a')); * // => false * * _.eq(NaN, NaN); * // => true */ function eq(value, other) { return value === other || (value !== value && other !== other); } /** * Checks if `value` is greater than `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than `other`, * else `false`. * @see _.lt * @example * * _.gt(3, 1); * // => true * * _.gt(3, 3); * // => false * * _.gt(1, 3); * // => false */ var gt = createRelationalOperation(baseGt); /** * Checks if `value` is greater than or equal to `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is greater than or equal to * `other`, else `false`. * @see _.lte * @example * * _.gte(3, 1); * // => true * * _.gte(3, 3); * // => true * * _.gte(1, 3); * // => false */ var gte = createRelationalOperation(function(value, other) { return value >= other; }); /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ var isArguments = baseIsArguments( (function() { return arguments; })() ) ? baseIsArguments : function(value) { return ( isObjectLike(value) && hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') ); }; /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; /** * Checks if `value` is classified as an `ArrayBuffer` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. * @example * * _.isArrayBuffer(new ArrayBuffer(2)); * // => true * * _.isArrayBuffer(new Array(2)); * // => false */ var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(value.length) && !isFunction(value); } /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject(value) { return isObjectLike(value) && isArrayLike(value); } /** * Checks if `value` is classified as a boolean primitive or object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. * @example * * _.isBoolean(false); * // => true * * _.isBoolean(null); * // => false */ function isBoolean(value) { return ( value === true || value === false || (isObjectLike(value) && baseGetTag(value) == boolTag) ); } /** * Checks if `value` is a buffer. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. * @example * * _.isBuffer(new Buffer(2)); * // => true * * _.isBuffer(new Uint8Array(2)); * // => false */ var isBuffer = nativeIsBuffer || stubFalse; /** * Checks if `value` is classified as a `Date` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a date object, else `false`. * @example * * _.isDate(new Date); * // => true * * _.isDate('Mon April 23 2012'); * // => false */ var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; /** * Checks if `value` is likely a DOM element. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. * @example * * _.isElement(document.body); * // => true * * _.isElement(''); * // => false */ function isElement(value) { return ( isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value) ); } /** * Checks if `value` is an empty object, collection, map, or set. * * Objects are considered empty if they have no own enumerable string keyed * properties. * * Array-like values such as `arguments` objects, arrays, buffers, strings, or * jQuery-like collections are considered empty if they have a `length` of `0`. * Similarly, maps and sets are considered empty if they have a `size` of `0`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is empty, else `false`. * @example * * _.isEmpty(null); * // => true * * _.isEmpty(true); * // => true * * _.isEmpty(1); * // => true * * _.isEmpty([1, 2, 3]); * // => false * * _.isEmpty({ 'a': 1 }); * // => false */ function isEmpty(value) { if (value == null) { return true; } if ( isArrayLike(value) && (isArray(value) || typeof value === 'string' || typeof value.splice === 'function' || isBuffer(value) || isTypedArray(value) || isArguments(value)) ) { return !value.length; } var tag = getTag(value); if (tag == mapTag || tag == setTag) { return !value.size; } if (isPrototype(value)) { return !baseKeys(value).length; } for (var key in value) { if (hasOwnProperty.call(value, key)) { return false; } } return true; } /** * Performs a deep comparison between two values to determine if they are * equivalent. * * **Note:** This method supports comparing arrays, array buffers, booleans, * date objects, error objects, maps, numbers, `Object` objects, regexes, * sets, strings, symbols, and typed arrays. `Object` objects are compared * by their own, not inherited, enumerable properties. Functions and DOM * nodes are compared by strict equality, i.e. `===`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.isEqual(object, other); * // => true * * object === other; * // => false */ function isEqual(value, other) { return baseIsEqual(value, other); } /** * This method is like `_.isEqual` except that it accepts `customizer` which * is invoked to compare values. If `customizer` returns `undefined`, comparisons * are handled by the method instead. The `customizer` is invoked with up to * six arguments: (objValue, othValue [, index|key, object, other, stack]). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * function isGreeting(value) { * return /^h(?:i|ello)$/.test(value); * } * * function customizer(objValue, othValue) { * if (isGreeting(objValue) && isGreeting(othValue)) { * return true; * } * } * * var array = ['hello', 'goodbye']; * var other = ['hi', 'goodbye']; * * _.isEqualWith(array, other, customizer); * // => true */ function isEqualWith(value, other, customizer) { customizer = typeof customizer === 'function' ? customizer : undefined; var result = customizer ? customizer(value, other) : undefined; return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; } /** * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, * `SyntaxError`, `TypeError`, or `URIError` object. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an error object, else `false`. * @example * * _.isError(new Error); * // => true * * _.isError(Error); * // => false */ function isError(value) { if (!isObjectLike(value)) { return false; } var tag = baseGetTag(value); return ( tag == errorTag || tag == domExcTag || (typeof value.message === 'string' && typeof value.name === 'string' && !isPlainObject(value)) ); } /** * Checks if `value` is a finite primitive number. * * **Note:** This method is based on * [`Number.isFinite`](https://mdn.io/Number/isFinite). * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. * @example * * _.isFinite(3); * // => true * * _.isFinite(Number.MIN_VALUE); * // => true * * _.isFinite(Infinity); * // => false * * _.isFinite('3'); * // => false */ function isFinite(value) { return typeof value === 'number' && nativeIsFinite(value); } /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { if (!isObject(value)) { return false; } // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 9 which returns 'object' for typed arrays and other constructors. var tag = baseGetTag(value); return ( tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag ); } /** * Checks if `value` is an integer. * * **Note:** This method is based on * [`Number.isInteger`](https://mdn.io/Number/isInteger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an integer, else `false`. * @example * * _.isInteger(3); * // => true * * _.isInteger(Number.MIN_VALUE); * // => false * * _.isInteger(Infinity); * // => false * * _.isInteger('3'); * // => false */ function isInteger(value) { return typeof value === 'number' && value == toInteger(value); } /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return ( typeof value === 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER ); } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value === 'object'; } /** * Checks if `value` is classified as a `Map` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a map, else `false`. * @example * * _.isMap(new Map); * // => true * * _.isMap(new WeakMap); * // => false */ var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; /** * Performs a partial deep comparison between `object` and `source` to * determine if `object` contains equivalent property values. * * **Note:** This method is equivalent to `_.matches` when `source` is * partially applied. * * Partial comparisons will match empty array and empty object `source` * values against any array or object value, respectively. See `_.isEqual` * for a list of supported value comparisons. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @returns {boolean} Returns `true` if `object` is a match, else `false`. * @example * * var object = { 'a': 1, 'b': 2 }; * * _.isMatch(object, { 'b': 2 }); * // => true * * _.isMatch(object, { 'b': 1 }); * // => false */ function isMatch(object, source) { return ( object === source || baseIsMatch(object, source, getMatchData(source)) ); } /** * This method is like `_.isMatch` except that it accepts `customizer` which * is invoked to compare values. If `customizer` returns `undefined`, comparisons * are handled by the method instead. The `customizer` is invoked with five * arguments: (objValue, srcValue, index|key, object, source). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if `object` is a match, else `false`. * @example * * function isGreeting(value) { * return /^h(?:i|ello)$/.test(value); * } * * function customizer(objValue, srcValue) { * if (isGreeting(objValue) && isGreeting(srcValue)) { * return true; * } * } * * var object = { 'greeting': 'hello' }; * var source = { 'greeting': 'hi' }; * * _.isMatchWith(object, source, customizer); * // => true */ function isMatchWith(object, source, customizer) { customizer = typeof customizer === 'function' ? customizer : undefined; return baseIsMatch(object, source, getMatchData(source), customizer); } /** * Checks if `value` is `NaN`. * * **Note:** This method is based on * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for * `undefined` and other non-number values. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. * @example * * _.isNaN(NaN); * // => true * * _.isNaN(new Number(NaN)); * // => true * * isNaN(undefined); * // => true * * _.isNaN(undefined); * // => false */ function isNaN(value) { // An `NaN` primitive is the only value that is not equal to itself. // Perform the `toStringTag` check first to avoid errors with some // ActiveX objects in IE. return isNumber(value) && value != +value; } /** * Checks if `value` is a pristine native function. * * **Note:** This method can't reliably detect native functions in the presence * of the core-js package because core-js circumvents this kind of detection. * Despite multiple requests, the core-js maintainer has made it clear: any * attempt to fix the detection will be obstructed. As a result, we're left * with little choice but to throw an error. Unfortunately, this also affects * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), * which rely on core-js. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. * @example * * _.isNative(Array.prototype.push); * // => true * * _.isNative(_); * // => false */ function isNative(value) { if (isMaskable(value)) { throw new Error(CORE_ERROR_TEXT); } return baseIsNative(value); } /** * Checks if `value` is `null`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `null`, else `false`. * @example * * _.isNull(null); * // => true * * _.isNull(void 0); * // => false */ function isNull(value) { return value === null; } /** * Checks if `value` is `null` or `undefined`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is nullish, else `false`. * @example * * _.isNil(null); * // => true * * _.isNil(void 0); * // => true * * _.isNil(NaN); * // => false */ function isNil(value) { return value == null; } /** * Checks if `value` is classified as a `Number` primitive or object. * * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are * classified as numbers, use the `_.isFinite` method. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a number, else `false`. * @example * * _.isNumber(3); * // => true * * _.isNumber(Number.MIN_VALUE); * // => true * * _.isNumber(Infinity); * // => true * * _.isNumber('3'); * // => false */ function isNumber(value) { return ( typeof value === 'number' || (isObjectLike(value) && baseGetTag(value) == numberTag) ); } /** * Checks if `value` is a plain object, that is, an object created by the * `Object` constructor or one with a `[[Prototype]]` of `null`. * * @static * @memberOf _ * @since 0.8.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * * function Foo() { * this.a = 1; * } * * _.isPlainObject(new Foo); * // => false * * _.isPlainObject([1, 2, 3]); * // => false * * _.isPlainObject({ 'x': 0, 'y': 0 }); * // => true * * _.isPlainObject(Object.create(null)); * // => true */ function isPlainObject(value) { if (!isObjectLike(value) || baseGetTag(value) != objectTag) { return false; } var proto = getPrototype(value); if (proto === null) { return true; } var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; return ( typeof Ctor === 'function' && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString ); } /** * Checks if `value` is classified as a `RegExp` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. * @example * * _.isRegExp(/abc/); * // => true * * _.isRegExp('/abc/'); * // => false */ var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; /** * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 * double precision number which isn't the result of a rounded unsafe integer. * * **Note:** This method is based on * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. * @example * * _.isSafeInteger(3); * // => true * * _.isSafeInteger(Number.MIN_VALUE); * // => false * * _.isSafeInteger(Infinity); * // => false * * _.isSafeInteger('3'); * // => false */ function isSafeInteger(value) { return ( isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER ); } /** * Checks if `value` is classified as a `Set` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a set, else `false`. * @example * * _.isSet(new Set); * // => true * * _.isSet(new WeakSet); * // => false */ var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; /** * Checks if `value` is classified as a `String` primitive or object. * * @static * @since 0.1.0 * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a string, else `false`. * @example * * _.isString('abc'); * // => true * * _.isString(1); * // => false */ function isString(value) { return ( typeof value === 'string' || (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag) ); } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return ( typeof value === 'symbol' || (isObjectLike(value) && baseGetTag(value) == symbolTag) ); } /** * Checks if `value` is classified as a typed array. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. * @example * * _.isTypedArray(new Uint8Array); * // => true * * _.isTypedArray([]); * // => false */ var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; /** * Checks if `value` is `undefined`. * * @static * @since 0.1.0 * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. * @example * * _.isUndefined(void 0); * // => true * * _.isUndefined(null); * // => false */ function isUndefined(value) { return value === undefined; } /** * Checks if `value` is classified as a `WeakMap` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. * @example * * _.isWeakMap(new WeakMap); * // => true * * _.isWeakMap(new Map); * // => false */ function isWeakMap(value) { return isObjectLike(value) && getTag(value) == weakMapTag; } /** * Checks if `value` is classified as a `WeakSet` object. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. * @example * * _.isWeakSet(new WeakSet); * // => true * * _.isWeakSet(new Set); * // => false */ function isWeakSet(value) { return isObjectLike(value) && baseGetTag(value) == weakSetTag; } /** * Checks if `value` is less than `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than `other`, * else `false`. * @see _.gt * @example * * _.lt(1, 3); * // => true * * _.lt(3, 3); * // => false * * _.lt(3, 1); * // => false */ var lt = createRelationalOperation(baseLt); /** * Checks if `value` is less than or equal to `other`. * * @static * @memberOf _ * @since 3.9.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if `value` is less than or equal to * `other`, else `false`. * @see _.gte * @example * * _.lte(1, 3); * // => true * * _.lte(3, 3); * // => true * * _.lte(3, 1); * // => false */ var lte = createRelationalOperation(function(value, other) { return value <= other; }); /** * Converts `value` to an array. * * @static * @since 0.1.0 * @memberOf _ * @category Lang * @param {*} value The value to convert. * @returns {Array} Returns the converted array. * @example * * _.toArray({ 'a': 1, 'b': 2 }); * // => [1, 2] * * _.toArray('abc'); * // => ['a', 'b', 'c'] * * _.toArray(1); * // => [] * * _.toArray(null); * // => [] */ function toArray(value) { if (!value) { return []; } if (isArrayLike(value)) { return isString(value) ? stringToArray(value) : copyArray(value); } if (symIterator && value[symIterator]) { return iteratorToArray(value[symIterator]()); } var tag = getTag(value), func = tag == mapTag ? mapToArray : tag == setTag ? setToArray : values; return func(value); } /** * Converts `value` to a finite number. * * @static * @memberOf _ * @since 4.12.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted number. * @example * * _.toFinite(3.2); * // => 3.2 * * _.toFinite(Number.MIN_VALUE); * // => 5e-324 * * _.toFinite(Infinity); * // => 1.7976931348623157e+308 * * _.toFinite('3.2'); * // => 3.2 */ function toFinite(value) { if (!value) { return value === 0 ? value : 0; } value = toNumber(value); if (value === INFINITY || value === -INFINITY) { var sign = value < 0 ? -1 : 1; return sign * MAX_INTEGER; } return value === value ? value : 0; } /** * Converts `value` to an integer. * * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); * // => 0 * * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * * _.toInteger('3.2'); * // => 3 */ function toInteger(value) { var result = toFinite(value), remainder = result % 1; return result === result ? (remainder ? result - remainder : result) : 0; } /** * Converts `value` to an integer suitable for use as the length of an * array-like object. * * **Note:** This method is based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toLength(3.2); * // => 3 * * _.toLength(Number.MIN_VALUE); * // => 0 * * _.toLength(Infinity); * // => 4294967295 * * _.toLength('3.2'); * // => 3 */ function toLength(value) { return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value === 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf === 'function' ? value.valueOf() : value; value = isObject(other) ? other + '' : other; } if (typeof value !== 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } /** * Converts `value` to a plain object flattening inherited enumerable string * keyed properties of `value` to own properties of the plain object. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to convert. * @returns {Object} Returns the converted plain object. * @example * * function Foo() { * this.b = 2; * } * * Foo.prototype.c = 3; * * _.assign({ 'a': 1 }, new Foo); * // => { 'a': 1, 'b': 2 } * * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); * // => { 'a': 1, 'b': 2, 'c': 3 } */ function toPlainObject(value) { return copyObject(value, keysIn(value)); } /** * Converts `value` to a safe integer. A safe integer can be compared and * represented correctly. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toSafeInteger(3.2); * // => 3 * * _.toSafeInteger(Number.MIN_VALUE); * // => 0 * * _.toSafeInteger(Infinity); * // => 9007199254740991 * * _.toSafeInteger('3.2'); * // => 3 */ function toSafeInteger(value) { return value ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0; } /** * Converts `value` to a string. An empty string is returned for `null` * and `undefined` values. The sign of `-0` is preserved. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {string} Returns the converted string. * @example * * _.toString(null); * // => '' * * _.toString(-0); * // => '-0' * * _.toString([1, 2, 3]); * // => '1,2,3' */ function toString(value) { return value == null ? '' : baseToString(value); } /* ------------------------------------------------------------------------*/ /** * Assigns own enumerable string keyed properties of source objects to the * destination object. Source objects are applied from left to right. * Subsequent sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object` and is loosely based on * [`Object.assign`](https://mdn.io/Object/assign). * * @static * @memberOf _ * @since 0.10.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.assignIn * @example * * function Foo() { * this.a = 1; * } * * function Bar() { * this.c = 3; * } * * Foo.prototype.b = 2; * Bar.prototype.d = 4; * * _.assign({ 'a': 0 }, new Foo, new Bar); * // => { 'a': 1, 'c': 3 } */ var assign = createAssigner(function(object, source) { if (isPrototype(source) || isArrayLike(source)) { copyObject(source, keys(source), object); return; } for (var key in source) { if (hasOwnProperty.call(source, key)) { assignValue(object, key, source[key]); } } }); /** * This method is like `_.assign` except that it iterates over own and * inherited source properties. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @alias extend * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.assign * @example * * function Foo() { * this.a = 1; * } * * function Bar() { * this.c = 3; * } * * Foo.prototype.b = 2; * Bar.prototype.d = 4; * * _.assignIn({ 'a': 0 }, new Foo, new Bar); * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } */ var assignIn = createAssigner(function(object, source) { copyObject(source, keysIn(source), object); }); /** * This method is like `_.assignIn` except that it accepts `customizer` * which is invoked to produce the assigned values. If `customizer` returns * `undefined`, assignment is handled by the method instead. The `customizer` * is invoked with five arguments: (objValue, srcValue, key, object, source). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @alias extendWith * @category Object * @param {Object} object The destination object. * @param {...Object} sources The source objects. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @see _.assignWith * @example * * function customizer(objValue, srcValue) { * return _.isUndefined(objValue) ? srcValue : objValue; * } * * var defaults = _.partialRight(_.assignInWith, customizer); * * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var assignInWith = createAssigner(function( object, source, srcIndex, customizer ) { copyObject(source, keysIn(source), object, customizer); }); /** * This method is like `_.assign` except that it accepts `customizer` * which is invoked to produce the assigned values. If `customizer` returns * `undefined`, assignment is handled by the method instead. The `customizer` * is invoked with five arguments: (objValue, srcValue, key, object, source). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The destination object. * @param {...Object} sources The source objects. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @see _.assignInWith * @example * * function customizer(objValue, srcValue) { * return _.isUndefined(objValue) ? srcValue : objValue; * } * * var defaults = _.partialRight(_.assignWith, customizer); * * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var assignWith = createAssigner(function( object, source, srcIndex, customizer ) { copyObject(source, keys(source), object, customizer); }); /** * Creates an array of values corresponding to `paths` of `object`. * * @static * @memberOf _ * @since 1.0.0 * @category Object * @param {Object} object The object to iterate over. * @param {...(string|string[])} [paths] The property paths to pick. * @returns {Array} Returns the picked values. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; * * _.at(object, ['a[0].b.c', 'a[1]']); * // => [3, 4] */ var at = flatRest(baseAt); /** * Creates an object that inherits from the `prototype` object. If a * `properties` object is given, its own enumerable string keyed properties * are assigned to the created object. * * @static * @memberOf _ * @since 2.3.0 * @category Object * @param {Object} prototype The object to inherit from. * @param {Object} [properties] The properties to assign to the object. * @returns {Object} Returns the new object. * @example * * function Shape() { * this.x = 0; * this.y = 0; * } * * function Circle() { * Shape.call(this); * } * * Circle.prototype = _.create(Shape.prototype, { * 'constructor': Circle * }); * * var circle = new Circle; * circle instanceof Circle; * // => true * * circle instanceof Shape; * // => true */ function create(prototype, properties) { var result = baseCreate(prototype); return properties == null ? result : baseAssign(result, properties); } /** * Assigns own and inherited enumerable string keyed properties of source * objects to the destination object for all destination properties that * resolve to `undefined`. Source objects are applied from left to right. * Once a property is set, additional values of the same property are ignored. * * **Note:** This method mutates `object`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.defaultsDeep * @example * * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); * // => { 'a': 1, 'b': 2 } */ var defaults = baseRest(function(object, sources) { object = Object(object); var index = -1; var length = sources.length; var guard = length > 2 ? sources[2] : undefined; if (guard && isIterateeCall(sources[0], sources[1], guard)) { length = 1; } while (++index < length) { var source = sources[index]; var props = keysIn(source); var propsIndex = -1; var propsLength = props.length; while (++propsIndex < propsLength) { var key = props[propsIndex]; var value = object[key]; if ( value === undefined || (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key)) ) { object[key] = source[key]; } } } return object; }); /** * This method is like `_.defaults` except that it recursively assigns * default properties. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 3.10.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.defaults * @example * * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); * // => { 'a': { 'b': 2, 'c': 3 } } */ var defaultsDeep = baseRest(function(args) { args.push(undefined, customDefaultsMerge); return apply(mergeWith, undefined, args); }); /** * This method is like `_.find` except that it returns the key of the first * element `predicate` returns truthy for instead of the element itself. * * @static * @memberOf _ * @since 1.1.0 * @category Object * @param {Object} object The object to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {string|undefined} Returns the key of the matched element, * else `undefined`. * @example * * var users = { * 'barney': { 'age': 36, 'active': true }, * 'fred': { 'age': 40, 'active': false }, * 'pebbles': { 'age': 1, 'active': true } * }; * * _.findKey(users, function(o) { return o.age < 40; }); * // => 'barney' (iteration order is not guaranteed) * * // The `_.matches` iteratee shorthand. * _.findKey(users, { 'age': 1, 'active': true }); * // => 'pebbles' * * // The `_.matchesProperty` iteratee shorthand. * _.findKey(users, ['active', false]); * // => 'fred' * * // The `_.property` iteratee shorthand. * _.findKey(users, 'active'); * // => 'barney' */ function findKey(object, predicate) { return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); } /** * This method is like `_.findKey` except that it iterates over elements of * a collection in the opposite order. * * @static * @memberOf _ * @since 2.0.0 * @category Object * @param {Object} object The object to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {string|undefined} Returns the key of the matched element, * else `undefined`. * @example * * var users = { * 'barney': { 'age': 36, 'active': true }, * 'fred': { 'age': 40, 'active': false }, * 'pebbles': { 'age': 1, 'active': true } * }; * * _.findLastKey(users, function(o) { return o.age < 40; }); * // => returns 'pebbles' assuming `_.findKey` returns 'barney' * * // The `_.matches` iteratee shorthand. * _.findLastKey(users, { 'age': 36, 'active': true }); * // => 'barney' * * // The `_.matchesProperty` iteratee shorthand. * _.findLastKey(users, ['active', false]); * // => 'fred' * * // The `_.property` iteratee shorthand. * _.findLastKey(users, 'active'); * // => 'pebbles' */ function findLastKey(object, predicate) { return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); } /** * Iterates over own and inherited enumerable string keyed properties of an * object and invokes `iteratee` for each property. The iteratee is invoked * with three arguments: (value, key, object). Iteratee functions may exit * iteration early by explicitly returning `false`. * * @static * @memberOf _ * @since 0.3.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forInRight * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forIn(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). */ function forIn(object, iteratee) { return object == null ? object : baseFor(object, getIteratee(iteratee, 3), keysIn); } /** * This method is like `_.forIn` except that it iterates over properties of * `object` in the opposite order. * * @static * @memberOf _ * @since 2.0.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forIn * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forInRight(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. */ function forInRight(object, iteratee) { return object == null ? object : baseForRight(object, getIteratee(iteratee, 3), keysIn); } /** * Iterates over own enumerable string keyed properties of an object and * invokes `iteratee` for each property. The iteratee is invoked with three * arguments: (value, key, object). Iteratee functions may exit iteration * early by explicitly returning `false`. * * @static * @memberOf _ * @since 0.3.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forOwnRight * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forOwn(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'a' then 'b' (iteration order is not guaranteed). */ function forOwn(object, iteratee) { return object && baseForOwn(object, getIteratee(iteratee, 3)); } /** * This method is like `_.forOwn` except that it iterates over properties of * `object` in the opposite order. * * @static * @memberOf _ * @since 2.0.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns `object`. * @see _.forOwn * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.forOwnRight(new Foo, function(value, key) { * console.log(key); * }); * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. */ function forOwnRight(object, iteratee) { return object && baseForOwnRight(object, getIteratee(iteratee, 3)); } /** * Creates an array of function property names from own enumerable properties * of `object`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the function names. * @see _.functionsIn * @example * * function Foo() { * this.a = _.constant('a'); * this.b = _.constant('b'); * } * * Foo.prototype.c = _.constant('c'); * * _.functions(new Foo); * // => ['a', 'b'] */ function functions(object) { return object == null ? [] : baseFunctions(object, keys(object)); } /** * Creates an array of function property names from own and inherited * enumerable properties of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to inspect. * @returns {Array} Returns the function names. * @see _.functions * @example * * function Foo() { * this.a = _.constant('a'); * this.b = _.constant('b'); * } * * Foo.prototype.c = _.constant('c'); * * _.functionsIn(new Foo); * // => ['a', 'b', 'c'] */ function functionsIn(object) { return object == null ? [] : baseFunctions(object, keysIn(object)); } /** * Gets the value at `path` of `object`. If the resolved value is * `undefined`, the `defaultValue` is returned in its place. * * @static * @memberOf _ * @since 3.7.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @param {*} [defaultValue] The value returned for `undefined` resolved values. * @returns {*} Returns the resolved value. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.get(object, 'a[0].b.c'); * // => 3 * * _.get(object, ['a', '0', 'b', 'c']); * // => 3 * * _.get(object, 'a.b.c', 'default'); * // => 'default' */ function get(object, path, defaultValue) { var result = object == null ? undefined : baseGet(object, path); return result === undefined ? defaultValue : result; } /** * Checks if `path` is a direct property of `object`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * * var object = { 'a': { 'b': 2 } }; * var other = _.create({ 'a': _.create({ 'b': 2 }) }); * * _.has(object, 'a'); * // => true * * _.has(object, 'a.b'); * // => true * * _.has(object, ['a', 'b']); * // => true * * _.has(other, 'a'); * // => false */ function has(object, path) { return object != null && hasPath(object, path, baseHas); } /** * Checks if `path` is a direct or inherited property of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * * var object = _.create({ 'a': _.create({ 'b': 2 }) }); * * _.hasIn(object, 'a'); * // => true * * _.hasIn(object, 'a.b'); * // => true * * _.hasIn(object, ['a', 'b']); * // => true * * _.hasIn(object, 'b'); * // => false */ function hasIn(object, path) { return object != null && hasPath(object, path, baseHasIn); } /** * Creates an object composed of the inverted keys and values of `object`. * If `object` contains duplicate values, subsequent values overwrite * property assignments of previous values. * * @static * @memberOf _ * @since 0.7.0 * @category Object * @param {Object} object The object to invert. * @returns {Object} Returns the new inverted object. * @example * * var object = { 'a': 1, 'b': 2, 'c': 1 }; * * _.invert(object); * // => { '1': 'c', '2': 'b' } */ var invert = createInverter(function(result, value, key) { if (value != null && typeof value.toString !== 'function') { value = nativeObjectToString.call(value); } result[value] = key; }, constant(identity)); /** * This method is like `_.invert` except that the inverted object is generated * from the results of running each element of `object` thru `iteratee`. The * corresponding inverted value of each inverted key is an array of keys * responsible for generating the inverted value. The iteratee is invoked * with one argument: (value). * * @static * @memberOf _ * @since 4.1.0 * @category Object * @param {Object} object The object to invert. * @param {Function} [iteratee=_.identity] The iteratee invoked per element. * @returns {Object} Returns the new inverted object. * @example * * var object = { 'a': 1, 'b': 2, 'c': 1 }; * * _.invertBy(object); * // => { '1': ['a', 'c'], '2': ['b'] } * * _.invertBy(object, function(value) { * return 'group' + value; * }); * // => { 'group1': ['a', 'c'], 'group2': ['b'] } */ var invertBy = createInverter(function(result, value, key) { if (value != null && typeof value.toString !== 'function') { value = nativeObjectToString.call(value); } if (hasOwnProperty.call(result, value)) { result[value].push(key); } else { result[value] = [key]; } }, getIteratee); /** * Invokes the method at `path` of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the method to invoke. * @param {...*} [args] The arguments to invoke the method with. * @returns {*} Returns the result of the invoked method. * @example * * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; * * _.invoke(object, 'a[0].b.c.slice', 1, 3); * // => [2, 3] */ var invoke = baseRest(baseInvoke); /** * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * for more details. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keys(new Foo); * // => ['a', 'b'] (iteration order is not guaranteed) * * _.keys('hi'); * // => ['0', '1'] */ function keys(object) { return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); } /** * Creates an array of the own and inherited enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ * @since 3.0.0 * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keysIn(new Foo); * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ function keysIn(object) { return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); } /** * The opposite of `_.mapValues`; this method creates an object with the * same values as `object` and keys generated by running each own enumerable * string keyed property of `object` thru `iteratee`. The iteratee is invoked * with three arguments: (value, key, object). * * @static * @memberOf _ * @since 3.8.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns the new mapped object. * @see _.mapValues * @example * * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { * return key + value; * }); * // => { 'a1': 1, 'b2': 2 } */ function mapKeys(object, iteratee) { var result = {}; iteratee = getIteratee(iteratee, 3); baseForOwn(object, function(value, key, object) { baseAssignValue(result, iteratee(value, key, object), value); }); return result; } /** * Creates an object with the same keys as `object` and values generated * by running each own enumerable string keyed property of `object` thru * `iteratee`. The iteratee is invoked with three arguments: * (value, key, object). * * @static * @memberOf _ * @since 2.4.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Object} Returns the new mapped object. * @see _.mapKeys * @example * * var users = { * 'fred': { 'user': 'fred', 'age': 40 }, * 'pebbles': { 'user': 'pebbles', 'age': 1 } * }; * * _.mapValues(users, function(o) { return o.age; }); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) * * // The `_.property` iteratee shorthand. * _.mapValues(users, 'age'); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ function mapValues(object, iteratee) { var result = {}; iteratee = getIteratee(iteratee, 3); baseForOwn(object, function(value, key, object) { baseAssignValue(result, key, iteratee(value, key, object)); }); return result; } /** * This method is like `_.assign` except that it recursively merges own and * inherited enumerable string keyed properties of source objects into the * destination object. Source properties that resolve to `undefined` are * skipped if a destination value exists. Array and plain object properties * are merged recursively. Other objects and value types are overridden by * assignment. Source objects are applied from left to right. Subsequent * sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 0.5.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @example * * var object = { * 'a': [{ 'b': 2 }, { 'd': 4 }] * }; * * var other = { * 'a': [{ 'c': 3 }, { 'e': 5 }] * }; * * _.merge(object, other); * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } */ var merge = createAssigner(function(object, source, srcIndex) { baseMerge(object, source, srcIndex); }); /** * This method is like `_.merge` except that it accepts `customizer` which * is invoked to produce the merged values of the destination and source * properties. If `customizer` returns `undefined`, merging is handled by the * method instead. The `customizer` is invoked with six arguments: * (objValue, srcValue, key, object, source, stack). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The destination object. * @param {...Object} sources The source objects. * @param {Function} customizer The function to customize assigned values. * @returns {Object} Returns `object`. * @example * * function customizer(objValue, srcValue) { * if (_.isArray(objValue)) { * return objValue.concat(srcValue); * } * } * * var object = { 'a': [1], 'b': [2] }; * var other = { 'a': [3], 'b': [4] }; * * _.mergeWith(object, other, customizer); * // => { 'a': [1, 3], 'b': [2, 4] } */ var mergeWith = createAssigner(function( object, source, srcIndex, customizer ) { baseMerge(object, source, srcIndex, customizer); }); /** * The opposite of `_.pick`; this method creates an object composed of the * own and inherited enumerable property paths of `object` that are not omitted. * * **Note:** This method is considerably slower than `_.pick`. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The source object. * @param {...(string|string[])} [paths] The property paths to omit. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.omit(object, ['a', 'c']); * // => { 'b': '2' } */ var omit = flatRest(function(object, paths) { var result = {}; if (object == null) { return result; } var isDeep = false; paths = arrayMap(paths, function(path) { path = castPath(path, object); isDeep || (isDeep = path.length > 1); return path; }); copyObject(object, getAllKeysIn(object), result); if (isDeep) { result = baseClone( result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone ); } var length = paths.length; while (length--) { baseUnset(result, paths[length]); } return result; }); /** * The opposite of `_.pickBy`; this method creates an object composed of * the own and inherited enumerable string keyed properties of `object` that * `predicate` doesn't return truthy for. The predicate is invoked with two * arguments: (value, key). * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The source object. * @param {Function} [predicate=_.identity] The function invoked per property. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.omitBy(object, _.isNumber); * // => { 'b': '2' } */ function omitBy(object, predicate) { return pickBy(object, negate(getIteratee(predicate))); } /** * Creates an object composed of the picked `object` properties. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The source object. * @param {...(string|string[])} [paths] The property paths to pick. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.pick(object, ['a', 'c']); * // => { 'a': 1, 'c': 3 } */ var pick = flatRest(function(object, paths) { return object == null ? {} : basePick(object, paths); }); /** * Creates an object composed of the `object` properties `predicate` returns * truthy for. The predicate is invoked with two arguments: (value, key). * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The source object. * @param {Function} [predicate=_.identity] The function invoked per property. * @returns {Object} Returns the new object. * @example * * var object = { 'a': 1, 'b': '2', 'c': 3 }; * * _.pickBy(object, _.isNumber); * // => { 'a': 1, 'c': 3 } */ function pickBy(object, predicate) { if (object == null) { return {}; } var props = arrayMap(getAllKeysIn(object), function(prop) { return [prop]; }); predicate = getIteratee(predicate); return basePickBy(object, props, function(value, path) { return predicate(value, path[0]); }); } /** * This method is like `_.get` except that if the resolved value is a * function it's invoked with the `this` binding of its parent object and * its result is returned. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the property to resolve. * @param {*} [defaultValue] The value returned for `undefined` resolved values. * @returns {*} Returns the resolved value. * @example * * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; * * _.result(object, 'a[0].b.c1'); * // => 3 * * _.result(object, 'a[0].b.c2'); * // => 4 * * _.result(object, 'a[0].b.c3', 'default'); * // => 'default' * * _.result(object, 'a[0].b.c3', _.constant('default')); * // => 'default' */ function result(object, path, defaultValue) { path = castPath(path, object); var index = -1, length = path.length; // Ensure the loop is entered when path is empty. if (!length) { length = 1; object = undefined; } while (++index < length) { var value = object == null ? undefined : object[toKey(path[index])]; if (value === undefined) { index = length; value = defaultValue; } object = isFunction(value) ? value.call(object) : value; } return object; } /** * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, * it's created. Arrays are created for missing index properties while objects * are created for all other missing properties. Use `_.setWith` to customize * `path` creation. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 3.7.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {*} value The value to set. * @returns {Object} Returns `object`. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.set(object, 'a[0].b.c', 4); * console.log(object.a[0].b.c); * // => 4 * * _.set(object, ['x', '0', 'y', 'z'], 5); * console.log(object.x[0].y.z); * // => 5 */ function set(object, path, value) { return object == null ? object : baseSet(object, path, value); } /** * This method is like `_.set` except that it accepts `customizer` which is * invoked to produce the objects of `path`. If `customizer` returns `undefined` * path creation is handled by the method instead. The `customizer` is invoked * with three arguments: (nsValue, key, nsObject). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {*} value The value to set. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @example * * var object = {}; * * _.setWith(object, '[0][1]', 'a', Object); * // => { '0': { '1': 'a' } } */ function setWith(object, path, value, customizer) { customizer = typeof customizer === 'function' ? customizer : undefined; return object == null ? object : baseSet(object, path, value, customizer); } /** * Creates an array of own enumerable string keyed-value pairs for `object` * which can be consumed by `_.fromPairs`. If `object` is a map or set, its * entries are returned. * * @static * @memberOf _ * @since 4.0.0 * @alias entries * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the key-value pairs. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.toPairs(new Foo); * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) */ var toPairs = createToPairs(keys); /** * Creates an array of own and inherited enumerable string keyed-value pairs * for `object` which can be consumed by `_.fromPairs`. If `object` is a map * or set, its entries are returned. * * @static * @memberOf _ * @since 4.0.0 * @alias entriesIn * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the key-value pairs. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.toPairsIn(new Foo); * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) */ var toPairsIn = createToPairs(keysIn); /** * An alternative to `_.reduce`; this method transforms `object` to a new * `accumulator` object which is the result of running each of its own * enumerable string keyed properties thru `iteratee`, with each invocation * potentially mutating the `accumulator` object. If `accumulator` is not * provided, a new object with the same `[[Prototype]]` will be used. The * iteratee is invoked with four arguments: (accumulator, value, key, object). * Iteratee functions may exit iteration early by explicitly returning `false`. * * @static * @memberOf _ * @since 1.3.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The custom accumulator value. * @returns {*} Returns the accumulated value. * @example * * _.transform([2, 3, 4], function(result, n) { * result.push(n *= n); * return n % 2 == 0; * }, []); * // => [4, 9] * * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { * (result[value] || (result[value] = [])).push(key); * }, {}); * // => { '1': ['a', 'c'], '2': ['b'] } */ function transform(object, iteratee, accumulator) { var isArr = isArray(object), isArrLike = isArr || isBuffer(object) || isTypedArray(object); iteratee = getIteratee(iteratee, 4); if (accumulator == null) { var Ctor = object && object.constructor; if (isArrLike) { accumulator = isArr ? new Ctor() : []; } else if (isObject(object)) { accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; } else { accumulator = {}; } } (isArrLike ? arrayEach : baseForOwn)(object, function( value, index, object ) { return iteratee(accumulator, value, index, object); }); return accumulator; } /** * Removes the property at `path` of `object`. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to unset. * @returns {boolean} Returns `true` if the property is deleted, else `false`. * @example * * var object = { 'a': [{ 'b': { 'c': 7 } }] }; * _.unset(object, 'a[0].b.c'); * // => true * * console.log(object); * // => { 'a': [{ 'b': {} }] }; * * _.unset(object, ['a', '0', 'b', 'c']); * // => true * * console.log(object); * // => { 'a': [{ 'b': {} }] }; */ function unset(object, path) { return object == null ? true : baseUnset(object, path); } /** * This method is like `_.set` except that accepts `updater` to produce the * value to set. Use `_.updateWith` to customize `path` creation. The `updater` * is invoked with one argument: (value). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.6.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {Function} updater The function to produce the updated value. * @returns {Object} Returns `object`. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.update(object, 'a[0].b.c', function(n) { return n * n; }); * console.log(object.a[0].b.c); * // => 9 * * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); * console.log(object.x[0].y.z); * // => 0 */ function update(object, path, updater) { return object == null ? object : baseUpdate(object, path, castFunction(updater)); } /** * This method is like `_.update` except that it accepts `customizer` which is * invoked to produce the objects of `path`. If `customizer` returns `undefined` * path creation is handled by the method instead. The `customizer` is invoked * with three arguments: (nsValue, key, nsObject). * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 4.6.0 * @category Object * @param {Object} object The object to modify. * @param {Array|string} path The path of the property to set. * @param {Function} updater The function to produce the updated value. * @param {Function} [customizer] The function to customize assigned values. * @returns {Object} Returns `object`. * @example * * var object = {}; * * _.updateWith(object, '[0][1]', _.constant('a'), Object); * // => { '0': { '1': 'a' } } */ function updateWith(object, path, updater, customizer) { customizer = typeof customizer === 'function' ? customizer : undefined; return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); } /** * Creates an array of the own enumerable string keyed property values of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property values. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.values(new Foo); * // => [1, 2] (iteration order is not guaranteed) * * _.values('hi'); * // => ['h', 'i'] */ function values(object) { return object == null ? [] : baseValues(object, keys(object)); } /** * Creates an array of the own and inherited enumerable string keyed property * values of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ * @since 3.0.0 * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property values. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.valuesIn(new Foo); * // => [1, 2, 3] (iteration order is not guaranteed) */ function valuesIn(object) { return object == null ? [] : baseValues(object, keysIn(object)); } /* ------------------------------------------------------------------------*/ /** * Clamps `number` within the inclusive `lower` and `upper` bounds. * * @static * @memberOf _ * @since 4.0.0 * @category Number * @param {number} number The number to clamp. * @param {number} [lower] The lower bound. * @param {number} upper The upper bound. * @returns {number} Returns the clamped number. * @example * * _.clamp(-10, -5, 5); * // => -5 * * _.clamp(10, -5, 5); * // => 5 */ function clamp(number, lower, upper) { if (upper === undefined) { upper = lower; lower = undefined; } if (upper !== undefined) { upper = toNumber(upper); upper = upper === upper ? upper : 0; } if (lower !== undefined) { lower = toNumber(lower); lower = lower === lower ? lower : 0; } return baseClamp(toNumber(number), lower, upper); } /** * Checks if `n` is between `start` and up to, but not including, `end`. If * `end` is not specified, it's set to `start` with `start` then set to `0`. * If `start` is greater than `end` the params are swapped to support * negative ranges. * * @static * @memberOf _ * @since 3.3.0 * @category Number * @param {number} number The number to check. * @param {number} [start=0] The start of the range. * @param {number} end The end of the range. * @returns {boolean} Returns `true` if `number` is in the range, else `false`. * @see _.range, _.rangeRight * @example * * _.inRange(3, 2, 4); * // => true * * _.inRange(4, 8); * // => true * * _.inRange(4, 2); * // => false * * _.inRange(2, 2); * // => false * * _.inRange(1.2, 2); * // => true * * _.inRange(5.2, 4); * // => false * * _.inRange(-3, -2, -6); * // => true */ function inRange(number, start, end) { start = toFinite(start); if (end === undefined) { end = start; start = 0; } else { end = toFinite(end); } number = toNumber(number); return baseInRange(number, start, end); } /** * Produces a random number between the inclusive `lower` and `upper` bounds. * If only one argument is provided a number between `0` and the given number * is returned. If `floating` is `true`, or either `lower` or `upper` are * floats, a floating-point number is returned instead of an integer. * * **Note:** JavaScript follows the IEEE-754 standard for resolving * floating-point values which can produce unexpected results. * * @static * @memberOf _ * @since 0.7.0 * @category Number * @param {number} [lower=0] The lower bound. * @param {number} [upper=1] The upper bound. * @param {boolean} [floating] Specify returning a floating-point number. * @returns {number} Returns the random number. * @example * * _.random(0, 5); * // => an integer between 0 and 5 * * _.random(5); * // => also an integer between 0 and 5 * * _.random(5, true); * // => a floating-point number between 0 and 5 * * _.random(1.2, 5.2); * // => a floating-point number between 1.2 and 5.2 */ function random(lower, upper, floating) { if ( floating && typeof floating !== 'boolean' && isIterateeCall(lower, upper, floating) ) { upper = floating = undefined; } if (floating === undefined) { if (typeof upper === 'boolean') { floating = upper; upper = undefined; } else if (typeof lower === 'boolean') { floating = lower; lower = undefined; } } if (lower === undefined && upper === undefined) { lower = 0; upper = 1; } else { lower = toFinite(lower); if (upper === undefined) { upper = lower; lower = 0; } else { upper = toFinite(upper); } } if (lower > upper) { var temp = lower; lower = upper; upper = temp; } if (floating || lower % 1 || upper % 1) { var rand = nativeRandom(); return nativeMin( lower + rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1))), upper ); } return baseRandom(lower, upper); } /* ------------------------------------------------------------------------*/ /** * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the camel cased string. * @example * * _.camelCase('Foo Bar'); * // => 'fooBar' * * _.camelCase('--foo-bar--'); * // => 'fooBar' * * _.camelCase('__FOO_BAR__'); * // => 'fooBar' */ var camelCase = createCompounder(function(result, word, index) { word = word.toLowerCase(); return result + (index ? capitalize(word) : word); }); /** * Converts the first character of `string` to upper case and the remaining * to lower case. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to capitalize. * @returns {string} Returns the capitalized string. * @example * * _.capitalize('FRED'); * // => 'Fred' */ function capitalize(string) { return upperFirst(toString(string).toLowerCase()); } /** * Deburrs `string` by converting * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) * letters to basic Latin letters and removing * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to deburr. * @returns {string} Returns the deburred string. * @example * * _.deburr('déjà vu'); * // => 'deja vu' */ function deburr(string) { string = toString(string); return ( string && string.replace(reLatin, deburrLetter).replace(reComboMark, '') ); } /** * Checks if `string` ends with the given target string. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to inspect. * @param {string} [target] The string to search for. * @param {number} [position=string.length] The position to search up to. * @returns {boolean} Returns `true` if `string` ends with `target`, * else `false`. * @example * * _.endsWith('abc', 'c'); * // => true * * _.endsWith('abc', 'b'); * // => false * * _.endsWith('abc', 'b', 2); * // => true */ function endsWith(string, target, position) { string = toString(string); target = baseToString(target); var length = string.length; position = position === undefined ? length : baseClamp(toInteger(position), 0, length); var end = position; position -= target.length; return position >= 0 && string.slice(position, end) == target; } /** * Converts the characters "&", "<", ">", '"', and "'" in `string` to their * corresponding HTML entities. * * **Note:** No other characters are escaped. To escape additional * characters use a third-party library like [_he_](https://mths.be/he). * * Though the ">" character is escaped for symmetry, characters like * ">" and "/" don't need escaping in HTML and have no special meaning * unless they're part of a tag or unquoted attribute value. See * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) * (under "semi-related fun fact") for more details. * * When working with HTML you should always * [quote attribute values](http://wonko.com/post/html-escaping) to reduce * XSS vectors. * * @static * @since 0.1.0 * @memberOf _ * @category String * @param {string} [string=''] The string to escape. * @returns {string} Returns the escaped string. * @example * * _.escape('fred, barney, & pebbles'); * // => 'fred, barney, & pebbles' */ function escape(string) { string = toString(string); return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string; } /** * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to escape. * @returns {string} Returns the escaped string. * @example * * _.escapeRegExp('[lodash](https://lodash.com/)'); * // => '\[lodash\]\(https://lodash\.com/\)' */ function escapeRegExp(string) { string = toString(string); return string && reHasRegExpChar.test(string) ? string.replace(reRegExpChar, '\\$&') : string; } /** * Converts `string` to * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the kebab cased string. * @example * * _.kebabCase('Foo Bar'); * // => 'foo-bar' * * _.kebabCase('fooBar'); * // => 'foo-bar' * * _.kebabCase('__FOO_BAR__'); * // => 'foo-bar' */ var kebabCase = createCompounder(function(result, word, index) { return result + (index ? '-' : '') + word.toLowerCase(); }); /** * Converts `string`, as space separated words, to lower case. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the lower cased string. * @example * * _.lowerCase('--Foo-Bar--'); * // => 'foo bar' * * _.lowerCase('fooBar'); * // => 'foo bar' * * _.lowerCase('__FOO_BAR__'); * // => 'foo bar' */ var lowerCase = createCompounder(function(result, word, index) { return result + (index ? ' ' : '') + word.toLowerCase(); }); /** * Converts the first character of `string` to lower case. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the converted string. * @example * * _.lowerFirst('Fred'); * // => 'fred' * * _.lowerFirst('FRED'); * // => 'fRED' */ var lowerFirst = createCaseFirst('toLowerCase'); /** * Pads `string` on the left and right sides if it's shorter than `length`. * Padding characters are truncated if they can't be evenly divided by `length`. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padded string. * @example * * _.pad('abc', 8); * // => ' abc ' * * _.pad('abc', 8, '_-'); * // => '_-abc_-_' * * _.pad('abc', 3); * // => 'abc' */ function pad(string, length, chars) { string = toString(string); length = toInteger(length); var strLength = length ? stringSize(string) : 0; if (!length || strLength >= length) { return string; } var mid = (length - strLength) / 2; return ( createPadding(nativeFloor(mid), chars) + string + createPadding(nativeCeil(mid), chars) ); } /** * Pads `string` on the right side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padded string. * @example * * _.padEnd('abc', 6); * // => 'abc ' * * _.padEnd('abc', 6, '_-'); * // => 'abc_-_' * * _.padEnd('abc', 3); * // => 'abc' */ function padEnd(string, length, chars) { string = toString(string); length = toInteger(length); var strLength = length ? stringSize(string) : 0; return length && strLength < length ? string + createPadding(length - strLength, chars) : string; } /** * Pads `string` on the left side if it's shorter than `length`. Padding * characters are truncated if they exceed `length`. * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to pad. * @param {number} [length=0] The padding length. * @param {string} [chars=' '] The string used as padding. * @returns {string} Returns the padded string. * @example * * _.padStart('abc', 6); * // => ' abc' * * _.padStart('abc', 6, '_-'); * // => '_-_abc' * * _.padStart('abc', 3); * // => 'abc' */ function padStart(string, length, chars) { string = toString(string); length = toInteger(length); var strLength = length ? stringSize(string) : 0; return length && strLength < length ? createPadding(length - strLength, chars) + string : string; } /** * Converts `string` to an integer of the specified radix. If `radix` is * `undefined` or `0`, a `radix` of `10` is used unless `value` is a * hexadecimal, in which case a `radix` of `16` is used. * * **Note:** This method aligns with the * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. * * @static * @memberOf _ * @since 1.1.0 * @category String * @param {string} string The string to convert. * @param {number} [radix=10] The radix to interpret `value` by. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {number} Returns the converted integer. * @example * * _.parseInt('08'); * // => 8 * * _.map(['6', '08', '10'], _.parseInt); * // => [6, 8, 10] */ function parseInt(string, radix, guard) { if (guard || radix == null) { radix = 0; } else if (radix) { radix = +radix; } return nativeParseInt( toString(string).replace(reTrimStart, ''), radix || 0 ); } /** * Repeats the given string `n` times. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to repeat. * @param {number} [n=1] The number of times to repeat the string. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {string} Returns the repeated string. * @example * * _.repeat('*', 3); * // => '***' * * _.repeat('abc', 2); * // => 'abcabc' * * _.repeat('abc', 0); * // => '' */ function repeat(string, n, guard) { if (guard ? isIterateeCall(string, n, guard) : n === undefined) { n = 1; } else { n = toInteger(n); } return baseRepeat(toString(string), n); } /** * Replaces matches for `pattern` in `string` with `replacement`. * * **Note:** This method is based on * [`String#replace`](https://mdn.io/String/replace). * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to modify. * @param {RegExp|string} pattern The pattern to replace. * @param {Function|string} replacement The match replacement. * @returns {string} Returns the modified string. * @example * * _.replace('Hi Fred', 'Fred', 'Barney'); * // => 'Hi Barney' */ function replace() { var args = arguments, string = toString(args[0]); return args.length < 3 ? string : string.replace(args[1], args[2]); } /** * Converts `string` to * [snake case](https://en.wikipedia.org/wiki/Snake_case). * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the snake cased string. * @example * * _.snakeCase('Foo Bar'); * // => 'foo_bar' * * _.snakeCase('fooBar'); * // => 'foo_bar' * * _.snakeCase('--FOO-BAR--'); * // => 'foo_bar' */ var snakeCase = createCompounder(function(result, word, index) { return result + (index ? '_' : '') + word.toLowerCase(); }); /** * Splits `string` by `separator`. * * **Note:** This method is based on * [`String#split`](https://mdn.io/String/split). * * @static * @memberOf _ * @since 4.0.0 * @category String * @param {string} [string=''] The string to split. * @param {RegExp|string} separator The separator pattern to split by. * @param {number} [limit] The length to truncate results to. * @returns {Array} Returns the string segments. * @example * * _.split('a-b-c', '-', 2); * // => ['a', 'b'] */ function split(string, separator, limit) { if ( limit && typeof limit !== 'number' && isIterateeCall(string, separator, limit) ) { separator = limit = undefined; } limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; if (!limit) { return []; } string = toString(string); if ( string && (typeof separator === 'string' || (separator != null && !isRegExp(separator))) ) { separator = baseToString(separator); if (!separator && hasUnicode(string)) { return castSlice(stringToArray(string), 0, limit); } } return string.split(separator, limit); } /** * Converts `string` to * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * * @static * @memberOf _ * @since 3.1.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the start cased string. * @example * * _.startCase('--foo-bar--'); * // => 'Foo Bar' * * _.startCase('fooBar'); * // => 'Foo Bar' * * _.startCase('__FOO_BAR__'); * // => 'FOO BAR' */ var startCase = createCompounder(function(result, word, index) { return result + (index ? ' ' : '') + upperFirst(word); }); /** * Checks if `string` starts with the given target string. * * @static * @memberOf _ * @since 3.0.0 * @category String * @param {string} [string=''] The string to inspect. * @param {string} [target] The string to search for. * @param {number} [position=0] The position to search from. * @returns {boolean} Returns `true` if `string` starts with `target`, * else `false`. * @example * * _.startsWith('abc', 'a'); * // => true * * _.startsWith('abc', 'b'); * // => false * * _.startsWith('abc', 'b', 1); * // => true */ function startsWith(string, target, position) { string = toString(string); position = position == null ? 0 : baseClamp(toInteger(position), 0, string.length); target = baseToString(target); return string.slice(position, position + target.length) == target; } /** * Creates a compiled template function that can interpolate data properties * in "interpolate" delimiters, HTML-escape interpolated data properties in * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data * properties may be accessed as free variables in the template. If a setting * object is given, it takes precedence over `_.templateSettings` values. * * **Note:** In the development build `_.template` utilizes * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) * for easier debugging. * * For more information on precompiling templates see * [lodash's custom builds documentation](https://lodash.com/custom-builds). * * For more information on Chrome extension sandboxes see * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). * * @static * @since 0.1.0 * @memberOf _ * @category String * @param {string} [string=''] The template string. * @param {Object} [options={}] The options object. * @param {RegExp} [options.escape=_.templateSettings.escape] * The HTML "escape" delimiter. * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] * The "evaluate" delimiter. * @param {Object} [options.imports=_.templateSettings.imports] * An object to import into the template as free variables. * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] * The "interpolate" delimiter. * @param {string} [options.sourceURL='lodash.templateSources[n]'] * The sourceURL of the compiled template. * @param {string} [options.variable='obj'] * The data object variable name. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. * @returns {Function} Returns the compiled template function. * @example * * // Use the "interpolate" delimiter to create a compiled template. * var compiled = _.template('hello <%= user %>!'); * compiled({ 'user': 'fred' }); * // => 'hello fred!' * * // Use the HTML "escape" delimiter to escape data property values. * var compiled = _.template('<%- value %>'); * compiled({ 'value': '