├── static ├── .gitkeep ├── children.json └── datatable.json ├── .eslintignore ├── vb ├── components │ ├── auto-complete │ │ ├── style │ │ │ └── index.less │ │ ├── index.js │ │ └── auto-complete.vue │ ├── icon │ │ ├── index.js │ │ └── icon.vue │ ├── tag │ │ ├── index.js │ │ ├── tag.vue │ │ └── style │ │ │ └── index.less │ ├── menu │ │ └── index.js │ ├── rate │ │ ├── index.js │ │ └── style │ │ │ └── index.less │ ├── spin │ │ ├── index.js │ │ ├── spinInner.vue │ │ └── spin.vue │ ├── tree │ │ ├── index.js │ │ └── style │ │ │ └── mixin.less │ ├── affix │ │ ├── index.js │ │ └── style │ │ │ └── index.less │ ├── alert │ │ ├── index.js │ │ └── alert.vue │ ├── badge │ │ └── index.js │ ├── avatar │ │ ├── index.js │ │ ├── style │ │ │ └── index.less │ │ └── avatar.vue │ ├── modal │ │ ├── style │ │ │ ├── index.less │ │ │ └── confirm.less │ │ ├── confirm.js │ │ └── index.js │ ├── popover │ │ └── index.js │ ├── select │ │ └── index.js │ ├── slider │ │ ├── index.js │ │ ├── track.vue │ │ ├── dots.vue │ │ └── marks.vue │ ├── switch │ │ ├── index.js │ │ ├── switch.vue │ │ └── style │ │ │ └── index.less │ ├── upload │ │ ├── index.js │ │ ├── uid.js │ │ ├── get-file-item.js │ │ ├── upload-list.vue │ │ └── request.js │ ├── back-top │ │ ├── index.js │ │ └── style │ │ │ └── index.less │ ├── cascader │ │ ├── index.js │ │ └── menu.vue │ ├── checkbox │ │ ├── style │ │ │ └── index.less │ │ └── index.js │ ├── tooltip │ │ ├── index.js │ │ └── tooltip.vue │ ├── transfer │ │ ├── index.js │ │ ├── search.vue │ │ └── operation.vue │ ├── more-panel │ │ ├── index.js │ │ ├── style │ │ │ └── index.less │ │ └── more-panel.vue │ ├── date-picker │ │ ├── index.js │ │ └── style │ │ │ ├── MonthPicker.less │ │ │ ├── index.less │ │ │ ├── DecadePanel.less │ │ │ ├── MonthPanel.less │ │ │ ├── YearPanel.less │ │ │ └── Picker.less │ ├── grid │ │ ├── index.js │ │ ├── row.vue │ │ ├── style │ │ │ └── index.less │ │ └── col.vue │ ├── pagination │ │ └── index.js │ ├── popconfirm │ │ ├── index.js │ │ ├── style │ │ │ └── index.less │ │ └── popconfirm.vue │ ├── time-picker │ │ └── index.js │ ├── tree-select │ │ └── index.js │ ├── input-number │ │ └── index.js │ ├── steps │ │ ├── index.js │ │ └── step.vue │ ├── card │ │ ├── index.js │ │ ├── card-grid.vue │ │ └── card.vue │ ├── form │ │ ├── index.js │ │ ├── form.vue │ │ └── style │ │ │ └── mixin.less │ ├── tabs │ │ ├── index.js │ │ └── tab-pane.vue │ ├── collapse │ │ ├── index.js │ │ ├── panel.vue │ │ ├── collapse.vue │ │ └── style │ │ │ └── index.less │ ├── data-table │ │ ├── index.js │ │ └── table.vue │ ├── input │ │ ├── index.js │ │ ├── style │ │ │ ├── index.less │ │ │ └── search-input.less │ │ └── input-group.vue │ ├── radio │ │ ├── index.js │ │ ├── radio.vue │ │ └── radio-group.vue │ ├── button │ │ ├── index.js │ │ ├── style │ │ │ └── button_vb.less │ │ ├── button-group.vue │ │ └── button.vue │ ├── progress │ │ └── index.js │ ├── carousel │ │ ├── index.js │ │ ├── carousel-item.vue │ │ └── style │ │ │ └── carousel_vb.less │ ├── dropdown │ │ └── index.js │ ├── timeline │ │ ├── index.js │ │ ├── timeline.vue │ │ ├── timeline-item.vue │ │ └── style │ │ │ └── index.less │ ├── breadcrumb │ │ ├── index.js │ │ ├── breadcrumb.vue │ │ ├── breadcrumb-item.vue │ │ └── style │ │ │ └── index.less │ ├── layout │ │ ├── index.js │ │ ├── footer.vue │ │ ├── header.vue │ │ ├── content.vue │ │ ├── layout.vue │ │ └── style │ │ │ └── index.less │ ├── message │ │ ├── message.js │ │ ├── style │ │ │ └── index.less │ │ ├── message.vue │ │ ├── index.js │ │ └── notice.vue │ └── notification │ │ ├── notification.js │ │ ├── notice.vue │ │ └── notification.vue ├── style │ ├── index.less │ ├── core │ │ ├── index.less │ │ ├── motion │ │ │ ├── other.less │ │ │ ├── fade.less │ │ │ ├── swing.less │ │ │ ├── slide.less │ │ │ └── move.less │ │ ├── motion.less │ │ ├── base.less │ │ └── base_vb.less │ ├── mixins │ │ ├── size.less │ │ ├── opacity.less │ │ ├── grid.less │ │ ├── index.less │ │ ├── clearfix.less │ │ ├── margin.less │ │ ├── padding.less │ │ ├── iconfont.less │ │ ├── compatibility.less │ │ └── motion.less │ ├── themes │ │ └── default_vb.less │ └── color │ │ └── colorPalette.less ├── utils │ ├── config.js │ ├── polyfill.js │ └── fn.js ├── mixins │ ├── locale.js │ └── emitter.js ├── directives │ └── clickoutside.js └── locale │ ├── format.js │ ├── lang │ ├── tr.js │ ├── zh-CN.js │ ├── jp.js │ └── en.js │ └── index.js ├── config ├── prod.env.js ├── dev.env.js └── index.js ├── src ├── assets │ └── VB-logo.png ├── docs │ └── zh-cn │ │ ├── polyfill.md │ │ ├── more-panel.md │ │ ├── affix.md │ │ ├── contribute.md │ │ ├── spin.md │ │ ├── avatar.md │ │ ├── start.md │ │ ├── tag.md │ │ ├── breadcrumb.md │ │ ├── timeline.md │ │ └── rate.md ├── components │ └── index.js ├── main.js ├── App.vue └── views │ └── layout-fixed.vue ├── .npmignore ├── tea.yaml ├── .editorconfig ├── .postcssrc.js ├── .gitignore ├── index.html ├── .babelrc ├── LICENSE ├── README.md └── .eslintrc.js /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /vb/components/auto-complete/style/index.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /vb/style/index.less: -------------------------------------------------------------------------------- 1 | @import "./themes/default"; 2 | @import "./core/index"; 3 | -------------------------------------------------------------------------------- /vb/components/icon/index.js: -------------------------------------------------------------------------------- 1 | import vIcon from './icon'; 2 | 3 | export default vIcon; 4 | -------------------------------------------------------------------------------- /src/assets/VB-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FE-Driver/vue-beauty/HEAD/src/assets/VB-logo.png -------------------------------------------------------------------------------- /vb/components/tag/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import tag from './tag'; 3 | 4 | export default tag; 5 | -------------------------------------------------------------------------------- /vb/components/menu/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import menu from './menu'; 3 | 4 | export default menu; 5 | -------------------------------------------------------------------------------- /vb/components/rate/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import rate from './rate'; 3 | 4 | export default rate; 5 | -------------------------------------------------------------------------------- /vb/components/spin/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import spin from './spin'; 3 | 4 | export default spin; 5 | -------------------------------------------------------------------------------- /vb/components/tree/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import tree from './tree'; 3 | 4 | export default tree; 5 | -------------------------------------------------------------------------------- /vb/style/core/index.less: -------------------------------------------------------------------------------- 1 | @import "../mixins/index"; 2 | @import "base"; 3 | @import "iconfont"; 4 | @import "motion"; 5 | -------------------------------------------------------------------------------- /vb/components/affix/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import affix from './affix'; 3 | 4 | export default affix; 5 | -------------------------------------------------------------------------------- /vb/components/alert/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import alert from './alert'; 3 | 4 | export default alert; 5 | -------------------------------------------------------------------------------- /vb/components/badge/index.js: -------------------------------------------------------------------------------- 1 | import vBadge from './badge'; 2 | import './style/index.less'; 3 | 4 | export default vBadge; 5 | -------------------------------------------------------------------------------- /vb/components/avatar/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import avatar from './avatar'; 3 | 4 | export default avatar; 5 | -------------------------------------------------------------------------------- /vb/components/modal/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "./modal"; 3 | @import "./confirm"; 4 | -------------------------------------------------------------------------------- /vb/components/popover/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import popover from './popover'; 3 | 4 | export default popover; 5 | -------------------------------------------------------------------------------- /vb/components/select/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import select from './select'; 3 | 4 | export default select; 5 | -------------------------------------------------------------------------------- /vb/components/slider/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import slider from './slider'; 3 | 4 | export default slider; 5 | -------------------------------------------------------------------------------- /vb/components/switch/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import vSwitch from './switch'; 3 | 4 | export default vSwitch; 5 | -------------------------------------------------------------------------------- /vb/components/upload/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import upload from './uploads'; 3 | 4 | export default upload; 5 | -------------------------------------------------------------------------------- /vb/components/back-top/index.js: -------------------------------------------------------------------------------- 1 | import backTop from './back-top'; 2 | import './style/index.less'; 3 | 4 | export default backTop; 5 | -------------------------------------------------------------------------------- /vb/components/cascader/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import cascader from './cascader'; 3 | 4 | export default cascader; 5 | -------------------------------------------------------------------------------- /vb/components/checkbox/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "./mixin"; 3 | 4 | .antCheckboxFn(); 5 | -------------------------------------------------------------------------------- /vb/components/tooltip/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import vTooltip from './tooltip'; 3 | 4 | export default vTooltip; 5 | -------------------------------------------------------------------------------- /vb/components/transfer/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import transfer from './transfer'; 3 | 4 | export default transfer; 5 | -------------------------------------------------------------------------------- /vb/utils/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by wl on 2017/3/16. 3 | */ 4 | 5 | export default { 6 | componentNamePrefix: 'v', 7 | }; 8 | -------------------------------------------------------------------------------- /vb/components/more-panel/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import morePanel from './more-panel'; 3 | 4 | export default morePanel; 5 | -------------------------------------------------------------------------------- /vb/components/date-picker/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import datePicker from './date-picker'; 3 | 4 | export default datePicker; 5 | -------------------------------------------------------------------------------- /vb/components/grid/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import row from './row'; 3 | import col from './col'; 4 | 5 | export { col, row }; 6 | -------------------------------------------------------------------------------- /vb/components/pagination/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import pagination from './pagination'; 3 | 4 | export default pagination; 5 | -------------------------------------------------------------------------------- /vb/components/popconfirm/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import popconfirm from './popconfirm'; 3 | 4 | export default popconfirm; 5 | -------------------------------------------------------------------------------- /vb/components/time-picker/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import timePicker from './time-picker'; 3 | 4 | export default timePicker; 5 | -------------------------------------------------------------------------------- /vb/components/tree-select/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import treeSelect from './tree-select'; 3 | 4 | export default treeSelect; 5 | -------------------------------------------------------------------------------- /vb/components/input-number/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import inputNumber from './input-number'; 3 | 4 | export default inputNumber; 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | index.html 3 | build/ 4 | config/ 5 | dist/ 6 | node_modules/ 7 | package/style.js 8 | package/style.min.js 9 | src/ 10 | static/ -------------------------------------------------------------------------------- /tea.yaml: -------------------------------------------------------------------------------- 1 | # https://tea.xyz/what-is-this-file 2 | --- 3 | version: 1.0.0 4 | codeOwners: 5 | - '0xB3676f5D874f7b2fBeE0BC0F5cc28ca49Ba90300' 6 | quorum: 1 7 | -------------------------------------------------------------------------------- /vb/components/auto-complete/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import autoComplete from './auto-complete'; 3 | 4 | export default autoComplete; 5 | -------------------------------------------------------------------------------- /vb/components/steps/index.js: -------------------------------------------------------------------------------- 1 | import './style/steps.less'; 2 | import steps from './steps'; 3 | import step from './step'; 4 | 5 | export { steps, step }; 6 | -------------------------------------------------------------------------------- /vb/components/affix/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | 3 | .@{ant-prefix}-affix { 4 | position: fixed; 5 | z-index: @zindex-affix; 6 | } 7 | -------------------------------------------------------------------------------- /vb/components/upload/uid.js: -------------------------------------------------------------------------------- 1 | const now = +(new Date()); 2 | let index = 0; 3 | 4 | export default function uid() { 5 | return `ant-upload-${now}-${++index}`; 6 | } 7 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /vb/components/card/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import card from './card'; 3 | import grid from './card-grid'; 4 | 5 | card.grid = grid; 6 | 7 | export default card; 8 | -------------------------------------------------------------------------------- /vb/components/form/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import form from './form'; 3 | import formItem from './form-item'; 4 | 5 | form.item = formItem; 6 | 7 | export default form; 8 | -------------------------------------------------------------------------------- /vb/components/tabs/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import tabs from './tabs'; 3 | import tabPane from './tab-pane'; 4 | 5 | tabs.pane = tabPane; 6 | 7 | export default tabs; 8 | -------------------------------------------------------------------------------- /vb/components/collapse/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import collapse from './collapse'; 3 | import panel from './panel'; 4 | 5 | collapse.panel = panel; 6 | export default collapse; 7 | -------------------------------------------------------------------------------- /vb/components/data-table/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by bailey on 17/2/20. 3 | */ 4 | import './style/index.less'; 5 | import dataTable from './data-table'; 6 | 7 | export default dataTable; 8 | -------------------------------------------------------------------------------- /vb/style/mixins/size.less: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | .size(@width; @height) { 4 | width: @width; 5 | height: @height; 6 | } 7 | 8 | .square(@size) { 9 | .size(@size; @size); 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /vb/components/input/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import input from './input'; 3 | import inputGroup from './input-group'; 4 | 5 | input.group = inputGroup; 6 | 7 | export default input; 8 | -------------------------------------------------------------------------------- /vb/components/popconfirm/style/index.less: -------------------------------------------------------------------------------- 1 | @import '../../../style/index.less'; 2 | 3 | // style dependencies 4 | @import '../../popover/style/index.less'; 5 | @import '../../button/style/index.less'; 6 | -------------------------------------------------------------------------------- /vb/components/radio/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import radio from './radio'; 3 | import radioGroup from './radio-group'; 4 | 5 | radio.group = radioGroup; 6 | 7 | export default radio; 8 | -------------------------------------------------------------------------------- /vb/style/mixins/opacity.less: -------------------------------------------------------------------------------- 1 | // Opacity 2 | 3 | .opacity(@opacity) { 4 | opacity: @opacity; 5 | // IE8 filter 6 | @opacity-ie: (@opacity * 100); 7 | filter: ~"alpha(opacity=@{opacity-ie})"; 8 | } 9 | -------------------------------------------------------------------------------- /vb/components/button/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import button from './button'; 3 | import buttonGroup from './button-group'; 4 | 5 | button.group = buttonGroup; 6 | 7 | export default button; 8 | -------------------------------------------------------------------------------- /vb/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 | -------------------------------------------------------------------------------- /vb/components/progress/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import progressLine from './progress-line'; 3 | import progressCircle from './progress-circle'; 4 | 5 | export { progressLine, progressCircle }; 6 | -------------------------------------------------------------------------------- /vb/components/date-picker/style/MonthPicker.less: -------------------------------------------------------------------------------- 1 | .@{calendar-prefix-cls}-month { 2 | .@{calendar-prefix-cls}-month-panel, 3 | .@{calendar-prefix-cls}-year-panel { 4 | top: 0; 5 | height: 248px; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /vb/components/carousel/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import carousel from './carousel'; 3 | import carouselItem from './carousel-item'; 4 | 5 | carousel.item = carouselItem; 6 | 7 | export default carousel; 8 | -------------------------------------------------------------------------------- /vb/components/checkbox/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import checkbox from './checkbox'; 3 | import checkboxGroup from './checkbox-group'; 4 | 5 | checkbox.group = checkboxGroup; 6 | 7 | export default checkbox; 8 | -------------------------------------------------------------------------------- /vb/components/dropdown/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import dropdown from './dropdown'; 3 | import dropdownMenu from './dropdown-menu'; 4 | 5 | dropdown.menu = dropdownMenu; 6 | 7 | export default dropdown; 8 | -------------------------------------------------------------------------------- /vb/components/timeline/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import timeline from './timeline'; 3 | import timelineItem from './timeline-item'; 4 | 5 | timeline.item = timelineItem; 6 | 7 | export default timeline; 8 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /vb/components/breadcrumb/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import breadcrumb from './breadcrumb'; 3 | import breadcrumbItem from './breadcrumb-item'; 4 | 5 | breadcrumb.item = breadcrumbItem; 6 | 7 | export default breadcrumb; 8 | -------------------------------------------------------------------------------- /vb/components/card/card-grid.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | -------------------------------------------------------------------------------- /vb/style/core/motion/other.less: -------------------------------------------------------------------------------- 1 | @keyframes loadingCircle { 2 | 0% { 3 | transform-origin: 50% 50%; 4 | transform: rotate(0deg); 5 | } 6 | 100% { 7 | transform-origin: 50% 50%; 8 | transform: rotate(360deg); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | selenium-debug.log 8 | package/style.js 9 | package/style.min.js 10 | test/unit/coverage 11 | test/e2e/reports 12 | .history 13 | .idea/ 14 | .vscode/ -------------------------------------------------------------------------------- /vb/style/mixins/grid.less: -------------------------------------------------------------------------------- 1 | // Centered container element 2 | .container-fixed(@gutter: @grid-gutter-width) { 3 | margin-right: auto; 4 | margin-left: auto; 5 | padding-left: floor((@gutter / 2)); 6 | padding-right: ceil((@gutter / 2)); 7 | &:extend(.clearfix all); 8 | } 9 | -------------------------------------------------------------------------------- /vb/components/layout/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import layout from './layout'; 3 | import sider from './sider'; 4 | import header from './header'; 5 | import content from './content'; 6 | import footer from './footer'; 7 | 8 | export { layout, sider, header, content, footer }; 9 | -------------------------------------------------------------------------------- /vb/style/mixins/index.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------------------------------- 3 | @import "opacity"; 4 | @import "size"; 5 | @import "compatibility"; 6 | @import "clearfix"; 7 | @import "iconfont"; 8 | @import "motion"; 9 | @import "grid"; 10 | @import "margin"; 11 | @import "padding"; 12 | -------------------------------------------------------------------------------- /vb/components/layout/footer.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /vb/components/layout/header.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /vb/components/layout/content.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /vb/style/mixins/clearfix.less: -------------------------------------------------------------------------------- 1 | // mixins for clearfix 2 | // ------------------------ 3 | .clearfix() { 4 | zoom: 1; 5 | &:before, 6 | &:after { 7 | content: " "; 8 | display: table; 9 | } 10 | &:after { 11 | clear: both; 12 | visibility: hidden; 13 | font-size: 0; 14 | height: 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-beauty2 6 | 7 | 8 |
9 | 10 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["env",{"modules": false}],"stage-2"], 3 | "plugins": [ 4 | ["transform-runtime", { 5 | "helpers": false, 6 | "polyfill": true, 7 | "regenerator": true 8 | }] 9 | ], 10 | "env": { 11 | "test": { 12 | "presets": ["env", "stage-2"], 13 | "plugins": ["istanbul"] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /vb/components/breadcrumb/breadcrumb.vue: -------------------------------------------------------------------------------- 1 | 6 | 17 | -------------------------------------------------------------------------------- /vb/components/upload/get-file-item.js: -------------------------------------------------------------------------------- 1 | export default function getFileItem(file, fileList) { 2 | const matchWay = (!file.uid) ? 'byName' : 'byUid'; 3 | 4 | const target = fileList.filter((item) => { 5 | if (matchWay === 'byName') { 6 | return item.name === file.name; 7 | } 8 | return item.uid === file.uid; 9 | })[0]; 10 | 11 | return target; 12 | } 13 | -------------------------------------------------------------------------------- /src/docs/zh-cn/polyfill.md: -------------------------------------------------------------------------------- 1 | # Polyfill 2 | vue-beauty使用了很多ES的最新语法进行开发,以下实例方法您可以直接在项目里使用。 3 | ## Array 4 | - find 5 | - findIndex 6 | - values 7 | - keys 8 | - entries 9 | - includes 10 | ## String 11 | - includes 12 | - startsWith 13 | - endsWith 14 | - repeat 15 | - padStart 16 | - padEnd 17 | - trimStart 18 | - trimEnd 19 | - at 20 | ## DOM collections 21 | - values 22 | - keys 23 | - entries 24 | - iterator 25 | -------------------------------------------------------------------------------- /vb/style/core/motion.less: -------------------------------------------------------------------------------- 1 | @import "../mixins/motion"; 2 | @import "motion/fade"; 3 | @import "motion/move"; 4 | @import "motion/other"; 5 | @import "motion/slide"; 6 | @import "motion/swing"; 7 | @import "motion/zoom"; 8 | 9 | // For common/openAnimation 10 | .ant-motion-collapse { 11 | overflow: hidden; 12 | &-active { 13 | transition: height .15s @ease-in-out, opacity .15s @ease-in-out !important; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /vb/components/button/style/button_vb.less: -------------------------------------------------------------------------------- 1 | .@{btn-prefix-cls} { 2 | .btn_generator(success); 3 | .btn_generator(info); 4 | .btn_generator(warning); 5 | .btn_generator(error); 6 | } 7 | 8 | .btn_generator(@type){ 9 | @color: ~"btn-@{type}-bg"; 10 | &-@{type} { 11 | .button-variant-primary(#fff, @@color); 12 | } 13 | &-@{type}&-clicked:after { 14 | border-color: @@color; 15 | } 16 | } 17 | 18 | .ant-btn-group > .ant-btn{ 19 | float: left 20 | } -------------------------------------------------------------------------------- /vb/style/mixins/margin.less: -------------------------------------------------------------------------------- 1 | 2 | .margin-side(@side,@size) { 3 | margin-@{side} : @size !important; 4 | } 5 | 6 | .margin(@size) { 7 | margin: @size !important; 8 | } 9 | 10 | .generate-margins(@n, @i: 5) when (@i =< @n) { 11 | .margin-@{i} { 12 | .margin(@i*1px); 13 | } 14 | .generate-margins(@n, (@i + 5)); 15 | } 16 | 17 | .generate-margins-side(@side, @n, @i: 5) when (@i =< @n) { 18 | .margin-@{side}-@{i} { 19 | .margin-side(@side,@i*1px); 20 | } 21 | .generate-margins-side(@side, @n, (@i + 5)); 22 | } -------------------------------------------------------------------------------- /vb/style/mixins/padding.less: -------------------------------------------------------------------------------- 1 | 2 | .padding-side(@side,@size) { 3 | padding-@{side} : @size !important; 4 | } 5 | 6 | .padding(@size) { 7 | padding: @size !important; 8 | } 9 | 10 | .generate-paddings(@n, @i: 5) when (@i =< @n) { 11 | .padding-@{i} { 12 | .padding(@i*1px); 13 | } 14 | .generate-paddings(@n, (@i + 5)); 15 | } 16 | 17 | .generate-paddings-side(@side, @n, @i: 5) when (@i =< @n) { 18 | .padding-@{side}-@{i} { 19 | .padding-side(@side,@i*1px); 20 | } 21 | .generate-paddings-side(@side, @n, (@i + 5)); 22 | } -------------------------------------------------------------------------------- /vb/components/slider/track.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 19 | -------------------------------------------------------------------------------- /vb/components/date-picker/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | @import "../../input/style/mixin"; 4 | @import "../../button/style/mixin"; 5 | 6 | @calendar-prefix-cls: ~"@{ant-prefix}-calendar"; 7 | @calendar-timepicker-prefix-cls: ~"@{ant-prefix}-calendar-time-picker"; 8 | 9 | @import "Picker"; 10 | @import "Calendar"; 11 | @import "RangePicker"; 12 | @import "TimePicker"; 13 | @import "MonthPanel"; 14 | @import "YearPanel"; 15 | @import "DecadePanel"; 16 | @import "MonthPicker"; 17 | -------------------------------------------------------------------------------- /vb/components/breadcrumb/breadcrumb-item.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /vb/components/data-table/table.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /vb/style/themes/default_vb.less: -------------------------------------------------------------------------------- 1 | @btn-success-bg : @success-color; 2 | @btn-info-bg : @blue-5; 3 | @btn-warning-bg : @warning-color; 4 | @btn-error-bg : @error-color; 5 | @dark-color : #000; 6 | 7 | // Container sizes 8 | @container-sm : (720px + @grid-gutter-width); 9 | @container-md : (940px + @grid-gutter-width); 10 | @container-lg : (1140px + @grid-gutter-width); 11 | 12 | @font-size-md : @font-size-base; 13 | @font-size-xl : @font-size-base + 4px; 14 | @font-size-xxl : @font-size-base + 6px; 15 | -------------------------------------------------------------------------------- /vb/directives/clickoutside.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bind(el, binding) { 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 | unbind(el) { 15 | document.removeEventListener('click', el.__vueClickOutside__); 16 | delete el.__vueClickOutside__; 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /vb/style/core/motion/fade.less: -------------------------------------------------------------------------------- 1 | .fade-motion(@className, @keyframeName) { 2 | .make-motion(@className, @keyframeName); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | opacity: 0; 6 | animation-timing-function: linear; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: linear; 10 | } 11 | } 12 | 13 | .fade-motion(fade, antFade); 14 | 15 | @keyframes antFadeIn { 16 | 0% { 17 | opacity: 0; 18 | } 19 | 100% { 20 | opacity: 1; 21 | } 22 | } 23 | 24 | @keyframes antFadeOut { 25 | 0% { 26 | opacity: 1; 27 | } 28 | 100% { 29 | opacity: 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /vb/components/button/button-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /vb/components/timeline/timeline.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | -------------------------------------------------------------------------------- /vb/components/tree/style/mixin.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/mixins/index"; 2 | 3 | @tree-default-open-icon: "\e606"; 4 | @tree-showline-open-icon: "\e621"; 5 | @tree-showline-close-icon: "\e645"; 6 | @tree-doc-icon: "\e664"; 7 | 8 | .antTreeSwitcherIcon(@type: "tree-default-open-icon") { 9 | &:after { 10 | .iconfont-size-under-12px(7px); 11 | display: inline-block; 12 | .iconfont-font(@@type); 13 | font-weight: bold; 14 | transition: transform .3s; 15 | } 16 | } 17 | 18 | .antTreeShowLineIcon(@type) { 19 | &:after { 20 | .iconfont-size-under-12px(12px); 21 | display: inline-block; 22 | .iconfont-font(@@type); 23 | vertical-align: baseline; 24 | font-weight: normal; 25 | transition: transform .3s; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import demoBox from './demoBox'; 2 | 3 | const compnents = { 4 | demoBox, 5 | }; 6 | 7 | for (const item of Object.values(compnents)) { 8 | if (!item.install && item.name) { 9 | item.install = function (Vue) { 10 | Vue.component(item.name, item); 11 | }; 12 | } 13 | } 14 | 15 | const install = function (Vue) { 16 | if (install.installed) return; 17 | 18 | for (const item of Object.values(compnents)) { 19 | if (item.install) { 20 | Vue.use(item); 21 | } 22 | } 23 | }; 24 | 25 | // auto install 26 | if (typeof window !== 'undefined' && window.Vue) { 27 | install(window.Vue); 28 | } 29 | 30 | export default { 31 | install, 32 | ...compnents, 33 | }; 34 | -------------------------------------------------------------------------------- /vb/utils/polyfill.js: -------------------------------------------------------------------------------- 1 | // es2015 2 | import 'core-js/fn/array/find'; 3 | import 'core-js/fn/array/find-index'; 4 | import 'core-js/fn/array/values'; 5 | import 'core-js/fn/array/keys'; 6 | import 'core-js/fn/array/entries'; 7 | 8 | import 'core-js/fn/string/includes'; 9 | import 'core-js/fn/string/starts-with'; 10 | import 'core-js/fn/string/ends-with'; 11 | import 'core-js/fn/string/repeat'; 12 | // es2016 13 | import 'core-js/fn/array/includes'; 14 | 15 | // stage 16 | import 'core-js/fn/string/pad-start'; 17 | import 'core-js/fn/string/pad-end'; 18 | import 'core-js/fn/string/trim-start'; 19 | import 'core-js/fn/string/trim-end'; 20 | import 'core-js/fn/string/at'; 21 | 22 | // web 23 | import 'core-js/web/dom-collections'; 24 | import 'core-js/fn/dom-collections/iterator'; 25 | -------------------------------------------------------------------------------- /vb/components/breadcrumb/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | 3 | @breadcrumb-prefix-cls: ~"@{ant-prefix}-breadcrumb"; 4 | 5 | .@{breadcrumb-prefix-cls} { 6 | color: @text-color-secondary; 7 | font-size: @font-size-base; 8 | 9 | a { 10 | color: @text-color; 11 | transition: color .3s; 12 | &:hover { 13 | color: @primary-5; 14 | } 15 | } 16 | 17 | & > span:last-child { 18 | font-weight: bold; 19 | color: @text-color; 20 | } 21 | 22 | & > span:last-child &-separator { 23 | display: none; 24 | } 25 | 26 | &-separator { 27 | margin: 0 8px; 28 | color: @border-color-base; 29 | } 30 | 31 | &-link { 32 | > .@{iconfont-css-prefix} + span { 33 | margin-left: 4px; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /vb/components/back-top/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | 3 | @backtop-prefix-cls: ~"@{ant-prefix}-back-top"; 4 | 5 | .@{backtop-prefix-cls} { 6 | z-index: @zindex-back-top; 7 | position: fixed; 8 | right: 100px; 9 | bottom: 50px; 10 | height: 40px; 11 | width: 40px; 12 | cursor: pointer; 13 | 14 | &-content { 15 | height: 40px; 16 | width: 40px; 17 | border-radius: 20px; 18 | background-color: rgba(64, 64, 64, 0.4); 19 | color: #fff; 20 | text-align: center; 21 | transition: all .3s @ease-in-out; 22 | 23 | &:hover { 24 | background-color: rgba(64, 64, 64, 0.6); 25 | transition: all .3s @ease-in-out; 26 | } 27 | } 28 | 29 | &-icon { 30 | font-size: 20px; 31 | margin-top: 10px; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vb/style/core/motion/swing.less: -------------------------------------------------------------------------------- 1 | .swing-motion(@className, @keyframeName) { 2 | .@{className}-enter, 3 | .@{className}-appear { 4 | .motion-common(); 5 | animation-play-state: paused; 6 | } 7 | .@{className}-enter.@{className}-enter-active, 8 | .@{className}-appear.@{className}-appear-active { 9 | animation-name: ~"@{keyframeName}In"; 10 | animation-play-state: running; 11 | } 12 | } 13 | 14 | .swing-motion(swing, antSwing); 15 | 16 | @keyframes antSwingIn { 17 | 0%, 18 | 100% { 19 | transform: translateX(0); 20 | } 21 | 20% { 22 | transform: translateX(-10px); 23 | } 24 | 40% { 25 | transform: translateX(10px); 26 | } 27 | 60% { 28 | transform: translateX(-5px); 29 | } 30 | 80% { 31 | transform: translateX(5px); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vb/components/icon/icon.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 34 | -------------------------------------------------------------------------------- /vb/components/input/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | @import "./mixin"; 4 | @import "./search-input"; 5 | 6 | // Input styles 7 | .@{ant-prefix}-input { 8 | .input; 9 | } 10 | 11 | //== Style for input-group: input with label, with button or dropdown... 12 | .@{ant-prefix}-input-group { 13 | .input-group(~"@{ant-prefix}-input"); 14 | &-wrapper { 15 | display: inline-block; 16 | vertical-align: top; // https://github.com/ant-design/ant-design/issues/6403 17 | width: 100%; 18 | } 19 | } 20 | 21 | // Input with affix: prefix or suffix 22 | .@{ant-prefix}-input-affix-wrapper { 23 | .input-affix-wrapper(~"@{ant-prefix}-input"); 24 | 25 | // https://github.com/ant-design/ant-design/issues/6144 26 | .@{ant-prefix}-input { 27 | min-height: 100%; // use min-height, assume that no smaller height to override 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vb/components/input/input-group.vue: -------------------------------------------------------------------------------- 1 | 6 | 31 | -------------------------------------------------------------------------------- /vb/components/message/message.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import vMessage from './message.vue'; 3 | 4 | vMessage.newInstance = (data) => { 5 | const _props = data || {}; 6 | 7 | const Instance = new Vue({ 8 | data: _props, 9 | render(h) { 10 | return h(vMessage, { 11 | props: _props, 12 | }); 13 | }, 14 | }); 15 | 16 | const component = Instance.$mount(); 17 | document.body.appendChild(component.$el); 18 | 19 | const message = Instance.$children[0]; 20 | 21 | return { 22 | notice(noticeProps) { 23 | message.add(noticeProps); 24 | }, 25 | 26 | removeNotice(key) { 27 | message.close(key); 28 | }, 29 | 30 | component: message, 31 | 32 | destroy() { 33 | message.destroy(); 34 | }, 35 | }; 36 | }; 37 | 38 | export default vMessage; 39 | 40 | -------------------------------------------------------------------------------- /static/children.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": [ 3 | { 4 | "id": 101, 5 | "name": "他大舅", 6 | "time": "03:37", 7 | "singer": "wyqbailey", 8 | "album": "他大舅他二舅都是他舅", 9 | "isparent":true 10 | }, 11 | { 12 | "id": 102, 13 | "name": "他二舅", 14 | "time": "03:37", 15 | "singer": "wyqbailey", 16 | "album": "他大舅他二舅都是他舅" 17 | }, 18 | { 19 | "id": 103, 20 | "name": "他三舅", 21 | "time": "03:37", 22 | "singer": "wyqbailey", 23 | "album": "他大舅他二舅都是他舅" 24 | }, 25 | { 26 | "id": 104, 27 | "name": "他四舅", 28 | "time": "03:37", 29 | "singer": "wyqbailey", 30 | "album": "他大舅他二舅都是他舅" 31 | } 32 | ], 33 | "totalCount":15, 34 | "pageSize":10, 35 | "pageNo":1 36 | } -------------------------------------------------------------------------------- /vb/components/carousel/carousel-item.vue: -------------------------------------------------------------------------------- 1 | 4 | 34 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | import 'highlight.js/styles/solarized-light.css'; 4 | import App from './App'; 5 | import routerMap from './routers'; 6 | // import 'highlight.js/styles/color-brewer.css'; 7 | import vueBeauty from '../vb'; 8 | // import '../package/style/vue-beauty.css'; 9 | // import vueBeauty from '../package/vue-beauty'; 10 | import components from './components'; 11 | // import locale from '../vb/locale/lang/en'; 12 | import locale from '../vb/locale/lang/zh-CN'; 13 | 14 | window.Promise = Promise; 15 | Vue.use(VueRouter); 16 | Vue.use(vueBeauty, { locale, size: '' }); 17 | Vue.use(components); 18 | 19 | window.Vue = Vue; 20 | Vue.config.productionTip = false; 21 | 22 | window.router = new VueRouter({ 23 | mode: 'hash', 24 | base: __dirname, 25 | routes: routerMap, 26 | }); 27 | 28 | new Vue({ 29 | el: '#app', 30 | router: window.router, 31 | render: h => h(App), 32 | }); 33 | -------------------------------------------------------------------------------- /vb/components/notification/notification.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import vNotification from './notification.vue'; 3 | 4 | vNotification.newInstance = (data) => { 5 | const _props = data || {}; 6 | 7 | const Instance = new Vue({ 8 | data: _props, 9 | render(h) { 10 | return h(vNotification, { 11 | props: _props, 12 | }); 13 | }, 14 | }); 15 | 16 | const component = Instance.$mount(); 17 | document.body.appendChild(component.$el); 18 | 19 | const notification = Instance.$children[0]; 20 | 21 | return { 22 | notice(noticeProps) { 23 | notification.add(noticeProps); 24 | }, 25 | 26 | removeNotice(key) { 27 | notification.close(key); 28 | }, 29 | 30 | component: notification, 31 | 32 | destroy() { 33 | notification.destroy(); 34 | }, 35 | }; 36 | }; 37 | 38 | export default vNotification; 39 | -------------------------------------------------------------------------------- /vb/components/modal/confirm.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import vConfirm from './confirm.vue'; 3 | 4 | vConfirm.newInstance = (properties = {}) => { 5 | const _props = properties; 6 | 7 | const Instance = new Vue({ 8 | data: _props, 9 | render(createElement) { 10 | return createElement(vConfirm, {}); 11 | }, 12 | computed: {}, 13 | methods: {}, 14 | }); 15 | const component = Instance.$mount(); 16 | document.body.appendChild(component.$el); 17 | 18 | const confirm = Instance.$children[0]; 19 | 20 | return { 21 | show(props) { 22 | for (const key in props) { 23 | if (typeof key !== 'function') { 24 | confirm[key] = props[key]; 25 | } 26 | } 27 | confirm.visible = true; 28 | }, 29 | remove() { 30 | confirm.$parent._remove(); 31 | }, 32 | }; 33 | }; 34 | 35 | export default vConfirm; 36 | -------------------------------------------------------------------------------- /vb/components/avatar/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | 3 | @avatar-prefix-cls: ~"@{ant-prefix}-avatar"; 4 | 5 | .@{avatar-prefix-cls} { 6 | display: inline-block; 7 | text-align: center; 8 | background: @avatar-bg; 9 | color: @avatar-color; 10 | white-space: nowrap; 11 | position: relative; 12 | overflow: hidden; 13 | 14 | .avatar-size(@avatar-size-base, @avatar-font-size-base); 15 | 16 | &-lg { 17 | .avatar-size(@avatar-size-lg, @avatar-font-size-lg); 18 | } 19 | 20 | &-sm { 21 | .avatar-size(@avatar-size-sm, @avatar-font-size-sm); 22 | } 23 | 24 | &-square { 25 | border-radius: @avatar-border-radius; 26 | } 27 | 28 | & > img { 29 | width: 100%; 30 | height: 100%; 31 | display: block; 32 | } 33 | } 34 | 35 | .avatar-size(@size, @font-size) { 36 | width: @size; 37 | height: @size; 38 | line-height: @size; 39 | border-radius: @size / 2; 40 | 41 | & > * { 42 | line-height: @size; 43 | } 44 | 45 | &.@{avatar-prefix-cls}-icon { 46 | font-size: @font-size; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vb/components/cascader/menu.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /vb/components/more-panel/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | 3 | @more-panel-prefix-cls: ~"@{ant-prefix}-more-panel"; 4 | 5 | .@{more-panel-prefix-cls} { 6 | background-color: #fff; 7 | border-radius: @border-radius-sm; 8 | font-size: @font-size-base; 9 | position: relative; 10 | padding: 15px; 11 | display: flex; 12 | border: 1px solid #e9e9e9; 13 | transition: all .3s; 14 | 15 | &:hover { 16 | box-shadow: @box-shadow-base; 17 | border-color: #eee; 18 | } 19 | 20 | &-body{ 21 | flex: 1; 22 | overflow:hidden; 23 | } 24 | &-form{ 25 | position: relative; 26 | display: inline-block; 27 | } 28 | 29 | &-control{ 30 | position: absolute; 31 | right:0; 32 | top:0; 33 | padding-top:2px; 34 | } 35 | 36 | &-btn{ 37 | cursor: pointer; 38 | border: 1px solid #e9e9e9; 39 | color: #96A1A7; 40 | border-radius: @border-radius-sm; 41 | width: 48px; 42 | text-align: center; 43 | line-height: 14px; 44 | position: absolute; 45 | left: 50%; 46 | bottom: -1px; 47 | margin-left: -1px; 48 | } 49 | } -------------------------------------------------------------------------------- /vb/components/layout/layout.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 vue-beauty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vb/mixins/emitter.js: -------------------------------------------------------------------------------- 1 | function broadcast(componentName, eventName, params) { 2 | for (const child of this.$children) { 3 | const name = child.$options.name; 4 | 5 | if (name === componentName) { 6 | child.$emit(...[eventName].concat(params)); 7 | } else { 8 | broadcast.apply(child, [componentName, eventName].concat([params])); 9 | } 10 | } 11 | } 12 | export default { 13 | methods: { 14 | dispatch(componentName, eventName, params) { 15 | let parent = this.$parent || this.$root; 16 | let name = parent.$options.name; 17 | 18 | while (parent && (!name || name !== componentName)) { 19 | parent = parent.$parent; 20 | 21 | if (parent) { 22 | name = parent.$options.name; 23 | } 24 | } 25 | if (parent) { 26 | parent.$emit(...[eventName].concat(params)); 27 | } 28 | }, 29 | broadcast(componentName, eventName, params) { 30 | broadcast.call(this, componentName, eventName, params); 31 | }, 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /vb/style/mixins/iconfont.less: -------------------------------------------------------------------------------- 1 | .iconfont-mixin() { 2 | display: inline-block; 3 | font-style: normal; 4 | vertical-align: baseline; 5 | text-align: center; 6 | text-transform: none; 7 | line-height: 1; 8 | text-rendering: optimizeLegibility; 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | &:before { 12 | display: block; 13 | font-family: "anticon" !important; 14 | } 15 | } 16 | 17 | .iconfont-font(@content) { 18 | font-family: 'anticon'; 19 | text-rendering: optimizeLegibility; 20 | -webkit-font-smoothing: antialiased; 21 | -moz-osx-font-smoothing: grayscale; 22 | content: @content; 23 | } 24 | 25 | // for iconfont font size 26 | // fix chrome 12px bug, support ie 27 | .iconfont-size-under-12px(@size, @rotate: 0deg) { 28 | display: inline-block; 29 | @font-scale: unit(@size / 12px); 30 | font-size: @font-size-base; 31 | // ie8-9 32 | font-size: ~"@{size} \9"; // lesshint duplicateProperty: false 33 | transform: scale(@font-scale) rotate(@rotate); 34 | .ie-rotate-via-degrees(@rotate); 35 | :root & { 36 | font-size: @font-size-base; // reset ie9 and above 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vb/locale/format.js: -------------------------------------------------------------------------------- 1 | /** 2 | * String format template 3 | * - Inspired: 4 | * https://github.com/Matt-Esch/string-template/index.js 5 | */ 6 | 7 | import { hasOwn } from '../utils/fn'; 8 | 9 | const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g; 10 | 11 | export default function () { 12 | /** 13 | * template 14 | * 15 | * @param {String} string 16 | * @param {Array} ...args 17 | * @return {String} 18 | */ 19 | 20 | function template(string, ...args) { 21 | if (args.length === 1 && typeof args[0] === 'object') { 22 | args = args[0]; 23 | } 24 | 25 | if (!args || !args.hasOwnProperty) { 26 | args = {}; 27 | } 28 | 29 | return string.replace(RE_NARGS, (match, prefix, i, index) => { 30 | if (string[index - 1] === '{' && 31 | string[index + match.length] === '}') { 32 | return i; 33 | } 34 | const result = hasOwn(args, i) ? args[i] : null; 35 | if (result === null || result === undefined) { 36 | return ''; 37 | } 38 | 39 | return result; 40 | }); 41 | } 42 | 43 | return template; 44 | } 45 | -------------------------------------------------------------------------------- /vb/components/upload/upload-list.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /vb/components/message/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | 3 | @message-prefix-cls: ~"@{ant-prefix}-message"; 4 | 5 | .@{message-prefix-cls} { 6 | font-size: @font-size-base; 7 | position: fixed; 8 | z-index: @zindex-message; 9 | width: 100%; 10 | top: 16px; 11 | left: 0; 12 | 13 | &-notice { 14 | width: auto; 15 | vertical-align: middle; 16 | position: absolute; 17 | left: 50%; 18 | } 19 | 20 | &-notice-content { 21 | position: relative; 22 | right: 50%; 23 | padding: 8px 16px; 24 | border-radius: @border-radius-base; 25 | box-shadow: @shadow-2; 26 | background: @component-background; 27 | display: block; 28 | } 29 | 30 | &-success .@{iconfont-css-prefix} { 31 | color: @success-color; 32 | } 33 | 34 | &-error .@{iconfont-css-prefix} { 35 | color: @error-color; 36 | } 37 | 38 | &-warning .@{iconfont-css-prefix} { 39 | color: @warning-color; 40 | } 41 | 42 | &-info .@{iconfont-css-prefix}, 43 | &-loading .@{iconfont-css-prefix} { 44 | color: @primary-color; 45 | } 46 | 47 | .@{iconfont-css-prefix} { 48 | margin-right: 8px; 49 | font-size: @font-size-lg; 50 | top: 1px; 51 | position: relative; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vb/components/timeline/timeline-item.vue: -------------------------------------------------------------------------------- 1 | 12 | 42 | -------------------------------------------------------------------------------- /vb/components/spin/spinInner.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 51 | -------------------------------------------------------------------------------- /vb/locale/lang/tr.js: -------------------------------------------------------------------------------- 1 | export default { 2 | select: { 3 | notFoundContent: 'bulunamadı', 4 | placeholder: 'lütfen seçin', 5 | loadingText: 'yükleniyor...' 6 | }, 7 | timePicker: { 8 | placeholder: 'saati seç' 9 | }, 10 | datePicker: { 11 | placeholder: 'tarihi seç', 12 | year: '', 13 | lastYear: 'geçen yıl', 14 | nextYear: 'gelecek yıl', 15 | lastMonth: 'geçen ay', 16 | nextMonth: 'gelecek ay', 17 | confirm: 'tamam', 18 | selectYear: 'yılı seçin', 19 | selectMonth: 'ayı seçin', 20 | selectTime: 'saati seçin', 21 | selectDate: 'tarihi seçin', 22 | days: 'Pzt, Sal, Çar, Per, Cum, Cmt, Paz', 23 | months: 'Ocak, Şubat, Mart, Nisan, Mayıs, Haziran, Temmuz, Ağustos, Eylül, Ekim, Kasım, Aralık' 24 | }, 25 | modal: { 26 | okText: 'Tamam', 27 | cancelText: 'İptal', 28 | justOkText: 'Anladım' 29 | }, 30 | popconfirm: { 31 | okText: 'Evet', 32 | cancelText: 'Hayır' 33 | }, 34 | input: { 35 | placeholder: 'Lütfen girin' 36 | }, 37 | transfer: { 38 | searchPlaceholder: 'Arama yapın', 39 | notFoundContent: 'Bulunamadı' 40 | }, 41 | treeSelect: { 42 | placeholder: 'lütfen seçin', 43 | }, 44 | } 45 | -------------------------------------------------------------------------------- /vb/components/tag/tag.vue: -------------------------------------------------------------------------------- 1 | 11 | 51 | -------------------------------------------------------------------------------- /vb/components/transfer/search.vue: -------------------------------------------------------------------------------- 1 | 12 | 50 | -------------------------------------------------------------------------------- /vb/style/mixins/compatibility.less: -------------------------------------------------------------------------------- 1 | // Compatibility for browsers. 2 | 3 | // rotate for ie8 and blow 4 | .ie-rotate(@rotation) { 5 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; 6 | } 7 | 8 | // rotate for ie8 and blow 9 | // degrees unit 10 | .ie-rotate-via-degrees(@degrees) { 11 | /* IE6-IE8 */ 12 | @radians: ~`parseInt("@{degrees}") * Math.PI * 2 / 360`; 13 | @costheta: ~`Math.cos("@{radians}")`; 14 | @sintheta: ~`Math.sin("@{radians}")`; 15 | @negsintheta: ~`"@{sintheta}" * -1`; 16 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=@{costheta}, M12=@{negsintheta}, M21=@{sintheta}, M22=@{costheta})"; 17 | zoom: 1; 18 | 19 | :root & { 20 | filter: none; 21 | } 22 | } 23 | 24 | // support rotate for all browsers 25 | .cross-rotate(@degrees) { 26 | .rotate(@degrees); 27 | .ie-rotate-via-degrees(@degrees); 28 | } 29 | 30 | // Placeholder text 31 | .placeholder(@color: @input-placeholder-color) { 32 | // Firefox 33 | &::-moz-placeholder { 34 | color: @color; 35 | opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526 36 | } 37 | // Internet Explorer 10+ 38 | &:-ms-input-placeholder { 39 | color: @color; 40 | } 41 | // Safari and Chrome 42 | &::-webkit-input-placeholder { 43 | color: @color; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /vb/components/spin/spin.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 53 | -------------------------------------------------------------------------------- /vb/style/mixins/motion.less: -------------------------------------------------------------------------------- 1 | @import '../themes/default'; 2 | 3 | .motion-common(@duration: @animation-duration-base) { 4 | animation-duration: @duration; 5 | animation-fill-mode: both; 6 | } 7 | 8 | .motion-common-leave(@duration: @animation-duration-base) { 9 | animation-duration: @duration; 10 | animation-fill-mode: both; 11 | } 12 | 13 | /* .make-motion(@className, @keyframeName, @duration: @animation-duration-base) { 14 | .@{className}-enter, 15 | .@{className}-appear { 16 | .motion-common(@duration); 17 | animation-play-state: paused; 18 | } 19 | .@{className}-leave { 20 | .motion-common-leave(@duration); 21 | animation-play-state: paused; 22 | } 23 | .@{className}-enter.@{className}-enter-active, 24 | .@{className}-appear.@{className}-appear-active { 25 | animation-name: ~"@{keyframeName}In"; 26 | animation-play-state: running; 27 | } 28 | .@{className}-leave.@{className}-leave-active { 29 | animation-name: ~"@{keyframeName}Out"; 30 | animation-play-state: running; 31 | pointer-events: none; 32 | } 33 | } */ 34 | 35 | .make-motion(@className, @keyframeName, @duration: @animation-duration-base) { 36 | .@{className}-enter-active { 37 | animation-duration: @duration; 38 | animation-name: ~"@{keyframeName}In"; 39 | } 40 | .@{className}-leave-active { 41 | animation-duration: @duration; 42 | animation-name: ~"@{keyframeName}Out"; 43 | pointer-events: none; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /vb/locale/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import deepmerge from 'deepmerge'; 3 | import defaultLang from './lang/zh-CN'; 4 | import Format from './format'; 5 | 6 | const format = Format(Vue); 7 | let lang = defaultLang; 8 | let merged = false; 9 | let i18nHandler = function () { 10 | const vuei18n = Object.getPrototypeOf(this || Vue).$t; 11 | if (typeof vuei18n === 'function') { 12 | if (!merged) { 13 | merged = true; 14 | Vue.locale( 15 | Vue.config.lang, 16 | deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true }), 17 | ); 18 | } 19 | return vuei18n.apply(this, arguments); 20 | } 21 | }; 22 | 23 | export const t = function (path, options) { 24 | let value = i18nHandler.apply(this, arguments); 25 | if (value !== null && value !== undefined) return value; 26 | 27 | const array = path.split('.'); 28 | let current = lang; 29 | 30 | for (let i = 0, j = array.length; i < j; i++) { 31 | const property = array[i]; 32 | value = current[property]; 33 | if (i === j - 1) return format(value, options); 34 | if (!value) return ''; 35 | current = value; 36 | } 37 | return ''; 38 | }; 39 | 40 | export const use = function (l) { 41 | lang = l || lang; 42 | }; 43 | 44 | export const i18n = function (fn) { 45 | i18nHandler = fn || i18nHandler; 46 | }; 47 | 48 | export default { use, t, i18n }; 49 | -------------------------------------------------------------------------------- /vb/components/carousel/style/carousel_vb.less: -------------------------------------------------------------------------------- 1 | .@{ant-prefix}-carousel { 2 | &-arrow { 3 | border: none; 4 | outline: 0; 5 | padding: 0; 6 | margin: 0; 7 | width: 36px; 8 | height: 36px; 9 | border-radius: 50%; 10 | cursor: pointer; 11 | display: none; 12 | position: absolute; 13 | top: 50%; 14 | z-index: 10; 15 | transform: translateY(-50%); 16 | transition: .2s; 17 | background-color: rgba(31,45,61,.11); 18 | color: #fff; 19 | text-align: center; 20 | font-size: 1em; 21 | font-family: inherit; 22 | line-height: inherit; 23 | 24 | &:hover { 25 | background-color: rgba(31, 45, 61, 0.5); 26 | } 27 | 28 | &-hover { 29 | display: inherit; 30 | opacity: 0; 31 | } 32 | 33 | &-always { 34 | display: inherit; 35 | } 36 | 37 | &.left { 38 | left: 16px; 39 | } 40 | &.right { 41 | right: 16px; 42 | } 43 | } 44 | &:hover &-arrow { 45 | opacity: 1; 46 | } 47 | 48 | & &-dots-outside { 49 | bottom: -10px; 50 | 51 | & > li > button { 52 | background: #8391a5; 53 | } 54 | & > li.slick-active > button { 55 | background: #8391a5; 56 | } 57 | } 58 | 59 | & &-dots-none { 60 | display: none; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vb/components/auto-complete/auto-complete.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 61 | -------------------------------------------------------------------------------- /vb/components/message/message.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 56 | -------------------------------------------------------------------------------- /vb/utils/fn.js: -------------------------------------------------------------------------------- 1 | // 返回当前页面相对于窗口显示区左上角的 X ,Y 的位置 2 | export function getScroll(top) { 3 | let ret = window[`page${top ? 'Y' : 'X'}Offset`]; 4 | const method = `scroll${top ? 'Top' : 'Left'}`; 5 | if (typeof ret !== 'number') { 6 | const d = window.document; 7 | // ie6,7,8 standard mode 8 | ret = d.documentElement[method]; 9 | if (typeof ret !== 'number') { 10 | // quirks mode 11 | ret = d.body[method]; 12 | } 13 | } 14 | return ret; 15 | } 16 | 17 | // 获取元素top,left,right,bottom的绝对位置 18 | export function getOffset(element, container = document.body) { 19 | const elRect = element.getBoundingClientRect(); 20 | const containerRect = container.getBoundingClientRect(); 21 | const clientTop = element.clientTop || container.clientTop || 0; 22 | const clientLeft = element.clientLeft || container.clientLeft || 0; 23 | let top; 24 | let left; 25 | 26 | if (container === document.body) { 27 | top = getScroll(true); 28 | left = getScroll(); 29 | } else { 30 | top = container.scrollTop - containerRect.top; 31 | left = container.scrollLeft - containerRect.left; 32 | } 33 | 34 | return { 35 | top: elRect.top + top - clientTop, 36 | left: elRect.left + left - clientLeft, 37 | right: elRect.right + left - clientLeft, 38 | bottom: elRect.bottom + top - clientTop, 39 | }; 40 | } 41 | 42 | export function hasOwn(obj, key) { 43 | return hasOwnProperty.call(obj, key); 44 | } 45 | -------------------------------------------------------------------------------- /src/docs/zh-cn/more-panel.md: -------------------------------------------------------------------------------- 1 | # MorePanel 更多条件面板 2 | 3 | 响应式地显示筛选条件。 4 | 5 | ## 何时使用 6 | 7 | 筛选条件太多需要隐藏时。 8 | 9 | ## 代码演示 10 | 11 | ::: demo 12 | 13 | #### 基本 14 | 最简单的用法,试着缩放窗口大小。 15 | 16 | 17 | ```html 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 查询 37 | 38 | ``` 39 | ::: 40 | 41 | ## API 42 | 43 | ### MorePanel Props 44 | | 属性 | 说明 | 类型 | 默认值 | 45 | |------------|----------------|-------------------|-------------| 46 | | originalHeight | 收起时morepanel的高度 | number/string | 34 | 47 | | controlStyle | 控制control slot包裹div的样式 | object | - | 48 | | slot:default | 默认的slot会位于面板的右侧 | slot node | - | 49 | | slot:form | form slot会位于面板的左侧,一般是搜索的表单区域 | slot node | - | 50 | | slot:control | control slot会跟在form slot后面,一般可以放置一些按钮,比如查询之类 | slot node | - | 51 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 50 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: '', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | dev: { 25 | env: require('./dev.env'), 26 | port: 3000, 27 | autoOpenBrowser: true, 28 | assetsSubDirectory: 'static', 29 | assetsPublicPath: '/', 30 | proxyTable: {}, 31 | // CSS Sourcemaps off by default because relative paths are "buggy" 32 | // with this option, according to the CSS-Loader README 33 | // (https://github.com/webpack/css-loader#sourcemaps) 34 | // In our experience, they generally work as expected, 35 | // just be aware of this issue when enabling this option. 36 | cssSourceMap: false 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vb/components/modal/style/confirm.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/mixins/index"; 2 | 3 | @confirm-prefix-cls: ~"@{ant-prefix}-confirm"; 4 | 5 | .@{confirm-prefix-cls} { 6 | .@{ant-prefix}-modal-header { 7 | display: none; 8 | } 9 | 10 | .@{ant-prefix}-modal-close { 11 | display: none; 12 | } 13 | 14 | .@{ant-prefix}-modal-body { 15 | padding: 30px 40px; 16 | } 17 | 18 | &-body-wrapper { 19 | .clearfix(); 20 | } 21 | 22 | &-body { 23 | .@{confirm-prefix-cls}-title { 24 | color: @text-color; 25 | font-weight: bold; 26 | font-size: @font-size-lg; 27 | } 28 | 29 | .@{confirm-prefix-cls}-content { 30 | margin-left: 42px; 31 | font-size: @font-size-base; 32 | color: @text-color; 33 | margin-top: 8px; 34 | } 35 | 36 | > .@{iconfont-css-prefix} { 37 | font-size: 24px; 38 | margin-right: 16px; 39 | padding: 0 1px; 40 | float: left; 41 | } 42 | } 43 | 44 | .@{confirm-prefix-cls}-btns { 45 | margin-top: 30px; 46 | float: right; 47 | 48 | button + button { 49 | margin-left: 10px; 50 | margin-bottom: 0; 51 | } 52 | } 53 | 54 | &-error &-body > .@{iconfont-css-prefix} { 55 | color: @error-color; 56 | } 57 | 58 | &-warning &-body > .@{iconfont-css-prefix}, 59 | &-confirm &-body > .@{iconfont-css-prefix} { 60 | color: @warning-color; 61 | } 62 | 63 | &-info &-body > .@{iconfont-css-prefix} { 64 | color: @info-color; 65 | } 66 | 67 | &-success &-body > .@{iconfont-css-prefix} { 68 | color: @success-color; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /vb/components/slider/dots.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 41 | -------------------------------------------------------------------------------- /src/docs/zh-cn/affix.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | # Affix 固钉 10 | 11 | 将页面元素钉在可视范围。 12 | 13 | ## 何时使用 14 | - 当内容区域比较长,需要滚动页面时,这部分内容对应的操作或者导航需要在滚动范围内始终展现。常用于侧边菜单和按钮组合。 15 | - 页面可视范围过小时,慎用此功能以免遮挡页面内容。 16 | 17 | ## 代码演示 18 | 19 | ::: demo 20 | 21 | #### 基本 22 | 最简单的用法。 23 | 24 | 25 | ```html 26 | 34 | ``` 35 | ::: 36 | 37 | ::: demo 38 | 39 | #### 固定状态改变的事件 40 | 可以获得是否固定的状态。 41 | 42 | 43 | ```html 44 | 49 | 50 | 57 | ``` 58 | ::: 59 | 60 | ## API 61 | 62 | ### Affix Props 63 | | 参数 | 说明 | 类型 | 默认值 | 64 | |------------|----------------|-------------------|-------------| 65 | | offsetTop | 距离窗口顶部达到指定偏移量后触发 | Number | - | 66 | | offsetBottom | 距离窗口底部达到指定偏移量后触发 | Number | - | 67 | 68 | ### Affix Events 69 | | 参数 | 说明 | 回调参数 | 70 | |------------|----------------|-------------------| 71 | | change | 固定状态改变时触发的事件 | affixed | 72 | -------------------------------------------------------------------------------- /vb/components/grid/row.vue: -------------------------------------------------------------------------------- 1 | 6 | 53 | 54 | -------------------------------------------------------------------------------- /vb/components/slider/marks.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 44 | -------------------------------------------------------------------------------- /vb/locale/lang/zh-CN.js: -------------------------------------------------------------------------------- 1 | export default { 2 | common: { 3 | placeholder1: '请选择', 4 | placeholder2: '请输入', 5 | }, 6 | select: { 7 | notFoundContent: '没有找到', 8 | loadingText: '加载中...', 9 | }, 10 | timePicker: { 11 | placeholder: '请选择时间', 12 | eliminate: '清除', 13 | }, 14 | datePicker: { 15 | placeholder: '请选择日期', 16 | year: '年', 17 | prevYear: '上一年', 18 | nextYear: '下一年', 19 | prevMonth: '上一月', 20 | nextMonth: '下一月', 21 | confirm: '确定', 22 | selectYear: '选择年份', 23 | selectMonth: '选择月份', 24 | selectTime: '选择时间', 25 | selectDate: '选择日期', 26 | days: '一,二,三,四,五,六,日', 27 | months: '1月,2月,3月,4月,5月,6月,7月,8月,9月,10月,11月,12月', 28 | today: '今天', 29 | yesterday: '昨天', 30 | last7days: '最近7天', 31 | thisMonth: '本月', 32 | lastMonth: '上个月', 33 | latelyMonth: '最近一个月', 34 | latelyYear: '最近一年', 35 | }, 36 | modal: { 37 | okText: '确定', 38 | cancelText: '取消', 39 | justOkText: '知道了', 40 | }, 41 | popconfirm: { 42 | okText: '是', 43 | cancelText: '否', 44 | }, 45 | transfer: { 46 | searchPlaceholder: '请输入搜索内容', 47 | notFoundContent: '列表为空', 48 | strip: '条', 49 | }, 50 | dataTable: { 51 | total: '共有 {total} 条数据', 52 | notFoundContent: '老板,没有找到你想要的信息......', 53 | }, 54 | pagination: { 55 | prev: '上一页', 56 | next: '下一页', 57 | forward5: '向前5页', 58 | backward5: '向后5页', 59 | goto: '跳至', 60 | page: '页', 61 | pageSize: '条/页', 62 | }, 63 | }; 64 | -------------------------------------------------------------------------------- /vb/components/collapse/panel.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 54 | -------------------------------------------------------------------------------- /vb/components/input/style/search-input.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | @import "../../button/style/mixin"; 4 | @import "./mixin"; 5 | 6 | .@{ant-prefix}-input-search-icon { 7 | cursor: pointer; 8 | transition: all .3s; 9 | font-size: 14px; 10 | &:hover { 11 | color: @input-hover-border-color; 12 | } 13 | } 14 | 15 | // code blow is keeped for compatibility 16 | // for this demo: http://1x.ant.design/components/select/#components-select-demo-search-box 17 | // do not delete until 3.x 18 | .@{ant-prefix}-search-input-wrapper { 19 | display: inline-block; 20 | vertical-align: middle; 21 | } 22 | 23 | .@{ant-prefix}-search-input { 24 | &.@{ant-prefix}-input-group .@{ant-prefix}-input:first-child, 25 | &.@{ant-prefix}-input-group .@{ant-prefix}-select:first-child { 26 | border-radius: @border-radius-base; 27 | position: absolute; 28 | top: -1px; 29 | width: 100%; 30 | } 31 | 32 | &.@{ant-prefix}-input-group .@{ant-prefix}-input:first-child { 33 | padding-right: 36px; 34 | } 35 | 36 | .@{ant-prefix}-search-btn { 37 | .btn-default; 38 | border-radius: 0 @border-radius-base - 1px @border-radius-base - 1px 0; 39 | left: -1px; 40 | position: relative; 41 | border-width: 0 0 0 1px; 42 | z-index: 2; 43 | padding-left: 8px; 44 | padding-right: 8px; 45 | &:hover { 46 | border-color: @border-color-base; 47 | } 48 | } 49 | &&-focus .@{ant-prefix}-search-btn-noempty, 50 | &:hover .@{ant-prefix}-search-btn-noempty { 51 | .btn-primary; 52 | } 53 | .@{ant-prefix}-select-combobox { 54 | .@{ant-prefix}-select-selection__rendered { 55 | margin-right: 29px; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vb/components/rate/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | 4 | @rate-prefix-cls: ~"@{ant-prefix}-rate"; 5 | @rate-star-color: #f5a623; 6 | 7 | .@{rate-prefix-cls} { 8 | margin: 0; 9 | padding: 0; 10 | list-style: none; 11 | font-size: 20px; 12 | display: inline-block; 13 | vertical-align: middle; 14 | font-family: 'anticon'; 15 | font-weight: normal; 16 | font-style: normal; 17 | 18 | &-disabled &-star { 19 | &:before, 20 | &-content:before { 21 | cursor: default; 22 | } 23 | &:hover { 24 | transform: scale(1); 25 | } 26 | } 27 | 28 | &-star { 29 | margin: 0; 30 | padding: 0; 31 | display: inline-block; 32 | margin-right: 8px; 33 | position: relative; 34 | transition: all 0.3s ease; 35 | 36 | &:hover { 37 | transform: scale(1.1); 38 | } 39 | 40 | &:before, 41 | &-content:before { 42 | color: #e9e9e9; 43 | cursor: pointer; 44 | content: "\e660"; 45 | transition: all 0.3s ease; 46 | display: block; 47 | } 48 | 49 | &-content { 50 | position: absolute; 51 | left: 0; 52 | top: 0; 53 | width: 50%; 54 | height: 100%; 55 | overflow: hidden; 56 | &:before { 57 | color: transparent; 58 | } 59 | } 60 | 61 | &-half &-content:before, 62 | &-full:before { 63 | color: @rate-star-color; 64 | } 65 | 66 | &-half:hover &-content:before, 67 | &-full:hover:before { 68 | color: tint(@rate-star-color, 20%); 69 | } 70 | } 71 | 72 | &-text { 73 | margin-left: 8px; 74 | vertical-align: middle; 75 | display: inline-block; 76 | font-size: @font-size-base; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /vb/locale/lang/jp.js: -------------------------------------------------------------------------------- 1 | export default { 2 | common: { 3 | placeholder1: '選択してください', 4 | placeholder2: '入力してください', 5 | }, 6 | select: { 7 | notFoundContent: '見つかりませんでした', 8 | loadingText: 'ロード中...', 9 | }, 10 | timePicker: { 11 | placeholder: '時間を選択してください', 12 | eliminate: 'クリア', 13 | }, 14 | datePicker: { 15 | placeholder: '日付を選択してください', 16 | year: '年', 17 | prevYear: '前年', 18 | nextYear: '次の年', 19 | prevMonth: '先月', 20 | nextMonth: '翌月', 21 | confirm: '確定する', 22 | selectYear: '年の選択', 23 | selectMonth: '月の選択', 24 | selectTime: '選択時間', 25 | selectDate: '日付の選択', 26 | days: '月,火,水,木,金,土,日', 27 | months: '1月,2月,3月,4月,5月,6月,7月,8月,9月,10月,11月,12月', 28 | today: '今日', 29 | yesterday: '昨日', 30 | last7days: '最近7日間', 31 | thisMonth: '今月', 32 | lastMonth: '先月', 33 | latelyMonth: '最近1ヶ月', 34 | latelyYear: '最近1年', 35 | }, 36 | modal: { 37 | okText: '確定する', 38 | cancelText: 'キャンセル', 39 | justOkText: 'はい', 40 | }, 41 | popconfirm: { 42 | okText: 'はい', 43 | cancelText: 'いいえ', 44 | }, 45 | transfer: { 46 | searchPlaceholder: '検索を入力してください', 47 | notFoundContent: 'リストが空です', 48 | strip: '条', 49 | }, 50 | dataTable: { 51 | total: '{total} 個のデータ', 52 | notFoundContent: 'ご希望の情報が見つかりませんでした......', 53 | }, 54 | pagination: { 55 | prev: '前のページ', 56 | next: '次のページ', 57 | forward5: '前へ5ページ', 58 | backward5: '後ろへ5ページ', 59 | goto: 'ジャンプ先', 60 | page: 'ページ', 61 | pageSize: 'レコード/ページ', 62 | }, 63 | }; 64 | -------------------------------------------------------------------------------- /vb/components/modal/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import vModal from './modal'; 3 | import vConfirm from './confirm'; 4 | 5 | 6 | let modalInstance; 7 | 8 | function getModalInstance() { 9 | modalInstance = modalInstance || vConfirm.newInstance({ 10 | prefixCls: 'ant-confirm', 11 | okLoading: false, 12 | cancelLoading: false, 13 | }); 14 | 15 | return modalInstance; 16 | } 17 | 18 | function confirm(options) { 19 | // const render = ('render' in options) ? options.render : undefined; 20 | const instance = getModalInstance(); 21 | 22 | instance.show(options); 23 | } 24 | 25 | vModal.confirm = (options) => { 26 | const config = Object.assign({ 27 | type: 'confirm', 28 | okCancel: true, 29 | }, options); 30 | confirm(config); 31 | }; 32 | 33 | vModal.info = (options) => { 34 | const config = Object.assign({ 35 | type: 'info', 36 | iconType: 'info-circle', 37 | okCancel: false, 38 | }, options); 39 | confirm(config); 40 | }; 41 | 42 | vModal.success = (options) => { 43 | const config = Object.assign({ 44 | type: 'success', 45 | iconType: 'check-circle', 46 | okCancel: false, 47 | }, options); 48 | confirm(config); 49 | }; 50 | 51 | vModal.error = (options) => { 52 | const config = Object.assign({ 53 | type: 'error', 54 | iconType: 'cross-circle', 55 | okCancel: false, 56 | }, options); 57 | confirm(config); 58 | }; 59 | 60 | vModal.warning = (options) => { 61 | const config = Object.assign({ 62 | type: 'warning', 63 | iconType: 'exclamation-circle', 64 | okCancel: false, 65 | }, options); 66 | confirm(config); 67 | }; 68 | 69 | export default vModal; 70 | -------------------------------------------------------------------------------- /vb/components/tabs/tab-pane.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

6 | 7 | # vue-beauty [![npm](http://img.shields.io/npm/v/vue-beauty.svg)](https://www.npmjs.com/package/vue-beauty) [![NPM downloads](http://img.shields.io/npm/dm/vue-beauty.svg)](https://www.npmjs.com/package/vue-beauty) [![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://www.npmjs.com/package/vue-beauty) 8 | Beautiful UI components build with vue and ant design 9 | 10 | ## 特性 11 | - 丰富的组件,涵盖常用场景 12 | - 基于vue组件化开发,数据驱动视图 13 | - 封装复杂性,提供简单友好的api 14 | - 基于ant design样式优化 15 | 16 | ## 引入 17 | 使用npm或者yarn 18 | ``` 19 | npm install vue-beauty -S OR yarn add vue-beauty 20 | 21 | import Vue from 'vue' 22 | //import css 23 | import 'vue-beauty/package/style/vue-beauty.min.css' 24 | 25 | //import components 26 | import vueBeauty from 'vue-beauty' 27 | Vue.use(vueBeauty) 28 | 29 | //OR 30 | import {alert} from 'vue-beauty' 31 | Vue.use(alert) 32 | ``` 33 | 或使用 <script> 全局引用 34 | ``` 35 | 36 | 37 | ``` 38 | 更多说明,请查看我们的[在线文档](https://fe-driver.github.io/vue-beauty)。 39 | 40 | ## 浏览器支持 41 | chrome、firefox、暂不支持IE(计划支持IE11+)。 42 | 43 | ## Polyfill 44 | 本组件库内置了一些es最新实例方法的垫片,请查看[Polyfill](https://fe-driver.github.io/vue-beauty/#/components/polyfill)。 45 | 46 | ## 更新日志 47 | 欢迎查看详细的[更新日志](https://github.com/FE-Driver/vue-beauty/releases)。 48 | 49 | ## 参与贡献 50 | 我们欢迎任何形式的贡献,请阅读[贡献指南](https://fe-driver.github.io/vue-beauty/#/components/contribute)了解详细的情况。 51 | 52 | ## 链接 53 | - [Vue官网](http://cn.vuejs.org//) 54 | - [Ant.Design官网](http://ant.design/) -------------------------------------------------------------------------------- /vb/components/date-picker/style/DecadePanel.less: -------------------------------------------------------------------------------- 1 | .@{calendar-prefix-cls}-decade-panel { 2 | position: absolute; 3 | top: 0; 4 | right: 0; 5 | bottom: 0; 6 | left: 0; 7 | z-index: 10; 8 | background: @component-background; 9 | border-radius: @border-radius-base; 10 | outline: none; 11 | } 12 | 13 | .@{calendar-prefix-cls}-decade-panel-hidden { 14 | display: none; 15 | } 16 | 17 | .@{calendar-prefix-cls}-decade-panel-header { 18 | .calendarPanelHeader(~"@{calendar-prefix-cls}-decade-panel"); 19 | } 20 | 21 | .@{calendar-prefix-cls}-decade-panel-body { 22 | height: ~"calc(100% - 34px)"; 23 | } 24 | 25 | .@{calendar-prefix-cls}-decade-panel-table { 26 | table-layout: fixed; 27 | width: 100%; 28 | height: 100%; 29 | border-collapse: separate; 30 | } 31 | 32 | .@{calendar-prefix-cls}-decade-panel-cell { 33 | text-align: center; 34 | white-space: nowrap; 35 | } 36 | 37 | .@{calendar-prefix-cls}-decade-panel-decade { 38 | display: inline-block; 39 | margin: 0 auto; 40 | color: @text-color; 41 | background: transparent; 42 | text-align: center; 43 | height: 24px; 44 | line-height: 24px; 45 | padding: 0 6px; 46 | border-radius: 4px; 47 | transition: background 0.3s ease; 48 | 49 | &:hover { 50 | background: @primary-1; 51 | cursor: pointer; 52 | } 53 | } 54 | 55 | .@{calendar-prefix-cls}-decade-panel-selected-cell .@{calendar-prefix-cls}-decade-panel-decade { 56 | background: @primary-color; 57 | color: #fff; 58 | 59 | &:hover { 60 | background: @primary-color; 61 | color: #fff; 62 | } 63 | } 64 | 65 | .@{calendar-prefix-cls}-decade-panel-last-century-cell, 66 | .@{calendar-prefix-cls}-decade-panel-next-century-cell { 67 | .@{calendar-prefix-cls}-decade-panel-decade { 68 | user-select: none; 69 | color: @disabled-color; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/docs/zh-cn/contribute.md: -------------------------------------------------------------------------------- 1 | ## 目录结构 2 | ```` 3 | VUE-BEAUTY/ 4 | |-- build 存放webpack的配置 5 | |-- vb 组件库 6 | | |-- components 组件 7 | | |-- directives 指令 8 | | |-- locale 多语言 9 | | |-- mixins 混合 10 | | |-- style 核心样式 11 | | |-- utils 工具方法 12 | | `-- index.js 入口 13 | `-- src 存放文档 14 | |-- views 视图页面 15 | |-- docs 组件文档 16 | |-- components 业务组件 17 | |-- main.js 入口 18 | `-- routers.js 路由 19 | ```` 20 | ## 参与流程 21 | - 我们会通过issue的形式发布一系列任务 22 | - 在任务issue下面回复并认领 23 | - 根据某个issue,fork并在next分支下实现 24 | - 提交pr到next分支 25 | - 合并pr,测试并发布到master分支 26 | - NOTICE:可以加入QQ群548062121讨论 27 | ## 开发步骤 28 | - 在vb/components建立组件的文件夹,比如xxx,里面包含style文件夹、index.js、xxx.vue 29 | - 到[ant-design](https://github.com/ant-design/ant-design/tree/master/components)官网拷贝相应的样式到vb/components/xxx的style文件夹下 30 | - 在index.js里面引入样式并导出组件 31 | - 开发完组件后,需要在vb/components/index.js里面导出 32 | - 到src/docs下编写组件的使用文档 33 | - 同时在下列文件:src/routers.js、src/views/components.vue,添加组件的路由和链接 34 | - NOTICE:如果你需要增加样式,可以在组件对应的style目录中增加xxx_vb.less(如button_vb.less),并在style/index.less中import该样式文件 35 | ## 命名规范 36 | - 文件,目录均以横线连接(如data-table) 37 | - 组件的name均以大写开头,驼峰式(如TreeSelect) 38 | ## ES语法说明 39 | - .babelrc配置了preset-latest保证新的语法支持(如const、let) 40 | - .babelrc配置了transform-runtime保证新的全局对象和全局对象上的方法的支持(如Promise、Object.assign) 41 | - vb/utils/polyfill.js配置了可以使用的实例方法(如'abc'.includes('a')) 42 | ## 感谢 43 | - 感谢为这个项目做过贡献的所有朋友。 44 | - 感谢vue和ant design的开发者。 45 | ## 开发环境搭建 46 | 首先你需要安装Node.js 4+、yarn 47 | ````javascript 48 | git clone your fork 49 | yarn 50 | npm run dev 51 | ```` 52 | ## 代码规范 53 | 参考Airbnb的JavaScript风格规范。 -------------------------------------------------------------------------------- /src/docs/zh-cn/spin.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | # Spin 加载中 10 | 11 | 用于页面和区块的加载中状态。 12 | 13 | ## 何时使用 14 | 15 | 页面局部处于等待异步数据或正在渲染过程时,合适的加载动效会有效缓解用户的焦虑。 16 | 17 | ## 代码演示 18 | 19 | ::: demo 20 | 21 | 22 | #### 基本 23 | 一个简单的 loading 状态 24 | 25 | 26 | ```html 27 | 28 | ``` 29 | ::: 30 | 31 | ::: demo 32 | 33 | #### 自定义描述文案 34 | 自定义描述文案,指定的 tip 文案会直接代替 ... 35 | 36 | 37 | 38 | ```html 39 | 40 | 43 | 44 | ``` 45 | ::: 46 | 47 | 48 | ::: demo 49 | 50 | #### 各种大小 51 | 小的用于文本加载,默认用于卡片容器级加载,大的用于页面级加载。 52 | 53 | 54 | 55 | ```html 56 | 57 | 58 | 59 | ``` 60 | ::: 61 | 62 | ::: demo 63 | 64 | #### 卡片加载中 65 | 可以直接把内容内嵌到 Spin 中,将现有容器变为加载状态。 66 | 67 | 68 | 69 | ```html 70 | 77 | 55 | -------------------------------------------------------------------------------- /vb/components/collapse/collapse.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 57 | -------------------------------------------------------------------------------- /vb/components/date-picker/style/YearPanel.less: -------------------------------------------------------------------------------- 1 | .@{calendar-prefix-cls}-year-panel { 2 | position: absolute; 3 | top: 1px; 4 | right: 0; 5 | bottom: 0; 6 | left: 0; 7 | z-index: 10; 8 | border-radius: @border-radius-base; 9 | background: @component-background; 10 | outline: none; 11 | 12 | > div { // TODO: this is a useless wrapper, and we need to remove it in rc-calendar 13 | height: 100%; 14 | } 15 | } 16 | 17 | .@{calendar-prefix-cls}-year-panel-hidden { 18 | display: none; 19 | } 20 | 21 | .@{calendar-prefix-cls}-year-panel-header { 22 | .calendarPanelHeader(~"@{calendar-prefix-cls}-year-panel"); 23 | } 24 | 25 | .@{calendar-prefix-cls}-year-panel-body { 26 | height: ~"calc(100% - 34px)"; 27 | } 28 | 29 | .@{calendar-prefix-cls}-year-panel-table { 30 | table-layout: fixed; 31 | width: 100%; 32 | height: 100%; 33 | border-collapse: separate; 34 | } 35 | 36 | .@{calendar-prefix-cls}-year-panel-cell { 37 | text-align: center; 38 | } 39 | 40 | .@{calendar-prefix-cls}-year-panel-year { 41 | display: inline-block; 42 | margin: 0 auto; 43 | color: @text-color; 44 | background: transparent; 45 | text-align: center; 46 | height: 24px; 47 | line-height: 24px; 48 | padding: 0 6px; 49 | border-radius: 4px; 50 | transition: background 0.3s ease; 51 | 52 | &:hover { 53 | background: @primary-1; 54 | cursor: pointer; 55 | } 56 | } 57 | 58 | .@{calendar-prefix-cls}-year-panel-selected-cell .@{calendar-prefix-cls}-year-panel-year { 59 | background: @primary-color; 60 | color: #fff; 61 | 62 | &:hover { 63 | background: @primary-color; 64 | color: #fff; 65 | } 66 | } 67 | 68 | .@{calendar-prefix-cls}-year-panel-last-decade-cell, 69 | .@{calendar-prefix-cls}-year-panel-next-decade-cell { 70 | .@{calendar-prefix-cls}-year-panel-year { 71 | user-select: none; 72 | color: @disabled-color; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vb/components/upload/request.js: -------------------------------------------------------------------------------- 1 | function getError(option, xhr) { 2 | const msg = `cannot post ${option.action} ${xhr.status}`; 3 | const err = new Error(msg); 4 | err.status = xhr.status; 5 | err.method = 'post'; 6 | err.url = option.action; 7 | return err; 8 | } 9 | 10 | function getBody(xhr) { 11 | const text = xhr.responseText || xhr.response; 12 | if (!text) { 13 | return text; 14 | } 15 | 16 | try { 17 | return JSON.parse(text); 18 | } catch (e) { 19 | return text; 20 | } 21 | } 22 | 23 | export default function upload(option) { 24 | if (typeof XMLHttpRequest === 'undefined') { 25 | return; 26 | } 27 | 28 | const xhr = new XMLHttpRequest(); 29 | if (xhr.upload) { 30 | xhr.upload.onprogress = (e) => { 31 | if (e.total > 0) { 32 | e.percent = e.loaded / e.total * 100; 33 | } 34 | option.onProgress(e); 35 | }; 36 | } 37 | 38 | const formData = new FormData(); 39 | // formData.append('enctype', 'multipart/form-data'); 40 | formData.append(option.filename, option.file); 41 | if (option.data) { 42 | for (const key in option.data) { 43 | formData.append(key, option.data[key]); 44 | } 45 | } 46 | 47 | xhr.onerror = (e) => { 48 | option.onError(e); 49 | }; 50 | 51 | xhr.onload = () => { 52 | if (xhr.status !== 200) { 53 | return option.onError(getError(option, xhr), getBody(xhr)); 54 | } 55 | 56 | option.onSuccess(getBody(xhr)); 57 | }; 58 | xhr.open('post', option.action, true); 59 | if (option.header) { 60 | for (const key in option.header) { 61 | xhr.setRequestHeader(key, option.header[key]); 62 | } 63 | } 64 | // xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest') 65 | xhr.send(formData); 66 | } 67 | -------------------------------------------------------------------------------- /vb/locale/lang/en.js: -------------------------------------------------------------------------------- 1 | export default { 2 | common: { 3 | placeholder1: 'please select', 4 | placeholder2: 'please enter', 5 | }, 6 | select: { 7 | notFoundContent: 'not found', 8 | loadingText: 'loding...', 9 | }, 10 | timePicker: { 11 | placeholder: 'select time', 12 | eliminate: 'eliminate', 13 | }, 14 | datePicker: { 15 | placeholder: 'please select date', 16 | year: '', 17 | prevYear: 'prev year', 18 | nextYear: 'next year', 19 | prevMonth: 'prev month', 20 | nextMonth: 'next month', 21 | confirm: 'ok', 22 | selectYear: 'select year', 23 | selectMonth: 'select month', 24 | selectTime: 'select time', 25 | selectDate: 'select date', 26 | days: 'Mo,Tu,We,Th,Fr,Sa,Su', 27 | months: 'January,February,March,April,May,June,July,August,September,October,November,December', 28 | today: 'Today', 29 | yesterday: 'Yesterday', 30 | last7days: 'The last 7 days', 31 | thisMonth: 'This month', 32 | lastMonth: 'Last month', 33 | latelyMonth: 'The last month', 34 | latelyYear: 'The last year', 35 | }, 36 | modal: { 37 | okText: 'OK', 38 | cancelText: 'Cancel', 39 | justOkText: 'Got it!', 40 | }, 41 | popconfirm: { 42 | okText: 'Yes', 43 | cancelText: 'No', 44 | }, 45 | transfer: { 46 | searchPlaceholder: 'Search here', 47 | notFoundContent: 'Not Found', 48 | strip: '', 49 | }, 50 | dataTable: { 51 | total: 'Total {total}', 52 | notFoundContent: 'Not Found', 53 | }, 54 | pagination: { 55 | prev: 'Prev', 56 | next: 'Next', 57 | forward5: '5 pages forward', 58 | backward5: '5 pages backward', 59 | goto: 'Go to', 60 | page: 'page', 61 | pageSize: '/page', 62 | }, 63 | }; 64 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | extends: 'airbnb-base', 13 | // required to lint *.vue files 14 | plugins: [ 15 | 'html' 16 | ], 17 | // check if imports actually resolve 18 | 'settings': { 19 | 'import/resolver': { 20 | 'webpack': { 21 | 'config': 'build/webpack.base.conf.js' 22 | } 23 | } 24 | }, 25 | // add your custom rules here 26 | 'rules': { 27 | // don't require .vue extension when importing 28 | 'import/extensions': ['error', 'always', { 29 | 'js': 'never', 30 | 'vue': 'never' 31 | }], 32 | // allow optionalDependencies 33 | 'import/no-extraneous-dependencies': ['error', { 34 | 'optionalDependencies': ['test/unit/index.js'] 35 | }], 36 | // allow debugger during development 37 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 38 | 'global-require': 0, 39 | 'no-multi-assign': 0, 40 | 'linebreak-style': 0, 41 | 'indent': ["error", 4, { "SwitchCase": 1 }], 42 | 'import/no-unresolved': 0, 43 | 'no-restricted-syntax': 0, 44 | 'no-plusplus': 0, 45 | 'guard-for-in': 0, 46 | 'no-new': 0, 47 | 'no-return-assign': 0, 48 | 'consistent-return': 0, 49 | 'no-mixed-operators': 0, 50 | 'no-param-reassign': 0, 51 | 'no-return-reassign': 0, 52 | 'max-len': 0, 53 | 'no-unused-expressions': 0, 54 | 'import/no-dynamic-require': 0, 55 | 'no-underscore-dangle': 0, 56 | 'prefer-arrow-callback': 0, 57 | 'no-continue': 0, 58 | 'yoda': 1, 59 | 'prefer-destructuring': 0, 60 | 'no-restricted-globals': 0, 61 | 'object-curly-newline': 0, 62 | 'operator-assignment': 0, 63 | 'no-prototype-builtins': 0, 64 | 'no-case-declarations': 0, 65 | 'prefer-rest-params': 0, 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/views/layout-fixed.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 45 | 46 | 56 | -------------------------------------------------------------------------------- /src/docs/zh-cn/avatar.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Avatar 头像 8 | 9 | 用来代表用户或事物,支持图片、图标或字符展示。 10 | 11 | ## 代码演示 12 | 13 | ::: demo 14 | 15 | #### 基本 16 | 头像有三种尺寸,两种形状可选。 17 | 18 | 19 | ```html 20 | 32 | ``` 33 | ::: 34 | 35 | ::: demo 36 | 37 | #### 类型 38 | 支持三种类型:图片、Icon 以及字符,其中 Icon 和字符型可以自定义图标颜色及背景色。 39 | 40 | 41 | ```html 42 | 52 | ``` 53 | ::: 54 | 55 | ::: demo 56 | 57 | #### 带徽标的头像 58 | 通常用于消息提示 59 | 60 | 61 | ```html 62 | 66 | ``` 67 | ::: 68 | 69 | ## API 70 | 71 | ### Affix Props 72 | | 参数 | 说明 | 类型 | 默认值 | 73 | |------------|----------------|-------------------|-------------| 74 | | icon | 设置头像的图标类型,参考 `Icon` 组件 | String | - | 75 | | shape | 指定头像的形状(square、circle) | String | circle | 76 | | size | 设置头像的大小(large、small、default) | String | default | 77 | | src | 图片类头像的资源地址 | String | - | 78 | -------------------------------------------------------------------------------- /vb/style/color/colorPalette.less: -------------------------------------------------------------------------------- 1 | @import "bezierEasing"; 2 | @import "tinyColor"; 3 | 4 | // We create a very complex algorithm which take the place of original tint/shade color system 5 | // to make sure no one can understand it 👻 6 | // and create an entire color palette magicly by inputing just a single primary color. 7 | // We are using bezier-curve easing function and some color manipulations like tint/shade/darken/spin 8 | .colorPaletteMixin() { 9 | @functions: ~`(function() { 10 | var warmDark = 0.5; // warm color darken radio 11 | var warmRotate = -26; // warm color rotate degree 12 | var coldDark = 0.55; // cold color darken radio 13 | var coldRotate = 10; // cold color rotate degree 14 | var getShadeColor = function(c) { 15 | var shadeColor = tinycolor(c); 16 | // warm and cold color will darken in different radio, and rotate in different degree 17 | // warmer color 18 | if (shadeColor.toRgb().r > shadeColor.toRgb().b) { 19 | return shadeColor.darken(shadeColor.toHsl().l * warmDark * 100).spin(warmRotate).toHexString(); 20 | } 21 | // colder color 22 | return shadeColor.darken(shadeColor.toHsl().l * coldDark * 100).spin(coldRotate).toHexString(); 23 | } 24 | var primaryEasing = colorEasing(0.6); 25 | this.colorPalette = function(color, index) { 26 | var currentEasing = colorEasing(index * 0.1); 27 | // return light colors after tint 28 | if (index <= 6) { 29 | return tinycolor.mix( 30 | '#ffffff', 31 | color, 32 | currentEasing * 100 / primaryEasing 33 | ).toHexString(); 34 | } 35 | return tinycolor.mix( 36 | getShadeColor(color), 37 | color, 38 | (1 - (currentEasing - primaryEasing) / (1 - primaryEasing)) * 100 39 | ).toHexString(); 40 | }; 41 | })()`; 42 | } 43 | // It is hacky way to make this function will be compiled preferentially by less 44 | // resolve error: `ReferenceError: colorPalette is not defined` 45 | // https://github.com/ant-design/ant-motion/issues/44 46 | .colorPaletteMixin(); 47 | -------------------------------------------------------------------------------- /vb/components/message/index.js: -------------------------------------------------------------------------------- 1 | import './style/index.less'; 2 | import Message from './message'; 3 | 4 | let defaultDuration = 1.5; 5 | let top = 24; 6 | let messageInstance; 7 | let key = 1; 8 | 9 | function getMessageInstance() { 10 | messageInstance = 11 | messageInstance || 12 | Message.newInstance({ 13 | top, 14 | }); 15 | 16 | return messageInstance; 17 | } 18 | 19 | function notice(content, duration = defaultDuration, onClose, selfKey, type) { 20 | const instance = getMessageInstance(); 21 | 22 | instance.notice({ 23 | selfKey: selfKey || `${key}`, 24 | duration, 25 | content, 26 | type, 27 | onClose, 28 | }); 29 | 30 | const target = key++; 31 | return function () { 32 | instance.removeNotice(target); 33 | }; 34 | } 35 | 36 | export default { 37 | info(content, duration, onClose, selfKey) { 38 | return notice(content, duration, onClose, selfKey, 'info'); 39 | }, 40 | success(content, duration, onClose, selfKey) { 41 | return notice(content, duration, onClose, selfKey, 'success'); 42 | }, 43 | error(content, duration, onClose, selfKey) { 44 | return notice(content, duration, onClose, selfKey, 'error'); 45 | }, 46 | warning(content, duration, onClose, selfKey) { 47 | return notice(content, duration, onClose, selfKey, 'warning'); 48 | }, 49 | loading(content, duration, onClose, selfKey) { 50 | return notice(content, duration, onClose, selfKey, 'loading'); 51 | }, 52 | config(options) { 53 | if (options.top) { 54 | top = options.top; 55 | // delete messageInstance for new defaultTop 56 | messageInstance = null; 57 | } 58 | 59 | if (options.duration) { 60 | defaultDuration = options.duration; 61 | } 62 | }, 63 | destroy() { 64 | if (messageInstance) { 65 | messageInstance.destroy(); 66 | messageInstance = null; 67 | } 68 | }, 69 | }; 70 | -------------------------------------------------------------------------------- /src/docs/zh-cn/start.md: -------------------------------------------------------------------------------- 1 | # vue-beauty 2 | 3 | vue-beauty 是一套基于 vue.js 和 ant-design样式 的PC端 UI 组件库,旨在帮助开发者提升产品体验和开发效率、降低维护成本。 4 | 5 | ## 特性 6 | - 丰富的组件,涵盖常用场景 7 | - 基于vue组件化开发,数据驱动视图 8 | - 封装复杂性,提供简单友好的api 9 | - 基于ant design样式优化 10 | 11 | ## 引入 12 | 使用npm or yarn 13 | ````javascript 14 | npm install vue-beauty -S 15 | //OR 16 | yarn add vue-beauty 17 | 18 | import Vue from 'vue' 19 | 20 | //import css 21 | import 'vue-beauty/package/style/vue-beauty.min.css' 22 | 23 | //import components 24 | import vueBeauty from 'vue-beauty' 25 | //size 属性用来改变组件的默认尺寸均为 'small' 26 | Vue.use(vueBeauty, { size: 'small' }) 27 | 28 | 29 | //OR 30 | import {alert} from 'vue-beauty' 31 | Vue.use(alert) 32 | ```` 33 | 或使用 \ 全局引用 34 | ````javascript 35 | 36 | 37 | ```` 38 | 示例 39 | ````javascript 40 | 43 | ```` 44 | 效果 45 | 按钮 46 | ## 版本 47 |
48 | 49 | 50 | 51 |

52 | 53 | ## 浏览器支持 54 | chrome、firefox,暂不支持IE(计划支持IE11+) 55 | ## 相关链接 56 | - vue官方网站 57 | - awesome vue 58 | - ES2015入门 59 | - webpack 60 | ## 相关开源项目 61 | vue-beauty 部分代码参考了以下项目: 62 | - Ant Design 63 | - Element 64 | - vue-antd 65 | - iview 66 | ## 谁在使用 67 | - 汇通天下 -------------------------------------------------------------------------------- /vb/components/switch/switch.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /vb/components/timeline/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | 4 | @timeline-prefix-cls: ~"@{ant-prefix}-timeline"; 5 | @timeline-color: @border-color-split; 6 | 7 | .@{timeline-prefix-cls} { 8 | list-style: none; 9 | margin: 0; 10 | padding: 0; 11 | 12 | &-item { 13 | position: relative; 14 | padding: 0 0 12px; 15 | list-style: none; 16 | margin: 0; 17 | 18 | &-tail { 19 | position: absolute; 20 | left: 5px; 21 | top: 0; 22 | height: 100%; 23 | border-left: 2px solid @timeline-color; 24 | } 25 | 26 | &-head { 27 | position: absolute; 28 | width: 12px; 29 | height: 12px; 30 | background-color: @component-background; 31 | border-radius: 100px; 32 | border: 2px solid transparent; 33 | &-blue { 34 | border-color: @primary-color; 35 | color: @primary-color; 36 | } 37 | &-red { 38 | border-color: @error-color; 39 | color: @error-color; 40 | } 41 | &-green { 42 | border-color: @success-color; 43 | color: @success-color; 44 | } 45 | } 46 | 47 | &-head-custom { 48 | position: absolute; 49 | text-align: center; 50 | width: 40px; 51 | left: -14px; 52 | line-height: 1; 53 | margin-top: 6px; 54 | border: 0; 55 | height: auto; 56 | border-radius: 0; 57 | padding: 3px 0; 58 | font-size: @font-size-base; 59 | transform: translateY(-50%); 60 | } 61 | 62 | &-content { 63 | padding: 0 0 10px 24px; 64 | font-size: @font-size-base; 65 | position: relative; 66 | top: -3px; 67 | } 68 | 69 | &:last-child { 70 | .@{timeline-prefix-cls}-item-tail { 71 | display: none; 72 | } 73 | } 74 | } 75 | 76 | &&-pending &-item:nth-last-child(2) { 77 | .@{timeline-prefix-cls}-item-tail { 78 | border-left: 2px dotted @timeline-color; 79 | } 80 | .@{timeline-prefix-cls}-item-content { 81 | min-height: 48px; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /vb/components/message/notice.vue: -------------------------------------------------------------------------------- 1 | 11 | 79 | -------------------------------------------------------------------------------- /src/docs/zh-cn/tag.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | # Tag 标签 13 | 14 | 进行标记和分类的小标签。 15 | 16 | ## 何时使用 17 | 18 | - 用于标记事物的属性和维度。 19 | - 进行分类。 20 | 21 | ## 代码演示 22 | 23 | ::: demo 24 | 25 | #### 基本 26 | 基本标签的用法,可以通过添加`closable`变为可关闭标签。可关闭标签具有`close`事件。 27 | 28 | 29 | ```html 30 | 34 | 35 | 44 | ``` 45 | ::: 46 | 47 | ::: demo 48 | 49 | #### 多彩标签 50 | 我们添加了多种预设色彩的标签样式,用作不同场景使用。如果预设值不能满足你的需求,可以设置为具体的色值。 51 | 52 | 53 | ```html 54 | pink 55 | red 56 | orange 57 | yellow 58 | green 59 | cyan 60 | blue 61 | purple 62 |

63 | pink-inverse 64 | red-inverse 65 | orange-inverse 66 | yellow-inverse 67 | green-inverse 68 | cyan-inverse 69 | blue-inverse 70 | purple-inverse 71 |

72 | #f50 73 | #2db7f5 74 | #87d068 75 | #108ee9 76 | ``` 77 | ::: 78 | 79 | ## API 80 | 81 | ### Tag Props 82 | | 属性 | 说明 | 类型 | 默认值 | 83 | |------------|----------------|-------------------|-------------| 84 | | color | 标签背景色 | string | - | 85 | | closable | 标签是否可以关闭 | boolean | false | 86 | 87 | ### Tag Events 88 | | 事件 | 说明 | 参数 | 89 | |------------|----------------|------------| 90 | | close | 关闭时触发 | - | 91 | -------------------------------------------------------------------------------- /vb/components/grid/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | @import "./mixin"; 4 | 5 | // Grid system 6 | .@{ant-prefix}-row { 7 | .make-row(); 8 | display: block; 9 | } 10 | 11 | .@{ant-prefix}-row-flex { 12 | display: flex; 13 | flex-direction: row; 14 | flex-wrap: wrap; 15 | 16 | &:before, 17 | &:after { 18 | display: flex; 19 | } 20 | } 21 | 22 | // x轴原点 23 | .@{ant-prefix}-row-flex-start { 24 | justify-content: flex-start; 25 | } 26 | 27 | // x轴居中 28 | .@{ant-prefix}-row-flex-center { 29 | justify-content: center; 30 | } 31 | 32 | // x轴反方向 33 | .@{ant-prefix}-row-flex-end { 34 | justify-content: flex-end; 35 | } 36 | 37 | // x轴平分 38 | .@{ant-prefix}-row-flex-space-between { 39 | justify-content: space-between; 40 | } 41 | 42 | // x轴有间隔地平分 43 | .@{ant-prefix}-row-flex-space-around { 44 | justify-content: space-around; 45 | } 46 | 47 | // 顶部对齐 48 | .@{ant-prefix}-row-flex-top { 49 | align-items: flex-start; 50 | } 51 | 52 | // 居中对齐 53 | .@{ant-prefix}-row-flex-middle { 54 | align-items: center; 55 | } 56 | 57 | // 底部对齐 58 | .@{ant-prefix}-row-flex-bottom { 59 | align-items: flex-end; 60 | } 61 | 62 | .@{ant-prefix}-col { 63 | position: relative; 64 | display: block; 65 | } 66 | 67 | .make-grid-columns(); 68 | .make-grid(); 69 | 70 | // Extra small grid 71 | // 72 | // Columns, offsets, pushes, and pulls for extra small devices like 73 | // smartphones. 74 | 75 | .make-grid(-xs); 76 | 77 | // Small grid 78 | // 79 | // Columns, offsets, pushes, and pulls for the small device range, from phones 80 | // to tablets. 81 | 82 | @media (min-width: @screen-sm-min) { 83 | .make-grid(-sm); 84 | } 85 | 86 | // Medium grid 87 | // 88 | // Columns, offsets, pushes, and pulls for the desktop device range. 89 | 90 | @media (min-width: @screen-md-min) { 91 | .make-grid(-md); 92 | } 93 | 94 | // Large grid 95 | // 96 | // Columns, offsets, pushes, and pulls for the large desktop device range. 97 | 98 | @media (min-width: @screen-lg-min) { 99 | .make-grid(-lg); 100 | } 101 | 102 | // Extra Large grid 103 | // 104 | // Columns, offsets, pushes, and pulls for the full hd device range. 105 | 106 | @media (min-width: @screen-xl-min) { 107 | .make-grid(-xl); 108 | } 109 | -------------------------------------------------------------------------------- /src/docs/zh-cn/breadcrumb.md: -------------------------------------------------------------------------------- 1 | # Breadcrumb 面包屑 2 | 3 | 显示当前页面在系统层级结构中的位置,并能向上返回。 4 | 5 | ## 何时使用 6 | 7 | + 当系统拥有超过两级以上的层级结构时; 8 | + 当需要告知用户『你在哪里』时; 9 | + 当需要向上导航的功能时。 10 | 11 | ## 代码演示 12 | 13 | ::: demo 14 | 15 | 16 | #### 基本 17 | 最简单的用法。 18 | 19 | 20 | ```html 21 | 22 | Home 23 | Application Center 24 | Application List 25 | An Application 26 | 27 | ``` 28 | 29 | ::: 30 | 31 | ::: demo 32 | 33 | 34 | #### 可点击的 35 | 用 `href`,会渲染为a标签,您也可以显式地使用 `` 36 | 37 | 38 | ```html 39 | 40 | 41 | Home 42 | 43 | 44 | Application Center 45 | 46 | 47 | Application List 48 | 49 | 50 | An Application 51 | 52 | 53 | ``` 54 | 55 | ::: 56 | 57 | ::: demo 58 | 59 | 60 | #### 带图标的 61 | 将图标组件放在文字前面。 62 | 63 | 64 | ```html 65 | 66 | 67 | 68 | 69 | 70 | Application List 71 | 72 | Application 73 | 74 | ``` 75 | 76 | ::: 77 | 78 | ::: demo 79 | 80 | 81 | #### 分隔符 82 | 使用 `separator=">"` 可以自定义分隔符。 83 | 84 | 85 | ```html 86 | 87 | Home 88 | Application Center 89 | Application List 90 | An Application 91 | 92 | ``` 93 | 94 | ::: 95 | 96 | ## API 97 | 98 | ### Breadcrumb Props 99 | | 参数 | 说明 | 类型 | 默认值 | 100 | |---------- |-------------- |---------- |-------- | 101 | | separator | 分隔符自定义 | string | '/' | 102 | | href | 跳转地址 | string | - | 103 | -------------------------------------------------------------------------------- /vb/components/layout/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | 4 | @layout-prefix-cls: ~"@{ant-prefix}-layout"; 5 | 6 | .@{layout-prefix-cls} { 7 | display: flex; 8 | flex-direction: column; 9 | flex: auto; 10 | background: @layout-body-background; 11 | 12 | &&-has-sider { 13 | flex-direction: row; 14 | } 15 | 16 | &-header, 17 | &-footer { 18 | flex: 0 0 auto; 19 | } 20 | 21 | &-header { 22 | background: @layout-header-background; 23 | padding: @layout-header-padding; 24 | height: @layout-header-height; 25 | line-height: @layout-header-height; 26 | } 27 | 28 | &-footer { 29 | padding: @layout-footer-padding; 30 | color: @text-color; 31 | font-size: @font-size-base; 32 | } 33 | 34 | &-content { 35 | flex: auto; 36 | } 37 | 38 | &-sider { 39 | transition: all .3s @ease-out; 40 | position: relative; 41 | background: @layout-sider-background; 42 | /* fix firefox can't set width smaller than content on flex item */ 43 | min-width: 0; 44 | 45 | &-has-trigger { 46 | padding-bottom: @layout-trigger-height; 47 | } 48 | 49 | &-right { 50 | order: 1; 51 | } 52 | 53 | &-trigger { 54 | position: absolute; 55 | text-align: center; 56 | width: 100%; 57 | bottom: 0; 58 | cursor: pointer; 59 | height: @layout-trigger-height; 60 | line-height: @layout-trigger-height; 61 | background: tint(@heading-color, 20%); 62 | color: #fff; 63 | } 64 | 65 | &-zero-width { 66 | & > * { 67 | overflow: hidden; 68 | } 69 | 70 | &-trigger { 71 | position: absolute; 72 | top: @layout-header-height; 73 | right: -@layout-zero-trigger-width; 74 | text-align: center; 75 | width: @layout-zero-trigger-width; 76 | height: @layout-zero-trigger-height; 77 | line-height: @layout-zero-trigger-height; 78 | background: @layout-sider-background; 79 | color: #fff; 80 | font-size: @layout-zero-trigger-width / 2; 81 | border-radius: 0 @border-radius-base @border-radius-base 0; 82 | cursor: pointer; 83 | transition: background .3s ease; 84 | 85 | &:hover { 86 | background: tint(@layout-sider-background, 10%); 87 | } 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /vb/components/more-panel/more-panel.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /vb/components/grid/col.vue: -------------------------------------------------------------------------------- 1 | 6 | 58 | -------------------------------------------------------------------------------- /static/datatable.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": [ 3 | { 4 | "id": 1, 5 | "pid": 0, 6 | "name": "高级动物", 7 | "time": "03:37", 8 | "singer": "窦唯", 9 | "album": "摇滚中国乐势力", 10 | "isparent":true 11 | }, 12 | { 13 | "id": 2, 14 | "pid": 0, 15 | "name": "谁伴我闯荡 - (电影《Beyond日记》插曲)", 16 | "time": "04:13", 17 | "singer": "Beyond", 18 | "album": "25周年精选" 19 | }, 20 | { 21 | "id": 3, 22 | "pid": 0, 23 | "name": "一无所有", 24 | "time": "05:35", 25 | "singer": "崔健", 26 | "album": "一无所有" 27 | }, 28 | { 29 | "id": 4, 30 | "pid": 0, 31 | "name": "无地自容", 32 | "time": "03:37", 33 | "singer": "秦勇/南京交警组合", 34 | "album": "梦想星搭档 第二季" 35 | }, 36 | { 37 | "id": 5, 38 | "pid": 0, 39 | "name": "我爱你亲爱的姑娘", 40 | "time": "03:49", 41 | "singer": "布衣乐队", 42 | "album": "那么久" 43 | }, 44 | { 45 | "id": 6, 46 | "pid": 0, 47 | "name": "梦回唐朝", 48 | "time": "07:11", 49 | "singer": "唐朝", 50 | "album": "中国大摇滚" 51 | }, 52 | { 53 | "id": 7, 54 | "pid": 0, 55 | "name": "无地自容MV", 56 | "time": "05:40", 57 | "singer": "黑豹乐队", 58 | "album": "黑豹1" 59 | }, 60 | { 61 | "id": 8, 62 | "pid": 1, 63 | "name": "黄河谣", 64 | "time": "05:57", 65 | "singer": "野孩子", 66 | "album": "黄河谣" 67 | }, 68 | { 69 | "id": 9, 70 | "pid": 1, 71 | "name": "兰州 兰州MV", 72 | "time": "06:33", 73 | "singer": "低苦艾", 74 | "album": "兰州 兰州" 75 | }, 76 | { 77 | "id": 10, 78 | "pid": 9, 79 | "name": "再见杰克", 80 | "time": "04:33", 81 | "singer": "痛仰乐队", 82 | "album": "不要停止我的音乐" 83 | }, 84 | { 85 | "id": 11, 86 | "pid": 9, 87 | "name": "钟鼓楼", 88 | "time": "08:30", 89 | "singer": "何勇", 90 | "album": "摇滚中国乐势力" 91 | } 92 | ], 93 | "totalCount":15, 94 | "pageSize":10, 95 | "pageNo":1 96 | } -------------------------------------------------------------------------------- /vb/components/form/form.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/docs/zh-cn/timeline.md: -------------------------------------------------------------------------------- 1 | # Timeline 时间轴 2 | 垂直展示的时间流信息。 3 | 4 | ## 何时使用 5 | - 当有一系列信息需要从上至下按时间排列时; 6 | - 需要有一条时间轴进行视觉上的串联时; 7 | 8 | ## 代码演示 9 | 10 | ::: demo 11 | 12 | #### 基本用法 13 | 基本的时间轴。 14 | 15 | 16 | ```html 17 | 18 | 创建服务现场 2015-09-01 19 | 初步排除网络异常 2015-09-01 20 | 技术测试 2015-09-01 21 | 网络异常正在修复 2015-09-01 22 | 23 | ``` 24 | 25 | ::: 26 | 27 | ::: demo 28 | 29 | #### 圆圈颜色 30 | 圆圈颜色,绿色用于已完成、成功状态,红色表示告警或错误状态,蓝色可表示正在进行或其他默认状态。 31 | 32 | 33 | ```html 34 | 35 | 创建服务现场 2015-09-01 36 | 创建服务现场 2015-09-01 37 | 38 |

初步排除网络异常1

39 |

初步排除网络异常2

40 |

初步排除网络异常3 2015-09-01

41 |
42 | 43 |

技术测试1

44 |

技术测试2

45 |

技术测试3 2015-09-01

46 |
47 |
48 | ``` 49 | 50 | ::: 51 | 52 | ::: demo 53 | 54 | #### 最后一个 55 | 通过 `pending` 标记最后一个元素为幽灵节点,表示时间轴未完成,还在记录过程中。 56 | 57 | 58 | ```html 59 | 60 | 创建服务现场 2015-09-01 61 | 初步排除网络异常 2015-09-01 62 | 技术测试 2015-09-01 63 | 查看更多 64 | 65 | ``` 66 | 67 | ::: 68 | 69 | ::: demo 70 | 71 | #### 自定义时间轴点 72 | 可以设置为图标或其他自定义元素。 73 | 74 | 75 | ```html 76 | 77 | 创建服务现场 2015-09-01 78 | 初步排除网络异常 2015-09-01 79 | 技术测试 2015-09-01 80 | 网络异常正在修复 2015-09-01 81 | 82 | ``` 83 | 84 | ::: 85 | 86 | ## API 87 | 88 | ### Timeline Props 89 | | 参数 | 说明 | 类型 | 默认值 | 90 | |---------- |-------------- |---------- |-------- | 91 | | pending | 指定最后一个幽灵节点是否存在 | Boolean | false | 92 | 93 | ### Timeline Props 94 | | 参数 | 说明 | 类型 | 默认值 | 95 | |---------- |-------------- |---------- |-------- | 96 | | color | 指定圆圈颜色 `blue, red, green`,或自定义的色值 | String | blue | 97 | | slot:dot | 自定义时间轴点 | Slot Node | - | 98 | -------------------------------------------------------------------------------- /vb/components/radio/radio.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /src/docs/zh-cn/rate.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | # Rate 评分 19 | 20 | 评分组件。 21 | 22 | ## 何时使用 23 | 24 | 对评价进行展示。 25 | 对事物进行快速的评级操作。 26 | 27 | ## 代码演示 28 | 29 | ::: demo 30 | 31 | #### 基本 32 | 最简单的用法。 33 | 34 | 35 | ```html 36 | 39 | 40 | 54 | ``` 55 | ::: 56 | 57 | ::: demo 58 | 59 | #### 半星 60 | 支持选中半星。 61 | 62 | 63 | ```html 64 | 67 | ``` 68 | ::: 69 | 70 | ::: demo 71 | 72 | #### 文案展示 73 | 给评分组件加上文案展示。 74 | 75 | 76 | ```html 77 | 82 | 83 | 97 | ``` 98 | ::: 99 | 100 | ::: demo 101 | 102 | #### 只读 103 | 只读,无法进行鼠标交互。 104 | 105 | 106 | ```html 107 | 110 | ``` 111 | ::: 112 | 113 | ## API 114 | 115 | ### Rate Props 116 | | 属性 | 说明 | 类型 | 默认值 | 117 | |------------|----------------|-------------------|-------------| 118 | | count | star 总数 | Number | 5 | 119 | | value | 当前值,如果输入值超过 count 会被强制转换成count值 | Number | 0 | 120 | | allowHalf | 是否允许半选 | Boolean | false | 121 | | disabled | 只读,无法进行交互 | Boolean | false | 122 | 123 | ### Rate Events 124 | | 事件名称 | 说明 | 回调参数 | 125 | |---------- |-------- |---------- | 126 | | change | 选择的值发生变化的时候触发 | value | 127 | 128 | -------------------------------------------------------------------------------- /vb/components/date-picker/style/Picker.less: -------------------------------------------------------------------------------- 1 | .@{calendar-prefix-cls}-picker-container { 2 | position: absolute; 3 | z-index: @zindex-picker; 4 | 5 | &.slide-up-enter.slide-up-enter-active&-placement-topLeft, 6 | &.slide-up-enter.slide-up-enter-active&-placement-topRight, 7 | &.slide-up-appear.slide-up-appear-active&-placement-topLeft, 8 | &.slide-up-appear.slide-up-appear-active&-placement-topRight { 9 | animation-name: antSlideDownIn; 10 | } 11 | 12 | &.slide-up-enter.slide-up-enter-active&-placement-bottomLeft, 13 | &.slide-up-enter.slide-up-enter-active&-placement-bottomRight, 14 | &.slide-up-appear.slide-up-appear-active&-placement-bottomLeft, 15 | &.slide-up-appear.slide-up-appear-active&-placement-bottomRight { 16 | animation-name: antSlideUpIn; 17 | } 18 | 19 | &.slide-up-leave.slide-up-leave-active&-placement-topLeft, 20 | &.slide-up-leave.slide-up-leave-active&-placement-topRight { 21 | animation-name: antSlideDownOut; 22 | } 23 | 24 | &.slide-up-leave.slide-up-leave-active&-placement-bottomLeft, 25 | &.slide-up-leave.slide-up-leave-active&-placement-bottomRight { 26 | animation-name: antSlideUpOut; 27 | } 28 | } 29 | 30 | .@{calendar-prefix-cls}-picker { 31 | position: relative; 32 | display: inline-block; 33 | outline: none; 34 | font-size: @font-size-base; 35 | transition: opacity 0.3s; 36 | 37 | &-input { 38 | outline: none; 39 | } 40 | 41 | &:hover &-input:not([disabled]) { 42 | border-color: @primary-color; 43 | } 44 | 45 | &-clear { 46 | opacity: 0; 47 | pointer-events: none; 48 | z-index: 1; 49 | position: absolute; 50 | right: 7px; 51 | background: #fff; 52 | top: 50%; 53 | font-size: @font-size-base; 54 | color: @disabled-color; 55 | width: 14px; 56 | height: 14px; 57 | margin-top: -7px; 58 | line-height: 14px; 59 | cursor: pointer; 60 | transition: color 0.3s, opacity 0.3s; 61 | &:hover { 62 | color: @text-color-secondary; 63 | } 64 | } 65 | 66 | &:hover &-clear { 67 | opacity: 1; 68 | pointer-events: auto; 69 | } 70 | 71 | &-icon { 72 | position: absolute; 73 | user-select: none; 74 | transition: all .3s; 75 | width: 12px; 76 | height: 12px; 77 | line-height: 12px; 78 | right: 8px; 79 | color: @text-color-secondary; 80 | top: 50%; 81 | margin-top: -6px; 82 | &:after { 83 | content: "\e6bb"; 84 | font-family: "anticon"; 85 | font-size: @font-size-base; 86 | color: @text-color-secondary; 87 | display: inline-block; 88 | line-height: 1; 89 | vertical-align: bottom; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /vb/components/radio/radio-group.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 91 | -------------------------------------------------------------------------------- /vb/components/notification/notice.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 83 | -------------------------------------------------------------------------------- /vb/components/transfer/operation.vue: -------------------------------------------------------------------------------- 1 | 28 | 83 | -------------------------------------------------------------------------------- /vb/components/button/button.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /vb/style/core/motion/slide.less: -------------------------------------------------------------------------------- 1 | .slide-motion(@className, @keyframeName) { 2 | .make-motion(@className, @keyframeName); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | opacity: 0; 6 | animation-timing-function: @ease-out-quint; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: @ease-in-quint; 10 | } 11 | } 12 | 13 | .slide-motion(slide-up, antSlideUp); 14 | .slide-motion(slide-down, antSlideDown); 15 | .slide-motion(slide-left, antSlideLeft); 16 | .slide-motion(slide-right, antSlideRight); 17 | 18 | @keyframes antSlideUpIn { 19 | 0% { 20 | opacity: 0; 21 | transform-origin: 0% 0%; 22 | transform: scaleY(.8); 23 | } 24 | 100% { 25 | opacity: 1; 26 | transform-origin: 0% 0%; 27 | transform: scaleY(1); 28 | } 29 | } 30 | 31 | @keyframes antSlideUpOut { 32 | 0% { 33 | opacity: 1; 34 | transform-origin: 0% 0%; 35 | transform: scaleY(1); 36 | } 37 | 100% { 38 | opacity: 0; 39 | transform-origin: 0% 0%; 40 | transform: scaleY(.8); 41 | } 42 | } 43 | 44 | @keyframes antSlideDownIn { 45 | 0% { 46 | opacity: 0; 47 | transform-origin: 100% 100%; 48 | transform: scaleY(.8); 49 | } 50 | 100% { 51 | opacity: 1; 52 | transform-origin: 100% 100%; 53 | transform: scaleY(1); 54 | } 55 | } 56 | 57 | @keyframes antSlideDownOut { 58 | 0% { 59 | opacity: 1; 60 | transform-origin: 100% 100%; 61 | transform: scaleY(1); 62 | } 63 | 100% { 64 | opacity: 0; 65 | transform-origin: 100% 100%; 66 | transform: scaleY(.8); 67 | } 68 | } 69 | 70 | @keyframes antSlideLeftIn { 71 | 0% { 72 | opacity: 0; 73 | transform-origin: 0% 0%; 74 | transform: scaleX(.8); 75 | } 76 | 100% { 77 | opacity: 1; 78 | transform-origin: 0% 0%; 79 | transform: scaleX(1); 80 | } 81 | } 82 | 83 | @keyframes antSlideLeftOut { 84 | 0% { 85 | opacity: 1; 86 | transform-origin: 0% 0%; 87 | transform: scaleX(1); 88 | } 89 | 100% { 90 | opacity: 0; 91 | transform-origin: 0% 0%; 92 | transform: scaleX(.8); 93 | } 94 | } 95 | 96 | @keyframes antSlideRightIn { 97 | 0% { 98 | opacity: 0; 99 | transform-origin: 100% 0%; 100 | transform: scaleX(.8); 101 | } 102 | 100% { 103 | opacity: 1; 104 | transform-origin: 100% 0%; 105 | transform: scaleX(1); 106 | } 107 | } 108 | 109 | @keyframes antSlideRightOut { 110 | 0% { 111 | opacity: 1; 112 | transform-origin: 100% 0%; 113 | transform: scaleX(1); 114 | } 115 | 100% { 116 | opacity: 0; 117 | transform-origin: 100% 0%; 118 | transform: scaleX(.8); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /vb/style/core/motion/move.less: -------------------------------------------------------------------------------- 1 | .move-motion(@className, @keyframeName) { 2 | .make-motion(@className, @keyframeName); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | opacity: 0; 6 | animation-timing-function: @ease-out-circ; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: @ease-in-circ; 10 | } 11 | } 12 | 13 | .move-motion(move-up, antMoveUp); 14 | .move-motion(move-down, antMoveDown); 15 | .move-motion(move-left, antMoveLeft); 16 | .move-motion(move-right, antMoveRight); 17 | 18 | @keyframes antMoveDownIn { 19 | 0% { 20 | transform-origin: 0 0; 21 | transform: translateY(100%); 22 | opacity: 0; 23 | } 24 | 100% { 25 | transform-origin: 0 0; 26 | transform: translateY(0%); 27 | opacity: 1; 28 | } 29 | } 30 | 31 | @keyframes antMoveDownOut { 32 | 0% { 33 | transform-origin: 0 0; 34 | transform: translateY(0%); 35 | opacity: 1; 36 | } 37 | 100% { 38 | transform-origin: 0 0; 39 | transform: translateY(100%); 40 | opacity: 0; 41 | } 42 | } 43 | 44 | @keyframes antMoveLeftIn { 45 | 0% { 46 | transform-origin: 0 0; 47 | transform: translateX(-100%); 48 | opacity: 0; 49 | } 50 | 100% { 51 | transform-origin: 0 0; 52 | transform: translateX(0%); 53 | opacity: 1; 54 | } 55 | } 56 | 57 | @keyframes antMoveLeftOut { 58 | 0% { 59 | transform-origin: 0 0; 60 | transform: translateX(0%); 61 | opacity: 1; 62 | } 63 | 100% { 64 | transform-origin: 0 0; 65 | transform: translateX(-100%); 66 | opacity: 0; 67 | } 68 | } 69 | 70 | @keyframes antMoveRightIn { 71 | 0% { 72 | opacity: 0; 73 | transform-origin: 0 0; 74 | transform: translateX(100%); 75 | } 76 | 100% { 77 | opacity: 1; 78 | transform-origin: 0 0; 79 | transform: translateX(0%); 80 | } 81 | } 82 | 83 | @keyframes antMoveRightOut { 84 | 0% { 85 | transform-origin: 0 0; 86 | transform: translateX(0%); 87 | opacity: 1; 88 | } 89 | 100% { 90 | transform-origin: 0 0; 91 | transform: translateX(100%); 92 | opacity: 0; 93 | } 94 | } 95 | 96 | @keyframes antMoveUpIn { 97 | 0% { 98 | transform-origin: 0 0; 99 | transform: translateY(-100%); 100 | opacity: 0; 101 | } 102 | 100% { 103 | transform-origin: 0 0; 104 | transform: translateY(0%); 105 | opacity: 1; 106 | } 107 | } 108 | 109 | @keyframes antMoveUpOut { 110 | 0% { 111 | transform-origin: 0 0; 112 | transform: translateY(0%); 113 | opacity: 1; 114 | } 115 | 100% { 116 | transform-origin: 0 0; 117 | transform: translateY(-100%); 118 | opacity: 0; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /vb/components/notification/notification.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 86 | -------------------------------------------------------------------------------- /vb/components/form/style/mixin.less: -------------------------------------------------------------------------------- 1 | @import "../../input/style/mixin"; 2 | 3 | .form-control-validation(@text-color: @input-color; @border-color: @input-border-color; @background-color: @input-bg) { 4 | .@{ant-prefix}-form-explain, 5 | .@{ant-prefix}-form-split { 6 | color: @text-color; 7 | } 8 | // 输入框的不同校验状态 9 | .@{ant-prefix}-input { 10 | &, 11 | &:hover { 12 | border-color: @border-color; 13 | } 14 | 15 | &:focus { 16 | .active(@border-color); 17 | } 18 | 19 | &:not([disabled]):hover { 20 | border-color: @border-color; 21 | } 22 | } 23 | 24 | .@{ant-prefix}-calendar-picker-open .@{ant-prefix}-calendar-picker-input { 25 | .active(@border-color); 26 | } 27 | 28 | .@{ant-prefix}-input-prefix { 29 | color: @text-color; 30 | } 31 | 32 | .@{ant-prefix}-input-group-addon { 33 | color: @text-color; 34 | border-color: @border-color; 35 | background-color: @background-color; 36 | } 37 | 38 | .has-feedback { 39 | color: @text-color; 40 | } 41 | } 42 | 43 | // Reset form styles 44 | // ----------------------------- 45 | // Based on Bootstrap framework 46 | .reset-form() { 47 | legend { 48 | display: block; 49 | width: 100%; 50 | padding: 0; 51 | margin-bottom: 20px; 52 | font-size: @font-size-lg; 53 | line-height: inherit; 54 | color: @text-color-secondary; 55 | border: 0; 56 | border-bottom: @border-width-base @border-style-base @border-color-base; 57 | } 58 | 59 | label { 60 | font-size: @font-size-base; 61 | } 62 | 63 | input[type="search"] { 64 | box-sizing: border-box; 65 | } 66 | 67 | // Position radios and checkboxes better 68 | input[type="radio"], 69 | input[type="checkbox"] { 70 | line-height: normal; 71 | } 72 | 73 | input[type="file"] { 74 | display: block; 75 | } 76 | 77 | // Make range inputs behave like textual form controls 78 | input[type="range"] { 79 | display: block; 80 | width: 100%; 81 | } 82 | 83 | // Make multiple select elements height not fixed 84 | select[multiple], 85 | select[size] { 86 | height: auto; 87 | } 88 | 89 | // Focus for file, radio, and checkbox 90 | input[type="file"]:focus, 91 | input[type="radio"]:focus, 92 | input[type="checkbox"]:focus { 93 | outline: thin dotted; 94 | outline: 5px auto -webkit-focus-ring-color; // lesshint duplicateProperty: false 95 | outline-offset: -2px; 96 | } 97 | 98 | // Adjust output element 99 | output { 100 | display: block; 101 | padding-top: 15px; 102 | font-size: @font-size-base; 103 | line-height: @line-height-base; 104 | color: @input-color; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /vb/components/avatar/avatar.vue: -------------------------------------------------------------------------------- 1 | 10 | 83 | 84 | -------------------------------------------------------------------------------- /vb/components/tooltip/tooltip.vue: -------------------------------------------------------------------------------- 1 | 16 | 79 | 80 | -------------------------------------------------------------------------------- /vb/components/card/card.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | -------------------------------------------------------------------------------- /vb/components/switch/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | 4 | @switch-prefix-cls: ~"@{ant-prefix}-switch"; 5 | @switch-duration: .3s; 6 | 7 | .@{switch-prefix-cls} { 8 | position: relative; 9 | display: inline-block; 10 | box-sizing: border-box; 11 | height: 22px; 12 | min-width: 44px; 13 | line-height: 20px; 14 | vertical-align: middle; 15 | border-radius: 20px; 16 | border: 1px solid #ccc; 17 | background-color: @disabled-color; 18 | cursor: pointer; 19 | transition: all @switch-duration; 20 | user-select: none; 21 | 22 | &-inner { 23 | color: #fff; 24 | font-size: @font-size-base; 25 | margin-left: 24px; 26 | margin-right: 6px; 27 | display: block; 28 | } 29 | 30 | &:after { 31 | position: absolute; 32 | width: 18px; 33 | height: 18px; 34 | left: 1px; 35 | top: 1px; 36 | 37 | border-radius: 18px; 38 | background-color: @component-background; 39 | content: " "; 40 | cursor: pointer; 41 | transition: all @switch-duration, width @switch-duration; 42 | } 43 | 44 | &:active:after { 45 | width: 24px; 46 | } 47 | 48 | &:focus { 49 | box-shadow: 0 0 0 2px fade(@primary-color, 20%); 50 | outline: 0; 51 | } 52 | 53 | &:focus:hover { 54 | box-shadow: none; 55 | } 56 | 57 | &-small { 58 | height: 14px; 59 | min-width: 28px; 60 | line-height: 12px; 61 | 62 | .@{switch-prefix-cls}-inner { 63 | margin-left: 18px; 64 | margin-right: 3px; 65 | } 66 | 67 | &:after { 68 | width: 12px; 69 | height: 12px; 70 | top: 0; 71 | left: 0.5px; 72 | } 73 | 74 | &:active:after { 75 | width: 16px; 76 | } 77 | } 78 | 79 | &-small&-checked { 80 | &:after { 81 | left: 100%; 82 | margin-left: -12.5px; 83 | } 84 | 85 | .@{switch-prefix-cls}-inner { 86 | margin-left: 3px; 87 | margin-right: 18px; 88 | } 89 | } 90 | 91 | &-small:active&-checked:after { 92 | margin-left: -16.5px; 93 | } 94 | 95 | &-checked { 96 | border-color: @primary-color; 97 | background-color: @primary-color; 98 | 99 | .@{switch-prefix-cls}-inner { 100 | margin-left: 6px; 101 | margin-right: 24px; 102 | } 103 | 104 | &:after { 105 | left: 100%; 106 | margin-left: -19px; 107 | } 108 | 109 | &:active:after { 110 | margin-left: -25px; 111 | } 112 | } 113 | 114 | &-disabled { 115 | cursor: not-allowed; 116 | background: #f4f4f4; 117 | border-color: #f4f4f4; 118 | 119 | &:after { 120 | background: #ccc; 121 | cursor: not-allowed; 122 | } 123 | 124 | .@{switch-prefix-cls}-inner { 125 | color: @disabled-color; 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /vb/style/core/base.less: -------------------------------------------------------------------------------- 1 | @import "./normalize.less"; 2 | 3 | // http://stackoverflow.com/a/13611748/3040605 4 | @font-face { 5 | font-family: "Helvetica Neue For Number"; 6 | src: local("Helvetica Neue"); 7 | unicode-range: U+30-39; 8 | } 9 | 10 | * { 11 | box-sizing: border-box; 12 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); // remove tap highlight color for mobile safari 13 | } 14 | 15 | *:before, 16 | *:after { 17 | box-sizing: border-box; 18 | } 19 | 20 | // HTML & Body reset 21 | html, body { 22 | .square(100%); 23 | } 24 | 25 | body { 26 | font-family: @font-family; 27 | font-size: @font-size-base; 28 | line-height: @line-height-base; 29 | color: @text-color; 30 | background-color: @body-background; 31 | } 32 | 33 | // unify the setting of elements's margin and padding for browsers 34 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { 35 | margin: 0; 36 | padding: 0; 37 | } 38 | 39 | // Reset fonts for relevant elements 40 | button,input,select,textarea { 41 | font-family: inherit; 42 | font-size: inherit; 43 | line-height: inherit; 44 | color: inherit; 45 | } 46 | 47 | input[type="text"], 48 | textarea { 49 | -webkit-appearance: none; 50 | } 51 | 52 | ul, 53 | ol { 54 | list-style: none; 55 | } 56 | 57 | // Remove the clear button of a text input control in IE10+ 58 | input::-ms-clear, input::-ms-reveal { 59 | display: none; 60 | } 61 | 62 | ::selection { 63 | background: @primary-color; 64 | color: #fff; 65 | } 66 | 67 | // Headers 68 | h1, h2, h3, h4, h5, h6 { 69 | color: @heading-color; 70 | font-weight: 500; 71 | } 72 | 73 | // Links 74 | a { 75 | color: @link-color; 76 | background: transparent; 77 | text-decoration: @link-decoration; 78 | outline: none; 79 | cursor: pointer; 80 | transition: color .3s ease; 81 | 82 | &:focus { 83 | text-decoration: underline; 84 | text-decoration-skip: ink; 85 | } 86 | 87 | &:hover { 88 | color: @link-hover-color; 89 | } 90 | 91 | &:active { 92 | color: @link-active-color; 93 | } 94 | 95 | &:active, 96 | &:hover { 97 | outline: 0; 98 | text-decoration: @link-hover-decoration; 99 | } 100 | 101 | &[disabled] { 102 | color: @disabled-color; 103 | cursor: not-allowed; 104 | pointer-events: none; 105 | } 106 | } 107 | 108 | .@{ant-prefix}-divider { 109 | margin: 0 6px; 110 | display: inline-block; 111 | height: 8px; 112 | width: 1px; 113 | background: #ccc; 114 | } 115 | 116 | code, 117 | kbd, 118 | pre, 119 | samp { 120 | font-family: @code-family; 121 | } 122 | 123 | // Utility classes 124 | .clearfix { 125 | .clearfix(); 126 | } 127 | 128 | @import "./base_vb.less"; 129 | -------------------------------------------------------------------------------- /vb/components/popconfirm/popconfirm.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 86 | -------------------------------------------------------------------------------- /vb/style/core/base_vb.less: -------------------------------------------------------------------------------- 1 | .pull-left { 2 | float: left; 3 | } 4 | .pull-right { 5 | float: right; 6 | } 7 | .hide { 8 | display: none !important; 9 | } 10 | .show { 11 | display: block !important; 12 | } 13 | .invisible { 14 | visibility: hidden; 15 | } 16 | 17 | .ant-divider { 18 | margin: 0 4px; 19 | color: #999; 20 | display: inline-block; 21 | height: 8px; 22 | width: 1px; 23 | background: #ccc; 24 | } 25 | 26 | code, 27 | kbd, 28 | pre, 29 | samp { 30 | font-family: @code-family; 31 | } 32 | 33 | // Container widths 34 | // 35 | // Set the container width, and override it for fixed navbars in media queries. 36 | 37 | .container { 38 | .container-fixed(); 39 | 40 | @media (min-width: @screen-sm-min) { 41 | width: @container-sm; 42 | } 43 | @media (min-width: @screen-md-min) { 44 | width: @container-md; 45 | } 46 | @media (min-width: @screen-lg-min) { 47 | width: @container-lg; 48 | } 49 | } 50 | 51 | // Fluid container 52 | // 53 | // Utilizes the mixin meant for fixed width containers, but without any defined 54 | // width for fluid, full width layouts. 55 | 56 | .container-fluid { 57 | .container-fixed(); 58 | } 59 | 60 | // Alignment 61 | .text-left { text-align: left; } 62 | .text-right { text-align: right; } 63 | .text-center { text-align: center; } 64 | .text-justify { text-align: justify; } 65 | .text-nowrap { white-space: nowrap; } 66 | 67 | // Contextual colors 68 | .text-muted { 69 | color: @normal-color; 70 | } 71 | .text-primary { 72 | color: @primary-color; 73 | } 74 | .text-success { 75 | color: @success-color; 76 | } 77 | .text-warning { 78 | color: @warning-color; 79 | } 80 | .text-error { 81 | color: @error-color; 82 | } 83 | .text-dark { 84 | color: @dark-color; 85 | } 86 | 87 | //文本大小 88 | .text-md { 89 | font-size: @font-size-md; 90 | } 91 | .text-lg { 92 | font-size: @font-size-lg; 93 | } 94 | .text-xl { 95 | font-size: @font-size-xl; 96 | } 97 | .text-xxl { 98 | font-size: @font-size-xxl; 99 | } 100 | 101 | //背景区块 102 | .bg-primary { 103 | color: #fff; 104 | background-color: @primary-color; 105 | } 106 | .bg-success { 107 | color: #fff; 108 | background-color: @success-color; 109 | } 110 | .bg-warning { 111 | color: #fff; 112 | background-color: @warning-color; 113 | } 114 | .bg-error { 115 | color: #fff; 116 | background-color: @error-color; 117 | } 118 | .bg-muted { 119 | background-color: @normal-color 120 | } 121 | 122 | //margin 123 | .generate-margins(25); 124 | .generate-margins-side(left, 25); 125 | .generate-margins-side(right, 25); 126 | .generate-margins-side(top, 25); 127 | .generate-margins-side(bottom, 25); 128 | 129 | //padding 130 | .generate-paddings(25); 131 | .generate-paddings-side(left, 25); 132 | .generate-paddings-side(right, 25); 133 | .generate-paddings-side(top, 25); 134 | .generate-paddings-side(bottom, 25); -------------------------------------------------------------------------------- /vb/components/alert/alert.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 86 | -------------------------------------------------------------------------------- /vb/components/tag/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | 4 | @tag-prefix-cls: ~"@{ant-prefix}-tag"; 5 | 6 | .@{tag-prefix-cls} { 7 | display: inline-block; 8 | line-height: 20px; 9 | height: 22px; 10 | padding: 0 8px; 11 | border-radius: @border-radius-base; 12 | border: @border-width-base @border-style-base @border-color-split; 13 | background: @tag-default-bg; 14 | font-size: @font-size-base; 15 | transition: all 0.3s @ease-in-out-circ; 16 | opacity: 1; 17 | margin-right: 8px; 18 | cursor: pointer; 19 | white-space: nowrap; 20 | 21 | &:hover { 22 | opacity: 0.85; 23 | } 24 | 25 | &, 26 | a, 27 | a:hover { 28 | color: @tag-default-color; 29 | } 30 | 31 | &-text { 32 | a:first-child:last-child { 33 | display: inline-block; 34 | margin: 0 -8px; 35 | padding: 0 8px; 36 | } 37 | } 38 | 39 | .@{iconfont-css-prefix}-cross { 40 | .iconfont-size-under-12px(10px); 41 | cursor: pointer; 42 | font-weight: bold; 43 | margin-left: 3px; 44 | transition: all 0.3s ease; 45 | opacity: 0.66; 46 | 47 | &:hover { 48 | opacity: 1; 49 | } 50 | } 51 | 52 | &-has-color { 53 | border-color: transparent; 54 | &, 55 | a, 56 | a:hover, 57 | .@{iconfont-css-prefix}-cross, 58 | .@{iconfont-css-prefix}-cross:hover { 59 | color: #fff; 60 | } 61 | } 62 | 63 | &-checkable { 64 | background-color: transparent; 65 | border-color: transparent; 66 | &:hover, 67 | &:active, 68 | &-checked { 69 | color: #fff; 70 | } 71 | &:hover { 72 | background-color: @primary-5; 73 | } 74 | &-checked { 75 | background-color: @primary-6; 76 | } 77 | &:active { 78 | background-color: @primary-7; 79 | } 80 | } 81 | 82 | &-close { 83 | width: 0 !important; 84 | padding: 0; 85 | margin: 0; 86 | } 87 | 88 | &-zoom-enter, 89 | &-zoom-appear { 90 | animation: antFadeIn .2s @ease-in-out-circ; 91 | animation-fill-mode: both; 92 | } 93 | 94 | &-zoom-leave { 95 | animation: antZoomOut .3s @ease-in-out-circ; 96 | animation-fill-mode: both; 97 | } 98 | 99 | @colors: pink, red, orange, yellow, cyan, green, blue, purple; 100 | 101 | // mixin to iterate over colors and create CSS class for each one 102 | .make-color-classes(@i: length(@colors)) when (@i > 0) { 103 | .make-color-classes(@i - 1); 104 | @color: extract(@colors, @i); 105 | @lightColor: "@{color}-2"; 106 | @darkColor: "@{color}-6"; 107 | &-@{color} { 108 | color: @@darkColor; 109 | background: @@lightColor; 110 | border-color: @@lightColor; 111 | } 112 | &-@{color}-inverse { 113 | background: @@darkColor; 114 | border-color: @@darkColor; 115 | color: #fff; 116 | } 117 | } 118 | 119 | .make-color-classes(); 120 | } 121 | -------------------------------------------------------------------------------- /vb/components/collapse/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../../style/themes/default"; 2 | @import "../../../style/mixins/index"; 3 | 4 | @collapse-prefix-cls: ~"@{ant-prefix}-collapse"; 5 | 6 | @collapse-active-bg: @primary-1; 7 | 8 | .collapse-close() { 9 | .iconfont-size-under-12px(9px, 0); 10 | } 11 | .collapse-open() { 12 | .iconfont-size-under-12px(9px, 90deg); 13 | } 14 | 15 | .@{collapse-prefix-cls} { 16 | background-color: @background-color-base; 17 | border-radius: @border-radius-base; 18 | border: @border-width-base @border-style-base @border-color-base; 19 | border-bottom: 0; 20 | 21 | & > &-item { 22 | border-bottom: @border-width-base @border-style-base @border-color-base; 23 | > .@{collapse-prefix-cls}-header { 24 | height: 38px; 25 | line-height: 38px; 26 | padding-left: 32px; 27 | color: @heading-color; 28 | cursor: pointer; 29 | position: relative; 30 | transition: all .3s; 31 | 32 | &:active { 33 | background-color: @collapse-active-bg !important; 34 | } 35 | 36 | .arrow { 37 | .collapse-close(); 38 | .iconfont-mixin(); 39 | position: absolute; 40 | color: @text-color-secondary; 41 | display: inline-block; 42 | font-weight: bold; 43 | line-height: 40px; 44 | vertical-align: middle; 45 | transition: transform 0.24s; 46 | top: 0; 47 | left: 16px; 48 | /* stylelint-disable declaration-block-no-duplicate-properties */ 49 | top: ~"16px \9"; 50 | left: ~"0 \9"; 51 | /* stylelint-enable declaration-block-no-duplicate-properties */ 52 | &:before { 53 | content: "\E61F"; 54 | } 55 | } 56 | } 57 | } 58 | 59 | &-anim-active { 60 | transition: height .2s @ease-out; 61 | } 62 | 63 | &-content { 64 | overflow: hidden; 65 | color: @text-color; 66 | padding: 0 16px; 67 | background-color: @component-background; 68 | 69 | & > &-box { 70 | padding-top: 16px; 71 | padding-bottom: 16px; 72 | } 73 | 74 | &-inactive { 75 | display: none; 76 | } 77 | } 78 | 79 | &-item:last-child { 80 | > .@{collapse-prefix-cls}-content { 81 | border-radius: 0 0 @border-radius-base @border-radius-base; 82 | } 83 | } 84 | 85 | & > &-item > &-header[aria-expanded="true"] { 86 | .arrow { 87 | .collapse-open(); 88 | } 89 | } 90 | 91 | &-borderless { 92 | background-color: @component-background; 93 | border: 0; 94 | } 95 | 96 | &-borderless > &-item-active { 97 | border: 0; 98 | } 99 | 100 | &-borderless > &-item > &-content { 101 | background-color: transparent; 102 | border-top: @border-width-base @border-style-base @border-color-base; 103 | } 104 | 105 | &-borderless > &-item > &-header { 106 | transition: all .3s; 107 | &:hover { 108 | background-color: @background-color-base; 109 | } 110 | } 111 | } --------------------------------------------------------------------------------