├── .eslintignore
├── .gitattributes
├── assets
├── iview.png
├── logo.png
├── pay.png
├── iview2.png
└── logo.svg
├── src
├── components
│ ├── card
│ │ ├── index.js
│ │ └── card.vue
│ ├── icon
│ │ ├── index.js
│ │ └── icon.vue
│ ├── page
│ │ └── index.js
│ ├── rate
│ │ └── index.js
│ ├── spin
│ │ ├── index.js
│ │ └── spin.vue
│ ├── tag
│ │ ├── index.js
│ │ └── tag.vue
│ ├── tree
│ │ └── index.js
│ ├── affix
│ │ └── index.js
│ ├── alert
│ │ └── index.js
│ ├── badge
│ │ ├── index.js
│ │ └── badge.vue
│ ├── input
│ │ └── index.js
│ ├── table
│ │ ├── index.js
│ │ ├── header.js
│ │ ├── expand.js
│ │ ├── table-tr.vue
│ │ ├── mixin.js
│ │ └── export-csv.js
│ ├── circle
│ │ └── index.js
│ ├── switch
│ │ ├── index.js
│ │ └── switch.vue
│ ├── back-top
│ │ ├── index.js
│ │ └── back-top.vue
│ ├── poptip
│ │ └── index.js
│ ├── slider
│ │ └── index.js
│ ├── upload
│ │ ├── index.js
│ │ └── ajax.js
│ ├── cascader
│ │ ├── index.js
│ │ └── casitem.vue
│ ├── progress
│ │ └── index.js
│ ├── tooltip
│ │ └── index.js
│ ├── transfer
│ │ ├── index.js
│ │ ├── operation.vue
│ │ └── search.vue
│ ├── input-number
│ │ └── index.js
│ ├── date-picker
│ │ ├── index.js
│ │ ├── time-mixins.js
│ │ ├── panel
│ │ │ └── mixin.js
│ │ ├── picker
│ │ │ ├── time-picker.js
│ │ │ └── date-picker.js
│ │ ├── base
│ │ │ ├── confirm.vue
│ │ │ └── month-table.vue
│ │ └── util.js
│ ├── grid
│ │ ├── index.js
│ │ └── row.vue
│ ├── time-picker
│ │ └── index.js
│ ├── tabs
│ │ ├── index.js
│ │ └── pane.vue
│ ├── steps
│ │ └── index.js
│ ├── form
│ │ └── index.js
│ ├── collapse
│ │ ├── index.js
│ │ └── panel.vue
│ ├── radio
│ │ ├── index.js
│ │ └── radio-group.vue
│ ├── button
│ │ ├── index.js
│ │ ├── button-group.vue
│ │ └── button.vue
│ ├── dropdown
│ │ ├── dropdown-menu.vue
│ │ ├── index.js
│ │ └── dropdown-item.vue
│ ├── carousel
│ │ ├── index.js
│ │ └── carousel-item.vue
│ ├── timeline
│ │ ├── index.js
│ │ ├── timeline.vue
│ │ └── timeline-item.vue
│ ├── checkbox
│ │ ├── index.js
│ │ └── checkbox-group.vue
│ ├── select
│ │ ├── index.js
│ │ ├── option-group.vue
│ │ └── option.vue
│ ├── breadcrumb
│ │ ├── index.js
│ │ ├── breadcrumb.vue
│ │ └── breadcrumb-item.vue
│ ├── base
│ │ ├── render.js
│ │ ├── notification
│ │ │ └── index.js
│ │ └── collapse-transition.js
│ ├── menu
│ │ ├── index.js
│ │ ├── menu-group.vue
│ │ └── menu-item.vue
│ ├── loading-bar
│ │ └── loading-bar.js
│ └── modal
│ │ └── index.js
├── styles
│ ├── components
│ │ ├── checkbox.less
│ │ ├── affix.less
│ │ ├── circle.less
│ │ ├── loading-bar.less
│ │ ├── dropdown.less
│ │ ├── back-top.less
│ │ ├── select-dropdown.less
│ │ ├── index.less
│ │ ├── tooltip.less
│ │ ├── card.less
│ │ ├── collapse.less
│ │ ├── badge.less
│ │ ├── spin.less
│ │ ├── tree.less
│ │ ├── rate.less
│ │ ├── message.less
│ │ ├── form.less
│ │ ├── input.less
│ │ ├── upload.less
│ │ ├── timeline.less
│ │ ├── alert.less
│ │ └── progress.less
│ ├── common
│ │ ├── index.less
│ │ ├── iconfont
│ │ │ ├── fonts
│ │ │ │ ├── ionicons.eot
│ │ │ │ ├── ionicons.ttf
│ │ │ │ └── ionicons.woff
│ │ │ ├── ionicons.less
│ │ │ └── _ionicons-font.less
│ │ ├── article.less
│ │ ├── base.less
│ │ └── layout.less
│ ├── copyright.less
│ ├── index.less
│ ├── README.md
│ ├── mixins
│ │ ├── close.less
│ │ ├── loading.less
│ │ ├── mask.less
│ │ ├── clearfix.less
│ │ ├── index.less
│ │ ├── size.less
│ │ ├── breadcrumb.less
│ │ ├── common.less
│ │ ├── caret.less
│ │ ├── content.less
│ │ ├── select.less
│ │ ├── layout.less
│ │ └── tooltip.less
│ └── animation
│ │ ├── fade.less
│ │ ├── ease.less
│ │ └── index.less
├── mixins
│ ├── locale.js
│ └── emitter.js
├── directives
│ └── clickoutside.js
├── utils
│ ├── dom.js
│ └── csv.js
└── locale
│ ├── format.js
│ ├── index.js
│ └── lang
│ ├── vi-VN.js
│ ├── zh-CN.js
│ ├── zh-TW.js
│ ├── ko-KR.js
│ └── ja-JP.js
├── .npmignore
├── .travis.yml
├── .babelrc
├── .github
└── ISSUE_TEMPLATE.md
├── .editorconfig
├── examples
├── routers
│ ├── page.vue
│ ├── back-top.vue
│ ├── affix.vue
│ ├── tooltip.vue
│ ├── slider.vue
│ ├── switch.vue
│ ├── tag.vue
│ ├── rate.vue
│ ├── poptip.vue
│ ├── grid.vue
│ ├── radio.vue
│ ├── loading-bar.vue
│ ├── input-number.vue
│ ├── badge.vue
│ ├── checkbox.vue
│ ├── dropdown.vue
│ ├── input.vue
│ ├── collapse.vue
│ ├── breadcrumb.vue
│ ├── message.vue
│ ├── alert.vue
│ ├── carousel.vue
│ ├── circle.vue
│ ├── progress.vue
│ ├── transfer.vue
│ ├── menu.vue
│ ├── notice.vue
│ ├── more.vue
│ ├── timeline.vue
│ ├── tree.vue
│ ├── tabs.vue
│ └── cascader.vue
├── components
│ ├── tableExpand.vue
│ └── test.vue
└── index.html
├── test
├── .eslintrc.json
└── unit
│ ├── index.js
│ ├── specs
│ └── breadcrumb.spec.js
│ ├── karma.conf.js
│ └── util.js
├── .gitignore
├── .eslintrc.json
└── CHANGE.md
/.eslintignore:
--------------------------------------------------------------------------------
1 | src/directives
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | src/styles/**/* linguist-vendored=false
--------------------------------------------------------------------------------
/assets/iview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/iview/2.0/assets/iview.png
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/iview/2.0/assets/logo.png
--------------------------------------------------------------------------------
/assets/pay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/iview/2.0/assets/pay.png
--------------------------------------------------------------------------------
/assets/iview2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/iview/2.0/assets/iview2.png
--------------------------------------------------------------------------------
/src/components/card/index.js:
--------------------------------------------------------------------------------
1 | import Card from './card.vue';
2 | export default Card;
--------------------------------------------------------------------------------
/src/components/icon/index.js:
--------------------------------------------------------------------------------
1 | import Icon from './icon.vue';
2 | export default Icon;
--------------------------------------------------------------------------------
/src/components/page/index.js:
--------------------------------------------------------------------------------
1 | import Page from './page.vue';
2 | export default Page;
--------------------------------------------------------------------------------
/src/components/rate/index.js:
--------------------------------------------------------------------------------
1 | import Rate from './rate.vue';
2 | export default Rate;
--------------------------------------------------------------------------------
/src/components/spin/index.js:
--------------------------------------------------------------------------------
1 | import Spin from './spin.vue';
2 | export default Spin;
--------------------------------------------------------------------------------
/src/components/tag/index.js:
--------------------------------------------------------------------------------
1 | import Tag from './tag.vue';
2 | export default Tag;
--------------------------------------------------------------------------------
/src/components/tree/index.js:
--------------------------------------------------------------------------------
1 | import Tree from './tree.vue';
2 | export default Tree;
--------------------------------------------------------------------------------
/src/components/affix/index.js:
--------------------------------------------------------------------------------
1 | import Affix from './affix.vue';
2 | export default Affix;
--------------------------------------------------------------------------------
/src/components/alert/index.js:
--------------------------------------------------------------------------------
1 | import Alert from './alert.vue';
2 | export default Alert;
--------------------------------------------------------------------------------
/src/components/badge/index.js:
--------------------------------------------------------------------------------
1 | import Badge from './badge.vue';
2 | export default Badge;
--------------------------------------------------------------------------------
/src/components/input/index.js:
--------------------------------------------------------------------------------
1 | import Input from './input.vue';
2 | export default Input;
--------------------------------------------------------------------------------
/src/components/table/index.js:
--------------------------------------------------------------------------------
1 | import Table from './table.vue';
2 | export default Table;
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .*
2 | *.md
3 | *.yml
4 | build/
5 | node_modules/
6 | test/
7 | gulpfile.js
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "4"
4 | script:
5 | - npm run test
6 |
--------------------------------------------------------------------------------
/src/components/circle/index.js:
--------------------------------------------------------------------------------
1 | import Circle from './circle.vue';
2 | export default Circle;
--------------------------------------------------------------------------------
/src/components/switch/index.js:
--------------------------------------------------------------------------------
1 | import Switch from './switch.vue';
2 | export default Switch;
--------------------------------------------------------------------------------
/src/components/back-top/index.js:
--------------------------------------------------------------------------------
1 | import BackTop from './back-top.vue';
2 | export default BackTop;
--------------------------------------------------------------------------------
/src/components/poptip/index.js:
--------------------------------------------------------------------------------
1 | import Poptip from './poptip.vue';
2 |
3 | export default Poptip;
--------------------------------------------------------------------------------
/src/components/slider/index.js:
--------------------------------------------------------------------------------
1 | import Slider from './slider.vue';
2 |
3 | export default Slider;
--------------------------------------------------------------------------------
/src/components/upload/index.js:
--------------------------------------------------------------------------------
1 | import Upload from './upload.vue';
2 |
3 | export default Upload;
--------------------------------------------------------------------------------
/src/components/cascader/index.js:
--------------------------------------------------------------------------------
1 | import Cascader from './cascader.vue';
2 | export default Cascader;
--------------------------------------------------------------------------------
/src/components/progress/index.js:
--------------------------------------------------------------------------------
1 | import Progress from './progress.vue';
2 | export default Progress;
--------------------------------------------------------------------------------
/src/components/tooltip/index.js:
--------------------------------------------------------------------------------
1 | import Tooltip from './tooltip.vue';
2 |
3 | export default Tooltip;
--------------------------------------------------------------------------------
/src/components/transfer/index.js:
--------------------------------------------------------------------------------
1 | import Transfer from './transfer.vue';
2 | export default Transfer;
--------------------------------------------------------------------------------
/src/styles/components/checkbox.less:
--------------------------------------------------------------------------------
1 | @checkbox-prefix-cls: ~"@{css-prefix}checkbox";
2 | .checkboxFn();
--------------------------------------------------------------------------------
/src/components/input-number/index.js:
--------------------------------------------------------------------------------
1 | import InputNumber from './input-number.vue';
2 | export default InputNumber;
--------------------------------------------------------------------------------
/src/styles/components/affix.less:
--------------------------------------------------------------------------------
1 | .ivu-affix {
2 | position: fixed;
3 | z-index: @zindex-affix;
4 | }
5 |
--------------------------------------------------------------------------------
/src/components/date-picker/index.js:
--------------------------------------------------------------------------------
1 | import DatePicker from './picker/date-picker';
2 |
3 | export default DatePicker;
--------------------------------------------------------------------------------
/src/components/grid/index.js:
--------------------------------------------------------------------------------
1 | import Row from './row.vue';
2 | import Col from './col.vue';
3 |
4 | export { Row, Col };
--------------------------------------------------------------------------------
/src/styles/common/index.less:
--------------------------------------------------------------------------------
1 | @import "base";
2 | @import "iconfont/ionicons";
3 | @import "layout";
4 | @import "article";
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"],
3 | "plugins": ["transform-runtime"],
4 | "comments": false
5 | }
6 |
--------------------------------------------------------------------------------
/src/components/time-picker/index.js:
--------------------------------------------------------------------------------
1 | import TimePicker from '../date-picker/picker/time-picker';
2 | export default TimePicker;
--------------------------------------------------------------------------------
/src/styles/common/iconfont/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/iview/2.0/src/styles/common/iconfont/fonts/ionicons.eot
--------------------------------------------------------------------------------
/src/styles/common/iconfont/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/iview/2.0/src/styles/common/iconfont/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/src/styles/common/iconfont/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/iview/2.0/src/styles/common/iconfont/fonts/ionicons.woff
--------------------------------------------------------------------------------
/src/styles/common/iconfont/ionicons.less:
--------------------------------------------------------------------------------
1 | @import "_ionicons-variables";
2 | @import "_ionicons-font";
3 | @import "_ionicons-icons";
4 |
--------------------------------------------------------------------------------
/src/components/tabs/index.js:
--------------------------------------------------------------------------------
1 | import Tabs from './tabs.vue';
2 | import Pane from './pane.vue';
3 |
4 | Tabs.Pane = Pane;
5 | export default Tabs;
--------------------------------------------------------------------------------
/src/styles/copyright.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * iView
3 | * Web: https://www.iviewui.com
4 | * Github: https://github.com/iview/iview
5 | * Author: Aresn
6 | */
--------------------------------------------------------------------------------
/src/components/steps/index.js:
--------------------------------------------------------------------------------
1 | import Steps from './steps.vue';
2 | import Step from './step.vue';
3 |
4 | Steps.Step = Step;
5 | export default Steps;
--------------------------------------------------------------------------------
/src/components/form/index.js:
--------------------------------------------------------------------------------
1 | import Form from './form.vue';
2 | import FormItem from './form-item.vue';
3 |
4 | Form.Item = FormItem;
5 | export default Form;
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/components/collapse/index.js:
--------------------------------------------------------------------------------
1 | import Collapse from './collapse.vue';
2 | import Panel from './panel.vue';
3 |
4 | Collapse.Panel = Panel;
5 | export default Collapse;
--------------------------------------------------------------------------------
/src/components/radio/index.js:
--------------------------------------------------------------------------------
1 | import Radio from './radio.vue';
2 | import RadioGroup from './radio-group.vue';
3 |
4 | Radio.Group = RadioGroup;
5 | export default Radio;
--------------------------------------------------------------------------------
/src/styles/index.less:
--------------------------------------------------------------------------------
1 | @import "./custom";
2 | @import "./mixins/index";
3 | @import "./common/index";
4 | @import "./animation/index";
5 | @import "./components/index";
6 |
--------------------------------------------------------------------------------
/src/components/button/index.js:
--------------------------------------------------------------------------------
1 | import Button from './button.vue';
2 | import ButtonGroup from './button-group.vue';
3 |
4 | Button.Group = ButtonGroup;
5 | export default Button;
--------------------------------------------------------------------------------
/src/styles/README.md:
--------------------------------------------------------------------------------
1 | # 样式库说明
2 |
3 | ## 目录
4 |
5 | |-- animation (动画)
6 |
7 | |-- common (全局样式)
8 |
9 | |-- components (组件样式)
10 |
11 | |-- mixins (混入)
12 |
--------------------------------------------------------------------------------
/src/components/dropdown/dropdown-menu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | charset = utf-8
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
--------------------------------------------------------------------------------
/src/components/carousel/index.js:
--------------------------------------------------------------------------------
1 | import Carousel from './carousel.vue';
2 | import CarouselItem from './carousel-item.vue';
3 |
4 | Carousel.Item = CarouselItem;
5 | export default Carousel;
--------------------------------------------------------------------------------
/src/components/timeline/index.js:
--------------------------------------------------------------------------------
1 | import Timeline from './timeline.vue';
2 | import TimelineItem from './timeline-item.vue';
3 |
4 | Timeline.Item = TimelineItem;
5 | export default Timeline;
--------------------------------------------------------------------------------
/examples/routers/page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/src/components/checkbox/index.js:
--------------------------------------------------------------------------------
1 | import Checkbox from './checkbox.vue';
2 | import CheckboxGroup from './checkbox-group.vue';
3 |
4 | Checkbox.Group = CheckboxGroup;
5 | export default Checkbox;
--------------------------------------------------------------------------------
/src/components/select/index.js:
--------------------------------------------------------------------------------
1 | import Select from './select.vue';
2 | import Option from './option.vue';
3 | import OptionGroup from './option-group.vue';
4 |
5 | export { Select, Option, OptionGroup };
--------------------------------------------------------------------------------
/src/components/breadcrumb/index.js:
--------------------------------------------------------------------------------
1 | import Breadcrumb from './breadcrumb.vue';
2 | import BreadcrumbItem from './breadcrumb-item.vue';
3 |
4 | Breadcrumb.Item = BreadcrumbItem;
5 | export default Breadcrumb;
--------------------------------------------------------------------------------
/src/mixins/locale.js:
--------------------------------------------------------------------------------
1 | import { t } from '../locale';
2 |
3 | export default {
4 | methods: {
5 | t(...args) {
6 | return t.apply(this, args);
7 | }
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/base/render.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'RenderCell',
3 | functional: true,
4 | props: {
5 | render: Function
6 | },
7 | render: (h, ctx) => {
8 | return ctx.props.render(h);
9 | }
10 | };
--------------------------------------------------------------------------------
/src/components/dropdown/index.js:
--------------------------------------------------------------------------------
1 | import Dropdown from './dropdown.vue';
2 | import DropdownMenu from './dropdown-menu.vue';
3 | import DropdownItem from './dropdown-item.vue';
4 |
5 | Dropdown.Menu = DropdownMenu;
6 | Dropdown.Item = DropdownItem;
7 | export default Dropdown;
--------------------------------------------------------------------------------
/src/styles/mixins/close.less:
--------------------------------------------------------------------------------
1 | .close-base(@top: 0, @icon-font-size: 22px) {
2 | font-size: @icon-font-size;
3 | color: @legend-color;
4 | transition: color @transition-time ease;
5 | position: relative;
6 | top: @top;
7 | &:hover {
8 | color: #444;
9 | }
10 | }
--------------------------------------------------------------------------------
/src/components/menu/index.js:
--------------------------------------------------------------------------------
1 | import Menu from './menu.vue';
2 | import MenuGroup from './menu-group.vue';
3 | import MenuItem from './menu-item.vue';
4 | import Submenu from './submenu.vue';
5 |
6 | Menu.Group = MenuGroup;
7 | Menu.Item = MenuItem;
8 | Menu.Sub = Submenu;
9 |
10 | export default Menu;
--------------------------------------------------------------------------------
/src/styles/mixins/loading.less:
--------------------------------------------------------------------------------
1 | // Loading for loop
2 | .ivu-load-loop{
3 | animation: ani-load-loop 1s linear infinite;
4 | }
5 |
6 | @keyframes ani-load-loop {
7 | from { transform: rotate(0deg);}
8 | 50% { transform: rotate(180deg);}
9 | to { transform: rotate(360deg);}
10 | }
11 |
--------------------------------------------------------------------------------
/src/styles/mixins/mask.less:
--------------------------------------------------------------------------------
1 | .mask() {
2 | position: fixed;
3 | top: 0;
4 | bottom: 0;
5 | left: 0;
6 | right: 0;
7 | background-color: rgba(55, 55, 55, 0.6);
8 | height: 100%;
9 | z-index: @zindex-modal;
10 |
11 | &-hidden {
12 | display: none;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/styles/mixins/clearfix.less:
--------------------------------------------------------------------------------
1 | .clearfix() {
2 | zoom: 1;
3 | &:before,
4 | &:after {
5 | content: "";
6 | display: table;
7 | }
8 | &:after {
9 | clear: both;
10 | visibility: hidden;
11 | font-size: 0;
12 | height: 0;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "../.eslintrc.json"
4 | ],
5 | "globals": {
6 | "expect": true
7 | },
8 | "env": {
9 | "node": true,
10 | "mocha": true
11 | },
12 | "rules": {
13 | "indent": ["error",2, { "SwitchCase": 1 }]
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .idea
3 | .ipr
4 | .iws
5 | *.diff
6 | *.patch
7 | *.bak
8 | .DS_Store
9 | node_modules/
10 | node_modules2/
11 | .project
12 | .settings
13 | npm-debug.log
14 | .*proj
15 | .svn/
16 | *.swp
17 | *.swo
18 | *.log
19 | examples/dist/
20 | dist/
21 | yarn-error.log
22 | test/unit/coverage
23 | .vscode
--------------------------------------------------------------------------------
/src/styles/mixins/index.less:
--------------------------------------------------------------------------------
1 | @import "common";
2 | @import "clearfix";
3 | @import "button";
4 | @import "layout";
5 | @import "size";
6 | @import "loading";
7 | @import "close";
8 | @import "checkbox";
9 | @import "input";
10 | @import "breadcrumb";
11 | @import "mask";
12 | @import "content"; // card、modal
13 | @import "tooltip";
14 | @import "select";
15 | @import "caret";
--------------------------------------------------------------------------------
/examples/routers/back-top.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
23 |
--------------------------------------------------------------------------------
/examples/components/tableExpand.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ name }}
3 |
4 |
--------------------------------------------------------------------------------
/src/styles/components/circle.less:
--------------------------------------------------------------------------------
1 | @circle-prefix-cls: ~"@{css-prefix}chart-circle";
2 |
3 | .@{circle-prefix-cls}{
4 | display: inline-block;
5 | position: relative;
6 |
7 | &-inner {
8 | width: 100%;
9 | text-align: center;
10 | position: absolute;
11 | left: 0;
12 | top: 50%;
13 | transform: translateY(-50%);
14 | line-height: 1;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/routers/affix.vue:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 | 固定在最顶部
15 |
16 |
17 |
22 |
--------------------------------------------------------------------------------
/src/components/table/header.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'TableRenderHeader',
3 | functional: true,
4 | props: {
5 | render: Function,
6 | column: Object,
7 | index: Number
8 | },
9 | render: (h, ctx) => {
10 | const params = {
11 | column: ctx.props.column,
12 | index: ctx.props.index
13 | };
14 | return ctx.props.render(h, params);
15 | }
16 | };
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | iView test page
6 |
7 |
8 |
9 |
10 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/routers/tooltip.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 延时1秒显示
5 |
6 |
7 | 延时1秒显示
8 |
9 |
10 |
11 |
16 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "parserOptions": {
4 | "ecmaVersion": 6,
5 | "sourceType": "module"
6 | },
7 | "env": {
8 | "browser": true
9 | },
10 | "extends": "eslint:recommended",
11 | "plugins": [ "html" ],
12 | "rules": {
13 | "indent": ["error", 4, { "SwitchCase": 1 }],
14 | "quotes": ["error", "single"],
15 | "semi": ["error", "always"],
16 | "no-console": ["error"]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/routers/slider.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | change
5 |
6 |
7 |
21 |
--------------------------------------------------------------------------------
/src/styles/components/loading-bar.less:
--------------------------------------------------------------------------------
1 | @loading-bar-prefix-cls: ~"@{css-prefix}loading-bar";
2 |
3 | .@{loading-bar-prefix-cls} {
4 | width: 100%;
5 | position: fixed;
6 | top: 0;
7 | left: 0;
8 | right: 0;
9 | z-index: @zindex-loading-bar;
10 |
11 | &-inner {
12 | transition: width @transition-time linear;
13 |
14 | &-color-primary {
15 | background-color: @primary-color;
16 | }
17 |
18 | &-failed-color-error {
19 | background-color: @error-color;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/styles/mixins/size.less:
--------------------------------------------------------------------------------
1 | .size(@width; @height) {
2 | width: @width;
3 | height: @height;
4 | }
5 |
6 | .square(@size) {
7 | .size(@size; @size);
8 | }
9 |
10 | // fix chrome 12px bug, support ie
11 | .iconfont-size-under-12px(@size, @rotate: 0deg) {
12 | display: inline-block;
13 | @font-scale: unit(@size / @font-size-base);
14 | font-size: @font-size-base;
15 | font-size: ~"@{size} \9"; // ie8-9
16 | transform: scale(@font-scale) rotate(@rotate);
17 | :root & {
18 | font-size: @font-size-base; // reset ie9 and above
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/table/expand.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'TableExpand',
3 | functional: true,
4 | props: {
5 | row: Object,
6 | render: Function,
7 | index: Number,
8 | column: {
9 | type: Object,
10 | default: null
11 | }
12 | },
13 | render: (h, ctx) => {
14 | const params = {
15 | row: ctx.props.row,
16 | index: ctx.props.index
17 | };
18 | if (ctx.props.column) params.column = ctx.props.column;
19 | return ctx.props.render(h, params);
20 | }
21 | };
--------------------------------------------------------------------------------
/examples/routers/switch.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 开
5 | 关
6 |
7 | {{ m1 }}
8 |
toggle
9 |
10 |
11 |
25 |
--------------------------------------------------------------------------------
/examples/routers/tag.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 标签{{ item + 1 }}
4 | 添加标签
5 |
6 |
7 |
22 |
--------------------------------------------------------------------------------
/examples/components/test.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 下拉菜单
5 |
6 |
7 |
8 | 驴打滚
9 | 炸酱面
10 | 豆汁儿
11 | 冰糖葫芦
12 | 北京烤鸭
13 |
14 |
15 |
16 |
21 |
--------------------------------------------------------------------------------
/examples/routers/rate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ v1 }}
5 |
6 | {{ v1 }}
7 |
change v1
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/menu/menu-group.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ title }}
4 |
5 |
6 |
7 |
25 |
--------------------------------------------------------------------------------
/src/components/date-picker/time-mixins.js:
--------------------------------------------------------------------------------
1 | export default {
2 | props: {
3 | disabledHours: {
4 | type: Array,
5 | default () {
6 | return [];
7 | }
8 | },
9 | disabledMinutes: {
10 | type: Array,
11 | default () {
12 | return [];
13 | }
14 | },
15 | disabledSeconds: {
16 | type: Array,
17 | default () {
18 | return [];
19 | }
20 | },
21 | hideDisabledOptions: {
22 | type: Boolean,
23 | default: false
24 | }
25 | }
26 | };
--------------------------------------------------------------------------------
/src/directives/clickoutside.js:
--------------------------------------------------------------------------------
1 | export default {
2 | bind (el, binding, vnode) {
3 | function documentHandler (e) {
4 | if (el.contains(e.target)) {
5 | return false;
6 | }
7 | if (binding.expression) {
8 | binding.value(e);
9 | }
10 | }
11 | el.__vueClickOutside__ = documentHandler;
12 | document.addEventListener('click', documentHandler);
13 | },
14 | update () {
15 |
16 | },
17 | unbind (el, binding) {
18 | document.removeEventListener('click', el.__vueClickOutside__);
19 | delete el.__vueClickOutside__;
20 | }
21 | };
--------------------------------------------------------------------------------
/src/styles/components/dropdown.less:
--------------------------------------------------------------------------------
1 | @dropdown-prefix-cls: ~"@{css-prefix}dropdown";
2 | @dropdown-item-prefix-cls: ~"@{dropdown-prefix-cls}-item";
3 |
4 | .@{dropdown-prefix-cls} {
5 | display: inline-block;
6 | //position: relative;
7 |
8 | .@{select-dropdown-prefix-cls} {
9 | overflow: visible;
10 | max-height: none;
11 | }
12 | .@{dropdown-prefix-cls} {
13 | width: 100%;
14 | }
15 |
16 | &-rel{
17 | //display: inline-block;
18 | position: relative;
19 | }
20 |
21 | &-menu{
22 | min-width: 100px;
23 | }
24 | }
25 |
26 | .select-item(@dropdown-prefix-cls, @dropdown-item-prefix-cls);
--------------------------------------------------------------------------------
/src/styles/animation/fade.less:
--------------------------------------------------------------------------------
1 | .fade-motion(@className, @keyframeName) {
2 | .make-motion(@className, @keyframeName);
3 | .@{className}-enter-active, .@{className}-appear {
4 | opacity: 0;
5 | animation-timing-function: linear;
6 | }
7 | .@{className}-leave-active {
8 | animation-timing-function: linear;
9 | }
10 | }
11 |
12 | .fade-motion(fade, ivuFade);
13 |
14 | @keyframes ivuFadeIn {
15 | 0% {
16 | opacity: 0;
17 | }
18 | 100% {
19 | opacity: 1;
20 | }
21 | }
22 |
23 | @keyframes ivuFadeOut {
24 | 0% {
25 | opacity: 1;
26 | }
27 | 100% {
28 | opacity: 0;
29 | }
30 | }
--------------------------------------------------------------------------------
/examples/routers/poptip.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | hover 激活
5 |
6 |
7 | click 激活
8 |
9 |
10 | focus 激活
11 |
12 |
13 |
14 |
15 |
16 |
17 |
22 |
--------------------------------------------------------------------------------
/examples/routers/grid.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 | col-8
11 |
12 |
13 |
add
14 |
15 |
16 |
30 |
--------------------------------------------------------------------------------
/src/components/timeline/timeline.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
29 |
--------------------------------------------------------------------------------
/src/styles/components/back-top.less:
--------------------------------------------------------------------------------
1 | @backtop-prefix-cls: ~"@{css-prefix}back-top";
2 |
3 | .@{backtop-prefix-cls} {
4 | z-index: @zindex-back-top;
5 | position: fixed;
6 | cursor: pointer;
7 | display: none;
8 |
9 | &.@{backtop-prefix-cls}-show {
10 | display: block;
11 | }
12 |
13 | &-inner {
14 | background-color: rgba(0,0,0,.6);
15 | border-radius: 2px;
16 | box-shadow: 0 1px 3px rgba(0,0,0,.2);
17 | transition: all @transition-time @ease-in-out;
18 |
19 | &:hover {
20 | background-color: rgba(0,0,0,.7);
21 | }
22 | }
23 |
24 | i{
25 | color: #fff;
26 | font-size: 24px;
27 | padding: 8px 12px;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/styles/components/select-dropdown.less:
--------------------------------------------------------------------------------
1 | @select-dropdown-prefix-cls: ~"@{css-prefix}select-dropdown";
2 |
3 | .@{select-dropdown-prefix-cls} {
4 | width: inherit;
5 | max-height: 200px;
6 | overflow: auto;
7 | margin: 5px 0;
8 | padding: 5px 0;
9 | background-color: #fff;
10 | box-sizing: border-box;
11 | //border: 1px solid @border-color-split;
12 | border-radius: @btn-border-radius;
13 | //box-shadow: 0 1px 3px rgba(0,0,0,.2);
14 | box-shadow: @shadow-base;
15 | position: absolute;
16 | z-index: @zindex-select;
17 | &-transfer{
18 | z-index: @zindex-transfer;
19 | }
20 | }
21 | .@{modal-prefix-cls} {
22 | .@{select-dropdown-prefix-cls} {
23 | position: absolute !important;
24 | }
25 | }
--------------------------------------------------------------------------------
/examples/routers/radio.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
change
10 |
11 |
12 |
30 |
--------------------------------------------------------------------------------
/src/styles/mixins/breadcrumb.less:
--------------------------------------------------------------------------------
1 | @breadcrumb-prefix-cls: ~"@{css-prefix}breadcrumb";
2 |
3 | .@{breadcrumb-prefix-cls} {
4 | color: #999;
5 | font-size: @font-size-base;
6 |
7 | a {
8 | color: @text-color;
9 | transition: color @transition-time @ease-in-out;
10 | &:hover {
11 | color: tint(@primary-color, 20%);
12 | }
13 | }
14 |
15 | & > span:last-child {
16 | font-weight: bold;
17 | color: @text-color;
18 | }
19 |
20 | & > span:last-child &-item-separator {
21 | display: none;
22 | }
23 |
24 | &-item-separator {
25 | margin: 0 8px;
26 | color: @border-color-base;
27 | }
28 |
29 | &-item-link {
30 | > .ivu-icon + span {
31 | margin-left: 4px;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/test/unit/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | Vue.config.productionTip = false;
3 |
4 | // Polyfill fn.bind() for PhantomJS
5 | /* eslint-disable no-extend-native */
6 | Function.prototype.bind = require('function-bind');
7 |
8 | // require all test files (files that ends with .spec.js)
9 | const testsContext = require.context('./specs', true, /\.spec$/);
10 | testsContext.keys().forEach(testsContext);
11 |
12 | // require all src files except main.js for coverage.
13 | // you can also change this to match only the subset of files that
14 | // you want coverage for.
15 | // const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/);
16 | // @todo
17 | const srcContext = require.context('../../src/components/breadcrumb', true, /^\.\/(?!styles.*?(\.less)?$)/);
18 | srcContext.keys().forEach(srcContext);
19 |
--------------------------------------------------------------------------------
/src/styles/mixins/common.less:
--------------------------------------------------------------------------------
1 | .placeholder(@color: @input-placeholder-color) {
2 | // Firefox
3 | &::-moz-placeholder {
4 | color: @color;
5 | opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
6 | }
7 | // Internet Explorer 10+
8 | &:-ms-input-placeholder {
9 | color: @color;
10 | }
11 | // Safari and Chrome
12 | &::-webkit-input-placeholder {
13 | color: @color;
14 | }
15 | }
16 |
17 | // for select and input like component's arrow
18 | .inner-arrow() {
19 | position: absolute;
20 | top: 50%;
21 | right: 8px;
22 | line-height: 1;
23 | margin-top: -7px;
24 | font-size: @font-size-base;
25 | color: @subsidiary-color;
26 | transition: all @transition-time @ease-in-out;
27 | }
28 |
--------------------------------------------------------------------------------
/examples/routers/loading-bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Start
4 | Finish
5 | Error
6 |
7 |
8 |
30 |
--------------------------------------------------------------------------------
/src/styles/mixins/caret.less:
--------------------------------------------------------------------------------
1 | // sortable
2 | .sortable() {
3 | display: inline-block;
4 | width: 9px;
5 | height: 12px;
6 | margin-left: 4px;
7 | margin-top: -1px;
8 | vertical-align: middle;
9 | overflow: hidden;
10 | cursor: pointer;
11 | position: relative;
12 |
13 | i {
14 | display: block;
15 | height: 6px;
16 | line-height: 6px;
17 | overflow: hidden;
18 | position: absolute;
19 | color: @btn-disable-color;
20 | transition: color @transition-time @ease-in-out;
21 |
22 | &:hover{
23 | color: inherit;
24 | }
25 |
26 | &.on{
27 | color: @primary-color;
28 | }
29 |
30 | &:first-child{
31 | top: 0;
32 | }
33 | &:last-child{
34 | bottom: 0;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/routers/input-number.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ v1 }}
5 |
change v1
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/routers/badge.vue:
--------------------------------------------------------------------------------
1 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
set count
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/components/icon/icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
34 |
--------------------------------------------------------------------------------
/src/styles/animation/ease.less:
--------------------------------------------------------------------------------
1 | .ease-motion(@className, @keyframeName) {
2 | .make-motion(@className, @keyframeName);
3 | .@{className}-enter-active, .@{className}-appear {
4 | opacity: 0;
5 | animation-timing-function: linear;
6 | animation-duration: @transition-time;
7 | }
8 | .@{className}-leave-active {
9 | animation-timing-function: linear;
10 | animation-duration: @transition-time;
11 | }
12 | }
13 |
14 | .ease-motion(ease, ivuEase);
15 |
16 | @keyframes ivuEaseIn {
17 | 0% {
18 | opacity: 0;
19 | transform: scale(0.9);
20 | }
21 | 100% {
22 | opacity: 1;
23 | transform: scale(1);
24 | }
25 | }
26 |
27 | @keyframes ivuEaseOut {
28 | 0% {
29 | opacity: 1;
30 | transform: scale(1);
31 | }
32 | 100% {
33 | opacity: 0;
34 | transform: scale(0.9);
35 | }
36 | }
--------------------------------------------------------------------------------
/src/styles/mixins/content.less:
--------------------------------------------------------------------------------
1 | @icon-prefix-cls: ~"@{css-prefix}icon";
2 |
3 | .content-header() {
4 | border-bottom: 1px solid @border-color-split;
5 | padding: 14px 16px;
6 | line-height: 1;
7 |
8 | p,
9 | &-inner
10 | {
11 | display: inline-block;
12 | width: 100%;
13 | height: 20px;
14 | line-height: 20px;
15 | font-size: @font-size-base;
16 | color: @title-color;
17 | font-weight: bold;
18 | overflow: hidden;
19 | text-overflow: ellipsis;
20 | white-space: nowrap;
21 | }
22 | }
23 |
24 | .content-close(@top: 0, @icon-font-size: 22px) {
25 | font-size: @font-size-small;
26 | position: absolute;
27 | right: 16px;
28 | top: 8px;
29 | overflow: hidden;
30 | cursor: pointer;
31 |
32 | .@{icon-prefix-cls}-ios-close-empty {
33 | .close-base(@top, @icon-font-size);
34 | }
35 | }
--------------------------------------------------------------------------------
/src/components/date-picker/panel/mixin.js:
--------------------------------------------------------------------------------
1 | const prefixCls = 'ivu-picker-panel';
2 | const datePrefixCls = 'ivu-date-picker';
3 |
4 | export default {
5 | methods: {
6 | iconBtnCls (direction, type = '') {
7 | return [
8 | `${prefixCls}-icon-btn`,
9 | `${datePrefixCls}-${direction}-btn`,
10 | `${datePrefixCls}-${direction}-btn-arrow${type}`,
11 | ];
12 | },
13 | handleShortcutClick (shortcut) {
14 | if (shortcut.value) this.$emit('on-pick', shortcut.value());
15 | if (shortcut.onClick) shortcut.onClick(this);
16 | },
17 | handlePickClear () {
18 | this.$emit('on-pick-clear');
19 | },
20 | handlePickSuccess () {
21 | this.$emit('on-pick-success');
22 | },
23 | handlePickClick () {
24 | this.$emit('on-pick-click');
25 | }
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/src/styles/components/index.less:
--------------------------------------------------------------------------------
1 | @import "button";
2 | @import "affix";
3 | @import "back-top";
4 | @import "badge";
5 | @import "circle";
6 | @import "spin";
7 | @import "alert";
8 | @import "collapse";
9 | @import "card";
10 | @import "message";
11 | @import "notice";
12 | @import "radio";
13 | @import "checkbox";
14 | @import "switch";
15 | @import "input-number";
16 | @import "tag";
17 | @import "loading-bar";
18 | @import "progress";
19 | @import "timeline";
20 | @import "page";
21 | @import "steps";
22 | @import "modal";
23 | @import "select";
24 | @import "select-dropdown";
25 | @import "tooltip";
26 | @import "poptip";
27 | @import "input";
28 | @import "slider";
29 | @import "cascader";
30 | @import "transfer";
31 | @import "table";
32 | @import "dropdown";
33 | @import "tabs";
34 | @import "menu";
35 | @import "date-picker";
36 | @import "time-picker";
37 | @import "form";
38 | @import "carousel";
39 | @import "rate";
40 | @import "upload";
41 | @import "tree";
--------------------------------------------------------------------------------
/test/unit/specs/breadcrumb.spec.js:
--------------------------------------------------------------------------------
1 | import { createVue, destroyVM } from '../util';
2 |
3 | describe('Breadcrumb.vue', () => {
4 | let vm;
5 | afterEach(() => {
6 | destroyVM(vm);
7 | });
8 | it('create', done => {
9 | vm = createVue(`
10 |
11 | Home4
12 | Components
13 | Breadcrumb
14 |
15 | `);
16 | expect(vm.$el.querySelectorAll('.ivu-breadcrumb-item-link').length).to.equal(3);
17 |
18 | vm.$nextTick(_ => {
19 | // console.log(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML);
20 | expect(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML).to.equal('=> ');
21 | done();
22 | });
23 | });
24 | });
--------------------------------------------------------------------------------
/examples/routers/checkbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ fruit }}
7 |
8 |
9 |
35 |
--------------------------------------------------------------------------------
/src/components/carousel/carousel-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
35 |
--------------------------------------------------------------------------------
/src/styles/animation/index.less:
--------------------------------------------------------------------------------
1 | .motion-common() {
2 | animation-duration: @animation-time;
3 | animation-fill-mode: both;
4 | }
5 |
6 | .make-motion(@className, @keyframeName) {
7 | .@{className}-enter-active, .@{className}-appear {
8 | .motion-common();
9 | animation-play-state: paused;
10 | }
11 | .@{className}-leave-active {
12 | .motion-common();
13 | animation-play-state: paused;
14 | }
15 | .@{className}-enter-active, .@{className}-appear {
16 | animation-name: ~"@{keyframeName}In";
17 | animation-play-state: running;
18 | }
19 | .@{className}-leave-active {
20 | animation-name: ~"@{keyframeName}Out";
21 | animation-play-state: running;
22 | }
23 | }
24 |
25 | @import "fade";
26 | @import "move";
27 | @import "ease";
28 | @import "slide";
29 |
30 | .collapse-transition {
31 | transition: @transition-time height ease-in-out, @transition-time padding-top ease-in-out, @transition-time padding-bottom ease-in-out;
32 | }
--------------------------------------------------------------------------------
/examples/routers/dropdown.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 北京小吃
5 |
6 |
7 |
8 | 驴打滚
9 | 炸酱面
10 | 豆汁儿
11 |
12 |
13 | 北京烤鸭
14 |
15 |
16 |
17 | 挂炉烤鸭
18 | 焖炉烤鸭
19 |
20 |
21 | 冰糖葫芦
22 |
23 |
24 |
25 |
30 |
--------------------------------------------------------------------------------
/src/components/date-picker/picker/time-picker.js:
--------------------------------------------------------------------------------
1 | import Picker from '../picker.vue';
2 | import TimePanel from '../panel/time.vue';
3 | import TimeRangePanel from '../panel/time-range.vue';
4 | import Options from '../time-mixins';
5 |
6 | const getPanel = function (type) {
7 | if (type === 'timerange') {
8 | return TimeRangePanel;
9 | }
10 | return TimePanel;
11 | };
12 |
13 | import { oneOf } from '../../../utils/assist';
14 |
15 | export default {
16 | mixins: [Picker, Options],
17 | props: {
18 | type: {
19 | validator (value) {
20 | return oneOf(value, ['time', 'timerange']);
21 | },
22 | default: 'time'
23 | },
24 | value: {}
25 | },
26 | created () {
27 | if (!this.currentValue) {
28 | if (this.type === 'timerange') {
29 | this.currentValue = ['',''];
30 | } else {
31 | this.currentValue = '';
32 | }
33 | }
34 | this.panel = getPanel(this.type);
35 | }
36 | };
--------------------------------------------------------------------------------
/src/components/table/table-tr.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/styles/common/iconfont/_ionicons-font.less:
--------------------------------------------------------------------------------
1 | // Ionicons Font Path
2 | // --------------------------
3 |
4 | @font-face {
5 | font-family: @ionicons-font-family;
6 | src:url("@{ionicons-font-path}/ionicons.eot?v=@{ionicons-version}");
7 | src:url("@{ionicons-font-path}/ionicons.eot?v=@{ionicons-version}#iefix") format("embedded-opentype"),
8 | url("@{ionicons-font-path}/ionicons.ttf?v=@{ionicons-version}") format("truetype"),
9 | url("@{ionicons-font-path}/ionicons.woff?v=@{ionicons-version}") format("woff"),
10 | url("@{ionicons-font-path}/ionicons.svg?v=@{ionicons-version}#Ionicons") format("svg");
11 | font-weight: normal;
12 | font-style: normal;
13 | }
14 |
15 | .ivu-icon() {
16 | display: inline-block;
17 | font-family: @ionicons-font-family;
18 | speak: none;
19 | font-style: normal;
20 | font-weight: normal;
21 | font-variant: normal;
22 | text-transform: none;
23 | text-rendering: auto;
24 | line-height: 1;
25 | -webkit-font-smoothing: antialiased;
26 | -moz-osx-font-smoothing: grayscale;
27 | }
28 |
29 | .ivu-icon {
30 | .ivu-icon();
31 | }
--------------------------------------------------------------------------------
/examples/routers/input.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
32 |
--------------------------------------------------------------------------------
/src/components/base/notification/index.js:
--------------------------------------------------------------------------------
1 | import Notification from './notification.vue';
2 | import Vue from 'vue';
3 |
4 | Notification.newInstance = properties => {
5 | const _props = properties || {};
6 |
7 | const Instance = new Vue({
8 | data: _props,
9 | render (h) {
10 | return h(Notification, {
11 | props: _props
12 | });
13 | }
14 | });
15 |
16 | const component = Instance.$mount();
17 | document.body.appendChild(component.$el);
18 | const notification = Instance.$children[0];
19 |
20 | return {
21 | notice (noticeProps) {
22 | notification.add(noticeProps);
23 | },
24 | remove (name) {
25 | notification.close(name);
26 | },
27 | component: notification,
28 | destroy (element) {
29 | notification.closeAll();
30 | setTimeout(function() {
31 | document.body.removeChild(document.getElementsByClassName(element)[0]);
32 | }, 500);
33 | }
34 | };
35 | };
36 |
37 | export default Notification;
38 |
--------------------------------------------------------------------------------
/src/styles/components/tooltip.less:
--------------------------------------------------------------------------------
1 | @tooltip-prefix-cls: ~"@{css-prefix}tooltip";
2 | @tooltip-arrow: ~"@{tooltip-prefix-cls}-arrow";
3 | @tooltip-max-width: 250px;
4 | @tooltip-arrow-width: 5px;
5 | @tooltip-distance: @tooltip-arrow-width - 1 + 4;
6 |
7 | .@{tooltip-prefix-cls} {
8 | display: inline-block;
9 |
10 | &-rel{
11 | display: inline-block;
12 | position: relative;
13 | }
14 |
15 | &-popper{
16 | .popper(@tooltip-arrow, @tooltip-arrow-width, @tooltip-distance, @tooltip-bg);
17 | }
18 |
19 | &-inner{
20 | max-width: @tooltip-max-width;
21 | min-height: 34px;
22 | padding: 8px 12px;
23 | color: @tooltip-color;
24 | text-align: left;
25 | text-decoration: none;
26 | background-color: @tooltip-bg;
27 | border-radius: @border-radius-small;
28 | box-shadow: @shadow-base;
29 | white-space: nowrap;
30 | }
31 |
32 | &-arrow{
33 | position: absolute;
34 | width: 0;
35 | height: 0;
36 | border-color: transparent;
37 | border-style: solid;
38 | }
39 | }
--------------------------------------------------------------------------------
/src/components/date-picker/picker/date-picker.js:
--------------------------------------------------------------------------------
1 | import Picker from '../picker.vue';
2 | import DatePanel from '../panel/date.vue';
3 | import DateRangePanel from '../panel/date-range.vue';
4 |
5 | const getPanel = function (type) {
6 | if (type === 'daterange' || type === 'datetimerange') {
7 | return DateRangePanel;
8 | }
9 | return DatePanel;
10 | };
11 |
12 | import { oneOf } from '../../../utils/assist';
13 |
14 | export default {
15 | mixins: [Picker],
16 | props: {
17 | type: {
18 | validator (value) {
19 | return oneOf(value, ['year', 'month', 'date', 'daterange', 'datetime', 'datetimerange']);
20 | },
21 | default: 'date'
22 | },
23 | value: {}
24 | },
25 | created () {
26 | if (!this.currentValue) {
27 | if (this.type === 'daterange' || this.type === 'datetimerange') {
28 | this.currentValue = ['',''];
29 | } else {
30 | this.currentValue = '';
31 | }
32 | }
33 |
34 | this.panel = getPanel(this.type);
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/test/unit/karma.conf.js:
--------------------------------------------------------------------------------
1 | // This is a karma config file. For more details see
2 | // http://karma-runner.github.io/0.13/config/configuration-file.html
3 | // we are also using it with karma-webpack
4 | // https://github.com/webpack/karma-webpack
5 |
6 | var webpackConfig = require('../../build/webpack.test.config.js');
7 |
8 | module.exports = function (config) {
9 | config.set({
10 | // to run in additional browsers:
11 | // 1. install corresponding karma launcher
12 | // http://karma-runner.github.io/0.13/config/browsers.html
13 | // 2. add it to the `browsers` array below.
14 | browsers: ['PhantomJS'],
15 | frameworks: ['mocha', 'sinon-chai'],
16 | reporters: ['spec', 'coverage'],
17 | files: ['./index.js'],
18 | preprocessors: {
19 | './index.js': ['webpack', 'sourcemap']
20 | },
21 | webpack: webpackConfig,
22 | webpackMiddleware: {
23 | noInfo: true,
24 | },
25 | coverageReporter: {
26 | dir: './coverage',
27 | reporters: [
28 | { type: 'lcov', subdir: '.' },
29 | { type: 'text-summary' },
30 | ]
31 | },
32 | });
33 | };
34 |
--------------------------------------------------------------------------------
/examples/routers/collapse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 史蒂夫·乔布斯
6 | 史蒂夫·乔布斯(Steve Jobs),1955年2月24日生于美国加利福尼亚州旧金山,美国发明家、企业家、美国苹果公司联合创办人。
7 |
8 |
9 | 斯蒂夫·盖瑞·沃兹尼亚克
10 | 斯蒂夫·盖瑞·沃兹尼亚克(Stephen Gary Wozniak),美国电脑工程师,曾与史蒂夫·乔布斯合伙创立苹果电脑(今之苹果公司)。斯蒂夫·盖瑞·沃兹尼亚克曾就读于美国科罗拉多大学,后转学入美国著名高等学府加州大学伯克利分校(UC Berkeley)并获得电机工程及计算机(EECS)本科学位(1987年)。
11 |
12 |
13 | 乔纳森·伊夫
14 | 乔纳森·伊夫是一位工业设计师,现任Apple公司设计师兼资深副总裁,英国爵士。他曾参与设计了iPod,iMac,iPhone,iPad等众多苹果产品。除了乔布斯,他是对苹果那些著名的产品最有影响力的人。
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/components/breadcrumb/breadcrumb.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
44 |
--------------------------------------------------------------------------------
/src/styles/components/card.less:
--------------------------------------------------------------------------------
1 | @card-prefix-cls: ~"@{css-prefix}card";
2 |
3 | .@{card-prefix-cls}{
4 | background: #fff;
5 | border-radius: @border-radius-small;
6 | font-size: @font-size-base;
7 | position: relative;
8 | //overflow: hidden;
9 | transition: all @transition-time @ease-in-out;
10 |
11 | &-bordered {
12 | border: 1px solid @border-color-base;
13 | border-color: @border-color-split;
14 | }
15 |
16 | &-shadow{
17 | box-shadow: @shadow-card;
18 | }
19 |
20 | &:hover {
21 | box-shadow: @shadow-base;
22 | border-color: #eee;
23 | }
24 | &&-dis-hover:hover{
25 | box-shadow: none;
26 | border-color: transparent;
27 | }
28 |
29 | &&-dis-hover&-bordered:hover{
30 | border-color: @border-color-split;
31 | }
32 |
33 | &&-shadow:hover{
34 | box-shadow: @shadow-card;
35 | }
36 |
37 | &-head {
38 | .content-header;
39 | }
40 |
41 | &-extra {
42 | position: absolute;
43 | right: 16px;
44 | top: 14px;
45 | }
46 |
47 | &-body {
48 | padding: 16px;
49 | }
50 | }
--------------------------------------------------------------------------------
/src/components/transfer/operation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ operations[0] }}
5 |
6 |
7 | {{ operations[1] }}
8 |
9 |
10 |
11 |
34 |
--------------------------------------------------------------------------------
/examples/routers/breadcrumb.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 | Home4
11 | Components
12 | Breadcrumb
13 |
14 |
15 |
16 | Home
17 |
18 | ->
19 |
20 |
21 |
22 | Breadcrumb
23 |
24 | ->
25 |
26 |
27 | Breadcrumb
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/components/loading-bar/loading-bar.js:
--------------------------------------------------------------------------------
1 | import LoadingBar from './loading-bar.vue';
2 | import Vue from 'vue';
3 |
4 | LoadingBar.newInstance = properties => {
5 | const _props = properties || {};
6 |
7 | const Instance = new Vue({
8 | data: _props,
9 | render (h) {
10 | return h(LoadingBar, {
11 | props: _props
12 | });
13 | }
14 | });
15 |
16 | const component = Instance.$mount();
17 | document.body.appendChild(component.$el);
18 | const loading_bar = Instance.$children[0];
19 |
20 | return {
21 | update (options) {
22 | if ('percent' in options) {
23 | loading_bar.percent = options.percent;
24 | }
25 | if (options.status) {
26 | loading_bar.status = options.status;
27 | }
28 | if ('show' in options) {
29 | loading_bar.show = options.show;
30 | }
31 | },
32 | component: loading_bar,
33 | destroy () {
34 | document.body.removeChild(document.getElementsByClassName('ivu-loading-bar')[0]);
35 | }
36 | };
37 | };
38 |
39 | export default LoadingBar;
40 |
--------------------------------------------------------------------------------
/src/utils/dom.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | const isServer = Vue.prototype.$isServer;
3 |
4 | /* istanbul ignore next */
5 | export const on = (function() {
6 | if (!isServer && document.addEventListener) {
7 | return function(element, event, handler) {
8 | if (element && event && handler) {
9 | element.addEventListener(event, handler, false);
10 | }
11 | };
12 | } else {
13 | return function(element, event, handler) {
14 | if (element && event && handler) {
15 | element.attachEvent('on' + event, handler);
16 | }
17 | };
18 | }
19 | })();
20 |
21 | /* istanbul ignore next */
22 | export const off = (function() {
23 | if (!isServer && document.removeEventListener) {
24 | return function(element, event, handler) {
25 | if (element && event) {
26 | element.removeEventListener(event, handler, false);
27 | }
28 | };
29 | } else {
30 | return function(element, event, handler) {
31 | if (element && event) {
32 | element.detachEvent('on' + event, handler);
33 | }
34 | };
35 | }
36 | })();
--------------------------------------------------------------------------------
/src/mixins/emitter.js:
--------------------------------------------------------------------------------
1 | function broadcast(componentName, eventName, params) {
2 | this.$children.forEach(child => {
3 | const name = child.$options.name;
4 |
5 | if (name === componentName) {
6 | child.$emit.apply(child, [eventName].concat(params));
7 | } else {
8 | // todo 如果 params 是空数组,接收到的会是 undefined
9 | broadcast.apply(child, [componentName, eventName].concat([params]));
10 | }
11 | });
12 | }
13 | export default {
14 | methods: {
15 | dispatch(componentName, eventName, params) {
16 | let parent = this.$parent || this.$root;
17 | let name = parent.$options.name;
18 |
19 | while (parent && (!name || name !== componentName)) {
20 | parent = parent.$parent;
21 |
22 | if (parent) {
23 | name = parent.$options.name;
24 | }
25 | }
26 | if (parent) {
27 | parent.$emit.apply(parent, [eventName].concat(params));
28 | }
29 | },
30 | broadcast(componentName, eventName, params) {
31 | broadcast.call(this, componentName, eventName, params);
32 | }
33 | }
34 | };
--------------------------------------------------------------------------------
/src/components/cascader/casitem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ data.label }}
4 |
5 |
6 |
7 |
8 |
35 |
--------------------------------------------------------------------------------
/src/components/button/button-group.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
43 |
--------------------------------------------------------------------------------
/examples/routers/message.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 显示普通提示
4 | 显示成功提示
5 | 显示警告提示
6 | 显示错误提示
7 | 销毁提示
8 |
9 |
10 |
39 |
--------------------------------------------------------------------------------
/src/styles/common/article.less:
--------------------------------------------------------------------------------
1 | .ivu-article {
2 | h1{
3 | font-size: 26px;
4 | font-weight: normal;
5 | }
6 | h2{
7 | font-size: 20px;
8 | font-weight: normal;
9 | }
10 | h3{
11 | font-size: 16px;
12 | font-weight: normal;
13 | }
14 | h4{
15 | font-size: 14px;
16 | font-weight: normal;
17 | }
18 | h5{
19 | font-size: 12px;
20 | font-weight: normal;
21 | }
22 | h6{
23 | font-size: 12px;
24 | font-weight: normal;
25 | }
26 |
27 | blockquote{
28 | padding: 5px 5px 3px 10px;
29 | line-height: 1.5;
30 | border-left: 4px solid #ddd;
31 | margin-bottom: 20px;
32 | color: #666;
33 | font-size: 14px;
34 | }
35 |
36 | ul:not([class^="ivu-"]){
37 | padding-left: 40px;
38 | list-style-type: disc;
39 | }
40 | li:not([class^="ivu-"]){
41 | margin-bottom: 5px;
42 | font-size: 14px;
43 | }
44 | ul ul:not([class^="ivu-"]), ol ul:not([class^="ivu-"]){
45 | list-style-type: circle;
46 | }
47 |
48 | p{
49 | margin: 5px;
50 | font-size: 14px;
51 | }
52 |
53 | a[target="_blank"]:after{
54 | content: "\F220";
55 | font-family: Ionicons;
56 | color: #aaa;
57 | margin-left: 3px;
58 | }
59 | }
--------------------------------------------------------------------------------
/src/locale/format.js:
--------------------------------------------------------------------------------
1 | /**
2 | * String format template
3 | * - Inspired:
4 | * https://github.com/Matt-Esch/string-template/index.js
5 | */
6 |
7 | const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
8 |
9 | export default function() {
10 | // const { hasOwn } = Vue.util;
11 | function hasOwn (obj, key) {
12 | return Object.prototype.hasOwnProperty.call(obj, key);
13 | }
14 |
15 | /**
16 | * template
17 | *
18 | * @param {String} string
19 | * @param {Array} ...args
20 | * @return {String}
21 | */
22 |
23 | function template(string, ...args) {
24 | if (args.length === 1 && typeof args[0] === 'object') {
25 | args = args[0];
26 | }
27 |
28 | if (!args || !args.hasOwnProperty) {
29 | args = {};
30 | }
31 |
32 | return string.replace(RE_NARGS, (match, prefix, i, index) => {
33 | let result;
34 |
35 | if (string[index - 1] === '{' &&
36 | string[index + match.length] === '}') {
37 | return i;
38 | } else {
39 | result = hasOwn(args, i) ? args[i] : null;
40 | if (result === null || result === undefined) {
41 | return '';
42 | }
43 |
44 | return result;
45 | }
46 | });
47 | }
48 |
49 | return template;
50 | }
51 |
--------------------------------------------------------------------------------
/src/components/transfer/search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
49 |
--------------------------------------------------------------------------------
/src/styles/components/collapse.less:
--------------------------------------------------------------------------------
1 | @collapse-prefix-cls: ~"@{css-prefix}collapse";
2 |
3 | .@{collapse-prefix-cls}{
4 | background-color: @background-color-base;
5 | border-radius: 3px;
6 | border: 1px solid @border-color-base;
7 |
8 | & > &-item{
9 | border-top: 1px solid @border-color-base;
10 | &:first-child {
11 | border-top: 0;
12 | }
13 |
14 | > .@{collapse-prefix-cls}-header{
15 | height: 38px;
16 | line-height: 38px;
17 | padding-left: 32px;
18 | color: #666;
19 | cursor: pointer;
20 | position: relative;
21 |
22 | > i{
23 | transition: transform @transition-time @ease-in-out;
24 | }
25 | }
26 | }
27 | & > &-item&-item-active > &-header > i{
28 | transform: rotate(90deg);
29 | }
30 |
31 | &-content{
32 | //display: none;
33 | overflow: hidden;
34 | color: @text-color;
35 | padding: 0 16px;
36 | background-color: #fff;
37 |
38 | & > &-box {
39 | padding-top: 16px;
40 | padding-bottom: 16px;
41 | }
42 | }
43 | &-item-active > &-content{
44 | //display: block;
45 | }
46 | &-item:last-child {
47 | > .@{collapse-prefix-cls}-content {
48 | border-radius: 0 0 3px 3px;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/examples/routers/alert.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
消息提示文案
4 |
成功提示文案
5 |
警告提示文案
6 |
错误提示文案
7 |
8 | 消息提示文案
9 | 消息提示的描述文案消息提示的描述文案消息提示的描述文案消息提示的描述文案消息提示的描述文案
10 |
11 |
12 | 成功提示文案
13 | 成功的提示描述文案成功的提示描述文案成功的提示描述文案成功的提示描述文案成功的提示描述文案
14 |
15 |
16 | 警告提示文案
17 |
18 | 警告的提示描述文案警告的提示描述文案警告的提示描述文案
19 |
20 |
21 |
22 | 错误提示文案
23 |
24 | 自定义错误描述文案。
25 |
26 |
27 |
28 | 自定义图标
29 |
30 | 自定义图标文案自定义图标文案自定义图标文案自定义图标文案自定义图标文案
31 |
32 |
33 |
34 |
40 |
--------------------------------------------------------------------------------
/examples/routers/carousel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 1
7 |
8 |
9 |
10 | 2
11 |
12 |
13 | 3
14 |
15 |
16 | 4
17 |
18 |
19 | {{ v1 }}
20 |
change v1
21 |
22 |
23 |
40 |
--------------------------------------------------------------------------------
/examples/routers/circle.vue:
--------------------------------------------------------------------------------
1 |
35 |
36 |
43 |
44 |
{{ 42001776 }}
45 |
消费人群规模
46 |
47 | 总占人数
48 | 75%
49 |
50 |
51 |
52 |
53 |
58 |
--------------------------------------------------------------------------------
/examples/routers/progress.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | 成功
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
43 |
--------------------------------------------------------------------------------
/src/styles/components/badge.less:
--------------------------------------------------------------------------------
1 | @badge-prefix-cls: ~"@{css-prefix}badge";
2 |
3 | .@{badge-prefix-cls} {
4 | position: relative;
5 | display: inline-block;
6 | line-height: 1;
7 | vertical-align: middle;
8 |
9 | &-count {
10 | position: absolute;
11 | transform: translateX(50%);
12 | top: -10px;
13 | right: 0;
14 | height: 20px;
15 | border-radius: 10px;
16 | min-width: 20px;
17 | background: @error-color;
18 | border: 1px solid transparent;
19 | color: #fff;
20 | line-height: 18px;
21 | text-align: center;
22 | padding: 0 6px;
23 | font-size: 12px;
24 | white-space: nowrap;
25 | transform-origin: -10% center;
26 | z-index: 10;
27 | box-shadow: 0 0 0 1px #fff;
28 |
29 | a,
30 | a:hover {
31 | color: #fff;
32 | }
33 |
34 | &-alone {
35 | top: auto;
36 | display: block;
37 | position: relative;
38 | transform: translateX(0);
39 | }
40 | }
41 |
42 | &-dot {
43 | position: absolute;
44 | transform: translateX(-50%);
45 | transform-origin: 0 center;
46 | top: -4px;
47 | right: -8px;
48 | height: 8px;
49 | width: 8px;
50 | border-radius: 100%;
51 | background: @error-color;
52 | z-index: 10;
53 | box-shadow: 0 0 0 1px #fff;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/locale/index.js:
--------------------------------------------------------------------------------
1 | // https://github.com/ElemeFE/element/blob/dev/src/locale/index.js
2 |
3 | import defaultLang from './lang/zh-CN';
4 | import Vue from 'vue';
5 | import deepmerge from 'deepmerge';
6 | import Format from './format';
7 |
8 | const format = Format(Vue);
9 | let lang = defaultLang;
10 | let merged = false;
11 | let i18nHandler = function() {
12 | const vuei18n = Object.getPrototypeOf(this || Vue).$t;
13 | if (typeof vuei18n === 'function') {
14 | if (!merged) {
15 | merged = true;
16 | Vue.locale(
17 | Vue.config.lang,
18 | deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true })
19 | );
20 | }
21 | return vuei18n.apply(this, arguments);
22 | }
23 | };
24 |
25 | export const t = function(path, options) {
26 | let value = i18nHandler.apply(this, arguments);
27 | if (value !== null && value !== undefined) return value;
28 |
29 | const array = path.split('.');
30 | let current = lang;
31 |
32 | for (let i = 0, j = array.length; i < j; i++) {
33 | const property = array[i];
34 | value = current[property];
35 | if (i === j - 1) return format(value, options);
36 | if (!value) return '';
37 | current = value;
38 | }
39 | return '';
40 | };
41 |
42 | export const use = function(l) {
43 | lang = l || lang;
44 | };
45 |
46 | export const i18n = function(fn) {
47 | i18nHandler = fn || i18nHandler;
48 | };
49 |
50 | export default { use, t, i18n };
--------------------------------------------------------------------------------
/examples/routers/transfer.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
46 |
--------------------------------------------------------------------------------
/src/styles/components/spin.less:
--------------------------------------------------------------------------------
1 | @spin-prefix-cls: ~"@{css-prefix}spin";
2 | @spin-dot-size-small: 12px;
3 | @spin-dot-size: 20px;
4 | @spin-dot-size-large: 32px;
5 |
6 | .@{spin-prefix-cls} {
7 | color: @primary-color;
8 | vertical-align: middle;
9 | text-align: center;
10 |
11 | &-dot {
12 | position: relative;
13 | display: block;
14 | border-radius: 50%;
15 | background-color: @primary-color;
16 | .square(@spin-dot-size);
17 | animation: ani-spin-bounce 1s 0s ease-in-out infinite;
18 | }
19 |
20 | &-large &-dot {
21 | .square(@spin-dot-size-large);
22 | }
23 |
24 | &-small &-dot {
25 | .square(@spin-dot-size-small);
26 | }
27 |
28 | &-fix {
29 | position: absolute;
30 | top: 0;
31 | bottom: 0;
32 | left: 0;
33 | right: 0;
34 | z-index: @zindex-spin;
35 | display: table;
36 | .square(100%);
37 | background-color: #fff;
38 | }
39 |
40 | &-fix &-main {
41 | display: table-cell;
42 | vertical-align: middle;
43 | .square(inherit);
44 | }
45 |
46 | &-fix &-dot {
47 | display: inline-block;
48 | }
49 |
50 | &-text,
51 | &-show-text &-dot {
52 | display: none;
53 | }
54 |
55 | &-show-text &-text {
56 | display: block;
57 | }
58 | }
59 |
60 | @keyframes ani-spin-bounce {
61 | 0% {
62 | transform: scale(0);
63 | }
64 |
65 | 100% {
66 | transform: scale(1);
67 | opacity: 0;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/styles/components/tree.less:
--------------------------------------------------------------------------------
1 | @tree-prefix-cls: ~"@{css-prefix}tree";
2 |
3 | .@{tree-prefix-cls} {
4 | ul{
5 | list-style: none;
6 | margin: 0;
7 | padding: 0;
8 | font-size: @font-size-small;
9 | li{
10 | list-style: none;
11 | margin: 8px 0;
12 | padding: 0;
13 | white-space: nowrap;
14 | outline: none;
15 | }
16 | }
17 | li{
18 | ul{
19 | margin: 0;
20 | padding: 0 0 0 18px;
21 | }
22 | }
23 | &-title {
24 | display: inline-block;
25 | margin: 0;
26 | padding: 0 4px;
27 | border-radius: @btn-border-radius-small;
28 | cursor: pointer;
29 | vertical-align: top;
30 | color: @text-color;
31 | transition: all @transition-time @ease-in-out;
32 | &:hover {
33 | background-color: tint(@primary-color, 90%);
34 | }
35 | &-selected, &-selected:hover{
36 | background-color: tint(@primary-color, 80%);
37 | }
38 | }
39 | &-arrow{
40 | cursor: pointer;
41 | i{
42 | transition: all @transition-time @ease-in-out;
43 | }
44 | &-open{
45 | i {
46 | transform: rotate(90deg);
47 | }
48 | }
49 | &-hidden{
50 | cursor: auto;
51 | i{
52 | display: none;
53 | }
54 | }
55 | &-disabled{
56 | cursor: @cursor-disabled;
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/src/components/select/option-group.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ label }}
4 |
7 |
8 |
9 |
49 |
--------------------------------------------------------------------------------
/src/components/tabs/pane.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
61 |
--------------------------------------------------------------------------------
/src/components/modal/index.js:
--------------------------------------------------------------------------------
1 | import Modal from './confirm';
2 |
3 | let modalInstance;
4 |
5 | function getModalInstance (render = undefined) {
6 | modalInstance = modalInstance || Modal.newInstance({
7 | closable: false,
8 | maskClosable: false,
9 | footerHide: true,
10 | render: render
11 | });
12 |
13 | return modalInstance;
14 | }
15 |
16 | function confirm (options) {
17 | const render = ('render' in options) ? options.render : undefined;
18 | let instance = getModalInstance(render);
19 |
20 | options.onRemove = function () {
21 | modalInstance = null;
22 | };
23 |
24 | instance.show(options);
25 | }
26 |
27 | Modal.info = function (props = {}) {
28 | props.icon = 'info';
29 | props.showCancel = false;
30 | return confirm(props);
31 | };
32 |
33 | Modal.success = function (props = {}) {
34 | props.icon = 'success';
35 | props.showCancel = false;
36 | return confirm(props);
37 | };
38 |
39 | Modal.warning = function (props = {}) {
40 | props.icon = 'warning';
41 | props.showCancel = false;
42 | return confirm(props);
43 | };
44 |
45 | Modal.error = function (props = {}) {
46 | props.icon = 'error';
47 | props.showCancel = false;
48 | return confirm(props);
49 | };
50 |
51 | Modal.confirm = function (props = {}) {
52 | props.icon = 'confirm';
53 | props.showCancel = true;
54 | return confirm(props);
55 | };
56 |
57 | Modal.remove = function () {
58 | if (!modalInstance) { // at loading status, remove after Cancel
59 | return false;
60 | }
61 |
62 | const instance = getModalInstance();
63 |
64 | instance.remove();
65 | };
66 |
67 | export default Modal;
--------------------------------------------------------------------------------
/examples/routers/menu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 内容管理
7 |
8 |
9 |
10 | 用户管理
11 |
12 |
13 |
14 |
15 | 统计分析
16 |
17 |
18 | 新增和启动
19 | 活跃分析
20 | 时段分析
21 |
22 |
23 | 用户留存
24 | 流失用户
25 |
26 |
27 |
28 |
29 | 综合设置
30 |
31 |
32 |
33 |
切换主题
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
50 |
--------------------------------------------------------------------------------
/CHANGE.md:
--------------------------------------------------------------------------------
1 | ### Button
2 | 可以考虑是否支持 @click,而不用 @click.native
3 | ### Input
4 | 使用 v-model,增加 on-input-change // todo 考虑更名
5 | ### RadioGroup
6 | 使用 v-model
7 | ### Radio
8 | value 改为了 label,使用 v-model,废弃 checked
9 | ### Checkbox
10 | 使用 v-model
11 | ### CheckboxGroup
12 | value 改为了 label,使用 v-model,废弃 checked
13 | ### Switch
14 | 废弃checked, 改为了 value,使用 v-model
15 | ### Badge
16 | class 改为了 className
17 | ### InputNumber
18 | 使用 v-model
19 | ### Progress (名称有警告)
20 | 新增 on-status-change 事件
21 | ### Upload
22 | 父级不能 computed Upload 的 fileList 了
23 | ### Collapse
24 | 废弃 activeKey,使用 v-model,key 是保留的,更名为 name
25 | ### Carousel
26 | 废弃 activeIndex,使用 v-model,v-for="n in slides.length",Vue2的数字循环,是从1开始的
27 | ### Tree
28 | 废弃 data,改为 value,使用 v-model,key 更名为 name,不能再 template 的prop 上使用 this
29 | ### Circle
30 | 改名为 iCircle
31 | ### Tabs
32 | 废弃 activeKey,改用 value,使用 v-model,key 更名为 name
33 | ### popper.js 将 prop: visible 移至 data 里
34 | ### Slider
35 | 支持 v-model
36 | ### Dropdown
37 | DropdownItem key 改为 name, Dropdown 的 visible 要使用 @on-visible-change 捕获,不再 sync
38 | DropdownItem 里,this.$parent.$parent 与1.0 有区别
39 | ### Menu
40 | MenuItem 和 Submenu 的 key 改为了 name
41 | Menu 的 activeKey 改为 activeName,openKeys 改为 openNames
42 | ### Cascader
43 | Caspanel 的 sublist 从 prop -> data
44 | ### Select
45 | model 改为 value,支持 v-model
46 | ### Page
47 | class 改为 className
48 | ### DatePicker
49 | 使用 v-model
50 | ### LoadingBar
51 | 部分 prop 移至 data
52 | ### Modal
53 | visible 改为 value,使用 v-model,style 改为 styles,$Modal 的关闭有改动,建议后面在纯 html 模式下测试
54 | ### Table
55 | i-table 改为 Table
56 | ### Message
57 | notice.vue 的 key 改为了 name,style 改为 styles
58 | notification.vue 的 key 改为了 name,style 改为 styles
59 | ## Popper
60 | 移除了 visible,使用 value 受控,可能涉及到的组件:Poptip、Tooltip
--------------------------------------------------------------------------------
/src/styles/common/base.less:
--------------------------------------------------------------------------------
1 | @import "normalize";
2 |
3 | * {
4 | box-sizing: border-box;
5 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
6 | }
7 |
8 | *:before,
9 | *:after {
10 | box-sizing: border-box;
11 | }
12 |
13 | body {
14 | font-family: @font-family;
15 | font-size: @font-size-small;
16 | line-height: @line-height-base;
17 | color: @text-color;
18 | background-color: @body-background;
19 | -webkit-font-smoothing: antialiased;
20 | -moz-osx-font-smoothing: grayscale;
21 | }
22 |
23 | body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
24 | margin: 0;
25 | padding: 0;
26 | }
27 |
28 | button, input, select, textarea {
29 | font-family: inherit;
30 | font-size: inherit;
31 | line-height: inherit;
32 | }
33 |
34 | ul,
35 | ol {
36 | list-style: none;
37 | }
38 |
39 | input::-ms-clear, input::-ms-reveal {
40 | display: none;
41 | }
42 |
43 | a {
44 | color: @link-color;
45 | background: transparent;
46 | text-decoration: none;
47 | outline: none;
48 | cursor: pointer;
49 | transition: color @transition-time ease;
50 |
51 | &:hover {
52 | color: @link-hover-color;
53 | }
54 |
55 | &:active {
56 | color: @link-active-color;
57 | }
58 |
59 | &:active,
60 | &:hover {
61 | outline: 0;
62 | text-decoration: none;
63 | }
64 |
65 | &[disabled] {
66 | color: #ccc;
67 | cursor: @cursor-disabled;
68 | pointer-events: none;
69 | }
70 | }
71 |
72 | code,
73 | kbd,
74 | pre,
75 | samp {
76 | font-family: @code-family;
77 | }
78 |
--------------------------------------------------------------------------------
/src/utils/csv.js:
--------------------------------------------------------------------------------
1 | // https://github.com/Terminux/react-csv-downloader/blob/master/src/lib/csv.js
2 |
3 | const newLine = '\r\n';
4 |
5 | export default function csv(columns, datas, separator = ',', noHeader = false) {
6 | let columnOrder;
7 | const content = [];
8 | const column = [];
9 |
10 | if (columns) {
11 | columnOrder = columns.map(v => {
12 | if (typeof v === 'string') {
13 | return v;
14 | }
15 | if (!noHeader) {
16 | column.push((typeof v.title !== 'undefined') ? v.title : v.key);
17 | }
18 | return v.key;
19 | });
20 | if (column.length > 0) {
21 | content.push(column.join(separator));
22 | }
23 | } else {
24 | columnOrder = [];
25 | datas.forEach(v => {
26 | if (!Array.isArray(v)) {
27 | columnOrder = columnOrder.concat(Object.keys(v));
28 | }
29 | });
30 | if (columnOrder.length > 0) {
31 | columnOrder = columnOrder.filter((value, index, self) => self.indexOf(value) === index);
32 |
33 | if (!noHeader) {
34 | content.push(columnOrder.join(separator));
35 | }
36 | }
37 | }
38 |
39 | if (Array.isArray(datas)) {
40 | datas.map(v => {
41 | if (Array.isArray(v)) {
42 | return v;
43 | }
44 | return columnOrder.map(k => {
45 | if (typeof v[k] !== 'undefined') {
46 | return v[k];
47 | }
48 | return '';
49 | });
50 | }).forEach(v => {
51 | content.push(v.join(separator));
52 | });
53 | }
54 | return content.join(newLine);
55 | }
--------------------------------------------------------------------------------
/src/components/date-picker/base/confirm.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ t('i.datepicker.selectDate') }}
5 | {{ t('i.datepicker.selectTime') }}
6 |
7 | {{ t('i.datepicker.clear') }}
8 | {{ t('i.datepicker.ok') }}
9 |
10 |
11 |
51 |
--------------------------------------------------------------------------------
/src/components/breadcrumb/breadcrumb-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
58 |
--------------------------------------------------------------------------------
/src/components/spin/spin.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
60 |
--------------------------------------------------------------------------------
/examples/routers/notice.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
带描述信息
4 |
消息
5 |
成功
6 |
警告
7 |
错误
8 |
仅标题
9 |
消息
10 |
成功
11 |
警告
12 |
错误
13 |
销毁
14 |
15 |
16 |
49 |
--------------------------------------------------------------------------------
/src/styles/components/rate.less:
--------------------------------------------------------------------------------
1 | @rate-prefix-cls: ~"@{css-prefix}rate";
2 |
3 | .@{rate-prefix-cls} {
4 | display: inline-block;
5 | margin: 0;
6 | padding: 0;
7 | font-size: 20px;
8 | vertical-align: middle;
9 | font-weight: normal;
10 | font-style: normal;
11 |
12 | &-disabled &-star {
13 | &:before,
14 | &-content:before {
15 | cursor: default;
16 | }
17 | &:hover {
18 | transform: scale(1);
19 | }
20 | }
21 |
22 | &-star {
23 | display: inline-block;
24 | margin: 0;
25 | padding: 0;
26 | margin-right: 8px;
27 | position: relative;
28 | font-family: 'Ionicons';
29 | transition: all 0.3s ease;
30 |
31 | &:hover {
32 | transform: scale(1.1);
33 | }
34 |
35 | &:before,
36 | &-content:before {
37 | color: #e9e9e9;
38 | cursor: pointer;
39 | content: "\F4B3";
40 | transition: all @transition-time @ease-in-out;
41 | display: block;
42 | }
43 |
44 | &-content {
45 | position: absolute;
46 | left: 0;
47 | top: 0;
48 | width: 50%;
49 | height: 100%;
50 | overflow: hidden;
51 | &:before {
52 | color: transparent;
53 | }
54 | }
55 |
56 | &-half &-content:before,
57 | &-full:before {
58 | color: @rate-star-color;
59 | }
60 |
61 | &-half:hover &-content:before,
62 | &-full:hover:before {
63 | color: tint(@rate-star-color, 20%);
64 | }
65 | }
66 | &-text {
67 | margin-left: 8px;
68 | vertical-align: middle;
69 | display: inline-block;
70 | font-size: @font-size-small;
71 | }
72 | }
--------------------------------------------------------------------------------
/src/styles/components/message.less:
--------------------------------------------------------------------------------
1 | @message-prefix-cls: ~"@{css-prefix}message";
2 | @icon-prefix-cls: ~"@{css-prefix}icon";
3 |
4 | .@{message-prefix-cls} {
5 | font-size: @font-size-small;
6 | position: fixed;
7 | z-index: @zindex-message;
8 | width: 100%;
9 | top: 16px;
10 | left: 0;
11 |
12 | &-notice {
13 | width: auto;
14 | vertical-align: middle;
15 | position: absolute;
16 | left: 50%;
17 |
18 | &-close {
19 | position: absolute;
20 | right: 4px;
21 | top: 9px;
22 | color: #999;
23 | outline: none;
24 |
25 | i.@{icon-prefix-cls}{
26 | .close-base(-3px);
27 | }
28 | }
29 | }
30 |
31 | &-notice-content {
32 | position: relative;
33 | right: 50%;
34 | padding: 8px 16px;
35 | //border: 1px solid @border-color-split;
36 | border-radius: @border-radius-small;
37 | box-shadow: @shadow-base;
38 | background: #fff;
39 | display: block;
40 | &-text{
41 | display: inline-block;
42 | }
43 | }
44 |
45 | &-notice-closable{
46 | .@{message-prefix-cls}-notice-content-text{
47 | padding-right: 32px;
48 | }
49 | }
50 |
51 | &-success .@{icon-prefix-cls} {
52 | color: @success-color;
53 | }
54 |
55 | &-error .@{icon-prefix-cls} {
56 | color: @error-color;
57 | }
58 |
59 | &-warning .@{icon-prefix-cls} {
60 | color: @warning-color;
61 | }
62 |
63 | &-info .@{icon-prefix-cls},
64 | &-loading .@{icon-prefix-cls} {
65 | color: @primary-color;
66 | }
67 |
68 | .@{icon-prefix-cls} {
69 | margin-right: 8px;
70 | font-size: 14px;
71 | top: 1px;
72 | position: relative;
73 | }
74 | }
--------------------------------------------------------------------------------
/src/styles/components/form.less:
--------------------------------------------------------------------------------
1 | @form-prefix-cls: ~"@{css-prefix}form";
2 | @form-item-prefix-cls: ~"@{form-prefix-cls}-item";
3 |
4 | .@{form-prefix-cls} {
5 | .@{form-item-prefix-cls}-label {
6 | text-align: right;
7 | vertical-align: middle;
8 | float: left;
9 | font-size: @font-size-small;
10 | color: @text-color;
11 | line-height: 1;
12 | padding: 10px 12px 10px 0;
13 | box-sizing: border-box;
14 | }
15 | &-label-left .@{form-item-prefix-cls}-label {
16 | text-align: left;
17 | }
18 | &-label-top .@{form-item-prefix-cls}-label {
19 | float: none;
20 | display: inline-block;
21 | padding: 0 0 10px 0;
22 | }
23 | &-inline{
24 | .@{form-item-prefix-cls} {
25 | display: inline-block;
26 | margin-right: 10px;
27 | vertical-align: top;
28 | }
29 | }
30 | }
31 |
32 | .@{form-item-prefix-cls} {
33 | margin-bottom: 24px;
34 | vertical-align: top;
35 | .clearfix();
36 | &-content {
37 | position: relative;
38 | line-height: 32px;
39 | font-size: @font-size-small;
40 | }
41 | & & {
42 | margin-bottom: 0;
43 | }
44 | & & &-content {
45 | margin-left: 0!important;
46 | }
47 |
48 | &-error-tip{
49 | position: absolute;
50 | top: 100%;
51 | left: 0;
52 | line-height: 1;
53 | padding-top: 6px;
54 | color: @error-color;
55 | }
56 |
57 | &-required {
58 | .@{form-item-prefix-cls}-label:before {
59 | content: '*';
60 | display: inline-block;
61 | margin-right: 4px;
62 | line-height: 1;
63 | font-family: SimSun;
64 | font-size: @font-size-small;
65 | color: @error-color;
66 | }
67 | }
68 | &-error {
69 | // todo
70 | }
71 | }
--------------------------------------------------------------------------------
/examples/routers/more.vue:
--------------------------------------------------------------------------------
1 |
17 |
18 | 距离顶部 20px
19 |
23 | 对话框内容
24 | 对话框内容
25 | 对话框内容
26 |
27 | 垂直居中
28 |
32 | 对话框内容
33 | 对话框内容
34 | 对话框内容
35 |
36 | Create Instance Scrollable
37 | Create Instance Non-scrollable
38 |
39 |
40 |
68 |
--------------------------------------------------------------------------------
/src/components/collapse/panel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
62 |
--------------------------------------------------------------------------------
/src/styles/common/layout.less:
--------------------------------------------------------------------------------
1 | .@{row-prefix-cls} {
2 | .make-row();
3 | display: block;
4 |
5 | &-flex {
6 | display: flex;
7 | flex-direction: row;
8 | flex-wrap: wrap;
9 |
10 | &:before,
11 | &:after {
12 | display: flex;
13 | }
14 | // x轴原点
15 | &-start {
16 | justify-content: flex-start;
17 | }
18 | // x轴居中
19 | &-center {
20 | justify-content: center;
21 | }
22 | // x轴反方向
23 | &-end {
24 | justify-content: flex-end;
25 | }
26 | // x轴平分
27 | &-space-between {
28 | justify-content: space-between;
29 | }
30 | // x轴有间隔地平分
31 | &-space-around {
32 | justify-content: space-around;
33 | }
34 | // 顶部对齐
35 | &-top {
36 | align-items: flex-start;
37 | }
38 | // 居中对齐
39 | &-middle {
40 | align-items: center;
41 | }
42 | // 底部对齐
43 | &-bottom {
44 | align-items: flex-end;
45 | }
46 | };
47 | }
48 |
49 | .@{col-prefix-cls} {
50 | position: relative;
51 | display: block;
52 | }
53 |
54 | .make-grid();
55 |
56 | // Extra small grid
57 | //
58 | // Columns, offsets, pushes, and pulls for extra small devices like
59 | // smartphones.
60 |
61 | .make-grid(-xs);
62 |
63 | // Small grid
64 | //
65 | // Columns, offsets, pushes, and pulls for the small device range, from phones
66 | // to tablets.
67 |
68 | @media (min-width: @screen-sm-min) {
69 | .make-grid(-sm);
70 | }
71 |
72 |
73 | // Medium grid
74 | //
75 | // Columns, offsets, pushes, and pulls for the desktop device range.
76 |
77 | @media (min-width: @screen-md-min) {
78 | .make-grid(-md);
79 | }
80 |
81 |
82 | // Large grid
83 | //
84 | // Columns, offsets, pushes, and pulls for the large desktop device range.
85 |
86 | @media (min-width: @screen-lg-min) {
87 | .make-grid(-lg);
88 | }
89 |
--------------------------------------------------------------------------------
/src/components/dropdown/dropdown-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
59 |
--------------------------------------------------------------------------------
/examples/routers/timeline.vue:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 | 1976年
15 | Apple I 问世
16 |
17 |
18 | 1984年
19 | 发布 Macintosh
20 |
21 |
22 | 2007年
23 | 发布 iPhone
24 |
25 |
26 | 2010年
27 | 发布 iPad
28 |
29 |
30 | 2011年10月5日
31 | 史蒂夫·乔布斯去世
32 |
33 |
34 |
35 | 发布1.0版本
36 | 发布2.0版本
37 | 严重故障
38 | 发布3.0版本
39 |
40 |
41 | 发布1.0版本
42 | 发布2.0版本
43 | 发布3.0版本
44 | 查看更多
45 |
46 |
47 |
48 |
49 | 发布里程碑版本
50 |
51 | 发布1.0版本
52 | 发布2.0版本
53 | 发布3.0版本
54 |
55 |
56 |
57 |
62 |
--------------------------------------------------------------------------------
/src/components/checkbox/checkbox-group.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
66 |
--------------------------------------------------------------------------------
/src/styles/mixins/select.less:
--------------------------------------------------------------------------------
1 | .select-item(@size-class, @item-class) {
2 | .@{item-class} {
3 | margin: 0;
4 | line-height: normal;
5 | padding: 7px 16px;
6 | clear: both;
7 | color: @text-color;
8 | font-size: @font-size-small !important;
9 | white-space: nowrap;
10 | list-style: none;
11 | cursor: pointer;
12 | transition: background @transition-time @ease-in-out;
13 |
14 | &:hover{
15 | background: @background-color-select-hover;
16 | }
17 |
18 | &-focus {
19 | background: @background-color-select-hover;
20 | }
21 |
22 | &-disabled {
23 | color: @btn-disable-color;
24 | cursor: @cursor-disabled;
25 |
26 | &:hover {
27 | color: @btn-disable-color;
28 | background-color: #fff;
29 | cursor: @cursor-disabled;
30 | }
31 | }
32 |
33 | &-selected ,&-selected:hover{
34 | color: #fff;
35 | background: @selected-color;
36 | }
37 |
38 | &-selected&-focus {
39 | background: shade(@selected-color, 10%);
40 | }
41 |
42 | &-divided{
43 | margin-top: 5px;
44 | border-top: 1px solid @border-color-split;
45 | &:before{
46 | content: '';
47 | height: 5px;
48 | display: block;
49 | margin: 0 -16px;
50 | background-color: #fff;
51 | position: relative;
52 | top: -7px;
53 | }
54 | }
55 | }
56 |
57 | .@{size-class}-large .@{item-class} {
58 | padding: 7px 16px 8px;
59 | font-size: @font-size-base !important;
60 | }
61 | // http://browserhacks.com/
62 | // https://bugzilla.mozilla.org/show_bug.cgi?id=488725
63 | // fixed #1224 #1143 #1127
64 | @-moz-document url-prefix() {
65 | .@{item-class} {
66 | white-space: normal;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/styles/mixins/layout.less:
--------------------------------------------------------------------------------
1 | @row-prefix-cls: ~"@{css-prefix}row";
2 | @col-prefix-cls: ~"@{css-prefix}col";
3 |
4 | .make-row(@gutter: @grid-gutter-width) {
5 | position: relative;
6 | margin-left: (@gutter / -2);
7 | margin-right: (@gutter / -2);
8 | height: auto;
9 | .clearfix;
10 | }
11 |
12 | .float-grid-columns(@class) {
13 | .col(@index) { // initial
14 | @item: ~".@{col-prefix-cls}-span@{class}-@{index}";
15 | .col((@index + 1), @item);
16 | }
17 | .col(@index, @list) when (@index =< @grid-columns) { // general
18 | @item: ~".@{col-prefix-cls}-span@{class}-@{index}";
19 | .col((@index + 1), ~"@{list}, @{item}");
20 | }
21 | .col(@index, @list) when (@index > @grid-columns) { // terminal
22 | @{list} {
23 | float: left;
24 | flex: 0 0 auto;
25 | }
26 | }
27 | .col(1); // kickstart it
28 | }
29 |
30 | .loop-grid-columns(@index, @class) when (@index > 0) {
31 | .@{col-prefix-cls}-span@{class}-@{index} {
32 | display: block;
33 | width: percentage((@index / @grid-columns));
34 | }
35 | .@{col-prefix-cls}@{class}-push-@{index} {
36 | left: percentage((@index / @grid-columns));
37 | }
38 | .@{col-prefix-cls}@{class}-pull-@{index} {
39 | right: percentage((@index / @grid-columns));
40 | }
41 | .@{col-prefix-cls}@{class}-offset-@{index} {
42 | margin-left: percentage((@index / @grid-columns));
43 | }
44 | .@{col-prefix-cls}@{class}-order-@{index} {
45 | order: @index;
46 | }
47 | .loop-grid-columns((@index - 1), @class);
48 | }
49 |
50 | .loop-grid-columns(@index, @class) when (@index = 0) {
51 | .@{col-prefix-cls}-span@{class}-@{index} {
52 | display: none;
53 | }
54 | .@{col-prefix-cls}@{class}-push-@{index} {
55 | left: auto;
56 | }
57 | .@{col-prefix-cls}@{class}-pull-@{index} {
58 | right: auto;
59 | }
60 | }
61 |
62 | .make-grid(@class: ~'') {
63 | .float-grid-columns(@class);
64 | .loop-grid-columns(@grid-columns, @class);
65 | }
--------------------------------------------------------------------------------
/src/components/table/mixin.js:
--------------------------------------------------------------------------------
1 | export default {
2 | methods: {
3 | alignCls (column, row = {}) {
4 | let cellClassName = '';
5 | if (row.cellClassName && column.key && row.cellClassName[column.key]) {
6 | cellClassName = row.cellClassName[column.key];
7 | }
8 | return [
9 | {
10 | [`${cellClassName}`]: cellClassName, // cell className
11 | [`${column.className}`]: column.className, // column className
12 | [`${this.prefixCls}-column-${column.align}`]: column.align,
13 | [`${this.prefixCls}-hidden`]: (this.fixed === 'left' && column.fixed !== 'left') || (this.fixed === 'right' && column.fixed !== 'right') || (!this.fixed && column.fixed && (column.fixed === 'left' || column.fixed === 'right'))
14 | }
15 | ];
16 | },
17 | isPopperShow (column) {
18 | return column.filters && ((!this.fixed && !column.fixed) || (this.fixed === 'left' && column.fixed === 'left') || (this.fixed === 'right' && column.fixed === 'right'));
19 | },
20 | setCellWidth (column, index, top) {
21 | let width = '';
22 | if (column.width) {
23 | width = column.width;
24 | } else if (this.columnsWidth[column._index]) {
25 | width = this.columnsWidth[column._index].width;
26 | }
27 | // when browser has scrollBar,set a width to resolve scroll position bug
28 | if (this.columns.length === index + 1 && top && this.$parent.bodyHeight !== 0) {
29 | width += this.$parent.scrollBarWidth;
30 | }
31 | // when fixed type,reset first right fixed column's width
32 | if (this.fixed === 'right') {
33 | const firstFixedIndex = this.columns.findIndex((col) => col.fixed === 'right');
34 | if (firstFixedIndex === index) width += this.$parent.scrollBarWidth;
35 | }
36 | if (width === '0') width = '';
37 | return width;
38 | }
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/examples/routers/tree.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
60 |
--------------------------------------------------------------------------------
/src/components/timeline/timeline-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
67 |
--------------------------------------------------------------------------------
/src/styles/components/input.less:
--------------------------------------------------------------------------------
1 | @input-prefix-cls: ~"@{css-prefix}input";
2 |
3 | .@{input-prefix-cls} {
4 | .input;
5 | &-wrapper{
6 | display: inline-block;
7 | width: 100%;
8 | position: relative;
9 | vertical-align: middle;
10 | }
11 | &-icon {
12 | width: 32px;
13 | height: @input-height-base;
14 | line-height: @input-height-base;
15 | font-size: 16px;
16 | text-align: center;
17 | color: @subsidiary-color;
18 | position: absolute;
19 | right: 0;
20 | z-index: 3;
21 | }
22 | &-hide-icon &-icon{
23 | display: none;
24 | }
25 | &-icon-validate{
26 | display: none;
27 | }
28 |
29 | &-icon-normal + &{
30 | padding-right: 32px;
31 | }
32 | // #554
33 | &-hide-icon &-icon-normal + &{
34 | padding-right: @input-padding-horizontal;
35 | }
36 |
37 | &-wrapper-large &-icon{
38 | font-size: 18px;
39 | height: @input-height-large;
40 | line-height: @input-height-large;
41 | }
42 | &-wrapper-small &-icon{
43 | width: 24px;
44 | font-size: 14px;
45 | height: @input-height-small;
46 | line-height: @input-height-small;
47 |
48 | //+ .@{input-prefix-cls} {
49 | // padding-right: 24px;
50 | //}
51 | }
52 | }
53 |
54 | .@{input-prefix-cls}-group{
55 | .input-group(~"@{input-prefix-cls}");
56 | }
57 |
58 | .@{form-item-prefix-cls}-error{
59 | .@{input-prefix-cls}{
60 | .input-error;
61 | &-icon{
62 | color: @error-color;
63 | }
64 | }
65 | .@{input-prefix-cls}-group{
66 | .input-group-error;
67 | }
68 | .@{transfer-prefix-cls} {
69 | .@{input-prefix-cls} {
70 | .input;
71 | &-icon{
72 | color: @subsidiary-color;
73 | }
74 | }
75 | }
76 | }
77 | .@{form-item-prefix-cls}-validating{
78 | .@{input-prefix-cls}{
79 | &-icon-validate{
80 | display: inline-block;
81 | }
82 | &-icon + .@{input-prefix-cls}{
83 | padding-right: 32px;
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/src/components/tag/tag.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
68 |
--------------------------------------------------------------------------------
/src/components/menu/menu-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
68 |
--------------------------------------------------------------------------------
/src/components/badge/badge.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ finalCount }}
9 |
10 |
11 |
71 |
--------------------------------------------------------------------------------
/src/components/switch/switch.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
73 |
--------------------------------------------------------------------------------
/src/components/upload/ajax.js:
--------------------------------------------------------------------------------
1 | // https://github.com/ElemeFE/element/blob/dev/packages/upload/src/ajax.js
2 |
3 | function getError(action, option, xhr) {
4 | const msg = `fail to post ${action} ${xhr.status}'`;
5 | const err = new Error(msg);
6 | err.status = xhr.status;
7 | err.method = 'post';
8 | err.url = action;
9 | return err;
10 | }
11 |
12 | function getBody(xhr) {
13 | const text = xhr.responseText || xhr.response;
14 | if (!text) {
15 | return text;
16 | }
17 |
18 | try {
19 | return JSON.parse(text);
20 | } catch (e) {
21 | return text;
22 | }
23 | }
24 |
25 | export default function upload(option) {
26 | if (typeof XMLHttpRequest === 'undefined') {
27 | return;
28 | }
29 |
30 | const xhr = new XMLHttpRequest();
31 | const action = option.action;
32 |
33 | if (xhr.upload) {
34 | xhr.upload.onprogress = function progress(e) {
35 | if (e.total > 0) {
36 | e.percent = e.loaded / e.total * 100;
37 | }
38 | option.onProgress(e);
39 | };
40 | }
41 |
42 | const formData = new FormData();
43 |
44 | if (option.data) {
45 | Object.keys(option.data).map(key => {
46 | formData.append(key, option.data[key]);
47 | });
48 | }
49 |
50 | formData.append(option.filename, option.file);
51 |
52 | xhr.onerror = function error(e) {
53 | option.onError(e);
54 | };
55 |
56 | xhr.onload = function onload() {
57 | if (xhr.status < 200 || xhr.status >= 300) {
58 | return option.onError(getError(action, option, xhr), getBody(xhr));
59 | }
60 |
61 | option.onSuccess(getBody(xhr));
62 | };
63 |
64 | xhr.open('post', action, true);
65 |
66 | if (option.withCredentials && 'withCredentials' in xhr) {
67 | xhr.withCredentials = true;
68 | }
69 |
70 | const headers = option.headers || {};
71 |
72 | // if (headers['X-Requested-With'] !== null) {
73 | // xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
74 | // }
75 |
76 | for (let item in headers) {
77 | if (headers.hasOwnProperty(item) && headers[item] !== null) {
78 | xhr.setRequestHeader(item, headers[item]);
79 | }
80 | }
81 | xhr.send(formData);
82 | }
83 |
--------------------------------------------------------------------------------
/test/unit/util.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import iView from '../../src/index';
3 |
4 | Vue.use(iView);
5 |
6 | let id = 0;
7 |
8 | const createElm = function() {
9 | const elm = document.createElement('div');
10 |
11 | elm.id = 'app' + ++id;
12 | document.body.appendChild(elm);
13 |
14 | return elm;
15 | };
16 |
17 | /**
18 | * 回收 vm
19 | * @param {Object} vm
20 | */
21 | exports.destroyVM = function(vm) {
22 | vm.$el &&
23 | vm.$el.parentNode &&
24 | vm.$el.parentNode.removeChild(vm.$el);
25 | };
26 |
27 | /**
28 | * 创建一个 Vue 的实例对象
29 | * @param {Object|String} Compo 组件配置,可直接传 template
30 | * @param {Boolean=false} mounted 是否添加到 DOM 上
31 | * @return {Object} vm
32 | */
33 | exports.createVue = function(Compo, mounted = false) {
34 | const elm = createElm();
35 |
36 | if (Object.prototype.toString.call(Compo) === '[object String]') {
37 | Compo = { template: Compo };
38 | }
39 | return new Vue(Compo).$mount(mounted === false ? null : elm);
40 | };
41 |
42 | /**
43 | * 创建一个测试组件实例
44 | * @link http://vuejs.org/guide/unit-testing.html#Writing-Testable-Components
45 | * @param {Object} Compo - 组件对象
46 | * @param {Object} propsData - props 数据
47 | * @param {Boolean=false} mounted - 是否添加到 DOM 上
48 | * @return {Object} vm
49 | */
50 | exports.createTest = function(Compo, propsData = {}, mounted = false) {
51 | if (propsData === true || propsData === false) {
52 | mounted = propsData;
53 | propsData = {};
54 | }
55 | const elm = createElm();
56 | const Ctor = Vue.extend(Compo);
57 | return new Ctor({ propsData }).$mount(mounted === false ? null : elm);
58 | };
59 |
60 | /**
61 | * 触发一个事件
62 | * mouseenter, mouseleave, mouseover, keyup, change, click 等
63 | * @param {Element} elm
64 | * @param {String} name
65 | * @param {*} opts
66 | */
67 | exports.triggerEvent = function(elm, name, ...opts) {
68 | let eventName;
69 |
70 | if (/^mouse|click/.test(name)) {
71 | eventName = 'MouseEvents';
72 | } else if (/^key/.test(name)) {
73 | eventName = 'KeyboardEvent';
74 | } else {
75 | eventName = 'HTMLEvents';
76 | }
77 | const evt = document.createEvent(eventName);
78 |
79 | evt.initEvent(name, ...opts);
80 | elm.dispatchEvent
81 | ? elm.dispatchEvent(evt)
82 | : elm.fireEvent('on' + name, evt);
83 |
84 | return elm;
85 | };
86 |
--------------------------------------------------------------------------------
/src/styles/components/upload.less:
--------------------------------------------------------------------------------
1 | @upload-prefix-cls: ~"@{css-prefix}upload";
2 |
3 | .@{upload-prefix-cls} {
4 | input[type="file"]{
5 | display: none;
6 | }
7 |
8 | &-list{
9 | margin-top: 8px;
10 |
11 | &-file{
12 | padding: 4px;
13 | color: @text-color;
14 | border-radius: @border-radius-small;
15 | transition: background-color @transition-time @ease-in-out;
16 | overflow: hidden;
17 | position: relative;
18 |
19 | & > span{
20 | cursor: pointer;
21 | transition: color @transition-time @ease-in-out;
22 | i{
23 | display: inline-block;
24 | width: @font-size-small;
25 | height: @font-size-small;
26 | color: @text-color;
27 | text-align: center;
28 | }
29 | }
30 |
31 | &:hover{
32 | background: @input-disabled-bg;
33 | & > span{
34 | color: @primary-color;
35 | i{
36 | color: @text-color;
37 | }
38 | }
39 | .@{upload-prefix-cls}-list-remove{
40 | opacity: 1;
41 | }
42 | }
43 | }
44 | &-remove{
45 | opacity: 0;
46 | font-size: 18px;
47 | cursor: pointer;
48 | float: right;
49 | margin-right: 4px;
50 | color: @legend-color;
51 | transition: all @transition-time ease;
52 | &:hover{
53 | color: #444;
54 | }
55 | }
56 | }
57 |
58 | &-select {
59 | display: inline-block;
60 | }
61 |
62 | &-drag{
63 | background: #fff;
64 | border: 1px dashed @border-color-base;
65 | border-radius: @border-radius-small;
66 | text-align: center;
67 | cursor: pointer;
68 | position: relative;
69 | overflow: hidden;
70 | transition: border-color @transition-time ease;
71 |
72 | &:hover{
73 | border: 1px dashed @primary-color;
74 | }
75 | }
76 | &-dragOver{
77 | border: 2px dashed @primary-color;
78 | }
79 | }
--------------------------------------------------------------------------------
/src/locale/lang/vi-VN.js:
--------------------------------------------------------------------------------
1 | export default {
2 | i: {
3 | select: {
4 | placeholder: 'Chọn',
5 | noMatch: 'Không tìm thấy',
6 | loading: 'Đang tải'
7 | },
8 | table: {
9 | noDataText: 'Không có dữ liệu',
10 | noFilteredDataText: 'Không có dữ liệu lọc',
11 | confirmFilter: 'Xác nhận',
12 | resetFilter: 'Làm lại',
13 | clearFilter: 'Xóa hết'
14 | },
15 | datepicker: {
16 | selectDate: 'Chọn ngày',
17 | selectTime: 'Chọn giờ',
18 | startTime: 'Ngày bắt đầu',
19 | endTime: 'Ngày kết thúc',
20 | clear: 'Xóa',
21 | ok: 'Đồng ý',
22 | month: '',
23 | month1: 'Tháng 1',
24 | month2: 'Tháng 2',
25 | month3: 'Tháng 3',
26 | month4: 'Tháng 4',
27 | month5: 'Tháng 5',
28 | month6: 'Tháng 6',
29 | month7: 'Tháng 7',
30 | month8: 'Tháng 8',
31 | month9: 'Tháng 9',
32 | month10: 'Tháng 10',
33 | month11: 'Tháng 11',
34 | month12: 'Tháng 12',
35 | year: '',
36 | weeks: {
37 | sun: 'CN',
38 | mon: 'T2',
39 | tue: 'T3',
40 | wed: 'T4',
41 | thu: 'T5',
42 | fri: 'T6',
43 | sat: 'T7'
44 | },
45 | months: {
46 | m1: 'Th.1',
47 | m2: 'Th.2',
48 | m3: 'Th.3',
49 | m4: 'Th.4',
50 | m5: 'Th.5',
51 | m6: 'Th.6',
52 | m7: 'Th.7',
53 | m8: 'Th.8',
54 | m9: 'Th.9',
55 | m10: 'Th.10',
56 | m11: 'Th.11',
57 | m12: 'Th.12'
58 | }
59 | },
60 | transfer: {
61 | titles: {
62 | source: 'Nguồn',
63 | target: 'Đích'
64 | },
65 | filterPlaceholder: 'Nhập từ khóa',
66 | notFoundText: 'Không tìm thấy'
67 | },
68 | modal: {
69 | okText: 'Đồng ý',
70 | cancelText: 'Hủy bỏ'
71 | },
72 | poptip: {
73 | okText: 'Đồng ý',
74 | cancelText: 'Hủy bỏ'
75 | },
76 | page: {
77 | prev: 'Trang trước',
78 | next: 'Trang kế',
79 | total: 'Tổng',
80 | item: 'kết quả',
81 | items: 'kết quả',
82 | prev5: '5 trang trước',
83 | next5: '5 trang kế',
84 | page: '/trang',
85 | goto: 'Tới trang',
86 | p: ''
87 | },
88 | rate: {
89 | star: 'Sao',
90 | stars: 'Sao'
91 | },
92 | tree: {
93 | emptyText: 'Không có dữ liệu'
94 | }
95 | }
96 | };
97 |
--------------------------------------------------------------------------------
/src/components/grid/row.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
75 |
--------------------------------------------------------------------------------
/src/components/card/card.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
75 |
--------------------------------------------------------------------------------
/src/styles/components/timeline.less:
--------------------------------------------------------------------------------
1 | @timeline-prefix-cls: ~"@{css-prefix}timeline";
2 | @timeline-color: @border-color-split;
3 |
4 | .@{timeline-prefix-cls} {
5 | list-style: none;
6 | margin: 0;
7 | padding: 0;
8 |
9 | &-item {
10 | margin: 0 !important;
11 | padding: 0 0 12px 0;
12 | list-style: none;
13 | position: relative;
14 |
15 | &-tail {
16 | height: 100%;
17 | border-left: 1px solid @timeline-color;
18 | position: absolute;
19 | left: 6px;
20 | top: 0;
21 | }
22 |
23 | &-pending &-tail {
24 | display: none;
25 | }
26 |
27 | &-head {
28 | width: 13px;
29 | height: 13px;
30 | background-color: #fff;
31 | border-radius: 50%;
32 | border: 1px solid transparent;
33 | position: absolute;
34 |
35 | &-blue {
36 | border-color: @primary-color;
37 | color: @primary-color;
38 | }
39 | &-red {
40 | border-color: @error-color;
41 | color: @error-color;
42 | }
43 | &-green {
44 | border-color: @success-color;
45 | color: @success-color;
46 | }
47 | }
48 |
49 | &-head-custom {
50 | width: 40px;
51 | height: auto;
52 | margin-top: 6px;
53 | padding: 3px 0;
54 | text-align: center;
55 | line-height: 1;
56 | border: 0;
57 | border-radius: 0;
58 | font-size: @font-size-base;
59 | position: absolute;
60 | left: -13px;
61 | transform: translateY(-50%);
62 | }
63 |
64 | &-content {
65 | padding: 1px 1px 10px 24px;
66 | font-size: @font-size-small;
67 | position: relative;
68 | top: -3px;
69 | }
70 |
71 | &:last-child {
72 | .@{timeline-prefix-cls}-item-tail {
73 | display: none;
74 | }
75 | }
76 | }
77 |
78 | &&-pending &-item:nth-last-of-type(2) {
79 |
80 | .@{timeline-prefix-cls}-item-tail {
81 | border-left: 1px dotted @timeline-color;
82 | }
83 | .@{timeline-prefix-cls}-item-content {
84 | min-height: 48px;
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/examples/routers/tabs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 标签2一的内容
6 | 标签2二的内容
7 | 标签2三的内容
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
71 |
--------------------------------------------------------------------------------
/src/components/date-picker/util.js:
--------------------------------------------------------------------------------
1 | import dateUtil from '../../utils/date';
2 |
3 | export const toDate = function(date) {
4 | date = new Date(date);
5 | if (isNaN(date.getTime())) return null;
6 | return date;
7 | };
8 |
9 | export const formatDate = function(date, format) {
10 | date = toDate(date);
11 | if (!date) return '';
12 | return dateUtil.format(date, format || 'yyyy-MM-dd');
13 | };
14 |
15 | export const parseDate = function(string, format) {
16 | return dateUtil.parse(string, format || 'yyyy-MM-dd');
17 | };
18 |
19 | export const getDayCountOfMonth = function(year, month) {
20 | if (month === 3 || month === 5 || month === 8 || month === 10) {
21 | return 30;
22 | }
23 |
24 | if (month === 1) {
25 | if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
26 | return 29;
27 | } else {
28 | return 28;
29 | }
30 | }
31 |
32 | return 31;
33 | };
34 |
35 | export const getFirstDayOfMonth = function(date) {
36 | const temp = new Date(date.getTime());
37 | temp.setDate(1);
38 | return temp.getDay();
39 | };
40 |
41 | export const prevMonth = function(src) {
42 | const year = src.getFullYear();
43 | const month = src.getMonth();
44 | const date = src.getDate();
45 |
46 | const newYear = month === 0 ? year - 1 : year;
47 | const newMonth = month === 0 ? 11 : month - 1;
48 |
49 | const newMonthDayCount = getDayCountOfMonth(newYear, newMonth);
50 | if (newMonthDayCount < date) {
51 | src.setDate(newMonthDayCount);
52 | }
53 |
54 | src.setMonth(newMonth);
55 | src.setFullYear(newYear);
56 |
57 | return new Date(src.getTime());
58 | };
59 |
60 | export const nextMonth = function(src) {
61 | const year = src.getFullYear();
62 | const month = src.getMonth();
63 | const date = src.getDate();
64 |
65 | const newYear = month === 11 ? year + 1 : year;
66 | const newMonth = month === 11 ? 0 : month + 1;
67 |
68 | const newMonthDayCount = getDayCountOfMonth(newYear, newMonth);
69 | if (newMonthDayCount < date) {
70 | src.setDate(newMonthDayCount);
71 | }
72 |
73 | src.setMonth(newMonth);
74 | src.setFullYear(newYear);
75 |
76 | return new Date(src.getTime());
77 | };
78 |
79 | export const initTimeDate = function () {
80 | const date = new Date();
81 | date.setHours(0);
82 | date.setMinutes(0);
83 | date.setSeconds(0);
84 | return date;
85 | };
--------------------------------------------------------------------------------
/examples/routers/cascader.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
69 |
--------------------------------------------------------------------------------
/src/styles/mixins/tooltip.less:
--------------------------------------------------------------------------------
1 | .popper(@arrow, @arrow-width, @arrow-distance, @bg){
2 | display: block;
3 | visibility: visible;
4 | font-size: @font-size-small;
5 | line-height: @line-height-base;
6 | position: absolute;
7 | z-index: @zindex-tooltip;
8 |
9 | &[x-placement^="top"] {
10 | padding: @arrow-width 0 @arrow-distance 0;
11 | }
12 | &[x-placement^="right"] {
13 | padding: 0 @arrow-width 0 @arrow-distance;
14 | }
15 | &[x-placement^="bottom"] {
16 | padding: @arrow-distance 0 @arrow-width 0;
17 | }
18 | &[x-placement^="left"] {
19 | padding: 0 @arrow-distance 0 @arrow-width;
20 | }
21 |
22 | &[x-placement^="top"] .@{arrow} {
23 | bottom: @arrow-distance - @arrow-width;
24 | border-width: @arrow-width @arrow-width 0;
25 | border-top-color: @bg;
26 | }
27 | &[x-placement="top"] .@{arrow} {
28 | left: 50%;
29 | margin-left: -@arrow-width;
30 | }
31 | &[x-placement="top-start"] .@{arrow} {
32 | left: 16px;
33 | }
34 | &[x-placement="top-end"] .@{arrow} {
35 | right: 16px;
36 | }
37 |
38 | &[x-placement^="right"] .@{arrow} {
39 | left: @arrow-distance - @arrow-width;
40 | border-width: @arrow-width @arrow-width @arrow-width 0;
41 | border-right-color: @bg;
42 | }
43 | &[x-placement="right"] .@{arrow} {
44 | top: 50%;
45 | margin-top: -@arrow-width;
46 | }
47 | &[x-placement="right-start"] .@{arrow} {
48 | top: 8px;
49 | }
50 | &[x-placement="right-end"] .@{arrow} {
51 | bottom: 8px;
52 | }
53 |
54 | &[x-placement^="left"] .@{arrow} {
55 | right: @arrow-distance - @arrow-width;
56 | border-width: @arrow-width 0 @arrow-width @arrow-width;
57 | border-left-color: @bg;
58 | }
59 | &[x-placement="left"] .@{arrow} {
60 | top: 50%;
61 | margin-top: -@arrow-width;
62 | }
63 | &[x-placement="left-start"] .@{arrow} {
64 | top: 8px;
65 | }
66 | &[x-placement="left-end"] .@{arrow} {
67 | bottom: 8px;
68 | }
69 |
70 | &[x-placement^="bottom"] .@{arrow} {
71 | top: @arrow-distance - @arrow-width;
72 | border-width: 0 @arrow-width @arrow-width;
73 | border-bottom-color: @bg;
74 | }
75 | &[x-placement="bottom"] .@{arrow} {
76 | left: 50%;
77 | margin-left: -@arrow-width;
78 | }
79 | &[x-placement="bottom-start"] .@{arrow} {
80 | left: 16px;
81 | }
82 | &[x-placement="bottom-end"] .@{arrow} {
83 | right: 16px;
84 | }
85 | }
--------------------------------------------------------------------------------
/src/components/radio/radio-group.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
83 |
--------------------------------------------------------------------------------
/src/locale/lang/zh-CN.js:
--------------------------------------------------------------------------------
1 | export default {
2 | i: {
3 | select: {
4 | placeholder: '请选择',
5 | noMatch: '无匹配数据',
6 | loading: '加载中'
7 | },
8 | table: {
9 | noDataText: '暂无数据',
10 | noFilteredDataText: '暂无筛选结果',
11 | confirmFilter: '筛选',
12 | resetFilter: '重置',
13 | clearFilter: '全部'
14 | },
15 | datepicker: {
16 | selectDate: '选择日期',
17 | selectTime: '选择时间',
18 | startTime: '开始时间',
19 | endTime: '结束时间',
20 | clear: '清空',
21 | ok: '确定',
22 | month: '月',
23 | month1: '1 月',
24 | month2: '2 月',
25 | month3: '3 月',
26 | month4: '4 月',
27 | month5: '5 月',
28 | month6: '6 月',
29 | month7: '7 月',
30 | month8: '8 月',
31 | month9: '9 月',
32 | month10: '10 月',
33 | month11: '11 月',
34 | month12: '12 月',
35 | year: '年',
36 | weeks: {
37 | sun: '日',
38 | mon: '一',
39 | tue: '二',
40 | wed: '三',
41 | thu: '四',
42 | fri: '五',
43 | sat: '六'
44 | },
45 | months: {
46 | m1: '1月',
47 | m2: '2月',
48 | m3: '3月',
49 | m4: '4月',
50 | m5: '5月',
51 | m6: '6月',
52 | m7: '7月',
53 | m8: '8月',
54 | m9: '9月',
55 | m10: '10月',
56 | m11: '11月',
57 | m12: '12月'
58 | }
59 | },
60 | transfer: {
61 | titles: {
62 | source: '源列表',
63 | target: '目的列表'
64 | },
65 | filterPlaceholder: '请输入搜索内容',
66 | notFoundText: '列表为空'
67 | },
68 | modal: {
69 | okText: '确定',
70 | cancelText: '取消'
71 | },
72 | poptip: {
73 | okText: '确定',
74 | cancelText: '取消'
75 | },
76 | page: {
77 | prev: '上一页',
78 | next: '下一页',
79 | total: '共',
80 | item: '条',
81 | items: '条',
82 | prev5: '向前 5 页',
83 | next5: '向后 5 页',
84 | page: '条/页',
85 | goto: '跳至',
86 | p: '页'
87 | },
88 | rate: {
89 | star: '星',
90 | stars: '星'
91 | },
92 | tree: {
93 | emptyText: '暂无数据'
94 | }
95 | }
96 | };
--------------------------------------------------------------------------------
/src/locale/lang/zh-TW.js:
--------------------------------------------------------------------------------
1 | export default {
2 | i: {
3 | select: {
4 | placeholder: '請選擇',
5 | noMatch: '無匹配數據',
6 | loading: '加載中'
7 | },
8 | table: {
9 | noDataText: '暫無數據',
10 | noFilteredDataText: '暫無篩選結果',
11 | confirmFilter: '篩選',
12 | resetFilter: '重置',
13 | clearFilter: '全部'
14 | },
15 | datepicker: {
16 | selectDate: '選擇日期',
17 | selectTime: '選擇時間',
18 | startTime: '開始時間',
19 | endTime: '結束時間',
20 | clear: '清空',
21 | ok: '確定',
22 | month: '月',
23 | month1: '1 月',
24 | month2: '2 月',
25 | month3: '3 月',
26 | month4: '4 月',
27 | month5: '5 月',
28 | month6: '6 月',
29 | month7: '7 月',
30 | month8: '8 月',
31 | month9: '9 月',
32 | month10: '10 月',
33 | month11: '11 月',
34 | month12: '12 月',
35 | year: '年',
36 | weeks: {
37 | sun: '日',
38 | mon: '一',
39 | tue: '二',
40 | wed: '三',
41 | thu: '四',
42 | fri: '五',
43 | sat: '六'
44 | },
45 | months: {
46 | m1: '1月',
47 | m2: '2月',
48 | m3: '3月',
49 | m4: '4月',
50 | m5: '5月',
51 | m6: '6月',
52 | m7: '7月',
53 | m8: '8月',
54 | m9: '9月',
55 | m10: '10月',
56 | m11: '11月',
57 | m12: '12月'
58 | }
59 | },
60 | transfer: {
61 | titles: {
62 | source: '源列表',
63 | target: '目的列表'
64 | },
65 | filterPlaceholder: '請輸入搜索內容',
66 | notFoundText: '列表爲空'
67 | },
68 | modal: {
69 | okText: '確定',
70 | cancelText: '取消'
71 | },
72 | poptip: {
73 | okText: '確定',
74 | cancelText: '取消'
75 | },
76 | page: {
77 | prev: '上壹頁',
78 | next: '下壹頁',
79 | total: '共',
80 | item: '條',
81 | items: '條',
82 | prev5: '向前 5 頁',
83 | next5: '向後 5 頁',
84 | page: '條/頁',
85 | goto: '跳至',
86 | p: '頁'
87 | },
88 | rate: {
89 | star: '星',
90 | stars: '星'
91 | },
92 | tree: {
93 | emptyText: '暫無數據'
94 | }
95 | }
96 | };
--------------------------------------------------------------------------------
/src/styles/components/alert.less:
--------------------------------------------------------------------------------
1 | @alert-prefix-cls: ~"@{css-prefix}alert";
2 | @icon-prefix-cls: ~"@{css-prefix}icon";
3 |
4 | .@{alert-prefix-cls}{
5 | position: relative;
6 | padding: 8px 48px 8px 16px;
7 | border-radius: @border-radius-base;
8 | color: @text-color;
9 | font-size: @font-size-small;
10 | line-height: 16px;
11 | margin-bottom: 10px;
12 |
13 | &&-with-icon{
14 | padding: 8px 48px 8px 38px;
15 | }
16 |
17 | &-icon {
18 | font-size: @font-size-base;
19 | top: 8px;
20 | left: 16px;
21 | position: absolute;
22 | }
23 |
24 | &-desc {
25 | font-size: @font-size-small;
26 | color: @text-color;
27 | line-height: 21px;
28 | display: none;
29 | text-align: justify;
30 | }
31 |
32 | &-success {
33 | border: 1px solid tint(@success-color, 80%);
34 | background-color: tint(@success-color, 90%);
35 | .@{alert-prefix-cls}-icon {
36 | color: @success-color;
37 | }
38 | }
39 |
40 | &-info {
41 | border: 1px solid tint(@primary-color, 80%);
42 | background-color: tint(@primary-color, 90%);
43 | .@{alert-prefix-cls}-icon {
44 | color: @primary-color;
45 | }
46 | }
47 |
48 | &-warning {
49 | border: 1px solid tint(@warning-color, 80%);
50 | background-color: tint(@warning-color, 90%);
51 | .@{alert-prefix-cls}-icon {
52 | color: @warning-color;
53 | }
54 | }
55 |
56 | &-error {
57 | border: 1px solid tint(@error-color, 80%);
58 | background-color: tint(@error-color, 90%);
59 | .@{alert-prefix-cls}-icon {
60 | color: @error-color;
61 | }
62 | }
63 |
64 | &-close {
65 | .content-close(-3px);
66 | }
67 |
68 | &-with-desc {
69 | padding: 16px;
70 | position: relative;
71 | border-radius: @border-radius-base;
72 | margin-bottom: 10px;
73 | color: @text-color;
74 | line-height: 1.5;
75 | }
76 |
77 | &-with-desc&-with-icon{
78 | padding: 16px 16px 16px 69px;
79 | }
80 |
81 | &-with-desc &-desc{
82 | display: block;
83 | }
84 |
85 | &-with-desc &-message {
86 | font-size: 14px;
87 | color: @title-color;
88 | display: block;
89 | }
90 |
91 | &-with-desc &-icon {
92 | top: 50%;
93 | left: 24px;
94 | margin-top: -21px;
95 | font-size: 28px;
96 | }
97 |
98 | &-with-banner{
99 | border-radius: 0;
100 | }
101 | }
--------------------------------------------------------------------------------
/src/locale/lang/ko-KR.js:
--------------------------------------------------------------------------------
1 | export default {
2 | i: {
3 | select: {
4 | placeholder: '선택',
5 | noMatch: '일치하는 데이터 없음',
6 | loading: '로딩'
7 | },
8 | table: {
9 | noDataText: '데이터 없음',
10 | noFilteredDataText: '필터된 데이터 없음',
11 | confirmFilter: '확인',
12 | resetFilter: '초기화',
13 | clearFilter: '전부'
14 | },
15 | datepicker: {
16 | selectDate: '날짜 선택',
17 | selectTime: '시간 선택',
18 | startTime: '시작 시간',
19 | endTime: '종료 시간',
20 | clear: '삭제',
21 | ok: '예',
22 | month: '월',
23 | month1: '1월',
24 | month2: '2월',
25 | month3: '3월',
26 | month4: '4월',
27 | month5: '5월',
28 | month6: '6월',
29 | month7: '7월',
30 | month8: '8월',
31 | month9: '9월',
32 | month10: '10월',
33 | month11: '11월',
34 | month12: '12월',
35 | year: '년',
36 | weeks: {
37 | sun: '일',
38 | mon: '월',
39 | tue: '화',
40 | wed: '수',
41 | thu: '목',
42 | fri: '금',
43 | sat: '토'
44 | },
45 | months: {
46 | m1: '1월',
47 | m2: '2월',
48 | m3: '3월',
49 | m4: '4월',
50 | m5: '5월',
51 | m6: '6월',
52 | m7: '7월',
53 | m8: '8월',
54 | m9: '9월',
55 | m10: '10월',
56 | m11: '11월',
57 | m12: '12월'
58 | }
59 | },
60 | transfer: {
61 | titles: {
62 | source: '소스',
63 | target: '타겟'
64 | },
65 | filterPlaceholder: '여기서 찾기',
66 | notFoundText: '아무 것도 찾을 수 없음'
67 | },
68 | modal: {
69 | okText: '예',
70 | cancelText: '취소'
71 | },
72 | poptip: {
73 | okText: '예',
74 | cancelText: '취소'
75 | },
76 | page: {
77 | prev: '이전 페이지',
78 | next: '다음 페이지',
79 | total: '전체',
80 | item: '항목',
81 | items: '항목',
82 | prev5: '이전 5 페이지',
83 | next5: '다음 5 페이지',
84 | page: '/페이지',
85 | goto: '이동',
86 | p: ''
87 | },
88 | rate: {
89 | star: '중요',
90 | stars: '중요'
91 | },
92 | tree: {
93 | emptyText: '데이터 없음'
94 | }
95 | }
96 | };
--------------------------------------------------------------------------------
/src/components/button/button.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
77 |
--------------------------------------------------------------------------------
/src/locale/lang/ja-JP.js:
--------------------------------------------------------------------------------
1 | export default {
2 | i: {
3 | select: {
4 | placeholder: '選んでください',
5 | noMatch: 'マッチするデータなし',
6 | loading: 'ロード中'
7 | },
8 | table: {
9 | noDataText: 'データなし',
10 | noFilteredDataText: 'スクリーニングしたデータなし',
11 | confirmFilter: 'スクリーニング',
12 | resetFilter: 'リセット',
13 | clearFilter: '全部'
14 | },
15 | datepicker: {
16 | selectDate: '日時を選んでください',
17 | selectTime: '時間を選んでください',
18 | startTime: 'スタート時間',
19 | endTime: '終了時間',
20 | clear: 'クリーア',
21 | ok: '確定',
22 | month: '月',
23 | month1: '1 月',
24 | month2: '2 月',
25 | month3: '3 月',
26 | month4: '4 月',
27 | month5: '5 月',
28 | month6: '6 月',
29 | month7: '7 月',
30 | month8: '8 月',
31 | month9: '9 月',
32 | month10: '10 月',
33 | month11: '11 月',
34 | month12: '12 月',
35 | year: '年',
36 | weeks: {
37 | sun: '日',
38 | mon: '月',
39 | tue: '火',
40 | wed: '水',
41 | thu: '木',
42 | fri: '金',
43 | sat: '土'
44 | },
45 | months: {
46 | m1: '1月',
47 | m2: '2月',
48 | m3: '3月',
49 | m4: '4月',
50 | m5: '5月',
51 | m6: '6月',
52 | m7: '7月',
53 | m8: '8月',
54 | m9: '9月',
55 | m10: '10月',
56 | m11: '11月',
57 | m12: '12月'
58 | }
59 | },
60 | transfer: {
61 | titles: {
62 | source: 'ソースリスト',
63 | target: 'ターゲットリスト'
64 | },
65 | filterPlaceholder: '検索内容を入力ください',
66 | notFoundText: '内容が見つかってなかった'
67 | },
68 | modal: {
69 | okText: '確定',
70 | cancelText: 'キャンセル'
71 | },
72 | poptip: {
73 | okText: '確定',
74 | cancelText: 'キャンセル'
75 | },
76 | page: {
77 | prev: '前へ',
78 | next: '次へ',
79 | total: '全部',
80 | item: '件',
81 | items: '件',
82 | prev5: '前の5ページへ',
83 | next5: '次の5ページへ',
84 | page: '件/ページ',
85 | goto: '',
86 | p: 'ページ目へ'
87 | },
88 | rate: {
89 | star: '点',
90 | stars: '点'
91 | },
92 | tree: {
93 | emptyText: 'データなし'
94 | }
95 | }
96 | };
--------------------------------------------------------------------------------
/src/components/back-top/back-top.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
82 |
--------------------------------------------------------------------------------
/src/components/base/collapse-transition.js:
--------------------------------------------------------------------------------
1 | // Thanks to https://github.com/ElemeFE/element/blob/dev/src/transitions/collapse-transition.js
2 |
3 | import { addClass, removeClass } from '../../utils/assist';
4 |
5 | const Transition = {
6 | beforeEnter(el) {
7 | addClass(el, 'collapse-transition');
8 | if (!el.dataset) el.dataset = {};
9 |
10 | el.dataset.oldPaddingTop = el.style.paddingTop;
11 | el.dataset.oldPaddingBottom = el.style.paddingBottom;
12 |
13 | el.style.height = '0';
14 | el.style.paddingTop = 0;
15 | el.style.paddingBottom = 0;
16 | },
17 |
18 | enter(el) {
19 | el.dataset.oldOverflow = el.style.overflow;
20 | if (el.scrollHeight !== 0) {
21 | el.style.height = el.scrollHeight + 'px';
22 | el.style.paddingTop = el.dataset.oldPaddingTop;
23 | el.style.paddingBottom = el.dataset.oldPaddingBottom;
24 | } else {
25 | el.style.height = '';
26 | el.style.paddingTop = el.dataset.oldPaddingTop;
27 | el.style.paddingBottom = el.dataset.oldPaddingBottom;
28 | }
29 |
30 | el.style.overflow = 'hidden';
31 | },
32 |
33 | afterEnter(el) {
34 | // for safari: remove class then reset height is necessary
35 | removeClass(el, 'collapse-transition');
36 | el.style.height = '';
37 | el.style.overflow = el.dataset.oldOverflow;
38 | },
39 |
40 | beforeLeave(el) {
41 | if (!el.dataset) el.dataset = {};
42 | el.dataset.oldPaddingTop = el.style.paddingTop;
43 | el.dataset.oldPaddingBottom = el.style.paddingBottom;
44 | el.dataset.oldOverflow = el.style.overflow;
45 |
46 | el.style.height = el.scrollHeight + 'px';
47 | el.style.overflow = 'hidden';
48 | },
49 |
50 | leave(el) {
51 | if (el.scrollHeight !== 0) {
52 | // for safari: add class after set height, or it will jump to zero height suddenly, weired
53 | addClass(el, 'collapse-transition');
54 | el.style.height = 0;
55 | el.style.paddingTop = 0;
56 | el.style.paddingBottom = 0;
57 | }
58 | },
59 |
60 | afterLeave(el) {
61 | removeClass(el, 'collapse-transition');
62 | el.style.height = '';
63 | el.style.overflow = el.dataset.oldOverflow;
64 | el.style.paddingTop = el.dataset.oldPaddingTop;
65 | el.style.paddingBottom = el.dataset.oldPaddingBottom;
66 | }
67 | };
68 |
69 | export default {
70 | name: 'CollapseTransition',
71 | functional: true,
72 | render(h, { children }) {
73 | const data = {
74 | on: Transition
75 | };
76 |
77 | return h('transition', data, children);
78 | }
79 | };
80 |
--------------------------------------------------------------------------------
/src/components/select/option.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ showLabel }}
3 |
4 |
81 |
--------------------------------------------------------------------------------
/src/components/table/export-csv.js:
--------------------------------------------------------------------------------
1 | function has (browser) {
2 | const ua = navigator.userAgent;
3 | if (browser === 'ie') {
4 | const isIE = ua.indexOf('compatible') > -1 && ua.indexOf('MSIE') > -1;
5 | if (isIE) {
6 | const reIE = new RegExp('MSIE (\\d+\\.\\d+);');
7 | reIE.test(ua);
8 | return parseFloat(RegExp['$1']);
9 | } else {
10 | return false;
11 | }
12 | } else {
13 | return ua.indexOf(browser) > -1;
14 | }
15 | }
16 |
17 | const csv = {
18 | _isIE11 () {
19 | let iev = 0;
20 | const ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
21 | const trident = !!navigator.userAgent.match(/Trident\/7.0/);
22 | const rv = navigator.userAgent.indexOf('rv:11.0');
23 |
24 | if (ieold) {
25 | iev = Number(RegExp.$1);
26 | }
27 | if (navigator.appVersion.indexOf('MSIE 10') !== -1) {
28 | iev = 10;
29 | }
30 | if (trident && rv !== -1) {
31 | iev = 11;
32 | }
33 |
34 | return iev === 11;
35 | },
36 |
37 | _isEdge () {
38 | return /Edge/.test(navigator.userAgent);
39 | },
40 |
41 | _getDownloadUrl (text) {
42 | const BOM = '\uFEFF';
43 | // Add BOM to text for open in excel correctly
44 | if (window.Blob && window.URL && window.URL.createObjectURL && !has('Safari')) {
45 | const csvData = new Blob([BOM + text], { type: 'text/csv' });
46 | return URL.createObjectURL(csvData);
47 | } else {
48 | return 'data:attachment/csv;charset=utf-8,' + BOM + encodeURIComponent(text);
49 | }
50 | },
51 |
52 | download (filename, text) {
53 | if (has('ie') && has('ie') < 10) {
54 | // has module unable identify ie11 and Edge
55 | const oWin = window.top.open('about:blank', '_blank');
56 | oWin.document.charset = 'utf-8';
57 | oWin.document.write(text);
58 | oWin.document.close();
59 | oWin.document.execCommand('SaveAs', filename);
60 | oWin.close();
61 | } else if (has('ie') === 10 || this._isIE11() || this._isEdge()) {
62 | const BOM = '\uFEFF';
63 | const csvData = new Blob([BOM + text], { type: 'text/csv' });
64 | navigator.msSaveBlob(csvData, filename);
65 | } else {
66 | const link = document.createElement('a');
67 | link.download = filename;
68 | link.href = this._getDownloadUrl(text);
69 | link.target = '_blank';
70 | document.body.appendChild(link);
71 | link.click();
72 | document.body.removeChild(link);
73 | }
74 | }
75 | };
76 |
77 | export default csv;
--------------------------------------------------------------------------------
/src/components/date-picker/base/month-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ tCell(cell.text) }}
4 |
5 |
6 |
80 |
--------------------------------------------------------------------------------
/src/styles/components/progress.less:
--------------------------------------------------------------------------------
1 | @progress-prefix-cls: ~"@{css-prefix}progress";
2 |
3 | .@{progress-prefix-cls} {
4 | display: inline-block;
5 |
6 | width: 100%;
7 | &-vertical {
8 | height: 100%;
9 | width: auto;
10 | }
11 |
12 | font-size: @font-size-small;
13 | position: relative;
14 |
15 | &-outer {
16 | display: inline-block;
17 | width: 100%;
18 | margin-right: 0;
19 | padding-right: 0;
20 |
21 | .@{progress-prefix-cls}-show-info & {
22 | padding-right: 55px;
23 | margin-right: -55px;
24 | }
25 | }
26 | &-vertical &-outer {
27 | height: 100%;
28 | width: auto;
29 | }
30 |
31 | &-inner {
32 | display: inline-block;
33 | width: 100%;
34 | background-color: #f3f3f3;
35 | border-radius: 100px;
36 | vertical-align: middle;
37 | }
38 | &-vertical &-inner {
39 | height: 100%;
40 | width: auto;
41 |
42 | & > *, &:after {
43 | display: inline-block;
44 | vertical-align: bottom;
45 | }
46 |
47 | &:after {
48 | content: '';
49 | height: 100%;
50 | }
51 | }
52 |
53 | &-bg {
54 | border-radius: 100px;
55 | background-color: @info-color;
56 | transition: all @transition-time linear;
57 | position: relative;
58 | }
59 |
60 | &-text {
61 | display: inline-block;
62 | margin-left: 5px;
63 | text-align: left;
64 | font-size: 1em;
65 | vertical-align: middle;
66 | }
67 |
68 | &-active {
69 | .@{progress-prefix-cls}-bg:before {
70 | content: '';
71 | opacity: 0;
72 | position: absolute;
73 | top: 0;
74 | left: 0;
75 | right: 0;
76 | bottom: 0;
77 | background: #fff;
78 | border-radius: 10px;
79 | animation: ivu-progress-active 2s @ease-in-out infinite;
80 | }
81 | }
82 |
83 | &-wrong {
84 | .@{progress-prefix-cls}-bg {
85 | background-color: @error-color;
86 | }
87 | .@{progress-prefix-cls}-text {
88 | color: @error-color;
89 | }
90 | }
91 |
92 | &-success {
93 | .@{progress-prefix-cls}-bg {
94 | background-color: @success-color;
95 | }
96 | .@{progress-prefix-cls}-text {
97 | color: @success-color;
98 | }
99 | }
100 | }
101 |
102 | @keyframes ivu-progress-active {
103 | 0% {
104 | opacity: .3;
105 | width: 0;
106 | }
107 | 100% {
108 | opacity: 0;
109 | width: 100%;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------