Repository: NewDadaFE/vue-impression Branch: master Commit: 6ff2b38f2a07 Files: 204 Total size: 327.8 KB Directory structure: gitextract_vku1hzea/ ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .scss-lint.yml ├── README.md ├── _config.yml ├── gulpfile.js ├── index.html ├── package.json ├── src/ │ ├── scripts/ │ │ ├── components/ │ │ │ ├── Alert.vue │ │ │ ├── BackToTop.vue │ │ │ ├── Badge.vue │ │ │ ├── Button.vue │ │ │ ├── Card.vue │ │ │ ├── CardBody.vue │ │ │ ├── Cell.vue │ │ │ ├── Checkbox.vue │ │ │ ├── CheckboxGroup.vue │ │ │ ├── DatePicker/ │ │ │ │ ├── DateRange.vue │ │ │ │ ├── DateTable.vue │ │ │ │ ├── Picker.vue │ │ │ │ └── index.js │ │ │ ├── Drawer.vue │ │ │ ├── DrawerItem.vue │ │ │ ├── Flex.vue │ │ │ ├── FlexItem.vue │ │ │ ├── Group.vue │ │ │ ├── GroupTitle.vue │ │ │ ├── HRule.vue │ │ │ ├── Icon.vue │ │ │ ├── InlineSelector.vue │ │ │ ├── InlineSelectorOption.vue │ │ │ ├── InputNumber.vue │ │ │ ├── InputText.vue │ │ │ ├── InputTextarea.vue │ │ │ ├── Loading.vue │ │ │ ├── Loadmore.vue │ │ │ ├── Mask.vue │ │ │ ├── Media.vue │ │ │ ├── MediaBody.vue │ │ │ ├── MediaObject.vue │ │ │ ├── Navbar.vue │ │ │ ├── Navigation.vue │ │ │ ├── NavigationItem.vue │ │ │ ├── Picker.vue │ │ │ ├── PickerOption.vue │ │ │ ├── Progressbar.vue │ │ │ ├── Progressbars.vue │ │ │ ├── Radio.vue │ │ │ ├── RadioGroup.vue │ │ │ ├── Searchbar.vue │ │ │ ├── SearchbarBtn.vue │ │ │ ├── SearchbarPlaceholder.vue │ │ │ ├── SegmentedControl.vue │ │ │ ├── SegmentedControlItem.vue │ │ │ ├── Selector.vue │ │ │ ├── SelectorOption.vue │ │ │ ├── Sidelip.vue │ │ │ ├── SlideUp.vue │ │ │ ├── SlideUpBody.vue │ │ │ ├── SlideUpHeader.vue │ │ │ ├── Stepbar.vue │ │ │ ├── StepbarItem.vue │ │ │ ├── Sticky.vue │ │ │ ├── Swipe.vue │ │ │ ├── SwipeItem.vue │ │ │ ├── Tabbar.vue │ │ │ ├── TabbarItem.vue │ │ │ ├── Tag.vue │ │ │ ├── Timeline.vue │ │ │ ├── TimelineItem.vue │ │ │ ├── Tip.vue │ │ │ ├── Toast.vue │ │ │ ├── Toggle.vue │ │ │ └── index.js │ │ ├── containers/ │ │ │ ├── layout.vue │ │ │ └── menubar.vue │ │ ├── directives/ │ │ │ └── disfavor.js │ │ ├── index.js │ │ ├── mixins/ │ │ │ ├── emitter.js │ │ │ ├── select.js │ │ │ ├── selectOption.js │ │ │ ├── sync.js │ │ │ ├── tab.js │ │ │ └── tabItem.js │ │ ├── router.js │ │ ├── routes.json │ │ ├── utils/ │ │ │ ├── alert.js │ │ │ ├── cssPrefix.js │ │ │ ├── date.js │ │ │ ├── dateUtil.js │ │ │ ├── dom.js │ │ │ ├── draggable.js │ │ │ ├── easing.js │ │ │ ├── loading.js │ │ │ ├── toast.js │ │ │ ├── translate.js │ │ │ └── type.js │ │ └── views/ │ │ ├── alert.vue │ │ ├── back-to-top.vue │ │ ├── badge.vue │ │ ├── button.vue │ │ ├── card.vue │ │ ├── cell.vue │ │ ├── checkbox.vue │ │ ├── confirm.vue │ │ ├── datepicker.vue │ │ ├── drawer.vue │ │ ├── flex.vue │ │ ├── hrule.vue │ │ ├── icon.vue │ │ ├── index.vue │ │ ├── inline-selecor.vue │ │ ├── input-number.vue │ │ ├── input-text.vue │ │ ├── input-textarea.vue │ │ ├── loading.vue │ │ ├── media.vue │ │ ├── navbar.vue │ │ ├── navigation.vue │ │ ├── picker.vue │ │ ├── progressbar.vue │ │ ├── pull-down.vue │ │ ├── pull-up.vue │ │ ├── radio.vue │ │ ├── searchbar.vue │ │ ├── segmented-control.vue │ │ ├── selector.vue │ │ ├── sideslip.vue │ │ ├── slideup.vue │ │ ├── stepbar.vue │ │ ├── sticky.vue │ │ ├── swipe.vue │ │ ├── tabbar.vue │ │ ├── tag.vue │ │ ├── timeline.vue │ │ ├── tip.vue │ │ ├── toast.vue │ │ └── toggle.vue │ └── styles/ │ ├── animate.scss │ ├── index.scss │ ├── mixins/ │ │ ├── border.scss │ │ ├── button.scss │ │ ├── media.scss │ │ ├── navbar.scss │ │ ├── progressbar.scss │ │ ├── tag.scss │ │ └── text.scss │ ├── mixins.scss │ ├── modules/ │ │ ├── alert.scss │ │ ├── back-to-top.scss │ │ ├── badge.scss │ │ ├── button.scss │ │ ├── card.scss │ │ ├── cell.scss │ │ ├── checkbox.scss │ │ ├── date-picker.scss │ │ ├── drawer.scss │ │ ├── group.scss │ │ ├── hrule.scss │ │ ├── inline-selector.scss │ │ ├── input-number.scss │ │ ├── input-text.scss │ │ ├── input-textarea.scss │ │ ├── loading.scss │ │ ├── loadmore.scss │ │ ├── mask.scss │ │ ├── media.scss │ │ ├── navbar.scss │ │ ├── navigation.scss │ │ ├── picker.scss │ │ ├── progressbar.scss │ │ ├── searchbar.scss │ │ ├── segmented-control.scss │ │ ├── selector.scss │ │ ├── sidelip.scss │ │ ├── slideup.scss │ │ ├── stepbar.scss │ │ ├── sticky.scss │ │ ├── swipe.scss │ │ ├── tabbar.scss │ │ ├── tag.scss │ │ ├── timeline.scss │ │ ├── tip.scss │ │ ├── toast.scss │ │ └── toggle.scss │ ├── modules.scss │ ├── utils/ │ │ ├── background.scss │ │ ├── border.scss │ │ ├── clearfix.scss │ │ ├── display.scss │ │ ├── flex.scss │ │ ├── img.scss │ │ ├── reboot.scss │ │ ├── spacing.scss │ │ └── text.scss │ ├── utils.scss │ └── variables.scss ├── webpack.dev.config.js ├── webpack.prebuilt.config.js └── webpack.prod.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": ["vue", ["es2015", { "modules": false }], "stage-1"], "comments": false, "plugins": [ "transform-runtime", "transform-object-assign" ] } ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 indent_style = space indent_size = 4 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true [*.{json,yml}] trim_trailing_whitespace = false ================================================ FILE: .eslintignore ================================================ build.js webpack.*.js ================================================ FILE: .eslintrc.js ================================================ module.exports = { extends: 'vue-impression', rules: { 'import/no-extraneous-dependencies': 0, } }; ================================================ FILE: .gitignore ================================================ /node_modules /site/build /site/node_modules /site/.sass-cache /site/src/scripts/components/impression /site/src/styles/impression /build /cache *.log /.idea /.sass-cache scss-lint-report.xml /lib .DS_Store /dist ================================================ FILE: .npmignore ================================================ /build /site /.sass-cache .DS_Store Makefile .babelrc .editorconfig .eslintignore .eslintrc.js .scss-lint.yml index.todo /src webpack.*.js *.log _config.yml build.js gulpfile.js index.html ================================================ FILE: .scss-lint.yml ================================================ scss_files: "src/styles/**/*.scss" exclude: ['src/styles/font-awesome/**', 'src/styles/modules/_normalize.scss', 'src/styles/modules/_reboot.scss'] plugin_directories: ['.scss-linters'] # List of gem names to load custom linters from (make sure they are already # installed) plugin_gems: [] # Default severity of all linters. severity: warning linters: BangFormat: enabled: true space_before_bang: true space_after_bang: false BemDepth: enabled: false max_elements: 1 BorderZero: enabled: true convention: zero # or `none` ChainedClasses: enabled: false ColorKeyword: enabled: true ColorVariable: enabled: true Comment: enabled: true style: silent DebugStatement: enabled: true DeclarationOrder: enabled: false DisableLinterReason: enabled: false DuplicateProperty: enabled: true ElsePlacement: enabled: true style: same_line # or 'new_line' EmptyLineBetweenBlocks: enabled: true ignore_single_line_blocks: true EmptyRule: enabled: true ExtendDirective: enabled: false FinalNewline: enabled: true present: true HexLength: enabled: true style: short # or 'long' HexNotation: enabled: true style: lowercase # or 'uppercase' HexValidation: enabled: true IdSelector: enabled: true ImportantRule: enabled: false ImportPath: enabled: true leading_underscore: false filename_extension: false Indentation: enabled: true allow_non_nested_indentation: false character: space # or 'tab' width: 4 LeadingZero: enabled: true style: exclude_zero # or 'include_zero' MergeableSelector: enabled: true force_nesting: true NameFormat: enabled: true allow_leading_underscore: true convention: hyphenated_lowercase # or 'camel_case', or 'snake_case', or a regex pattern NestingDepth: enabled: true max_depth: 6 ignore_parent_selectors: false PlaceholderInExtend: enabled: false PrivateNamingConvention: enabled: false prefix: _ PropertyCount: enabled: false include_nested: false max_properties: 10 PropertySortOrder: enabled: false ignore_unspecified: false min_properties: 2 separate_groups: false PropertySpelling: enabled: true extra_properties: [] disabled_properties: [] PropertyUnits: enabled: true global: [ 'ch', 'em', 'ex', 'rem', # Font-relative lengths 'cm', 'in', 'mm', 'pc', 'pt', 'px', 'q', # Absolute lengths 'vh', 'vw', 'vmin', 'vmax', # Viewport-percentage lengths 'deg', 'grad', 'rad', 'turn', # Angle 'ms', 's', # Duration 'Hz', 'kHz', # Frequency 'dpi', 'dpcm', 'dppx', # Resolution '%'] # Other properties: {} PseudoElement: enabled: true QualifyingElement: enabled: false allow_element_with_attribute: false allow_element_with_class: false allow_element_with_id: false SelectorDepth: enabled: true max_depth: 4 SelectorFormat: enabled: true convention: hyphenated_lowercase # or 'strict_BEM', or 'hyphenated_BEM', or 'snake_case', or 'camel_case', or a regex pattern Shorthand: enabled: true allowed_shorthands: [1, 2, 3, 4] SingleLinePerProperty: enabled: true allow_single_line_rule_sets: true SingleLinePerSelector: enabled: true SpaceAfterComma: enabled: true style: one_space # or 'no_space', or 'at_least_one_space' SpaceAfterPropertyColon: enabled: true style: one_space # or 'no_space', or 'at_least_one_space', or 'aligned' SpaceAfterPropertyName: enabled: true SpaceAfterVariableColon: enabled: false style: one_space # or 'no_space', 'at_least_one_space' or 'one_space_or_newline' SpaceAfterVariableName: enabled: true SpaceAroundOperator: enabled: true style: one_space # or 'at_least_one_space', or 'no_space' SpaceBeforeBrace: enabled: true style: space # or 'new_line' allow_single_line_padding: false SpaceBetweenParens: enabled: true spaces: 0 StringQuotes: enabled: true style: single_quotes # or double_quotes TrailingSemicolon: enabled: true TrailingWhitespace: enabled: true TrailingZero: enabled: false TransitionAll: enabled: false UnnecessaryMantissa: enabled: true UnnecessaryParentReference: enabled: true UrlFormat: enabled: true UrlQuotes: enabled: true VariableForProperty: enabled: false properties: [] VendorPrefix: enabled: true identifier_list: base additional_identifiers: [] excluded_identifiers: [] ZeroUnit: enabled: true Compass::*: enabled: false ================================================ FILE: README.md ================================================ # vue-impression A Vue.js 2.0 UI elements for mobile. ## Demo https://newdadafe.github.io/impression_vue/#/button ## Installation ```sh yarn add vue-impression ``` ## Usage styles: ```scss @import '~vue-impression/dist/styles/index.scss'; ``` scripts: ```js import Vue from 'vue'; import VueImpression from 'vue-impression'; Vue.use(VueImpression); ``` tree-shaking: ```sh yarn add babel-plugin-transform-imports -D ``` ```json { "plugins": [ [ "transform-imports", { "vue-impression": { "transform": "vue-impression/dist/scripts/components/${member}", "preventFullImport": true } } ] ] } ``` ## Example ```html 按钮 ``` ## Components - [x] Button - [x] Group - [x] GroupTitle - [x] Cell - [x] Flex - [x] FlexItem - [x] Icon - [x] Navbar - [x] Navigation - [x] Tabbar - [x] Drawer - [x] Loading - [x] Alert - [x] Toast - [x] Radio - [x] RadioGroup - [x] Checkbox - [x] CheckboxGroup - [x] Toggle(Switch) - [x] InputNumber - [x] InputText - [x] InputArea - [x] Selector - [x] Tag - [x] Badge - [x] Tip - [x] HRule(Hr) - [x] InlineSelector - [x] Swipe - [x] SlideUp - [x] SegmentedControl - [x] Media - [x] Card - [x] Picker - [x] DatePicker - [x] Search - [x] BackToTop - [x] Pull down - [x] Pull up - [x] Sideslip - [x] Progressbar - [x] Stepbar - [x] Timeline - [x] Sticky ## Quick start [generator-vue-impression](https://github.com/NewDadaFE/generator/tree/master/packages/generator-vue-impression) ================================================ FILE: _config.yml ================================================ theme: jekyll-theme-cayman ================================================ FILE: gulpfile.js ================================================ const fs = require('fs-extra'); const gulp = require('gulp'); const minimist = require('minimist'); const plugin = require('gulp-load-plugins')(); const replaceExt = require('replace-ext'); const through = require('through2'); const { createDefaultCompiler, assemble } = require('@vue/component-compiler'); const options = minimist(process.argv.slice(2)); process.env.NODE_ENV = options.env || 'production'; const clean = () => Promise.all([fs.emptyDir('dist'), fs.emptyDir('build')]); const copyHTML = () => fs.copy('index.html', 'build/index.html'); const copyImage = () => fs.copy('src/images', 'build/images'); const style = () => fs.copy('src/styles', 'dist/styles'); const sass = () => { return gulp .src('src/styles/index.scss') .pipe(plugin.sass().on('error', plugin.sass.logError)) .pipe(plugin.autoprefixer({ browsers: ['last 30 version', '> 90%'] })) .pipe(plugin.cssmin()) .pipe(gulp.dest('build/styles')); }; const script = () => { const directory = ['components', 'directives', 'mixins', 'utils']; const compiler = createDefaultCompiler(); return gulp .src(`src/scripts/?(${directory.join('|')})/**/*.{js,vue}`) .pipe( through.obj((file, encoding, callback) => { if(file.extname === '.vue') { const result = compiler.compileToDescriptor( file.basename, file.contents.toString() ); const output = assemble(compiler, file.basename, result); file.contents = new Buffer(output.code); file.path = replaceExt(file.path, '.js'); } callback(null, file); }) ) .pipe(plugin.babel()) .pipe(gulp.dest('dist/scripts')); }; const watch = () => gulp.watch('src/styles/**/*.scss', sass); const build = gulp.series(clean, gulp.parallel(copyHTML, copyImage, sass)); const release = gulp.series(clean, gulp.parallel(style, script)); module.exports = { watch, build, release }; ================================================ FILE: index.html ================================================ vue-impression
================================================ FILE: package.json ================================================ { "name": "vue-impression", "version": "0.21.13", "description": "A Vue.js 2.0 UI elements for mobile.", "sass": "dist/styles/index.scss", "main": "dist/scripts/components/index.js", "module": "dist/scripts/components/index.js", "scripts": { "start": "gulp build && webpack -p --config webpack.prebuilt.config.js", "poststart": "webpack-dev-server --config webpack.dev.config.js --colors --port 9008", "build:site": "gulp build && webpack -p --config webpack.prod.config.js", "scsslint": "scss-lint src/styles/**/*.scss", "eslint": "eslint ./src/scripts/", "build": "npm run eslint && gulp release" }, "repository": { "type": "git", "url": "git+https://github.com/NewDadaFE/vue-impression.git" }, "keywords": [ "Vue 2.0", "UI" ], "author": "NewDadaFE", "license": "MIT", "bugs": { "url": "https://github.com/NewDadaFE/vue-impression/issues" }, "homepage": "https://github.com/NewDadaFE/vue-impression#readme", "devDependencies": { "@vue/component-compiler": "^3.6.0", "ajv": "5.5.2", "autoprefixer": "^6.5.3", "babel-cli": "^6.24.1", "babel-core": "^6.18.2", "babel-eslint": "^7.1.1", "babel-helper-vue-jsx-merge-props": "^2.0.2", "babel-loader": "^6.2.8", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-object-assign": "^6.22.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-transform-vue-jsx": "^3.2.0", "babel-preset-es2015": "^6.18.0", "babel-preset-stage-1": "^6.24.1", "babel-preset-vue": "^0.1.0", "babel-register": "^6.18.0", "chalk": "^1.1.3", "connect-history-api-fallback": "^1.3.0", "css-loader": "^0.26.0", "eslint": "^3.10.2", "eslint-config-vue-impression": "2.1.6", "eslint-friendly-formatter": "^2.0.6", "eslint-import-resolver-webpack": "^0.7.0", "eslint-loader": "^1.6.1", "eslint-plugin-import": "^2.2.0", "extract-text-webpack-plugin": "2.1.2", "file-loader": "^0.9.0", "fs-extra": "^7.0.0", "gulp": "^4.0.0", "gulp-autoprefixer": "^3.1.1", "gulp-babel": "7.0.1", "gulp-cssmin": "^0.1.7", "gulp-imagemin": "^3.1.1", "gulp-load-plugins": "^1.5.0", "gulp-minify-css": "^1.2.4", "gulp-rename": "^1.2.2", "gulp-sass": "4.0.1", "html-webpack-plugin": "^2.24.1", "json-loader": "^0.5.4", "minimist": "^1.2.0", "postcss": "6.0.23", "replace-ext": "^1.0.0", "through2": "^2.0.3", "url-loader": "^0.5.7", "vue-html-loader": "^1.2.3", "vue-loader": "^10.0.0", "vue-router": "^2.1.1", "vue-style-loader": "^1.0.0", "vue-template-compiler": "^2.1.10", "webpack": "2.7.0", "webpack-dashboard": "^0.2.0", "webpack-dev-middleware": "^1.8.4", "webpack-dev-server": "^1.16.2", "webpack-hot-middleware": "^2.13.2", "webpack-merge": "^0.17.0" }, "dependencies": { "babel-runtime": "^6.26.0", "vue": "^2.1.10" } } ================================================ FILE: src/scripts/components/Alert.vue ================================================ ================================================ FILE: src/scripts/components/BackToTop.vue ================================================ ================================================ FILE: src/scripts/components/Badge.vue ================================================ ================================================ FILE: src/scripts/components/Button.vue ================================================ ================================================ FILE: src/scripts/components/Card.vue ================================================ ================================================ FILE: src/scripts/components/CardBody.vue ================================================ ================================================ FILE: src/scripts/components/Cell.vue ================================================ ================================================ FILE: src/scripts/components/Checkbox.vue ================================================ ================================================ FILE: src/scripts/components/CheckboxGroup.vue ================================================ ================================================ FILE: src/scripts/components/DatePicker/DateRange.vue ================================================ ================================================ FILE: src/scripts/components/DatePicker/DateTable.vue ================================================ ================================================ FILE: src/scripts/components/DatePicker/Picker.vue ================================================ ================================================ FILE: src/scripts/components/DatePicker/index.js ================================================ import Picker from './Picker'; import DateRangeView from './DateRange'; const getView = function(type) { if(type === 'daterange') { return DateRangeView; } // other type view return null; }; const DatePicker = { mixins: [Picker], name: 'date-picker', props: { type: { type: String, default: 'daterange', }, }, watch: { type(type) { if(this.picker) { this.unmountPicker(); this.view = getView(type); this.mountPicker(); } else { this.view = getView(type); } }, }, created() { this.view = getView(this.type); }, }; export default DatePicker; ================================================ FILE: src/scripts/components/Drawer.vue ================================================ ================================================ FILE: src/scripts/components/DrawerItem.vue ================================================ ================================================ FILE: src/scripts/components/Flex.vue ================================================ ================================================ FILE: src/scripts/components/FlexItem.vue ================================================ ================================================ FILE: src/scripts/components/Group.vue ================================================ ================================================ FILE: src/scripts/components/GroupTitle.vue ================================================ ================================================ FILE: src/scripts/components/HRule.vue ================================================ ================================================ FILE: src/scripts/components/Icon.vue ================================================ ================================================ FILE: src/scripts/components/InlineSelector.vue ================================================ ================================================ FILE: src/scripts/components/InlineSelectorOption.vue ================================================ ================================================ FILE: src/scripts/components/InputNumber.vue ================================================ ================================================ FILE: src/scripts/components/InputText.vue ================================================ ================================================ FILE: src/scripts/components/InputTextarea.vue ================================================ ================================================ FILE: src/scripts/components/Loading.vue ================================================ ================================================ FILE: src/scripts/components/Loadmore.vue ================================================ ================================================ FILE: src/scripts/components/Mask.vue ================================================ ================================================ FILE: src/scripts/components/Media.vue ================================================ ================================================ FILE: src/scripts/components/MediaBody.vue ================================================ ================================================ FILE: src/scripts/components/MediaObject.vue ================================================ ================================================ FILE: src/scripts/components/Navbar.vue ================================================ ================================================ FILE: src/scripts/components/Navigation.vue ================================================ ================================================ FILE: src/scripts/components/NavigationItem.vue ================================================ ================================================ FILE: src/scripts/components/Picker.vue ================================================ ================================================ FILE: src/scripts/components/PickerOption.vue ================================================ ================================================ FILE: src/scripts/components/Progressbar.vue ================================================ ================================================ FILE: src/scripts/components/Progressbars.vue ================================================ ================================================ FILE: src/scripts/components/Radio.vue ================================================ ================================================ FILE: src/scripts/components/RadioGroup.vue ================================================ ================================================ FILE: src/scripts/components/Searchbar.vue ================================================ ================================================ FILE: src/scripts/components/SearchbarBtn.vue ================================================ ================================================ FILE: src/scripts/components/SearchbarPlaceholder.vue ================================================ ================================================ FILE: src/scripts/components/SegmentedControl.vue ================================================ ================================================ FILE: src/scripts/components/SegmentedControlItem.vue ================================================ ================================================ FILE: src/scripts/components/Selector.vue ================================================ ================================================ FILE: src/scripts/components/SelectorOption.vue ================================================ ================================================ FILE: src/scripts/components/Sidelip.vue ================================================ ================================================ FILE: src/scripts/components/SlideUp.vue ================================================ ================================================ FILE: src/scripts/components/SlideUpBody.vue ================================================ = ================================================ FILE: src/scripts/components/SlideUpHeader.vue ================================================ ================================================ FILE: src/scripts/components/Stepbar.vue ================================================ ================================================ FILE: src/scripts/components/StepbarItem.vue ================================================ ================================================ FILE: src/scripts/components/Sticky.vue ================================================ ================================================ FILE: src/scripts/components/Swipe.vue ================================================ ================================================ FILE: src/scripts/components/SwipeItem.vue ================================================ ================================================ FILE: src/scripts/components/Tabbar.vue ================================================ ================================================ FILE: src/scripts/components/TabbarItem.vue ================================================ ================================================ FILE: src/scripts/components/Tag.vue ================================================ ================================================ FILE: src/scripts/components/Timeline.vue ================================================ ================================================ FILE: src/scripts/components/TimelineItem.vue ================================================ ================================================ FILE: src/scripts/components/Tip.vue ================================================ ================================================ FILE: src/scripts/components/Toast.vue ================================================ ================================================ FILE: src/scripts/components/Toggle.vue ================================================ ================================================ FILE: src/scripts/components/index.js ================================================ import Button from './Button'; import Icon from './Icon'; import Group from './Group'; import GroupTitle from './GroupTitle'; import Cell from './Cell'; import Flex from './Flex'; import FlexItem from './FlexItem'; import Navbar from './Navbar'; import Tabbar from './Tabbar'; import TabbarItem from './TabbarItem'; import Mask from './Mask'; import Loading from './Loading'; import Checkbox from './Checkbox'; import CheckboxGroup from './CheckboxGroup'; import Radio from './Radio'; import RadioGroup from './RadioGroup'; import Toggle from './Toggle'; import InputNumber from './InputNumber'; import InputText from './InputText'; import InputTextarea from './InputTextarea'; import Selector from './Selector'; import SelectorOption from './SelectorOption'; import InlineSelector from './InlineSelector'; import InlineSelectorOption from './InlineSelectorOption'; import Navigation from './Navigation'; import NavigationItem from './NavigationItem'; import Tag from './Tag'; import Tip from './Tip'; import HRule from './HRule'; import BackToTop from './BackToTop'; import Badge from './Badge'; import Drawer from './Drawer'; import DrawerItem from './DrawerItem'; import SlideUp from './SlideUp'; import SlideUpHeader from './SlideUpHeader'; import SlideUpBody from './SlideUpBody'; import SegmentedControl from './SegmentedControl'; import SegmentedControlItem from './SegmentedControlItem'; import Sidelip from './Sidelip'; import Media from './Media'; import MediaObject from './MediaObject'; import MediaBody from './MediaBody'; import Card from './Card'; import CardBody from './CardBody'; import DatePicker from './DatePicker'; import Searchbar from './Searchbar'; import SearchbarBtn from './SearchbarBtn'; import SearchbarPlaceholder from './SearchbarPlaceholder'; import Picker from './Picker'; import PickerOption from './PickerOption'; import Loadmore from './Loadmore'; import Alert from './Alert'; import Swipe from './Swipe'; import SwipeItem from './SwipeItem'; import Progressbar from './Progressbar'; import Progressbars from './Progressbars'; import Stepbar from './Stepbar'; import StepbarItem from './StepbarItem'; import Timeline from './Timeline'; import TimelineItem from './TimelineItem'; import Sticky from './Sticky'; // global utils import toast from '../utils/toast'; import { alert } from '../utils/alert'; import loading from '../utils/loading'; // directives import disfavor from '../directives/disfavor'; const impression = { Button, Group, GroupTitle, Cell, Flex, FlexItem, Icon, Tag, Tip, HRule, Badge, Media, MediaObject, MediaBody, Card, CardBody, Swipe, SwipeItem, Navbar, Tabbar, TabbarItem, Navigation, NavigationItem, Drawer, DrawerItem, SegmentedControl, SegmentedControlItem, SlideUp, SlideUpHeader, SlideUpBody, Sidelip, Searchbar, SearchbarBtn, SearchbarPlaceholder, Picker, PickerOption, Loadmore, Mask, Alert, Loading, BackToTop, Checkbox, CheckboxGroup, Radio, RadioGroup, Toggle, InputNumber, InputText, InputTextarea, Selector, SelectorOption, InlineSelector, InlineSelectorOption, DatePicker, Progressbar, Progressbars, Stepbar, StepbarItem, Timeline, TimelineItem, Sticky, }; const install = Vue => { if(install.installed) return; // components Object.keys(impression).forEach(key => { Vue.component(impression[key].name, impression[key]); }); // global component utils Vue.$toast = Vue.prototype.$toast = toast; Vue.$alert = Vue.prototype.$alert = alert; Vue.$loading = Vue.prototype.$loading = loading; // directives Vue.directive('disfavor', disfavor); }; if(typeof window !== 'undefined' && window.Vue) { install(window.Vue); } export { Button, Group, GroupTitle, Cell, Flex, FlexItem, Icon, Tag, Tip, HRule, Badge, Media, MediaObject, MediaBody, Card, CardBody, Swipe, SwipeItem, Navbar, Tabbar, TabbarItem, Navigation, NavigationItem, Drawer, DrawerItem, SegmentedControl, SegmentedControlItem, SlideUp, SlideUpHeader, SlideUpBody, Sidelip, Searchbar, SearchbarBtn, SearchbarPlaceholder, Picker, PickerOption, Loadmore, Mask, Alert, Loading, BackToTop, Checkbox, CheckboxGroup, Radio, RadioGroup, Toggle, InputNumber, InputText, InputTextarea, Selector, SelectorOption, InlineSelector, InlineSelectorOption, DatePicker, Progressbar, Stepbar, StepbarItem, Timeline, TimelineItem, Sticky, }; export default { install, ...impression, }; ================================================ FILE: src/scripts/containers/layout.vue ================================================ ================================================ FILE: src/scripts/containers/menubar.vue ================================================ ================================================ FILE: src/scripts/directives/disfavor.js ================================================ import { contains } from '../utils/dom'; const disfavorContext = '@@disfavor'; // 失去焦点 export default { bind(el, binding, vnode) { const clickHandle = event => { if(vnode.context && !contains(el, event.target)) { el[disfavorContext].callback && vnode.context[el[disfavorContext].callback](); } }; el[disfavorContext] = { clickHandle, callback: binding.expression, }; document.addEventListener('click', clickHandle); }, unbind(el) { let { clickHandle } = el[disfavorContext]; document.removeEventListener('click', clickHandle); }, }; ================================================ FILE: src/scripts/index.js ================================================ import Vue from 'vue'; import router from './router'; import Impression from './components'; Vue.use(Impression); /* eslint-disable no-new */ new Vue({ el: '#app', router, template: '', }); ================================================ FILE: src/scripts/mixins/emitter.js ================================================ export default { methods: { dispatch(componentName, eventName, params) { let parent = this.$parent || this.$root, name = parent.$options._componentTag; while(parent && (!name || name !== componentName)) { parent = parent.$parent; if(parent) { name = parent.$options._componentTag; } } if(parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, }, }; ================================================ FILE: src/scripts/mixins/select.js ================================================ export default { props: { multiple: Boolean, }, data() { return { currentText: {}, }; }, methods: { optionClickHandle(option) { if(this.disabled || this.currentValue === option.value) return; if(this.multiple) { this.currentValue = this.currentValue || []; let index = this.currentValue.indexOf(option.value); if(index === -1) { this.currentValue.push(option.value); } else { this.currentValue.splice(index, 1); } return; } this.currentText = option.$el.innerText.trim(); this.currentValue = option.value; }, }, created() { this.$on('optionClick', this.optionClickHandle); }, }; ================================================ FILE: src/scripts/mixins/selectOption.js ================================================ export default { props: { value: {}, checkedIcon: { type: String, default: 'check', }, disabled: Boolean, }, methods: { clickHandle() { if(this.disabled) return; this.$parent.$emit.apply(this.$parent, ['optionClick'].concat(this)); }, isActive() { if(this.$parent.multiple) { return this.$parent.currentValue && this.$parent.currentValue.indexOf(this.value) !== -1; } return this.$parent.currentValue === this.value; }, }, }; ================================================ FILE: src/scripts/mixins/sync.js ================================================ import { isArray } from '../utils/type'; export default { props: { value: {}, disabled: Boolean, }, data() { return { currentValue: this.value, }; }, watch: { value(val) { this.currentValue = val; }, currentValue(val) { if(this.disabled) return; if(isArray(val) && val.length === 0) { this.currentValue = undefined; return; } this.$emit('input', val); this.$emit('change', val, this.currentText); }, }, }; ================================================ FILE: src/scripts/mixins/tab.js ================================================ export default { props: { activeKey: {}, disabled: Boolean, }, data() { return { currentActiveKey: this.activeKey, }; }, methods: { itemClickHandle(val) { if(this.currentActiveKey === val) return; this.currentActiveKey = val; this.$emit('change', val); }, }, created() { this.$on('itemClick', this.itemClickHandle); }, }; ================================================ FILE: src/scripts/mixins/tabItem.js ================================================ export default { props: { eventKey: {}, disabled: Boolean, }, data() { return { currentEventKey: this.eventKey, index: 0, }; }, mounted() { this.index = this.$parent.$children.indexOf(this); this.eventKey === undefined && (this.currentEventKey = this.index); }, methods: { clickHandle() { if(this.disabled || this.$parent.disabled) return; this.$parent.$emit('itemClick', this.currentEventKey, this.index); }, }, }; ================================================ FILE: src/scripts/router.js ================================================ import Vue from 'vue'; import VueRouter from 'vue-router'; import routesConfig from './routes.json'; Vue.use(VueRouter); // 提取路由 const extractRoutes = config => { const routes = [], children = []; routes.push({ path: '/', component: require('./containers/layout'), children, }); config.forEach(group => { group.children.forEach(item => { const { path, name } = item; children.push({ path, name, component: require(`./views${path}`), }); }); }); return routes; }; const routes = extractRoutes(routesConfig); // 创建router对象 const router = new VueRouter({ base: __dirname, routes, }); export default router; ================================================ FILE: src/scripts/routes.json ================================================ [ { "title": "Base", "children": [ { "path": "/button", "name": "Button", "icon": "hand-pointer-o" }, { "path": "/icon", "name": "Icon", "icon": "flag" }, { "path": "/cell", "name": "Group && Cell", "icon": "list" }, { "path": "/flex", "name": "Flex && FlexItem", "icon": "th" }, { "path": "/tag", "name": "Tag", "icon": "tag" }, { "path": "/badge", "name": "Badge", "icon": "bell-o" }, { "path": "/hrule", "name": "HRule(Hr)", "icon": "minus" }, { "path": "/tip", "name": "Tip", "icon": "paperclip" }, { "path": "/card", "name": "Card", "icon": "file-image-o" }, { "path": "/media", "name": "Media", "icon": "id-card-o" }, { "path": "/swipe", "name": "Swipe", "icon": "newspaper-o" }, { "path": "/datepicker", "name": "DatePicker", "icon": "newspaper-o" } ] }, { "title": "Layout", "children": [ { "path": "/navbar", "name": "Navbar", "icon": "window-maximize" }, { "path": "/tabbar", "name": "Tabbar", "icon": "clone" }, { "path": "/navigation", "name": "Navigation", "icon": "tablet" }, { "path": "/drawer", "name": "Drawer", "icon": "caret-square-o-down" }, { "path": "/segmented-control", "name": "SegmentedControl", "icon": "columns" }, { "path": "/slideup", "name": "SlideUp", "icon": "angle-double-up" }, { "path": "/sideslip", "name": "Sideslip", "icon": "window-restore" }, { "path": "/searchbar", "name": "Searchbar", "icon": "search" }, { "path": "/stepbar", "name": "Stepbar", "icon": "flag-checkered" }, { "path": "/timeline", "name": "Timeline", "icon": "flag-o" }, { "path": "/picker", "name": "Picker", "icon": "building-o" }, { "path": "/pull-down", "name": "Pull down", "icon": "long-arrow-down" }, { "path": "/pull-up", "name": "Pull up", "icon": "long-arrow-up" }, { "path": "/sticky", "name": "Sticky Affix", "icon": "thumb-tack" } ] }, { "title": "prompt", "children": [ { "path": "/toast", "name": "Toast", "icon": "commenting-o" }, { "path": "/alert", "name": "Alert", "icon": "bullhorn" }, { "path": "/loading", "name": "loading", "icon": "spinner" }, { "path": "/progressbar", "name": "Progressbar", "icon": "battery-three-quarters" }, { "path": "/back-to-top", "name": "BackToTop", "icon": "arrow-circle-up" } ] }, { "title": "form", "children": [ { "path": "/checkbox", "name": "Checkbox", "icon": "check-square" }, { "path": "/radio", "name": "Radio", "icon": "dot-circle-o" }, { "path": "/toggle", "name": "Toggle(Switch)", "icon": "toggle-on" }, { "path": "/input-text", "name": "InputText", "icon": "font" }, { "path": "/input-number", "name": "InputNumber", "icon": "plus-circle" }, { "path": "/input-textarea", "name": "InputTextarea", "icon": "file-text-o" }, { "path": "/selector", "name": "Selector", "icon": "check" }, { "path": "/inline-selecor", "name": "InlineSelector", "icon": "th-large" } ] } ] ================================================ FILE: src/scripts/utils/alert.js ================================================ import Vue from 'vue'; import OriginAlert from '../components/Alert'; const Alert = Vue.extend(OriginAlert); let alertInstance; // Alert框 export const alert = option => { option.title = option.title || '提示'; alertInstance = new Alert({ el: document.createElement('div'), }); document.body.appendChild(alertInstance.$el); Object.assign(alertInstance, option); Vue.nextTick(() => { alertInstance.show(); }); return alertInstance; }; alert.hide = () => { alertInstance.hide(); }; ================================================ FILE: src/scripts/utils/cssPrefix.js ================================================ let engine; let docStyle = document.documentElement.style; if('MozAppearance' in docStyle) { engine = 'gecko'; } else if('WebkitAppearance' in docStyle) { engine = 'webkit'; } else if(typeof navigator.cpuClass === 'string') { engine = 'trident'; } export const vendorPrefix = { trident: 'ms', gecko: 'Moz', webkit: 'Webkit' }[engine]; export const cssPrefix = { trident: '-ms-', gecko: '-moz-', webkit: '-webkit-', presto: '-o-' }[engine]; export const getPrefixStyle = (name, value) => { let namePrefix = `${cssPrefix}${name}`; return `${namePrefix} ${value}`; }; ================================================ FILE: src/scripts/utils/date.js ================================================ /*eslint-disable*/ import dateUtil from './dateUtil'; const weeks = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']; const newArray = function(start, end) { let result = []; for (let i = start; i <= end; i++) { result.push(i); } return result; }; export const toDate = function(date) { return isDate(date) ? new Date(date) : null; }; export const isDate = function(date) { if(date === null || date === undefined) return false; if(isNaN(new Date(date).getTime())) return false; if(Array.isArray(date)) return false; // deal with `new Date([ new Date() ]) -> new Date()` return true; }; export const isDateObject = function(val) { return val instanceof Date; }; export const formatDate = function(date, format) { date = toDate(date); if(!date) return ''; return dateUtil.format(date, format || 'yyyy-MM-dd'); }; export const parseDate = function(string, format) { return dateUtil.parse(string, format || 'yyyy-MM-dd'); }; export const getDayCountOfMonth = function(year, month) { if(month === 3 || month === 5 || month === 8 || month === 10) { return 30; } if(month === 1) { if(year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) { return 29; } else { return 28; } } return 31; }; export const getDayCountOfYear = function(year) { const isLeapYear = year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0); return isLeapYear ? 366 : 365; }; export const getFirstDayOfMonth = function(date) { const temp = new Date(date.getTime()); temp.setDate(1); return temp.getDay(); }; // see: https://stackoverflow.com/questions/3674539/incrementing-a-date-in-javascript // {prev, next} Date should work for Daylight Saving Time // Adding 24 * 60 * 60 * 1000 does not work in the above scenario export const prevDate = function(date, amount = 1) { return new Date(date.getFullYear(), date.getMonth(), date.getDate() - amount); }; export const nextDate = function(date, amount = 1) { return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount); }; export const getStartDateOfMonth = function(year, month) { const result = new Date(year, month, 1); const day = result.getDay(); if(day === 0) { return prevDate(result, 7); } else { return prevDate(result, day); } }; export const getWeekNumber = function(src) { if(!isDate(src)) return null; const date = new Date(src.getTime()); date.setHours(0, 0, 0, 0); // Thursday in current week decides the year. date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7); // January 4 is always in week 1. const week1 = new Date(date.getFullYear(), 0, 4); // Adjust to Thursday in week 1 and count number of weeks from date to week 1. // Rounding should be fine for Daylight Saving Time. Its shift should never be more than 12 hours. return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7); }; export const getRangeHours = function(ranges) { const hours = []; let disabledHours = []; (ranges || []).forEach(range => { const value = range.map(date => date.getHours()); disabledHours = disabledHours.concat(newArray(value[0], value[1])); }); if (disabledHours.length) { for (let i = 0; i < 24; i++) { hours[i] = disabledHours.indexOf(i) === -1; } } else { for (let i = 0; i < 24; i++) { hours[i] = false; } } return hours; }; export const range = function(n) { // see https://stackoverflow.com/questions/3746725/create-a-javascript-array-containing-1-n return Array.apply(null, {length: n}).map((_, n) => n); }; export const modifyDate = function(date, y, m, d) { return new Date(y, m, d, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); }; export const modifyTime = function(date, h, m, s) { return new Date(date.getFullYear(), date.getMonth(), date.getDate(), h, m, s, date.getMilliseconds()); }; export const modifyWithTimeString = (date, time) => { if(date == null || !time) { return date; } time = parseDate(time, 'HH:mm:ss'); return modifyTime(date, time.getHours(), time.getMinutes(), time.getSeconds()); }; export const clearTime = function(date) { return new Date(date.getFullYear(), date.getMonth(), date.getDate()); }; export const clearMilliseconds = function(date) { return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0); }; export const limitTimeRange = function(date, ranges, format = 'HH:mm:ss') { // TODO: refactory a more elegant solution if(ranges.length === 0) return date; const normalizeDate = date => dateUtil.parse(dateUtil.format(date, format), format); const ndate = normalizeDate(date); const nranges = ranges.map(range => range.map(normalizeDate)); if(nranges.some(nrange => ndate >= nrange[0] && ndate <= nrange[1])) return date; let minDate = nranges[0][0]; let maxDate = nranges[0][0]; nranges.forEach(nrange => { minDate = new Date(Math.min(nrange[0], minDate)); maxDate = new Date(Math.max(nrange[1], minDate)); }); const ret = ndate < minDate ? minDate : maxDate; // preserve Year/Month/Date return modifyDate( ret, date.getFullYear(), date.getMonth(), date.getDate() ); }; export const timeWithinRange = function(date, selectableRange, format) { const limitedDate = limitTimeRange(date, selectableRange, format); return limitedDate.getTime() === date.getTime(); }; export const changeYearMonthAndClampDate = function(date, year, month) { // clamp date to the number of days in `year`, `month` // eg: (2010-1-31, 2010, 2) => 2010-2-28 const monthDate = Math.min(date.getDate(), getDayCountOfMonth(year, month)); return modifyDate(date, year, month, monthDate); }; export const prevMonth = function(date) { const year = date.getFullYear(); const month = date.getMonth(); return month === 0 ? changeYearMonthAndClampDate(date, year - 1, 11) : changeYearMonthAndClampDate(date, year, month - 1); }; export const nextMonth = function(date) { const year = date.getFullYear(); const month = date.getMonth(); return month === 11 ? changeYearMonthAndClampDate(date, year + 1, 0) : changeYearMonthAndClampDate(date, year, month + 1); }; export const prevYear = function(date, amount = 1) { const year = date.getFullYear(); const month = date.getMonth(); return changeYearMonthAndClampDate(date, year - amount, month); }; export const nextYear = function(date, amount = 1) { const year = date.getFullYear(); const month = date.getMonth(); return changeYearMonthAndClampDate(date, year + amount, month); }; export const extractDateFormat = function(format) { return format .replace(/\W?m{1,2}|\W?ZZ/g, '') .replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi, '') .trim(); }; export const extractTimeFormat = function(format) { return format .replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g, '') .trim(); }; ================================================ FILE: src/scripts/utils/dateUtil.js ================================================ /* Modified from https://github.com/taylorhakes/fecha * * The MIT License (MIT) * * Copyright (c) 2015 Taylor Hakes * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /*eslint-disable*/ // 把 YYYY-MM-DD 改成了 yyyy-MM-dd (function (main) { 'use strict'; /** * Parse or format dates * @class fecha */ var fecha = {}; var token = /d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g; var twoDigits = /\d\d?/; var threeDigits = /\d{3}/; var fourDigits = /\d{4}/; var word = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i; var noop = function () { }; function shorten(arr, sLen) { var newArr = []; for (var i = 0, len = arr.length; i < len; i++) { newArr.push(arr[i].substr(0, sLen)); } return newArr; } function monthUpdate(arrName) { return function (d, v, i18n) { var index = i18n[arrName].indexOf(v.charAt(0).toUpperCase() + v.substr(1).toLowerCase()); if (~index) { d.month = index; } }; } function pad(val, len) { val = String(val); len = len || 2; while (val.length < len) { val = '0' + val; } return val; } var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; var monthNamesShort = shorten(monthNames, 3); var dayNamesShort = shorten(dayNames, 3); fecha.i18n = { dayNamesShort: dayNamesShort, dayNames: dayNames, monthNamesShort: monthNamesShort, monthNames: monthNames, amPm: ['am', 'pm'], DoFn: function DoFn(D) { return D + ['th', 'st', 'nd', 'rd'][D % 10 > 3 ? 0 : (D - D % 10 !== 10) * D % 10]; } }; var formatFlags = { D: function(dateObj) { return dateObj.getDay(); }, DD: function(dateObj) { return pad(dateObj.getDay()); }, Do: function(dateObj, i18n) { return i18n.DoFn(dateObj.getDate()); }, d: function(dateObj) { return dateObj.getDate(); }, dd: function(dateObj) { return pad(dateObj.getDate()); }, ddd: function(dateObj, i18n) { return i18n.dayNamesShort[dateObj.getDay()]; }, dddd: function(dateObj, i18n) { return i18n.dayNames[dateObj.getDay()]; }, M: function(dateObj) { return dateObj.getMonth() + 1; }, MM: function(dateObj) { return pad(dateObj.getMonth() + 1); }, MMM: function(dateObj, i18n) { return i18n.monthNamesShort[dateObj.getMonth()]; }, MMMM: function(dateObj, i18n) { return i18n.monthNames[dateObj.getMonth()]; }, yy: function(dateObj) { return String(dateObj.getFullYear()).substr(2); }, yyyy: function(dateObj) { return dateObj.getFullYear(); }, h: function(dateObj) { return dateObj.getHours() % 12 || 12; }, hh: function(dateObj) { return pad(dateObj.getHours() % 12 || 12); }, H: function(dateObj) { return dateObj.getHours(); }, HH: function(dateObj) { return pad(dateObj.getHours()); }, m: function(dateObj) { return dateObj.getMinutes(); }, mm: function(dateObj) { return pad(dateObj.getMinutes()); }, s: function(dateObj) { return dateObj.getSeconds(); }, ss: function(dateObj) { return pad(dateObj.getSeconds()); }, S: function(dateObj) { return Math.round(dateObj.getMilliseconds() / 100); }, SS: function(dateObj) { return pad(Math.round(dateObj.getMilliseconds() / 10), 2); }, SSS: function(dateObj) { return pad(dateObj.getMilliseconds(), 3); }, a: function(dateObj, i18n) { return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1]; }, A: function(dateObj, i18n) { return dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase(); }, ZZ: function(dateObj) { var o = dateObj.getTimezoneOffset(); return (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4); } }; var parseFlags = { d: [twoDigits, function (d, v) { d.day = v; }], M: [twoDigits, function (d, v) { d.month = v - 1; }], yy: [twoDigits, function (d, v) { var da = new Date(), cent = +('' + da.getFullYear()).substr(0, 2); d.year = '' + (v > 68 ? cent - 1 : cent) + v; }], h: [twoDigits, function (d, v) { d.hour = v; }], m: [twoDigits, function (d, v) { d.minute = v; }], s: [twoDigits, function (d, v) { d.second = v; }], yyyy: [fourDigits, function (d, v) { d.year = v; }], S: [/\d/, function (d, v) { d.millisecond = v * 100; }], SS: [/\d{2}/, function (d, v) { d.millisecond = v * 10; }], SSS: [threeDigits, function (d, v) { d.millisecond = v; }], D: [twoDigits, noop], ddd: [word, noop], MMM: [word, monthUpdate('monthNamesShort')], MMMM: [word, monthUpdate('monthNames')], a: [word, function (d, v, i18n) { var val = v.toLowerCase(); if (val === i18n.amPm[0]) { d.isPm = false; } else if (val === i18n.amPm[1]) { d.isPm = true; } }], ZZ: [/[\+\-]\d\d:?\d\d/, function (d, v) { var parts = (v + '').match(/([\+\-]|\d\d)/gi), minutes; if (parts) { minutes = +(parts[1] * 60) + parseInt(parts[2], 10); d.timezoneOffset = parts[0] === '+' ? minutes : -minutes; } }] }; parseFlags.DD = parseFlags.D; parseFlags.dddd = parseFlags.ddd; parseFlags.Do = parseFlags.dd = parseFlags.d; parseFlags.mm = parseFlags.m; parseFlags.hh = parseFlags.H = parseFlags.HH = parseFlags.h; parseFlags.MM = parseFlags.M; parseFlags.ss = parseFlags.s; parseFlags.A = parseFlags.a; // Some common format strings fecha.masks = { 'default': 'ddd MMM dd yyyy HH:mm:ss', shortDate: 'M/D/yy', mediumDate: 'MMM d, yyyy', longDate: 'MMMM d, yyyy', fullDate: 'dddd, MMMM d, yyyy', shortTime: 'HH:mm', mediumTime: 'HH:mm:ss', longTime: 'HH:mm:ss.SSS' }; /*** * Format a date * @method format * @param {Date|number} dateObj * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate' */ fecha.format = function (dateObj, mask, i18nSettings) { var i18n = i18nSettings || fecha.i18n; if (typeof dateObj === 'number') { dateObj = new Date(dateObj); } if (Object.prototype.toString.call(dateObj) !== '[object Date]' || isNaN(dateObj.getTime())) { throw new Error('Invalid Date in fecha.format'); } mask = fecha.masks[mask] || mask || fecha.masks['default']; return mask.replace(token, function ($0) { return $0 in formatFlags ? formatFlags[$0](dateObj, i18n) : $0.slice(1, $0.length - 1); }); }; /** * Parse a date string into an object, changes - into / * @method parse * @param {string} dateStr Date string * @param {string} format Date parse format * @returns {Date|boolean} */ fecha.parse = function (dateStr, format, i18nSettings) { var i18n = i18nSettings || fecha.i18n; if (typeof format !== 'string') { throw new Error('Invalid format in fecha.parse'); } format = fecha.masks[format] || format; // Avoid regular expression denial of service, fail early for really long strings // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS if (dateStr.length > 1000) { return false; } var isValid = true; var dateInfo = {}; format.replace(token, function ($0) { if (parseFlags[$0]) { var info = parseFlags[$0]; var index = dateStr.search(info[0]); if (!~index) { isValid = false; } else { dateStr.replace(info[0], function (result) { info[1](dateInfo, result, i18n); dateStr = dateStr.substr(index + result.length); return result; }); } } return parseFlags[$0] ? '' : $0.slice(1, $0.length - 1); }); if (!isValid) { return false; } var today = new Date(); if (dateInfo.isPm === true && dateInfo.hour != null && +dateInfo.hour !== 12) { dateInfo.hour = +dateInfo.hour + 12; } else if (dateInfo.isPm === false && +dateInfo.hour === 12) { dateInfo.hour = 0; } var date; if (dateInfo.timezoneOffset != null) { dateInfo.minute = +(dateInfo.minute || 0) - +dateInfo.timezoneOffset; date = new Date(Date.UTC(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0)); } else { date = new Date(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0); } return date; }; /* istanbul ignore next */ if (typeof module !== 'undefined' && module.exports) { module.exports = fecha; } else if (typeof define === 'function' && define.amd) { define(function () { return fecha; }); } else { main.fecha = fecha; } })(this); ================================================ FILE: src/scripts/utils/dom.js ================================================ /** * 判断一个元素是否为另一个的后代元素. * @param {[Element]} ancestor [祖先元素] * @param {[Element]} descendent [后代元素] * @return {[Boolean]} [是否] */ export const contains = (ancestor, descendent) => { if(ancestor.compareDocumentPosition) { return ancestor === descendent || !!(ancestor.compareDocumentPosition(descendent) & 16); } if(ancestor.contains && descendent.nodeType === 1) { return ancestor.contains(descendent) && ancestor !== descendent; } let tmpDescendent = descendent; // 递归 while(tmpDescendent !== document) { tmpDescendent = tmpDescendent.parentNode; if(tmpDescendent === ancestor) return true; } return false; }; /** * 判断元素是否有滚动条. * @param {[Element]} el [元素] * @return {[Boolean]} [是否有滚动条] */ export const hasScrollbar = el => { if(!el) return false; return el.scrollHeight > el.offsetHeight; }; /** * 返回具有滚动条的祖先元素. * @param {[Element]} el [Dom元素] * @return {[Element]} [祖先元素] */ export const getScrollContainer = el => { let tmpEl = el; while(tmpEl !== document) { tmpEl = tmpEl.parentNode; if(hasScrollbar(tmpEl)) return tmpEl; } return document; }; /** * 返回布尔值. * @param {[Element]} el [Dom元素] * @param {[class]} cls [样式] * @return {[Boolean]} [是否有class] */ export const hasClass = (el, cls) => { if(!el || !cls) return false; if(cls.indexOf(' ') !== -1) throw new Error('className should not contain space.'); if(el.classList) { return el.classList.contains(cls); } /*eslint-disable*/ return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1; /*eslint-disable*/ }; ================================================ FILE: src/scripts/utils/draggable.js ================================================ import { getTranslate } from './translate'; /* global document:true */ const draggable = (el, options) => { let prevTranslateX, prevTranslateY, dragState = { dragging: false, effectEl: options.effectEl || el, }; // start const onTouchStartHandle = (event, sourceEvent) => { if(dragState.dragging) return; let translate = getTranslate(dragState.effectEl); Object.assign(dragState, { startTimestamp: new Date(), pageX: event.pageX, pageY: event.pageY, translateX: translate.x, translateY: translate.y, }); document.onselectstart = () => false; document.ondragstart = () => false; if(options.onDragStart) options.onDragStart(dragState, sourceEvent); }; // move const onTouchMoveHandle = (event, sourceEvent) => { let deltaX = event.pageX - dragState.pageX, deltaY = event.pageY - dragState.pageY, translateX = dragState.translateX + deltaX, translateY = dragState.translateY + deltaY, velocityTranslateX = translateX - prevTranslateX || translateX, velocityTranslateY = translateY - prevTranslateY || translateY; prevTranslateX = translateX; prevTranslateY = translateY; Object.assign(dragState, { dragging: true, velocityTranslateX, velocityTranslateY, }); if(options.onDrag) { options.onDrag({ ...dragState, deltaX, deltaY, translateX, translateY, }, sourceEvent); } }; // end const onTouchEndHandle = (event, sourceEvent) => { Object.assign(dragState, { dragging: false, }); document.onselectstart = null; document.ondragstart = null; if(options.onDragEnd) options.onDragEnd(dragState, sourceEvent); // reset dragState = { dragging: false, effectEl: options.effectEl || el, }; }; el.addEventListener('touchstart', event => onTouchStartHandle(event.changedTouches[0] || event.touches[0], event)); el.addEventListener('touchmove', event => onTouchMoveHandle(event.changedTouches[0] || event.touches[0], event)); el.addEventListener('touchend', event => onTouchEndHandle(event.changedTouches[0] || event.touches[0], event)); el.addEventListener('touchcancel', event => onTouchEndHandle(event.changedTouches[0] || event.touches[0], event)); }; export default draggable; ================================================ FILE: src/scripts/utils/easing.js ================================================ // easeInOut export const easeInOutCubic = (time, offset, end, duration) => { let cc = end - offset, tempTime = time / (duration / 2); if(tempTime < 1) { return (cc / 2 * tempTime * tempTime * tempTime) + offset; } return (cc / 2 * (((tempTime -= 2) * tempTime * tempTime) + 2)) + offset; }; ================================================ FILE: src/scripts/utils/loading.js ================================================ import Vue from 'vue'; import OriginToast from '../components/Toast'; const Toast = Vue.extend(OriginToast); let instance, active = false; export default { show(message = '加载中') { if(active) return; /* global document:true */ if(!instance) { instance = new Toast({ el: document.createElement('div'), }); document.body.appendChild(instance.$el); } active = true; instance.message = message; instance.type = 'loading'; instance.position = 'center'; Vue.nextTick(() => { instance.show(); }); }, hide() { instance.hide(); active = false; }, toggle(message) { return active ? this.hide() : this.show(message); }, }; ================================================ FILE: src/scripts/utils/toast.js ================================================ import Vue from 'vue'; import OriginToast from '../components/Toast'; const Toast = Vue.extend(OriginToast); // toast缓存池 const toastCache = { cache: [], active: false, pop() { if(this.cache.length) return this.cache.splice(0, 1)[0]; return new Toast({ el: document.createElement('div'), }); }, push(instance) { this.cache.push(instance); }, toggle() { this.active = !this.active; }, }; Toast.prototype.show = function() { this.currentValue = true; toastCache.active = true; }; Toast.prototype.hide = function() { this.currentValue = false; toastCache.active = false; }; /* global document:true */ const toastUtil = (options = {}) => { if(toastCache.active) return; let duration = options.duration || 2000, instance = toastCache.pop(); instance.message = typeof options === 'string' ? options : options.message; instance.type = options.type || ''; instance.position = options.position || 'bottom'; document.body.appendChild(instance.$el); instance.show(); instance.timer = setTimeout(() => { instance.hide(); toastCache.push(instance); }, duration); }; export default toastUtil; ================================================ FILE: src/scripts/utils/translate.js ================================================ import { vendorPrefix } from './cssPrefix'; let transformProperty = `${vendorPrefix}Transform`; // 获取位移 export const getTranslate = el => { let result = { x: 0, y: 0, }; if(el === null || el.style === null) return result; let transform = el.style[transformProperty]; let matches = /translate\(\s*(-?\d+(\.?\d+?)?)px,\s*(-?\d+(\.\d+)?)px\)\s*(translateZ\(0px\))?/g.exec(transform); if(matches) { result.x = +matches[1]; result.y = +matches[3]; } return result; }; // 取消位移 export const cancelTranslate = el => { if(el === null || el.style === null) return; let transform = el.style[transformProperty]; if(transform) { transform = transform.replace(/translate\(\s*(-?\d+(\.?\d+?)?)px,\s*(-?\d+(\.\d+)?)px\)\s*(translateZ\(0px\))?/g, ''); el.style[transformProperty] = transform; } }; // 设置位移 export const setTranslate = (el, x, y) => { if(!el) return; if(x === null && y === null) return; // if(!el.style.transform && !x && !y) return; let translate = getTranslate(el), currentX = x, currentY = y; if(x === null) currentX = translate.x; if(y === null) currentY = translate.y; cancelTranslate(el); el.style[transformProperty] += ` translate(${currentX ? `${currentX}px` : '0px'}, ${currentY ? `${currentY}px` : '0px'})`; }; ================================================ FILE: src/scripts/utils/type.js ================================================ // 是否数组 export const isArray = array => Object.prototype.toString.call(array) === '[object Array]'; ================================================ FILE: src/scripts/views/alert.vue ================================================ ================================================ FILE: src/scripts/views/back-to-top.vue ================================================ ================================================ FILE: src/scripts/views/badge.vue ================================================ ================================================ FILE: src/scripts/views/button.vue ================================================ ================================================ FILE: src/scripts/views/card.vue ================================================ ================================================ FILE: src/scripts/views/cell.vue ================================================ ================================================ FILE: src/scripts/views/checkbox.vue ================================================ ================================================ FILE: src/scripts/views/confirm.vue ================================================ ================================================ FILE: src/scripts/views/datepicker.vue ================================================ ================================================ FILE: src/scripts/views/drawer.vue ================================================ ================================================ FILE: src/scripts/views/flex.vue ================================================ ================================================ FILE: src/scripts/views/hrule.vue ================================================ ================================================ FILE: src/scripts/views/icon.vue ================================================ ================================================ FILE: src/scripts/views/index.vue ================================================ ================================================ FILE: src/scripts/views/inline-selecor.vue ================================================ ================================================ FILE: src/scripts/views/input-number.vue ================================================ ================================================ FILE: src/scripts/views/input-text.vue ================================================ ================================================ FILE: src/scripts/views/input-textarea.vue ================================================ ================================================ FILE: src/scripts/views/loading.vue ================================================ ================================================ FILE: src/scripts/views/media.vue ================================================ ================================================ FILE: src/scripts/views/navbar.vue ================================================ ================================================ FILE: src/scripts/views/navigation.vue ================================================ ================================================ FILE: src/scripts/views/picker.vue ================================================ ================================================ FILE: src/scripts/views/progressbar.vue ================================================ ================================================ FILE: src/scripts/views/pull-down.vue ================================================ ================================================ FILE: src/scripts/views/pull-up.vue ================================================ ================================================ FILE: src/scripts/views/radio.vue ================================================ ================================================ FILE: src/scripts/views/searchbar.vue ================================================ ================================================ FILE: src/scripts/views/segmented-control.vue ================================================ ================================================ FILE: src/scripts/views/selector.vue ================================================ ================================================ FILE: src/scripts/views/sideslip.vue ================================================ ================================================ FILE: src/scripts/views/slideup.vue ================================================ ================================================ FILE: src/scripts/views/stepbar.vue ================================================ ================================================ FILE: src/scripts/views/sticky.vue ================================================ ================================================ FILE: src/scripts/views/swipe.vue ================================================ ================================================ FILE: src/scripts/views/tabbar.vue ================================================ ================================================ FILE: src/scripts/views/tag.vue ================================================ ================================================ FILE: src/scripts/views/timeline.vue ================================================ ================================================ FILE: src/scripts/views/tip.vue ================================================ ================================================ FILE: src/scripts/views/toast.vue ================================================ ================================================ FILE: src/scripts/views/toggle.vue ================================================ ================================================ FILE: src/styles/animate.scss ================================================ // fade @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } // slide @keyframes slideInUp { from { transform: translate3d(0, 100%, 0); } to { transform: translate3d(0, 0, 0); } } @keyframes slideOutDown { from { transform: translate3d(0, 0, 0); } to { visibility: hidden; transform: translate3d(0, 100%, 0); } } @keyframes slideInLeft { from { transform: translate3d(-100%, 0, 0); } to { transform: translate3d(0, 0, 0); } } @keyframes slideOutLeft { from { transform: translate3d(0, 0, 0); } to { visibility: hidden; transform: translate3d(-100%, 0, 0); } } // ZoomIn @keyframes lightZoomIn { 0% { opacity: .5; transform: scale(.5, .5); } 100% { opacity: 1; transform: scale(1, 1); } } @keyframes lightZoomOut { 0% { transform: scale(1, 1); } 100% { opacity: .5; transform: scale(.5, .5); } } ================================================ FILE: src/styles/index.scss ================================================ @import 'variables'; @import 'mixins'; @import 'modules'; @import 'utils'; @import 'animate'; ================================================ FILE: src/styles/mixins/border.scss ================================================ // 上边框 @mixin border-top { background-image: $border-image-top; background-size: 100% 1px; background-repeat: no-repeat; background-position: left top; } // 下边框 @mixin border-bottom { background-image: $border-image-bottom; background-size: 100% 1px; background-repeat: no-repeat; background-position: left bottom; } // 上下边框 @mixin border-vertical { background-image: $border-image-top, $border-image-bottom; background-size: 100% 1px; background-repeat: no-repeat, no-repeat; background-position: left top, left bottom; } @mixin border-left { background-image: $border-image-left; background-size: 1px 100%; background-repeat: no-repeat; background-position: left top; } @mixin no-border { background-size: 0; } ================================================ FILE: src/styles/mixins/button.scss ================================================ // Button sizes @mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { padding: $padding-y $padding-x; font-size: $font-size; border-radius: $border-radius; } // Button variant @mixin button-variant($color, $bg-color, $border-color) { $active-background: darken($bg-color, 6%); $active-border: darken($border-color, 6%); color: $color; background-color: $bg-color; border-color: $border-color; &:active, &.active { color: $color; background-color: $active-background; border-color: $active-border; } &.disabled, &:disabled { &:hover { background-color: $bg-color; border-color: $border-color; } } } // Button outline variant @mixin button-outline-variant($color) { color: $color; border-color: $color; background-color: transparent; &:active, &.active { color: $brand-pure; background-color: $color; } &.disabled, &:disabled { &:hover { background-color: transparent; border-color: $color; } } } ================================================ FILE: src/styles/mixins/media.scss ================================================ @mixin respond-to($size) { $query: map-get($all-media-query-device, $size); @if not $query { @error 'No value found for `#{$size}`. Please make sure it is defined in `$allMediaDevice` map.'; } @media only screen and #{if(type-of($query) == 'string', unquote($query), inspect($query))} { @content; } } ================================================ FILE: src/styles/mixins/navbar.scss ================================================ // Navbar variant @mixin navbar-variant($background-color, $color, $has-border) { background-color: $background-color; color: $color; @if $has-border { @include border-bottom(); } a { &, &:active, &:focus { color: $color; } } } ================================================ FILE: src/styles/mixins/progressbar.scss ================================================ @mixin progressbar-variant($background-color) { .progressbar-indicator { background-color: $background-color; } } ================================================ FILE: src/styles/mixins/tag.scss ================================================ @mixin tag-variant($background-color) { background-color: $background-color; } @mixin tag-outline-variant($border-color, $color:$border-color) { border-color: $border-color; color: $color; } ================================================ FILE: src/styles/mixins/text.scss ================================================ // Typography @mixin text-emphasis-variant($parent, $color) { #{$parent} { color: $color !important; } a#{$parent} { &:hover, &:focus { color: darken($color, 10%) !important; } } } ================================================ FILE: src/styles/mixins.scss ================================================ // utils @import 'mixins/border'; @import 'mixins/text'; @import 'mixins/button'; @import 'mixins/navbar'; @import 'mixins/tag'; @import 'mixins/progressbar'; @import 'mixins/media'; ================================================ FILE: src/styles/modules/alert.scss ================================================ .alert { position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: $z-index-alert; display: flex; align-items: center; justify-content: center; } .alert-modal { width: $alert-width; max-width: $alert-max-width; padding: $alert-padding; background-color: $alert-bg-color; border-radius: $alert-border-radius; box-shadow: $alert-box-h-shadow, $alert-box-v-shadow; } .alert-title { text-align: center; font-size: $alert-title-font-size; font-weight: $alert-title-font-weight; color: $alert-title-color; } .alert-message { text-align: $alert-message-text-align; color: $alert-message-color; font-size: $alert-message-font-size; padding: $alert-message-padding; line-height: $alert-message-line-height; } .alert-footer { display: flex; @include border-top; } .alert-btn { flex: 1; text-align: center; color: $alert-btn-color; font-size: $alert-btn-font-size; padding: $alert-btn-padding; &:not(:first-child) { @include border-left; } } .alert-footer-vertical { flex-direction: column; .alert-btn { &:not(:first-child) { @include no-border; } &:not(:last-child) { @include border-bottom; } } } .zoom-enter { opacity: .5; transform: scale(.5, .5); } .zoom-enter-active { animation: lightZoomIn $alert-animation-duration $alert-animation-enter-function; } .zoom-leave-active { animation: lightZoomOut $alert-animation-duration $alert-animation-leave-function; } ================================================ FILE: src/styles/modules/back-to-top.scss ================================================ .back-to-top { position: fixed; right: $top-right; bottom: -1.5 * $top-height; z-index: $z-index-top; text-align: center; border-radius: 50%; color: $top-color; background-color: $top-bg-color; &.active { bottom: $top-bottom; transition: $top-transition; .back-to-top-icon { transform: rotate(0deg); transition: $top-transition; } } } i.back-to-top-icon { width: $top-width; height: $top-height; font-size: $top-font-size; line-height: $top-line-height; transform: rotate(360deg); transform-origin: center center; } ================================================ FILE: src/styles/modules/badge.scss ================================================ .badge { position: relative; display: inline-block; vertical-align: middle; } .badge-gap { margin-right: $badge-margin-right; .badge-addon { box-shadow: $badge-box-shadow; } } .badge-addon { position: absolute; right: 0; top: 0; line-height: 1; text-align: center; border-radius: $border-radius-circle; color: $badge-color; padding: $badge-padding; min-width: $badge-min-width; min-height: $badge-min-height; transform: translateX(100%) translateY(-50%); &:not(:empty) { min-width: $badge-min-width-not-empty; // 使缩放后得到的是整数的px值 $width-px: $badge-min-width-not-empty * $font-size-root; $scale: round($width-px * $badge-scale) / $width-px; transform: translateX(50%) translateY(-50%) scale($scale); @include respond-to(md) { $width-px: $badge-min-width-not-empty * $font-size-root-md; $scale: round($width-px * $badge-scale) / $width-px; transform: translateX(50%) translateY(-50%) scale($scale); } @include respond-to(lg) { $width-px: $badge-min-width-not-empty * $font-size-root-lg; $scale: round($width-px * $badge-scale) / $width-px; transform: translateX(50%) translateY(-50%) scale($scale); } } &:last-child { position: static; transform: none; } } ================================================ FILE: src/styles/modules/button.scss ================================================ .btn { display: inline-block; appearance: none; overflow: hidden; outline: 0; text-align: center; white-space: nowrap; vertical-align: middle; user-select: none; border: 1px solid transparent; @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius); &, &:active { &:focus { outline: 0; background-image: none; } } &:hover, &:focus { text-decoration: none; } &:disabled { opacity: $btn-loading-opacity-disabled; &:not(.btn-loading) { opacity: $btn-opacity-disabled; } } .loading { display: inline-block; vertical-align: middle; margin-left: $btn-loading-gap; } } .btn-block { display: block; width: 100%; } // Size .btn-sm { @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm); } .btn-lg { @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg); } // Theme .btn-primary { @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); } .btn-secondary { @include button-variant($btn-secondary-color, $btn-secondary-bg, $btn-secondary-border); } .btn-default { @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border); } // Outline .btn-primary-outline { @include button-outline-variant($btn-primary-border); } .btn-secondary-outline { @include button-outline-variant($btn-secondary-border); } .btn-default-outline { @include button-outline-variant($btn-default-border); } ================================================ FILE: src/styles/modules/card.scss ================================================ .card { background-color: $card-bg-color; } .card-body { padding: $card-body-padding; } ================================================ FILE: src/styles/modules/cell.scss ================================================ .cell { display: flex; align-items: center; overflow: hidden; text-decoration: none; color: $cell-color; padding: $cell-padding; @include border-bottom(); background-position: $cell-gap-left 100%; background-color: $cell-bg-color; } .cell-no-gap { background-position: 0 100%; } .cell-link { &:focus { outline: 0; background-image: none; color: $cell-color; } &:active { background-color: $cell-bg-color-active; } } .cell-disabled { opacity: .6; // background-color: $cell-bg-color-disabled; } .cell-header { padding-right: $cell-children-gap; } .cell-body { flex: 1; display: block; } .cell-footer { padding-left: $cell-children-gap; } .cell-arrow { color: $cell-arrow-color; margin: $cell-arrow-margin; } ================================================ FILE: src/styles/modules/checkbox.scss ================================================ .checkbox, .radio { user-select: none; display: inline-block; } // shape .checkbox-square { .checkbox-addon { border-radius: $checkbox-square-border-radius; } } .checkbox-circle { .checkbox-addon { border-radius: 50%; } } // checkbox .checkbox-input, .radio-input { display: none; &:checked + .checkbox-addon, &:checked + .radio-addon { border-color: $checkbox-border-color-checked; background-color: $checkbox-bg-color-checked; i { transform: scale(1); } } &:disabled + .checkbox-addon, &:disabled + .radio-addon, { border-color: $checkbox-border-color-disabled; background-color: $checkbox-bg-color-disabled; } } // addon .checkbox-addon, .radio-addon { font-size: 0; vertical-align: middle; display: inline-block; color: $checkbox-color; padding: $checkbox-padding; background-color: $checkbox-bg-color; border: 1px solid $checkbox-border-color; transition: $checkbox-transition; } .checkbox-addon { line-height: 1; i { vertical-align: middle; transform: scale(0); transform-origin: 50% 50%; transition: $checkbox-transition; font-size: $checkbox-addon-font-size; width: $checkbox-addon-font-size; height: $checkbox-addon-font-size; line-height: $checkbox-addon-font-size; padding-top: $checkbox-addon-padding-top; } } .radio-default .radio-addon { border-radius: 50%; padding: $radio-addon-padding; line-height: 1; i { text-align: center; vertical-align: middle; display: inline-block; width: $radio-addon-width; height: $radio-addon-height; background: $checkbox-color; border-radius: 50%; transform: scale(0); transform-origin: 50% 50%; transition: $checkbox-transition; } } .radio-square .radio-addon { border-radius: $checkbox-square-border-radius; } .radio-circle .radio-addon { border-radius: 50%; } .radio-square .radio-addon, .radio-circle .radio-addon { line-height: 1; i { vertical-align: middle; transform: scale(0); transform-origin: 50% 50%; transition: $checkbox-transition; font-size: $checkbox-addon-font-size; width: $checkbox-addon-font-size; height: $checkbox-addon-font-size; line-height: $checkbox-addon-font-size; padding-top: $checkbox-addon-padding-top; } } // text .checkbox-label, .radios-label { display: inline-block; margin-left: $checkbox-label-gap; } .checkbox + .checkbox, .radio + .radio { margin-left: $checkbox-gap; } ================================================ FILE: src/styles/modules/date-picker.scss ================================================ $ColorBlue: #1287FF; $ColorGrey: #BCC1CC; .date-picker { width: 18.75em; box-sizing: border-box; margin: 0; padding: 0; .header { width: 100%; .header-cnt { width: 9em; padding: .5em 0; margin: 0 auto; .btn { // width: 2.5em; // height: 2.5em; // line-height: 2.5em; border: none; border-radius: 1.5em; // padding: .35rem .7rem; font-size: .6em; &.btn-left { float: left; padding: .35em .9em .4em .7em; } &.btn-right { float: right; padding: .35em .7em .4em .9em; } } // font-size: .8em; 改元素其他属性基于此综合计算 div { height: 1.875em; line-height: 1.875em; font-size: .8em; // 32px font-weight: 500; text-align: center; } } } table { display: table; table-layout: fixed; width: 100%; } // font-size: .7em; 其子元素属性基于此综合计算 .date-table { font-size: .7em; // 28px user-select: none; td { height: 3.9em; padding: .25em 0; box-sizing: border-box; text-align: center; cursor: pointer; position: relative; &.prev-month, &.next-month { } &.disabled div { cursor: not-allowed; } div { height: 2.2em; box-sizing: border-box; } span { width: 2.2em; height: 2.2em; line-height: 2.2em; display: block; margin: 0 auto; position: absolute; left: 50%; transform: translateX(-50%); border-radius: 50%; } &.today { position: relative; } &.in-range div, &.in-range div:hover { } &.start-date div { border-top-left-radius: 1em; border-bottom-left-radius: 1em; } &.end-date div { border-top-right-radius: 1em; border-bottom-right-radius: 1em; } &.end-date div, &.start-date div { } &.end-date span, &.start-date span { } } th { padding-top: .3em; font-weight: 400; text-align: center; } } } // Size .date-picker-base { font-size: $datepicker-font-size-base; } // Theme .date-picker-default { .header { background-color: #FFF; .btn { background-color: #f5f5f9; color: #737A89; } } table { background-color: #f5f5f9; } .date-table { td { color: #22252A; &.prev-month, &.next-month { color: $ColorGrey; } &.disabled div { background-color: #EEF1F6; color: #FFF; } &.today { span { border: 1px solid #22252A; } } &.in-range div, &.in-range div:hover { background-color: $ColorBlue; color: #FFF; } &.end-date div, &.start-date div { color: #FFF; } &.end-date span, &.start-date span { background-color: $ColorBlue; } } th { color: $ColorGrey; } } } ================================================ FILE: src/styles/modules/drawer.scss ================================================ .drawer { display: flex; color: $drawer-color; background-color: $drawer-bg-color; padding: $drawer-padding; @include border-bottom(); } .drawer-item { flex: 1; text-align: center; transition: $drawer-transition; &:not(:first-child) { @include border-left; } &.active { color: $drawer-color-active; .drawer-item-icon { color: $drawer-color-active; transform-origin: 50% 50%; transform: rotate(180deg); } } &.disabled { opacity: $drawer-opacity-disabled; } } .drawer-item-icon { color: $drawer-icon-color; margin-left: $drawer-icon-margin-right; transition: $drawer-transition; } ================================================ FILE: src/styles/modules/group.scss ================================================ .group { padding-top: 1px; padding-bottom: 1px; margin: $group-margin; @include border-vertical(); background-color: $cell-bg-color; > .cell:last-child { background-size: 0; } } // title .group-title { padding: $group-title-padding; + .group { margin: 0; } } ================================================ FILE: src/styles/modules/hrule.scss ================================================ .hr { border-width: 0; border-top-width: 1px; border-style: solid; border-color: $hr-color; transform: scaleY(.5); transform-origin: 0 0; margin: $hr-margin; } ================================================ FILE: src/styles/modules/inline-selector.scss ================================================ .inline-selector { display: block; } .inline-selector-option { line-height: 1; padding: $inline-selector-option-padding; transition: $inline-selector-transition; min-width: $inline-selector-option-min-width; &.disabled { border-style: dashed; } } ================================================ FILE: src/styles/modules/input-number.scss ================================================ .input-number { display: inline-block; } .input-number-disabled { opacity: .6; .input-number-input { background-color: $number-input-bg-color-disabled; } } .input-number-minus, .input-number-plus { text-align: center; display: inline-block; border-radius: 50%; appearance: none; overflow: hidden; outline: 0; white-space: nowrap; vertical-align: middle; user-select: none; font-weight: bold; height: $number-btn-size; width: $number-btn-size; line-height: $number-btn-line-height; border: 1px solid $number-border-color; &, &:active, &.active { &:focus { outline: 0; background-image: none; } } &:hover, &:focus { text-decoration: none; } &.disabled { opacity: $btn-opacity-disabled; } } .input-number-plus:not([href]) { &, &:active, &:focus, &:hover { color: $number-plus-color; background-color: $number-plus-bg-color; } &:active:not(.disabled) { background-color: $number-plus-bg-color-active; } } .input-number-minus:not([href]) { &, &:focus, &:hover { color: $number-minus-color; background-color: $number-minus-bg-color; } &:active:not(.disabled) { color: $number-minus-color-active; background-color: $number-minus-bg-color-active; } } .input-number-input { text-align: center; vertical-align: middle; width: $number-input-width; padding: $number-input-padding; margin: $number-input-margin; background: $number-input-bg-color; -webkit-appearance: none; -webkit-box-shadow: none; outline: none; line-height: 1; background-image: none; border: 1px solid $number-input-border-color; } ================================================ FILE: src/styles/modules/input-text.scss ================================================ .input-text { display: flex; align-items: center; } .input-text-input { flex: 1; border: 0; padding: 0; height: 100%; font-size: $input-font-size; background-color: transparent; &:focus { outline: none; } } i.input-text-clear { opacity: .2; transition: all .2s ease; + i { margin-left: $input-text-icon-gap; } } ================================================ FILE: src/styles/modules/input-textarea.scss ================================================ .textarea-input { border: 0; width: 100%; resize: none; display: block; appearance: none; user-select: auto; padding: $textarea-padding; &:focus { outline: none; } } .textarea-counter { text-align: right; transform-origin: right bottom; transform: scale($textarea-counter-scale); color: $textarea-counter-color; padding: $textarea-counter-padding; } ================================================ FILE: src/styles/modules/loading.scss ================================================ .loading { width: $loading-width; animation: rotate $loading-animation-duration linear infinite; } .loading-path { stroke-dasharray: 1,100; stroke-dashoffset: 0; stroke-linecap: round; stroke: $loading-path-stroke; stroke-width: $loading-path-stroke-width; animation: dash $loading-path-animation-duration ease-in-out infinite; } .loading-primary { .loading-path { stroke: $loading-path-stroke-primary; } } .loading-secondary { .loading-path { stroke: $loading-path-stroke-secondary; } } .loading-sm { width: $loading-width-sm; } @keyframes rotate { 100% { transform: rotate(1turn); } } @keyframes dash { 0% { stroke-dasharray: 1,150; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90,150; stroke-dashoffset: -35; } 100% { stroke-dasharray: 90,150; stroke-dashoffset: -124; } } ================================================ FILE: src/styles/modules/loadmore.scss ================================================ .loadmore { overflow: hidden; } .loadmore-content { &.dropped { transition: $loadmore-dropped-transition; } } .loadmore-hint { text-align: center; height: $loadmore-hint-height; line-height: $loadmore-hint-height; .loading { vertical-align: middle; } } .loadmore-hint-top { margin-top: $loadmore-hint-margin; } .loadmore-hint-bottom { margin-bottom: $loadmore-hint-margin; } .loadmore-text { vertical-align: middle; } ================================================ FILE: src/styles/modules/mask.scss ================================================ .mask { position: fixed; left: 0; top: 0; right: 0; bottom: 0; background-color: $mask-bg-color; z-index: $z-index-mask; } .fade-enter { opacity: 0; } .fade-enter-active { animation: fadeIn $mask-animation-enter-duration $mask-animation-enter-function; } .fade-leave-active { animation: fadeOut $mask-animation-leave-duration $mask-animation-leave-function; } ================================================ FILE: src/styles/modules/media.scss ================================================ .media { display: flex; background-color: $media-bg-color; } .media-object { display: block; &:first-child { padding-right: $media-object-gap; } &:last-child { padding-left: $media-object-gap; } } .media-body { flex: 1; display: block; } ================================================ FILE: src/styles/modules/navbar.scss ================================================ .navbar { display: flex; user-select: none; padding: $navbar-padding; height: $navbar-height; line-height: $navbar-line-height; a { &:active, &.active { &:focus { outline: 0; background-image: none; } } &:hover, &:focus { text-decoration: none; } } } .navbar-header { flex: $navbar-header-flex; padding: $navbar-header-padding; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .navbar-body { flex: $navbar-body-flex; padding: $navbar-body-padding; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .navbar-footer { flex: $navbar-footer-flex; padding: $navbar-footer-padding; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } // theme .navbar-primary { @include navbar-variant($navbar-primary-bg-color, $navbar-primary-color, false); } .navbar-default { @include navbar-variant($navbar-default-bg-color, $navbar-default-color, true); } ================================================ FILE: src/styles/modules/navigation.scss ================================================ .navigation { display: flex; align-items: center; @include border-top(); height: $navigation-height; background-color: $navigation-bg-color; } .navigation-item { flex: 1; display: flex; height: 100%; text-align: center; color: $navigation-color; align-items: center; flex-direction: column; justify-content: center; &.active { color: $navigation-color-active; } } .navigation-item-label { &:not(:first-child) { margin: $navigation-margin; transform: scale($navigation-label-scale); } } ================================================ FILE: src/styles/modules/picker.scss ================================================ .picker { width: 100%; display: block; position: relative; overflow: hidden; background: $picker-bg-color; height: $picker-items-count * $picker-item-height; } .picker-sm { height: $picker-items-count-sm * $picker-item-height; .picker-list { padding-top: ($picker-items-count-sm - 1) / 2 * $picker-item-height; } .picker-mask { background-image: $picker-mask-bg-image-sm; background-size: 100% $picker-item-height * ($picker-items-count-sm - 1) / 2; } } .picker-lg { height: $picker-items-count-lg * $picker-item-height; .picker-list { padding-top: ($picker-items-count-lg - 1) / 2 * $picker-item-height; } .picker-mask { background-image: $picker-mask-bg-image-lg; background-size: 100% $picker-item-height * ($picker-items-count-lg - 1) / 2; } } .picker-mask { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 2; background-image: $picker-mask-bg-image; background-size: 100% $picker-item-height * ($picker-items-count - 1) / 2; background-position: top, bottom; background-repeat: no-repeat; } .picker-indicator { position: absolute; left: 0; top: 50%; width: 100%; height: $picker-tap-height; transform: translateY(-50%); @include border-vertical; } .picker-list { position: absolute; left: 0; top: 0; width: 100%; text-align: center; padding-top: ($picker-items-count - 1) / 2 * $picker-item-height; transition: $picker-list-transition; &.active { transition-duration: 0s; } } .picker-list-item { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; backface-visibility: hidden; height: $picker-item-height; line-height: $picker-item-line-height; font-size: $picker-item-font-size; padding: $picker-item-padding; transition: $picker-item-transition; &.active { font-size: $picker-item-font-size-active; font-weight: $picker-item-font-weight-active; } } ================================================ FILE: src/styles/modules/progressbar.scss ================================================ .progressbar { height: $progressbar-height; overflow: hidden; background-color: $progressbar-bg-color; border-radius: $progressbar-border-radius; box-shadow: $progressbar-box-shadow; } .progressbar-indicator { float: left; width: 0; height: 100%; text-align: center; line-height: $progressbar-height; font-size: $progressbar-indicator-font-size; color: $progressbar-indicator-color; box-shadow: $progressbar-indicator-box-shadow; transition: $progressbar-indicator-transition; } .progressbar-sm { height: $progressbar-height-sm; border-radius: $progressbar-border-radius-sm; .progressbar-indicator { font-size: 0; } } .progressbar-primary { @include progressbar-variant($progressbar-primary-bg); } .progressbar-success { @include progressbar-variant($progressbar-success-bg); } .progressbar-warning { @include progressbar-variant($progressbar-warning-bg); } .progressbar-danger { @include progressbar-variant($progressbar-danger-bg); } .progressbars { width: 100%; height: 1.5em; position: relative; .node { position: absolute; z-index: 3; top: .35em; width: .8em; height: .8em; &.dot { background-color: #FFF; -webkit-border-radius: .4em; border-radius: .4em; -webkit-box-sizing: border-box; box-sizing: border-box; border: .25em solid; &.active { // background-color: #6974A0; } &.current { } } &.circle { border-radius: .4em; } &.check-circle { border-radius: .4em; &::after { content: ''; width: .24em; height: .4em; border-bottom: 1px solid #FFF; border-right: 1px solid #FFF; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); position: absolute; left: .26em; top: .15em; } } } .line-bg { width: 100%; height: .5em; border-radius: .25em; position: absolute; z-index: 1; top: .5em; background-color: #DEE0E8; .line-progress { height: 100%; background-color: #6974A0; border-radius: .25em; } } .info { text-align: center; font-size: 1em; position: absolute; top: 1em; left: 0; transform: translateX(-50%); } &.progressbars-lg { font-size: $progressbars-font-size-lg; } &.progressbars-sm { font-size: $progressbars-font-size-sm; } &.progressbars-xsm { font-size: $progressbars-font-size-sm; .line-bg { height: .2em; border-radius: .1em; .line-progress { border-radius: .1em; height: 100%; } } .node { top: .15em; } } } ================================================ FILE: src/styles/modules/searchbar.scss ================================================ .searchbar { display: flex; align-items: center; &.active { .searchbar-input-field { width: auto; flex: 1; } .searchbar-input-placeholder { flex: initial; width: $searchbar-placeholder-width; } .searchbar-btn { width: auto; padding: $searchbar-btn-padding; } .searchbar-input-clear { width: auto; overflow: visible; padding: $searchbar-clear-padding; } } } .searchbar-input { flex: 1; display: flex; align-items: center; padding: $searchbar-padding; border: 1px solid $searchbar-border-color; border-radius: $searchbar-border-radius; } .searchbar-input-field { height: 100%; outline: none; border: 0; width: 0; overflow: hidden; white-space: nowrap; background-color: transparent; transition: $searchbar-transition; } .searchbar-input-placeholder { flex: 1; text-align: center; overflow: visible; white-space: nowrap; opacity: $searchbar-placeholder-opacity; transition: $searchbar-transition; i { vertical-align: middle; } } .searchbar-input-clear { width: 0; overflow: hidden; white-space: nowrap; opacity: $searchbar-clear-opacity; } .searchbar-btn { width: 0; overflow: hidden; white-space: nowrap; transition: $searchbar-transition; } ================================================ FILE: src/styles/modules/segmented-control.scss ================================================ .segmented-control { font-size: 0; display: inline-block; border: 1px solid $segmented-control-border-color; border-radius: $segmented-control-border-radius; background-color: $segmented-control-bg-color; } .segmented-control-item { display: inline-block; color: $segmented-control-color; font-size: $segmented-control-item-font-size; padding: $segmented-control-item-padding; transition: $segmented-control-transition; &.active { color: $segmented-control-color-active; background-color: $segmented-control-bg-color-active; } &.disabled { opacity: $segmented-control-opacity-disabled; } } ================================================ FILE: src/styles/modules/selector.scss ================================================ .selector { > .selector-option:last-child { background-size: 0; } } .selector-option { transition: $selector-color-transition; &.active { color: $selector-color-active; .selector-icon { transform: scale(1); } } } i.selector-icon { transform: scale(0); transform-origin: 50% 50%; color: $selector-icon-color; transition: $selector-color-transition; } ================================================ FILE: src/styles/modules/sidelip.scss ================================================ .sidelip { position: fixed; left: 0; top: 0; display: block; height: 100%; overflow-y: auto; -webkit-overflow-scrolling : touch; width: $sidelip-width; z-index: $z-index-sidelip; background-color: $sidelip-bg-color; } .slide-left-enter { transform: translate3d(-100%, 0, 0); } .slide-left-enter-active { animation: slideInLeft $sidelip-animation-enter-duration $sidelip-animation-enter-function; } .slide-left-leave-active { animation: slideOutLeft $sidelip-animation-leave-duration $sidelip-animation-leave-function; } ================================================ FILE: src/styles/modules/slideup.scss ================================================ .slideup { position: fixed; left: 0; bottom: 0; width: 100%; background-color: $slide-bg-color; z-index: $z-index-slide; } .slideup-header { padding: $slide-header-padding; @include border-bottom; } .slideup-body { overflow-y: auto; -webkit-overflow-scrolling : touch; padding: $slide-body-padding; min-height: $slide-min-height; max-height: $slide-max-height; } .slide-up-enter { transform: translate3d(0, 100%, 0); } .slide-up-enter-active { animation: slideInUp $slide-animation-enter-duration $slide-animation-enter-function; } .slide-up-leave-active { animation: slideOutDown $slide-animation-leave-duration $slide-animation-leave-function; } ================================================ FILE: src/styles/modules/stepbar.scss ================================================ .stepbar { display: flex; align-items: center; } .stepbar-item { flex: 1; display: flex; align-items: center; .fa { font-size: $stepbar-item-addon-icon-font-size; line-height: $stepbar-item-addon-size; } } .stepbar-line { flex: 1; height: $stepbar-line-height; border-top: $stepbar-line-height solid $stepbar-line-border-color; transition: $stepbar-line-transition; &:first-child { margin-right: $stepbar-gap; } &:last-child { margin-left: $stepbar-gap; } &.active { border-color: $stepbar-line-border-color-active; } } .stepbar-item-addon { text-align: center; color: $stepbar-item-addon-color; width: $stepbar-item-addon-size; height: $stepbar-item-addon-size; line-height: $stepbar-item-addon-line-height; border: $stepbar-item-addon-border-width solid $stepbar-item-addon-border-color; border-radius: 50%; transition: $stepbar-item-addon-transition; &.active { color: $stepbar-item-addon-color-active; background: $stepbar-item-addon-bg-active; border-color: $stepbar-item-addon-border-color-active; } &.finished { color: $stepbar-item-addon-color-finished; border-color: $stepbar-item-addon-border-color-finished; } } .stepbar-item-title { color: $stepbar-item-addon-title-color; margin: 0 $stepbar-gap; &.active { color: $stepbar-item-addon-title-color-active; font-weight: $stepbar-item-addon-title-font-weight-active; } &.finished { color: $stepbar-item-addon-title-color-active; } } ================================================ FILE: src/styles/modules/sticky.scss ================================================ .sticky-affix { position: fixed; z-index: 999; } .demo-sticky { display: inline-block; color: #fff; padding: 10px 30px; text-align: center; background: rgba(0,153,229,.9); } ================================================ FILE: src/styles/modules/swipe.scss ================================================ .swipe { overflow: hidden; position: relative; } .swipe-indicators { position: absolute; left: 50%; bottom: $swipe-indicators-bottom; transform: translateX(-50%); } .swipe-indicator { display: inline-block; border-radius: 50%; padding: $swipe-indicator-padding; border: 1px solid $swipe-indicator-border-color; margin: $swipe-indicator-margin; opacity: $swipe-indicator-opacity; transition: background-color $swipe-indicator-transition-duration $swipe-indicator-transition-function; &.active { background-color: $swipe-indicator-bg-color-active; } } .swipe-items { height: 100%; } .swipe-item { position: absolute; width: 100%; height: 100%; transform: translateX(-100%); } ================================================ FILE: src/styles/modules/tabbar.scss ================================================ .tabbar { position: relative; display: flex; height: $tabbar-height; margin-bottom: $tabbar-margin-bottom; background-color: $tabbar-bg-color; @include border-bottom(); } .tabbar-item { flex: 1; height: $tabbar-height; line-height: $tabbar-line-height; text-align: center; transition: $tabbar-transition; &.active { color: $tabbar-item-color-active; border-bottom-color: $tabbar-item-border-color-active; } &.disabled { opacity: $tabbar-opacity-disabled; } } .tabbar-indicator { display: block; position: absolute; left: 0; bottom: 0; background-color: $brand-primary; height: $tabbar-item-border-width; transition: $tabbar-transition; } ================================================ FILE: src/styles/modules/tag.scss ================================================ .tag { display: inline-block; padding: $tag-padding; color: $tag-color; text-align: center; white-space: nowrap; line-height: 1; border: 1px solid transparent; border-radius: $tag-border-radius; } .tag-sm { padding: $tag-padding-sm; transform-origin: 0 50%; transform: scale($tag-scale-sm); } .tag-primary { @include tag-variant($tag-primary-bg); } .tag-success { @include tag-variant($tag-success-bg); } .tag-warning { @include tag-variant($tag-warning-bg); } .tag-danger { @include tag-variant($tag-danger-bg); } .tag-default { @include tag-variant($tag-default-bg); } .tag-outline-primary { @include tag-outline-variant($tag-primary-bg); } .tag-outline-success { @include tag-outline-variant($tag-success-bg); } .tag-outline-warning { @include tag-outline-variant($tag-warning-bg); } .tag-outline-danger { @include tag-outline-variant($tag-danger-bg); } .tag-outline-default { @include tag-outline-variant($tag-default-bg, $tag-default-color); } ================================================ FILE: src/styles/modules/timeline.scss ================================================ .timeline { margin: 0; padding: 0; list-style: none; } .timeline-item { position: relative; padding-bottom: $timeline-item-padding-bottom; &:last-child { padding-bottom: 0; .timeline-item-line { display: none; } } &.active { .timeline-item-addon { top: 0; width: $timeline-item-addon-size-active; height: $timeline-item-addon-size-active; border-color: $timeline-item-addon-border-color; background: $timeline-item-addon-bg; &::after { width: $timeline-item-addon-dot-size-active; height: $timeline-item-addon-dot-size-active; background: $timeline-item-addon-dot-bg-active; } } } } .timeline-item-addon { position: absolute; top: ($timeline-item-addon-size-active - $timeline-item-addon-size) / 2; left: 0; z-index: 2; border: $timeline-item-addon-border-width solid transparent; border-radius: 50%; width: $timeline-item-addon-size-active; height: $timeline-item-addon-size; &::after { content: ' '; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; border-radius: 50%; width: $timeline-item-addon-dot-size; height: $timeline-item-addon-dot-size; background: $timeline-item-addon-dot-bg; } } .timeline-item-line { height: 100%; position: absolute; top: $timeline-item-addon-size; left: $timeline-item-addon-size-active / 2; border-left: $timeline-item-line-width solid $timeline-item-line-color; } .timeline-item-body { color: $timeline-item-body-color; display: inline-block; line-height: $timeline-item-body-line-height; padding-left: $timeline-item-body-padding-left; } ================================================ FILE: src/styles/modules/tip.scss ================================================ .tip { display: flex; align-items: center; padding: $tip-padding; .hr { flex: 1; } } .tip-label { color: $tip-label-color; padding: $tip-label-padding; } ================================================ FILE: src/styles/modules/toast.scss ================================================ .toast { position: fixed; text-align: center; color: $toast-color; z-index: $z-index-toast; max-width: $toast-max-width; background: $toast-bg; padding: $toast-padding; font-size: $toast-font-size; border-radius: $toast-border-radius; .loading { margin: $toast-loading-margin; } } .toast-top { left: 50%; top: $toast-position-gap; transform: translate(-50%, 0); } .toast-bottom { left: 50%; bottom: $toast-position-gap; transform: translate(-50%, 0); } .toast-center { left: 50%; top: 50%; transform: translate(-50%, -50%); } .toast-lg { padding: $toast-padding-lg; border-radius: $toast-border-radius-lg; } .toast-icon { font-size: $toast-icon-font-size; margin-bottom: $toast-icon-margin-bottom; } .toast-message { line-height: 1; } .toast-fade-enter { opacity: 0; } .toast-fade-enter-active { animation: fadeIn $toast-animation-enter-duration $toast-animation-enter-function; } .toast-fade-leave-active { animation: fadeOut $toast-animation-leave-duration $toast-animation-leave-function; } ================================================ FILE: src/styles/modules/toggle.scss ================================================ .toggle { display: inline-block; position: relative; } .toggle-input { display: none; &:checked + .toggle-addon { background-color: $toggle-addon-bg-color-checked; i { transform: translateX($toggle-width - $toggle-addon-size - $toggle-padding * 2); } } &:disabled + .toggle-addon { opacity: $toggle-addon-opacity-disabled; } } .toggle-addon { line-height: 0; width: $toggle-width; display: inline-block; padding: $toggle-padding; background-color: $toggle-bg-color; border-radius: $toggle-border-radius; transition: $toggle-transition; i { border-radius: 50%; display: inline-block; width: $toggle-addon-size; height: $toggle-addon-size; background: $toggle-addon-bg-color; transition: $toggle-transition; } } ================================================ FILE: src/styles/modules.scss ================================================ // css components @import 'modules/button'; @import 'modules/group'; @import 'modules/cell'; @import 'modules/tag'; @import 'modules/tip'; @import 'modules/hrule'; @import 'modules/badge'; @import 'modules/media'; @import 'modules/card'; @import 'modules/swipe'; @import 'modules/navbar'; @import 'modules/tabbar'; @import 'modules/navigation'; @import 'modules/drawer'; @import 'modules/slideup'; @import 'modules/segmented-control'; @import 'modules/sidelip'; @import 'modules/mask'; @import 'modules/searchbar'; @import 'modules/picker'; @import 'modules/loadmore'; @import 'modules/stepbar'; @import 'modules/timeline'; @import 'modules/sticky'; @import 'modules/toast'; @import 'modules/loading'; @import 'modules/alert'; @import 'modules/progressbar'; @import 'modules/back-to-top'; @import 'modules/checkbox'; @import 'modules/toggle'; @import 'modules/input-number'; @import 'modules/input-text'; @import 'modules/input-textarea'; @import 'modules/selector'; @import 'modules/inline-selector'; @import 'modules/date-picker'; ================================================ FILE: src/styles/utils/background.scss ================================================ // backgrounds .bg-inverse { color: $gray-lighter; background-color: $gray-dark; } .bg-faded { background-color: $gray-lightest; } .bg-default { background-color: $gray-lighter; } .bg-transparent { background-color: transparent !important; } .bg-pure { background-color: $brand-pure !important; } .bg-primary { color: $brand-pure; background-color: $brand-primary !important; } .bg-secondary { background-color: $brand-secondary !important; } .bg-danger { background-color: $brand-danger !important; } .bg-warning { background-color: $brand-warning !important; } .bg-success { background-color: $brand-success !important; } ================================================ FILE: src/styles/utils/border.scss ================================================ // shape .border-circle { border-radius: $border-radius-circle !important; } .border-pill { border-radius: $border-radius-circle !important; } // style .border-dashed { border-style: dashed; } .border-dotted { border-style: dotted; } // Theme .border-primary { border-color: $brand-primary !important; } .border-secondary { border-color: $brand-secondary !important; } .border-danger { border-color: $brand-danger !important; } .border-success { border-color: $brand-success !important; } .border-warning { border-color: $brand-warning !important; } ================================================ FILE: src/styles/utils/clearfix.scss ================================================ .clearfix { &::after { content: ''; display: table; clear: both; } } ================================================ FILE: src/styles/utils/display.scss ================================================ .invisible { visibility: hidden !important; } .hidden { display: none !important; } .block { display: block !important; } ================================================ FILE: src/styles/utils/flex.scss ================================================ .flex { overflow: hidden; display: flex; } .flex-vertical { height: 100%; flex-direction: column; } .flex-item { flex: 1; overflow-y: auto; -webkit-overflow-scrolling : touch; } .flex-align-top { align-items: flex-start; } .flex-align-middle { align-items: center; } .flex-align-bottom { align-items: flex-end; } .flex-justify-start { justify-content: flex-start; } .flex-justify-end { justify-content: flex-end; } .flex-justify-center { justify-content: center; } .flex-justify-between { justify-content: space-between; } .flex-justify-around { justify-content: space-around; } ================================================ FILE: src/styles/utils/img.scss ================================================ .img-circle { border-radius: 50%; } .img-fluid { display: block; max-width: 100%; height: auto; } ================================================ FILE: src/styles/utils/reboot.scss ================================================ // scss-lint:disable ImportantRule, QualifyingElement, DuplicateProperty // Reboot // // Global resets to common HTML elements and more for easier usage by Bootstrap. // Adds additional rules on top of Normalize.css, including several overrides. // Reset the box-sizing // // Change from `box-sizing: content-box` to `border-box` so that when you add // `padding` or `border`s to an element, the overall declared `width` does not // change. For example, `width: 100px;` will always be `100px` despite the // `border: 10px solid red;` and `padding: 20px;`. // // Heads up! This reset may cause conflicts with some third-party widgets. For // recommendations on resolving such conflicts, see // http://getbootstrap.com/getting-started/#third-box-sizing. // // Credit: https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ html { height: 100%; box-sizing: border-box; font-size: $font-size-root; -ms-overflow-style: scrollbar; -webkit-tap-highlight-color:rgba(255, 255, 255, 0); @include respond-to(md) { font-size: $font-size-root-md; } @include respond-to(lg) { font-size: $font-size-root-lg; } } // iphone 4/5 // @media only screen // and (min-device-width: 320px) // and (min-resolution: 2dppx) { // html { // font-size: $font-size-root; // } // } // // iphone 6/7 // @media only screen // and (min-device-width: 360px) // and (min-resolution: 2dppx) { // html { // font-size: $font-size-root-md; // } // } // // iphone 6/7 plus // @media only screen // and (min-device-width: 414px) // and (min-resolution: 3dppx) { // html { // font-size: $font-size-root-lg; // } // } *, *::before, *::after { box-sizing: inherit; } // Make viewport responsive // // @viewport is needed because IE 10+ doesn't honor in // some cases. See http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/. // Eventually @viewport will replace . // // However, `device-width` is broken on IE 10 on Windows (Phone) 8, // (see http://timkadlec.com/2013/01/windows-phone-8-and-device-width/ and https://github.com/twbs/bootstrap/issues/10497) // and the fix for that involves a snippet of JavaScript to sniff the user agent // and apply some conditional CSS. // // See http://getbootstrap.com/getting-started/#support-ie10-width for the relevant hack. // // Wrap `@viewport` with `@at-root` for when folks do a nested import (e.g., // `.class-name { @import "bootstrap"; }`). @at-root { @-ms-viewport { width: device-width; } } body { height: 100%; font-family: $font-family-base; font-size: $font-size-base; line-height: $line-height-base; color: $body-color; background-color: $body-bg; padding: 0; margin: 0; } // Suppress the focus outline on elements that cannot be accessed via keyboard. // This prevents an unwanted focus outline from appearing around elements that // might still respond to pointer events. // // Credit: https://github.com/suitcss/base [tabindex="-1"]:focus { outline: none !important; } // // Typography // // Remove top margins from headings // // By default, `

`-`

` all receive top and bottom margins. We nuke the top // margin for easier control within type scales as it avoids margin collapsing. h1, h2, h3, h4, h5, h6 { margin-top: 0; margin-bottom: .5rem; } // Reset margins on paragraphs // // Similarly, the top margin on `

`s get reset. However, we also reset the // bottom margin to use `rem` units instead of `em`. p { margin-top: 0; margin-bottom: .5rem; } address { margin-bottom: .5rem; font-style: normal; line-height: inherit; } ol, ul, dl { margin-top: 0; margin-bottom: 1rem; } ol ol, ul ul, ol ul, ul ol { margin-bottom: 0; } dt { font-weight: bold; } dd { margin-bottom: .5rem; margin-left: 0; // Undo browser default } blockquote { margin: 0 0 1rem; } // // Links // a { cursor: none; color: $link-color; text-decoration: $link-decoration; &:active, &:focus { color: $link-color; text-decoration: none; } &:active { color: $link-active-color; } } // And undo these styles for placeholder links/named anchors (without href). // It would be more straightforward to just use a[href] in previous block, but that // causes specificity issues in many other styles that are too complex to fix. // See https://github.com/twbs/bootstrap/issues/19402 a:not([href]) { color: inherit; text-decoration: none; &:hover, &:focus { color: inherit; text-decoration: none; } &:focus { outline: none; } } // // Code // pre { margin-top: 0; margin-bottom: 1rem; } // // Figures // figure { margin: 0 0 1rem; } // // Images // img { vertical-align: middle; } // iOS "clickable elements" fix for role="button" // // Fixes "clickability" issue (and more generally, the firing of events such as focus as well) // for traditionally non-focusable elements with role="button" // see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile [role="button"] { cursor: pointer; } // Avoid 300ms click delay on touch devices that support the `touch-action` CSS property. // // In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11 // DON'T remove the click delay when `` is present. // However, they DO support removing the click delay via `touch-action: manipulation`. // See: // * http://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch // * http://caniuse.com/#feat=css-touch-action // * http://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay a, area, button, [role="button"], input, label, select, summary, textarea { touch-action: manipulation; } // // Tables // table { background-color: $table-bg; } caption { padding-top: $table-cell-padding; padding-bottom: $table-cell-padding; color: $text-muted; text-align: left; caption-side: bottom; } th { text-align: left; } // // Forms // label { display: inline-block; } // Work around a Firefox/IE bug where the transparent `button` background // results in a loss of the default `button` focus styles. // // Credit: https://github.com/suitcss/base/ button:focus { outline: 1px dotted; outline: 5px auto -webkit-focus-ring-color; } input, button, select, textarea { margin: 0; line-height: inherit; border-radius: 0; } textarea { font-size: $font-size-base; resize: none; } fieldset { min-width: 0; padding: 0; margin: 0; border: 0; } legend { display: block; width: 100%; padding: 0; margin-bottom: .5rem; font-size: 1.5rem; line-height: inherit; } input[type="search"] { -webkit-appearance: none; } // todo: needed? output { display: inline-block; } // Always hide an element with the `hidden` HTML attribute (from PureCSS). [hidden] { display: none !important; } ================================================ FILE: src/styles/utils/spacing.scss ================================================ .no-margin { margin: 0 !important; } .no-padding { padding: 0 !important; } .gap-left { margin-right: $spacer-gap; } .gap-right { margin-left: $spacer-gap; } ================================================ FILE: src/styles/utils/text.scss ================================================ // Contextual colors @include text-emphasis-variant('.text-muted', $text-muted); @include text-emphasis-variant('.text-primary', $brand-primary); @include text-emphasis-variant('.text-success', $brand-success); @include text-emphasis-variant('.text-info', $brand-info); @include text-emphasis-variant('.text-warning', $brand-warning); @include text-emphasis-variant('.text-danger', $brand-danger); @include text-emphasis-variant('.text-secondary', $brand-secondary); @include text-emphasis-variant('.text-pure', $brand-pure); //== Text align .text-center { text-align: center; } .text-left { text-align: left; } .text-right { text-align: right; } ================================================ FILE: src/styles/utils.scss ================================================ @import 'utils/reboot'; @import 'utils/flex'; @import 'utils/spacing'; @import 'utils/background'; @import 'utils/text'; @import 'utils/display'; @import 'utils/img'; @import 'utils/border'; @import 'utils/clearfix'; ================================================ FILE: src/styles/variables.scss ================================================ // Colors $brand-primary: #1C89EA !default; $brand-secondary: #FF7043 !default; $brand-success: #30BE71 !default; $brand-info: #2b71b5 !default; $brand-warning: #fab83a !default; $brand-danger: #EA413A !default; $brand-pure: #fff !default; $gray-dark: #373a3c !default; $gray: #55595c !default; $gray-light: #999 !default; $gray-lighter: #eceeef !default; $gray-lightest: #f4f4f4 !default; // Border radius $border-radius: 2px !default; $border-radius-lg: 4px !default; $border-radius-sm: 1px !default; $border-radius-circle: 10rem !default; // Cursor $cursor-pointer: pointer !default; // Opacity $opacity-disabled: .65 !default; // z-index $z-index-top: 1000 !default; $z-index-mask: 1010 !default; $z-index-slide: 1020 !default; $z-index-sidelip: 1020 !default; $z-index-toast: 1030 !default; $z-index-alert: 1030 !default; // Base $font-family-base: -apple-system, BlinkMacSystemFont, "Microsoft YaHei", "WenQuanYi Micro Hei", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif !default; $line-height-base: 1.43 !default; $body-color: #333 !default; $body-bg: #f0eff5 !default; $text-muted: $gray-light !default; $font-size-root: 12px !default; $font-size-root-md: 14px !default; $font-size-root-lg: 16px !default; $font-size-base: 1rem !default; $font-size-lg: 1.4rem !default; $font-size-sm: .875rem !default; // media query $all-media-query-device: ( 'sm': '(min-width: 320px) and (min-resolution: 2dppx)', 'md': '(min-width: 360px) and (min-resolution: 2dppx)', 'lg': '(min-width: 414px) and (min-resolution: 3dppx)', ) !default; $spacer: 1rem !default; $spacer-x: $spacer !default; $spacer-y: $spacer !default; $spacer-gap: $spacer / 2 !default; // Border $border-color: #e0e0e0 !default; $border-image-top: linear-gradient(to bottom, $border-color, $border-color 50%, transparent 0) !default; $border-image-bottom: linear-gradient(to top, $border-color, $border-color 50%, transparent 0) !default; $border-image-left: linear-gradient(to right, $border-color, $border-color 50%, transparent 0) !default; // Hr $hr-color: $border-color !default; $hr-margin: 1rem 0 !default; // Links $link-color: $brand-primary !default; $link-decoration: none !default; $link-active-color: darken($link-color, 15%) !default; // Tables $table-bg: $brand-pure !default; $table-cell-padding: .75rem !default; $table-sm-cell-padding: .3rem !default; // Buttons $btn-opacity-disabled: $opacity-disabled !default; $btn-loading-opacity-disabled: .9 !default; $btn-font-size: $font-size-base !default; $btn-padding-x: 1.6rem !default; $btn-padding-y: .7rem !default; $btn-border-radius: $border-radius !default; $btn-font-size-sm: $font-size-sm !default; $btn-padding-x-sm: .6rem !default; $btn-padding-y-sm: .2rem !default; $btn-border-radius-sm: $border-radius-sm !default; $btn-font-size-lg: $font-size-lg !default; $btn-padding-x-lg: 2rem !default; $btn-padding-y-lg: 1rem !default; $btn-border-radius-lg: $border-radius-lg !default; $btn-primary-color: $brand-pure; $btn-primary-bg: $brand-primary !default; $btn-primary-border: $brand-primary !default; $btn-secondary-color: $brand-pure; $btn-secondary-bg: $brand-secondary !default; $btn-secondary-border: $brand-secondary !default; $btn-default-color: $gray; $btn-default-bg: #fff !default; $btn-default-border: $border-color !default; $btn-loading-gap: .25rem !default; // Group/Cell $group-bg-color: $brand-pure !default; $group-margin: 1rem 0 0 0 !default; $group-title-padding: .5rem 1rem !default; $cell-color: $body-color !default; $cell-bg-color: $brand-pure !default; $cell-padding: 1.2rem 1rem !default; $cell-gap-left: 1rem !default; $cell-children-gap: 1rem !default; $cell-bg-color-active: $gray-lightest !default; $cell-bg-color-disabled: $border-color !default; $cell-arrow-color: #818a91 !default; $cell-arrow-margin: 0 0 0 $spacer-gap !default; // Navbar $navbar-height: 3.67rem !default; $navbar-line-height: $navbar-height !default; $navbar-padding: 0 !default; $navbar-header-flex: .5 !default; $navbar-header-padding: 0 1rem !default; $navbar-body-flex: 1 !default; $navbar-body-padding: 0 1rem !default; $navbar-footer-flex: .5 !default; $navbar-footer-padding: 0 1rem !default; $navbar-primary-color: $brand-pure !default; $navbar-primary-bg-color: $brand-primary !default; $navbar-default-color: #666 !default; $navbar-default-bg-color: $brand-pure !default; // Tabbar $tabbar-bg-color: $brand-pure !default; $tabbar-margin-bottom: 1rem !default; $tabbar-height: $navbar-height !default; $tabbar-line-height: $tabbar-height !default; $tabbar-transition: all .3s cubic-bezier(.86, 0, .07, 1) !default; $tabbar-opacity-disabled: $opacity-disabled !default; $tabbar-item-border-width: .167rem !default; $tabbar-item-color-active: $brand-primary !default; $tabbar-item-border-color-active: $brand-primary !default; // Toast $toast-bg: rgba(0, 0, 0, .6) !default; $toast-color: $brand-pure !default; $toast-font-size: 1.1rem !default; $toast-border-radius: .333rem !default; $toast-border-radius-lg: .5rem !default; $toast-padding: 1rem 1.2rem !default; $toast-padding-lg: 1rem 3.5rem 1.5rem !default; $toast-position-gap: 4rem !default; $toast-max-width: 80% !default; $toast-animation-enter-duration: .6s !default; $toast-animation-enter-function: ease-in !default; $toast-animation-leave-duration: .3s !default; $toast-animation-leave-function: cubic-bezier(.6, .04, .98, .34) !default; $toast-icon-font-size: 4rem !default; $toast-icon-margin-bottom: .5rem !default; $toast-loading-margin: 1rem 0 !default; // Alert $alert-width: 22.5rem !default; $alert-max-width: 22.5rem !default; $alert-padding: 2.145rem 0 0 0 !default; $alert-bg-color: $brand-pure !default; $alert-border-radius: $border-radius-lg !default; $alert-animation-duration: .2s !default; $alert-animation-enter-function: cubic-bezier(.08, .82, .167, 1) !default; $alert-animation-leave-function: cubic-bezier(.6, .04, .98, .34) !default; $alert-title-font-size: 1.43rem !default; $alert-title-font-weight: bold !default; $alert-title-color: #333333 !default; $alert-message-color: #666666 !default; $alert-message-font-size: 1.07rem !default; $alert-message-padding: 1.785rem 1.43rem !default; $alert-message-line-height: 1.43 !default; $alert-message-text-align: center !default; $alert-btn-color: $brand-primary !default; $alert-btn-font-size: 1.215rem !default; $alert-btn-padding: 1rem 0 !default; $alert-box-h-shadow: 0 0 0.85rem 0 rgba(0, 0, 0, 0.22) !default; $alert-box-v-shadow: 0 0.85rem 0.85rem 0 rgba(0, 0, 0, 0.30) !default; // Checkbox $checkbox-padding: 3px !default; $checkbox-color: $brand-pure !default; $checkbox-bg-color: $brand-pure !default; $checkbox-border-color: #ddd !default; $checkbox-transition: all .2s ease-in !default; $checkbox-bg-color-checked: $brand-primary !default; $checkbox-border-color-checked: $brand-primary !default; $checkbox-bg-color-disabled: #dfdfdf !default; $checkbox-border-color-disabled: $checkbox-border-color !default; $checkbox-addon-font-size: 1.5rem !default; $checkbox-addon-padding-top: 0 !default; $radio-addon-width: 1.0rem !default; $radio-addon-height: $radio-addon-width !default; $radio-addon-padding: .5rem !default; $checkbox-label-gap: .167rem !default; $checkbox-square-border-radius: $border-radius !default; $checkbox-gap: 1rem !default; // Toggle $toggle-addon-size: 1.34rem !default; $toggle-addon-bg-color: $brand-pure !default; $toggle-addon-bg-color-checked: $brand-primary !default; $toggle-addon-opacity-disabled: $opacity-disabled !default; $toggle-bg-color: #e7eaec !default; $toggle-width: 3.84rem !default; $toggle-padding: 0.25rem !default; $toggle-border-radius: $toggle-addon-size !default; $toggle-transition: all .2s ease !default; // Number $number-border-color: $brand-primary !default; $number-btn-size: 2.0rem !default; $number-btn-line-height: $number-btn-size - 0.167 !default; $number-plus-color: $brand-pure !default; $number-plus-bg-color: $brand-primary !default; $number-plus-bg-color-active: darken($number-plus-bg-color, 6%) !default; $number-minus-color: $brand-primary !default; $number-minus-bg-color: $brand-pure !default; $number-minus-color-active: $brand-pure !default; $number-minus-bg-color-active: $brand-primary !default; $number-input-width: 3rem !default; $number-input-bg-color: $brand-pure !default; $number-input-border-color: #d9d9d9 !default; $number-input-padding: .6rem .3rem !default; $number-input-margin: 0 .167rem !default; $number-input-bg-color-disabled: #eee !default; // InputText $input-font-size: 1rem !default; $input-text-icon-gap: 1rem !default; // InputTeaxtarea $textarea-padding: .6rem !default; $textarea-counter-scale: .8 !default; $textarea-counter-color: $text-muted !default; $textarea-counter-padding: 0 $textarea-padding / $textarea-counter-scale .2rem 0 !default; // Selector $selector-color-active: $brand-primary !default; $selector-icon-color: $brand-primary !default; $selector-color-transition: all .2s ease-in-out !default; // InlineSelector $inline-selector-transition: all .2s ease-in !default; $inline-selector-option-min-width: 4.583rem !default; $inline-selector-option-padding: .6rem .2rem !default; // Tag $tag-padding: .4em .6em !default; $tag-color: $brand-pure !default; $tag-border-radius: $border-radius !default; $tag-padding-sm: .2em .4em !default; $tag-scale-sm: .85 !default; $tag-primary-bg: $brand-primary !default; $tag-success-bg: $brand-success !default; $tag-warning-bg: $brand-warning !default; $tag-danger-bg: $brand-danger !default; $tag-default-bg: #ccc !default; $tag-default-color: #666 !default; // Navigation $navigation-height: 4.0833rem !default; $navigation-color: #888 !default; $navigation-color-active: $brand-primary !default; $navigation-bg-color: $tabbar-bg-color !default; $navigation-label-scale: .8 !default; $navigation-margin: .167rem 0 -.8rem 0 !default; // Tip $tip-padding: 1rem 4rem !default; $tip-line-height: 1px !default; $tip-label-padding: 0 1rem !default; $tip-label-color: #888 !default; // BackToTop $top-right: 2.5rem !default; $top-bottom: 2.5rem !default; $top-color: $brand-pure !default; $top-width: 3.5rem !default; $top-height: 3.5rem !default; $top-line-height: 3.5rem !default; $top-font-size: 1.667rem !default; $top-bg-color: rgba(0, 0, 0, .3) !default; $top-transition: all .6s ease-in-out !default; // Badge $badge-color: $brand-pure !default; $badge-padding: 0.25rem !default; $badge-min-width: 0.5rem !default; $badge-min-width-not-empty: 1rem + $badge-padding * 2 !default; $badge-min-height: 0.5rem !default; $badge-margin-right: $badge-min-width-not-empty / 2 !default; $badge-scale: .8 !default; $badge-box-shadow: 0 0 0 1px $brand-pure !default; // Drawer $drawer-color: #666 !default; $drawer-bg-color: $tabbar-bg-color !default; $drawer-padding: ($navbar-height - $line-height-base * 1) / 2 0 !default; $drawer-transition: all .2s ease-in-out !default; $drawer-color-active: $brand-primary !default; $drawer-opacity-disabled: $opacity-disabled !default; $drawer-icon-color: #999 !default; $drawer-icon-margin-right: .167rem !default; // mask $mask-bg-color: rgba(0, 0, 0, .3) !default; $mask-animation-enter-duration: .3s !default; $mask-animation-enter-function: ease !default; $mask-animation-leave-duration: .2s !default; $mask-animation-leave-function: ease !default; // Slide $slide-bg-color: $brand-pure !default; $slide-min-height: 5rem !default; $slide-max-height: 25rem !default; $slide-animation-enter-duration: .3s !default; $slide-animation-enter-function: ease-in-out !default; $slide-animation-leave-duration: .2s !default; $slide-animation-leave-function: ease-in-out !default; $slide-header-padding: 1rem !default; $slide-body-padding: 1rem !default; // Sidelip $sidelip-width: 65% !default; $sidelip-bg-color: $brand-pure !default; $sidelip-animation-enter-duration: .3s !default; $sidelip-animation-enter-function: ease !default; $sidelip-animation-leave-duration: .2s !default; $sidelip-animation-leave-function: ease-in-out !default; // SegmentedControl $segmented-control-color: $brand-primary !default; $segmented-control-bg-color: $brand-pure !default; $segmented-control-border-color: $brand-primary !default; $segmented-control-border-radius: $border-radius-lg !default; $segmented-control-transition: all .3s ease-in-out !default; $segmented-control-opacity-disabled: $opacity-disabled !default; $segmented-control-color-active: $brand-pure !default; $segmented-control-bg-color-active: $brand-primary !default; $segmented-control-item-padding: .4rem .6rem !default; $segmented-control-item-font-size: $font-size-base !default; // Meida $media-bg-color: $brand-pure !default; $media-object-gap: 1rem !default; // Card $card-bg-color: $brand-pure !default; $card-body-padding: .6rem 1rem !default; // Searchbar $searchbar-padding: .5rem !default; $searchbar-border-color: $border-color !default; $searchbar-border-radius: $border-radius !default; $searchbar-transition: all .3s ease !default; $searchbar-placeholder-opacity: .2 !default; $searchbar-placeholder-width: 1rem + 0.5rem !default; $searchbar-clear-padding: 0 0 0 .5rem !default; $searchbar-clear-opacity: .2 !default; $searchbar-btn-padding: 0 .5rem !default; // Loadmore $loadmore-dropped-transition: .2s !default; $loadmore-hint-height: 4.167rem !default; $loadmore-hint-margin: -4.167rem !default; // Loading $loading-width: 4rem !default; $loading-animation-duration: 2s !default; $loading-path-stroke: $border-color !default; $loading-path-stroke-width: 3 !default; $loading-path-animation-duration: 1.5s !default; $loading-path-stroke-primary: $brand-primary !default; $loading-path-stroke-secondary: $brand-secondary !default; $loading-width-sm: 1rem !default; // Picker $picker-bg-color: $brand-pure !default; $picker-items-count: 5 !default; $picker-items-count-sm: 3 !default; $picker-items-count-lg: 7 !default; $picker-item-font-size: 1.2rem !default; $picker-item-height: 3rem !default; $picker-item-line-height: $picker-item-height !default; $picker-item-padding: 0 1rem !default; $picker-item-transition: all .2s ease !default; $picker-item-font-size-active: 1.3rem !default; $picker-item-font-weight-active: bold !default; $picker-mask-bg-size: 100% $picker-item-height * 2 !default; $picker-mask-leve-1: hsla(0, 0%, 100%, .95) !default; $picker-mask-leve-2: hsla(0, 0%, 100%, .6) !default; $picker-mask-leve-3: hsla(0, 0%, 100%, .3) !default; $picker-mask-bg-image: linear-gradient(180deg, $picker-mask-leve-1, $picker-mask-leve-2), linear-gradient(0deg, $picker-mask-leve-1, $picker-mask-leve-2) !default; $picker-mask-bg-image-sm: linear-gradient(180deg, $picker-mask-leve-3), linear-gradient(0deg, $picker-mask-leve-3) !default; $picker-mask-bg-image-lg: linear-gradient(180deg, $picker-mask-leve-1, $picker-mask-leve-2, $picker-mask-leve-3), linear-gradient(0deg, $picker-mask-leve-1, $picker-mask-leve-2, $picker-mask-leve-3) !default; $picker-tap-height: $picker-item-height !default; $picker-list-transition: all .3s ease-out !default; // Swipe $swipe-indicators-bottom: .5rem !default; $swipe-indicator-padding: 0.25rem !default; $swipe-indicator-margin: 0 1px !default; $swipe-indicator-opacity: 1 !default; $swipe-indicator-border-color: $brand-pure !default; $swipe-indicator-bg-color-active: $brand-pure !default; $swipe-indicator-transition-duration: .3s !default; $swipe-indicator-transition-function: ease-in-out !default; // Progressbar $progressbar-height: 1.667rem !default; $progressbar-border-radius: $border-radius-lg !default; $progressbar-bg-color: $gray-lightest !default; $progressbar-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1) !default; $progressbar-primary-bg: $brand-primary !default; $progressbar-success-bg: $brand-success !default; $progressbar-warning-bg: $brand-warning !default; $progressbar-danger-bg: $brand-danger !default; $progressbar-indicator-color: $brand-pure !default; $progressbar-indicator-font-size: $font-size-sm !default; $progressbar-indicator-transition: width .6s ease !default; $progressbar-indicator-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15) !default; $progressbar-height-sm: .667rem !default; $progressbar-border-radius-sm: $progressbar-height-sm !default; // Stepbar $stepbar-gap: .167rem !default; $stepbar-item-addon-size: 1.5rem !default; $stepbar-item-addon-line-height: 1.357rem !default; $stepbar-item-addon-color: $text-muted !default; $stepbar-item-addon-color-active: $brand-pure !default; $stepbar-item-addon-bg-active: $brand-primary !default; $stepbar-item-addon-border-color-active: $brand-primary !default; $stepbar-item-addon-border-width: 1px !default; $stepbar-item-addon-border-color: $border-color !default; $stepbar-item-addon-icon-font-size: 1rem !default; $stepbar-item-addon-transition: all .2s ease-in !default; $stepbar-item-addon-color-finished: $brand-primary !default; $stepbar-item-addon-border-color-finished: $brand-primary !default; $stepbar-item-addon-title-color: $text-muted !default; $stepbar-item-addon-title-color-active: $body-color !default; $stepbar-item-addon-title-font-weight-active: bold !default; $stepbar-line-height: 1px !default; $stepbar-line-color: $border-color !default; $stepbar-line-border-color: $stepbar-line-color !default; $stepbar-line-border-color-active: $brand-primary !default; $stepbar-line-transition: all .2s ease-in !default; // Timeline $timeline-item-padding-bottom: 2rem !default; $timeline-item-addon-bg: $brand-pure !default; $timeline-item-addon-size: 1rem !default; $timeline-item-addon-border-width: 2px !default; $timeline-item-addon-size-active: 2.0rem !default; $timeline-item-addon-border-color: $brand-primary !default; $timeline-item-addon-dot-size: 1rem !default; $timeline-item-addon-dot-size-active: 1rem !default; $timeline-item-addon-dot-bg: #cbcccd !default; $timeline-item-addon-dot-bg-active: $brand-primary !default; $timeline-item-line-width: 1px !default; $timeline-item-line-color: $timeline-item-addon-dot-bg !default; $timeline-item-body-color: $text-muted !default; $timeline-item-body-padding-left: ($timeline-item-addon-size-active + .7 * 1) !default; $timeline-item-body-line-height: $timeline-item-addon-size-active !default; // date-picker $datepicker-font-size-base: 20px !default; // progressbars $progressbars-font-size-lg: 20px !default; $progressbars-font-size-sm: 15px !default; ================================================ FILE: webpack.dev.config.js ================================================ const path = require('path'), webpack = require('webpack'), DashboardPlugin = require('webpack-dashboard/plugin'); module.exports = { devtool: 'eval-source-map', entry: { app: [ `webpack-dev-server/client?http://localhost:9008`, 'webpack/hot/dev-server', './src/scripts/index.js'], }, output: { path: path.join(__dirname, 'dist'), filename: 'app.js', publicPath: '/scripts', }, resolve: { extensions: ['.js', '.vue'], modules: [path.join(__dirname, 'node_modules')], alias: { vue$: 'vue/dist/vue', }, }, module: { rules: [ { test: /\.js$/, enforce: 'pre', loader: 'eslint-loader', include: path.join(__dirname, 'src'), exclude: /node_modules/, },{ test: /\.vue$/, loader: 'vue-loader', }, { test: /\.js$/, loader: 'babel-loader', include: path.join(__dirname, 'src'), exclude: /node_modules/, }, { test: /\.scss$/, use: ['style-loader', 'css-loader', 'scss-loader'], }, { test: /\.(jpe?g|png|gif|svg)$/i, loader: 'url-loader', }, { test: /\.json$/, loader: 'json-loader', }], }, plugins: [ new webpack.HotModuleReplacementPlugin(), new DashboardPlugin(), ], devServer: { host: '0.0.0.0', disableHostCheck: true, contentBase: './build', publicPath: '/scripts', hot: true, historyApiFallback: true, stats: { colors: true, chunks: false, children: false, }, headers: { 'Access-Control-Allow-Origin': '*', }, }, }; ================================================ FILE: webpack.prebuilt.config.js ================================================ const path = require('path') const webpack = require('webpack') module.exports = { entry: './src/scripts/components/index', output: { path: path.join(__dirname, 'build', 'scripts'), filename: 'vue-impression.js', publicPath: '/', }, plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"', }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, }, comments: false, mangle: { except: ['$super', '$', 'exports', 'require', 'module'], }, }), new webpack.optimize.MinChunkSizePlugin({minChunkSize: 51200}), new webpack.optimize.OccurrenceOrderPlugin(), ], resolve: { extensions: ['.js', '.vue'], }, module: { loaders: [{ test: /\.vue$/, loader: 'vue-loader', }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/, }, { test: /\.(jpe?g|png|gif|svg)$/i, loader: 'url-loader', }, { test: /\.json$/, loader: 'json-loader', }], }, }; ================================================ FILE: webpack.prod.config.js ================================================ var path = require('path'), webpack = require('webpack'); module.exports = { entry: './src/scripts/index', output: { path: path.join(__dirname, 'build', 'scripts'), filename: 'app.js', publicPath: '/', }, plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"', }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, }, comments: false, mangle: { except: ['$super', '$', 'exports', 'require', 'module'], }, }), new webpack.optimize.MinChunkSizePlugin({ minChunkSize: 51200 }), new webpack.optimize.OccurrenceOrderPlugin(), ], resolve: { extensions: ['.js', '.vue'], modules: [path.join(__dirname, 'node_modules')], alias: { vue$: 'vue/dist/vue', }, }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader', }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/, }, { test: /\.(jpe?g|png|gif|svg)$/i, loader: 'url-loader', }, { test: /\.json$/, loader: 'json-loader', }], }, };