├── .babelrc ├── .eslintignore ├── .eslintrc.js ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── build ├── build.js ├── build_publish.js ├── check-versions.js ├── dev-client.js ├── dev-server.js ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js ├── webpack.prod.conf.js └── webpack.publish.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── docs ├── Datepicker.png ├── app.css ├── app.css.map ├── app.js ├── app.js.map ├── button.png ├── card.png ├── form.png ├── index.html ├── logo.png ├── manifest.js ├── manifest.js.map ├── menu.png ├── select.png ├── table.png ├── treeselect.png ├── vendor.js └── vendor.js.map ├── examples ├── components │ ├── CodeCard.vue │ ├── DemoBackTop.vue │ ├── DemoButton.vue │ ├── DemoCalendar.vue │ ├── DemoCard.vue │ ├── DemoCarousel.vue │ ├── DemoCascader.vue │ ├── DemoChart.vue │ ├── DemoChartLine.vue │ ├── DemoCheckbox.vue │ ├── DemoCollapse.vue │ ├── DemoDatePicker.vue │ ├── DemoDivider.vue │ ├── DemoDropdown.vue │ ├── DemoForm.vue │ ├── DemoFormValidate.vue │ ├── DemoGrid.vue │ ├── DemoGridBase.vue │ ├── DemoGridFixed.vue │ ├── DemoGridGutterOffset.vue │ ├── DemoImage.vue │ ├── DemoIndex.vue │ ├── DemoInput.vue │ ├── DemoInputNumber.vue │ ├── DemoLayouUpMiddleDown.vue │ ├── DemoLayout.vue │ ├── DemoLayoutBase.vue │ ├── DemoLayoutSider.vue │ ├── DemoLayoutTopSiderHeader.vue │ ├── DemoLoader.vue │ ├── DemoMenu.vue │ ├── DemoMessage.vue │ ├── DemoModal.vue │ ├── DemoNotification.vue │ ├── DemoPagination.vue │ ├── DemoPopup.vue │ ├── DemoRadio.vue │ ├── DemoSegment.vue │ ├── DemoSelect.vue │ ├── DemoSteps.vue │ ├── DemoSwitch.vue │ ├── DemoTable.vue │ ├── DemoTableBase.vue │ ├── DemoTableBorder.vue │ ├── DemoTableColumnFilters.vue │ ├── DemoTableColumnFixed.vue │ ├── DemoTableColumnFixedScrollX.vue │ ├── DemoTableColumnOrder.vue │ ├── DemoTableColumnType.vue │ ├── DemoTableExpand.vue │ ├── DemoTableFixedHeader.vue │ ├── DemoTableNoMore.vue │ ├── DemoTablePagination.vue │ ├── DemoTableScrollXY.vue │ ├── DemoTableScrollY.vue │ ├── DemoTabs.vue │ ├── DemoTag.vue │ ├── DemoTimePicker.vue │ ├── DemoTimeline.vue │ ├── DemoTransfer.vue │ ├── DemoTransferBase.vue │ ├── DemoTree.vue │ ├── DemoTreeCheckbox.vue │ ├── DemoTreeEdit.vue │ ├── DemoTreeSelect.vue │ ├── DemoTreeSelectMultiple.vue │ ├── DemoTreeSelectSingle.vue │ ├── DemoUpload.vue │ └── MainLayout.vue ├── main.js └── static │ ├── image.png │ ├── paragraph.png │ ├── square-image.png │ └── white-image.png ├── index.html ├── package-lock.json ├── package.json ├── src ├── assets │ └── logo.png ├── components │ ├── BackTop.vue │ ├── Button.vue │ ├── Buttons.vue │ ├── Calendar.vue │ ├── Card.vue │ ├── Cards.vue │ ├── Carousel.vue │ ├── CarouselItem.vue │ ├── Cascader.vue │ ├── ChartLine.vue │ ├── Checkbox.vue │ ├── Checkboxes.vue │ ├── Col.vue │ ├── Collapse.vue │ ├── CollapseItem.vue │ ├── ContentRender.vue │ ├── DatePicker.vue │ ├── Divider.vue │ ├── Dropdown.vue │ ├── ElementToBody.vue │ ├── Field.vue │ ├── Fields.vue │ ├── Form.vue │ ├── Image.vue │ ├── Input.vue │ ├── InputNumber.vue │ ├── Layout.vue │ ├── List.vue │ ├── ListItem.vue │ ├── Loader.vue │ ├── Menu.vue │ ├── Message.vue │ ├── Modal.vue │ ├── OptGroup.vue │ ├── Option.vue │ ├── Pagination.vue │ ├── Popover.vue │ ├── Pull.vue │ ├── Radio.vue │ ├── Radios.vue │ ├── Row.vue │ ├── Segment.vue │ ├── Select.vue │ ├── Step.vue │ ├── Steps.vue │ ├── Submenu.vue │ ├── Switch.vue │ ├── TabPane.vue │ ├── Table.vue │ ├── TableBody.vue │ ├── TableHead.vue │ ├── TableHeadBodyFoot.vue │ ├── TableHeadFilter.vue │ ├── Tabs.vue │ ├── Tag.vue │ ├── Tags.vue │ ├── TimePicker.vue │ ├── Timeline.vue │ ├── TimelineItem.vue │ ├── Transfer.vue │ ├── TransferPanel.vue │ ├── Tree.vue │ ├── TreeNode.vue │ ├── TreeSelect.vue │ ├── Upload.vue │ ├── UploadImage.vue │ ├── ajax.js │ ├── message.js │ └── popup.js ├── config.js ├── directives │ └── clickoutside.js ├── index.js └── styles │ ├── back-top.less │ ├── base.less │ ├── button.less │ ├── calendar.less │ ├── card.less │ ├── carousel.less │ ├── cascader.less │ ├── chart.less │ ├── collapse.less │ ├── dark.less │ ├── date-picker.less │ ├── dimmer.less │ ├── divider.less │ ├── dropdown.less │ ├── form.less │ ├── grid.less │ ├── image.less │ ├── index.less │ ├── input-number.less │ ├── input.less │ ├── layout.less │ ├── list.less │ ├── menu.less │ ├── message.less │ ├── modal.less │ ├── normalize.less │ ├── notice.less │ ├── pagination.less │ ├── popup.less │ ├── radio-checkbox.less │ ├── segment.less │ ├── select.less │ ├── step.less │ ├── submenu.less │ ├── switch.less │ ├── table.less │ ├── tabs.less │ ├── tag.less │ ├── time-picker.less │ ├── timeline.less │ ├── transfer.less │ ├── tree.less │ └── upload.less └── static ├── .gitkeep ├── Datepicker.png ├── button.png ├── card.png ├── form.png ├── logo.png ├── menu.png ├── select.png ├── table.png └── treeselect.png /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 myliang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /build/build_publish.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.publish.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | var shell = require('shelljs') 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | ] 16 | 17 | if (shell.which('npm')) { 18 | versionRequirements.push({ 19 | name: 'npm', 20 | currentVersion: exec('npm --version'), 21 | versionRequirement: packageConfig.engines.npm 22 | }) 23 | } 24 | 25 | module.exports = function () { 26 | var warnings = [] 27 | for (var i = 0; i < versionRequirements.length; i++) { 28 | var mod = versionRequirements[i] 29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 30 | warnings.push(mod.name + ': ' + 31 | chalk.red(mod.currentVersion) + ' should be ' + 32 | chalk.green(mod.versionRequirement) 33 | ) 34 | } 35 | } 36 | 37 | if (warnings.length) { 38 | console.log('') 39 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 40 | console.log() 41 | for (var i = 0; i < warnings.length; i++) { 42 | var warning = warnings[i] 43 | console.log(' ' + warning) 44 | } 45 | console.log() 46 | process.exit(1) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = require('./webpack.dev.conf') 14 | 15 | // default port where dev server listens for incoming traffic 16 | var port = process.env.PORT || config.dev.port 17 | // automatically open browser, if not set will be false 18 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 19 | // Define HTTP proxies to your custom API backend 20 | // https://github.com/chimurai/http-proxy-middleware 21 | var proxyTable = config.dev.proxyTable 22 | 23 | var app = express() 24 | var compiler = webpack(webpackConfig) 25 | 26 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 27 | publicPath: webpackConfig.output.publicPath, 28 | quiet: true 29 | }) 30 | 31 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 32 | log: false, 33 | heartbeat: 2000 34 | }) 35 | // force page reload when html-webpack-plugin template changes 36 | compiler.plugin('compilation', function (compilation) { 37 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 38 | hotMiddleware.publish({ action: 'reload' }) 39 | cb() 40 | }) 41 | }) 42 | 43 | // proxy api requests 44 | Object.keys(proxyTable).forEach(function (context) { 45 | var options = proxyTable[context] 46 | if (typeof options === 'string') { 47 | options = { target: options } 48 | } 49 | app.use(proxyMiddleware(options.filter || context, options)) 50 | }) 51 | 52 | // handle fallback for HTML5 history API 53 | app.use(require('connect-history-api-fallback')()) 54 | 55 | // serve webpack bundle output 56 | app.use(devMiddleware) 57 | 58 | // enable hot-reload and state-preserving 59 | // compilation error display 60 | app.use(hotMiddleware) 61 | 62 | // serve pure static assets 63 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 64 | app.use(staticPath, express.static('./static')) 65 | 66 | var uri = 'http://localhost:' + port 67 | 68 | var _resolve 69 | var readyPromise = new Promise(resolve => { 70 | _resolve = resolve 71 | }) 72 | 73 | console.log('> Starting dev server...') 74 | devMiddleware.waitUntilValid(() => { 75 | console.log('> Listening at ' + uri + '\n') 76 | // when env is testing, don't need open it 77 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 78 | opn(uri) 79 | } 80 | _resolve() 81 | }) 82 | 83 | var server = app.listen(port) 84 | 85 | module.exports = { 86 | ready: readyPromise, 87 | close: () => { 88 | server.close() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.cssLoaders = function (options) { 13 | options = options || {} 14 | 15 | var cssLoader = { 16 | loader: 'css-loader', 17 | options: { 18 | minimize: process.env.NODE_ENV === 'production', 19 | sourceMap: options.sourceMap 20 | } 21 | } 22 | 23 | // generate loader string to be used with extract text plugin 24 | function generateLoaders (loader, loaderOptions) { 25 | var loaders = [cssLoader] 26 | if (loader) { 27 | loaders.push({ 28 | loader: loader + '-loader', 29 | options: Object.assign({}, loaderOptions, { 30 | sourceMap: options.sourceMap 31 | }) 32 | }) 33 | } 34 | 35 | // Extract CSS when that option is specified 36 | // (which is the case during production build) 37 | if (options.extract) { 38 | return ExtractTextPlugin.extract({ 39 | use: loaders, 40 | fallback: 'vue-style-loader' 41 | }) 42 | } else { 43 | return ['vue-style-loader'].concat(loaders) 44 | } 45 | } 46 | 47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 48 | return { 49 | css: generateLoaders(), 50 | postcss: generateLoaders(), 51 | less: generateLoaders('less'), 52 | sass: generateLoaders('sass', { indentedSyntax: true }), 53 | scss: generateLoaders('sass'), 54 | stylus: generateLoaders('stylus'), 55 | styl: generateLoaders('stylus') 56 | } 57 | } 58 | 59 | // Generate loaders for standalone style files (outside of .vue) 60 | exports.styleLoaders = function (options) { 61 | var output = [] 62 | var loaders = exports.cssLoaders(options) 63 | for (var extension in loaders) { 64 | var loader = loaders[extension] 65 | output.push({ 66 | test: new RegExp('\\.' + extension + '$'), 67 | use: loader 68 | }) 69 | } 70 | return output 71 | } 72 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var config = require('../config') 3 | var isProduction = process.env.NODE_ENV === 'production' 4 | 5 | module.exports = { 6 | loaders: utils.cssLoaders({ 7 | sourceMap: isProduction 8 | ? config.build.productionSourceMap 9 | : config.dev.cssSourceMap, 10 | extract: isProduction 11 | }), 12 | transformToRequire: { 13 | video: 'src', 14 | source: 'src', 15 | img: 'src', 16 | image: 'xlink:href' 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var config = require('../config') 4 | var vueLoaderConfig = require('./vue-loader.conf') 5 | 6 | function resolve (dir) { 7 | return path.join(__dirname, '..', dir) 8 | } 9 | 10 | module.exports = { 11 | entry: { 12 | app: './examples/main.js' 13 | }, 14 | output: { 15 | path: config.build.assetsRoot, 16 | filename: '[name].js', 17 | publicPath: process.env.NODE_ENV === 'production' 18 | ? config.build.assetsPublicPath 19 | : config.dev.assetsPublicPath 20 | }, 21 | resolve: { 22 | extensions: ['.js', '.vue', '.json'], 23 | alias: { 24 | 'vue$': 'vue/dist/vue.esm.js', 25 | '@': resolve('src') 26 | } 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.(js|vue)$/, 32 | loader: 'eslint-loader', 33 | enforce: 'pre', 34 | include: [resolve('src'), resolve('test')], 35 | options: { 36 | formatter: require('eslint-friendly-formatter') 37 | } 38 | }, 39 | { 40 | test: /\.vue$/, 41 | loader: 'vue-loader', 42 | options: vueLoaderConfig 43 | }, 44 | { 45 | test: /\.js$/, 46 | loader: 'babel-loader', 47 | include: [resolve('src'), resolve('test')] 48 | }, 49 | { 50 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 51 | loader: 'url-loader', 52 | options: { 53 | limit: 10000, 54 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 55 | } 56 | }, 57 | { 58 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 59 | loader: 'url-loader', 60 | options: { 61 | limit: 10000, 62 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 63 | } 64 | }, 65 | { 66 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 67 | loader: 'url-loader', 68 | options: { 69 | limit: 10000, 70 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 71 | } 72 | } 73 | ] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var webpack = require('webpack') 3 | var config = require('../config') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 8 | 9 | // add hot-reload related code to entry chunks 10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 12 | }) 13 | 14 | module.exports = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 17 | }, 18 | // cheap-module-eval-source-map is faster for development 19 | devtool: '#cheap-module-eval-source-map', 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env': config.dev.env 23 | }), 24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoEmitOnErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }), 33 | new FriendlyErrorsPlugin() 34 | ] 35 | }) 36 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../docs/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../docs'), 9 | assetsSubDirectory: '', 10 | assetsPublicPath: '', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | // productionGzip: false, 17 | // productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | dev: { 25 | env: require('./dev.env'), 26 | port: 8088, 27 | autoOpenBrowser: true, 28 | assetsSubDirectory: 'static', 29 | assetsPublicPath: '/', 30 | proxyTable: {}, 31 | // CSS Sourcemaps off by default because relative paths are "buggy" 32 | // with this option, according to the CSS-Loader README 33 | // (https://github.com/webpack/css-loader#sourcemaps) 34 | // In our experience, they generally work as expected, 35 | // just be aware of this issue when enabling this option. 36 | cssSourceMap: false 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /docs/Datepicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/docs/Datepicker.png -------------------------------------------------------------------------------- /docs/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/docs/button.png -------------------------------------------------------------------------------- /docs/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/docs/card.png -------------------------------------------------------------------------------- /docs/form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/docs/form.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | fish-ui A Vue.js 2.0 UI Toolkit for Web.
-------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/docs/logo.png -------------------------------------------------------------------------------- /docs/manifest.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,u,c){for(var i,a,f,l=0,s=[];l 2 |
3 |
4 | 5 |
6 |
7 |
{{ title }}
8 | 9 | 10 | expand code 11 | expand code 12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 | 36 | -------------------------------------------------------------------------------- /examples/components/DemoBackTop.vue: -------------------------------------------------------------------------------- 1 | 28 | 45 | -------------------------------------------------------------------------------- /examples/components/DemoChart.vue: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /examples/components/DemoChartLine.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoDivider.vue: -------------------------------------------------------------------------------- 1 | 45 | -------------------------------------------------------------------------------- /examples/components/DemoGridBase.vue: -------------------------------------------------------------------------------- 1 | 49 | 54 | -------------------------------------------------------------------------------- /examples/components/DemoGridFixed.vue: -------------------------------------------------------------------------------- 1 | 9 | 14 | -------------------------------------------------------------------------------- /examples/components/DemoGridGutterOffset.vue: -------------------------------------------------------------------------------- 1 | 20 | 25 | -------------------------------------------------------------------------------- /examples/components/DemoIndex.vue: -------------------------------------------------------------------------------- 1 | 72 | 79 | -------------------------------------------------------------------------------- /examples/components/DemoLayouUpMiddleDown.vue: -------------------------------------------------------------------------------- 1 | 17 | 22 | -------------------------------------------------------------------------------- /examples/components/DemoLayoutBase.vue: -------------------------------------------------------------------------------- 1 | 22 | 27 | -------------------------------------------------------------------------------- /examples/components/DemoLayoutSider.vue: -------------------------------------------------------------------------------- 1 | 31 | 36 | -------------------------------------------------------------------------------- /examples/components/DemoLayoutTopSiderHeader.vue: -------------------------------------------------------------------------------- 1 | 34 | 39 | -------------------------------------------------------------------------------- /examples/components/DemoLoader.vue: -------------------------------------------------------------------------------- 1 | 37 | 57 | -------------------------------------------------------------------------------- /examples/components/DemoPopup.vue: -------------------------------------------------------------------------------- 1 | 56 | 92 | -------------------------------------------------------------------------------- /examples/components/DemoSwitch.vue: -------------------------------------------------------------------------------- 1 | 60 | 83 | -------------------------------------------------------------------------------- /examples/components/DemoTableBase.vue: -------------------------------------------------------------------------------- 1 | 4 | 30 | -------------------------------------------------------------------------------- /examples/components/DemoTableBorder.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoTableColumnFilters.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoTableColumnFixed.vue: -------------------------------------------------------------------------------- 1 | 4 | 37 | -------------------------------------------------------------------------------- /examples/components/DemoTableColumnFixedScrollX.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoTableColumnOrder.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoTableColumnType.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoTableExpand.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoTableFixedHeader.vue: -------------------------------------------------------------------------------- 1 | 4 | 44 | -------------------------------------------------------------------------------- /examples/components/DemoTableNoMore.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /examples/components/DemoTablePagination.vue: -------------------------------------------------------------------------------- 1 | 5 | 39 | -------------------------------------------------------------------------------- /examples/components/DemoTableScrollXY.vue: -------------------------------------------------------------------------------- 1 | 4 | 37 | -------------------------------------------------------------------------------- /examples/components/DemoTableScrollY.vue: -------------------------------------------------------------------------------- 1 | 4 | 33 | -------------------------------------------------------------------------------- /examples/components/DemoTimePicker.vue: -------------------------------------------------------------------------------- 1 | 57 | 82 | -------------------------------------------------------------------------------- /examples/components/DemoTransfer.vue: -------------------------------------------------------------------------------- 1 | 59 | -------------------------------------------------------------------------------- /examples/components/DemoTransferBase.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /examples/components/DemoTreeSelectSingle.vue: -------------------------------------------------------------------------------- 1 | 8 | 59 | -------------------------------------------------------------------------------- /examples/static/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/examples/static/image.png -------------------------------------------------------------------------------- /examples/static/paragraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/examples/static/paragraph.png -------------------------------------------------------------------------------- /examples/static/square-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/examples/static/square-image.png -------------------------------------------------------------------------------- /examples/static/white-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/examples/static/white-image.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | fish-ui A Vue.js 2.0 UI Toolkit for Web. 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fish-ui", 3 | "version": "1.2.83", 4 | "description": "A Vue.js 2.0 UI Toolkit for Web", 5 | "author": "myliang ", 6 | "private": false, 7 | "license": "MIT", 8 | "main": "./src/index.js", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/myliang/fish-ui.git" 12 | }, 13 | "scripts": { 14 | "dev": "node build/dev-server.js", 15 | "start": "node build/dev-server.js", 16 | "build": "node build/build.js", 17 | "build_publish": "node build/build_publish.js", 18 | "lint": "eslint --ext .js,.vue src" 19 | }, 20 | "dependencies": { 21 | "async-validator": "1.8.1", 22 | "chart.js": "4.4.0", 23 | "moment": "2.27.0", 24 | "vue": "2.6.12" 25 | }, 26 | "devDependencies": { 27 | "autoprefixer": "^7.1.2", 28 | "babel-core": "^6.22.1", 29 | "babel-eslint": "^7.1.1", 30 | "babel-helper-vue-jsx-merge-props": "^2.0.2", 31 | "babel-loader": "^7.1.1", 32 | "babel-plugin-syntax-jsx": "^6.18.0", 33 | "babel-plugin-transform-runtime": "^6.22.0", 34 | "babel-plugin-transform-vue-jsx": "^3.5.0", 35 | "babel-preset-env": "^1.3.2", 36 | "babel-preset-es2015": "^6.24.1", 37 | "babel-preset-stage-2": "^6.22.0", 38 | "babel-register": "^6.22.0", 39 | "chalk": "^2.0.1", 40 | "connect-history-api-fallback": "^1.3.0", 41 | "copy-webpack-plugin": "^4.0.1", 42 | "css-loader": "^0.28.0", 43 | "cssnano": "^3.10.0", 44 | "eslint": "^4.18.2", 45 | "eslint-config-standard": "^6.2.1", 46 | "eslint-friendly-formatter": "^3.0.0", 47 | "eslint-loader": "^1.7.1", 48 | "eslint-plugin-html": "^3.0.0", 49 | "eslint-plugin-promise": "^3.4.0", 50 | "eslint-plugin-standard": "^2.0.1", 51 | "eventsource-polyfill": "^0.9.6", 52 | "express": "^4.14.1", 53 | "extract-text-webpack-plugin": "^2.0.0", 54 | "file-loader": "^0.11.1", 55 | "friendly-errors-webpack-plugin": "^1.1.3", 56 | "html-webpack-plugin": "^2.28.0", 57 | "http-proxy-middleware": "^0.17.3", 58 | "less": "^2.7.2", 59 | "less-loader": "^4.0.5", 60 | "opn": "^5.1.0", 61 | "optimize-css-assets-webpack-plugin": "^2.0.0", 62 | "ora": "^1.2.0", 63 | "rimraf": "^2.6.0", 64 | "semver": "^5.3.0", 65 | "shelljs": "^0.7.6", 66 | "url-loader": "^0.5.8", 67 | "vue-highlightjs": "^1.3.3", 68 | "vue-loader": "^13.3.0", 69 | "vue-router": "^3.0.1", 70 | "vue-style-loader": "^3.0.1", 71 | "vue-template-compiler": "^2.6.12", 72 | "webpack": "^2.6.1", 73 | "webpack-bundle-analyzer": "^2.2.1", 74 | "webpack-dev-middleware": "^1.10.0", 75 | "webpack-hot-middleware": "^2.18.0", 76 | "webpack-merge": "^4.1.0" 77 | }, 78 | "engines": { 79 | "node": ">= 4.0.0", 80 | "npm": ">= 3.0.0" 81 | }, 82 | "browserslist": [ 83 | "> 1%", 84 | "last 2 versions", 85 | "not ie <= 8" 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/BackTop.vue: -------------------------------------------------------------------------------- 1 | 6 | 27 | -------------------------------------------------------------------------------- /src/components/Button.vue: -------------------------------------------------------------------------------- 1 | 8 | 41 | -------------------------------------------------------------------------------- /src/components/Buttons.vue: -------------------------------------------------------------------------------- 1 | 6 | 24 | -------------------------------------------------------------------------------- /src/components/Card.vue: -------------------------------------------------------------------------------- 1 | 17 | 41 | -------------------------------------------------------------------------------- /src/components/Cards.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | 15 | -------------------------------------------------------------------------------- /src/components/CarouselItem.vue: -------------------------------------------------------------------------------- 1 | 6 | 17 | -------------------------------------------------------------------------------- /src/components/ChartLine.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /src/components/Checkbox.vue: -------------------------------------------------------------------------------- 1 | 9 | 47 | -------------------------------------------------------------------------------- /src/components/Checkboxes.vue: -------------------------------------------------------------------------------- 1 | 6 | 43 | -------------------------------------------------------------------------------- /src/components/Col.vue: -------------------------------------------------------------------------------- 1 | 6 | 45 | -------------------------------------------------------------------------------- /src/components/Collapse.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | 15 | -------------------------------------------------------------------------------- /src/components/CollapseItem.vue: -------------------------------------------------------------------------------- 1 | 12 | 33 | 34 | -------------------------------------------------------------------------------- /src/components/ContentRender.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/DatePicker.vue: -------------------------------------------------------------------------------- 1 | 19 | 95 | -------------------------------------------------------------------------------- /src/components/Divider.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/components/Dropdown.vue: -------------------------------------------------------------------------------- 1 | 12 | 43 | -------------------------------------------------------------------------------- /src/components/ElementToBody.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/components/Fields.vue: -------------------------------------------------------------------------------- 1 | 7 | 15 | -------------------------------------------------------------------------------- /src/components/Form.vue: -------------------------------------------------------------------------------- 1 | 6 | 44 | -------------------------------------------------------------------------------- /src/components/Image.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/components/Input.vue: -------------------------------------------------------------------------------- 1 | 29 | 82 | -------------------------------------------------------------------------------- /src/components/InputNumber.vue: -------------------------------------------------------------------------------- 1 | 18 | 75 | -------------------------------------------------------------------------------- /src/components/Layout.vue: -------------------------------------------------------------------------------- 1 | 24 | 57 | -------------------------------------------------------------------------------- /src/components/List.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/components/ListItem.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/components/Loader.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/components/Message.vue: -------------------------------------------------------------------------------- 1 | 6 | 15 | -------------------------------------------------------------------------------- /src/components/OptGroup.vue: -------------------------------------------------------------------------------- 1 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /src/components/Option.vue: -------------------------------------------------------------------------------- 1 | 6 | 36 | -------------------------------------------------------------------------------- /src/components/Popover.vue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/src/components/Popover.vue -------------------------------------------------------------------------------- /src/components/Pull.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /src/components/Radio.vue: -------------------------------------------------------------------------------- 1 | 9 | 34 | -------------------------------------------------------------------------------- /src/components/Radios.vue: -------------------------------------------------------------------------------- 1 | 6 | 39 | -------------------------------------------------------------------------------- /src/components/Row.vue: -------------------------------------------------------------------------------- 1 | 6 | 25 | -------------------------------------------------------------------------------- /src/components/Segment.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/components/Step.vue: -------------------------------------------------------------------------------- 1 | 10 | 41 | -------------------------------------------------------------------------------- /src/components/Steps.vue: -------------------------------------------------------------------------------- 1 | 6 | 26 | -------------------------------------------------------------------------------- /src/components/Submenu.vue: -------------------------------------------------------------------------------- 1 | 11 | 90 | -------------------------------------------------------------------------------- /src/components/Switch.vue: -------------------------------------------------------------------------------- 1 | 6 | 23 | 24 | -------------------------------------------------------------------------------- /src/components/TabPane.vue: -------------------------------------------------------------------------------- 1 | 6 | 27 | -------------------------------------------------------------------------------- /src/components/TableHeadBodyFoot.vue: -------------------------------------------------------------------------------- 1 | 16 | 46 | -------------------------------------------------------------------------------- /src/components/TableHeadFilter.vue: -------------------------------------------------------------------------------- 1 | 12 | 66 | -------------------------------------------------------------------------------- /src/components/Tabs.vue: -------------------------------------------------------------------------------- 1 | 16 | 87 | -------------------------------------------------------------------------------- /src/components/Tag.vue: -------------------------------------------------------------------------------- 1 | 14 | 59 | -------------------------------------------------------------------------------- /src/components/Tags.vue: -------------------------------------------------------------------------------- 1 | 25 | 81 | 82 | -------------------------------------------------------------------------------- /src/components/TimePicker.vue: -------------------------------------------------------------------------------- 1 | 19 | 72 | -------------------------------------------------------------------------------- /src/components/Timeline.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/components/TimelineItem.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /src/components/Transfer.vue: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /src/components/Upload.vue: -------------------------------------------------------------------------------- 1 | 13 | 95 | -------------------------------------------------------------------------------- /src/components/ajax.js: -------------------------------------------------------------------------------- 1 | function getError (action, option, xhr) { 2 | let msg = '' 3 | if (xhr.response) { 4 | msg = `${xhr.status} ${xhr.response.error || xhr.response}` 5 | } else if (xhr.responseText) { 6 | msg = `${xhr.status} ${xhr.responseText}` 7 | } else { 8 | msg = `fail to post ${action} ${xhr.status}` 9 | } 10 | 11 | const err = new Error(msg) 12 | err.status = xhr.status 13 | err.method = 'post' 14 | err.url = action 15 | return err 16 | } 17 | 18 | function getBody (xhr) { 19 | const text = xhr.responseText || xhr.response 20 | if (!text) { 21 | return text 22 | } 23 | 24 | try { 25 | return JSON.parse(text) 26 | } catch (e) { 27 | return text 28 | } 29 | } 30 | 31 | export default function upload (option) { 32 | if (typeof XMLHttpRequest === 'undefined') { 33 | return 34 | } 35 | 36 | const xhr = new XMLHttpRequest() 37 | const action = option.action 38 | 39 | if (xhr.upload) { 40 | xhr.upload.onprogress = function progress (e) { 41 | if (e.total > 0) { 42 | e.percent = e.loaded / e.total * 100 43 | } 44 | option.onProgress(e) 45 | } 46 | } 47 | 48 | const formData = new FormData() 49 | 50 | if (option.data) { 51 | Object.keys(option.data).map(key => { 52 | formData.append(key, option.data[key]) 53 | }) 54 | } 55 | 56 | formData.append(option.filename, option.file) 57 | 58 | xhr.onerror = function error (e) { 59 | option.onError(e, xhr) 60 | } 61 | 62 | xhr.onload = function onload () { 63 | if (xhr.status < 200 || xhr.status >= 300) { 64 | return option.onError(getError(action, option, xhr), xhr) 65 | } 66 | 67 | option.onSuccess(getBody(xhr)) 68 | } 69 | 70 | xhr.open('post', action, true) 71 | 72 | if (option.withCredentials && 'withCredentials' in xhr) { 73 | xhr.withCredentials = true 74 | } 75 | 76 | const headers = option.headers || {} 77 | 78 | for (let item in headers) { 79 | if (headers.hasOwnProperty(item) && headers[item] !== null) { 80 | xhr.setRequestHeader(item, headers[item]) 81 | } 82 | } 83 | xhr.send(formData) 84 | return xhr 85 | } 86 | -------------------------------------------------------------------------------- /src/components/message.js: -------------------------------------------------------------------------------- 1 | // const messageRootDiv = document.createElement('div') 2 | // messageRootDiv.setAttribute('class', 'ui notice') 3 | // document.body.appendChild(messageRootDiv) 4 | let createElement = (tag, className = null, html = null, onclick = null) => { 5 | let ele = document.createElement(tag) 6 | if (className !== null) ele.setAttribute('class', className) 7 | if (html !== null) ele.innerHTML = html 8 | if (onclick !== null) ele.onclick = onclick 9 | return ele 10 | } 11 | 12 | let _messageRoot = null 13 | let _noticeRoot = {} 14 | let getRoot = (className) => { 15 | let _root = createElement('div', className) 16 | document.body.appendChild(_root) 17 | return _root 18 | } 19 | 20 | const message = (color, html, fadeTime, position = 'top center') => { 21 | // console.log('color=', color, text, fadeTime) 22 | if (_messageRoot === null) _messageRoot = getRoot(`fish ${position} notices`) 23 | let div = createElement('div', ``, `
${html}
`) 24 | _messageRoot.appendChild(div) 25 | setTimeout(() => { 26 | _messageRoot.removeChild(div) 27 | }, fadeTime) 28 | } 29 | 30 | export default { 31 | info: (text, fadeTime = 3000) => { 32 | message('info', `${text}`, fadeTime) 33 | }, 34 | success: (text, fadeTime = 3000) => { 35 | message('success', `${text}`, fadeTime) 36 | }, 37 | error: (text, fadeTime = 3000) => { 38 | message('error', `${text}`, fadeTime) 39 | }, 40 | warning: (text, fadeTime = 3000) => { 41 | message('warning', `${text}`, fadeTime) 42 | }, 43 | tip: (title, content, position = 'top right') => { 44 | if (_noticeRoot[position] === undefined) _noticeRoot[position] = getRoot(`fish ${position} notices`) 45 | // console.log(_noticeRoot[position]) 46 | let div = createElement('div', 'fish notice fade-in', ` 47 | 48 |
${title}
49 |
${content}
50 | `) 51 | div.querySelector('.close').onclick = () => { 52 | _noticeRoot[position].removeChild(div) 53 | } 54 | _noticeRoot[position].appendChild(div) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | // calendar config 2 | exports.calendar = { 3 | today: 'Today', 4 | weeks: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 5 | months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 6 | hours: ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'], 7 | minutes: [ 8 | '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', 9 | '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', 10 | '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', 11 | '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', 12 | '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', 13 | '50', '51', '52', '53', '54', '55', '56', '57', '58', '59' 14 | ], 15 | seconds: [ 16 | '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', 17 | '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', 18 | '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', 19 | '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', 20 | '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', 21 | '50', '51', '52', '53', '54', '55', '56', '57', '58', '59' 22 | ] 23 | } 24 | exports.cssPrefix = 'fish' 25 | exports.notify = { 26 | field: { 27 | change (el) { 28 | el.$nextTick(() => { 29 | // 通知parent, 值发生了变化 30 | if (el.$parent && el.$parent.$options.name === 'fish-field') { 31 | el.$parent['fieldValueChange']() 32 | } 33 | }) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/directives/clickoutside.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bind: (el, binding, vnode) => { 3 | let documentHandler = (e) => { 4 | if (el.contains(e.target)) { 5 | return false 6 | } 7 | if (binding.expression) { 8 | binding.value(e) 9 | } 10 | } 11 | el.__vueClickOutside__ = documentHandler 12 | document.addEventListener('click', documentHandler) 13 | }, 14 | update: () => { 15 | 16 | }, 17 | unbind: (el, binding) => { 18 | document.removeEventListener('click', el.__vueClickOutside__) 19 | delete el.__vueClickOutside__ 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/styles/back-top.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.back-top { 4 | z-index: 1000; 5 | position: fixed; 6 | right: 80px; 7 | bottom: 50px; 8 | cursor: pointer; 9 | background: rgba(0, 0, 0, .6); 10 | box-shadow: 0px 0px 0px 1px transparent inset, 0px 0em 0px 0px rgba(34, 36, 38, 0.15) inset; 11 | border-radius: @border-radius; 12 | padding: 1em; 13 | line-height: 1em; 14 | color: #ffffff; 15 | } 16 | -------------------------------------------------------------------------------- /src/styles/calendar.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.calendar { 4 | color: rgba(0,0,0,.7); 5 | background: #ffffff; 6 | .user-select(none); 7 | 8 | > .header { 9 | font-weight: 700; 10 | color: inherit; 11 | text-align: right; 12 | line-height: @line-height; 13 | 14 | > a { 15 | padding: @padding-vertical; 16 | display: inline-block; 17 | color: inherit; 18 | 19 | &:hover { 20 | background-color: @hover-background-color; 21 | color: @hover-color; 22 | } 23 | 24 | .disabled; 25 | } 26 | } 27 | 28 | > table.body { 29 | width: 100%; 30 | 31 | &.day { 32 | th, td { 33 | width: 100%/7; 34 | } 35 | } 36 | &.month { 37 | th, td { 38 | width: 100%/3; 39 | } 40 | } 41 | &.year { 42 | th, td { 43 | width: 100%/4; 44 | } 45 | } 46 | 47 | th { 48 | text-align: right; 49 | .padding; 50 | } 51 | 52 | td > .cell { 53 | border-top: 3px solid @border-color; 54 | margin: 0 3px 1px 3px; 55 | text-align: center; 56 | .padding; 57 | 58 | > .title { 59 | text-align: right; 60 | font-weight: 700; 61 | //opacity: .85; 62 | } 63 | 64 | > .content { 65 | min-height: 5em; 66 | } 67 | 68 | &:hover { 69 | background: @active-background-color; 70 | } 71 | &.active, &.active:hover { 72 | background: @active-background-color; 73 | border-color: @active-border-color; 74 | color: @active-color; 75 | } 76 | 77 | .disabled; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/styles/card.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.card { 4 | position: relative; 5 | background: #fff; 6 | .transition(all .3s); 7 | font-size: 1em; 8 | .box-shadow; 9 | .border; 10 | border-radius: @border-radius @border-radius 0 0; 11 | max-width: 100%; 12 | display: flex; 13 | .flex-direction(column); 14 | width: 290px; 15 | 16 | &.fluid { 17 | width: 100%; 18 | } 19 | 20 | &.nopadding { 21 | > .content { 22 | padding: 0; 23 | } 24 | } 25 | 26 | .card-loop-color(@color-length); 27 | 28 | > .image { 29 | font-size: 0; 30 | line-height: 1; 31 | } 32 | 33 | > .header { 34 | border-bottom: @card-border-style; 35 | .padding; 36 | } 37 | > .content { 38 | .padding; 39 | border-bottom: @card-border-style; 40 | flex-grow: 1; 41 | 42 | &:last-child { 43 | border-bottom: none; 44 | } 45 | 46 | > .tabs { 47 | border: none; 48 | box-shadow: none; 49 | .nav.top li { 50 | margin-top: 0; 51 | border-top: 0; 52 | } 53 | } 54 | > * > .table, > .table { 55 | border: none; 56 | } 57 | } 58 | > .footer { 59 | .padding; 60 | } 61 | } 62 | 63 | .@{css-prefix}.cards { 64 | display: flex; 65 | flex-wrap: wrap; 66 | margin: -@padding-horizontal/2; 67 | align-items: flex-start; 68 | 69 | > .card { 70 | margin: @padding-horizontal/2; 71 | } 72 | 73 | &.two > .card { 74 | width: calc(~"50% - 0.925em") 75 | } 76 | &.three > .card { 77 | width: calc(~"33.333% - 0.925em") 78 | } 79 | &.four > .card { 80 | width: calc(~"25% - 0.925em") 81 | } 82 | &.five > .card { 83 | width: calc(~"20% - 0.925em") 84 | } 85 | &.six > .card { 86 | width: calc(~"16.666% - 0.925em") 87 | } 88 | 89 | } 90 | 91 | .@{css-prefix}.tabs { 92 | .cards { 93 | margin: @padding-horizontal/2; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/styles/carousel.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.carousel { 4 | position: relative; 5 | display: block; 6 | box-sizing: border-box; 7 | -webkit-touch-callout: none; 8 | -ms-touch-action: pan-y; 9 | touch-action: pan-y; 10 | -webkit-tap-highlight-color: transparent; 11 | 12 | .content { 13 | position: relative; 14 | overflow: hidden; 15 | display: block; 16 | margin: 0; 17 | padding: 0; 18 | 19 | > .list { 20 | position: relative; 21 | left: 0; 22 | top: 0; 23 | display: block; 24 | list-style: none; 25 | margin: 0; 26 | padding: 0; 27 | 28 | > .item { 29 | float: left; 30 | height: 100%; 31 | min-height: 1px; 32 | display: block; 33 | padding: 0; 34 | border: none; 35 | 36 | .image { 37 | margin: 0!important; 38 | } 39 | } 40 | } 41 | } 42 | 43 | &:hover { 44 | .play-toolbar-wrapper { 45 | visibility: visible; 46 | } 47 | } 48 | 49 | .play-toolbar-wrapper { 50 | visibility: hidden; 51 | display: flex; 52 | flex-direction: row; 53 | justify-content: center; 54 | position: absolute; 55 | bottom: 8px; 56 | width: 100%; 57 | } 58 | 59 | .play-toolbar { 60 | display: flex; 61 | flex-direction: row; 62 | justify-content: center; 63 | background-color: rgba(0, 0, 0, 0.2); 64 | border-radius: 5px; 65 | 66 | .play-toolbar-item { 67 | padding: 6px 10px; 68 | color: white; 69 | 70 | &.disabled { 71 | pointer-events: none; 72 | opacity: 0.5; 73 | } 74 | 75 | &:hover { 76 | background-color: rgba(0, 0, 0, .15); 77 | } 78 | } 79 | } 80 | 81 | > .count { 82 | text-align: center; 83 | margin: 0; 84 | padding: 5px; 85 | width: 100%; 86 | position: absolute; 87 | bottom: 12px; 88 | color: white; 89 | } 90 | 91 | > .dots { 92 | position: absolute; 93 | bottom: 12px; 94 | list-style: none; 95 | display: block; 96 | text-align: center; 97 | padding: 0; 98 | margin: 0; 99 | width: 100%; 100 | height: 3px; 101 | 102 | > li { 103 | position: relative; 104 | display: inline-block; 105 | vertical-align: top; 106 | text-align: center; 107 | margin: 0 2px; 108 | padding: 0; 109 | background: #fff; 110 | opacity: .3; 111 | .transition(all .5s); 112 | width: 1em; 113 | height: 3px; 114 | cursor: pointer; 115 | 116 | &.active { 117 | opacity: 1; 118 | width: 1.6em; 119 | } 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/styles/cascader.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.cascader { 4 | 5 | > .content { 6 | position: absolute; 7 | top: calc(~"100% + 5px"); 8 | margin: 0 -1px; 9 | left: 0; 10 | z-index: 10; 11 | 12 | .menu { 13 | display: inline-block; 14 | overflow: auto; 15 | height: 181px; 16 | margin-left: -1px; 17 | 18 | &:first-child { 19 | margin-left: 0; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/styles/chart.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.chart { 4 | &.line { 5 | .grids { 6 | .grid { 7 | stroke: rgba(0,0,0,.1); 8 | stroke-width: 1px; 9 | //stroke-dasharray: 5px; 10 | } 11 | } 12 | .labels { 13 | .label { 14 | fill: rgba(0,0,0,.4); 15 | color: rgba(0,0,0,.4); 16 | font-size: .75rem; 17 | line-height: 1; 18 | 19 | &.vertical { 20 | text-align: right; 21 | justify-content: flex-end; 22 | .align-items(right); 23 | display: -ms-flexbox; 24 | display: -webkit-flex; 25 | display: flex; 26 | } 27 | } 28 | } 29 | } 30 | 31 | &.pie { 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/styles/collapse.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.collapse { 4 | font-size: 1em; 5 | // .user-select(none); 6 | 7 | &.bordered { 8 | .border; 9 | } 10 | 11 | > .item { 12 | border-bottom: @border-style; 13 | -webkit-transition: all .3s; 14 | transition: all .3s; 15 | position: relative; 16 | 17 | &:hover, &.active { 18 | background: @hover-background-color; 19 | } 20 | 21 | &.active > .content { 22 | display: block; 23 | } 24 | 25 | &:after { 26 | position: absolute; 27 | right: @padding-horizontal; 28 | top: @padding-vertical + .25; 29 | display: inline-block; 30 | font: normal normal normal 14px/1 FontAwesome; 31 | font-size: inherit; 32 | text-rendering: auto; 33 | -webkit-font-smoothing: antialiased; 34 | content: "\f107"; 35 | } 36 | 37 | &:last-child { 38 | border-bottom-width: 0; 39 | } 40 | 41 | > .title { 42 | .padding; 43 | cursor: pointer; 44 | // &:hover { 45 | // background-color: @hover-background-color; 46 | // } 47 | 48 | > label { 49 | float: right; 50 | font-size: .8em; 51 | .user-select(none); 52 | background-color: #E8E8E8; 53 | color: rgba(0, 0, 0, 0.6); 54 | padding: 0.15em 0.6em; 55 | margin: -0.15em 1.5em -0.15em 0; 56 | border-radius: 3px; 57 | } 58 | } 59 | > .content { 60 | .padding; 61 | padding-top: 0; 62 | display: none; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/styles/dark.less: -------------------------------------------------------------------------------- 1 | /** dark */ 2 | .fish.dark { 3 | background-color: #2B2B2B; 4 | color: #fff; 5 | 6 | .button { 7 | background: #4D5153; 8 | color: rgba(255, 255, 255, .82); 9 | 10 | &.active, &:hover, &:focus { 11 | background-color: #282828; 12 | color: #fff; 13 | } 14 | 15 | &.basic { 16 | background-color: transparent; 17 | border: 1px solid #5E6060; 18 | box-shadow: none; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/styles/date-picker.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | @td-min-width: 2.8em; 4 | @padding: .8em 0; 5 | 6 | .@{css-prefix}.date-picker { 7 | // max-width: 14em; 8 | 9 | .content { 10 | box-shadow: 0 1px 5px rgba(0,0,0,.2); 11 | min-width: @td-min-width * 7; 12 | position: absolute; 13 | left: 0; 14 | top: calc(~"100% + 5px"); 15 | z-index: 10; 16 | width: 100%; 17 | 18 | .calendar { 19 | 20 | > .header { 21 | position: relative; 22 | text-align: center; 23 | background: #F9FAFB; 24 | 25 | > a:not(.prev):not(.next) { 26 | padding-left: .1em; 27 | padding-right: .1em; 28 | 29 | &:hover { 30 | background-color: transparent; 31 | } 32 | } 33 | 34 | > .prev { 35 | position: absolute; 36 | left: 0; 37 | } 38 | > .next { 39 | position: absolute; 40 | right: 0; 41 | } 42 | > a { 43 | padding: 0.65em; 44 | } 45 | } 46 | 47 | > table.body { 48 | 49 | th { 50 | padding: @padding; 51 | text-align: center; 52 | } 53 | 54 | td { 55 | 56 | > .cell { 57 | // box-shadow: 0 0 1px rgba(0,0,0,1) inset; 58 | border: 1px solid rgba(0, 0, 0, .05); 59 | cursor: pointer; 60 | margin: 0; 61 | // border: 0; 62 | padding: @padding; 63 | line-height: 1em; 64 | font-weight: bold; 65 | 66 | } 67 | } 68 | } 69 | } 70 | 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/styles/dimmer.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.dimmer { 4 | display: none; 5 | position: absolute; 6 | top: 0 !important; 7 | left: 0 !important; 8 | width: 100%; 9 | height: 100%; 10 | text-align: center; 11 | vertical-align: middle; 12 | background-color: rgba(0, 0, 0, 0.06); 13 | opacity: 0; 14 | -webkit-animation-fill-mode: both; 15 | animation-fill-mode: both; 16 | -webkit-animation-duration: 0.5s; 17 | animation-duration: 0.5s; 18 | .transition(background-color 0.5s linear); 19 | .user-select(none); 20 | will-change: opacity; 21 | z-index: 1000; 22 | 23 | &.loading { 24 | .loading(3.25em, 0.325em); 25 | } 26 | 27 | &.active { 28 | display: block; 29 | opacity: 1; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/styles/divider.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.divider { 4 | margin: 1em 0; 5 | line-height: 1; 6 | height: 0; 7 | text-transform: uppercase; 8 | letter-spacing: 0.05em; 9 | .user-select(none); 10 | -webkit-tap-highlight-color: transparent; 11 | font-size: 1rem; 12 | 13 | border-top: 1px solid rgba(34,36,38,.15); 14 | border-bottom: 1px solid rgba(255,255,255,.1); 15 | 16 | &.fitted { 17 | margin: 0; 18 | } 19 | } -------------------------------------------------------------------------------- /src/styles/dropdown.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.dropdown { 4 | display: inline-block; 5 | position: relative; 6 | outline: none; 7 | 8 | .content { 9 | position: absolute; 10 | z-index: 100; 11 | .box-shadow; 12 | .border; 13 | 14 | > * { 15 | box-shadow: none; 16 | border: none; 17 | } 18 | } 19 | 20 | &.bottom-left .content { 21 | top: calc(~"100% + 5px"); 22 | left: 0; 23 | } 24 | &.bottom-right .content { 25 | top: calc(~"100% + 5px"); 26 | right: 0; 27 | } 28 | &.top-left .content { 29 | bottom: calc(~"100% + 5px"); 30 | left: 0; 31 | } 32 | &.top-right .content { 33 | bottom: calc(~"100% + 5px"); 34 | right: 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/styles/form.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.form { 4 | //padding: @padding-horizontal; 5 | //margin: 0em -1px; 6 | width: 100%; 7 | 8 | &.inline { 9 | .field { 10 | display: inline-block; 11 | margin-right: .8em; 12 | margin-bottom: 0; 13 | vertical-align: middle; 14 | } 15 | } 16 | 17 | .fields { 18 | display: -webkit-box; 19 | display: -ms-flexbox; 20 | display: flex; 21 | -webkit-box-orient: horizontal; 22 | -webkit-box-direction: normal; 23 | .flex-direction(row); 24 | margin: 0 -.5em 1em; 25 | flex-wrap: wrap; 26 | 27 | > .field { 28 | -webkit-box-flex: 0; 29 | .flex(0 1 auto); 30 | padding-left: .5em; 31 | padding-right: .5em; 32 | margin: 0; 33 | } 34 | 35 | &:last-child { 36 | margin-bottom: 0; 37 | } 38 | } 39 | 40 | .field { 41 | display: block; 42 | font-size: 1em; 43 | margin: 0 0 .6em; 44 | 45 | .disabled; 46 | 47 | &.required { 48 | > .label:after { 49 | margin: 0 0 0 .3em; 50 | content: '*'; 51 | color: @form-error-color; 52 | //display: inline-block; 53 | } 54 | } 55 | 56 | &.inline { 57 | //display: inline-block; 58 | display: -webkit-box; 59 | display: -ms-flexbox; 60 | display: flex; 61 | -webkit-box-align: center; 62 | -ms-flex-align: center; 63 | align-items: center; 64 | 65 | > label { 66 | display: inline-block; 67 | margin: 0 1em 0 0; 68 | } 69 | 70 | &.required { 71 | > .label:before { 72 | margin: 0 0.3em 0 0; 73 | content: '*'; 74 | color: @form-error-color; 75 | } 76 | > .label:after { 77 | margin: 0; 78 | content: ''; 79 | } 80 | } 81 | 82 | &.error .tip { 83 | margin-left: 0.6em; 84 | } 85 | } 86 | 87 | .@{css-prefix}.input, .select { 88 | width: 100%!important; 89 | } 90 | 91 | > label { 92 | display: block; 93 | margin: 0.3em 0em 0.3rem 0em; 94 | font-weight: 500; 95 | text-align: left; 96 | text-transform: none; 97 | } 98 | 99 | .radios, .checkboxes { 100 | padding: @input-padding-vertical 0; 101 | } 102 | 103 | .switch { 104 | margin-top: @input-padding-vertical; 105 | } 106 | 107 | &.error { 108 | .tip { 109 | color: @form-error-color; 110 | font-size: .9em; 111 | } 112 | input, .select { 113 | border-color: @form-error-color; 114 | } 115 | } 116 | 117 | } 118 | } 119 | 120 | @media only screen and (max-width: @largestMobileScreen) { 121 | .@{css-prefix}.form { 122 | .fields { 123 | .flex-direction(column); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/styles/grid.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | @ColSpanWidth: 4.16666%; 4 | 5 | .@{css-prefix}.row { 6 | position: relative; 7 | display: -webkit-box; 8 | display: -ms-flexbox; 9 | display: flex; 10 | -webkit-box-orient: horizontal; 11 | .flex-direction(row); 12 | 13 | -ms-flex-wrap: nowrap; 14 | flex-wrap: nowrap; 15 | -webkit-box-pack: inherit; 16 | -ms-flex-pack: inherit; 17 | justify-content: inherit; 18 | -webkit-box-align: stretch; 19 | -ms-flex-align: stretch; 20 | align-items: stretch; 21 | width: 100% !important; 22 | padding: 0; 23 | 24 | .col { 25 | position: relative; 26 | //display: inline-block; 27 | .flex(0 1 auto); 28 | -webkit-box-flex: 0; 29 | clear: both; 30 | } 31 | 32 | .col.width-fixed { 33 | .flex(0 0 auto); 34 | } 35 | .col.width-auto { 36 | .flex(1 1 auto); 37 | } 38 | 39 | // align垂直对齐方式 40 | &.top { 41 | .align-items(flex-start); 42 | } 43 | &.middle { 44 | .align-items(center) 45 | } 46 | &.bottom { 47 | .align-items(flex-end) 48 | } 49 | // 水平排列方式 50 | &.start { 51 | .justify-content(flex-start); 52 | } 53 | &.center { 54 | .justify-content(center); 55 | } 56 | &.end { 57 | .justify-content(flex-end); 58 | } 59 | &.space-around { 60 | .justify-content(space-around); 61 | } 62 | &.space-between { 63 | .justify-content(space-between); 64 | } 65 | } 66 | 67 | @media only screen and (max-width: @largestMobileScreen) { 68 | .@{css-prefix}.row { 69 | -ms-flex-wrap: wrap; 70 | flex-wrap: wrap; 71 | 72 | .col { 73 | width: 100%!important; 74 | padding-right: 0!important; 75 | } 76 | 77 | .col.width-fixed { 78 | width: 100%!important; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/styles/image.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.image { 4 | background-color: transparent; 5 | vertical-align: middle; 6 | display: inline-block; 7 | max-width: 100%; 8 | border: 0; 9 | margin: 0 .5em .5em 0; 10 | 11 | .disabled; 12 | 13 | &.bordered { 14 | border: 1px solid rgba(0,0,0,.15); 15 | } 16 | 17 | &.rounded { 18 | border-radius: .3125em; 19 | } 20 | 21 | &.circle { 22 | border-radius: 500rem; 23 | } 24 | } -------------------------------------------------------------------------------- /src/styles/index.less: -------------------------------------------------------------------------------- 1 | @import "./normalize.less"; 2 | @import './button.less'; 3 | @import './input.less'; 4 | @import './input-number.less'; 5 | @import './step.less'; 6 | @import './tag.less'; 7 | @import './submenu.less'; 8 | @import './menu.less'; 9 | @import './select.less'; 10 | @import './cascader.less'; 11 | @import './pagination.less'; 12 | @import './layout.less'; 13 | @import './dropdown.less'; 14 | @import './radio-checkbox.less'; 15 | @import './calendar.less'; 16 | @import './date-picker.less'; 17 | @import './time-picker.less'; 18 | @import './tree.less'; 19 | @import './dimmer.less'; 20 | @import './modal.less'; 21 | @import './form.less'; 22 | @import './notice.less'; 23 | @import './popup.less'; 24 | @import './message.less'; 25 | @import './back-top.less'; 26 | @import './card.less'; 27 | @import './carousel.less'; 28 | @import './tabs.less'; 29 | @import './upload.less'; 30 | @import './table.less'; 31 | @import './grid.less'; 32 | @import './divider.less'; 33 | @import './image.less'; 34 | @import './transfer.less'; 35 | @import './timeline.less'; 36 | @import './list.less'; 37 | @import './switch.less'; 38 | @import './collapse.less'; 39 | @import './segment.less'; 40 | @import './dark.less'; 41 | 42 | -------------------------------------------------------------------------------- /src/styles/input-number.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.input.number { 4 | z-index: 1; 5 | vertical-align: middle; 6 | 7 | &:hover { 8 | .step { 9 | opacity: 1; 10 | } 11 | } 12 | 13 | .step { 14 | width: 1.8em; 15 | opacity: 0; 16 | background: #f1f1f1; 17 | 18 | > i { 19 | cursor: pointer; 20 | z-index: 2; 21 | font-size: 1em; 22 | display: block; 23 | text-align: center; 24 | width: 100%; 25 | height: 50%; 26 | color: rgba(0, 0, 0, 0.65); 27 | padding-top: 2px; 28 | 29 | &:hover { 30 | background-color: rgba(0, 0, 0, 0.05); 31 | } 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/styles/input.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.input { 4 | font-size: 1em; 5 | position: relative; 6 | font-weight: 400; 7 | display: flex; 8 | color: rgba(0,0,0,.87); 9 | vertical-align: baseline; 10 | height: 37px; 11 | 12 | > i { 13 | .icon-right; 14 | } 15 | 16 | &.left { 17 | > i { 18 | right: auto; 19 | left: 1px; 20 | border-radius: @border-radius 0 0 @border-radius; 21 | } 22 | > input { 23 | padding-left: 2.6em; 24 | } 25 | } 26 | &.right > input { 27 | padding-right: 2.6em; 28 | } 29 | 30 | &.transparent input{ 31 | border-color: transparent!important; 32 | background-color: transparent!important; 33 | padding: 0!important; 34 | box-shadow: none!important; 35 | border-radius: 0!important; 36 | } 37 | 38 | &.loading >i { 39 | .loading(1.2em, 0.2em); 40 | } 41 | 42 | > input, > textarea { 43 | z-index: 1; 44 | margin: 0; 45 | max-width: 100%; 46 | flex: 1 0 auto; 47 | outline: 0; 48 | -webkit-tap-highlight-color: rgba(255,255,255,0); 49 | text-align: left; 50 | line-height: @line-height; 51 | padding: @input-padding; 52 | background: #fff; 53 | border: 1px solid @input-border-color; 54 | //border: 0; 55 | border-radius: @border-radius; 56 | transition: box-shadow .1s ease,border-color .1s ease; 57 | box-shadow: @input-box-shadow; 58 | 59 | &:focus { 60 | border-color: @input-active-color; 61 | //box-shadow: 0 0 0 1px rgba(16,142,233,.8); 62 | color: rgba(0,0,0,.9); 63 | } 64 | 65 | } 66 | 67 | 68 | .label-right { 69 | .user-select(none); 70 | position: absolute; 71 | top: 1px; 72 | right: 1px; 73 | z-index: 2; 74 | height: calc(~"100% - 2px"); 75 | border-radius: 0 @border-radius @border-radius 0; 76 | display: inline-flex; 77 | 78 | > label { 79 | padding: @input-padding; 80 | background: #f1f1f1; 81 | border-left: 1px solid @input-border-color; 82 | border-radius: 0 @border-radius @border-radius 0; 83 | } 84 | } 85 | 86 | .label-left { 87 | .user-select(none); 88 | border-radius: @border-radius 0 0 @border-radius; 89 | display: inline-flex; 90 | padding: @input-padding; 91 | background: #f1f1f1; 92 | border: 1px solid @input-border-color; 93 | border-right: none; 94 | 95 | ~ input { 96 | border-top-left-radius: 0; 97 | border-bottom-left-radius: 0; 98 | } 99 | } 100 | 101 | // size 102 | .font-sizes; 103 | 104 | .disabled; 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/styles/layout.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix} { 4 | &.layout { 5 | display: -webkit-box; 6 | display: -webkit-flex; 7 | display: -ms-flexbox; 8 | display: flex; 9 | -webkit-box-orient: vertical; 10 | -webkit-box-direction: normal; 11 | .flex-direction(column); 12 | -webkit-box-flex: 1; 13 | .flex(auto); 14 | 15 | &.has-sider { 16 | -webkit-box-orient: horizontal; 17 | -webkit-box-direction: normal; 18 | .flex-direction(row); 19 | } 20 | 21 | > .header, > .footer { 22 | -webkit-box-flex: 0; 23 | .flex(none); 24 | } 25 | > .header { 26 | } 27 | > .content { 28 | -webkit-box-flex: 1; 29 | .flex(auto); 30 | } 31 | > .footer { 32 | padding: 20px 0; 33 | color: rgba(0,0,0,.65); 34 | text-align: center; 35 | } 36 | > .sider { 37 | .transition(all .15s cubic-bezier(.645,.045,.355,1)); 38 | position: relative; 39 | min-width: 0; 40 | flex: 0 0 200px; 41 | width: 200px; 42 | } 43 | 44 | > .toggle { 45 | display: none; 46 | } 47 | } 48 | } 49 | 50 | /* Mobile */ 51 | @media only screen and (max-width: @largestMobileScreen) { 52 | .@{css-prefix} { 53 | &.layout.responsive { 54 | &.has-sider { 55 | .flex-direction(column); 56 | margin: 0; 57 | } 58 | > .sider { 59 | position: fixed; 60 | left: 0; 61 | top: 0; 62 | z-index: 1000; 63 | display: none; 64 | overflow-y: auto; 65 | height: 100%; 66 | } 67 | > .toggle { 68 | display: block; 69 | position: fixed; 70 | color: #666; 71 | z-index: 1000; 72 | background: #fff; 73 | left: 0; 74 | top: -1000px; 75 | .padding; 76 | box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/styles/list.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.list { 4 | &.bordered { 5 | > .item { 6 | border-bottom: @border-style; 7 | &:last-child { 8 | border-bottom: none; 9 | } 10 | } 11 | } 12 | 13 | > .item { 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /src/styles/menu.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix} { 4 | &.menu { 5 | list-style: none; 6 | margin: 0; 7 | padding: 0; 8 | font-size: @base-font-size; 9 | background-color: #ffffff; 10 | .user-select(none); 11 | z-index: 5; 12 | 13 | .item { 14 | //display: flex; 15 | //flex: 0 0 auto; 16 | line-height: 1em; 17 | .padding; 18 | margin: 0; 19 | vertical-align: middle; 20 | text-align: left; 21 | font-weight: 400; 22 | color: @base-font-color; 23 | white-space: nowrap; 24 | cursor: pointer; 25 | -webkit-transition: all .3s; 26 | transition: all .3s; 27 | 28 | &:not(.header):not(.submenu):hover { 29 | background: @hover-background-color; 30 | } 31 | &.active, &.active:not(.header):not(.submenu):hover { 32 | background: @hover-background-color; 33 | //background: @active-background-color; 34 | //color: @active-color; 35 | // font-weight: bold; 36 | } 37 | 38 | .disabled; 39 | 40 | > i.expand { 41 | float: right; 42 | } 43 | } 44 | 45 | .optgroup { 46 | .header { 47 | .item; 48 | // padding-left: @padding-horizontal/2; 49 | color: lighten(@base-font-color, 40%)!important; 50 | } 51 | ul { 52 | list-style: none; 53 | margin: 0; 54 | padding: 0; 55 | } 56 | } 57 | 58 | &.vertical { 59 | // max-height: 264px; 60 | .box-shadow; 61 | .border; 62 | 63 | > .item { 64 | border-top: 1px solid @menu-item-border-color; 65 | // min-width: @menu-min-width; 66 | 67 | &:first-child { 68 | border-top: none; 69 | } 70 | } 71 | } 72 | 73 | &.horizontal { 74 | display: flex; 75 | border-bottom: @border-style; 76 | 77 | > .item { 78 | position: relative; 79 | float: left; 80 | border: 0; 81 | border-bottom: 3px solid transparent; 82 | z-index: 10; 83 | 84 | &:hover, &.active { 85 | border-bottom: 3px solid @primary-color; 86 | } 87 | } 88 | } 89 | 90 | &.inline { 91 | .item { 92 | border-top: none; 93 | border-right: 3px solid @border-color; 94 | 95 | &.active { 96 | border-right-color: @primary-color; 97 | } 98 | } 99 | 100 | } 101 | 102 | &.compact { 103 | display: inline-flex; 104 | vertical-align: middle; 105 | } 106 | 107 | // size 108 | .font-sizes; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/styles/message.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.message { 4 | .padding; 5 | font-size: 1em; 6 | color: #333; 7 | background-color: #f8f8f9; 8 | .border; 9 | border-radius: @border-radius; 10 | margin: 1em 0; 11 | 12 | &:last-child { 13 | margin-bottom: 0; 14 | } 15 | 16 | &.attached { 17 | margin: 0; 18 | border-radius: 0; 19 | border-bottom-width: 0; 20 | 21 | &.top { 22 | border-radius: @border-radius @border-radius 0 0; 23 | } 24 | 25 | &.bottom { 26 | border-bottom-width: 1px; 27 | margin-bottom: 1em; 28 | border-radius: 0 0 @border-radius @border-radius; 29 | } 30 | } 31 | 32 | &.warning { 33 | background: @warning-background-color; 34 | color: @warning-font-color; 35 | } 36 | 37 | &.error { 38 | background: @error-background-color; 39 | color: @error-font-color; 40 | } 41 | 42 | &.success { 43 | background: @success-background-color; 44 | color: @success-font-color; 45 | } 46 | 47 | &.info { 48 | background: @info-background-color; 49 | color: @info-font-color; 50 | } 51 | } 52 | 53 | 54 | .@{css-prefix}.card > .content, 55 | .@{css-prefix}.tabs > .content .pane { 56 | > .message.attached { 57 | border-radius: 0; 58 | border-left: none; 59 | border-right: none; 60 | &:first-child { 61 | border-top: 0; 62 | } 63 | &:last-child { 64 | border-bottom: 0; 65 | } 66 | &.top { 67 | border-bottom-width: 1px; 68 | border-top: none; 69 | } 70 | &.bottom { 71 | border-bottom: none; 72 | margin-bottom: 0; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/styles/modal.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.modal { 4 | font-size: 1em; 5 | position: fixed; 6 | z-index: 1001; 7 | text-align: left; 8 | background: #ffffff; 9 | border: none; 10 | width: @modal-width; 11 | color: rgba(0, 0, 0, .65); 12 | box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 8px; 13 | 14 | &.attached { 15 | &.center { 16 | border-radius: 6px; 17 | top: 0; 18 | left: 50%; 19 | } 20 | &.top, &.bottom { 21 | width: 100%; 22 | left: 0; 23 | > .content { 24 | width: 100%; 25 | overflow: auto; 26 | } 27 | } 28 | &.top { 29 | top: 0; 30 | } 31 | &.bottom { 32 | bottom: 0; 33 | } 34 | &.left, &.right { 35 | height: 100%; 36 | top: 0; 37 | > .content { 38 | height: ~'calc(100% - 3em)'; 39 | overflow: auto; 40 | } 41 | } 42 | &.left { 43 | left: 0; 44 | } 45 | &.right { 46 | right: 0; 47 | } 48 | } 49 | 50 | .image { 51 | font-size: 0; 52 | line-height: 1; 53 | } 54 | 55 | > i { 56 | opacity: .8; 57 | position: absolute; 58 | top: @padding-horizontal; 59 | right: @padding-horizontal; 60 | cursor: pointer; 61 | } 62 | 63 | > .header { 64 | padding: @padding-vertical @padding-horizontal; 65 | font-size: 1.1em; 66 | border-radius: @modal-border-radius @modal-border-radius 0 0; 67 | background: #F8F8F9; 68 | font-weight: bold; 69 | //opacity: .8; 70 | } 71 | 72 | > .content { 73 | border-radius: 0 0 @modal-border-radius @modal-border-radius; 74 | padding: @padding-horizontal; 75 | } 76 | } 77 | 78 | @media only screen and (max-width: @largestMobileScreen) { 79 | .@{css-prefix}.modal { 80 | width: 96%; 81 | margin: 0 0 0 -48%; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/styles/notice.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .notice() { 4 | padding: @notice-padding; 5 | margin-bottom: 1em; 6 | background-color: #fff; 7 | color: @base-font-color; 8 | box-shadow: 0 1px 5px rgba(0,0,0,.2); 9 | 10 | &.success { 11 | border-top: 3px solid @success-color; 12 | } 13 | &.warning { 14 | border-top: 3px solid @warning-color; 15 | } 16 | &.error { 17 | border-top: 3px solid @error-color; 18 | } 19 | } 20 | 21 | .@{css-prefix}.notices { 22 | position: fixed; 23 | z-index: 1010; 24 | font-size: @base-font-size; 25 | width: 345px; 26 | 27 | &.top.center { 28 | text-align: center; 29 | left: 0; 30 | top: 1em; 31 | width: 100%; 32 | padding-left: 1em; 33 | padding-right: 1em; 34 | 35 | .notice { 36 | text-align: center; 37 | display: inline-block; 38 | .notice; 39 | } 40 | 41 | } 42 | 43 | &.top.right { 44 | top: 1rem; 45 | right: 1rem; 46 | } 47 | &.top.left { 48 | top: 1rem; 49 | left: 1rem; 50 | } 51 | &.bottom.right { 52 | bottom: 1rem; 53 | right: 1rem; 54 | 55 | } 56 | &.bottom.left { 57 | bottom: 1rem; 58 | left: 1rem; 59 | } 60 | 61 | } 62 | 63 | .@{css-prefix}.top.right.notices .notice, 64 | .@{css-prefix}.top.left.notices .notice , 65 | .@{css-prefix}.bottom.right.notices .notice , 66 | .@{css-prefix}.bottom.right.notices .notice { 67 | position: relative; 68 | top: 0; 69 | left: 0; 70 | z-index: 1011; 71 | width: 100%; 72 | text-align: left; 73 | 74 | .notice; 75 | 76 | .header { 77 | font-size: 1.1em; 78 | margin-right: 1.2em; 79 | } 80 | 81 | .content { 82 | margin-top: @padding-vertical; 83 | } 84 | 85 | .close { 86 | cursor: pointer; 87 | position: absolute; 88 | right: @padding-horizontal; 89 | top: @padding-vertical; 90 | opacity: .6; 91 | } 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/styles/pagination.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.pagination { 4 | list-style: none; 5 | font-size: @base-font-size; 6 | margin: 0; 7 | padding: 2px; 8 | .user-select(none); 9 | 10 | .item { 11 | display: inline-block; 12 | border-radius: @border-radius; 13 | cursor: pointer; 14 | .user-select(none); 15 | text-align: center; 16 | vertical-align: middle; 17 | //border: 1px solid transparent; 18 | outline: 0; 19 | margin-right: .55em; 20 | line-height: 1.4em; 21 | padding: 6px 10px; 22 | font-weight: bold; 23 | box-shadow: 0px 0px 1px 1px @border-color; 24 | 25 | > input { 26 | margin: 0; 27 | padding: 0; 28 | width: 35px; 29 | border: none; 30 | outline: 0; 31 | text-align: center; 32 | -webkit-tap-highlight-color: rgba(255, 255, 255, 0); 33 | } 34 | 35 | &.total { 36 | border-color: transparent; 37 | background: @warning-background-color; 38 | } 39 | 40 | &:not(.total):hover { 41 | //border-color: @primary-color; 42 | color: @primary-color; 43 | } 44 | &.active, &.active:hover { 45 | background-color: @primary-color; 46 | //border-color: @primary-color; 47 | color: #fff; 48 | } 49 | .disabled; 50 | 51 | &:last-child { 52 | margin-right: 0; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/styles/popup.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | @arrow-width: 0.7em; 4 | 5 | .@{css-prefix}.popup { 6 | position: absolute; 7 | font-size: 1em; 8 | z-index: 1200; 9 | background: #ffffff; 10 | padding: @popup-padding; 11 | color: @base-font-color; 12 | border-radius: 0; 13 | box-shadow: 0 1px 6px rgba(0,0,0,.2); 14 | line-height: 1em; 15 | 16 | &.bottom.left { 17 | -webkit-transform-origin: left top; 18 | transform-origin: left top; 19 | 20 | &:before { 21 | top: -@arrow-width/2; 22 | left: 1em; 23 | -webkit-transform: rotate(-135deg); 24 | transform: rotate(-135deg); 25 | } 26 | } 27 | 28 | &.bottom.right { 29 | -webkit-transform-origin: right top; 30 | transform-origin: right top; 31 | 32 | &:before { 33 | top: -@arrow-width/2; 34 | right: 1em; 35 | -webkit-transform: rotate(-135deg); 36 | transform: rotate(-135deg); 37 | } 38 | } 39 | 40 | &.top.left { 41 | -webkit-transform-origin: left bottom; 42 | transform-origin: left bottom; 43 | 44 | &:before { 45 | bottom: -@arrow-width/2; 46 | left: 1em; 47 | } 48 | } 49 | 50 | &.top.right { 51 | -webkit-transform-origin: right bottom; 52 | transform-origin: right bottom; 53 | 54 | &:before { 55 | bottom: -@arrow-width/2; 56 | right: 1em; 57 | } 58 | } 59 | 60 | &.bottom { 61 | margin: @arrow-width 0 0; 62 | } 63 | 64 | &.top { 65 | margin: 0 0 @arrow-width; 66 | } 67 | 68 | &:before { 69 | position: absolute; 70 | content: ''; 71 | width: @arrow-width; 72 | height: @arrow-width; 73 | background: #FFFFFF; 74 | -webkit-transform: rotate(45deg); 75 | transform: rotate(45deg); 76 | z-index: 1; 77 | box-shadow: 1px 1px 3px -1px rgba(0,0,0,.3); 78 | //box-shadow: 0 0 0 6px rgba(0,0,0,.2); 79 | } 80 | 81 | .content { 82 | margin-bottom: 1em; 83 | 84 | > i { 85 | color: @warning-color; 86 | margin-right: .6em; 87 | font-size: 1.1em; 88 | } 89 | } 90 | 91 | .footer { 92 | float: right; 93 | 94 | .button { 95 | font-weight: bold; 96 | margin-left: .6em; 97 | } 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/styles/radio-checkbox.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.radio, .@{css-prefix}.checkbox { 4 | display: flex; 5 | -webkit-backface-visibility: hidden; 6 | backface-visibility: hidden; 7 | outline: 0; 8 | font-style: normal; 9 | font-size: 1rem; 10 | line-height: 1.2; 11 | align-items: center; 12 | //margin-right: .5em; 13 | 14 | span { 15 | padding: 0 8px; 16 | cursor: pointer; 17 | .user-select(none); 18 | line-height: 1.2; 19 | } 20 | 21 | &.active, &.open { 22 | > label:before { 23 | border-color: @primary-color; 24 | } 25 | > label:after { 26 | position: absolute; 27 | top: 0; 28 | left: 0; 29 | border-radius: 1em; 30 | content: ''!important; 31 | text-align: center; 32 | width: 1em; 33 | height: 1em; 34 | opacity: 1; 35 | transform: scale(.4555555); 36 | background: @primary-color; 37 | } 38 | } 39 | 40 | &.disabled { 41 | ._disabled; 42 | > label:before { 43 | background: #fdfdfd; 44 | } 45 | } 46 | 47 | input { 48 | opacity: 0!important; 49 | outline: 0; 50 | z-index: -1; 51 | } 52 | 53 | > label { 54 | display: block; 55 | cursor: pointer; 56 | line-height: 1.2; 57 | position: relative; 58 | height: 14px; 59 | 60 | &:hover { 61 | &:before { 62 | border-color: @primary-color; 63 | } 64 | } 65 | 66 | &:before { 67 | position: absolute; 68 | top: 0; 69 | left: 0; 70 | content: ''!important; 71 | background: #FFF; 72 | border-radius: 1em; 73 | transform: none; 74 | width: 1em; 75 | height: 1em; 76 | border: 1px solid #d9d9d9; 77 | } 78 | 79 | } 80 | 81 | } 82 | 83 | .@{css-prefix}.checkbox { 84 | &.active, &.open { 85 | > label:after { 86 | display: inline-block; 87 | font: normal normal normal 14px/1 FontAwesome; 88 | transform: scale(.8222); 89 | color: #fff; 90 | border-radius: @border-radius; 91 | } 92 | > label:before { 93 | background: @primary-color; 94 | } 95 | } 96 | &.active { 97 | > label:after { 98 | content: '\f00c' !important; 99 | } 100 | } 101 | 102 | &.open { 103 | > label:before { 104 | background: @primary-color; 105 | } 106 | } 107 | 108 | > label { 109 | &:before { 110 | border-radius: @border-radius; 111 | } 112 | } 113 | } 114 | 115 | .@{css-prefix}.checkboxes, .@{css-prefix}.radios { 116 | &.vertical { 117 | .checkbox, .radio { 118 | flex-direction: row; 119 | margin-bottom: .5em; 120 | } 121 | } 122 | &.horizontal { 123 | display: flex; 124 | flex-direction: row; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/styles/segment.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.segment { 4 | font-size: 1em; 5 | position: relative; 6 | background: #fff; 7 | .box-shadow; 8 | margin: 1em 0; 9 | .padding; 10 | border-radius: @border-radius; 11 | .border; 12 | 13 | .button { 14 | display: block; 15 | } 16 | 17 | &:last-child { 18 | margin-bottom: 0; 19 | } 20 | 21 | .segment-loop-color(@color-length); 22 | 23 | &.attached { 24 | border-radius: 0; 25 | margin: 0; 26 | box-shadow: none; 27 | 28 | &:not(.bottom) { 29 | border-bottom: none; 30 | } 31 | 32 | &.top { 33 | margin-top: 0; 34 | border-radius: @border-radius @border-radius 0 0; 35 | } 36 | &.bottom { 37 | margin-bottom: 1em; 38 | border-radius: 0 0 @border-radius @border-radius; 39 | } 40 | } 41 | 42 | &.floated { 43 | &.left { 44 | float: left; 45 | margin-left: 0; 46 | } 47 | &.right { 48 | float: right; 49 | margin-right: 0; 50 | } 51 | } 52 | 53 | &.aligned { 54 | &.left { 55 | text-align: left; 56 | } 57 | &.right { 58 | text-align: right; 59 | } 60 | &.center { 61 | text-align: center; 62 | } 63 | } 64 | 65 | &.basic { 66 | background: none transparent; 67 | box-shadow: none; 68 | border: none; 69 | border-radius: 0; 70 | } 71 | 72 | &.loading { 73 | .loading(3em, 0.325em); 74 | } 75 | 76 | .disabled; 77 | 78 | &.placeholder { 79 | display: flex; 80 | .flex-direction(column); 81 | .justify-content(center); 82 | .align-items(center); 83 | background: #f9fafb; 84 | min-height: 15em; 85 | max-width: initial; 86 | border-color: @border-color; 87 | padding: 1em; 88 | box-shadow: 0 2px 25px 0 @border-color inset; 89 | } 90 | 91 | &.vertical { 92 | margin: 0; 93 | padding-left: 0; 94 | padding-right: 0; 95 | background: none transparent; 96 | border-radius: 0; 97 | border: none; 98 | border-bottom: @border-style; 99 | box-shadow: none; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/styles/step.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.step { 4 | font-size: 1em; 5 | padding: 1em 1.2em; 6 | color: rgba(0,0,0,.87); 7 | vertical-align: middle; 8 | display: flex; 9 | flex: 1 0 auto; 10 | position: relative; 11 | align-items: center; 12 | justify-content: center; 13 | border-right: @border-style; 14 | .user-select(none); 15 | background: #ffffff; 16 | 17 | &.active { 18 | background: #F3F4F5; 19 | 20 | //> i { 21 | // color: @primary-color; 22 | //} 23 | 24 | > .content > .title { 25 | color: @primary-color; 26 | } 27 | } 28 | 29 | .disabled; 30 | 31 | > i { 32 | margin: 0 1rem 0 0; 33 | font-size: 2em; 34 | } 35 | 36 | > .content { 37 | display: block; 38 | flex: 0 1 auto; 39 | 40 | > .title { 41 | font-weight: 700; 42 | font-size: 1.2em; 43 | } 44 | > .description { 45 | margin-top: .25em; 46 | font-weight: 400; 47 | font-size: 1.1em; 48 | } 49 | } 50 | } 51 | 52 | .@{css-prefix}.steps { 53 | display: inline-flex; 54 | .border; 55 | border-radius: @border-radius; 56 | margin: .6em 0; 57 | 58 | &.vertical { 59 | display: flex; 60 | flex-direction: column; 61 | width: 100%; 62 | 63 | .step { 64 | justify-content: flex-start; 65 | border-right: none; 66 | border-bottom: @border-style; 67 | 68 | &:not(.active):after { 69 | display:none; 70 | } 71 | } 72 | } 73 | 74 | .step { 75 | &:after { 76 | position: absolute; 77 | z-index: 2; 78 | content: ''; 79 | top: 50%; 80 | right: 0; 81 | border: solid; 82 | background-color: #FFF; 83 | width: 1.14285714em; 84 | height: 1.14285714em; 85 | border-color: @border-color; 86 | border-width: 0 1px 1px 0; 87 | -webkit-transition: background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease; 88 | transition: background-color .1s ease,opacity .1s ease,color .1s ease,box-shadow .1s ease; 89 | -webkit-transform: translateY(-50%) translateX(50%) rotate(-45deg); 90 | transform: translateY(-50%) translateX(50%) rotate(-45deg); 91 | } 92 | &.active { 93 | &:after { 94 | background: #F3F4F5; 95 | } 96 | } 97 | 98 | &:last-child { 99 | border-right: none; 100 | 101 | &:after { 102 | //background: none; 103 | display:none; 104 | } 105 | } 106 | } 107 | 108 | // size 109 | .font-sizes; 110 | } 111 | -------------------------------------------------------------------------------- /src/styles/submenu.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.menu { 4 | .submenu { 5 | position: relative; 6 | 7 | &:after { 8 | position: absolute; 9 | right: @padding-horizontal; 10 | top: @padding-vertical; 11 | display: inline-block; 12 | font: normal normal normal 14px/1 FontAwesome; 13 | font-size: inherit; 14 | text-rendering: auto; 15 | -webkit-font-smoothing: antialiased; 16 | } 17 | 18 | .menu { 19 | font-size: inherit; 20 | } 21 | } 22 | 23 | &.horizontal .submenu { 24 | > .menu { 25 | position: absolute; 26 | top: @padding-vertical * 2 + 1.5; 27 | left: 0; 28 | //margin-top: 5px; 29 | } 30 | } 31 | 32 | &.vertical .submenu { 33 | &:after { 34 | content: "\f105"; 35 | } 36 | 37 | > .menu { 38 | position: absolute; 39 | left: 100%; 40 | top: -1px; 41 | margin-left: 5px; 42 | } 43 | } 44 | 45 | &.inline .submenu { 46 | padding: 0; 47 | 48 | &.item.active { 49 | border-right-color: @border-color; 50 | background-color: transparent; 51 | font-weight: 400; 52 | } 53 | &.item.active:after { 54 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; 55 | -webkit-transform:rotate(180deg); 56 | -ms-transform: rotate(180deg); 57 | transform: rotate(180deg); 58 | } 59 | &:after { 60 | content: "\f107"; 61 | } 62 | 63 | > .title { 64 | .padding; 65 | &:hover { 66 | background-color: @hover-background-color; 67 | } 68 | } 69 | > .menu { 70 | box-shadow: none; 71 | border: none; 72 | 73 | .item { 74 | margin-right: -3px; 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/styles/switch.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.switch { 4 | cursor: pointer; 5 | .user-select(none); 6 | font-size: @base-font-size; 7 | outline: 0; 8 | position: relative; 9 | height: @base-font-size + .5rem; 10 | width: auto; 11 | display: inline-block; 12 | padding-left: 4em; 13 | vertical-align: middle; 14 | 15 | .disabled; 16 | 17 | &.checked { 18 | &:before { 19 | background: @primary-color; 20 | } 21 | &:after { 22 | box-shadow: none; 23 | left: 2.15em; 24 | } 25 | } 26 | 27 | &:before { 28 | position: absolute; 29 | top: 0; 30 | left: 0; 31 | width: 3.5em; 32 | height: 1.5em; 33 | content: ''; 34 | background: #E0E1E2; 35 | border-radius: @border-radius; 36 | z-index: 1; 37 | } 38 | &:after { 39 | position: absolute; 40 | z-index: 2; 41 | top: .15em; 42 | left: .15em; 43 | width: 1.2em; 44 | height: 1.2em; 45 | content: ''; 46 | text-align: center; 47 | border-radius: @border-radius; 48 | background: #fff; 49 | box-shadow: 0px 0px 3px #aaa; 50 | transition: all 0.36s; 51 | } 52 | } -------------------------------------------------------------------------------- /src/styles/tabs.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.tabs { 4 | font-size: @base-font-size; 5 | background: #ffffff; 6 | 7 | &.-card { 8 | .border; 9 | .box-shadow; 10 | 11 | .nav { 12 | background: @hover-background-color; 13 | margin: 0; 14 | 15 | li { 16 | &:first-child { 17 | margin-left: -1px; 18 | } 19 | } 20 | 21 | &.top li { 22 | margin-top: -1px; 23 | } 24 | 25 | &.bottom li { 26 | margin-bottom: -1px; 27 | } 28 | } 29 | } 30 | 31 | &.-text { 32 | .nav { 33 | border-color: transparent!important; 34 | li { 35 | padding: .35714286em .5em; 36 | border-color: transparent!important; 37 | } 38 | } 39 | } 40 | 41 | &.-button { 42 | .nav { 43 | border: none!important; 44 | li { 45 | border: none!important; 46 | border-radius: @border-radius; 47 | margin: 0 .357em!important; 48 | 49 | &.active, &:hover { 50 | background-color: rgba(0,0,0,.05); 51 | } 52 | } 53 | } 54 | } 55 | 56 | .nav { 57 | padding: 0; 58 | margin: 0; 59 | display: -ms-flexbox; 60 | display: flex; 61 | -ms-flex-wrap: wrap; 62 | flex-wrap: wrap; 63 | list-style: none; 64 | 65 | &.center { 66 | justify-content: center; 67 | } 68 | 69 | li { 70 | .padding; 71 | cursor: pointer; 72 | border: 1px solid transparent; 73 | line-height: 1; 74 | 75 | &.active { 76 | .border; 77 | color: @active-color; 78 | background: #fff; 79 | font-weight: bold; 80 | } 81 | 82 | &:hover { 83 | color: @active-color; 84 | } 85 | } 86 | 87 | &.top { 88 | border-bottom: @border-style; 89 | li { 90 | margin-bottom: -1px; 91 | &.active { 92 | border-bottom-color: #fff; 93 | } 94 | } 95 | } 96 | &.bottom { 97 | border-top: @border-style; 98 | li { 99 | margin-top: -1px; 100 | &.active { 101 | border-top-color: #fff; 102 | } 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/styles/tag.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | @tag-font-size: @base-font-size - 0.15; 4 | 5 | .@{css-prefix}.tag { 6 | cursor: pointer; 7 | display: inline-block; 8 | line-height: 1em; 9 | font-size: @tag-font-size; 10 | vertical-align: baseline; 11 | background-color: #E8E8E8; 12 | background-image: none; 13 | padding: 0.5833em 0.833em; 14 | color: rgba(0, 0, 0, 0.6); 15 | text-transform: none; 16 | font-weight: bold; 17 | border: 0 solid transparent; 18 | border-radius: @border-radius; 19 | .transition(background 0.1s ease); 20 | .user-select(none); 21 | margin: 0em 0.5em 0.5em 0em; 22 | 23 | &:first-child { 24 | margin-left: 0; 25 | } 26 | &:last-child { 27 | margin-right: 0; 28 | } 29 | 30 | i { 31 | opacity: 0.8; 32 | margin-left: 0.5em; 33 | } 34 | 35 | &:not(.attached):hover { 36 | color: rgba(0, 0, 0, 0.8); 37 | background: rgba(0, 0, 0, 0.15); 38 | } 39 | 40 | &.circle { 41 | border-radius: 50em; 42 | } 43 | 44 | &.floating { 45 | position: absolute; 46 | top: -1em; 47 | left: 100%; 48 | margin: 0 0 0 -1em!important; 49 | padding: .4em .5em; 50 | } 51 | 52 | &.attached { 53 | position: absolute; 54 | padding: @input-padding; 55 | font-size: 1em; 56 | border-radius: 0; 57 | margin: 0; 58 | border: 1px solid transparent; 59 | z-index: 10; 60 | 61 | &.top, &.bottom { 62 | width: 100%; 63 | left: 0; 64 | &.left, &.right { 65 | width: auto; 66 | } 67 | &.right { 68 | right: 0; 69 | left: auto; 70 | } 71 | } 72 | 73 | &.top { 74 | top: 0; 75 | } 76 | &.bottom { 77 | bottom: 0; 78 | } 79 | } 80 | 81 | .colors; 82 | 83 | &.positive { 84 | .type-positive; 85 | } 86 | 87 | &.negative { 88 | .type-negative; 89 | } 90 | 91 | &.primary { 92 | .type-primary; 93 | } 94 | 95 | // size 96 | .font-sizes; 97 | } 98 | 99 | .@{css-prefix}.tags { 100 | input { 101 | font-size: @tag-font-size; 102 | outline: none; 103 | border: 1px solid rgba(34, 36, 38, 0.15); 104 | color: rgba(0, 0, 0, 0.6); 105 | background: #fff; 106 | padding: 0.3633em 0.633em; 107 | width: 100px; 108 | border-radius: @border-radius; 109 | } 110 | input:focus { 111 | border-color: #85B7D9; 112 | box-shadow: 0 0 0 2px rgba(16,142,233,.2); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/styles/time-picker.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | 3 | .@{css-prefix}.time-picker { 4 | 5 | .content { 6 | position: absolute; 7 | top: calc(~"100% + 5px"); 8 | left: 0; 9 | z-index: 10; 10 | 11 | .menu { 12 | display: inline-block; 13 | overflow: hidden; 14 | height: 210px; 15 | margin-left: -1px; 16 | width: 60px; 17 | 18 | .item { 19 | min-width: 60px; 20 | } 21 | 22 | &:first-child { 23 | margin-left: 0; 24 | } 25 | 26 | &:hover { 27 | overflow-y: auto; 28 | } 29 | } 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/styles/timeline.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.timeline { 4 | list-style: none; 5 | padding: 0; 6 | margin: 0; 7 | position: relative; 8 | 9 | &::before { 10 | top: 0; 11 | bottom: 0; 12 | position: absolute; 13 | content: " "; 14 | width: 3px; 15 | background-color: #dddddd; 16 | left: 20px; 17 | } 18 | 19 | .event { 20 | margin: 10px 0 10px 40px; 21 | .timeline-loop-color(@color-length); 22 | 23 | > .badge { 24 | border: 3px solid #fff; 25 | position: absolute; 26 | left: 13px; 27 | width: 17px; 28 | height: 17px; 29 | background: @primary-color; 30 | border-radius: 10em; 31 | } 32 | > .panel { 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/styles/transfer.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.transfer { 4 | line-height: 1em; 5 | font-size: @base-font-size; 6 | .user-select(none); 7 | 8 | .panel { 9 | .border; 10 | display: inline-block; 11 | border-radius: @border-radius; 12 | vertical-align: middle; 13 | 14 | > .header { 15 | padding: @transfer-padding; 16 | border-radius: @border-radius @border-radius 0 0; 17 | border-bottom: @border-style; 18 | overflow: hidden; 19 | background: @transfer-header-background-color; 20 | } 21 | 22 | > .body { 23 | overflow-y: auto; 24 | 25 | .item { 26 | overflow: hidden; 27 | white-space: nowrap; 28 | text-overflow: ellipsis; 29 | padding: @transfer-padding; 30 | .transition(all .3s); 31 | cursor: pointer; 32 | 33 | .disabled; 34 | 35 | &:hover, &.active { 36 | background: @transfer-item-hover-background-color; 37 | } 38 | } 39 | } 40 | } 41 | 42 | > .operation { 43 | display: inline-block; 44 | vertical-align: middle; 45 | margin: 0 1em; 46 | 47 | .button { 48 | display: block; 49 | margin-bottom: .6em; 50 | &:last-child { 51 | margin-bottom: 0; 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/styles/tree.less: -------------------------------------------------------------------------------- 1 | @import "./base.less"; 2 | 3 | .@{css-prefix}.tree { 4 | list-style: none; 5 | margin: 0; 6 | padding: 0; 7 | font-size: 1em; 8 | 9 | li { 10 | //height: 36px; 11 | line-height: 2em; 12 | white-space: nowrap; 13 | cursor: pointer; 14 | .user-select(none); 15 | // vertical-align: middle; 16 | 17 | .checkbox { 18 | display: inline-block; 19 | vertical-align: middle; 20 | } 21 | 22 | i { 23 | vertical-align: middle; 24 | text-align: center; 25 | padding: 0; 26 | .user-select(none); 27 | width: 1em; 28 | display: inline-block; 29 | } 30 | 31 | .title { 32 | padding: .2em .4em; 33 | &:hover { 34 | color: @hover-color; 35 | } 36 | } 37 | 38 | &.active { 39 | > .title { 40 | //font-weight: bold; 41 | background: #ecf6fd; 42 | //color: @active-color; 43 | } 44 | } 45 | 46 | } 47 | 48 | li > .@{css-prefix}.tree { 49 | padding-left: 1.5em; 50 | } 51 | } 52 | 53 | .@{css-prefix}.tree-select { 54 | 55 | > .content { 56 | box-shadow: 0 1px 5px rgba(0,0,0,.2); 57 | position: absolute; 58 | top: calc(~"100% + 5px"); 59 | left: 0; 60 | z-index: 10; 61 | background: #ffffff; 62 | min-width: 100%; 63 | height: 260px; 64 | overflow: auto; 65 | padding: 0 @input-padding-vertical; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/.gitkeep -------------------------------------------------------------------------------- /static/Datepicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/Datepicker.png -------------------------------------------------------------------------------- /static/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/button.png -------------------------------------------------------------------------------- /static/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/card.png -------------------------------------------------------------------------------- /static/form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/form.png -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/logo.png -------------------------------------------------------------------------------- /static/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/menu.png -------------------------------------------------------------------------------- /static/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/select.png -------------------------------------------------------------------------------- /static/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/table.png -------------------------------------------------------------------------------- /static/treeselect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myliang/fish-ui/4cfea162956eb66aa8b89d5475add04371a30b0e/static/treeselect.png --------------------------------------------------------------------------------