-
BIN.DS_Store
-
14.editorconfig
-
6.env.development
-
5.env.production
-
7.env.staging
-
4.eslintignore
-
197.eslintrc.js
-
23.gitignore
-
2README.md
-
23babel.config.js
-
1index.html
-
24jest.config.js
-
9jsconfig.json
-
71package.json
-
8postcss.config.js
-
0public/favicon.ico
-
17public/index.html
-
11src/App.vue
-
0src/api/index.js
-
BINsrc/assets/datapage_images/No1.png
-
BINsrc/assets/datapage_images/No1@2x.png
-
BINsrc/assets/datapage_images/No2.png
-
BINsrc/assets/datapage_images/No2@2x.png
-
BINsrc/assets/datapage_images/No3.png
-
BINsrc/assets/datapage_images/No3@2x.png
-
BINsrc/assets/layout_images/LOGO.png
-
BINsrc/assets/layout_images/LOGO@2x.png
-
BINsrc/assets/layout_images/LOGO@3x.png
-
BINsrc/assets/layout_images/MATRIX@2x.png
-
BINsrc/assets/layout_images/MATRIX备份.png
-
BINsrc/assets/layout_images/MATRIX备份@3x.png
-
0src/assets/login_img/login_bg.png
-
0src/assets/login_img/logo.png
-
0src/assets/registration_img/code.png
-
BINsrc/assets/registration_img/mail.png
-
0src/assets/workAvatar.png
-
0src/assets/workImg.png
-
BINsrc/assets/上传之后的图片备份.png
-
BINsrc/assets/上传之后的图片备份@2x.png
-
39src/components/Breadcrumb/index.vue
-
118src/components/ContainerBox/index.vue
-
128src/components/baseDetail/CompactDetailCard.vue
-
110src/components/baseDetail/TwoRowDetail.vue
-
0src/components/index.js
-
76src/components/menu/_util/clickoutside.js
-
368src/components/menu/_util/date.js
-
291src/components/menu/_util/dateUtil.js
-
229src/components/menu/_util/dom.js
-
43src/components/menu/_util/getRequestAnimationFrame.js
-
17src/components/menu/_util/getScroll.js
-
1src/components/menu/_util/icon.json
-
14src/components/menu/_util/merge.js
-
1257src/components/menu/_util/popper.js
-
218src/components/menu/_util/popup/index.js
-
194src/components/menu/_util/popup/popup-manager.js
-
7src/components/menu/_util/proptype.js
-
24src/components/menu/_util/repeatClick.js
-
33src/components/menu/_util/resizeEvent.js
-
27src/components/menu/_util/scrollIntoView.js
-
29src/components/menu/_util/scrollbar-width.js
-
35src/components/menu/_util/soda.js
-
8src/components/menu/_util/switchcase.js
-
47src/components/menu/_util/throttleByAnimationFrame.js
-
237src/components/menu/_util/tree/node.js
-
120src/components/menu/_util/tree/tree.js
-
141src/components/menu/_util/util.js
-
205src/components/menu/_util/vue-popper.js
-
13src/components/menu/index.js
-
95src/components/menu/menu-item.vue
-
79src/components/menu/menu-itemgroup.vue
-
158src/components/menu/menu-submenu.vue
-
165src/components/menu/menu.vue
-
2src/components/menu/style/index.js
-
717src/components/menu/style/index.less
-
108src/components/menu/style/style/color/bezierEasing.less
-
46src/components/menu/style/style/color/colorPalette.less
-
92src/components/menu/style/style/color/colors.less
-
1184src/components/menu/style/style/color/tinyColor.less
-
126src/components/menu/style/style/core/base.less
-
1181src/components/menu/style/style/core/icon/iconfont.css
-
0src/components/menu/style/style/core/icon/iconfont.eot
-
1src/components/menu/style/style/core/icon/iconfont.js
-
0src/components/menu/style/style/core/icon/iconfont.svg
-
0src/components/menu/style/style/core/icon/iconfont.ttf
-
0src/components/menu/style/style/core/icon/iconfont.woff
-
BINsrc/components/menu/style/style/core/icon/iconfont.woff2
-
2214src/components/menu/style/style/core/iconfont.less
-
4src/components/menu/style/style/core/index.less
-
15src/components/menu/style/style/core/motion.less
-
31src/components/menu/style/style/core/motion/fade.less
-
120src/components/menu/style/style/core/motion/move.less
-
10src/components/menu/style/style/core/motion/other.less
-
120src/components/menu/style/style/core/motion/slide.less
-
33src/components/menu/style/style/core/motion/swing.less
-
160src/components/menu/style/style/core/motion/zoom.less
-
447src/components/menu/style/style/core/normalize.less
-
1src/components/menu/style/style/index.js
-
2src/components/menu/style/style/index.less
-
16src/components/menu/style/style/mixins/clearfix.less
-
45src/components/menu/style/style/mixins/compatibility.less
@ -0,0 +1,14 @@ |
|||
# http://editorconfig.org |
|||
root = true |
|||
|
|||
[*] |
|||
charset = utf-8 |
|||
indent_style = space |
|||
indent_size = 2 |
|||
end_of_line = lf |
|||
insert_final_newline = true |
|||
trim_trailing_whitespace = true |
|||
|
|||
[*.md] |
|||
insert_final_newline = false |
|||
trim_trailing_whitespace = false |
@ -0,0 +1,6 @@ |
|||
ENV = 'development' |
|||
|
|||
# base api |
|||
VUE_APP_BASE_API = '/dev-api' |
|||
|
|||
VUE_CLI_BABEL_TRANSPILE_MODULES = true |
@ -0,0 +1,5 @@ |
|||
ENV = 'production' |
|||
|
|||
# base api |
|||
VUE_APP_BASE_API = '/prod-api' |
|||
|
@ -0,0 +1,7 @@ |
|||
NODE_ENV = production |
|||
|
|||
ENV = 'staging' |
|||
|
|||
# base api |
|||
VUE_APP_BASE_API = '/stage-api' |
|||
|
@ -0,0 +1,4 @@ |
|||
build/*.js |
|||
src/assets |
|||
public |
|||
dist |
@ -0,0 +1,197 @@ |
|||
module.exports = { |
|||
root: true, |
|||
parserOptions: { |
|||
parser: 'babel-eslint' |
|||
}, |
|||
env: { |
|||
browser: true, |
|||
node: true, |
|||
es6: true, |
|||
}, |
|||
extends: ['plugin:vue/essential', 'eslint:recommended'], |
|||
|
|||
rules: { |
|||
"vue/max-attributes-per-line": [2, { |
|||
"singleline": 10, |
|||
"multiline": { |
|||
"max": 1, |
|||
"allowFirstLine": false |
|||
} |
|||
}], |
|||
"vue/singleline-html-element-content-newline": "off", |
|||
"vue/multiline-html-element-content-newline": "off", |
|||
"vue/name-property-casing": ["error", "PascalCase"], |
|||
"vue/no-v-html": "off", |
|||
'accessor-pairs': 2, |
|||
'arrow-spacing': [2, { |
|||
'before': true, |
|||
'after': true |
|||
}], |
|||
'block-spacing': [2, 'always'], |
|||
'brace-style': [2, '1tbs', { |
|||
'allowSingleLine': true |
|||
}], |
|||
'camelcase': [0, { |
|||
'properties': 'always' |
|||
}], |
|||
'comma-dangle': [2, 'never'], |
|||
'comma-spacing': [2, { |
|||
'before': false, |
|||
'after': true |
|||
}], |
|||
'comma-style': [2, 'last'], |
|||
'constructor-super': 2, |
|||
'curly': [2, 'multi-line'], |
|||
'dot-location': [2, 'property'], |
|||
'eol-last': 2, |
|||
'eqeqeq': ["error", "always", { |
|||
"null": "ignore" |
|||
}], |
|||
'generator-star-spacing': [2, { |
|||
'before': true, |
|||
'after': true |
|||
}], |
|||
'handle-callback-err': [2, '^(err|error)$'], |
|||
'indent': [2, 2, { |
|||
'SwitchCase': 1 |
|||
}], |
|||
'jsx-quotes': [2, 'prefer-single'], |
|||
'key-spacing': [2, { |
|||
'beforeColon': false, |
|||
'afterColon': true |
|||
}], |
|||
'keyword-spacing': [2, { |
|||
'before': true, |
|||
'after': true |
|||
}], |
|||
'new-cap': [2, { |
|||
'newIsCap': true, |
|||
'capIsNew': false |
|||
}], |
|||
'new-parens': 2, |
|||
'no-array-constructor': 2, |
|||
'no-caller': 2, |
|||
'no-console': 'off', |
|||
'no-class-assign': 2, |
|||
'no-cond-assign': 2, |
|||
'no-const-assign': 2, |
|||
'no-control-regex': 0, |
|||
'no-delete-var': 2, |
|||
'no-dupe-args': 2, |
|||
'no-dupe-class-members': 2, |
|||
'no-dupe-keys': 2, |
|||
'no-duplicate-case': 2, |
|||
'no-empty-character-class': 2, |
|||
'no-empty-pattern': 2, |
|||
'no-eval': 2, |
|||
'no-ex-assign': 2, |
|||
'no-extend-native': 2, |
|||
'no-extra-bind': 2, |
|||
'no-extra-boolean-cast': 2, |
|||
'no-extra-parens': [2, 'functions'], |
|||
'no-fallthrough': 2, |
|||
'no-floating-decimal': 2, |
|||
'no-func-assign': 2, |
|||
'no-implied-eval': 2, |
|||
'no-inner-declarations': [2, 'functions'], |
|||
'no-invalid-regexp': 2, |
|||
'no-irregular-whitespace': 2, |
|||
'no-iterator': 2, |
|||
'no-label-var': 2, |
|||
'no-labels': [2, { |
|||
'allowLoop': false, |
|||
'allowSwitch': false |
|||
}], |
|||
'no-lone-blocks': 2, |
|||
'no-mixed-spaces-and-tabs': 2, |
|||
'no-multi-spaces': 2, |
|||
'no-multi-str': 2, |
|||
'no-multiple-empty-lines': [2, { |
|||
'max': 1 |
|||
}], |
|||
'no-native-reassign': 2, |
|||
'no-negated-in-lhs': 2, |
|||
'no-new-object': 2, |
|||
'no-new-require': 2, |
|||
'no-new-symbol': 2, |
|||
'no-new-wrappers': 2, |
|||
'no-obj-calls': 2, |
|||
'no-octal': 2, |
|||
'no-octal-escape': 2, |
|||
'no-path-concat': 2, |
|||
'no-proto': 2, |
|||
'no-redeclare': 2, |
|||
'no-regex-spaces': 2, |
|||
'no-return-assign': [2, 'except-parens'], |
|||
'no-self-assign': 2, |
|||
'no-self-compare': 2, |
|||
'no-sequences': 2, |
|||
'no-shadow-restricted-names': 2, |
|||
'no-spaced-func': 2, |
|||
'no-sparse-arrays': 2, |
|||
'no-this-before-super': 2, |
|||
'no-throw-literal': 2, |
|||
'no-trailing-spaces': 2, |
|||
'no-undef': 2, |
|||
'no-undef-init': 2, |
|||
'no-unexpected-multiline': 2, |
|||
'no-unmodified-loop-condition': 2, |
|||
'no-unneeded-ternary': [2, { |
|||
'defaultAssignment': false |
|||
}], |
|||
'no-unreachable': 2, |
|||
'no-unsafe-finally': 2, |
|||
'no-unused-vars': [2, { |
|||
'vars': 'all', |
|||
'args': 'none' |
|||
}], |
|||
'no-useless-call': 2, |
|||
'no-useless-computed-key': 2, |
|||
'no-useless-constructor': 2, |
|||
'no-useless-escape': 0, |
|||
'no-whitespace-before-property': 2, |
|||
'no-with': 2, |
|||
'one-var': [2, { |
|||
'initialized': 'never' |
|||
}], |
|||
'operator-linebreak': [2, 'after', { |
|||
'overrides': { |
|||
'?': 'before', |
|||
':': 'before' |
|||
} |
|||
}], |
|||
'padded-blocks': [2, 'never'], |
|||
'quotes': [2, 'single', { |
|||
'avoidEscape': true, |
|||
'allowTemplateLiterals': true |
|||
}], |
|||
'semi': [2, 'never'], |
|||
'semi-spacing': [2, { |
|||
'before': false, |
|||
'after': true |
|||
}], |
|||
'space-before-blocks': [2, 'always'], |
|||
'space-before-function-paren': [2, 'never'], |
|||
'space-in-parens': [2, 'never'], |
|||
'space-infix-ops': 2, |
|||
'space-unary-ops': [2, { |
|||
'words': true, |
|||
'nonwords': false |
|||
}], |
|||
'spaced-comment': [2, 'always', { |
|||
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] |
|||
}], |
|||
'template-curly-spacing': [2, 'never'], |
|||
'use-isnan': 2, |
|||
'valid-typeof': 2, |
|||
'wrap-iife': [2, 'any'], |
|||
'yield-star-spacing': [2, 'both'], |
|||
'yoda': [2, 'never'], |
|||
'prefer-const': 2, |
|||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, |
|||
'object-curly-spacing': [2, 'always', { |
|||
objectsInObjects: false |
|||
}], |
|||
'array-bracket-spacing': [2, 'never'] |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
.DS_Store |
|||
node_modules |
|||
/dist |
|||
tree.txt |
|||
|
|||
# local env files |
|||
.env.local |
|||
.env.*.local |
|||
|
|||
# Log files |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
pnpm-debug.log* |
|||
|
|||
# Editor directories and files |
|||
.idea |
|||
.vscode |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.sw? |
@ -0,0 +1,23 @@ |
|||
const plugins = [] |
|||
if (process.env.NODE_ENV === 'production') { |
|||
// 如果是生产环境,则自动清理掉打印的日志,但保留error 与 warn
|
|||
plugins.push([ |
|||
'transform-remove-console', |
|||
{ |
|||
// 保留 console.error 与 console.warn
|
|||
exclude: ['error'] |
|||
} |
|||
]) |
|||
} |
|||
plugins.push(['import', { |
|||
libraryName: 'vant', |
|||
libraryDirectory: 'es', |
|||
style: true |
|||
}, 'vant']) |
|||
|
|||
module.exports = { |
|||
presets: [ |
|||
'@vue/cli-plugin-babel/preset' |
|||
], |
|||
plugins |
|||
} |
@ -1 +0,0 @@ |
|||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=https://ape_card.gitee.io/matrix-template-vertical/favicon.ico><title>MATRIX MAGIC</title><link href=https://ape_card.gitee.io/matrix-template-vertical/static/css/chunk-mdsUI.css rel=stylesheet><link href=https://ape_card.gitee.io/matrix-template-vertical/static/css/chunk-libs.css rel=stylesheet><link href=https://ape_card.gitee.io/matrix-template-vertical/static/css/app.css rel=stylesheet></head><body><noscript><strong>We're sorry but MATRIX MAGIC doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=https://ape_card.gitee.io/matrix-template-vertical/static/js/runtime.js></script><script src=https://ape_card.gitee.io/matrix-template-vertical/static/js/chunk-mdsUI.js></script><script src=https://ape_card.gitee.io/matrix-template-vertical/static/js/chunk-libs.js></script><script src=https://ape_card.gitee.io/matrix-template-vertical/static/js/app.js></script></body></html> |
@ -0,0 +1,24 @@ |
|||
module.exports = { |
|||
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], |
|||
transform: { |
|||
'^.+\\.vue$': 'vue-jest', |
|||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': |
|||
'jest-transform-stub', |
|||
'^.+\\.jsx?$': 'babel-jest' |
|||
}, |
|||
moduleNameMapper: { |
|||
'^@/(.*)$': '<rootDir>/src/$1' |
|||
}, |
|||
snapshotSerializers: ['jest-serializer-vue'], |
|||
testMatch: [ |
|||
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' |
|||
], |
|||
collectCoverageFrom: ['src/utils/**/*.{js,vue}', 'src/components/**/*.{js,vue}'], |
|||
coverageDirectory: '<rootDir>/tests/unit/coverage', |
|||
// 'collectCoverage': true,
|
|||
'coverageReporters': [ |
|||
'lcov', |
|||
'text-summary' |
|||
], |
|||
testURL: 'http://localhost/' |
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"baseUrl": "./", |
|||
"paths": { |
|||
"@/*": ["src/*"] |
|||
} |
|||
}, |
|||
"exclude": ["node_modules", "dist"] |
|||
} |
@ -0,0 +1,71 @@ |
|||
{ |
|||
"name": "matrix-magic", |
|||
"version": "1.0.0", |
|||
"scripts": { |
|||
"start": "npm run dev", |
|||
"dev": "npm run serve", |
|||
"serve": "vue-cli-service serve", |
|||
"build": "npm run build:prod", |
|||
"build:prod": "vue-cli-service build", |
|||
"build:stage": "vue-cli-service build --mode staging", |
|||
"lint": "eslint --fix --ext .js,.vue src", |
|||
"test:unit": "jest --clearCache && vue-cli-service test:unit", |
|||
"test:ci": "npm run lint && npm run test:unit" |
|||
}, |
|||
"dependencies": { |
|||
"@babel/core": "^7.11.4", |
|||
"@bic-fe/mds-ui": "0.0.10", |
|||
"babel-loader": "^7.1.5", |
|||
"babel-register": "^6.26.0", |
|||
"echarts": "^4.8.0", |
|||
"normalize.css": "7.0.0", |
|||
"nprogress": "0.2.0", |
|||
"path-to-regexp": "2.4.0", |
|||
"vue": "2.6.10", |
|||
"vue-router": "3.0.6", |
|||
"vuex": "3.1.0" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "^7.11.4", |
|||
"@vue/cli-plugin-babel": "~4.4.0", |
|||
"@vue/cli-plugin-eslint": "~4.4.0", |
|||
"@vue/cli-plugin-unit-jest": "3.6.3", |
|||
"@vue/cli-service": "3.6.0", |
|||
"@vue/test-utils": "1.0.0-beta.29", |
|||
"autoprefixer": "^9.5.1", |
|||
"babel-eslint": "10.1.0", |
|||
"babel-jest": "23.6.0", |
|||
"babel-plugin-import": "^1.13.0", |
|||
"babel-plugin-transform-remove-console": "^6.9.4", |
|||
"chalk": "2.4.2", |
|||
"connect": "3.6.6", |
|||
"core-js": "3.6.4", |
|||
"eslint": "5.15.3", |
|||
"eslint-plugin-vue": "5.2.2", |
|||
"html-webpack-plugin": "3.2.0", |
|||
"less": "2.7.2", |
|||
"less-loader": "^6.2.0", |
|||
"lint-staged": "^9.5.0", |
|||
"runjs": "^4.3.2", |
|||
"sass": "^1.26.8", |
|||
"sass-loader": "^7.1.0", |
|||
"script-ext-html-webpack-plugin": "2.1.3", |
|||
"serve-static": "^1.13.2", |
|||
"vue-template-compiler": "2.6.10" |
|||
}, |
|||
"engines": { |
|||
"node": ">=8.9", |
|||
"npm": ">= 3.0.0" |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions" |
|||
], |
|||
"gitHooks": {}, |
|||
"lint-staged": { |
|||
"*.{js,jsx,vue}": [ |
|||
"vue-cli-service lint", |
|||
"git add" |
|||
] |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
// https://github.com/michael-ciniawsky/postcss-load-config
|
|||
|
|||
module.exports = { |
|||
'plugins': { |
|||
// to edit target browsers: use "browserslist" field in package.json
|
|||
'autoprefixer': {} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
|||
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
|||
<title><%= webpackConfig.name %></title> |
|||
</head> |
|||
<body> |
|||
<noscript> |
|||
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
|||
</noscript> |
|||
<div id="app"></div> |
|||
<!-- built files will be auto injected --> |
|||
</body> |
|||
</html> |
@ -0,0 +1,11 @@ |
|||
<template> |
|||
<div id="app"> |
|||
<router-view /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'App' |
|||
} |
|||
</script> |
After Width: 24 | Height: 19 | Size: 928 B |
After Width: 48 | Height: 38 | Size: 2.2 KiB |
After Width: 24 | Height: 20 | Size: 915 B |
After Width: 48 | Height: 40 | Size: 2.0 KiB |
After Width: 24 | Height: 20 | Size: 1.1 KiB |
After Width: 48 | Height: 40 | Size: 2.6 KiB |
After Width: 31 | Height: 32 | Size: 1.6 KiB |
After Width: 62 | Height: 64 | Size: 3.6 KiB |
After Width: 93 | Height: 96 | Size: 6.4 KiB |
After Width: 218 | Height: 28 | Size: 2.9 KiB |
After Width: 109 | Height: 14 | Size: 1.6 KiB |
After Width: 327 | Height: 42 | Size: 6.4 KiB |
Before Width: 2880 | Height: 1800 | Size: 4.8 MiB After Width: 2880 | Height: 1800 | Size: 4.8 MiB |
Before Width: 96 | Height: 96 | Size: 8.5 KiB After Width: 96 | Height: 96 | Size: 8.5 KiB |
Before Width: 154 | Height: 56 | Size: 21 KiB After Width: 154 | Height: 56 | Size: 21 KiB |
After Width: 96 | Height: 96 | Size: 2.9 KiB |
Before Width: 176 | Height: 176 | Size: 11 KiB After Width: 176 | Height: 176 | Size: 11 KiB |
Before Width: 218 | Height: 62 | Size: 11 KiB After Width: 218 | Height: 62 | Size: 11 KiB |
After Width: 267 | Height: 170 | Size: 2.4 KiB |
After Width: 534 | Height: 340 | Size: 6.4 KiB |
@ -0,0 +1,39 @@ |
|||
<template> |
|||
<div> |
|||
<mds-breadcrumb separator="/"> |
|||
<template v-for="(item, index) in levelList"> |
|||
<mds-breadcrumb-item |
|||
v-if="index !== (levelList.length - 1)" |
|||
:key="item.path" |
|||
:to="item.path" |
|||
>{{ item.meta.title }}</mds-breadcrumb-item> |
|||
<mds-breadcrumb-item :key="item.path" v-else>{{ item.meta.title }}</mds-breadcrumb-item> |
|||
</template> |
|||
</mds-breadcrumb> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
levelList: null |
|||
} |
|||
}, |
|||
watch: { |
|||
$route(route) { |
|||
this.getBreadcrumb() |
|||
} |
|||
}, |
|||
created() { |
|||
this.getBreadcrumb() |
|||
}, |
|||
methods: { |
|||
getBreadcrumb() { |
|||
// only show routes with meta.title |
|||
const matched = this.$route.matched.filter(item => item.meta && item.meta.title) |
|||
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,118 @@ |
|||
<template> |
|||
<div class="containerbox-wrapper"> |
|||
<mds-tabs v-model="active" ref="containerboxMdsTabs" :class="{'not-show': !showTabTitle}"> |
|||
<mds-tabs-pane tab="模版页" :index="1"> |
|||
<div class="containerbox-tab_item"> |
|||
<slot name="container" /> |
|||
</div> |
|||
</mds-tabs-pane> |
|||
<!-- <mds-tabs-pane tab="设计说明" :index="2"> |
|||
<div class="containerbox-tab_item"> |
|||
<slot name="info" /> |
|||
</div> |
|||
</mds-tabs-pane> --> |
|||
</mds-tabs> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'ContainerBox', |
|||
props: { |
|||
metaTitle: { |
|||
type: String, |
|||
required: true, |
|||
default: '' |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
active: 1, |
|||
showTabTitle: false |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.changeTabTitle() |
|||
setTimeout(() => { |
|||
this.showTabTitle = true |
|||
}, 300) |
|||
}, |
|||
methods: { |
|||
changeTabTitle() { |
|||
try { |
|||
this.$refs['containerboxMdsTabs'].$children[0].$el.setAttribute('data-star', this.metaTitle) |
|||
// eslint-disable-next-line no-empty |
|||
} catch {} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.containerbox-wrapper { |
|||
.not-show .mds-tabs-nav-container { |
|||
opacity: 0 !important; |
|||
} |
|||
.mds-tabs { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: flex-start; |
|||
align-items: flex-start; |
|||
.mds-tabs-bar { |
|||
position: relative; |
|||
width: 100%; |
|||
flex-shrink: 0; |
|||
background-color: #fff; |
|||
padding: 0 26px 8px 24px; |
|||
margin: 0; |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
border: none; |
|||
&::after { |
|||
content: attr(data-star); |
|||
position: absolute; |
|||
top: 40%; |
|||
left: 24px; |
|||
transform: translateY(-50%); |
|||
font-size: 20px; |
|||
font-weight: bold; |
|||
font-family:PingFangSC-Medium,PingFang SC; |
|||
color: #354052; |
|||
line-height: 28px; |
|||
} |
|||
} |
|||
.mds-tabs-content { |
|||
width: 100%; |
|||
// flex: 1; |
|||
// overflow: hidden; |
|||
height: calc(100% - 43px); |
|||
background-color: #F0F2F5; |
|||
.mds-tabs-tabpane { |
|||
box-sizing: border-box; |
|||
padding: 21px 24px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
<style lang="scss" scoped> |
|||
.containerbox-wrapper { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: flex-start; |
|||
align-items: flex-start; |
|||
.containerbox-tab_item { |
|||
width: 100%; |
|||
height: 100%; |
|||
min-height: 100%; |
|||
background-color: #fff; |
|||
border-radius: 4px; |
|||
overflow: auto; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,128 @@ |
|||
<template> |
|||
<div class="ComDetailCard"> |
|||
<div class="cardBox" v-for="(item,index) in formData" :key="index" :style="'width:'+item.pop"> |
|||
<div class="cardRow" v-if="!item.flag"> |
|||
<span class="labelBox"> |
|||
<span class="labelText">{{item.label}} </span> |
|||
|
|||
</span> |
|||
<span class="valueBox">{{item.value}}</span> |
|||
</div> |
|||
<div class="imgRowBox" v-if="item.flag"> |
|||
<span class="imglabelBox">{{item.label}}</span> |
|||
<span class="imgvalueBox"> |
|||
<img v-for="(i,index) in item.img_list" :style="'height:'+item.height+';width:'+item.width+';'" :key=index src="../../assets/上传之后的图片备份.png" alt=""> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
formData: { |
|||
type: Array, |
|||
default: () => |
|||
[{ |
|||
label: '姓 名:', |
|||
value: '经纬(jingwei01)', |
|||
color: '', |
|||
flag: false |
|||
}] |
|||
|
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
|
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.ComDetailCard{ |
|||
background:rgba(255,255,255,1); |
|||
height: 100%; |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
background:rgba(255,255,255,1); |
|||
.cardBox{ |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
padding: 16px 0 16px 0; |
|||
flex-direction: row; |
|||
flex-wrap: nowrap; |
|||
.cardRow{ |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
.labelBox{ |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
width: 50%; |
|||
.labelText{ |
|||
font-size:14px; |
|||
font-family:PingFangSC-Regular,PingFang SC; |
|||
font-weight:400; |
|||
color:rgba(127,143,164,1); |
|||
line-height:22px; |
|||
// width: 458px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
} |
|||
.valueBox{ |
|||
font-size:14px; |
|||
font-family:PingFangSC-Regular,PingFang SC; |
|||
font-weight:400; |
|||
color:rgba(53,64,82,1); |
|||
line-height:22px; |
|||
text-align: start; |
|||
width: 50%; |
|||
|
|||
} |
|||
} |
|||
|
|||
.imgRowBox{ |
|||
width: 100%; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
|
|||
.imglabelBox{ |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
align-items: flex-start; |
|||
padding-left: 24px; |
|||
font-size:14px; |
|||
font-family:PingFangSC-Regular,PingFang SC; |
|||
font-weight:400; |
|||
color:rgba(127,143,164,1); |
|||
line-height:22px; |
|||
width: 50%; |
|||
|
|||
} |
|||
.imgvalueBox{ |
|||
width: 50%; |
|||
display: flex; |
|||
justify-content:flex-start; |
|||
flex-wrap: wrap; |
|||
img{ |
|||
|
|||
// background: burlywood; |
|||
margin:20px 16px 0px 16px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,110 @@ |
|||
<template> |
|||
<div class="trDetail"> |
|||
<div class="rowBox" v-for="(item,index) in formData" :key="index" :style="'width:'+item.pop"> |
|||
<div v-if="!item.flag"> |
|||
<span class="labelBox">{{item.label}}</span> |
|||
<span class="valueBox">{{item.value}}</span> |
|||
</div> |
|||
<div class="imgRowBox" v-if="item.flag"> |
|||
<span class="imglabelBox">{{item.label}}</span> |
|||
<span class="imgvalueBox"> |
|||
<img v-for="(i,index) in item.img_list" :style="'height:'+item.height+';width:'+item.width+';'" :key=index src="../../assets/上传之后的图片备份.png" alt=""> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
formData: { |
|||
type: Array, |
|||
default: () => |
|||
[{ |
|||
label: '姓 名:', |
|||
value: '经纬(jingwei01)', |
|||
color: '', |
|||
flag: false |
|||
}] |
|||
|
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.trDetail{ |
|||
height: 100%; |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
background:rgba(255,255,255,1); |
|||
div:nth-child(even) |
|||
{ |
|||
border-left: 1px solid rgba(240,242,245,1); |
|||
} |
|||
.rowBox{ |
|||
width: 50%; |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
border-bottom: 1px solid rgba(240,242,245,1); |
|||
padding: 17px 0 17px 0; |
|||
flex-direction: row; |
|||
.labelBox{ |
|||
padding-left: 24px; |
|||
font-size:14px; |
|||
font-family:PingFangSC-Regular,PingFang SC; |
|||
font-weight:400; |
|||
color:rgba(127,143,164,1); |
|||
line-height:22px; |
|||
width: 76px; |
|||
overflow: hidden; |
|||
text-overflow:ellipsis; |
|||
white-space: nowrap; |
|||
|
|||
} |
|||
.valueBox{ |
|||
font-size:14px; |
|||
font-family:PingFangSC-Regular,PingFang SC; |
|||
font-weight:400; |
|||
color:rgba(53,64,82,1); |
|||
line-height:22px; |
|||
text-align: start; |
|||
|
|||
} |
|||
.imgRowBox{ |
|||
display: flex; |
|||
flex-direction: row; |
|||
|
|||
.imglabelBox{ |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: flex-start; |
|||
padding-left: 24px; |
|||
font-size:14px; |
|||
font-family:PingFangSC-Regular,PingFang SC; |
|||
font-weight:400; |
|||
color:rgba(127,143,164,1); |
|||
line-height:22px; |
|||
width: 102px; |
|||
|
|||
} |
|||
.imgvalueBox{ |
|||
display: flex; |
|||
justify-content:flex-start; |
|||
flex-wrap: wrap; |
|||
img{ |
|||
|
|||
// background: burlywood; |
|||
margin:20px 16px 0px 16px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,76 @@ |
|||
import Vue from 'vue' |
|||
import { on } from './dom.js' |
|||
|
|||
const nodeList = [] |
|||
const ctx = '@@clickoutsideContext' |
|||
|
|||
let startClick |
|||
let seed = 0 |
|||
|
|||
!Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e)) |
|||
|
|||
!Vue.prototype.$isServer && on(document, 'mouseup', e => { |
|||
nodeList.forEach(node => node[ctx].documentHandler(e, startClick)) |
|||
}) |
|||
|
|||
function createDocumentHandler(el, binding, vnode) { |
|||
return function(mouseup = {}, mousedown = {}) { |
|||
if (!vnode || |
|||
!vnode.context || |
|||
!mouseup.target || |
|||
!mousedown.target || |
|||
el.contains(mouseup.target) || |
|||
el.contains(mousedown.target) || |
|||
el === mouseup.target || |
|||
(vnode.context.popperElm && |
|||
(vnode.context.popperElm.contains(mouseup.target) || |
|||
vnode.context.popperElm.contains(mousedown.target)))) return |
|||
|
|||
if (binding.expression && |
|||
el[ctx].methodName && |
|||
vnode.context[el[ctx].methodName]) { |
|||
vnode.context[el[ctx].methodName]() |
|||
} else { |
|||
el[ctx].bindingFn && el[ctx].bindingFn() |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* v-clickoutside |
|||
* @desc 点击元素外面才会触发的事件 |
|||
* @example |
|||
* ```vue
|
|||
* <div v-element-clickoutside="handleClose"> |
|||
* ```
|
|||
*/ |
|||
export default { |
|||
bind(el, binding, vnode) { |
|||
nodeList.push(el) |
|||
const id = seed++ |
|||
el[ctx] = { |
|||
id, |
|||
documentHandler: createDocumentHandler(el, binding, vnode), |
|||
methodName: binding.expression, |
|||
bindingFn: binding.value |
|||
} |
|||
}, |
|||
|
|||
update(el, binding, vnode) { |
|||
el[ctx].documentHandler = createDocumentHandler(el, binding, vnode) |
|||
el[ctx].methodName = binding.expression |
|||
el[ctx].bindingFn = binding.value |
|||
}, |
|||
|
|||
unbind(el) { |
|||
const len = nodeList.length |
|||
|
|||
for (let i = 0; i < len; i++) { |
|||
if (nodeList[i][ctx].id === el[ctx].id) { |
|||
nodeList.splice(i, 1) |
|||
break |
|||
} |
|||
} |
|||
delete el[ctx] |
|||
} |
|||
} |
@ -0,0 +1,368 @@ |
|||
/* Modified from https://github.com/taylorhakes/fecha |
|||
* |
|||
* The MIT License (MIT) |
|||
* |
|||
* Copyright (c) 2015 Taylor Hakes |
|||
* |
|||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* of this software and associated documentation files (the "Software"), to deal |
|||
* in the Software without restriction, including without limitation the rights |
|||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
* copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
|||
* The above copyright notice and this permission notice shall be included in all |
|||
* copies or substantial portions of the Software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
* SOFTWARE. |
|||
*/ |
|||
|
|||
/*eslint-disable*/ |
|||
// 把 YYYY-MM-DD 改成了 yyyy-MM-dd
|
|||
(function (main) { |
|||
'use strict' |
|||
|
|||
/** |
|||
* Parse or format dates |
|||
* @class fecha |
|||
*/ |
|||
var fecha = {} |
|||
var token = /d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g |
|||
var twoDigits = '\\d\\d?' |
|||
var threeDigits = '\\d{3}' |
|||
var fourDigits = '\\d{4}' |
|||
var word = '[^\\s]+' |
|||
var literal = /\[([^]*?)\]/gm |
|||
var noop = function () { |
|||
} |
|||
|
|||
function regexEscape(str) { |
|||
return str.replace( /[|\\{()[^$+*?.-]/g, '\\$&') |
|||
} |
|||
|
|||
function shorten(arr, sLen) { |
|||
var newArr = [] |
|||
for (var i = 0, len = arr.length; i < len; i++) { |
|||
newArr.push(arr[i].substr(0, sLen)) |
|||
} |
|||
return newArr |
|||
} |
|||
|
|||
function monthUpdate(arrName) { |
|||
return function (d, v, i18n) { |
|||
var index = i18n[arrName].indexOf(v.charAt(0).toUpperCase() + v.substr(1).toLowerCase()) |
|||
if (~index) { |
|||
d.month = index |
|||
} |
|||
} |
|||
} |
|||
|
|||
function pad(val, len) { |
|||
val = String(val) |
|||
len = len || 2 |
|||
while (val.length < len) { |
|||
val = '0' + val |
|||
} |
|||
return val |
|||
} |
|||
|
|||
var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] |
|||
var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] |
|||
var monthNamesShort = shorten(monthNames, 3) |
|||
var dayNamesShort = shorten(dayNames, 3) |
|||
fecha.i18n = { |
|||
dayNamesShort: dayNamesShort, |
|||
dayNames: dayNames, |
|||
monthNamesShort: monthNamesShort, |
|||
monthNames: monthNames, |
|||
amPm: ['am', 'pm'], |
|||
DoFn: function DoFn(D) { |
|||
return D + ['th', 'st', 'nd', 'rd'][D % 10 > 3 ? 0 : (D - D % 10 !== 10) * D % 10] |
|||
} |
|||
} |
|||
|
|||
var formatFlags = { |
|||
D: function(dateObj) { |
|||
return dateObj.getDay() |
|||
}, |
|||
DD: function(dateObj) { |
|||
return pad(dateObj.getDay()) |
|||
}, |
|||
Do: function(dateObj, i18n) { |
|||
return i18n.DoFn(dateObj.getDate()) |
|||
}, |
|||
d: function(dateObj) { |
|||
return dateObj.getDate() |
|||
}, |
|||
dd: function(dateObj) { |
|||
return pad(dateObj.getDate()) |
|||
}, |
|||
ddd: function(dateObj, i18n) { |
|||
return i18n.dayNamesShort[dateObj.getDay()] |
|||
}, |
|||
dddd: function(dateObj, i18n) { |
|||
return i18n.dayNames[dateObj.getDay()] |
|||
}, |
|||
M: function(dateObj) { |
|||
return dateObj.getMonth() + 1 |
|||
}, |
|||
MM: function(dateObj) { |
|||
return pad(dateObj.getMonth() + 1) |
|||
}, |
|||
MMM: function(dateObj, i18n) { |
|||
return i18n.monthNamesShort[dateObj.getMonth()] |
|||
}, |
|||
MMMM: function(dateObj, i18n) { |
|||
return i18n.monthNames[dateObj.getMonth()] |
|||
}, |
|||
yy: function(dateObj) { |
|||
return pad(String(dateObj.getFullYear()), 4).substr(2) |
|||
}, |
|||
yyyy: function(dateObj) { |
|||
return pad(dateObj.getFullYear(), 4) |
|||
}, |
|||
h: function(dateObj) { |
|||
return dateObj.getHours() % 12 || 12 |
|||
}, |
|||
hh: function(dateObj) { |
|||
return pad(dateObj.getHours() % 12 || 12) |
|||
}, |
|||
H: function(dateObj) { |
|||
return dateObj.getHours() |
|||
}, |
|||
HH: function(dateObj) { |
|||
return pad(dateObj.getHours()) |
|||
}, |
|||
m: function(dateObj) { |
|||
return dateObj.getMinutes() |
|||
}, |
|||
mm: function(dateObj) { |
|||
return pad(dateObj.getMinutes()) |
|||
}, |
|||
s: function(dateObj) { |
|||
return dateObj.getSeconds() |
|||
}, |
|||
ss: function(dateObj) { |
|||
return pad(dateObj.getSeconds()) |
|||
}, |
|||
S: function(dateObj) { |
|||
return Math.round(dateObj.getMilliseconds() / 100) |
|||
}, |
|||
SS: function(dateObj) { |
|||
return pad(Math.round(dateObj.getMilliseconds() / 10), 2) |
|||
}, |
|||
SSS: function(dateObj) { |
|||
return pad(dateObj.getMilliseconds(), 3) |
|||
}, |
|||
a: function(dateObj, i18n) { |
|||
return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1] |
|||
}, |
|||
A: function(dateObj, i18n) { |
|||
return dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase() |
|||
}, |
|||
ZZ: function(dateObj) { |
|||
var o = dateObj.getTimezoneOffset() |
|||
return (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4) |
|||
} |
|||
} |
|||
|
|||
var parseFlags = { |
|||
d: [twoDigits, function (d, v) { |
|||
d.day = v |
|||
}], |
|||
Do: [twoDigits + word, function (d, v) { |
|||
d.day = parseInt(v, 10) |
|||
}], |
|||
M: [twoDigits, function (d, v) { |
|||
d.month = v - 1 |
|||
}], |
|||
yy: [twoDigits, function (d, v) { |
|||
var da = new Date(), cent = +('' + da.getFullYear()).substr(0, 2) |
|||
d.year = '' + (v > 68 ? cent - 1 : cent) + v |
|||
}], |
|||
h: [twoDigits, function (d, v) { |
|||
d.hour = v |
|||
}], |
|||
m: [twoDigits, function (d, v) { |
|||
d.minute = v |
|||
}], |
|||
s: [twoDigits, function (d, v) { |
|||
d.second = v |
|||
}], |
|||
yyyy: [fourDigits, function (d, v) { |
|||
d.year = v |
|||
}], |
|||
S: ['\\d', function (d, v) { |
|||
d.millisecond = v * 100 |
|||
}], |
|||
SS: ['\\d{2}', function (d, v) { |
|||
d.millisecond = v * 10 |
|||
}], |
|||
SSS: [threeDigits, function (d, v) { |
|||
d.millisecond = v |
|||
}], |
|||
D: [twoDigits, noop], |
|||
ddd: [word, noop], |
|||
MMM: [word, monthUpdate('monthNamesShort')], |
|||
MMMM: [word, monthUpdate('monthNames')], |
|||
a: [word, function (d, v, i18n) { |
|||
var val = v.toLowerCase() |
|||
if (val === i18n.amPm[0]) { |
|||
d.isPm = false |
|||
} else if (val === i18n.amPm[1]) { |
|||
d.isPm = true |
|||
} |
|||
}], |
|||
ZZ: ['[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z', function (d, v) { |
|||
var parts = (v + '').match(/([+-]|\d\d)/gi), minutes |
|||
|
|||
if (parts) { |
|||
minutes = +(parts[1] * 60) + parseInt(parts[2], 10) |
|||
d.timezoneOffset = parts[0] === '+' ? minutes : -minutes |
|||
} |
|||
}] |
|||
} |
|||
parseFlags.dd = parseFlags.d |
|||
parseFlags.dddd = parseFlags.ddd |
|||
parseFlags.DD = parseFlags.D |
|||
parseFlags.mm = parseFlags.m |
|||
parseFlags.hh = parseFlags.H = parseFlags.HH = parseFlags.h |
|||
parseFlags.MM = parseFlags.M |
|||
parseFlags.ss = parseFlags.s |
|||
parseFlags.A = parseFlags.a |
|||
|
|||
|
|||
// Some common format strings
|
|||
fecha.masks = { |
|||
default: 'ddd MMM dd yyyy HH:mm:ss', |
|||
shortDate: 'M/D/yy', |
|||
mediumDate: 'MMM d, yyyy', |
|||
longDate: 'MMMM d, yyyy', |
|||
fullDate: 'dddd, MMMM d, yyyy', |
|||
shortTime: 'HH:mm', |
|||
mediumTime: 'HH:mm:ss', |
|||
longTime: 'HH:mm:ss.SSS' |
|||
} |
|||
|
|||
/*** |
|||
* Format a date |
|||
* @method format |
|||
* @param {Date|number} dateObj |
|||
* @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate' |
|||
*/ |
|||
fecha.format = function (dateObj, mask, i18nSettings) { |
|||
var i18n = i18nSettings || fecha.i18n |
|||
|
|||
if (typeof dateObj === 'number') { |
|||
dateObj = new Date(dateObj) |
|||
} |
|||
|
|||
if (Object.prototype.toString.call(dateObj) !== '[object Date]' || isNaN(dateObj.getTime())) { |
|||
throw new Error('Invalid Date in fecha.format') |
|||
} |
|||
|
|||
mask = fecha.masks[mask] || mask || fecha.masks['default'] |
|||
|
|||
var literals = [] |
|||
|
|||
// Make literals inactive by replacing them with ??
|
|||
mask = mask.replace(literal, function($0, $1) { |
|||
literals.push($1) |
|||
return '@@@' |
|||
}) |
|||
// Apply formatting rules
|
|||
mask = mask.replace(token, function ($0) { |
|||
return $0 in formatFlags ? formatFlags[$0](dateObj, i18n) : $0.slice(1, $0.length - 1) |
|||
}) |
|||
// Inline literal values back into the formatted value
|
|||
return mask.replace(/@@@/g, function() { |
|||
return literals.shift() |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* Parse a date string into an object, changes - into / |
|||
* @method parse |
|||
* @param {string} dateStr Date string |
|||
* @param {string} format Date parse format |
|||
* @returns {Date|boolean} |
|||
*/ |
|||
fecha.parse = function (dateStr, format, i18nSettings) { |
|||
var i18n = i18nSettings || fecha.i18n |
|||
|
|||
if (typeof format !== 'string') { |
|||
throw new Error('Invalid format in fecha.parse') |
|||
} |
|||
|
|||
format = fecha.masks[format] || format |
|||
|
|||
// Avoid regular expression denial of service, fail early for really long strings
|
|||
// https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
|
|||
if (dateStr.length > 1000) { |
|||
return null |
|||
} |
|||
|
|||
var dateInfo = {} |
|||
var parseInfo = [] |
|||
var literals = [] |
|||
format = format.replace(literal, function($0, $1) { |
|||
literals.push($1) |
|||
return '@@@' |
|||
}) |
|||
var newFormat = regexEscape(format).replace(token, function ($0) { |
|||
if (parseFlags[$0]) { |
|||
var info = parseFlags[$0] |
|||
parseInfo.push(info[1]) |
|||
return '(' + info[0] + ')' |
|||
} |
|||
|
|||
return $0 |
|||
}) |
|||
newFormat = newFormat.replace(/@@@/g, function() { |
|||
return literals.shift() |
|||
}) |
|||
var matches = dateStr.match(new RegExp(newFormat, 'i')) |
|||
if (!matches) { |
|||
return null |
|||
} |
|||
|
|||
for (var i = 1; i < matches.length; i++) { |
|||
parseInfo[i - 1](dateInfo, matches[i], i18n) |
|||
} |
|||
|
|||
var today = new Date() |
|||
if (dateInfo.isPm === true && dateInfo.hour != null && +dateInfo.hour !== 12) { |
|||
dateInfo.hour = +dateInfo.hour + 12 |
|||
} else if (dateInfo.isPm === false && +dateInfo.hour === 12) { |
|||
dateInfo.hour = 0 |
|||
} |
|||
|
|||
var date |
|||
if (dateInfo.timezoneOffset != null) { |
|||
dateInfo.minute = +(dateInfo.minute || 0) - +dateInfo.timezoneOffset |
|||
date = new Date(Date.UTC(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, |
|||
dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0)) |
|||
} else { |
|||
date = new Date(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, |
|||
dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0) |
|||
} |
|||
return date |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
if (typeof module !== 'undefined' && module.exports) { |
|||
module.exports = fecha |
|||
} else if (typeof define === 'function' && define.amd) { |
|||
define(function () { |
|||
return fecha |
|||
}) |
|||
} else { |
|||
main.fecha = fecha |
|||
} |
|||
})(this) |
@ -0,0 +1,291 @@ |
|||
import fecha from './date.js' |
|||
|
|||
const weeks = ['日', '一', '二', '三', '四', '五', '六'] |
|||
const months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'] |
|||
|
|||
const newArray = function(start, end) { |
|||
const result = [] |
|||
for (let i = start; i <= end; i++) { |
|||
result.push(i) |
|||
} |
|||
return result |
|||
} |
|||
|
|||
export const getI18nSettings = () => { |
|||
return { |
|||
dayNamesShort: weeks, |
|||
dayNames: weeks, |
|||
monthNamesShort: months, |
|||
monthNames: months, |
|||
amPm: ['am', 'pm'] |
|||
} |
|||
} |
|||
|
|||
export const toDate = function(date) { |
|||
return isDate(date) ? new Date(date) : null |
|||
} |
|||
|
|||
export const isDate = function(date) { |
|||
if (date === null || date === undefined) return false |
|||
if (isNaN(new Date(date).getTime())) return false |
|||
if (Array.isArray(date)) return false // deal with `new Date([ new Date() ]) -> new Date()`
|
|||
return true |
|||
} |
|||
|
|||
export const isDateObject = function(val) { |
|||
return val instanceof Date |
|||
} |
|||
|
|||
export const formatDate = function(date, format) { |
|||
date = toDate(date) |
|||
if (!date) return '' |
|||
return fecha.format(date, format || 'yyyy-MM-dd', getI18nSettings()) |
|||
} |
|||
|
|||
export const parseDate = function(string, format) { |
|||
return fecha.parse(string, format || 'yyyy-MM-dd', getI18nSettings()) |
|||
} |
|||
|
|||
export const getDayCountOfMonth = function(year, month) { |
|||
if (month === 3 || month === 5 || month === 8 || month === 10) { |
|||
return 30 |
|||
} |
|||
|
|||
if (month === 1) { |
|||
if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) { |
|||
return 29 |
|||
} else { |
|||
return 28 |
|||
} |
|||
} |
|||
|
|||
return 31 |
|||
} |
|||
|
|||
export const getDayCountOfYear = function(year) { |
|||
const isLeapYear = year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0) |
|||
return isLeapYear ? 366 : 365 |
|||
} |
|||
|
|||
export const getFirstDayOfMonth = function(date) { |
|||
const temp = new Date(date.getTime()) |
|||
temp.setDate(1) |
|||
return temp.getDay() |
|||
} |
|||
|
|||
// see: https://stackoverflow.com/questions/3674539/incrementing-a-date-in-javascript
|
|||
// {prev, next} Date should work for Daylight Saving Time
|
|||
// Adding 24 * 60 * 60 * 1000 does not work in the above scenario
|
|||
export const prevDate = function(date, amount = 1) { |
|||
return new Date(date.getFullYear(), date.getMonth(), date.getDate() - amount) |
|||
} |
|||
|
|||
export const nextDate = function(date, amount = 1) { |
|||
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount) |
|||
} |
|||
|
|||
export const getStartDateOfMonth = function(year, month) { |
|||
const result = new Date(year, month, 1) |
|||
const day = result.getDay() |
|||
|
|||
if (day === 0) { |
|||
return prevDate(result, 7) |
|||
} else { |
|||
return prevDate(result, day) |
|||
} |
|||
} |
|||
|
|||
export const getWeekNumber = function(src) { |
|||
if (!isDate(src)) return null |
|||
const date = new Date(src.getTime()) |
|||
date.setHours(0, 0, 0, 0) |
|||
// Thursday in current week decides the year.
|
|||
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7) |
|||
// January 4 is always in week 1.
|
|||
const week1 = new Date(date.getFullYear(), 0, 4) |
|||
// Adjust to Thursday in week 1 and count number of weeks from date to week 1.
|
|||
// Rounding should be fine for Daylight Saving Time. Its shift should never be more than 12 hours.
|
|||
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7) |
|||
} |
|||
|
|||
export const getRangeHours = function(ranges = []) { |
|||
const hours = [] |
|||
let disabledHours = [] |
|||
|
|||
ranges.forEach(range => { |
|||
const value = range.map(date => date.getHours()) |
|||
|
|||
disabledHours = disabledHours.concat(newArray(value[0], value[1])) |
|||
}) |
|||
|
|||
if (disabledHours.length) { |
|||
for (let i = 0; i < 24; i++) { |
|||
hours[i] = disabledHours.indexOf(i) === -1 |
|||
} |
|||
} else { |
|||
for (let i = 0; i < 24; i++) { |
|||
hours[i] = false |
|||
} |
|||
} |
|||
|
|||
return hours |
|||
} |
|||
|
|||
export const getPrevMonthLastDays = (date, amount) => { |
|||
if (amount <= 0) return [] |
|||
const temp = new Date(date.getTime()) |
|||
temp.setDate(0) |
|||
const lastDay = temp.getDate() |
|||
return range(amount).map((_, index) => lastDay - (amount - index - 1)) |
|||
} |
|||
|
|||
export const getMonthDays = (date) => { |
|||
const temp = new Date(date.getFullYear(), date.getMonth() + 1, 0) |
|||
const days = temp.getDate() |
|||
return range(days).map((_, index) => index + 1) |
|||
} |
|||
|
|||
function setRangeData(arr, start, end, value) { |
|||
for (let i = start; i < end; i++) { |
|||
arr[i] = value |
|||
} |
|||
} |
|||
|
|||
export const getRangeMinutes = function(ranges, hour) { |
|||
const minutes = new Array(60) |
|||
|
|||
if (ranges.length > 0) { |
|||
ranges.forEach(range => { |
|||
const start = range[0] |
|||
const end = range[1] |
|||
const startHour = start.getHours() |
|||
const startMinute = start.getMinutes() |
|||
const endHour = end.getHours() |
|||
const endMinute = end.getMinutes() |
|||
if (startHour === hour && endHour !== hour) { |
|||
setRangeData(minutes, startMinute, 60, true) |
|||
} else if (startHour === hour && endHour === hour) { |
|||
setRangeData(minutes, startMinute, endMinute + 1, true) |
|||
} else if (startHour !== hour && endHour === hour) { |
|||
setRangeData(minutes, 0, endMinute + 1, true) |
|||
} else if (startHour < hour && endHour > hour) { |
|||
setRangeData(minutes, 0, 60, true) |
|||
} |
|||
}) |
|||
} else { |
|||
setRangeData(minutes, 0, 60, true) |
|||
} |
|||
return minutes |
|||
} |
|||
|
|||
export const range = function(n) { |
|||
// see https://stackoverflow.com/questions/3746725/create-a-javascript-array-containing-1-n
|
|||
return Array.apply(null, { length: n }).map((_, n) => n) |
|||
} |
|||
|
|||
export const modifyDate = function(date, y, m, d) { |
|||
return new Date(y, m, d, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()) |
|||
} |
|||
|
|||
export const modifyTime = function(date, h, m, s) { |
|||
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), h, m, s, date.getMilliseconds()) |
|||
} |
|||
|
|||
export const modifyWithTimeString = (date, time) => { |
|||
if (date == null || !time) { |
|||
return date |
|||
} |
|||
time = parseDate(time, 'HH:mm:ss') |
|||
return modifyTime(date, time.getHours(), time.getMinutes(), time.getSeconds()) |
|||
} |
|||
|
|||
export const clearTime = function(date) { |
|||
return new Date(date.getFullYear(), date.getMonth(), date.getDate()) |
|||
} |
|||
|
|||
export const clearMilliseconds = function(date) { |
|||
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0) |
|||
} |
|||
|
|||
export const limitTimeRange = function(date, ranges, format = 'HH:mm:ss') { |
|||
// TODO: refactory a more elegant solution
|
|||
if (ranges.length === 0) return date |
|||
const normalizeDate = date => fecha.parse(fecha.format(date, format), format) |
|||
const ndate = normalizeDate(date) |
|||
const nranges = ranges.map(range => range.map(normalizeDate)) |
|||
if (nranges.some(nrange => ndate >= nrange[0] && ndate <= nrange[1])) return date |
|||
|
|||
let minDate = nranges[0][0] |
|||
let maxDate = nranges[0][0] |
|||
|
|||
nranges.forEach(nrange => { |
|||
minDate = new Date(Math.min(nrange[0], minDate)) |
|||
maxDate = new Date(Math.max(nrange[1], minDate)) |
|||
}) |
|||
|
|||
const ret = ndate < minDate ? minDate : maxDate |
|||
// preserve Year/Month/Date
|
|||
return modifyDate( |
|||
ret, |
|||
date.getFullYear(), |
|||
date.getMonth(), |
|||
date.getDate() |
|||
) |
|||
} |
|||
|
|||
export const timeWithinRange = function(date, selectableRange, format) { |
|||
const limitedDate = limitTimeRange(date, selectableRange, format) |
|||
return limitedDate.getTime() === date.getTime() |
|||
} |
|||
|
|||
export const changeYearMonthAndClampDate = function(date, year, month) { |
|||
// clamp date to the number of days in `year`, `month`
|
|||
// eg: (2010-1-31, 2010, 2) => 2010-2-28
|
|||
const monthDate = Math.min(date.getDate(), getDayCountOfMonth(year, month)) |
|||
return modifyDate(date, year, month, monthDate) |
|||
} |
|||
|
|||
export const prevMonth = function(date) { |
|||
const year = date.getFullYear() |
|||
const month = date.getMonth() |
|||
return month === 0 |
|||
? changeYearMonthAndClampDate(date, year - 1, 11) |
|||
: changeYearMonthAndClampDate(date, year, month - 1) |
|||
} |
|||
|
|||
export const nextMonth = function(date) { |
|||
const year = date.getFullYear() |
|||
const month = date.getMonth() |
|||
return month === 11 |
|||
? changeYearMonthAndClampDate(date, year + 1, 0) |
|||
: changeYearMonthAndClampDate(date, year, month + 1) |
|||
} |
|||
|
|||
export const prevYear = function(date, amount = 1) { |
|||
const year = date.getFullYear() |
|||
const month = date.getMonth() |
|||
return changeYearMonthAndClampDate(date, year - amount, month) |
|||
} |
|||
|
|||
export const nextYear = function(date, amount = 1) { |
|||
const year = date.getFullYear() |
|||
const month = date.getMonth() |
|||
return changeYearMonthAndClampDate(date, year + amount, month) |
|||
} |
|||
|
|||
export const extractDateFormat = function(format) { |
|||
return format |
|||
.replace(/\W?m{1,2}|\W?ZZ/g, '') |
|||
.replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi, '') |
|||
.trim() |
|||
} |
|||
|
|||
export const extractTimeFormat = function(format) { |
|||
return format |
|||
.replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g, '') |
|||
.trim() |
|||
} |
|||
|
|||
export const validateRangeInOneMonth = function(start, end) { |
|||
return (start.getMonth() === end.getMonth()) && (start.getFullYear() === end.getFullYear()) |
|||
} |
@ -0,0 +1,229 @@ |
|||
/* istanbul ignore next */ |
|||
|
|||
import Vue from 'vue' |
|||
|
|||
const isServer = Vue.prototype.$isServer |
|||
|
|||
/* eslint no-useless-escape: 0 */ |
|||
const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g |
|||
const MOZ_HACK_REGEXP = /^moz([A-Z])/ |
|||
const ieVersion = isServer ? 0 : Number(document.documentMode) |
|||
|
|||
/* istanbul ignore next */ |
|||
const trim = function(string) { |
|||
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '') |
|||
} |
|||
/* istanbul ignore next */ |
|||
const camelCase = function(name) { |
|||
return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { |
|||
return offset ? letter.toUpperCase() : letter |
|||
}).replace(MOZ_HACK_REGEXP, 'Moz$1') |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
export const on = (function() { |
|||
if (!isServer && document.addEventListener) { |
|||
return function(element, event, handler) { |
|||
if (element && event && handler) { |
|||
element.addEventListener(event, handler, false) |
|||
} |
|||
} |
|||
} else { |
|||
return function(element, event, handler) { |
|||
if (element && event && handler) { |
|||
element.attachEvent('on' + event, handler) |
|||
} |
|||
} |
|||
} |
|||
})() |
|||
|
|||
/* istanbul ignore next */ |
|||
export const off = (function() { |
|||
if (!isServer && document.removeEventListener) { |
|||
return function(element, event, handler) { |
|||
if (element && event) { |
|||
element.removeEventListener(event, handler, false) |
|||
} |
|||
} |
|||
} else { |
|||
return function(element, event, handler) { |
|||
if (element && event) { |
|||
element.detachEvent('on' + event, handler) |
|||
} |
|||
} |
|||
} |
|||
})() |
|||
|
|||
/* istanbul ignore next */ |
|||
export const once = function(el, event, fn) { |
|||
var listener = function() { |
|||
if (fn) { |
|||
fn.apply(this, arguments) |
|||
} |
|||
off(el, event, listener) |
|||
} |
|||
on(el, event, listener) |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
export function hasClass(el, cls) { |
|||
if (!el || !cls) return false |
|||
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.') |
|||
if (el.classList) { |
|||
return el.classList.contains(cls) |
|||
} else { |
|||
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1 |
|||
} |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
export function addClass(el, cls) { |
|||
if (!el) return |
|||
var curClass = el.className |
|||
var classes = (cls || '').split(' ') |
|||
|
|||
for (var i = 0, j = classes.length; i < j; i++) { |
|||
var clsName = classes[i] |
|||
if (!clsName) continue |
|||
|
|||
if (el.classList) { |
|||
el.classList.add(clsName) |
|||
} else if (!hasClass(el, clsName)) { |
|||
curClass += ' ' + clsName |
|||
} |
|||
} |
|||
if (!el.classList) { |
|||
el.className = curClass |
|||
} |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
export function removeClass(el, cls) { |
|||
if (!el || !cls) return |
|||
var classes = cls.split(' ') |
|||
var curClass = ' ' + el.className + ' ' |
|||
|
|||
for (var i = 0, j = classes.length; i < j; i++) { |
|||
var clsName = classes[i] |
|||
if (!clsName) continue |
|||
|
|||
if (el.classList) { |
|||
el.classList.remove(clsName) |
|||
} else if (hasClass(el, clsName)) { |
|||
curClass = curClass.replace(' ' + clsName + ' ', ' ') |
|||
} |
|||
} |
|||
if (!el.classList) { |
|||
el.className = trim(curClass) |
|||
} |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
export const getStyle = ieVersion < 9 ? function(element, styleName) { |
|||
if (isServer) return |
|||
if (!element || !styleName) return null |
|||
styleName = camelCase(styleName) |
|||
if (styleName === 'float') { |
|||
styleName = 'styleFloat' |
|||
} |
|||
try { |
|||
switch (styleName) { |
|||
case 'opacity': |
|||
try { |
|||
return element.filters.item('alpha').opacity / 100 |
|||
} catch (e) { |
|||
return 1.0 |
|||
} |
|||
default: |
|||
return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null) |
|||
} |
|||
} catch (e) { |
|||
return element.style[styleName] |
|||
} |
|||
} : function(element, styleName) { |
|||
if (isServer) return |
|||
if (!element || !styleName) return null |
|||
styleName = camelCase(styleName) |
|||
if (styleName === 'float') { |
|||
styleName = 'cssFloat' |
|||
} |
|||
try { |
|||
var computed = document.defaultView.getComputedStyle(element, '') |
|||
return element.style[styleName] || computed ? computed[styleName] : null |
|||
} catch (e) { |
|||
return element.style[styleName] |
|||
} |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
export function setStyle(element, styleName, value) { |
|||
if (!element || !styleName) return |
|||
|
|||
if (typeof styleName === 'object') { |
|||
for (var prop in styleName) { |
|||
if (styleName.hasOwnProperty(prop)) { |
|||
setStyle(element, prop, styleName[prop]) |
|||
} |
|||
} |
|||
} else { |
|||
styleName = camelCase(styleName) |
|||
if (styleName === 'opacity' && ieVersion < 9) { |
|||
element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')' |
|||
} else { |
|||
element.style[styleName] = value |
|||
} |
|||
} |
|||
} |
|||
|
|||
export const isScroll = (el, vertical) => { |
|||
if (isServer) return |
|||
|
|||
const determinedDirection = vertical !== null || vertical !== undefined |
|||
const overflow = determinedDirection |
|||
? vertical |
|||
? getStyle(el, 'overflow-y') |
|||
: getStyle(el, 'overflow-x') |
|||
: getStyle(el, 'overflow') |
|||
|
|||
return overflow.match(/(scroll|auto)/) |
|||
} |
|||
|
|||
export const getScrollContainer = (el, vertical) => { |
|||
if (isServer) return |
|||
|
|||
let parent = el |
|||
while (parent) { |
|||
if ([window, document, document.documentElement].includes(parent)) { |
|||
return window |
|||
} |
|||
if (isScroll(parent, vertical)) { |
|||
return parent |
|||
} |
|||
parent = parent.parentNode |
|||
} |
|||
|
|||
return parent |
|||
} |
|||
|
|||
export const isInContainer = (el, container) => { |
|||
if (isServer || !el || !container) return false |
|||
|
|||
const elRect = el.getBoundingClientRect() |
|||
let containerRect |
|||
|
|||
if ([window, document, document.documentElement, null, undefined].includes(container)) { |
|||
containerRect = { |
|||
top: 0, |
|||
right: window.innerWidth, |
|||
bottom: window.innerHeight, |
|||
left: 0 |
|||
} |
|||
} else { |
|||
containerRect = container.getBoundingClientRect() |
|||
} |
|||
|
|||
return elRect.top < containerRect.bottom && |
|||
elRect.bottom > containerRect.top && |
|||
elRect.right > containerRect.left && |
|||
elRect.left < containerRect.right |
|||
} |
@ -0,0 +1,43 @@ |
|||
const availablePrefixs = ['moz', 'ms', 'webkit'] |
|||
|
|||
function requestAnimationFramePolyfill() { |
|||
let lastTime = 0 |
|||
return function(callback) { |
|||
const currTime = new Date().getTime() |
|||
const timeToCall = Math.max(0, 16 - (currTime - lastTime)) |
|||
const id = window.setTimeout(function() { |
|||
const rs = currTime + timeToCall |
|||
callback(rs) |
|||
}, timeToCall) |
|||
lastTime = currTime + timeToCall |
|||
return id |
|||
} |
|||
} |
|||
|
|||
export default function getRequestAnimationFrame() { |
|||
if (typeof window === 'undefined') { |
|||
return () => {} |
|||
} |
|||
if (window.requestAnimationFrame) { |
|||
// https://github.com/vuejs/vue/issues/4465
|
|||
return window.requestAnimationFrame.bind(window) |
|||
} |
|||
|
|||
const prefix = availablePrefixs.filter(key => `${key}RequestAnimationFrame` in window)[0] |
|||
|
|||
return prefix |
|||
? window[`${prefix}RequestAnimationFrame`] |
|||
: requestAnimationFramePolyfill() |
|||
} |
|||
|
|||
export function cancelRequestAnimationFrame(id) { |
|||
if (typeof window === 'undefined') { |
|||
return null |
|||
} |
|||
if (window.cancelAnimationFrame) { |
|||
return window.cancelAnimationFrame(id) |
|||
} |
|||
const prefix = availablePrefixs.filter(key => `${key}CancelAnimationFrame` in window || `${key}CancelRequestAnimationFrame` in window)[0] |
|||
|
|||
return prefix ? (window[`${prefix}CancelAnimationFrame`] || window[`${prefix}CancelRequestAnimationFrame`]).call(this, id) : clearTimeout(id) |
|||
} |
@ -0,0 +1,17 @@ |
|||
export default function getScroll(target, top) { |
|||
if (typeof window === 'undefined') { |
|||
return 0 |
|||
} |
|||
|
|||
const prop = top ? 'pageYOffset' : 'pageXOffset' |
|||
const method = top ? 'scrollTop' : 'scrollLeft' |
|||
const isWindow = target === window |
|||
|
|||
let ret = isWindow ? target[prop] : target[method] |
|||
// ie6,7,8 standard mode
|
|||
if (isWindow && typeof ret !== 'number') { |
|||
ret = window.document.documentElement[method] |
|||
} |
|||
|
|||
return ret |
|||
} |
@ -0,0 +1 @@ |
|||
["info","error","success","warning","question","back","arrow-left","arrow-down","arrow-right","arrow-up","caret-left","caret-bottom","caret-top","caret-right","d-arrow-left","d-arrow-right","minus","plus","remove","circle-plus","remove-outline","circle-plus-outline","close","check","circle-close","circle-check","circle-close-outline","circle-check-outline","zoom-out","zoom-in","d-caret","sort","sort-down","sort-up","tickets","document","goods","sold-out","news","message","date","printer","time","bell","mobile-phone","service","view","menu","more","more-outline","star-on","star-off","location","location-outline","phone","phone-outline","picture","picture-outline","delete","search","edit","edit-outline","rank","refresh","share","setting","upload","upload2","download","loading"] |
@ -0,0 +1,14 @@ |
|||
export default function(target) { |
|||
for (let i = 1, j = arguments.length; i < j; i++) { |
|||
const source = arguments[i] || {} |
|||
for (const prop in source) { |
|||
if (source.hasOwnProperty(prop)) { |
|||
const value = source[prop] |
|||
if (value !== undefined) { |
|||
target[prop] = value |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return target |
|||
} |
1257
src/components/menu/_util/popper.js
File diff suppressed because it is too large
View File
@ -0,0 +1,218 @@ |
|||
import Vue from 'vue' |
|||
import merge from './../merge' |
|||
import PopupManager from './popup-manager' |
|||
import getScrollBarWidth from '../scrollbar-width' |
|||
import { getStyle, addClass, removeClass, hasClass } from '../dom' |
|||
|
|||
let idSeed = 1 |
|||
|
|||
let scrollBarWidth |
|||
|
|||
export default { |
|||
props: { |
|||
visible: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
openDelay: {}, |
|||
closeDelay: {}, |
|||
zIndex: {}, |
|||
modal: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
modalFade: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
modalClass: {}, |
|||
modalAppendToBody: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
lockScroll: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
closeOnPressEscape: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
closeOnClickModal: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
|
|||
beforeMount() { |
|||
this._popupId = 'popup-' + idSeed++ |
|||
PopupManager.register(this._popupId, this) |
|||
}, |
|||
|
|||
beforeDestroy() { |
|||
PopupManager.deregister(this._popupId) |
|||
PopupManager.closeModal(this._popupId) |
|||
|
|||
this.restoreBodyStyle() |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
opened: false, |
|||
bodyPaddingRight: null, |
|||
computedBodyPaddingRight: 0, |
|||
withoutHiddenClass: true, |
|||
rendered: false |
|||
} |
|||
}, |
|||
|
|||
watch: { |
|||
visible(val) { |
|||
if (val) { |
|||
if (this._opening) return |
|||
if (!this.rendered) { |
|||
this.rendered = true |
|||
Vue.nextTick(() => { |
|||
this.open() |
|||
}) |
|||
} else { |
|||
this.open() |
|||
} |
|||
} else { |
|||
this.close() |
|||
} |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
open(options) { |
|||
if (!this.rendered) { |
|||
this.rendered = true |
|||
} |
|||
|
|||
const props = merge({}, this.$props || this, options) |
|||
|
|||
if (this._closeTimer) { |
|||
clearTimeout(this._closeTimer) |
|||
this._closeTimer = null |
|||
} |
|||
clearTimeout(this._openTimer) |
|||
|
|||
const openDelay = Number(props.openDelay) |
|||
if (openDelay > 0) { |
|||
this._openTimer = setTimeout(() => { |
|||
this._openTimer = null |
|||
this.doOpen(props) |
|||
}, openDelay) |
|||
} else { |
|||
this.doOpen(props) |
|||
} |
|||
}, |
|||
|
|||
doOpen(props) { |
|||
if (this.$isServer) return |
|||
if (this.willOpen && !this.willOpen()) return |
|||
if (this.opened) return |
|||
|
|||
this._opening = true |
|||
|
|||
const dom = this.$el |
|||
|
|||
const modal = props.modal |
|||
|
|||
const zIndex = props.zIndex |
|||
if (zIndex) { |
|||
PopupManager.zIndex = zIndex |
|||
} |
|||
|
|||
if (modal) { |
|||
if (this._closing) { |
|||
PopupManager.closeModal(this._popupId) |
|||
this._closing = false |
|||
} |
|||
PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), this.modalAppendToBody ? undefined : dom, props.modalClass, props.modalFade) |
|||
if (props.lockScroll) { |
|||
this.withoutHiddenClass = !hasClass(document.body, 'mds-popup-parent--hidden') |
|||
if (this.withoutHiddenClass) { |
|||
this.bodyPaddingRight = document.body.style.paddingRight |
|||
this.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10) |
|||
} |
|||
scrollBarWidth = getScrollBarWidth() |
|||
const bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight |
|||
const bodyOverflowY = getStyle(document.body, 'overflowY') |
|||
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && this.withoutHiddenClass) { |
|||
document.body.style.paddingRight = this.computedBodyPaddingRight + scrollBarWidth + 'px' |
|||
} |
|||
addClass(document.body, 'mds-popup-parent--hidden') |
|||
} |
|||
} |
|||
|
|||
if (getComputedStyle(dom).position === 'static') { |
|||
dom.style.position = 'absolute' |
|||
} |
|||
|
|||
dom.style.zIndex = PopupManager.nextZIndex() |
|||
this.opened = true |
|||
|
|||
this.onOpen && this.onOpen() |
|||
|
|||
this.doAfterOpen() |
|||
}, |
|||
|
|||
doAfterOpen() { |
|||
this._opening = false |
|||
}, |
|||
|
|||
close() { |
|||
if (this.willClose && !this.willClose()) return |
|||
|
|||
if (this._openTimer !== null) { |
|||
clearTimeout(this._openTimer) |
|||
this._openTimer = null |
|||
} |
|||
clearTimeout(this._closeTimer) |
|||
|
|||
const closeDelay = Number(this.closeDelay) |
|||
|
|||
if (closeDelay > 0) { |
|||
this._closeTimer = setTimeout(() => { |
|||
this._closeTimer = null |
|||
this.doClose() |
|||
}, closeDelay) |
|||
} else { |
|||
this.doClose() |
|||
} |
|||
}, |
|||
|
|||
doClose() { |
|||
this._closing = true |
|||
|
|||
this.onClose && this.onClose() |
|||
|
|||
if (this.lockScroll) { |
|||
setTimeout(this.restoreBodyStyle, 200) |
|||
} |
|||
|
|||
this.opened = false |
|||
|
|||
this.doAfterClose() |
|||
}, |
|||
|
|||
doAfterClose() { |
|||
PopupManager.closeModal(this._popupId) |
|||
this._closing = false |
|||
}, |
|||
|
|||
restoreBodyStyle() { |
|||
if (this.modal && this.withoutHiddenClass) { |
|||
document.body.style.paddingRight = this.bodyPaddingRight |
|||
removeClass(document.body, 'mds-popup-parent--hidden') |
|||
} |
|||
this.withoutHiddenClass = true |
|||
} |
|||
} |
|||
} |
|||
|
|||
export { |
|||
PopupManager |
|||
} |
@ -0,0 +1,194 @@ |
|||
import Vue from 'vue' |
|||
import { addClass, removeClass } from '../dom' |
|||
|
|||
let hasModal = false |
|||
let hasInitZIndex = false |
|||
let zIndex |
|||
|
|||
const getModal = function() { |
|||
if (Vue.prototype.$isServer) return |
|||
let modalDom = PopupManager.modalDom |
|||
if (modalDom) { |
|||
hasModal = true |
|||
} else { |
|||
hasModal = false |
|||
modalDom = document.createElement('div') |
|||
PopupManager.modalDom = modalDom |
|||
|
|||
modalDom.addEventListener('touchmove', function(event) { |
|||
event.preventDefault() |
|||
event.stopPropagation() |
|||
}) |
|||
|
|||
modalDom.addEventListener('click', function() { |
|||
PopupManager.doOnModalClick && PopupManager.doOnModalClick() |
|||
}) |
|||
} |
|||
|
|||
return modalDom |
|||
} |
|||
|
|||
const instances = {} |
|||
|
|||
const PopupManager = { |
|||
modalFade: true, |
|||
|
|||
getInstance: function(id) { |
|||
return instances[id] |
|||
}, |
|||
|
|||
register: function(id, instance) { |
|||
if (id && instance) { |
|||
instances[id] = instance |
|||
} |
|||
}, |
|||
|
|||
deregister: function(id) { |
|||
if (id) { |
|||
instances[id] = null |
|||
delete instances[id] |
|||
} |
|||
}, |
|||
|
|||
nextZIndex: function() { |
|||
return PopupManager.zIndex++ |
|||
}, |
|||
|
|||
modalStack: [], |
|||
|
|||
doOnModalClick: function() { |
|||
const topItem = PopupManager.modalStack[PopupManager.modalStack.length - 1] |
|||
if (!topItem) return |
|||
|
|||
const instance = PopupManager.getInstance(topItem.id) |
|||
if (instance && instance.closeOnClickModal) { |
|||
instance.close() |
|||
} |
|||
}, |
|||
|
|||
openModal: function(id, zIndex, dom, modalClass, modalFade) { |
|||
if (Vue.prototype.$isServer) return |
|||
if (!id || zIndex === undefined) return |
|||
this.modalFade = modalFade |
|||
|
|||
const modalStack = this.modalStack |
|||
|
|||
for (let i = 0, j = modalStack.length; i < j; i++) { |
|||
const item = modalStack[i] |
|||
if (item.id === id) { |
|||
return |
|||
} |
|||
} |
|||
|
|||
const modalDom = getModal() |
|||
|
|||
addClass(modalDom, 'v-modal') |
|||
if (this.modalFade && !hasModal) { |
|||
addClass(modalDom, 'v-modal-enter') |
|||
} |
|||
if (modalClass) { |
|||
const classArr = modalClass.trim().split(/\s+/) |
|||
classArr.forEach(item => addClass(modalDom, item)) |
|||
} |
|||
setTimeout(() => { |
|||
removeClass(modalDom, 'v-modal-enter') |
|||
}, 200) |
|||
|
|||
if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) { |
|||
dom.parentNode.appendChild(modalDom) |
|||
} else { |
|||
document.body.appendChild(modalDom) |
|||
} |
|||
|
|||
if (zIndex) { |
|||
modalDom.style.zIndex = zIndex |
|||
} |
|||
modalDom.tabIndex = 0 |
|||
modalDom.style.display = '' |
|||
|
|||
this.modalStack.push({ id: id, zIndex: zIndex, modalClass: modalClass }) |
|||
}, |
|||
|
|||
closeModal: function(id) { |
|||
const modalStack = this.modalStack |
|||
const modalDom = getModal() |
|||
|
|||
if (modalStack.length > 0) { |
|||
const topItem = modalStack[modalStack.length - 1] |
|||
if (topItem.id === id) { |
|||
if (topItem.modalClass) { |
|||
const classArr = topItem.modalClass.trim().split(/\s+/) |
|||
classArr.forEach(item => removeClass(modalDom, item)) |
|||
} |
|||
|
|||
modalStack.pop() |
|||
if (modalStack.length > 0) { |
|||
modalDom.style.zIndex = modalStack[modalStack.length - 1].zIndex |
|||
} |
|||
} else { |
|||
for (let i = modalStack.length - 1; i >= 0; i--) { |
|||
if (modalStack[i].id === id) { |
|||
modalStack.splice(i, 1) |
|||
break |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (modalStack.length === 0) { |
|||
if (this.modalFade) { |
|||
addClass(modalDom, 'v-modal-leave') |
|||
} |
|||
setTimeout(() => { |
|||
if (modalStack.length === 0) { |
|||
if (modalDom.parentNode) modalDom.parentNode.removeChild(modalDom) |
|||
modalDom.style.display = 'none' |
|||
PopupManager.modalDom = undefined |
|||
} |
|||
removeClass(modalDom, 'v-modal-leave') |
|||
}, 200) |
|||
} |
|||
} |
|||
} |
|||
|
|||
Object.defineProperty(PopupManager, 'zIndex', { |
|||
configurable: true, |
|||
get() { |
|||
if (!hasInitZIndex) { |
|||
zIndex = zIndex || (Vue.prototype.$ELEMENT || {}).zIndex || 2000 |
|||
hasInitZIndex = true |
|||
} |
|||
return zIndex |
|||
}, |
|||
set(value) { |
|||
zIndex = value |
|||
} |
|||
}) |
|||
|
|||
const getTopPopup = function() { |
|||
if (Vue.prototype.$isServer) return |
|||
if (PopupManager.modalStack.length > 0) { |
|||
const topPopup = PopupManager.modalStack[PopupManager.modalStack.length - 1] |
|||
if (!topPopup) return |
|||
const instance = PopupManager.getInstance(topPopup.id) |
|||
|
|||
return instance |
|||
} |
|||
} |
|||
|
|||
if (!Vue.prototype.$isServer) { |
|||
// handle `esc` key when the popup is shown
|
|||
window.addEventListener('keydown', function(event) { |
|||
if (event.keyCode === 27) { |
|||
const topPopup = getTopPopup() |
|||
|
|||
if (topPopup && topPopup.closeOnPressEscape) { |
|||
topPopup.handleClose |
|||
? topPopup.handleClose() |
|||
: (topPopup.handleAction ? topPopup.handleAction('cancel') : topPopup.close()) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
export default PopupManager |
@ -0,0 +1,7 @@ |
|||
/** |
|||
* Check if a value in validList |
|||
* @param {String} value |
|||
* @param {Array} validList |
|||
* @return {Boolean} |
|||
*/ |
|||
export const oneOf = (value, validList) => validList.indexOf(value) > -1 |
@ -0,0 +1,24 @@ |
|||
import { once, on } from './dom.js' |
|||
|
|||
export default { |
|||
bind(el, binding, vnode) { |
|||
let interval = null |
|||
let startTime |
|||
const handler = () => vnode.context[binding.expression].apply() |
|||
const clear = () => { |
|||
if (Date.now() - startTime < 100) { |
|||
handler() |
|||
} |
|||
clearInterval(interval) |
|||
interval = null |
|||
} |
|||
|
|||
on(el, 'mousedown', (e) => { |
|||
if (e.button !== 0) return |
|||
startTime = Date.now() |
|||
once(document, 'mouseup', clear) |
|||
clearInterval(interval) |
|||
interval = setInterval(handler, 100) |
|||
}) |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
import ResizeObserver from 'resize-observer-polyfill' |
|||
|
|||
const isServer = typeof window === 'undefined' |
|||
|
|||
const resizeHandler = function(entries) { |
|||
for (const entry of entries) { |
|||
const listeners = entry.target.__resizeListeners__ || [] |
|||
if (listeners.length) { |
|||
listeners.forEach(fn => { |
|||
fn() |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
|
|||
export const addResizeListener = function(element, fn) { |
|||
if (isServer) return |
|||
if (!element.__resizeListeners__) { |
|||
element.__resizeListeners__ = [] |
|||
element.__ro__ = new ResizeObserver(resizeHandler) |
|||
element.__ro__.observe(element) |
|||
} |
|||
element.__resizeListeners__.push(fn) |
|||
} |
|||
|
|||
/* istanbul ignore next */ |
|||
export const removeResizeListener = function(element, fn) { |
|||
if (!element || !element.__resizeListeners__) return |
|||
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1) |
|||
if (!element.__resizeListeners__.length) { |
|||
element.__ro__.disconnect() |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
import Vue from 'vue' |
|||
|
|||
export default function scrollIntoView(container, selected) { |
|||
if (Vue.prototype.$isServer) return |
|||
|
|||
if (!selected) { |
|||
container.scrollTop = 0 |
|||
return |
|||
} |
|||
|
|||
const offsetParents = [] |
|||
let pointer = selected.offsetParent |
|||
while (pointer && container !== pointer && container.contains(pointer)) { |
|||
offsetParents.push(pointer) |
|||
pointer = pointer.offsetParent |
|||
} |
|||
const top = selected.offsetTop + offsetParents.reduce((prev, curr) => (prev + curr.offsetTop), 0) |
|||
const bottom = top + selected.offsetHeight |
|||
const viewRectTop = container.scrollTop |
|||
const viewRectBottom = viewRectTop + container.clientHeight |
|||
|
|||
if (top < viewRectTop) { |
|||
container.scrollTop = top |
|||
} else if (bottom > viewRectBottom) { |
|||
container.scrollTop = bottom - container.clientHeight |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
import Vue from 'vue' |
|||
|
|||
let scrollBarWidth |
|||
|
|||
export default function() { |
|||
if (Vue.prototype.$isServer) return 0 |
|||
if (scrollBarWidth !== undefined) return scrollBarWidth |
|||
|
|||
const outer = document.createElement('div') |
|||
outer.className = 'mds-scrollbar__wrap' |
|||
outer.style.visibility = 'hidden' |
|||
outer.style.width = '100px' |
|||
outer.style.position = 'absolute' |
|||
outer.style.top = '-9999px' |
|||
document.body.appendChild(outer) |
|||
|
|||
const widthNoScroll = outer.offsetWidth |
|||
outer.style.overflow = 'scroll' |
|||
|
|||
const inner = document.createElement('div') |
|||
inner.style.width = '100%' |
|||
outer.appendChild(inner) |
|||
|
|||
const widthWithScroll = inner.offsetWidth |
|||
outer.parentNode.removeChild(outer) |
|||
scrollBarWidth = widthNoScroll - widthWithScroll |
|||
|
|||
return scrollBarWidth |
|||
} |
@ -0,0 +1,35 @@ |
|||
import { assert } from './util' |
|||
|
|||
class Soda { |
|||
constructor(vm, options = {}) { |
|||
this.mutations = options.mutations |
|||
assert(typeof options.state === 'function', 'Soda state must be a function.') |
|||
this.state = options.state() |
|||
this.root = vm |
|||
this.init(vm) |
|||
return this |
|||
} |
|||
|
|||
commit(type, payload) { |
|||
this.mutations[type].call(this, this.state, payload) |
|||
} |
|||
|
|||
init(root = this.root) { |
|||
const map = (_vm) => { |
|||
if (!_vm.$children.length) return |
|||
_vm.$children.forEach(child => { |
|||
inject(child) |
|||
map(child) |
|||
}) |
|||
} |
|||
const inject = (_vm) => { |
|||
if (typeof _vm.soda === 'undefined' || typeof this.$soda !== 'undefined') return |
|||
_vm.$soda = this |
|||
_vm.soda = this.state |
|||
} |
|||
root.soda = this.state |
|||
map(root) |
|||
} |
|||
} |
|||
|
|||
export default Soda |
@ -0,0 +1,8 @@ |
|||
const executeIfFunction = f => |
|||
typeof f === 'function' ? f() : f |
|||
|
|||
export const switchcase = cases => defaultCase => key => |
|||
key in cases ? cases[key] : defaultCase |
|||
|
|||
export const switchcaseF = cases => defaultCase => key => |
|||
executeIfFunction(switchcase(cases)(defaultCase)(key)) |
@ -0,0 +1,47 @@ |
|||
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from './getRequestAnimationFrame' |
|||
|
|||
const reqAnimFrame = getRequestAnimationFrame() |
|||
|
|||
export default function throttleByAnimationFrame(fn) { |
|||
let requestId |
|||
|
|||
const later = args => () => { |
|||
requestId = null |
|||
fn(...args) |
|||
} |
|||
|
|||
const throttled = (...args) => { |
|||
if (requestId == null) { |
|||
requestId = reqAnimFrame(later(args)) |
|||
} |
|||
} |
|||
|
|||
throttled.cancel = () => cancelRequestAnimationFrame(requestId) |
|||
|
|||
return throttled |
|||
} |
|||
|
|||
export function throttleByAnimationFrameDecorator() { |
|||
return function(target, key, descriptor) { |
|||
const fn = descriptor.value |
|||
let definingProperty = false |
|||
return { |
|||
configurable: true, |
|||
get() { |
|||
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) { |
|||
return fn |
|||
} |
|||
|
|||
const boundFn = throttleByAnimationFrame(fn.bind(this)) |
|||
definingProperty = true |
|||
Object.defineProperty(this, key, { |
|||
value: boundFn, |
|||
configurable: true, |
|||
writable: true |
|||
}) |
|||
definingProperty = false |
|||
return boundFn |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,237 @@ |
|||
let defaultId = new Date().getTime() |
|||
export default class Node { |
|||
constructor(options) { |
|||
this.id = defaultId++ |
|||
this.checked = false |
|||
this.indeterminate = false |
|||
this.data = null |
|||
this.expanded = false |
|||
this.parent = null |
|||
this.isLeaf = false |
|||
for (const name in options) { |
|||
if (options.hasOwnProperty(name)) { |
|||
this[name] = options[name] |
|||
} |
|||
} |
|||
this.select = false |
|||
this.loaded = false |
|||
this.childNodes = [] |
|||
this.loading = false |
|||
this.parent ? this.level = this.parent.level + 1 : this.level = 0 |
|||
this.update(this.data) |
|||
} |
|||
update(data) { |
|||
const { prop } = this.tree |
|||
let children |
|||
|
|||
this.markData(data) |
|||
|
|||
if (this.key !== null) { |
|||
this.id = this.key |
|||
} |
|||
|
|||
if (Array.isArray(data) && this.level === 0) { |
|||
children = data |
|||
this.id = 'root' |
|||
} else if (data.hasOwnProperty(prop.children)) { |
|||
children = data[prop.children] |
|||
} else { |
|||
if (!this.tree.lazy) this.isLeaf = true |
|||
} |
|||
|
|||
if (Array.isArray(children) && children.length > 0) { |
|||
children.forEach(data => { |
|||
this.appendChild(data) |
|||
}) |
|||
} else { |
|||
if (!this.tree.lazy) this.isLeaf = true |
|||
} |
|||
this.tree.nodesMap.set(this.id, this) |
|||
} |
|||
getTrueData(prop) { |
|||
const props = this.tree.prop[prop] |
|||
const data = this.data |
|||
if (data.hasOwnProperty(props)) { |
|||
return data[props] |
|||
} else if (data.hasOwnProperty(prop)) { |
|||
return data[prop] |
|||
} else { |
|||
return null |
|||
} |
|||
} |
|||
get label() { |
|||
return this.getTrueData('label') |
|||
} |
|||
get key() { |
|||
return this.getTrueData('key') |
|||
} |
|||
get disabled() { |
|||
return this.getTrueData('disabled') |
|||
} |
|||
get check() { |
|||
return this.checked |
|||
} |
|||
set check(val) { |
|||
if (val !== this.checked) { |
|||
this.checked = val |
|||
this.handleCheckChange() |
|||
} |
|||
} |
|||
get siblingsNodes() { |
|||
const arr = [] |
|||
const currentNode = this |
|||
this.parent.childNodes.forEach(node => { |
|||
if (node.id !== currentNode.id) { |
|||
arr.push(node) |
|||
} |
|||
}) |
|||
return arr |
|||
} |
|||
get checkedChildNodes() { |
|||
const arr = [] |
|||
this.childNodes.forEach(node => { |
|||
if (node.checked) arr.push(node) |
|||
}) |
|||
return arr |
|||
} |
|||
get indeterminateChildNodes() { |
|||
const arr = [] |
|||
this.childNodes.forEach(node => { |
|||
if (node.checked || node.indeterminate) arr.push(node) |
|||
}) |
|||
return arr |
|||
} |
|||
markData(data) { |
|||
Object.defineProperty(data, '_node', { |
|||
value: this, |
|||
enumerable: false, |
|||
configurable: false, |
|||
writable: false |
|||
}) |
|||
if (!Array.isArray(data)) { |
|||
Object.defineProperty(data, '_nodeId', { |
|||
value: this.id, |
|||
enumerable: false, |
|||
configurable: false, |
|||
writable: false |
|||
}) |
|||
} else if (this.level === 0) { |
|||
Object.defineProperty(data, '_nodeId', { |
|||
value: 'root', |
|||
enumerable: false, |
|||
configurable: false, |
|||
writable: false |
|||
}) |
|||
} |
|||
} |
|||
get isExpanded() { |
|||
return this.expanded |
|||
} |
|||
set isExpanded(value) { |
|||
this.changeExpanded(value) |
|||
} |
|||
changeExpanded(value) { |
|||
if (this.tree.lazy && !this.loaded) { |
|||
this.loadNode() |
|||
} else { |
|||
this.expanded = value |
|||
} |
|||
if (this.tree.accordion && value) { |
|||
this.siblingsNodes.forEach(node => { |
|||
node.expanded = false |
|||
}) |
|||
} |
|||
} |
|||
loadNode() { |
|||
const node = this |
|||
if (node.loaded || node.loading || !node.tree.lazy || node.childNodes.length > 0) { |
|||
return |
|||
} |
|||
node.loading = true |
|||
node.tree.load(node.data, (data) => { |
|||
if (!Array.isArray(data)) throw new Error('传入子元素必须是数组') |
|||
data.forEach(data => { |
|||
node.appendChild(data) |
|||
}) |
|||
node.loading = false |
|||
node.loaded = true |
|||
node.check = false |
|||
node.expanded = true |
|||
}) |
|||
} |
|||
getPath() { |
|||
const arr = [] |
|||
let n = 0 |
|||
let node = this |
|||
if (Array.isArray(this.tree.root)) { |
|||
n = 1 |
|||
} |
|||
while (node.level > n) { |
|||
arr.push(node.data) |
|||
node = node.parent |
|||
} |
|||
return arr |
|||
} |
|||
handleCheckChange() { |
|||
const checked = this.checked |
|||
this.childNodes.forEach(node => { |
|||
node.check = checked |
|||
}) |
|||
if (this.parent) { |
|||
this.parent.handleChildCheckChange() |
|||
} |
|||
} |
|||
handleChildCheckChange() { |
|||
if (Array.isArray(this.data) || this.level === 0) { |
|||
return |
|||
} |
|||
if (this.childNodes.length === this.checkedChildNodes.length && this.childNodes.length !== 0) { |
|||
this.checked = true |
|||
this.indeterminate = false |
|||
} else if (this.checkedChildNodes.length > 0) { |
|||
this.checked = false |
|||
this.indeterminate = true |
|||
} else { |
|||
this.checked = false |
|||
this.indeterminate = false |
|||
for (let i = 0; i < this.childNodes.length; i++) { |
|||
if (this.childNodes[i].indeterminate) { |
|||
this.indeterminate = true |
|||
break |
|||
} |
|||
} |
|||
} |
|||
this.parent.handleChildCheckChange() |
|||
} |
|||
appendChild(data, index) { |
|||
let isLeaf = false |
|||
this.isLeaf = false |
|||
if (data.hasOwnProperty(this.tree.prop.leaf)) isLeaf = data[this.tree.prop.leaf] |
|||
if (data.hasOwnProperty(this.tree.prop.key)) { |
|||
if (this.tree.nodesMap.get(data[this.tree.prop.key])) { |
|||
throw new Error('节点的key不能重复') |
|||
} |
|||
} |
|||
const child = new Node({ |
|||
parent: this, |
|||
data: data, |
|||
index: this.childNodes.length, |
|||
tree: this.tree, |
|||
isLeaf |
|||
}) |
|||
if (index) { |
|||
this.childNodes.splice(index, 0, child) |
|||
} else { |
|||
this.childNodes.push(child) |
|||
} |
|||
if (this.parent) this.parent.handleChildCheckChange() |
|||
} |
|||
remove() { |
|||
let node = this |
|||
const index = node.parent.childNodes.indexOf(node) |
|||
node.parent.childNodes.splice(index, 1) |
|||
node.parent.handleChildCheckChange() |
|||
node.tree.nodesMap.delete(node.id) |
|||
node = null |
|||
} |
|||
} |
@ -0,0 +1,120 @@ |
|||
import Node from './node' |
|||
const copyData = (data, tree) => { |
|||
const newData = {} |
|||
for (const key in data) { |
|||
if (data.hasOwnProperty(key) && key !== tree.prop.children) { |
|||
newData[key] = data[key] |
|||
} |
|||
} |
|||
return newData |
|||
} |
|||
const copyNode = (node, tree) => { |
|||
const newData = copyData(node.data, tree) |
|||
if (node.isLeaf) { |
|||
return newData |
|||
} |
|||
newData[tree.prop.children] = [] |
|||
node.indeterminateChildNodes.forEach(item => { |
|||
newData[tree.prop.children].push(copyNode(item, tree)) |
|||
}) |
|||
return newData |
|||
} |
|||
|
|||
export default class Tree { |
|||
constructor(options) { |
|||
this.accordion = true |
|||
for (const name in options) { |
|||
if (options.hasOwnProperty(name)) { |
|||
this[name] = options[name] |
|||
} |
|||
} |
|||
if (typeof this.prop !== 'object') { |
|||
this.prop = { |
|||
label: 'label', |
|||
key: 'key', |
|||
leaf: 'leaf', |
|||
disabled: 'disabled', |
|||
children: 'children' |
|||
} |
|||
} |
|||
if (this.lazy && !this.load) { |
|||
throw new Error('loadNodeFunction is required!') |
|||
} |
|||
this.nodesMap = new Map() |
|||
this.root = new Node({ |
|||
data: this.data, |
|||
tree: this |
|||
}) |
|||
} |
|||
getCheckNode() { |
|||
const arr = [] |
|||
this.nodesMap.forEach(item => { |
|||
if (item.checked) { |
|||
arr.push(item.data) |
|||
} |
|||
}) |
|||
return arr |
|||
} |
|||
setCheckNode(keys, bor = true) { |
|||
const nodesMap = this.nodesMap |
|||
|
|||
if (Array.isArray(keys)) { |
|||
keys.forEach(item => { |
|||
const node = nodesMap.get(item) |
|||
if (node) node.check = bor |
|||
}) |
|||
} else { |
|||
const node = nodesMap.get(keys) |
|||
if (node) nodesMap.get(keys).check = bor |
|||
} |
|||
} |
|||
getCheckNodeTree() { |
|||
const root = this.root |
|||
|
|||
if (Array.isArray(root.data)) { |
|||
const newTree = [] |
|||
root.indeterminateChildNodes.forEach(item => { |
|||
newTree.push(copyNode(item, this)) |
|||
}) |
|||
return newTree |
|||
} else { |
|||
return copyNode(root, this) |
|||
} |
|||
} |
|||
clearCheckNode() { |
|||
this.nodesMap.forEach(item => { |
|||
item.check = false |
|||
}) |
|||
} |
|||
clearExpandNode() { |
|||
this.nodesMap.forEach(item => { |
|||
item.isExpanded = false |
|||
}) |
|||
} |
|||
appendNodes(key, nodes) { |
|||
const parent = this.nodesMap.get(key) |
|||
if (!parent) { |
|||
return |
|||
} |
|||
if (Array.isArray(nodes)) { |
|||
if (typeof nodes === 'object') { |
|||
nodes.forEach(item => { |
|||
parent.appendChild(item) |
|||
}) |
|||
} |
|||
} else if (typeof nodes === 'object') { |
|||
parent.appendChild(nodes) |
|||
} |
|||
} |
|||
delectNodeByKey(keys) { |
|||
if (Array.isArray(keys)) { |
|||
keys.forEach(item => { |
|||
const node = this.nodesMap.get(item) |
|||
if (node) node.remove() |
|||
}) |
|||
} else { |
|||
const node = this.nodesMap.get(keys) |
|||
node.remove() |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,141 @@ |
|||
import Vue from 'vue' |
|||
export const noop = () => {} |
|||
|
|||
const getScroll = (w, top) => { |
|||
let ret = top ? w.pageYOffset : w.pageXOffset |
|||
const method = top ? 'scrollTop' : 'scrollLeft' |
|||
if (typeof ret !== 'number') { |
|||
const d = w.document |
|||
// ie6,7,8 standard mode
|
|||
ret = d.documentElement[method] |
|||
if (typeof ret !== 'number') { |
|||
// quirks mode
|
|||
ret = d.body[method] |
|||
} |
|||
} |
|||
return ret |
|||
} |
|||
|
|||
const getClientPosition = elem => { |
|||
let box = null |
|||
let x |
|||
let y |
|||
const doc = elem.ownerDocument |
|||
const body = doc.body |
|||
const docElem = doc && doc.documentElement |
|||
box = elem.getBoundingClientRect() |
|||
x = box.left |
|||
y = box.top |
|||
x -= docElem.clientLeft || body.clientLeft || 0 |
|||
y -= docElem.clientTop || body.clientTop || 0 |
|||
return { |
|||
left: x, |
|||
top: y |
|||
} |
|||
} |
|||
|
|||
export const getOffsetLeft = el => { |
|||
const pos = getClientPosition(el) |
|||
const doc = el.ownerDocument |
|||
const w = doc.defaultView || doc.parentWindow |
|||
pos.left += getScroll(w) |
|||
return pos.left |
|||
} |
|||
/** |
|||
* 获取对象深层级的对象,避免循环 |
|||
* @export |
|||
* @param {*} sourceObj 源对象 {a:{b:{d:1}}} |
|||
* @param {*} pathName path组成的数组 例如:'a.b.c' |
|||
* @param {*} defaultValue 如果没有值默认的值 [] |
|||
*/ |
|||
export function getValueByPath(sourceObj, pathName, defaultValue) { |
|||
const getValue = function(sourceObj, pathNameArray) { |
|||
const key = pathNameArray.shift() |
|||
const value = sourceObj[key] |
|||
if (value === undefined || value === null) { |
|||
return defaultValue |
|||
} else if (pathNameArray.length === 0) { |
|||
return value |
|||
} else if (pathNameArray.length > 0) { |
|||
return getValue(value, pathNameArray) |
|||
} |
|||
} |
|||
const pathNameArray = pathName.split('.') |
|||
return getValue(sourceObj, pathNameArray) |
|||
} |
|||
/** |
|||
* |
|||
* 判断两个数是否相等 |
|||
* @param {*} a |
|||
* @param {*} b |
|||
* @returns |
|||
*/ |
|||
export const valueEquals = (a, b) => { |
|||
// see: https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript
|
|||
if (a === b) return true |
|||
if (!(a instanceof Array)) return false |
|||
if (!(b instanceof Array)) return false |
|||
if (a.length !== b.length) return false |
|||
for (let i = 0; i !== a.length; ++i) { |
|||
if (a[i] !== b[i]) return false |
|||
} |
|||
return true |
|||
} |
|||
// TODO: use native Array.find, Array.findIndex when IE support is dropped
|
|||
export const arrayFindIndex = function(arr, pred) { |
|||
for (let i = 0; i !== arr.length; ++i) { |
|||
if (pred(arr[i])) { |
|||
return i |
|||
} |
|||
} |
|||
return -1 |
|||
} |
|||
|
|||
export const arrayFind = function(arr, pred) { |
|||
const idx = arrayFindIndex(arr, pred) |
|||
return idx !== -1 ? arr[idx] : undefined |
|||
} |
|||
|
|||
// coerce truthy value to array
|
|||
export const coerceTruthyValueToArray = function(val) { |
|||
if (Array.isArray(val)) { |
|||
return val |
|||
} else if (val) { |
|||
return [val] |
|||
} else { |
|||
return [] |
|||
} |
|||
} |
|||
|
|||
export const isIE = function() { |
|||
return !Vue.prototype.$isServer && !isNaN(Number(document.documentMode)) |
|||
} |
|||
|
|||
export const isEdge = function() { |
|||
return !Vue.prototype.$isServer && navigator.userAgent.indexOf('Edge') > -1 |
|||
} |
|||
|
|||
export const isFirefox = function() { |
|||
return !Vue.prototype.$isServer && !!window.navigator.userAgent.match(/firefox/i) |
|||
} |
|||
|
|||
export const assert = (condition, msg) => { |
|||
if (!condition) throw new Error(`[mds-ui] ${msg}`) |
|||
} |
|||
/** |
|||
* |
|||
* 特殊字符转译 |
|||
* @param {string} [value=''] |
|||
*/ |
|||
export const escapeRegexpString = (value = '') => String(value).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') |
|||
/** |
|||
* Get element offset width |
|||
* @param {*} node HTMLDOMElemment |
|||
* @return {Number} width |
|||
*/ |
|||
/** |
|||
* Get element offset width |
|||
* @param {*} node HTMLDOMElemment |
|||
* @return {Number} width |
|||
*/ |
|||
export const getOffsetWidth = (node) => node ? node.offsetWidth : 0 |
@ -0,0 +1,205 @@ |
|||
import Vue from 'vue' |
|||
import { |
|||
PopupManager |
|||
} from './popup' |
|||
import PopperJS2 from './popper.js' |
|||
// todo 可以替换但是 替换后功能有差异 待定
|
|||
// import PopperJS2 from 'popper.js'
|
|||
const PopperJS = Vue.prototype.$isServer ? function() {} : PopperJS2 |
|||
const stop = e => e.stopPropagation() |
|||
|
|||
/** |
|||
* @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper. |
|||
* @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper. |
|||
* @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -end), left(-start, -end) |
|||
* @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative). |
|||
* @param {Boolean} [visible=false] Visibility of the popup element. |
|||
* @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style. |
|||
*/ |
|||
export default { |
|||
props: { |
|||
transformOrigin: { |
|||
type: [Boolean, String], |
|||
default: true |
|||
}, |
|||
placement: { |
|||
type: String, |
|||
default: 'bottom' |
|||
}, |
|||
boundariesPadding: { |
|||
type: Number, |
|||
default: 5 |
|||
}, |
|||
reference: {}, |
|||
popper: {}, |
|||
offset: { |
|||
default: 0 |
|||
}, |
|||
value: Boolean, |
|||
visibleArrow: Boolean, |
|||
arrowOffset: { |
|||
type: Number, |
|||
default: 35 |
|||
}, |
|||
appendToBody: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
popperOptions: { |
|||
type: Object, |
|||
default() { |
|||
return { |
|||
gpuAcceleration: false |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
showPopper: false, |
|||
currentPlacement: '' |
|||
} |
|||
}, |
|||
|
|||
watch: { |
|||
value: { |
|||
immediate: true, |
|||
handler(val) { |
|||
this.showPopper = val |
|||
this.$emit('input', val) |
|||
} |
|||
}, |
|||
|
|||
showPopper(val) { |
|||
if (this.disabled) return |
|||
val ? this.updatePopper() : this.destroyPopper() |
|||
this.$emit('input', val) |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
createPopper() { |
|||
if (this.$isServer) return |
|||
this.currentPlacement = this.currentPlacement || this.placement |
|||
if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.currentPlacement)) { |
|||
return |
|||
} |
|||
|
|||
const options = this.popperOptions |
|||
const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper |
|||
let reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference |
|||
|
|||
if (!reference && |
|||
this.$slots.reference && |
|||
this.$slots.reference[0]) { |
|||
reference = this.referenceElm = this.$slots.reference[0].elm |
|||
} |
|||
|
|||
if (!popper || !reference) return |
|||
if (this.visibleArrow) this.appendArrow(popper) |
|||
if (this.appendToBody) document.body.appendChild(this.popperElm) |
|||
if (this.popperJS && this.popperJS.destroy) { |
|||
this.popperJS.destroy() |
|||
} |
|||
options.placement = this.currentPlacement |
|||
options.offset = this.offset |
|||
options.arrowOffset = this.arrowOffset |
|||
this.popperJS = new PopperJS(reference, popper, options) |
|||
this.popperJS.onCreate(_ => { |
|||
this.$emit('created', this) |
|||
this.resetTransformOrigin() |
|||
this.$nextTick(this.updatePopper) |
|||
}) |
|||
if (typeof options.onUpdate === 'function') { |
|||
this.popperJS.onUpdate(options.onUpdate) |
|||
} |
|||
this.popperJS._popper.style.zIndex = PopupManager.nextZIndex() |
|||
this.popperElm.addEventListener('click', stop) |
|||
}, |
|||
|
|||
updatePopper() { |
|||
const popperJS = this.popperJS |
|||
if (popperJS) { |
|||
popperJS.update() |
|||
if (popperJS._popper) { |
|||
popperJS._popper.style.zIndex = PopupManager.nextZIndex() |
|||
} |
|||
} else { |
|||
this.createPopper() |
|||
} |
|||
}, |
|||
|
|||
doDestroy(forceDestroy) { |
|||
/* istanbul ignore if */ |
|||
if (!this.popperJS || (this.showPopper && !forceDestroy)) return |
|||
if (!forceDestroy) { |
|||
if (this.popperElm && this.popperElm.parentNode === document.body) { |
|||
this.popperElm.removeEventListener('click', stop) |
|||
document.body.removeChild(this.popperElm) |
|||
} |
|||
} |
|||
this.popperJS.destroy() |
|||
this.popperJS = null |
|||
}, |
|||
|
|||
destroyPopper() { |
|||
if (this.popperJS) { |
|||
this.resetTransformOrigin() |
|||
} |
|||
}, |
|||
|
|||
resetTransformOrigin() { |
|||
if (!this.transformOrigin) return |
|||
const placementMap = { |
|||
top: 'bottom', |
|||
bottom: 'top', |
|||
left: 'right', |
|||
right: 'left' |
|||
} |
|||
const placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0] |
|||
const origin = placementMap[placement] |
|||
this.popperJS._popper.style.transformOrigin = typeof this.transformOrigin === 'string' |
|||
? this.transformOrigin |
|||
: ['top', 'bottom'].indexOf(placement) > -1 ? `center ${origin}` : `${origin} center` |
|||
}, |
|||
|
|||
appendArrow(element) { |
|||
let hash |
|||
if (this.appended) { |
|||
return |
|||
} |
|||
|
|||
this.appended = true |
|||
|
|||
for (const item in element.attributes) { |
|||
if (/^_v-/.test(element.attributes[item].name)) { |
|||
hash = element.attributes[item].name |
|||
break |
|||
} |
|||
} |
|||
|
|||
const arrow = document.createElement('div') |
|||
|
|||
if (hash) { |
|||
arrow.setAttribute(hash, '') |
|||
} |
|||
arrow.setAttribute('x-arrow', '') |
|||
arrow.className = 'popper__arrow' |
|||
element.appendChild(arrow) |
|||
} |
|||
}, |
|||
|
|||
beforeDestroy() { |
|||
this.doDestroy(true) |
|||
if (this.popperElm && this.popperElm.parentNode === document.body) { |
|||
this.popperElm.removeEventListener('click', stop) |
|||
document.body.removeChild(this.popperElm) |
|||
} |
|||
}, |
|||
|
|||
// call destroy in keep-alive mode
|
|||
deactivated() { |
|||
this.$options.beforeDestroy[0].call(this) |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
import './style/index.js' |
|||
|
|||
import MdsMenuLocal from './menu' |
|||
import MdsItemLocal from './menu-item' |
|||
import MdsSubMenuLocal from './menu-submenu' |
|||
import MdsItemGroupLocal from './menu-itemgroup' |
|||
|
|||
export default { |
|||
MdsMenuLocal, |
|||
MdsItemLocal, |
|||
MdsSubMenuLocal, |
|||
MdsItemGroupLocal |
|||
} |
@ -0,0 +1,95 @@ |
|||
<template> |
|||
<li |
|||
role="menuitem" |
|||
:aria-selected="selected" |
|||
:aria-disabled="disabled" |
|||
:class="classes" |
|||
:style="style" |
|||
@click="handleClick" |
|||
@keydown.enter="handleKeyDown" |
|||
> |
|||
<slot /> |
|||
</li> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'MdsMenuItemLocal', |
|||
inject: ['menuRoot'], |
|||
props: { |
|||
disabled: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
index: [String, Number] |
|||
}, |
|||
_parent: null, |
|||
computed: { |
|||
classes() { |
|||
const prefixCls = this.menuRoot.prefixCls |
|||
return [ |
|||
`${prefixCls}-item`, |
|||
{ |
|||
[`${prefixCls}-item-disabled`]: this.disabled, |
|||
[`${prefixCls}-item-selected`]: this.selected |
|||
} |
|||
] |
|||
}, |
|||
style() { |
|||
const res = {} |
|||
if (this.mode === 'inline' && this.level > 0) { |
|||
res['padding-left'] = this.level * this.inlineIndent + 'px' |
|||
} |
|||
return res |
|||
}, |
|||
// From parent |
|||
multiple() { |
|||
return this.$options._parent.multiple |
|||
}, |
|||
mode() { |
|||
if (this.inlineCollapsed) { |
|||
return 'vertical' |
|||
} else { |
|||
return this.$options._parent.mode |
|||
} |
|||
}, |
|||
inlineCollapsed() { |
|||
return this.$options._parent.inlineCollapsed |
|||
}, |
|||
selected() { |
|||
return this.$options._parent.selected.indexOf(this.index) > -1 |
|||
}, |
|||
level() { |
|||
return this.$options._parent.level + 1 |
|||
}, |
|||
path() { |
|||
return this.$options._parent.path.slice().concat(this.index) |
|||
}, |
|||
inlineIndent() { |
|||
return this.$options._parent.inlineIndent |
|||
} |
|||
}, |
|||
created() { |
|||
this.$options._parent = this.$parent |
|||
while (!this.$options._parent.mode) { |
|||
this.$options._parent = this.$options._parent.$parent |
|||
} |
|||
}, |
|||
methods: { |
|||
handleClick(e) { |
|||
const info = { |
|||
e, |
|||
vm: this, |
|||
path: this.path, |
|||
index: this.index |
|||
} |
|||
this.$options._parent.handleClickItem(info) |
|||
this.multiple ? this.selected ? this.$options._parent.handleDeSelect(info) : this.$options._parent.handleSelect(info) |
|||
: !this.selected && this.$options._parent.handleSelect(info) |
|||
}, |
|||
handleKeyDown(e) { |
|||
this.handleClick(e) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,79 @@ |
|||
<template> |
|||
<li |
|||
:class="`${prefixCls}-item-group`" |
|||
> |
|||
<div |
|||
v-if="title" |
|||
:class="`${prefixCls}-item-group-title`" |
|||
:style="style" |
|||
v-text="title" |
|||
/> |
|||
<ul |
|||
v-if="$slots.default" |
|||
:class="`${prefixCls}-item-group-list`" |
|||
> |
|||
<slot /> |
|||
</ul> |
|||
</li> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'MdsMenuItemGroupLocal', |
|||
inject: ['menuRoot'], |
|||
props: { |
|||
title: String |
|||
}, |
|||
_parent: null, |
|||
data() { |
|||
return { |
|||
prefixCls: this.menuRoot.prefixCls |
|||
} |
|||
}, |
|||
computed: { |
|||
style() { |
|||
const res = {} |
|||
if (this.mode === 'inline' && this.level > 0) { |
|||
res['padding-left'] = (this.level + 1) * this.inlineIndent + 'px' |
|||
} |
|||
return res |
|||
}, |
|||
mode() { |
|||
return this.$options._parent.mode |
|||
}, |
|||
multiple() { |
|||
return this.$options._parent.multiple |
|||
}, |
|||
level() { |
|||
return this.$options._parent.level |
|||
}, |
|||
inlineIndent() { |
|||
return this.$options._parent.inlineIndent |
|||
}, |
|||
path() { |
|||
return this.$options._parent.path.slice() |
|||
}, |
|||
selected() { |
|||
return this.$options._parent.selected |
|||
}, |
|||
handleClickItem() { |
|||
return this.$options._parent.handleClickItem |
|||
}, |
|||
handleSelect() { |
|||
return this.$options._parent.handleSelect |
|||
}, |
|||
handleDeSelect() { |
|||
return this.$options._parent.handleDeSelect |
|||
}, |
|||
handleOpenChange() { |
|||
return this.$options._parent.handleOpenChange |
|||
} |
|||
}, |
|||
created() { |
|||
this.$options._parent = this.$parent |
|||
while (!this.$options._parent.mode) { |
|||
this.$options._parent = this.$options._parent.$parent |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,158 @@ |
|||
<template> |
|||
<li |
|||
:aria-expanded="isOpen" |
|||
aria-haspopup="true" |
|||
:class="[ |
|||
`${prefixCls}-submenu`, |
|||
`${prefixCls}-submenu-${mode}`, |
|||
disabled ? `${prefixCls}-submenu-disabled` : ``, |
|||
isOpen ? `${prefixCls}-submenu-open` : `` |
|||
]" |
|||
@mouseenter="handleMouseEnter" |
|||
@mouseleave="handleMouseLeave" |
|||
> |
|||
<div |
|||
v-if="$slots.title || title" |
|||
:class="`${prefixCls}-submenu-title`" |
|||
:style="style" |
|||
@click="handleClick" |
|||
> |
|||
<slot name="title">{{ title }}</slot> |
|||
<mds-icon type="down" :class="`${prefixCls}-submenu-title-after`" /> |
|||
</div> |
|||
<mds-transition v-if="$slots.default" :type="animition.type" :motion="animition.motion"> |
|||
<ul |
|||
v-show="isOpen" |
|||
:class="[ |
|||
prefixCls, |
|||
`${prefixCls}-sub`, |
|||
`${prefixCls}-${subMode}` |
|||
]" |
|||
> |
|||
<slot /> |
|||
</ul> |
|||
</mds-transition> |
|||
</li> |
|||
</template> |
|||
|
|||
<script> |
|||
import { switchcase } from './_util/switchcase' |
|||
|
|||
export default { |
|||
name: 'MdsMenuSubmenuLocal', |
|||
inject: ['menuRoot'], |
|||
props: { |
|||
disabled: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
index: [String, Number], |
|||
title: String |
|||
}, |
|||
_parent: null, |
|||
data() { |
|||
return { |
|||
timer: null, |
|||
prefixCls: this.menuRoot.prefixCls |
|||
} |
|||
}, |
|||
computed: { |
|||
animition() { |
|||
return switchcase({ |
|||
'horizontal': { |
|||
type: 'slide', |
|||
motion: 'up' |
|||
}, |
|||
'vertical': { |
|||
type: 'zoom', |
|||
motion: 'big' |
|||
}, |
|||
'inline': { |
|||
type: 'collapse' |
|||
} |
|||
})('')(this.mode) |
|||
}, |
|||
path() { |
|||
return this.$options._parent.path.slice().concat(this.index) |
|||
}, |
|||
style() { |
|||
const res = {} |
|||
if (this.mode === 'inline' && this.level > 0) { |
|||
res['padding-left'] = this.level * this.inlineIndent + 'px' |
|||
} |
|||
return res |
|||
}, |
|||
// From parent |
|||
mode() { |
|||
if (this.inlineCollapsed) { |
|||
return 'vertical' |
|||
} else { |
|||
return this.$options._parent.mode |
|||
} |
|||
}, |
|||
inlineCollapsed() { |
|||
return this.$options._parent.inlineCollapsed |
|||
}, |
|||
multiple() { |
|||
return this.$options._parent.multiple |
|||
}, |
|||
subMode() { |
|||
if (this.inlineCollapsed) { |
|||
return 'vertical' |
|||
} else { |
|||
return this.$options._parent.mode === 'horizontal' ? 'vertical' : this.$options._parent.mode |
|||
} |
|||
}, |
|||
level() { |
|||
return this.$options._parent.level + 1 |
|||
}, |
|||
inlineIndent() { |
|||
return this.$options._parent.inlineIndent |
|||
}, |
|||
isOpen() { |
|||
return this.$options._parent.open.indexOf(this.index) > -1 |
|||
}, |
|||
open() { |
|||
return this.$options._parent.open |
|||
}, |
|||
selected() { |
|||
return this.$options._parent.selected |
|||
}, |
|||
handleClickItem() { |
|||
return this.$options._parent.handleClickItem |
|||
}, |
|||
handleSelect() { |
|||
return this.$options._parent.handleSelect |
|||
}, |
|||
handleDeSelect() { |
|||
return this.$options._parent.handleDeSelect |
|||
}, |
|||
handleOpenChange() { |
|||
return this.$options._parent.handleOpenChange |
|||
} |
|||
}, |
|||
created() { |
|||
this.$options._parent = this.$parent |
|||
while (!this.$options._parent.mode) { |
|||
this.$options._parent = this.$options._parent.$parent |
|||
} |
|||
}, |
|||
methods: { |
|||
handleClick() { |
|||
if (this.mode !== 'inline') return |
|||
this.$options._parent.handleOpenChange(this.index, !this.isOpen) |
|||
}, |
|||
handleMouseEnter(e) { |
|||
if (this.mode === 'inline') return |
|||
this.timer && clearTimeout(this.timer) |
|||
this.$options._parent.handleOpenChange(this.index, true) |
|||
}, |
|||
handleMouseLeave(e) { |
|||
if (this.mode === 'inline') return |
|||
this.timer = setTimeout(() => { |
|||
this.$options._parent.handleOpenChange(this.index, false) |
|||
}, 100) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,165 @@ |
|||
<template> |
|||
<ul |
|||
aria-activedescendant |
|||
role="menu" |
|||
:class="classes" |
|||
> |
|||
<slot /> |
|||
</ul> |
|||
</template> |
|||
|
|||
<script> |
|||
import { oneOf } from './_util/proptype' |
|||
export default { |
|||
name: 'MdsMenuLocal', |
|||
provide() { |
|||
return { |
|||
menuRoot: this |
|||
} |
|||
}, |
|||
props: { |
|||
prefixCls: { |
|||
type: String, |
|||
default: 'mds-menu' |
|||
}, |
|||
defaultSelectedKeys: { |
|||
type: Array, |
|||
default() { |
|||
return [] |
|||
} |
|||
}, |
|||
defaultOpenKeys: { |
|||
type: Array, |
|||
default() { |
|||
return [] |
|||
} |
|||
}, |
|||
inlineCollapsed: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
inlineIndent: { |
|||
type: Number, |
|||
default: 24 |
|||
}, |
|||
mode: { |
|||
type: String, |
|||
default: 'vertical', |
|||
validator(value) { |
|||
return oneOf(value, ['vertical', 'horizontal', 'inline']) |
|||
} |
|||
}, |
|||
multiple: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
openKeys: { |
|||
type: Array, |
|||
default() { |
|||
return [] |
|||
} |
|||
}, |
|||
selectable: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
selectedKeys: { |
|||
type: Array, |
|||
default() { |
|||
return [] |
|||
} |
|||
}, |
|||
theme: { |
|||
type: String, |
|||
default: 'light', |
|||
validator(value) { |
|||
return oneOf(value, ['dark', 'light']) |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
level: 0, |
|||
path: [], |
|||
selected: [], |
|||
open: [] |
|||
} |
|||
}, |
|||
computed: { |
|||
classes() { |
|||
const prefixCls = this.prefixCls |
|||
return [ |
|||
`${prefixCls}`, |
|||
`${prefixCls}-root`, |
|||
`${prefixCls}-${this.theme}`, |
|||
`${prefixCls}-${this.mode}`, |
|||
{ |
|||
[`${prefixCls}-inline-collapsed`]: this.inlineCollapsed |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
watch: { |
|||
openKeys(value) { |
|||
this.open = value.slice() |
|||
}, |
|||
selectedKeys(value) { |
|||
this.selected = value.slice() |
|||
}, |
|||
inlineCollapsed(value) { |
|||
if (value) { |
|||
this.mode = 'vertical' |
|||
} |
|||
} |
|||
}, |
|||
created() { |
|||
function mergeDefaultAndSetting(def, setting) { |
|||
const arr = setting.length ? setting.slice() |
|||
: def.length ? def.slice() : [] |
|||
return arr |
|||
} |
|||
this.selected = mergeDefaultAndSetting(this.defaultSelectedKeys, this.selectedKeys) |
|||
this.open = mergeDefaultAndSetting(this.defaultOpenKeys, this.openKeys) |
|||
}, |
|||
methods: { |
|||
handleClickItem(info) { |
|||
this.mode !== 'inline' && (this.open = []) |
|||
this.$emit('click', info) |
|||
}, |
|||
handleDeSelect(info) { |
|||
const { index } = info |
|||
if (!this.selectable) return |
|||
this.removeArrayEle(this.selected, index) |
|||
this.$emit('de-select', info) |
|||
}, |
|||
removeArrayEle(arr, val) { |
|||
for (var i = 0; i < arr.length; i++) { |
|||
if (arr[i] === val) { |
|||
arr.splice(i, 1) |
|||
break |
|||
} |
|||
} |
|||
}, |
|||
handleOpenChange(index, isIncrease) { |
|||
let changed = false |
|||
const increaseOpen = () => { |
|||
const pos = this.open.indexOf(index) |
|||
pos < 0 && this.open.push(index) && (changed = true) |
|||
} |
|||
const deleteOpen = () => { |
|||
const pos = this.open.indexOf(index) |
|||
pos > -1 && this.open.splice(pos, 1) && (changed = true) |
|||
} |
|||
isIncrease ? increaseOpen() : deleteOpen() |
|||
changed && this.$emit('open-change', this.open) |
|||
}, |
|||
handleSelect(info) { |
|||
const { index } = info |
|||
if (!this.selectable) return |
|||
this.selected = this.multiple ? this.selected.concat([index]) : [index] |
|||
info.selected = this.selected |
|||
this.$emit('select', info) |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,2 @@ |
|||
import './style/index.less' |
|||
import './index.less' |
@ -0,0 +1,717 @@ |
|||
@import "./style/themes/default"; |
|||
@import "./style/mixins/index"; |
|||
|
|||
@menu-prefix-cls: ~"@{mds-prefix}-menu"; |
|||
@menu-default-inline-submie-color: #CCD2DB; |
|||
|
|||
@tooltip-prefix-cls: ~"@{mds-prefix}-tooltip"; |
|||
|
|||
// Base class |
|||
.@{tooltip-prefix-cls} { |
|||
position: absolute; |
|||
z-index: @zindex-tooltip; |
|||
display: block; |
|||
visibility: visible; |
|||
font-size: @font-size-base; |
|||
line-height: @line-height-base; |
|||
|
|||
&-hidden { |
|||
display: none; |
|||
} |
|||
|
|||
&-placement-top, |
|||
&-placement-topLeft, |
|||
&-placement-topRight { |
|||
padding-bottom: @tooltip-distance; |
|||
} |
|||
&-placement-right, |
|||
&-placement-rightTop, |
|||
&-placement-rightBottom { |
|||
padding-left: @tooltip-distance; |
|||
} |
|||
&-placement-bottom, |
|||
&-placement-bottomLeft, |
|||
&-placement-bottomRight { |
|||
padding-top: @tooltip-distance; |
|||
} |
|||
&-placement-left, |
|||
&-placement-leftTop, |
|||
&-placement-leftBottom { |
|||
padding-right: @tooltip-distance; |
|||
} |
|||
} |
|||
|
|||
// Wrapper for the tooltip content |
|||
.@{tooltip-prefix-cls}-inner { |
|||
max-width: @tooltip-max-width; |
|||
padding: 8px 16px; |
|||
color: @tooltip-color; |
|||
text-align: center; |
|||
text-decoration: none; |
|||
background-color: @tooltip-bg; |
|||
border-radius: @border-radius-base; |
|||
box-shadow: @box-shadow-base; |
|||
min-height: 34px; |
|||
font-size:@f14; |
|||
font-family:PingFangSC-Regular; |
|||
font-weight:@w400; |
|||
line-height:22px; |
|||
} |
|||
|
|||
// Arrows |
|||
.@{tooltip-prefix-cls}-arrow { |
|||
position: absolute; |
|||
width: 0; |
|||
height: 0; |
|||
border-color: transparent; |
|||
border-style: solid; |
|||
} |
|||
|
|||
.@{tooltip-prefix-cls} { |
|||
&-placement-top &-arrow, |
|||
&-placement-topLeft &-arrow, |
|||
&-placement-topRight &-arrow { |
|||
bottom: @tooltip-distance - @tooltip-arrow-width; |
|||
border-width: @tooltip-arrow-width @tooltip-arrow-width 0; |
|||
border-top-color: @tooltip-arrow-color; |
|||
} |
|||
|
|||
&-placement-top &-arrow { |
|||
left: 50%; |
|||
margin-left: -@tooltip-arrow-width; |
|||
} |
|||
|
|||
&-placement-topLeft &-arrow { |
|||
left: 16px; |
|||
} |
|||
|
|||
&-placement-topRight &-arrow { |
|||
right: 16px; |
|||
} |
|||
|
|||
&-placement-right &-arrow, |
|||
&-placement-rightTop &-arrow, |
|||
&-placement-rightBottom &-arrow { |
|||
left: @tooltip-distance - @tooltip-arrow-width; |
|||
border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0; |
|||
border-right-color: @tooltip-arrow-color; |
|||
} |
|||
|
|||
&-placement-right &-arrow { |
|||
top: 50%; |
|||
margin-top: -@tooltip-arrow-width; |
|||
} |
|||
|
|||
&-placement-rightTop &-arrow { |
|||
top: 8px; |
|||
} |
|||
|
|||
&-placement-rightBottom &-arrow { |
|||
bottom: 8px; |
|||
} |
|||
|
|||
&-placement-left &-arrow, |
|||
&-placement-leftTop &-arrow, |
|||
&-placement-leftBottom &-arrow { |
|||
right: @tooltip-distance - @tooltip-arrow-width; |
|||
border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width; |
|||
border-left-color: @tooltip-arrow-color; |
|||
} |
|||
|
|||
&-placement-left &-arrow { |
|||
top: 50%; |
|||
margin-top: -@tooltip-arrow-width; |
|||
} |
|||
|
|||
&-placement-leftTop &-arrow { |
|||
top: 8px; |
|||
} |
|||
|
|||
&-placement-leftBottom &-arrow { |
|||
bottom: 8px; |
|||
} |
|||
|
|||
&-placement-bottom &-arrow, |
|||
&-placement-bottomLeft &-arrow, |
|||
&-placement-bottomRight &-arrow { |
|||
top: @tooltip-distance - @tooltip-arrow-width; |
|||
border-width: 0 @tooltip-arrow-width @tooltip-arrow-width; |
|||
border-bottom-color: @tooltip-arrow-color; |
|||
} |
|||
|
|||
&-placement-bottom &-arrow { |
|||
left: 50%; |
|||
margin-left: -@tooltip-arrow-width; |
|||
} |
|||
|
|||
&-placement-bottomLeft &-arrow { |
|||
left: 16px; |
|||
} |
|||
|
|||
&-placement-bottomRight &-arrow { |
|||
right: 16px; |
|||
} |
|||
} |
|||
|
|||
// default theme |
|||
.@{menu-prefix-cls} { |
|||
outline: none; |
|||
margin-bottom: 0; |
|||
padding-left: 0; // Override default ul/ol |
|||
list-style: none; |
|||
z-index: @zindex-dropdown; |
|||
box-shadow: @box-shadow-base; |
|||
color: @text-color-base ; |
|||
background: @component-background; |
|||
line-height: 46px; |
|||
transition: background .3s, width .2s; |
|||
|
|||
&-hidden { |
|||
display: none; |
|||
} |
|||
|
|||
&-item-group-list { |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
&-item-group-title { |
|||
color: @text-color-secondary; |
|||
font-size:@menu-font-size; |
|||
line-height: @line-height-base; |
|||
padding: 8px 16px; |
|||
transition: all .3s; |
|||
} |
|||
&-item .point{ |
|||
position: relative; |
|||
top :-2px; |
|||
display: inline-block; |
|||
width: 3px; |
|||
height: 3px; |
|||
margin-right: 10px; |
|||
border-radius: 50%; |
|||
background:rgba(200,208,221,1); |
|||
vertical-align: middle; |
|||
} |
|||
&-item, |
|||
&-submenu, |
|||
&-submenu-title { |
|||
vertical-align: middle; |
|||
cursor: pointer; |
|||
} |
|||
&-submenu, &-submenu-inline { |
|||
transition: border-color .3s @ease-in-out, background .3s @ease-in-out, padding .15s @ease-in-out; |
|||
} |
|||
&-item, &-submenu-title { |
|||
transition: color .3s @ease-in-out, border-color .3s @ease-in-out, background .3s @ease-in-out, padding .15s @ease-in-out; |
|||
} |
|||
|
|||
|
|||
&-item:active, |
|||
&-submenu-title:active { |
|||
background: @item-active-bg; |
|||
} |
|||
|
|||
&-submenu &-sub { |
|||
cursor: initial; |
|||
transition: background .3s @ease-in-out, padding .3s @ease-in-out; |
|||
} |
|||
|
|||
&-item > a { |
|||
display: block; |
|||
color: @text-color; |
|||
&:hover { |
|||
color: @primary-color; |
|||
} |
|||
&:focus { |
|||
text-decoration: none; |
|||
} |
|||
&:before { |
|||
position: absolute; |
|||
background-color: transparent; |
|||
width: 100%; |
|||
height: 100%; |
|||
top: 0; |
|||
left: 0; |
|||
bottom: 0; |
|||
right: 0; |
|||
content: ''; |
|||
} |
|||
} |
|||
|
|||
&-item-divider { |
|||
height: 1px; |
|||
overflow: hidden; |
|||
background-color: @border-color-split; |
|||
line-height: 0; |
|||
} |
|||
|
|||
&-item:hover, |
|||
&-item-active, |
|||
&:not(&-inline) &-submenu-open, |
|||
&-submenu-active, |
|||
&-submenu-title:hover { |
|||
color: @primary-color; |
|||
} |
|||
|
|||
&:not(&-inline) &-submenu-open { |
|||
z-index: @zindex-dropdown; |
|||
} |
|||
|
|||
&-horizontal &-item, |
|||
&-horizontal &-submenu { |
|||
margin-top: -1px; |
|||
} |
|||
|
|||
&-horizontal > &-item:hover, |
|||
&-horizontal > &-item-active, |
|||
&-horizontal > &-submenu &-submenu-title:hover { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
&-item-selected { |
|||
color: #0366FF; |
|||
> a, |
|||
> a:hover { |
|||
color: #0366FF; |
|||
} |
|||
.point{ |
|||
background-color: #0366FF; |
|||
} |
|||
} |
|||
|
|||
&:not(&-horizontal) &-item-selected { |
|||
background:rgba(237,243,254,1) |
|||
} |
|||
|
|||
&-horizontal, |
|||
&-inline, |
|||
&-vertical { |
|||
z-index: auto; |
|||
} |
|||
|
|||
&-inline, |
|||
&-vertical { |
|||
// border-right: @border-width-base @border-style-base @border-color-split; |
|||
.@{menu-prefix-cls}-item { |
|||
margin-left: -1px; |
|||
left: 1px; |
|||
position: relative; |
|||
z-index: 1; |
|||
&:after { |
|||
content: ""; |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
bottom: 0; |
|||
border-left: 3px solid #0366ff; |
|||
transform: scaleY(.0001); |
|||
opacity: 0; |
|||
transition: transform .15s @ease-out, opacity .15s @ease-out; |
|||
} |
|||
} |
|||
} |
|||
|
|||
&-vertical&-sub { |
|||
border-right: 0; |
|||
.@{menu-prefix-cls}-item { |
|||
border-right: 0; |
|||
margin-left: 0; |
|||
left: 0; |
|||
&:after { |
|||
border-right: 0; |
|||
} |
|||
} |
|||
> .@{menu-prefix-cls}-item:first-child { |
|||
border-radius: @border-radius-base @border-radius-base 0 0; |
|||
} |
|||
> .@{menu-prefix-cls}-item:last-child, |
|||
> .@{menu-prefix-cls}-item-group:last-child > .@{menu-prefix-cls}-item-group-list:last-child > .@{menu-prefix-cls}-item:last-child { |
|||
border-radius: 0 0 @border-radius-base @border-radius-base; |
|||
} |
|||
> .@{menu-prefix-cls}-item:only-child { |
|||
border-radius: @border-radius-base; |
|||
} |
|||
} |
|||
|
|||
&-inline { |
|||
width: 100%; |
|||
.@{menu-prefix-cls}-selected, |
|||
.@{menu-prefix-cls}-item-selected { |
|||
&:after { |
|||
transition: transform .15s @ease-in-out, opacity .15s @ease-in-out; |
|||
opacity: 1; |
|||
transform: scaleY(1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
&-submenu-horizontal > & { |
|||
top: 100%; |
|||
left: 0; |
|||
position: absolute; |
|||
min-width: 100%; |
|||
margin-top: 7px; |
|||
z-index: @zindex-dropdown; |
|||
} |
|||
|
|||
&-submenu-vertical { |
|||
z-index: 1; |
|||
} |
|||
|
|||
&-submenu-vertical > & { |
|||
top: 0; |
|||
left: 100%; |
|||
position: absolute; |
|||
min-width: 160px; |
|||
margin-left: 4px; |
|||
z-index: @zindex-dropdown; |
|||
} |
|||
|
|||
&-item, |
|||
&-submenu-title { |
|||
margin: 0; |
|||
padding: 0 20px; |
|||
position: relative; |
|||
display: block; |
|||
white-space: nowrap; |
|||
.@{iconfont-css-prefix} { |
|||
width:16px; |
|||
margin-right: 8px; |
|||
transition: font-size .15s @ease-out, margin .3s @ease-in-out; |
|||
+ span { |
|||
transition: opacity .3s @ease-in-out, width .3s @ease-in-out; |
|||
opacity: 1; |
|||
} |
|||
} |
|||
} |
|||
|
|||
& > &-item-divider { |
|||
height: 1px; |
|||
margin: 1px 0; |
|||
overflow: hidden; |
|||
padding: 0; |
|||
line-height: 0; |
|||
background-color: @border-color-split; |
|||
} |
|||
|
|||
&-submenu { |
|||
position: relative; |
|||
|
|||
> .@{menu-prefix-cls} { |
|||
background-color: @component-background; |
|||
border-radius: @border-radius-base; |
|||
&-submenu-title:after { |
|||
transition: transform .3s @ease-in-out; |
|||
} |
|||
} |
|||
|
|||
&-vertical > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-title-after { |
|||
// font-family: "mdsicon" !important; |
|||
font-style: normal; |
|||
vertical-align: baseline; |
|||
text-align: center; |
|||
text-transform: none; |
|||
text-rendering: auto; |
|||
position: absolute; |
|||
// content: "\e62a"; |
|||
color: @menu-default-inline-submie-color; |
|||
font-size: 12px; |
|||
right: 16px; |
|||
top: 50%; |
|||
margin-top: -6px; |
|||
.ie-rotate(3); |
|||
transform: rotate(270deg); |
|||
} |
|||
|
|||
&-inline > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-title-after { |
|||
// font-family: "mdsicon" !important; |
|||
font-style: normal; |
|||
vertical-align: baseline; |
|||
text-align: center; |
|||
text-transform: none; |
|||
text-rendering: auto; |
|||
position: absolute; |
|||
color: @menu-default-inline-submie-color; |
|||
// content: "\e62a"; |
|||
right: 16px; |
|||
top: 50%; |
|||
margin-top: -6px; |
|||
font-size: 12px; |
|||
} |
|||
|
|||
&-open { |
|||
&.@{menu-prefix-cls}-submenu-inline > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-title-after { |
|||
.ie-rotate(1); |
|||
transform: rotate(180deg); |
|||
} |
|||
} |
|||
} |
|||
|
|||
&-vertical &-submenu-selected { |
|||
color: @primary-color; |
|||
> a { |
|||
color: @primary-color; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
&-horizontal { |
|||
border: 0; |
|||
border-bottom: @border-width-base @border-style-base @border-color-split; |
|||
box-shadow: none; |
|||
z-index: 0; |
|||
|
|||
> .@{menu-prefix-cls}-item, |
|||
> .@{menu-prefix-cls}-submenu { |
|||
position: relative; |
|||
top: 1px; |
|||
float: left; |
|||
border-bottom: 2px solid transparent; |
|||
|
|||
&:hover, |
|||
&-active, |
|||
&-open, |
|||
&-selected { |
|||
border-bottom: 2px solid @primary-color; |
|||
color: @primary-color; |
|||
} |
|||
|
|||
> a { |
|||
display: block; |
|||
color: @text-color; |
|||
&:hover { |
|||
color: @primary-color; |
|||
} |
|||
} |
|||
} |
|||
|
|||
&:after { |
|||
content: "\20"; |
|||
display: block; |
|||
height: 0; |
|||
clear: both; |
|||
} |
|||
} |
|||
|
|||
&-vertical, |
|||
&-inline { |
|||
.@{menu-prefix-cls}-item, |
|||
.@{menu-prefix-cls}-submenu-title { |
|||
padding: 0 16px; |
|||
font-size: @menu-font-size; |
|||
line-height: 44px; |
|||
height: 44px; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
} |
|||
} |
|||
|
|||
&-inline-collapsed { |
|||
width: @menu-collapsed-width; |
|||
|
|||
> .@{menu-prefix-cls}-item, |
|||
> .@{menu-prefix-cls}-item-group > .@{menu-prefix-cls}-item-group-list > .@{menu-prefix-cls}-item, |
|||
> .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { |
|||
left: 0; |
|||
text-overflow: ellipsis; |
|||
padding: 0 (@menu-collapsed-width - 16px) / 2 !important; |
|||
.@{menu-prefix-cls}-submenu-title-after { |
|||
display: none; |
|||
} |
|||
.@{iconfont-css-prefix} { |
|||
font-size: 16px; |
|||
line-height: 42px; |
|||
margin: 0; |
|||
+ span { |
|||
max-width: 0; |
|||
display: inline-block !important; |
|||
opacity: 0; |
|||
} |
|||
} |
|||
} |
|||
&-tooltip { |
|||
pointer-events: none; |
|||
.@{iconfont-css-prefix} { |
|||
display: none; |
|||
} |
|||
a { |
|||
color: @text-color-dark; |
|||
} |
|||
} |
|||
|
|||
.@{menu-prefix-cls}-item-group-title { |
|||
overflow: hidden; |
|||
white-space: nowrap; |
|||
text-overflow: ellipsis; |
|||
padding-left: 4px; |
|||
padding-right: 4px; |
|||
|
|||
} |
|||
|
|||
.@{menu-prefix-cls}-item-group-list { |
|||
.@{menu-prefix-cls}-item, |
|||
.@{menu-prefix-cls}-submenu-title { |
|||
padding: 0 16px 0 28px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
&-item-group-list { |
|||
.@{menu-prefix-cls}-item, |
|||
.@{menu-prefix-cls}-submenu-title { |
|||
padding: 0 16px 0 28px; |
|||
} |
|||
} |
|||
|
|||
&-vertical&-sub { |
|||
padding: 0; |
|||
transform-origin: 0 0; |
|||
& > .@{menu-prefix-cls}-item, |
|||
& > .@{menu-prefix-cls}-submenu { |
|||
transform-origin: 0 0; |
|||
} |
|||
} |
|||
|
|||
&-root&-vertical, |
|||
&-root&-inline { |
|||
box-shadow: none; |
|||
} |
|||
|
|||
&-sub&-inline { |
|||
padding: 0; |
|||
border: 0; |
|||
box-shadow: none; |
|||
border-radius: 0; |
|||
& > .@{menu-prefix-cls}-item, |
|||
& > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { |
|||
line-height: 44px; |
|||
height: 44px; |
|||
list-style-type: disc; |
|||
list-style-position: inside; |
|||
} |
|||
// & > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-sub .mds-menu-item-group { |
|||
// line-height: 44px; |
|||
// height: 44px; |
|||
// list-style-type: disc; |
|||
// list-style-position: inside; |
|||
// } |
|||
|
|||
|
|||
& .@{menu-prefix-cls}-item-group-title { |
|||
padding-left: 48px; |
|||
} |
|||
} |
|||
|
|||
// Disabled state sets text to gray and nukes hover/tab effects |
|||
&-item-disabled, |
|||
&-submenu-disabled { |
|||
color: @disabled-color !important; |
|||
cursor: not-allowed; |
|||
background: none; |
|||
border-color: transparent !important; |
|||
> a { |
|||
color: @disabled-color !important; |
|||
pointer-events: none; |
|||
} |
|||
> .@{menu-prefix-cls}-submenu-title { |
|||
color: @disabled-color !important; |
|||
cursor: not-allowed; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// dark theme |
|||
.@{menu-prefix-cls} { |
|||
&-dark, |
|||
&-dark &-sub { |
|||
color: @menu-text-color-secondary-dark; |
|||
background: #2C405A; |
|||
} |
|||
|
|||
&-dark &-inline&-sub { |
|||
background: #24364D; |
|||
} |
|||
|
|||
&-dark&-horizontal { |
|||
border-bottom-color: @menu-dark-bg; |
|||
} |
|||
|
|||
&-dark&-horizontal > &-item, |
|||
&-dark&-horizontal > &-submenu { |
|||
border-color: @menu-dark-bg; |
|||
border-bottom: 0; |
|||
} |
|||
|
|||
&-dark &-item, |
|||
&-dark &-item-group-title, |
|||
&-dark &-item > a { |
|||
color:@menu-text-color-secondary-dark; |
|||
} |
|||
|
|||
&-dark&-inline, |
|||
&-dark&-vertical { |
|||
border-right: 0; |
|||
} |
|||
|
|||
&-dark&-inline &-item, |
|||
&-dark&-vertical &-item { |
|||
border-right: 0; |
|||
margin-left: 0; |
|||
left: 0; |
|||
&:after { |
|||
border-right: 0; |
|||
} |
|||
} |
|||
|
|||
&-dark &-item:hover, |
|||
&-dark &-item-active, |
|||
&-dark &-submenu-active, |
|||
&-dark:not(&-inline) &-submenu-open, |
|||
&-dark &-submenu-selected, |
|||
&-dark &-submenu-title:hover { |
|||
background-color: transparent; |
|||
color: #fff; |
|||
> a { |
|||
color: #fff; |
|||
} |
|||
} |
|||
|
|||
&-dark &-item-selected { |
|||
border-right: 0; |
|||
color: #fff; |
|||
&:after { |
|||
border-right: 0; |
|||
} |
|||
> a, |
|||
> a:hover { |
|||
color: #fff; |
|||
} |
|||
.point{ |
|||
background-color: #fff; |
|||
} |
|||
} |
|||
|
|||
&&-dark &-item-selected { |
|||
background-color: #0366ff; |
|||
} |
|||
|
|||
// Disabled state sets text to dark gray and nukes hover/tab effects |
|||
&-dark &-item-disabled, |
|||
&-dark &-submenu-disabled { |
|||
&, |
|||
> a { |
|||
opacity: 0.8; |
|||
color: @disabled-color-dark !important; |
|||
} |
|||
> .@{menu-prefix-cls}-submenu-title { |
|||
color: @disabled-color-dark !important; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,108 @@ |
|||
/* stylelint-disable declaration-bang-space-before */ |
|||
.bezierEasingMixin() { |
|||
@functions: ~`(function() { |
|||
var NEWTON_ITERATIONS = 4; |
|||
var NEWTON_MIN_SLOPE = 0.001; |
|||
var SUBDIVISION_PRECISION = 0.0000001; |
|||
var SUBDIVISION_MAX_ITERATIONS = 10; |
|||
|
|||
var kSplineTableSize = 11; |
|||
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); |
|||
|
|||
var float32ArraySupported = typeof Float32Array === 'function'; |
|||
|
|||
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } |
|||
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } |
|||
function C (aA1) { return 3.0 * aA1; } |
|||
|
|||
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. |
|||
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; } |
|||
|
|||
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. |
|||
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); } |
|||
|
|||
function binarySubdivide (aX, aA, aB, mX1, mX2) { |
|||
var currentX, currentT, i = 0; |
|||
do { |
|||
currentT = aA + (aB - aA) / 2.0; |
|||
currentX = calcBezier(currentT, mX1, mX2) - aX; |
|||
if (currentX > 0.0) { |
|||
aB = currentT; |
|||
} else { |
|||
aA = currentT; |
|||
} |
|||
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); |
|||
return currentT; |
|||
} |
|||
|
|||
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { |
|||
for (var i = 0; i < NEWTON_ITERATIONS; ++i) { |
|||
var currentSlope = getSlope(aGuessT, mX1, mX2); |
|||
if (currentSlope === 0.0) { |
|||
return aGuessT; |
|||
} |
|||
var currentX = calcBezier(aGuessT, mX1, mX2) - aX; |
|||
aGuessT -= currentX / currentSlope; |
|||
} |
|||
return aGuessT; |
|||
} |
|||
|
|||
var BezierEasing = function (mX1, mY1, mX2, mY2) { |
|||
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { |
|||
throw new Error('bezier x values must be in [0, 1] range'); |
|||
} |
|||
|
|||
// Precompute samples table |
|||
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); |
|||
if (mX1 !== mY1 || mX2 !== mY2) { |
|||
for (var i = 0; i < kSplineTableSize; ++i) { |
|||
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); |
|||
} |
|||
} |
|||
|
|||
function getTForX (aX) { |
|||
var intervalStart = 0.0; |
|||
var currentSample = 1; |
|||
var lastSample = kSplineTableSize - 1; |
|||
|
|||
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) { |
|||
intervalStart += kSampleStepSize; |
|||
} |
|||
--currentSample; |
|||
|
|||
// Interpolate to provide an initial guess for t |
|||
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]); |
|||
var guessForT = intervalStart + dist * kSampleStepSize; |
|||
|
|||
var initialSlope = getSlope(guessForT, mX1, mX2); |
|||
if (initialSlope >= NEWTON_MIN_SLOPE) { |
|||
return newtonRaphsonIterate(aX, guessForT, mX1, mX2); |
|||
} else if (initialSlope === 0.0) { |
|||
return guessForT; |
|||
} else { |
|||
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); |
|||
} |
|||
} |
|||
|
|||
return function BezierEasing (x) { |
|||
if (mX1 === mY1 && mX2 === mY2) { |
|||
return x; // linear |
|||
} |
|||
// Because JavaScript number are imprecise, we should guarantee the extremes are right. |
|||
if (x === 0) { |
|||
return 0; |
|||
} |
|||
if (x === 1) { |
|||
return 1; |
|||
} |
|||
return calcBezier(getTForX(x), mY1, mY2); |
|||
}; |
|||
}; |
|||
|
|||
this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18); |
|||
})()`; |
|||
} |
|||
// It is hacky way to make this function will be compiled preferentially by less |
|||
// resolve error: `ReferenceError: colorPalette is not defined` |
|||
// https://github.com/mds-design/mds-motion/issues/44 |
|||
.bezierEasingMixin(); |
@ -0,0 +1,46 @@ |
|||
@import "bezierEasing"; |
|||
@import "tinyColor"; |
|||
|
|||
// We create a very complex algorithm which take the place of original tint/shade color system |
|||
// to make sure no one can understand it 👻 |
|||
// and create an entire color palette magicly by inputing just a single primary color. |
|||
// We are using bezier-curve easing function and some color manipulations like tint/shade/darken/spin |
|||
.colorPaletteMixin() { |
|||
@functions: ~`(function() { |
|||
var warmDark = 0.5; // warm color darken radio |
|||
var warmRotate = -26; // warm color rotate degree |
|||
var coldDark = 0.55; // cold color darken radio |
|||
var coldRotate = 10; // cold color rotate degree |
|||
var getShadeColor = function(c) { |
|||
var shadeColor = tinycolor(c); |
|||
// warm and cold color will darken in different radio, and rotate in different degree |
|||
// warmer color |
|||
if (shadeColor.toRgb().r > shadeColor.toRgb().b) { |
|||
return shadeColor.darken(shadeColor.toHsl().l * warmDark * 100).spin(warmRotate).toHexString(); |
|||
} |
|||
// colder color |
|||
return shadeColor.darken(shadeColor.toHsl().l * coldDark * 100).spin(coldRotate).toHexString(); |
|||
} |
|||
var primaryEasing = colorEasing(0.6); |
|||
this.colorPalette = function(color, index) { |
|||
var currentEasing = colorEasing(index * 0.1); |
|||
// return light colors after tint |
|||
if (index <= 6) { |
|||
return tinycolor.mix( |
|||
'#ffffff', |
|||
color, |
|||
currentEasing * 100 / primaryEasing |
|||
).toHexString(); |
|||
} |
|||
return tinycolor.mix( |
|||
getShadeColor(color), |
|||
color, |
|||
(1 - (currentEasing - primaryEasing) / (1 - primaryEasing)) * 100 |
|||
).toHexString(); |
|||
}; |
|||
})()`; |
|||
} |
|||
// It is hacky way to make this function will be compiled preferentially by less |
|||
// resolve error: `ReferenceError: colorPalette is not defined` |
|||
// https://github.com/mds-design/mds-motion/issues/44 |
|||
.colorPaletteMixin(); |
@ -0,0 +1,92 @@ |
|||
@import 'colorPalette'; |
|||
|
|||
// color palettes |
|||
@blue-1: color(~`colorPalette("@{blue-6}", 1)`); |
|||
@blue-2: color(~`colorPalette("@{blue-6}", 2)`); |
|||
@blue-3: color(~`colorPalette("@{blue-6}", 3)`); |
|||
@blue-4: color(~`colorPalette("@{blue-6}", 4)`); |
|||
@blue-5: color(~`colorPalette("@{blue-6}", 5)`); |
|||
// @blue-6: #108ee9; |
|||
@blue-6: rgba(3,100,255,1); |
|||
@blue-7: color(~`colorPalette("@{blue-6}", 7)`); |
|||
@blue-8: color(~`colorPalette("@{blue-6}", 8)`); |
|||
@blue-9: color(~`colorPalette("@{blue-6}", 9)`); |
|||
@blue-10: color(~`colorPalette("@{blue-6}", 10)`); |
|||
|
|||
@purple-1: color(~`colorPalette("@{purple-6}", 1)`); |
|||
@purple-2: color(~`colorPalette("@{purple-6}", 2)`); |
|||
@purple-3: color(~`colorPalette("@{purple-6}", 3)`); |
|||
@purple-4: color(~`colorPalette("@{purple-6}", 4)`); |
|||
@purple-5: color(~`colorPalette("@{purple-6}", 5)`); |
|||
@purple-6: #7265e6; |
|||
@purple-7: color(~`colorPalette("@{purple-6}", 7)`); |
|||
@purple-8: color(~`colorPalette("@{purple-6}", 8)`); |
|||
@purple-9: color(~`colorPalette("@{purple-6}", 9)`); |
|||
@purple-10: color(~`colorPalette("@{purple-6}", 10)`); |
|||
|
|||
@cyan-1: color(~`colorPalette("@{cyan-6}", 1)`); |
|||
@cyan-2: color(~`colorPalette("@{cyan-6}", 2)`); |
|||
@cyan-3: color(~`colorPalette("@{cyan-6}", 3)`); |
|||
@cyan-4: color(~`colorPalette("@{cyan-6}", 4)`); |
|||
@cyan-5: color(~`colorPalette("@{cyan-6}", 5)`); |
|||
@cyan-6: #00a2ae; |
|||
@cyan-7: color(~`colorPalette("@{cyan-6}", 7)`); |
|||
@cyan-8: color(~`colorPalette("@{cyan-6}", 8)`); |
|||
@cyan-9: color(~`colorPalette("@{cyan-6}", 9)`); |
|||
@cyan-10: color(~`colorPalette("@{cyan-6}", 10)`); |
|||
|
|||
@green-1: color(~`colorPalette("@{green-6}", 1)`); |
|||
@green-2: color(~`colorPalette("@{green-6}", 2)`); |
|||
@green-3: color(~`colorPalette("@{green-6}", 3)`); |
|||
@green-4: color(~`colorPalette("@{green-6}", 4)`); |
|||
@green-5: color(~`colorPalette("@{green-6}", 5)`); |
|||
@green-6: #00a854; |
|||
@green-7: color(~`colorPalette("@{green-6}", 7)`); |
|||
@green-8: color(~`colorPalette("@{green-6}", 8)`); |
|||
@green-9: color(~`colorPalette("@{green-6}", 9)`); |
|||
@green-10: color(~`colorPalette("@{green-6}", 10)`); |
|||
|
|||
@pink-1: color(~`colorPalette("@{pink-6}", 1)`); |
|||
@pink-2: color(~`colorPalette("@{pink-6}", 2)`); |
|||
@pink-3: color(~`colorPalette("@{pink-6}", 3)`); |
|||
@pink-4: color(~`colorPalette("@{pink-6}", 4)`); |
|||
@pink-5: color(~`colorPalette("@{pink-6}", 5)`); |
|||
@pink-6: #f5317f; |
|||
@pink-7: color(~`colorPalette("@{pink-6}", 7)`); |
|||
@pink-8: color(~`colorPalette("@{pink-6}", 8)`); |
|||
@pink-9: color(~`colorPalette("@{pink-6}", 9)`); |
|||
@pink-10: color(~`colorPalette("@{pink-6}", 10)`); |
|||
|
|||
@red-1: color(~`colorPalette("@{red-6}", 1)`); |
|||
@red-2: color(~`colorPalette("@{red-6}", 2)`); |
|||
@red-3: color(~`colorPalette("@{red-6}", 3)`); |
|||
@red-4: color(~`colorPalette("@{red-6}", 4)`); |
|||
@red-5: color(~`colorPalette("@{red-6}", 5)`); |
|||
// @red-6: #f04134; |
|||
@red-6: #EE3333; |
|||
@red-7: color(~`colorPalette("@{red-6}", 7)`); |
|||
@red-8: color(~`colorPalette("@{red-6}", 8)`); |
|||
@red-9: color(~`colorPalette("@{red-6}", 9)`); |
|||
@red-10: color(~`colorPalette("@{red-6}", 10)`); |
|||
|
|||
@orange-1: color(~`colorPalette("@{orange-6}", 1)`); |
|||
@orange-2: color(~`colorPalette("@{orange-6}", 2)`); |
|||
@orange-3: color(~`colorPalette("@{orange-6}", 3)`); |
|||
@orange-4: color(~`colorPalette("@{orange-6}", 4)`); |
|||
@orange-5: color(~`colorPalette("@{orange-6}", 5)`); |
|||
@orange-6: #f56a00; |
|||
@orange-7: color(~`colorPalette("@{orange-6}", 7)`); |
|||
@orange-8: color(~`colorPalette("@{orange-6}", 8)`); |
|||
@orange-9: color(~`colorPalette("@{orange-6}", 9)`); |
|||
@orange-10: color(~`colorPalette("@{orange-6}", 10)`); |
|||
|
|||
@yellow-1: color(~`colorPalette("@{yellow-6}", 1)`); |
|||
@yellow-2: color(~`colorPalette("@{yellow-6}", 2)`); |
|||
@yellow-3: color(~`colorPalette("@{yellow-6}", 3)`); |
|||
@yellow-4: color(~`colorPalette("@{yellow-6}", 4)`); |
|||
@yellow-5: color(~`colorPalette("@{yellow-6}", 5)`); |
|||
@yellow-6: #ffbf00; |
|||
@yellow-7: color(~`colorPalette("@{yellow-6}", 7)`); |
|||
@yellow-8: color(~`colorPalette("@{yellow-6}", 8)`); |
|||
@yellow-9: color(~`colorPalette("@{yellow-6}", 9)`); |
|||
@yellow-10: color(~`colorPalette("@{yellow-6}", 10)`); |
1184
src/components/menu/style/style/color/tinyColor.less
File diff suppressed because it is too large
View File
@ -0,0 +1,126 @@ |
|||
@import "./normalize.less"; |
|||
|
|||
// http://stackoverflow.com/a/13611748/3040605 |
|||
@font-face { |
|||
font-family: "Helvetica Neue For Number"; |
|||
src: local("Helvetica Neue"); |
|||
unicode-range: U+30-39; |
|||
} |
|||
|
|||
* { |
|||
box-sizing: border-box; |
|||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); // remove tap highlight color for mobile safari |
|||
} |
|||
|
|||
*:before, |
|||
*:after { |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
// HTML & Body reset |
|||
html, body { |
|||
.square(100%); |
|||
} |
|||
|
|||
body { |
|||
font-family: @font-family; |
|||
font-size: @font-size-base; |
|||
line-height: @line-height-base; |
|||
color: @text-color; |
|||
background-color: @body-background; |
|||
} |
|||
|
|||
// unify the setting of elements's margin and padding for browsers |
|||
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
// Reset fonts for relevant elements |
|||
button,input,select,textarea { |
|||
font-family: inherit; |
|||
font-size: inherit; |
|||
line-height: inherit; |
|||
color: inherit; |
|||
} |
|||
|
|||
input[type="text"], |
|||
textarea { |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
ul, |
|||
ol { |
|||
list-style: none; |
|||
} |
|||
|
|||
// Remove the clear button of a text input control in IE10+ |
|||
input::-ms-clear, input::-ms-reveal { |
|||
display: none; |
|||
} |
|||
|
|||
::selection { |
|||
background: @primary-color; |
|||
color: #fff; |
|||
} |
|||
|
|||
// Headers |
|||
h1, h2, h3, h4, h5, h6 { |
|||
color: @heading-color; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
// Links |
|||
a { |
|||
color: @link-color; |
|||
background: transparent; |
|||
text-decoration: @link-decoration; |
|||
outline: none; |
|||
cursor: pointer; |
|||
transition: color .3s ease; |
|||
|
|||
&:focus { |
|||
text-decoration: underline; |
|||
text-decoration-skip: ink; |
|||
} |
|||
|
|||
&:hover { |
|||
color: @link-hover-color; |
|||
} |
|||
|
|||
&:active { |
|||
color: @link-active-color; |
|||
} |
|||
|
|||
&:active, |
|||
&:hover { |
|||
outline: 0; |
|||
text-decoration: @link-hover-decoration; |
|||
} |
|||
|
|||
&[disabled] { |
|||
color: @disabled-color; |
|||
cursor: not-allowed; |
|||
pointer-events: none; |
|||
} |
|||
} |
|||
|
|||
.@{mds-prefix}-divider { |
|||
margin: 0 6px; |
|||
display: inline-block; |
|||
height: 8px; |
|||
width: 1px; |
|||
background: #ccc; |
|||
} |
|||
|
|||
code, |
|||
kbd, |
|||
pre, |
|||
samp { |
|||
font-family: @code-family; |
|||
} |
|||
|
|||
// Utility classes |
|||
.clearfix { |
|||
.clearfix(); |
|||
} |
1181
src/components/menu/style/style/core/icon/iconfont.css
File diff suppressed because it is too large
View File
1
src/components/menu/style/style/core/icon/iconfont.js
File diff suppressed because it is too large
View File
2214
src/components/menu/style/style/core/iconfont.less
File diff suppressed because it is too large
View File
@ -0,0 +1,4 @@ |
|||
@import "../mixins/index"; |
|||
@import "base"; |
|||
@import "iconfont"; |
|||
@import "motion"; |
@ -0,0 +1,15 @@ |
|||
@import "../mixins/motion"; |
|||
@import "motion/fade"; |
|||
@import "motion/move"; |
|||
@import "motion/other"; |
|||
@import "motion/slide"; |
|||
@import "motion/swing"; |
|||
@import "motion/zoom"; |
|||
|
|||
// For common/openAnimation |
|||
.mds-motion-collapse { |
|||
overflow: hidden; |
|||
&-active { |
|||
transition: height .15s @ease-in-out, opacity .15s @ease-in-out !important; |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
.fade-motion(@className, @keyframeName) { |
|||
.make-motion(@className, @keyframeName); |
|||
.@{className}-enter, |
|||
.@{className}-appear { |
|||
opacity: 0; |
|||
animation-timing-function: linear; |
|||
} |
|||
.@{className}-leave { |
|||
animation-timing-function: linear; |
|||
} |
|||
} |
|||
|
|||
.fade-motion(fade, antFade); |
|||
|
|||
@keyframes antFadeIn { |
|||
0% { |
|||
opacity: 0; |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
@keyframes antFadeOut { |
|||
0% { |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
} |
|||
} |
@ -0,0 +1,120 @@ |
|||
.move-motion(@className, @keyframeName) { |
|||
.make-motion(@className, @keyframeName); |
|||
.@{className}-enter, |
|||
.@{className}-appear { |
|||
opacity: 0; |
|||
animation-timing-function: @ease-out-circ; |
|||
} |
|||
.@{className}-leave { |
|||
animation-timing-function: @ease-in-circ; |
|||
} |
|||
} |
|||
|
|||
.move-motion(move-up, antMoveUp); |
|||
.move-motion(move-down, antMoveDown); |
|||
.move-motion(move-left, antMoveLeft); |
|||
.move-motion(move-right, antMoveRight); |
|||
|
|||
@keyframes antMoveDownIn { |
|||
0% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(100%); |
|||
opacity: 0; |
|||
} |
|||
100% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(0%); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
@keyframes antMoveDownOut { |
|||
0% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(0%); |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(100%); |
|||
opacity: 0; |
|||
} |
|||
} |
|||
|
|||
@keyframes antMoveLeftIn { |
|||
0% { |
|||
transform-origin: 0 0; |
|||
transform: translateX(-100%); |
|||
opacity: 0; |
|||
} |
|||
100% { |
|||
transform-origin: 0 0; |
|||
transform: translateX(0%); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
@keyframes antMoveLeftOut { |
|||
0% { |
|||
transform-origin: 0 0; |
|||
transform: translateX(0%); |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
transform-origin: 0 0; |
|||
transform: translateX(-100%); |
|||
opacity: 0; |
|||
} |
|||
} |
|||
|
|||
@keyframes antMoveRightIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 0 0; |
|||
transform: translateX(100%); |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
transform-origin: 0 0; |
|||
transform: translateX(0%); |
|||
} |
|||
} |
|||
|
|||
@keyframes antMoveRightOut { |
|||
0% { |
|||
transform-origin: 0 0; |
|||
transform: translateX(0%); |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
transform-origin: 0 0; |
|||
transform: translateX(100%); |
|||
opacity: 0; |
|||
} |
|||
} |
|||
|
|||
@keyframes antMoveUpIn { |
|||
0% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(-100%); |
|||
opacity: 0; |
|||
} |
|||
100% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(0%); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
@keyframes antMoveUpOut { |
|||
0% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(0%); |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
transform-origin: 0 0; |
|||
transform: translateY(-100%); |
|||
opacity: 0; |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
@keyframes loadingCircle { |
|||
0% { |
|||
transform-origin: 50% 50%; |
|||
transform: rotate(0deg); |
|||
} |
|||
100% { |
|||
transform-origin: 50% 50%; |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
@ -0,0 +1,120 @@ |
|||
.slide-motion(@className, @keyframeName) { |
|||
.make-motion(@className, @keyframeName); |
|||
.@{className}-enter, |
|||
.@{className}-appear { |
|||
opacity: 0; |
|||
animation-timing-function: @ease-out-quint; |
|||
} |
|||
.@{className}-leave { |
|||
animation-timing-function: @ease-in-quint; |
|||
} |
|||
} |
|||
|
|||
.slide-motion(slide-up, antSlideUp); |
|||
.slide-motion(slide-down, antSlideDown); |
|||
.slide-motion(slide-left, antSlideLeft); |
|||
.slide-motion(slide-right, antSlideRight); |
|||
|
|||
@keyframes antSlideUpIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleY(.8); |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleY(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antSlideUpOut { |
|||
0% { |
|||
opacity: 1; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleY(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleY(.8); |
|||
} |
|||
} |
|||
|
|||
@keyframes antSlideDownIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 100% 100%; |
|||
transform: scaleY(.8); |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
transform-origin: 100% 100%; |
|||
transform: scaleY(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antSlideDownOut { |
|||
0% { |
|||
opacity: 1; |
|||
transform-origin: 100% 100%; |
|||
transform: scaleY(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 100% 100%; |
|||
transform: scaleY(.8); |
|||
} |
|||
} |
|||
|
|||
@keyframes antSlideLeftIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleX(.8); |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleX(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antSlideLeftOut { |
|||
0% { |
|||
opacity: 1; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleX(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 0% 0%; |
|||
transform: scaleX(.8); |
|||
} |
|||
} |
|||
|
|||
@keyframes antSlideRightIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 100% 0%; |
|||
transform: scaleX(.8); |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
transform-origin: 100% 0%; |
|||
transform: scaleX(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antSlideRightOut { |
|||
0% { |
|||
opacity: 1; |
|||
transform-origin: 100% 0%; |
|||
transform: scaleX(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 100% 0%; |
|||
transform: scaleX(.8); |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
.swing-motion(@className, @keyframeName) { |
|||
.@{className}-enter, |
|||
.@{className}-appear { |
|||
.motion-common(); |
|||
animation-play-state: paused; |
|||
} |
|||
.@{className}-enter.@{className}-enter-active, |
|||
.@{className}-appear.@{className}-appear-active { |
|||
animation-name: ~"@{keyframeName}In"; |
|||
animation-play-state: running; |
|||
} |
|||
} |
|||
|
|||
.swing-motion(swing, antSwing); |
|||
|
|||
@keyframes antSwingIn { |
|||
0%, |
|||
100% { |
|||
transform: translateX(0); |
|||
} |
|||
20% { |
|||
transform: translateX(-10px); |
|||
} |
|||
40% { |
|||
transform: translateX(10px); |
|||
} |
|||
60% { |
|||
transform: translateX(-5px); |
|||
} |
|||
80% { |
|||
transform: translateX(5px); |
|||
} |
|||
} |
@ -0,0 +1,160 @@ |
|||
.zoom-motion(@className, @keyframeName, @duration: @animation-duration-base) { |
|||
.make-motion(@className, @keyframeName, @duration); |
|||
.@{className}-enter, |
|||
.@{className}-appear { |
|||
transform: scale(0); // need this by yiminghe |
|||
animation-timing-function: @ease-out-circ; |
|||
} |
|||
.@{className}-leave { |
|||
animation-timing-function: @ease-in-out-circ; |
|||
} |
|||
} |
|||
|
|||
// For Modal, Select choosen item |
|||
.zoom-motion(zoom, antZoom); |
|||
// For Popover, Popconfirm, Dropdown |
|||
.zoom-motion(zoom-big, antZoomBig); |
|||
// For Tooltip |
|||
.zoom-motion(zoom-big-fast, antZoomBig, @animation-duration-fast); |
|||
|
|||
.zoom-motion(zoom-up, antZoomUp); |
|||
.zoom-motion(zoom-down, antZoomDown); |
|||
.zoom-motion(zoom-left, antZoomLeft); |
|||
.zoom-motion(zoom-right, antZoomRight); |
|||
|
|||
@keyframes antZoomIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform: scale(0.2); |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomOut { |
|||
0% { |
|||
transform: scale(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform: scale(0.2); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomBigIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform: scale(.8); |
|||
} |
|||
100% { |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomBigOut { |
|||
0% { |
|||
transform: scale(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform: scale(.8); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomUpIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 50% 0%; |
|||
transform: scale(.8); |
|||
} |
|||
100% { |
|||
transform-origin: 50% 0%; |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomUpOut { |
|||
0% { |
|||
transform-origin: 50% 0%; |
|||
transform: scale(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 50% 0%; |
|||
transform: scale(.8); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomLeftIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 0% 50%; |
|||
transform: scale(.8); |
|||
} |
|||
100% { |
|||
transform-origin: 0% 50%; |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomLeftOut { |
|||
0% { |
|||
transform-origin: 0% 50%; |
|||
transform: scale(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 0% 50%; |
|||
transform: scale(.8); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomRightIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 100% 50%; |
|||
transform: scale(.8); |
|||
} |
|||
100% { |
|||
transform-origin: 100% 50%; |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomRightOut { |
|||
0% { |
|||
transform-origin: 100% 50%; |
|||
transform: scale(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 100% 50%; |
|||
transform: scale(.8); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomDownIn { |
|||
0% { |
|||
opacity: 0; |
|||
transform-origin: 50% 100%; |
|||
transform: scale(.8); |
|||
} |
|||
100% { |
|||
transform-origin: 50% 100%; |
|||
transform: scale(1); |
|||
} |
|||
} |
|||
|
|||
@keyframes antZoomDownOut { |
|||
0% { |
|||
transform-origin: 50% 100%; |
|||
transform: scale(1); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
transform-origin: 50% 100%; |
|||
transform: scale(.8); |
|||
} |
|||
} |
@ -0,0 +1,447 @@ |
|||
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ |
|||
|
|||
/* Document |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* 1. Correct the line height in all browsers. |
|||
* 2. Prevent adjustments of font size after orientation changes in |
|||
* IE on Windows Phone and in iOS. |
|||
*/ |
|||
|
|||
html { |
|||
line-height: 1.15; /* 1 */ |
|||
-ms-text-size-adjust: 100%; /* 2 */ |
|||
-webkit-text-size-adjust: 100%; /* 2 */ |
|||
} |
|||
|
|||
/* Sections |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Remove the margin in all browsers (opinionated). |
|||
*/ |
|||
|
|||
body { |
|||
margin: 0; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct display in IE 9-. |
|||
*/ |
|||
|
|||
article, |
|||
aside, |
|||
footer, |
|||
header, |
|||
nav, |
|||
section { |
|||
display: block; |
|||
} |
|||
|
|||
/** |
|||
* Correct the font size and margin on `h1` elements within `section` and |
|||
* `article` contexts in Chrome, Firefox, and Safari. |
|||
*/ |
|||
|
|||
h1 { |
|||
font-size: 2em; |
|||
margin: 0.67em 0; |
|||
} |
|||
|
|||
/* Grouping content |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Add the correct display in IE 9-. |
|||
* 1. Add the correct display in IE. |
|||
*/ |
|||
|
|||
figcaption, |
|||
figure, |
|||
main { /* 1 */ |
|||
display: block; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct margin in IE 8. |
|||
*/ |
|||
|
|||
figure { |
|||
margin: 1em 40px; |
|||
} |
|||
|
|||
/** |
|||
* 1. Add the correct box sizing in Firefox. |
|||
* 2. Show the overflow in Edge and IE. |
|||
*/ |
|||
|
|||
hr { |
|||
box-sizing: content-box; /* 1 */ |
|||
height: 0; /* 1 */ |
|||
overflow: visible; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the inheritance and scaling of font size in all browsers. |
|||
* 2. Correct the odd `em` font sizing in all browsers. |
|||
*/ |
|||
|
|||
pre { |
|||
font-family: monospace, monospace; /* 1 */ /* stylelint-disable-line */ |
|||
font-size: 1em; /* 2 */ |
|||
} |
|||
|
|||
/* Text-level semantics |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* 1. Remove the gray background on active links in IE 10. |
|||
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+. |
|||
*/ |
|||
|
|||
a { |
|||
background-color: transparent; /* 1 */ |
|||
-webkit-text-decoration-skip: objects; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* 1. Remove the bottom border in Chrome 57- and Firefox 39-. |
|||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. |
|||
*/ |
|||
|
|||
abbr[title] { |
|||
border-bottom: none; /* 1 */ |
|||
text-decoration: underline; /* 2 */ |
|||
text-decoration: underline dotted; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Prevent the duplicate application of `bolder` by the next rule in Safari 6. |
|||
*/ |
|||
|
|||
b, |
|||
strong { |
|||
font-weight: inherit; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct font weight in Chrome, Edge, and Safari. |
|||
*/ |
|||
|
|||
b, |
|||
strong { |
|||
font-weight: bolder; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the inheritance and scaling of font size in all browsers. |
|||
* 2. Correct the odd `em` font sizing in all browsers. |
|||
*/ |
|||
|
|||
code, |
|||
kbd, |
|||
samp { |
|||
font-family: monospace, monospace; /* 1 */ /* stylelint-disable-line */ |
|||
font-size: 1em; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Add the correct font style in Android 4.3-. |
|||
*/ |
|||
|
|||
dfn { |
|||
font-style: italic; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct background and color in IE 9-. |
|||
*/ |
|||
|
|||
mark { |
|||
background-color: #ff0; |
|||
color: #000; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct font size in all browsers. |
|||
*/ |
|||
|
|||
small { |
|||
font-size: 80%; |
|||
} |
|||
|
|||
/** |
|||
* Prevent `sub` and `sup` elements from affecting the line height in |
|||
* all browsers. |
|||
*/ |
|||
|
|||
sub, |
|||
sup { |
|||
font-size: 75%; |
|||
line-height: 0; |
|||
position: relative; |
|||
vertical-align: baseline; |
|||
} |
|||
|
|||
sub { |
|||
bottom: -0.25em; |
|||
} |
|||
|
|||
sup { |
|||
top: -0.5em; |
|||
} |
|||
|
|||
/* Embedded content |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Add the correct display in IE 9-. |
|||
*/ |
|||
|
|||
audio, |
|||
video { |
|||
display: inline-block; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct display in iOS 4-7. |
|||
*/ |
|||
|
|||
audio:not([controls]) { |
|||
display: none; |
|||
height: 0; |
|||
} |
|||
|
|||
/** |
|||
* Remove the border on images inside links in IE 10-. |
|||
*/ |
|||
|
|||
img { |
|||
border-style: none; |
|||
} |
|||
|
|||
/** |
|||
* Hide the overflow in IE. |
|||
*/ |
|||
|
|||
svg:not(:root) { |
|||
overflow: hidden; |
|||
} |
|||
|
|||
/* Forms |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* 1. Change the font styles in all browsers (opinionated). |
|||
* 2. Remove the margin in Firefox and Safari. |
|||
*/ |
|||
|
|||
button, |
|||
input, |
|||
optgroup, |
|||
select, |
|||
textarea { |
|||
font-family: sans-serif; /* 1 */ |
|||
font-size: 100%; /* 1 */ |
|||
line-height: 1.15; /* 1 */ |
|||
margin: 0; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Show the overflow in IE. |
|||
* 1. Show the overflow in Edge. |
|||
*/ |
|||
|
|||
button, |
|||
input { /* 1 */ |
|||
overflow: visible; |
|||
} |
|||
|
|||
/** |
|||
* Remove the inheritance of text transform in Edge, Firefox, and IE. |
|||
* 1. Remove the inheritance of text transform in Firefox. |
|||
*/ |
|||
|
|||
button, |
|||
select { /* 1 */ |
|||
text-transform: none; |
|||
} |
|||
|
|||
/** |
|||
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` |
|||
* controls in Android 4. |
|||
* 2. Correct the inability to style clickable types in iOS and Safari. |
|||
*/ |
|||
|
|||
button, |
|||
html [type="button"], /* 1 */ |
|||
[type="reset"], |
|||
[type="submit"] { |
|||
-webkit-appearance: button; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Remove the inner border and padding in Firefox. |
|||
*/ |
|||
|
|||
button::-moz-focus-inner, |
|||
[type="button"]::-moz-focus-inner, |
|||
[type="reset"]::-moz-focus-inner, |
|||
[type="submit"]::-moz-focus-inner { |
|||
border-style: none; |
|||
padding: 0; |
|||
} |
|||
|
|||
/** |
|||
* Restore the focus styles unset by the previous rule. |
|||
*/ |
|||
|
|||
button:-moz-focusring, |
|||
[type="button"]:-moz-focusring, |
|||
[type="reset"]:-moz-focusring, |
|||
[type="submit"]:-moz-focusring { |
|||
outline: 1px dotted ButtonText; |
|||
} |
|||
|
|||
/** |
|||
* Correct the padding in Firefox. |
|||
*/ |
|||
|
|||
fieldset { |
|||
padding: 0.35em 0.75em 0.625em; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the text wrapping in Edge and IE. |
|||
* 2. Correct the color inheritance from `fieldset` elements in IE. |
|||
* 3. Remove the padding so developers are not caught out when they zero out |
|||
* `fieldset` elements in all browsers. |
|||
*/ |
|||
|
|||
legend { |
|||
box-sizing: border-box; /* 1 */ |
|||
color: inherit; /* 2 */ |
|||
display: table; /* 1 */ |
|||
max-width: 100%; /* 1 */ |
|||
padding: 0; /* 3 */ |
|||
white-space: normal; /* 1 */ |
|||
} |
|||
|
|||
/** |
|||
* 1. Add the correct display in IE 9-. |
|||
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. |
|||
*/ |
|||
|
|||
progress { |
|||
display: inline-block; /* 1 */ |
|||
vertical-align: baseline; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Remove the default vertical scrollbar in IE. |
|||
*/ |
|||
|
|||
textarea { |
|||
overflow: auto; |
|||
} |
|||
|
|||
/** |
|||
* 1. Add the correct box sizing in IE 10-. |
|||
* 2. Remove the padding in IE 10-. |
|||
*/ |
|||
|
|||
[type="checkbox"], |
|||
[type="radio"] { |
|||
box-sizing: border-box; /* 1 */ |
|||
padding: 0; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Correct the cursor style of increment and decrement buttons in Chrome. |
|||
*/ |
|||
|
|||
[type="number"]::-webkit-inner-spin-button, |
|||
[type="number"]::-webkit-outer-spin-button { |
|||
height: auto; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the odd appearance in Chrome and Safari. |
|||
* 2. Correct the outline style in Safari. |
|||
*/ |
|||
|
|||
[type="search"] { |
|||
-webkit-appearance: textfield; /* 1 */ |
|||
outline-offset: -2px; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS. |
|||
*/ |
|||
|
|||
[type="search"]::-webkit-search-cancel-button, |
|||
[type="search"]::-webkit-search-decoration { |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct the inability to style clickable types in iOS and Safari. |
|||
* 2. Change font properties to `inherit` in Safari. |
|||
*/ |
|||
|
|||
::-webkit-file-upload-button { |
|||
-webkit-appearance: button; /* 1 */ |
|||
font: inherit; /* 2 */ |
|||
} |
|||
|
|||
/* Interactive |
|||
========================================================================== */ |
|||
|
|||
/* |
|||
* Add the correct display in IE 9-. |
|||
* 1. Add the correct display in Edge, IE, and Firefox. |
|||
*/ |
|||
|
|||
details, /* 1 */ |
|||
menu { |
|||
display: block; |
|||
} |
|||
|
|||
/* |
|||
* Add the correct display in all browsers. |
|||
*/ |
|||
|
|||
summary { |
|||
display: list-item; |
|||
} |
|||
|
|||
/* Scripting |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Add the correct display in IE 9-. |
|||
*/ |
|||
|
|||
canvas { |
|||
display: inline-block; |
|||
} |
|||
|
|||
/** |
|||
* Add the correct display in IE. |
|||
*/ |
|||
|
|||
template { |
|||
display: none; |
|||
} |
|||
|
|||
/* Hidden |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Add the correct display in IE 10-. |
|||
*/ |
|||
|
|||
[hidden] { |
|||
display: none; |
|||
} |
@ -0,0 +1 @@ |
|||
import './index.less' |
@ -0,0 +1,2 @@ |
|||
@import "./themes/default"; |
|||
@import "./core/index"; |
@ -0,0 +1,16 @@ |
|||
// mixins for clearfix |
|||
// ------------------------ |
|||
.clearfix() { |
|||
zoom: 1; |
|||
&:before, |
|||
&:after { |
|||
content: " "; |
|||
display: table; |
|||
} |
|||
&:after { |
|||
clear: both; |
|||
visibility: hidden; |
|||
font-size: 0; |
|||
height: 0; |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
// Compatibility for browsers. |
|||
|
|||
// rotate for ie8 and blow |
|||
.ie-rotate(@rotation) { |
|||
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; |
|||
} |
|||
|
|||
// rotate for ie8 and blow |
|||
// degrees unit |
|||
.ie-rotate-via-degrees(@degrees) { |
|||
/* IE6-IE8 */ |
|||
@radians: ~`parseInt("@{degrees}") * Math.PI * 2 / 360`; |
|||
@costheta: ~`Math.cos("@{radians}")`; |
|||
@sintheta: ~`Math.sin("@{radians}")`; |
|||
@negsintheta: ~`"@{sintheta}" * -1`; |
|||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=@{costheta}, M12=@{negsintheta}, M21=@{sintheta}, M22=@{costheta})"; |
|||
zoom: 1; |
|||
|
|||
:root & { |
|||
filter: none; |
|||
} |
|||
} |
|||
|
|||
// support rotate for all browsers |
|||
.cross-rotate(@degrees) { |
|||
.rotate(@degrees); |
|||
.ie-rotate-via-degrees(@degrees); |
|||
} |
|||
|
|||
// Placeholder text |
|||
.placeholder(@color: @input-placeholder-color) { |
|||
// Firefox |
|||
&::-moz-placeholder { |
|||
color: @color; |
|||
opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526 |
|||
} |
|||
// Internet Explorer 10+ |
|||
&:-ms-input-placeholder { |
|||
color: @color; |
|||
} |
|||
// Safari and Chrome |
|||
&::-webkit-input-placeholder { |
|||
color: @color; |
|||
} |
|||
} |