├── .eslintignore ├── .eslintrc.cjs ├── .gitignore ├── .husky └── pre-commit ├── .vscode └── extensions.json ├── README.md ├── index.html ├── package.json ├── postcss.config.cjs ├── public └── vite.svg ├── scripts ├── postinstall.mjs ├── switch-cli.mjs └── utils.mjs ├── src ├── App.vue ├── assets │ └── vue.svg ├── components │ ├── eipControl │ │ └── TextInput.vue │ └── index.ts ├── libs │ ├── lulu-ui │ │ ├── css │ │ │ └── common │ │ │ │ ├── animate.css │ │ │ │ ├── color.css │ │ │ │ ├── comp │ │ │ │ └── Table.css │ │ │ │ ├── form.css │ │ │ │ ├── ui.css │ │ │ │ ├── ui.min.css │ │ │ │ ├── ui │ │ │ │ ├── Button.css │ │ │ │ ├── Checkbox.css │ │ │ │ ├── Color.css │ │ │ │ ├── Datalist.css │ │ │ │ ├── Date.css │ │ │ │ ├── Dialog.css │ │ │ │ ├── Drop.css │ │ │ │ ├── Input.css │ │ │ │ ├── Keyboard.css │ │ │ │ ├── LightTip.css │ │ │ │ ├── Loading.css │ │ │ │ ├── Pagination.css │ │ │ │ ├── Placeholder.css │ │ │ │ ├── Progress.css │ │ │ │ ├── Radio.css │ │ │ │ ├── Range.css │ │ │ │ ├── Select.css │ │ │ │ ├── Switch.css │ │ │ │ ├── Tab.css │ │ │ │ ├── Table.css │ │ │ │ ├── Textarea.css │ │ │ │ └── Tips.css │ │ │ │ └── variables.css │ │ ├── index.js │ │ └── js │ │ │ └── common │ │ │ ├── all.js │ │ │ ├── comp │ │ │ ├── Form.js │ │ │ └── Table.js │ │ │ ├── safari-polyfill.js │ │ │ └── ui │ │ │ ├── Color.js │ │ │ ├── Datalist.js │ │ │ ├── DateTime.js │ │ │ ├── Dialog.js │ │ │ ├── Drop.js │ │ │ ├── ErrorTip.js │ │ │ ├── Follow.js │ │ │ ├── Keyboard.js │ │ │ ├── LightTip.js │ │ │ ├── Loading.js │ │ │ ├── Pagination.js │ │ │ ├── Range.js │ │ │ ├── Select.js │ │ │ ├── Tab.js │ │ │ ├── Tips.js │ │ │ └── Validate.js │ └── tailwindcss │ │ └── index.css ├── main.ts ├── style.css └── vite-env.d.ts ├── tailwind.config.cjs ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | lib 4 | .rpt2_cache 5 | src/libs/lulu-ui -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | commonjs: true, 5 | node: true, 6 | es2021: true 7 | }, 8 | extends: [ 9 | // add more generic rulesets here, such as: 10 | // 'eslint:recommended', 11 | 'plugin:vue/vue3-recommended', 12 | // 'plugin:vue/recommended' // Use this if you are using Vue.js 2.x. 13 | 'plugin:prettier/recommended' 14 | ], 15 | rules: { 16 | // override/add rules settings here, such as: 17 | // 'vue/no-unused-vars': 'error' 18 | 'prettier/prettier': [ 19 | 1, 20 | { 21 | arrowParens: 'always', // 在单个箭头函数参数周围加上括号:(x) => x 22 | bracketSpacing: true, // 是否在对象属性添加空格,这里选择是 { binding: 'new' } 23 | endOfLine: 'lf', // 行结束 Line Feed only(\n),在 Linux 和 macOS 以及 git repos 内部很常见 24 | ignorePath: '.prettierignore', // 不使用prettier格式化的文件写在.prettierignore里面:每行写一个路径 25 | jsxBracketSameLine: false, // 在jsx中把'>' 是否单独放一行 26 | jsxSingleQuote: false, // 在jsx中使用单引号代替双引号 27 | htmlWhitespaceSensitivity: 'ignore', // 空格被认为是不敏感的 28 | printWidth: 160, // 每行最大值后换行 29 | proseWrap: 'always', // 超过超过打印宽度换行 30 | semi: false, // 句尾是否添加分号 31 | singleQuote: true, // 是否使用单引号代替双引号 32 | tabWidth: 2, // 缩进字节数 33 | trailingComma: 'none', // 在对象或数组最后一个元素后面是否加逗号(在ES5中加尾逗号) 34 | useTabs: false, // 缩进不使用tab,使用空格 35 | vueIndentScriptAndStyle: false 36 | } 37 | ] 38 | }, 39 | parser: 'vue-eslint-parser', 40 | parserOptions: { 41 | parser: '@typescript-eslint/parser', 42 | sourceType: 'module', 43 | ecmaVersion: 2021, 44 | ecmaFeatures: { 45 | jsx: true 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | lib 13 | dist-ssr 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + TypeScript + Vite 2 | 3 | This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-demi-sfc-component", 3 | "private": false, 4 | "version": "0.0.1", 5 | "type": "module", 6 | "main": "./lib/vue-demi-sfc-component.umd.cjs", 7 | "exports": { 8 | ".": { 9 | "import": "./lib/vue-demi-sfc-component.js", 10 | "require": "./lib/vue-demi-sfc-component.umd.cjs" 11 | } 12 | }, 13 | "scripts": { 14 | "postinstall": "node ./scripts/postinstall.mjs", 15 | "dev": "vite", 16 | "dev:3": "npm run switch:3 && vite --force", 17 | "dev:2": "npm run switch:2 && vite", 18 | "switch:2": "npx vue-demi-switch 2 vue2", 19 | "switch:3": "npx vue-demi-switch 3 vue3", 20 | "build:3": "npm run switch:3 && vue-tsc --noEmit && vite build", 21 | "build:2": "npm run switch:2 && vue-tsc --noEmit && vite build", 22 | "build": "rimraf lib && npm run build:2 && npm run build:3", 23 | "preview": "vite preview", 24 | "lint:fix": "eslint . --ext .js,.ts,.vue --fix", 25 | "prepare": "husky install", 26 | "pub": "npm publish --access=public" 27 | }, 28 | "dependencies": { 29 | "@vue/composition-api": "^1.7.0", 30 | "vue-demi": "^0.13.8" 31 | }, 32 | "files": [ 33 | "lib/*", 34 | "scripts/*" 35 | ], 36 | "lint-staged": { 37 | "*.{js,ts,vue,html}": [ 38 | "eslint --fix --color", 39 | "git add" 40 | ] 41 | }, 42 | "peerDependencies": { 43 | "@vue/composition-api": "^1.7.0", 44 | "vue": "^2.0.0 || >=3.0.0" 45 | }, 46 | "peerDependenciesMeta": { 47 | "@vue/composition-api": { 48 | "optional": true 49 | } 50 | }, 51 | "devDependencies": { 52 | "@types/node": "^18.7.6", 53 | "@typescript-eslint/parser": "^5.33.1", 54 | "@vitejs/plugin-vue": "^3.0.3", 55 | "autoprefixer": "^10.4.8", 56 | "eslint": "^8.22.0", 57 | "eslint-config-prettier": "^8.5.0", 58 | "eslint-plugin-prettier": "^4.2.1", 59 | "eslint-plugin-vue": "^9.3.0", 60 | "husky": "^8.0.1", 61 | "lint-staged": "^13.0.3", 62 | "postcss": "^8.4.16", 63 | "postcss-import": "^14.1.0", 64 | "postcss-nested": "^5.0.6", 65 | "prettier": "2.7.1", 66 | "rimraf": "^3.0.2", 67 | "rollup-plugin-postcss": "^4.0.2", 68 | "tailwindcss": "^3.1.8", 69 | "typescript": "^4.6.4", 70 | "vite": "^3.0.7", 71 | "vite-plugin-vue2": "^2.0.2", 72 | "vue": "2.6.14", 73 | "vue-eslint-parser": "^9.0.3", 74 | "vue-template-compiler": "2.6.14", 75 | "vue-tsc": "^0.39.5", 76 | "vue2": "npm:vue@2.6.14", 77 | "vue3": "npm:vue@^3.2.36" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'postcss-import': {}, 4 | 'tailwindcss/nesting': {}, 5 | tailwindcss: {}, 6 | autoprefixer: {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/postinstall.mjs: -------------------------------------------------------------------------------- 1 | import { version } from 'vue-demi' 2 | import { switchVersion } from './utils.mjs' 3 | 4 | switchVersion(version) 5 | -------------------------------------------------------------------------------- /scripts/switch-cli.mjs: -------------------------------------------------------------------------------- 1 | import { switchVersion } from './utils.mjs' 2 | 3 | const version = process.argv[2] 4 | switchVersion(version) 5 | -------------------------------------------------------------------------------- /scripts/utils.mjs: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import fs from 'fs' 3 | import { fileURLToPath } from 'url' 4 | const __filename = fileURLToPath(import.meta.url) 5 | const __dirname = path.dirname(__filename) 6 | 7 | function switchVersion(version) { 8 | const src = getLibDir(version) 9 | const dest = path.join(src, '..') 10 | console.log(`[frontend-shared] switch lib to vue version ${version}`) 11 | copyDir(src, dest) 12 | } 13 | 14 | function getLibDir(version) { 15 | const dirname = String(version).startsWith('2') ? 'v2' : 'v3' 16 | return path.join(__dirname, `../lib/${dirname}`) 17 | } 18 | 19 | function copyDir(src, dest) { 20 | console.log(`copying from ${src} to ${dest}`) 21 | // unlink for pnpm, #92 22 | try { 23 | fs.unlinkSync(dest) 24 | } catch (error) {} 25 | try { 26 | copyRecursiveSync(src, dest) 27 | } catch (error) { 28 | console.error(error) 29 | } 30 | } 31 | 32 | function copyRecursiveSync(src, dest) { 33 | const exists = fs.existsSync(src) 34 | const stats = exists && fs.statSync(src) 35 | const isDirectory = stats && stats.isDirectory() 36 | if (isDirectory) { 37 | !fs.existsSync(dest) && fs.mkdirSync(dest) 38 | fs.readdirSync(src).forEach((childItemName) => { 39 | copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName)) 40 | }) 41 | } else { 42 | fs.copyFileSync(src, dest) 43 | } 44 | } 45 | 46 | export { getLibDir, copyDir, switchVersion } 47 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/eipControl/TextInput.vue: -------------------------------------------------------------------------------- 1 | 9 | 22 | 30 | -------------------------------------------------------------------------------- /src/components/index.ts: -------------------------------------------------------------------------------- 1 | import '@/libs/tailwindcss/index.css' 2 | import '@/libs/lulu-ui' 3 | 4 | import EipInputVue from './eipControl/TextInput.vue' 5 | 6 | export default EipInputVue 7 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/animate.css: -------------------------------------------------------------------------------- 1 | @keyframes tinydown { 2 | 0%, 3 | 5% { 4 | opacity: 0; 5 | transform: translateY(-10px); 6 | } 7 | 10% { 8 | opacity: 1; 9 | transform: translateY(-10px); 10 | } 11 | to { 12 | transform: translateY(0); 13 | } 14 | } 15 | 16 | @keyframes fallDown { 17 | form { 18 | transform: translateY(-5px); 19 | } 20 | to { 21 | transform: translateY(0); 22 | } 23 | } 24 | 25 | @keyframes raiseup { 26 | from { 27 | transform: translateY(5px); 28 | } 29 | to { 30 | transform: translateY(0); 31 | } 32 | } 33 | 34 | @keyframes fadeIn { 35 | from { 36 | opacity: 0; 37 | } 38 | to { 39 | opacity: 1; 40 | } 41 | } 42 | 43 | @keyframes spin { 44 | from { 45 | transform: rotate(0); 46 | } 47 | to { 48 | transform: rotate(360deg); 49 | } 50 | } 51 | 52 | @keyframes spin2 { 53 | 0% { 54 | transform: rotate(0); 55 | } 56 | 100% { 57 | transform: rotate(-360deg); 58 | } 59 | } 60 | 61 | @keyframes bounceIn { 62 | 0% { 63 | transform: scale(0); 64 | } 65 | 75% { 66 | transform: scale(1.1); 67 | } 68 | 100% { 69 | transform: scale(1); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/color.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @color.css 5 | * @author xinxuzhang 6 | * @create 16-04-18 7 | **/ 8 | /*主色*/ 9 | body, 10 | .dark { 11 | color: #4c5161; 12 | } 13 | 14 | /*蓝色*/ 15 | a, 16 | .blue, 17 | a.dark[href]:hover { 18 | color: var(--ui-blue, #2a80eb); 19 | } 20 | 21 | /*hover蓝色*/ 22 | a:hover { 23 | color: var(--ui-dark-blue, #0057c3); 24 | } 25 | 26 | /* 深蓝色 */ 27 | .dark-blue { 28 | color: var(--ui-dark-blue, #0057c3); 29 | } 30 | 31 | /*灰色*/ 32 | .gray { 33 | color: var(--ui-gray, #a2a9b6); 34 | } 35 | 36 | /*白色*/ 37 | .white { 38 | color: var(--ui-white, #ffffff); 39 | } 40 | 41 | /* 绿色 */ 42 | .green { 43 | color: var(--ui-green, #1cad70); 44 | } 45 | 46 | /* 橘色 */ 47 | .orange { 48 | color: var(--ui-orange, #f59b00); 49 | } 50 | 51 | /* 红色 */ 52 | .red { 53 | color: var(--ui-red, #eb4646); 54 | } 55 | 56 | /* 浅色 */ 57 | .light { 58 | color: var(--ui-light, #f7f9fa); 59 | } 60 | 61 | /* diabled禁用灰色 */ 62 | .disabled-gray { 63 | color: #ccd0d7; 64 | } 65 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/comp/Table.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Table.css 5 | * @author zhangxinxu 6 | * @edit 17-10-18 从原Table.css中分离出来 7 | * 8 | **/ 9 | /* table shadow */ 10 | .table-x { 11 | background-color: #fff; 12 | border: 1px solid var(--ui-border, #d0d0d5); 13 | } 14 | 15 | .table-x table { 16 | border: 0; 17 | } 18 | 19 | /* table without data */ 20 | .table-null-x, 21 | .table-error-x { 22 | display: none; 23 | align-items: center; 24 | justify-content: center; 25 | height: 300px; 26 | flex-direction: column; 27 | text-align: center; 28 | -webkit-user-select: none; 29 | -moz-user-select: none; 30 | -ms-user-select: none; 31 | user-select: none; 32 | } 33 | 34 | .table-null-x:empty::before { 35 | content: '暂无数据'; 36 | } 37 | .table-error-x:empty::before { 38 | content: '数据获取失败'; 39 | } 40 | 41 | /* 列表分页 */ 42 | .table-page-x, 43 | .table-x > ui-pagination { 44 | padding: 10px 10px 10px 20px; 45 | margin-top: -1px; 46 | border-top: 1px solid var(--ui-light-border, #ededed); 47 | background-color: var(--ui-light, #f7f9fa); 48 | position: relative; 49 | overflow: hidden; 50 | } 51 | .table-x > ui-pagination { 52 | justify-content: flex-end; 53 | } 54 | .table-x > ui-pagination:not([current]) { 55 | --ui-visibility: hidden; 56 | } 57 | @media screen and (max-width: 640px) { 58 | .table-page-x { 59 | padding-left: 10px; 60 | padding-right: 5px; 61 | } 62 | } 63 | 64 | .table-page-data { 65 | float: left; 66 | line-height: 20px; 67 | padding-top: 5px; 68 | font-size: 14px; 69 | } 70 | 71 | .table-page-total { 72 | margin: 0 3px; 73 | } 74 | 75 | .table-page-per { 76 | display: inline-block; 77 | margin-left: 5px; 78 | color: var(--ui-blue, #2a80eb); 79 | cursor: pointer; 80 | } 81 | .table-page-per::after { 82 | content: ''; 83 | display: inline-block; 84 | width: 20px; height: 20px; 85 | background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-205 197 200 400'%3E%3Cpath d='M-59.7 271.6c-4.2-4.1-11-4.1-15.3 0l-30.5 29.6-30.5-29.6c-4.2-4.1-11-4.1-15.3 0-4.2 4.1-4.2 10.7 0 14.8l38.2 37c4.2 4.1 11 4.1 15.3 0l38.2-37c4.1-4.1 4.1-10.7-.1-14.8z' fill='%23a2a9b6'/%3E%3Cpath d='M-58.7 471.6c-4.2-4.1-11-4.1-15.3 0l-30.5 29.6-30.5-29.6c-4.2-4.1-11-4.1-15.3 0-4.2 4.1-4.2 10.7 0 14.8l38.2 37c4.2 4.1 11 4.1 15.3 0l38.2-37c4.1-4.1 4.1-10.7-.1-14.8z' fill='%232a80eb'/%3E%3C/svg%3E") no-repeat; 86 | background-size: 20px 40px; 87 | vertical-align: -5px; 88 | } 89 | 90 | .table-page-per:hover::after { 91 | color: var(--ui-blue, #2a80eb); 92 | background-position: 0 -20px; 93 | } 94 | 95 | .table-page { 96 | float: right; 97 | padding-top: 2px; 98 | } 99 | 100 | .table-checkbox td:first-child, 101 | .table-checkbox th:first-child { 102 | width: 20px; 103 | padding-right: 0; 104 | padding-left: 18px; 105 | text-align: right; 106 | } 107 | 108 | .table-checkbox td:first-child + td, 109 | .table-checkbox th:first-child + th { 110 | padding-left: 13px; 111 | } 112 | 113 | .table-checkbox tr:hover td { 114 | background-color: var(--ui-list-hover, #f0f7ff); 115 | } 116 | 117 | .table-checkbox tr.selected td { 118 | background-color: var(--ui-list-selected, #e0f0ff); 119 | } 120 | 121 | 122 | /* 表格头部操作,搜索,或者大标题 */ 123 | .table-header { 124 | padding: 12px 20px; 125 | border-bottom: 1px solid var(--ui-light-border, #ededed); 126 | } 127 | 128 | .table-title { 129 | line-height: 56px; 130 | font-size: 24px; 131 | margin: 0; 132 | } 133 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Button.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Button.css 5 | * @author zhangxinxu 6 | * @create 15-06-12 7 | * @edited 17-06-13 8 | 17-11-07 use png+spin for loading 9 | 19-07-09 IE9+, no external links 10 | 20-04-03 version edge 11 | * @editor lennonover 12 | */ 13 | 14 | /* button基础变量 */ 15 | :root { 16 | --ui-button-height: var(--ui-component-height, 40px); 17 | --ui-button-line-height: var(--ui-line-height, 20px); 18 | --ui-button-color: var(--ui-dark, #4c5161); 19 | --ui-button-loading-img: url("data:image/svg+xml,%3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M512 1024q-104 0-199-40-92-39-163-110T40 711Q0 616 0 512q0-15 10.5-25.5T36 476t25.5 10.5T72 512q0 90 35 171 33 79 94 140t140 95q81 34 171 34t171-35q79-33 140-94t95-140q34-81 34-171t-35-171q-33-79-94-140t-140-95q-81-34-171-34-15 0-25.5-10.5T476 36t10.5-25.5T512 0q104 0 199 40 92 39 163 110t110 163q40 95 40 199t-40 199q-39 92-110 163T711 984q-95 40-199 40z' fill='%232a80eb'/%3E%3C/svg%3E") no-repeat; 20 | } 21 | 22 | .ui-button, 23 | [is="ui-button"] { 24 | display: inline-block; 25 | line-height: var(--ui-button-line-height); 26 | font-size: var(--ui-font, 14px); 27 | text-align: center; 28 | color: var(--ui-white, #fff); 29 | border-radius: var(--ui-radius, 4px); 30 | border: 1px solid var(--ui-button-color); 31 | padding: calc((var(--ui-button-height) - var(--ui-button-line-height) - 2px) / 2) calc(var(--ui-button-height) / 2.5); 32 | min-width: 80px; 33 | background: var(--ui-button-color) no-repeat center; 34 | text-decoration: none; 35 | box-sizing: border-box; 36 | transition: border-color var(--ui-animate-time, .2s), box-shadow var(--ui-animate-time, .2s), opacity var(--ui-animate-time, .2s); 37 | fill: currentColor; 38 | font-family: inherit; 39 | cursor: pointer; 40 | overflow: visible; 41 | } 42 | 43 | @media (prefers-reduced-motion: reduce) { 44 | .ui-button, 45 | [is="ui-button"] { 46 | transition: none; 47 | } 48 | } 49 | 50 | .ui-button[width="100%"], 51 | [is="ui-button"][width="100%"] { 52 | width: 100%; 53 | } 54 | 55 | div.ui-button, 56 | div[is="ui-button"] { 57 | display: block; 58 | } 59 | 60 | [type="submit"]:not([class]):not([is]) { 61 | position: absolute; 62 | clip: rect(0 0 0 0); 63 | } 64 | 65 | /* Chrome/Firefox的outline会由Keyboard.js帮忙呈现 */ 66 | @supports (-webkit-mask: none) { 67 | button, 68 | [type="button"], 69 | [type="submit"], 70 | [tabindex] { 71 | outline: 0 none; 72 | } 73 | } 74 | ::-moz-focus-inner { 75 | border: 0; 76 | } 77 | 78 | .ui-button:hover, 79 | [is="ui-button"]:hover { 80 | color: var(--ui-white, #fff); 81 | text-decoration: none; 82 | } 83 | .ui-button:not(.disabled):not(.loading):not(:disabled):hover, 84 | [is="ui-button"]:not(.disabled):not(.loading):not(:disabled):hover { 85 | filter: brightness(1.05); 86 | } 87 | 88 | .ui-button:not(.disabled):not(.loading):active, 89 | [is="ui-button"]:not(.disabled):not(.loading):active { 90 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 91 | inset 0 0 0 100px rgba(0, 0, 0, 0.1); 92 | } 93 | .ui-button[type="normal"], 94 | .ui-button[data-type="normal"], 95 | [is="ui-button"][type="normal"], 96 | [is="ui-button"][data-type="normal"] { 97 | --ui-button-color: var(--ui-white, #fff); 98 | color: var(--ui-dark, #4c5161); 99 | border-color: var(--ui-border); 100 | } 101 | 102 | /* primary button */ 103 | .ui-button[data-type="primary"], 104 | .ui-button[data-type="remind"], 105 | .ui-button[type="primary"], 106 | .ui-button[type="remind"], 107 | [is="ui-button"][data-type="primary"], 108 | [is="ui-button"][data-type="remind"], 109 | [is="ui-button"][type="primary"], 110 | [is="ui-button"][type="remind"] { 111 | --ui-button-color: var(--ui-blue, #2a80eb); 112 | } 113 | 114 | /* success button */ 115 | .ui-button[data-type="success"], 116 | .ui-button[type="success"], 117 | [is="ui-button"][data-type="success"], 118 | [is="ui-button"][type="success"] { 119 | --ui-button-color: var(--ui-green, #1cad70); 120 | } 121 | 122 | /* warning button */ 123 | .ui-button[data-type^="warn"], 124 | .ui-button[type^="warn"], 125 | [is="ui-button"][data-type^="warn"], 126 | [is="ui-button"][type^="warn"] { 127 | --ui-button-color: var(--ui-orange, #f59b00); 128 | } 129 | /* danger button */ 130 | .ui-button[data-type="danger"], 131 | .ui-button[data-type="error"], 132 | .ui-button[type="danger"], 133 | .ui-button[type="error"], 134 | [is="ui-button"][data-type="danger"], 135 | [is="ui-button"][data-type="error"], 136 | [is="ui-button"][type="danger"], 137 | [is="ui-button"][type="error"] { 138 | --ui-button-color: var(--ui-red, #eb4646); 139 | } 140 | 141 | /* disabled status */ 142 | .ui-button.disabled, 143 | .ui-button:disabled, 144 | [is="ui-button"].disabled, 145 | [is="ui-button"]:disabled { 146 | opacity: var(--ui-opacity, .4); 147 | cursor: default; 148 | } 149 | /* loading status */ 150 | .ui-button.loading, 151 | [is="ui-button"].loading { 152 | color: transparent !important; 153 | pointer-events: none; 154 | position: relative; 155 | cursor: default; 156 | } 157 | /* input按钮,三个点 */ 158 | input.ui-button.loading, 159 | input[is="ui-button"].loading { 160 | --ui-loading-color: var(--ui-white, #fff); 161 | --ui-loading-radial: radial-gradient(3px circle, var(--ui-loading-color), var(--ui-loading-color) 2px, transparent 3px); 162 | background-image: var(--ui-loading-radial), var(--ui-loading-radial), var(--ui-loading-radial); 163 | background-position-x: calc(50% - 10px), 50%, calc(50% + 10px); 164 | background-position-y: 50%; 165 | background-size: 5px 5px; 166 | animation: bubbling 1s infinite; 167 | } 168 | input[data-type="normal"].loading { 169 | --ui-loading-color: var(--ui-blue, #2a80eb); 170 | } 171 | 172 | /* button 按钮 */ 173 | .ui-button.loading::before, 174 | [is="ui-button"].loading::before { 175 | content: ""; 176 | position: absolute; 177 | left: 0; 178 | top: 0; 179 | right: 0; 180 | bottom: 0; 181 | width: 20px; 182 | height: 20px; 183 | background-color: var(--ui-white,#fff); 184 | -webkit-mask: var(--ui-button-loading-img); 185 | mask: var(--ui-button-loading-img); 186 | -webkit-mask-size: 100% 100%; 187 | mask-size: 100% 100%; 188 | margin: auto; 189 | animation: spin 1s linear infinite; 190 | } 191 | /* 有底色按钮 */ 192 | [data-type="normal"].loading::before, 193 | [type="normal"].loading::before { 194 | background-color: var(--ui-blue,#2a80eb); 195 | } 196 | 197 | @keyframes bubbling { 198 | 0% { 199 | background-position-y: 50%, 50%, 50%; 200 | } 201 | 15% { 202 | background-position-y: calc(50% - 3px), 50%, 50%; 203 | } 204 | 30% { 205 | background-position-y: calc(50% - 1px), calc(50% - 3px), 50%; 206 | } 207 | 45% { 208 | background-position-y: 50%, calc(50% - 1px), calc(50% - 3px); 209 | } 210 | 60% { 211 | background-position-y: 50%, 50%, calc(50% - 1px); 212 | } 213 | 75% { 214 | background-position-y: 50%, 50%, 50%; 215 | } 216 | } 217 | 218 | @keyframes spin { 219 | from { 220 | transform: rotate(0); 221 | } 222 | to { 223 | transform: rotate(360deg); 224 | } 225 | } 226 | 227 | /* error */ 228 | .ui-button[is-error], 229 | [is="ui-button"][is-error] { 230 | border-color: var(--ui-red, #eb4646) !important; 231 | } 232 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Checkbox.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Checkbox.css 5 | * @author zhangxinxu 6 | * @create 15-06-18 7 | * @edit 17-06-14 focusable 8 | * @editor shanyerong 9 | * @edit 20-04-30 description here 10 | **/ 11 | /* checkbox基础变量 */ 12 | :root { 13 | --ui-checkbox-width: 20px; 14 | --ui-checkbox-height: 20px; 15 | } 16 | 17 | [is="ui-checkbox"] { 18 | -webkit-appearance: none; 19 | width: var(--ui-checkbox-width, 20px); 20 | height: var(--ui-checkbox-height, 20px); 21 | display: inline-flex; 22 | border: solid 1px rgba(0, 0, 0, 0); 23 | outline: none; 24 | border-radius: var(--ui-radius, 4px); 25 | box-sizing: border-box; 26 | box-shadow: inset 0 1px, inset 1px 0, inset -1px 0, inset 0 -1px; 27 | background-color: var(--ui-white, #ffffff); 28 | background-clip: content-box; 29 | color: var(--ui-border, #d0d0d5); 30 | transition: color var(--ui-animate-time, .2s), background-color var(--ui-animate-time, .2s); 31 | -webkit-user-select: none; 32 | -ms-user-select: none; 33 | user-select: none; 34 | vertical-align: -.5ex; 35 | } 36 | 37 | [is="ui-checkbox"]::after { 38 | content: ""; 39 | width: 100%; 40 | height: 100%; 41 | background: url("data:image/svg+xml,%3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M920.185 224.838c-33.782-33.935-88.619-33.935-122.464 0L409.955 614.564 226.231 429.952c-33.782-33.935-88.68-33.935-122.461 0-33.784 33.997-33.784 89.108 0 123.044l244.925 246.118c33.782 33.998 88.68 33.998 122.463 0l449.028-451.201c33.843-33.967 33.843-89.048-.001-123.075z' fill='%23fff'/%3E%3C/svg%3E") no-repeat center; 42 | background-size: 12px 12px; 43 | visibility: hidden; 44 | opacity: 0; 45 | transition: opacity var(--ui-animate-time, .2s); 46 | } 47 | 48 | [is="ui-checkbox"]:not(:disabled):hover, 49 | [is="ui-checkbox"]:disabled { 50 | color: var(--ui-dark-border, #ababaf); 51 | } 52 | 53 | [is="ui-checkbox"]:focus { 54 | color: var(--ui-blue, #2a80eb); 55 | } 56 | 57 | [is="ui-checkbox"]:focus:hover { 58 | color: var(--ui-dark-blue, #0057c3); 59 | } 60 | 61 | [is="ui-checkbox"]:checked { 62 | color: var(--ui-blue, #2a80eb); 63 | background-color: var(--ui-blue, #2a80eb); 64 | } 65 | 66 | [is="ui-checkbox"]:not(:disabled):checked:focus, 67 | [is="ui-checkbox"]:not(:disabled):checked:hover { 68 | color: var(--ui-dark-blue, #0057c3); 69 | background-color: var(--ui-dark-blue, #0057c3); 70 | } 71 | 72 | [is="ui-checkbox"]:checked::after { 73 | opacity: 1; 74 | visibility: visible; 75 | } 76 | 77 | [is="ui-checkbox"]:indeterminate::after { 78 | opacity: 1; 79 | visibility: visible; 80 | color: var(--ui-blue, #2a80eb); 81 | background-image: linear-gradient(currentColor, currentColor); 82 | background-size: 8px 8px; 83 | } 84 | 85 | [is="ui-checkbox"]:not(:disabled):indeterminate:focus, 86 | [is="ui-checkbox"]:not(:disabled):indeterminate:hover { 87 | color: var(--ui-dark-blue, #0057c3); 88 | } 89 | 90 | [is="ui-checkbox"]:disabled { 91 | opacity: var(--ui-opacity, .4); 92 | } 93 | 94 | /* error */ 95 | [is="ui-checkbox"][is-error] { 96 | color: var(--ui-red, #eb4646) !important; 97 | } 98 | 99 | @media (prefers-reduced-motion: reduce) { 100 | [is="ui-checkbox"], 101 | [is="ui-checkbox"]::after { 102 | transition: none; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Color.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Color.css 5 | * @author xinxuzhang 6 | * @create 16-06-03 7 | * @edited 20-07-16 @Gwokhov 8 | **/ 9 | 10 | [is="ui-color"] { 11 | width: 40px; 12 | height: 40px; 13 | padding: 0; 14 | vertical-align: middle; 15 | border: 0; 16 | border-radius: var(--ui-radius, 4px); 17 | background-color: rgba(25, 28, 34, 0.2); 18 | outline: none; 19 | cursor: pointer; 20 | } 21 | 22 | [is="ui-color"]::-webkit-color-swatch-wrapper { 23 | padding: 0; 24 | margin: 8px auto; 25 | width: 24px; 26 | height: 24px; 27 | } 28 | 29 | [is="ui-color"]::-webkit-color-swatch { 30 | border: 1px solid var(--ui-light, #f7f9fa); 31 | border-radius: calc(var(--ui-radius, 4px) - 1px); 32 | } 33 | [is="ui-color"]:disabled::-webkit-color-swatch { 34 | background-image: linear-gradient(to right bottom, transparent calc(50% - 1px), red 50%, transparent calc(50% + 1px)), linear-gradient(to top right, transparent calc(50% - 1px), red 50%, transparent calc(50% + 1px)); 35 | } 36 | 37 | /* for firefox */ 38 | [is="ui-color"], 39 | _::-moz-color-swatch { 40 | padding: 8px; 41 | } 42 | [is="ui-color"]::-moz-color-swatch { 43 | border: 1px solid var(--ui-light, #f7f9fa); 44 | } 45 | 46 | .ui-color-container { 47 | display: none; 48 | position: absolute; 49 | width: 241px; 50 | padding: 10px 12px; 51 | border-radius: var(--ui-radius, 4px); 52 | background-color: var(--ui-light, #f7f9fa); 53 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); 54 | font-size: var(--ui-font, 14px); 55 | animation: fadeIn var(--ui-animate-time, .2s); 56 | touch-action: none; 57 | --safe-area: 3px; 58 | z-index: 21; 59 | } 60 | 61 | .ui-color-switch { 62 | position: absolute; 63 | top: 12px; 64 | right: 12px; 65 | color: var(--ui-blue, #2a80eb); 66 | border: 1px solid transparent; 67 | height: 20px; 68 | line-height: 20px; 69 | padding: 2px 5px; 70 | border-radius: calc(var(--ui-radius, 4px) - 1px); 71 | background: none; 72 | font-family: inherit; 73 | transition: border-color var(--ui-animate-time, .2s), background-color var(--ui-animate-time, .2s); 74 | box-sizing: content-box; 75 | } 76 | .ui-color-switch:hover { 77 | background-color: var(--ui-white, #ffffff); 78 | border-color: #d0d0d5; 79 | background-color: var(--ui-white, #ffffff); 80 | } 81 | .ui-color-switch:active { 82 | line-height: normal; 83 | } 84 | 85 | .ui-color-switch[data-mode]::before { 86 | content: ''; 87 | display: inline-block; 88 | width: 14px; height: 14px; 89 | vertical-align: -2px; 90 | margin-right: 4px; 91 | pointer-events: none; 92 | } 93 | .ui-color-switch[data-mode="basic"]::before { 94 | background: conic-gradient(red 120deg, blue 120deg 240deg, lime 240deg); 95 | transform: rotate(-60deg); 96 | border-radius: 50%; 97 | } 98 | .ui-color-switch[data-mode="more"]::before { 99 | background: radial-gradient(closest-side, white, transparent), 100 | conic-gradient(red, magenta, blue, aqua, lime, yellow, red); 101 | border-radius: 50%; 102 | } 103 | 104 | [type="color-opacity"] { 105 | background: linear-gradient(var(--ui-color-opacity, #000000), var(--ui-color-opacity, #000000)), 106 | conic-gradient(black 45deg, white 45deg, white 225deg, black 225deg); 107 | box-sizing: border-box; 108 | background-clip: content-box; 109 | border: 8px solid rgba(25, 28, 34, 0.2); 110 | padding: 1px; 111 | font-size: 0; 112 | } 113 | 114 | .ui-color-current { 115 | padding-bottom: 20px; 116 | } 117 | 118 | .ui-color-current-square, 119 | .ui-color-current-square-opacity { 120 | display: inline-block; 121 | width: 20px; 122 | height: 20px; 123 | margin-right: 5px; 124 | border-radius: calc(var(--ui-radius, 4px) - 1px); 125 | box-shadow: inset 0 1px rgba(0, 0, 0, 0.25), 126 | inset 0 -1px rgba(0, 0, 0, 0.25), inset 1px 0 rgba(0, 0, 0, 0.25), 127 | inset -1px 0 rgba(0, 0, 0, 0.25); 128 | background-color: currentColor; 129 | vertical-align: middle; 130 | } 131 | .ui-color-current-square-opacity { 132 | background: linear-gradient(var(--ui-color-opacity, #000000),var(--ui-color-opacity, #000000)), 133 | conic-gradient(black 45deg, white 45deg, white 225deg, black 225deg); 134 | } 135 | 136 | .ui-color-current-input { 137 | width: 72px; 138 | border: 1px solid var(--ui-border, #d0d0d5); 139 | background-color: var(--ui-white, #ffffff); 140 | height: 20px; 141 | line-height: 20px; 142 | padding: 2px 5px; 143 | border-radius: calc(var(--ui-radius, 4px) - 1px); 144 | margin-left: 5px; 145 | font-size: 13px; 146 | vertical-align: middle; 147 | box-sizing: content-box; 148 | text-transform: uppercase; 149 | color: inherit; 150 | } 151 | 152 | .ui-color-body { 153 | min-height: 100px; 154 | } 155 | 156 | .ui-color-basic { 157 | overflow: hidden; 158 | } 159 | 160 | .ui-color-lump-group { 161 | width: 72px; 162 | float: left; 163 | } 164 | 165 | .ui-color-lump { 166 | display: block; 167 | width: 11px; 168 | height: 11px; 169 | margin: 0 1px 1px 0; 170 | box-sizing: border-box; 171 | background-color: currentColor; 172 | } 173 | 174 | .ui-color-lump:hover, 175 | .ui-color-basic a.active, 176 | .ui-color-lump-preset:hover { 177 | border: 1px solid var(--ui-white, #ffffff); 178 | } 179 | 180 | .ui-color-lump-preset { 181 | display: block; 182 | height: 35px; 183 | margin: 0 1px 1px 0; 184 | box-sizing: border-box; 185 | background-color: currentColor; 186 | border: 1px solid transparent; 187 | } 188 | 189 | .ui-color-basic-l { 190 | width: 12px; 191 | float: left; 192 | overflow: hidden; 193 | } 194 | 195 | .ui-color-basic-r { 196 | margin-left: 25px; 197 | overflow: hidden; 198 | display: flex; 199 | flex-direction: column; 200 | height: 150px; 201 | flex-wrap: wrap; 202 | } 203 | 204 | .ui-color-basic-r .ui-color-lump { 205 | float: left; 206 | } 207 | 208 | .ui-color-more { 209 | display: none; 210 | height: 150px; 211 | } 212 | 213 | .ui-color-more .ui-color-gradient { 214 | width: 100%; 215 | height: 100%; 216 | } 217 | 218 | .ui-color-more-l { 219 | width: 180px; 220 | height: inherit; 221 | float: left; 222 | position: relative; 223 | } 224 | 225 | .ui-color-more-l .ui-color-gradient { 226 | background: linear-gradient(90deg, #ff0000 0%, #ffff00 16.66%, #00ff00 33.33%, #00ffff 50%, #0000ff 66.66%, #ff00ff 83.33%, #ff0000 100%); 227 | } 228 | 229 | .ui-color-cover-white { 230 | background-color: rgba(0, 0, 0, 0); 231 | background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), #808080); 232 | cursor: crosshair; 233 | } 234 | 235 | .ui-color-circle { 236 | position: absolute; 237 | left: 0; 238 | top: 0; 239 | width: 16px; 240 | height: 16px; 241 | border: 3px solid var(--ui-white, #ffffff); 242 | border-radius: 20px; 243 | background-color: #f00; 244 | background-clip: content-box; 245 | transform: translate(-11px, -11px); 246 | pointer-events: none; 247 | } 248 | 249 | .ui-color-more-r { 250 | height: inherit; 251 | float: right; 252 | padding-right: 8px; 253 | position: relative; 254 | } 255 | 256 | .ui-color-more-fill { 257 | display: block; 258 | width: 16px; 259 | height: 100%; 260 | background-color: #f00; 261 | } 262 | 263 | .ui-color-cover-white, 264 | .ui-color-more-cover { 265 | position: absolute; 266 | left: 0; 267 | top: 0; 268 | width: inherit; 269 | height: 150px; 270 | } 271 | 272 | .ui-color-more-cover { 273 | background-color: rgba(0, 0, 0, 0.01); 274 | -webkit-tap-highlight-color: transparent; 275 | } 276 | 277 | .ui-color-more-arrow { 278 | position: absolute; 279 | right: 0; 280 | top: 100%; 281 | } 282 | 283 | .ui-color-more-arrow::before { 284 | content: ""; 285 | position: absolute; 286 | right: 0; 287 | top: -5px; 288 | width: 0; 289 | height: 0; 290 | border-width: 5px 6px; 291 | border-style: solid; 292 | border-color: transparent; 293 | border-right-color: #36383f; 294 | overflow: hidden; 295 | } 296 | 297 | .ui-color-opacity { 298 | margin-top: 12px; 299 | text-align: center; 300 | } 301 | 302 | .ui-color-opacity-range { 303 | width: 180px; 304 | } 305 | 306 | .ui-color-footer { 307 | margin-top: 15px; 308 | padding-bottom: 5px; 309 | text-align: right; 310 | } 311 | 312 | .ui-color-button-cancel, 313 | .ui-color-button-ensure { 314 | display: inline-block; 315 | width: 80px; 316 | line-height: 20px; 317 | padding-top: 8px; 318 | padding-bottom: 8px; 319 | margin-left: 15px; 320 | border-radius: var(--ui-radius, 4px); 321 | text-align: center; 322 | font-size: var(--ui-font, 14px); 323 | font-family: inherit; 324 | transition: box-shadow var(--ui-animate-time, .2s), border-color var(--ui-animate-time, .2s); 325 | cursor: pointer; 326 | } 327 | 328 | .ui-color-button-cancel { 329 | border: 1px solid var(--ui-border, #d0d0d5); 330 | background-color: var(--ui-white, #ffffff); 331 | color: var(--ui-dark, #4c5161); 332 | } 333 | 334 | .ui-color-button-cancel:hover { 335 | border-color: var(--ui-dark-border, #ababaf); 336 | color: var(--ui-dark, #4c5161); 337 | } 338 | 339 | .ui-color-button-ensure { 340 | border: 1px solid var(--ui-blue, #2a80eb); 341 | background-color: var(--ui-blue, #2a80eb); 342 | color: var(--ui-white, #ffffff); 343 | } 344 | 345 | .ui-color-button-ensure:hover { 346 | color: var(--ui-white, #ffffff); 347 | } 348 | 349 | .ui-color-button-cancel:hover, 350 | .ui-color-button-ensure:hover { 351 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.01), 352 | inset 0 0 0 100px rgba(0, 0, 0, 0.05); 353 | } 354 | 355 | .ui-color-button-cancel:active, 356 | .ui-color-button-ensure:active { 357 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 358 | inset 0 0 0 100px rgba(0, 0, 0, 0.1); 359 | } 360 | 361 | @media (prefers-reduced-motion: reduce) { 362 | .ui-color-container { 363 | animation: none; 364 | } 365 | .ui-color-switch, 366 | .ui-color-button-cancel, 367 | .ui-color-button-ensure { 368 | transition: none; 369 | } 370 | } -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Datalist.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @Datalist.css 4 | * @author zhangxinxu 5 | * @create 16-03-29 6 | * 7 | **/ 8 | 9 | datalist { 10 | display: none; 11 | } 12 | 13 | .ui-datalist { 14 | display: none; 15 | position: absolute; 16 | animation: fadeIn var(--ui-animate-time, .2s); 17 | z-index: 19; 18 | } 19 | 20 | .ui-datalist-datalist { 21 | max-height: 304px; 22 | background-color: var(--ui-white, #ffffff); 23 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); 24 | margin: 0; 25 | padding: 0; 26 | list-style: none; 27 | border: 1px solid var(--ui-border, #d0d0d5); 28 | border: 0 rgba(0, 0, 0, 0.2); 29 | font-size: var(--ui-font, 14px); 30 | position: relative; 31 | overflow: auto; 32 | overscroll-behavior: none; 33 | -ms-scroll-chaining: none; 34 | } 35 | 36 | .ui-datalist-datalist::-webkit-scrollbar { 37 | width: 8px; 38 | height: 8px; 39 | } 40 | 41 | .ui-datalist-datalist::-webkit-scrollbar-thumb { 42 | background-color: #bbb; 43 | border-radius: calc(var(--ui-radius, 4px) + 4px); 44 | } 45 | 46 | .ui-datalist-datalist::-webkit-scrollbar-thumb:hover { 47 | background-color: #aaa; 48 | } 49 | 50 | .ui-datalist-datalist::-webkit-scrollbar-track-piece { 51 | background-color: #ddd; 52 | } 53 | 54 | .ui-datalist-option { 55 | line-height: 20px; 56 | padding: 9px 12px; 57 | background-color: var(--ui-white, #ffffff); 58 | transition: background-color var(--ui-animate-time, .2s); 59 | overflow: hidden; 60 | cursor: pointer; 61 | } 62 | 63 | .ui-datalist:empty, 64 | .ui-datalist-option:empty { 65 | display: none; 66 | } 67 | 68 | .ui-datalist-option:not(.disabled):hover { 69 | background-color: var(--ui-list-hover, #f0f7ff); 70 | } 71 | 72 | .ui-datalist-datalist > .selected { 73 | background-color: var(--ui-list-selected, #e0f0ff); 74 | } 75 | 76 | .ui-datalist-datalist > .disabled { 77 | opacity: var(--ui-opacity, .4); 78 | cursor: default; 79 | -webkit-user-select: none; 80 | -moz-user-select: none; 81 | -ms-user-select: none; 82 | user-select: none; 83 | } 84 | 85 | .ui-datalist-value { 86 | display: block; 87 | text-overflow: ellipsis; 88 | white-space: nowrap; 89 | color: inherit; 90 | overflow: hidden; 91 | } 92 | 93 | .ui-datalist-label { 94 | float: right; 95 | color: var(--ui-gray, #a2a9b6); 96 | font-size: calc(var(--ui-font, 14px) - 2px); 97 | } 98 | 99 | .ui-datalist-label + .ui-datalist-value { 100 | margin-right: 60px; 101 | } 102 | 103 | @media (prefers-reduced-motion: reduce) { 104 | .ui-datalist { 105 | animation: none; 106 | } 107 | .ui-datalist-option { 108 | transition: none; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Date.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Date.css 5 | * @author xinxuzhang 6 | * @create 15-07-03 7 | * 8 | **/ 9 | [is="ui-datetime"]::-webkit-clear-button, 10 | [is="ui-datetime"]::-webkit-inner-spin-button, 11 | [is="ui-datetime"]::-webkit-calendar-picker-indicator { 12 | display: none; 13 | } 14 | 15 | [type="date"][is="ui-datetime"]::-webkit-datetime-edit-text { 16 | color: transparent; 17 | background: linear-gradient( 18 | to bottom, 19 | transparent 9px, 20 | var(--ui-dark, #4c5161) 9px, 21 | var(--ui-dark, #4c5161) 10px, 22 | transparent 10px 23 | ) 24 | no-repeat center; 25 | background-size: 80% 100%; 26 | } 27 | 28 | [is="ui-datetime"]::-webkit-datetime-edit-text, 29 | [is="ui-datetime"]::-webkit-datetime-edit-year-field, 30 | [is="ui-datetime"]::-webkit-datetime-edit-month-field, 31 | [is="ui-datetime"]::-webkit-datetime-edit-day-field, 32 | [is="ui-datetime"]::-webkit-datetime-edit-hour-field, 33 | [is="ui-datetime"]::-webkit-datetime-edit-minute-field, 34 | [is="ui-datetime"]::-webkit-datetime-edit-ampm-field { 35 | background: none; 36 | color: var(--ui-dark, #4c5161); 37 | } 38 | [is="ui-datetime"]:disabled::-webkit-datetime-edit-text, 39 | [is="ui-datetime"]:disabled::-webkit-datetime-edit-year-field, 40 | [is="ui-datetime"]:disabled::-webkit-datetime-edit-month-field, 41 | [is="ui-datetime"]:disabled::-webkit-datetime-edit-day-field, 42 | [is="ui-datetime"]:disabled::-webkit-datetime-edit-hour-field, 43 | [is="ui-datetime"]:disabled::-webkit-datetime-edit-minute-field, 44 | [is="ui-datetime"]:disabled::-webkit-datetime-edit-ampm-field { 45 | opacity: var(--ui-opacity, .4); 46 | } 47 | 48 | [is="ui-datetime"]:valid::-webkit-datetime-edit { 49 | visibility: hidden; 50 | } 51 | 52 | [is="ui-datetime"] { 53 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 54 | height: var(--ui-input-height); 55 | line-height: var(--ui-input-line-height); 56 | padding: calc((var(--ui-input-height) - var(--ui-input-line-height) - 2px) / 2) 8px; 57 | padding-right: 20px; /* 下拉图标 */ 58 | border: 1px solid var(--ui-border, #d0d0d5); 59 | border-radius: var(--ui-radius, 4px); 60 | box-sizing: border-box; 61 | font-size: var(--ui-font, 14px); 62 | outline: none; 63 | color: var(--ui-dark, #4c5161); 64 | transition: border-color var(--ui-animate-time, .2s), background-color var(--ui-animate-time, .2s); 65 | -webkit-tap-highlight-color: transparent; 66 | -webkit-appearance: none; 67 | 68 | background: var(--ui-white, #fff) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-205 297 200 200'%3E%3Cpath d='M-59.3 365.9c-5.1-5.2-13.4-5.2-18.5 0l-27.7 28.3-27.7-28.3c-5.1-5.2-13.4-5.2-18.5 0s-5.1 13.6 0 18.9l46.2 47.1 46.2-47.1c5.1-5.2 5.1-13.6 0-18.9z' fill='%232a80eb'/%3E%3C/svg%3E") 69 | no-repeat right 3px center; 70 | background-size: 20px 20px; 71 | user-select: none; 72 | cursor: pointer; 73 | } 74 | [is="ui-datetime"]:read-write { 75 | /* avoid firefox invalid style */ 76 | box-shadow: none; 77 | color: transparent; 78 | } 79 | 80 | :disabled[is="ui-datetime"] { 81 | color: var(--ui-gray, #a2a9b6); 82 | background: var(--ui-light, #f7f9fa) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-205 297 200 200'%3E%3Cpath d='M-59.3 365.9c-5.1-5.2-13.4-5.2-18.5 0l-27.7 28.3-27.7-28.3c-5.1-5.2-13.4-5.2-18.5 0s-5.1 13.6 0 18.9l46.2 47.1 46.2-47.1c5.1-5.2 5.1-13.6 0-18.9z' fill='%232a80eb' fill-opacity='0.4' /%3E%3C/svg%3E") no-repeat right 3px center; 83 | background-size: 20px 20px; 84 | cursor: default; 85 | } 86 | 87 | :active[is="ui-datetime"] { 88 | background-color: var(--ui-light, #f7f9fa); 89 | } 90 | 91 | [is-error][is="ui-datetime"] { 92 | border-color: var(--ui-red, #eb4646); 93 | } 94 | 95 | [is="ui-datetime"]:not(:disabled):hover { 96 | border-color: var(--ui-dark-border, #ababaf); 97 | } 98 | 99 | [is="ui-datetime"]:not(:disabled):active { 100 | background-color: var(--ui-light, #f7f9fa); 101 | } 102 | 103 | [is="ui-datetime"]:not([type]) { 104 | width: 125px; 105 | } 106 | [is="ui-datetime"][type="date"] { 107 | min-width: 125px; 108 | } 109 | 110 | [is="ui-datetime"][type="year"], 111 | [is="ui-datetime"][type="time"], 112 | [is="ui-datetime"][type="hour"], 113 | [is="ui-datetime"][type="minute"] { 114 | width: 85px; 115 | } 116 | 117 | [is="ui-datetime"][type="month"] { 118 | width: 125px; 119 | } 120 | 121 | [is="ui-datetime"][type="date-range"] { 122 | width: 210px; 123 | } 124 | 125 | [is="ui-datetime"][type="month-range"] { 126 | width: 170px; 127 | } 128 | 129 | [is="ui-datetime"][type="time"] { 130 | width: auto; 131 | } 132 | /* for Safari */ 133 | @supports not (text-align-last: auto) { 134 | [is="ui-datetime"][type="time"] { 135 | max-width: 125px; 136 | } 137 | } 138 | @supports not (-moz-appearance: none) { 139 | [is="ui-datetime"][type="time"] { 140 | padding-right: 33px; 141 | } 142 | } 143 | 144 | /* 选择浮层 */ 145 | .ui-date-container { 146 | display: inline-block; 147 | background-color: var(--ui-white, #ffffff); 148 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25); 149 | border: 1px solid var(--ui-border, #d0d0d5); 150 | border-radius: var(--ui-radius, 4px); 151 | font-size: var(--ui-font, 14px); 152 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 153 | animation: fadeIn var(--ui-animate-time, .2s); 154 | --safe-area: 3px; 155 | -webkit-user-select: none; 156 | user-select: none; 157 | } 158 | body > .ui-date-container { 159 | display: none; 160 | position: absolute; 161 | z-index: 9; 162 | } 163 | 164 | .ui-date-container a { 165 | text-decoration: none; 166 | transition: background-color var(--ui-animate-time, .2s), color var(--ui-animate-time, .2s); 167 | } 168 | 169 | .ui-date-head { 170 | padding: 5px 0 0; 171 | overflow: hidden; 172 | } 173 | 174 | .ui-date-half { 175 | width: 50%; 176 | float: left; 177 | } 178 | 179 | .ui-date-prev, 180 | .ui-date-next { 181 | width: 35px; 182 | height: 30px; 183 | text-align: center; 184 | color: #b6bbc6; 185 | } 186 | 187 | a.ui-date-prev:hover { 188 | color: var(--ui-blue, #2a80eb); 189 | } 190 | 191 | span.ui-date-prev { 192 | color: var(--ui-diabled, #ccd0d7); 193 | } 194 | 195 | a.ui-date-next:hover { 196 | color: var(--ui-blue, #2a80eb); 197 | } 198 | 199 | span.ui-date-next { 200 | color: var(--ui-diabled, #ccd0d7); 201 | } 202 | 203 | .ui-date-prev::before, 204 | .ui-date-next::before { 205 | content: ''; 206 | display: block; 207 | width: 20px; 208 | height: 20px; 209 | background-color: currentColor; 210 | margin: 5px auto 0; 211 | --mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'%3E%3Cpath d='M85.876 100.5l49.537-50.526c4.089-4.215 4.089-11.049 0-15.262-4.089-4.218-10.719-4.218-14.808 0L63.586 92.868c-4.089 4.215-4.089 11.049 0 15.264l57.018 58.156c4.089 4.215 10.719 4.215 14.808 0s4.089-11.049 0-15.262L85.876 100.5z'/%3E%3C/svg%3E"); 212 | -webkit-mask: var(--mask-image); 213 | mask: var(--mask-image); 214 | -webkit-mask-size: 100% 100%; 215 | mask-size: 100% 100%; 216 | } 217 | 218 | .ui-date-next::before { 219 | transform: rotate(180deg); 220 | } 221 | 222 | .ui-date-prev { 223 | float: left; 224 | } 225 | 226 | .ui-date-next { 227 | float: right; 228 | } 229 | 230 | .ui-date-switch { 231 | display: block; 232 | line-height: 30px; 233 | margin: 0 35px; 234 | border-radius: calc(var(--ui-radius, 4px) - 2px); 235 | color: var(--ui-dark, #4c5161); 236 | text-align: center; 237 | } 238 | 239 | a.ui-date-switch:hover, 240 | a.ui-date-item:not(.selected):hover { 241 | color: var(--ui-dark, #4c5161); 242 | background-color: #f0f0f2; 243 | } 244 | 245 | .ui-minute-x, 246 | .ui-hour-x, 247 | .ui-year-x, 248 | .ui-month-x, 249 | .ui-date-x { 250 | width: 225px; 251 | } 252 | 253 | .ui-minute-x[data-step="1"] { 254 | width: 328px; 255 | } 256 | .ui-minute-x[data-step="2"] { 257 | width: 276px; 258 | } 259 | 260 | .ui-minute-body { 261 | padding-left: 12px; 262 | padding-bottom: 12px; 263 | } 264 | 265 | .ui-hour-body { 266 | padding: 8px 0 12px 12px; 267 | } 268 | 269 | .ui-year-body, 270 | .ui-month-body, 271 | .ui-date-body { 272 | padding-left: 5px; 273 | padding-right: 2px; 274 | padding-bottom: 5px; 275 | } 276 | 277 | .ui-date-item { 278 | display: inline-block; 279 | border-radius: calc(var(--ui-radius, 4px) - 2px); 280 | text-align: center; 281 | font-size: 13px; 282 | color: var(--ui-dark, #4c5161); 283 | } 284 | 285 | span.ui-date-item { 286 | opacity: var(--ui-opacity, .4); 287 | } 288 | 289 | .ui-date-item.col0, 290 | .ui-date-item.col6, 291 | .ui-day-item.col0, 292 | .ui-day-item.col6 { 293 | color: var(--ui-red, #eb4646); 294 | } 295 | 296 | .ui-date-tr:last-child .ui-date-item:empty { 297 | display: none; 298 | } 299 | 300 | .ui-minute-body .ui-date-item, 301 | .ui-hour-body .ui-date-item { 302 | width: 45px; 303 | line-height: 26px; 304 | margin-top: 4px; 305 | margin-right: 7px; 306 | } 307 | 308 | .ui-year-body .ui-date-item, 309 | .ui-month-body .ui-date-item { 310 | width: 45px; 311 | line-height: 54px; 312 | margin-top: 5px; 313 | margin-left: 7px; 314 | } 315 | 316 | .ui-date-now { 317 | display: block; 318 | line-height: 30px; 319 | margin: 0 5px 5px; 320 | text-align: center; 321 | } 322 | 323 | .ui-day-x { 324 | padding: 0 2px 0 5px; 325 | text-align: center; 326 | } 327 | 328 | .ui-day-item, 329 | .ui-date-body .ui-date-item { 330 | display: inline-block; 331 | width: 28px; 332 | line-height: 28px; 333 | margin-right: 3px; 334 | margin-top: 1px; 335 | vertical-align: top; 336 | } 337 | 338 | .ui-range-x { 339 | width: 458px; 340 | } 341 | 342 | .ui-range-body { 343 | overflow: hidden; 344 | } 345 | 346 | .ui-range-body .ui-date-half + .ui-date-half { 347 | border-left: 1px solid #f0f0f2; 348 | margin-left: -1px; 349 | } 350 | 351 | .ui-range-footer { 352 | padding: 5px 15px 15px; 353 | text-align: right; 354 | } 355 | 356 | .ui-range-footer > .ui-button { 357 | margin-left: 10px; 358 | } 359 | 360 | .ui-date-container .selected { 361 | background-color: var(--ui-blue, #2a80eb); 362 | color: var(--ui-white, #ffffff); 363 | cursor: default; 364 | } 365 | 366 | .ui-date-container span.selected { 367 | opacity: var(--ui-opacity, .4); 368 | } 369 | 370 | .ui-range-body .ui-date-half { 371 | width: 229px; 372 | } 373 | 374 | .ui-range-body .ui-date-body { 375 | padding-left: 6px; 376 | padding-right: 0; 377 | } 378 | 379 | .ui-range-body .ui-month-body { 380 | margin-bottom: 15px; 381 | } 382 | 383 | .ui-range-date-body .selected { 384 | width: 26px; 385 | line-height: 26px; 386 | border: 1px solid var(--ui-blue, #2a80eb); 387 | border-right-width: 4px; 388 | margin-right: 0; 389 | border-radius: 0; 390 | } 391 | 392 | .ui-range-body .selected.col0 { 393 | margin-left: -6px; 394 | border-left-width: 7px; 395 | } 396 | 397 | .ui-range-body .selected.col6 { 398 | border-right-width: 10px; 399 | } 400 | 401 | .ui-range-body .selected.ui-date-first:not(.col0) { 402 | border-top-left-radius: 2px; 403 | border-bottom-left-radius: 2px; 404 | } 405 | 406 | .ui-range-body .selected.ui-date-last:not(.col6) { 407 | border-top-right-radius: 2px; 408 | border-bottom-right-radius: 2px; 409 | } 410 | 411 | .ui-range-body .ui-date-begin, 412 | .ui-range-body .ui-date-end { 413 | border-radius: 0; 414 | width: 26px; 415 | background-color: var(--ui-white, #ffffff); 416 | color: var(--ui-dark, #4c5161); 417 | } 418 | 419 | .ui-range-body .ui-date-begin { 420 | border-right-width: 4px; 421 | border-left-width: 1px; 422 | border-top-left-radius: 2px; 423 | border-bottom-left-radius: 2px; 424 | } 425 | 426 | .ui-range-body .ui-date-end { 427 | margin-right: 3px; 428 | border-right-width: 1px; 429 | border-top-right-radius: 2px; 430 | border-bottom-right-radius: 2px; 431 | } 432 | 433 | .ui-range-body .ui-date-begin:hover, 434 | .ui-range-body .ui-date-end:hover { 435 | background-color: var(--ui-white, #ffffff); 436 | color: var(--ui-dark, #4c5161); 437 | } 438 | 439 | .ui-range-body .ui-date-begin.col6 { 440 | border-right-width: 0; 441 | padding-right: 9px; 442 | } 443 | 444 | .ui-range-body .ui-date-begin.col0 { 445 | border-left-width: 1px; 446 | margin-left: 0; 447 | } 448 | 449 | .ui-range-body .ui-date-end.col0 { 450 | border-left-width: 0; 451 | padding-left: 7px; 452 | } 453 | 454 | .ui-range-body .ui-date-end.col6 { 455 | border-right-width: 1px; 456 | } 457 | 458 | .ui-range-body .ui-date-begin.ui-date-end { 459 | margin-right: 3px; 460 | padding: 0; 461 | border: 1px solid var(--ui-blue, #2a80eb); 462 | border-radius: calc(var(--ui-radius, 4px) - 2px); 463 | } 464 | 465 | .ui-range-body .ui-date-begin + .ui-date-end { 466 | border-left-width: 1px; 467 | margin-right: 3px; 468 | } 469 | 470 | 471 | .ui-time-x { 472 | display: inline-flex; 473 | gap: 5px; 474 | padding: 5px; 475 | } 476 | .ui-time-col { 477 | height: calc(290px); 478 | overflow: auto; 479 | overflow: overlay; 480 | scrollbar-width: none; 481 | overscroll-behavior: contain; 482 | } 483 | .ui-time-col::-webkit-scrollbar { 484 | display: none; 485 | } 486 | .ui-time-item { 487 | display: block; 488 | border: 0; 489 | background-color: var(--ui-white, #fff); 490 | padding: 0 1em; 491 | height: var(--ui-component-height, 40px); 492 | color: var(--ui-dark, #4c5161); 493 | } 494 | .ui-time-item:disabled { 495 | opacity: var(--ui-opacity, .4); 496 | } 497 | .ui-time-item:not(:disabled):not(.selected):hover { 498 | background-color: var(--ui-list-hover, #f0f7ff); 499 | } 500 | .ui-time-item[data-visibility="false"] { 501 | display: none; 502 | } 503 | 504 | @media (prefers-reduced-motion: reduce) { 505 | .ui-date-container { 506 | animation: none; 507 | } 508 | [is="ui-datetime"], 509 | .ui-date-container a { 510 | transition: none; 511 | } 512 | } 513 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Dialog.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /** 4 | * 5 | * @Dialog.css 6 | * @author zhangxinxu 7 | * @create 15-06-18 8 | * @edit 19-10-31 9 | * 10 | **/ 11 | :root { 12 | --ui-url-close: url("data:image/svg+xml,%3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M594.698 511.995l186.788-186.808a37.693 37.693 0 0 0 0-53.35l-26.7-26.702c-14.7-14.75-38.6-14.75-53.351 0L514.637 431.933 327.839 245.13a37.755 37.755 0 0 0-53.402 0l-26.65 26.701a37.693 37.693 0 0 0 0 53.35L434.576 511.99 247.788 698.778a37.755 37.755 0 0 0 0 53.401l26.65 26.701a37.847 37.847 0 0 0 53.4 0l186.799-186.819L701.44 778.885c14.75 14.7 38.65 14.7 53.35 0l26.701-26.7a37.755 37.755 0 0 0 0-53.402L594.698 511.995z' fill='%23bbb'/%3E%3C/svg%3E"); 13 | --ui-dialog-icon-url: url("data:image/svg+xml,%3Csvg width='401' height='401' viewBox='0 0 401 401' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M200.501.5C310.958.5 400.5 90.042 400.5 200.5c0 110.457-89.542 199.999-199.999 199.999C90.043 400.499.5 310.957.5 200.5.5 90.042 90.043.5 200.501.5zm5.002 280.002h-10a5 5 0 0 0-5 4.999v20.002a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5v-20.002a5 5 0 0 0-5-4.999zm0-179.999h-10a5 5 0 0 0-5 5v150a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5v-150a5 5 0 0 0-5-5z' fill='%23F59B00' fill-rule='nonzero'/%3E%3C/svg%3E"); 14 | --ui-dialog-success-url:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400' viewBox='0 0 400 400'%3E%3Cpath fill='%231cad70' d='M400.5 200.5c0 110.457-89.542 199.999-199.999 199.999C90.043 400.499.5 310.957.5 200.5m0 0C.5 90.042 90.043.5 200.501.5 310.958.5 400.5 90.042 400.5 200.5'/%3E%3Cpath fill='%23FFF' d='M286.398 147.132c-1.654-1.134-3.306-2.395-6.801-4.293-4.271-2.336-9.259 2.624-12.391 6.816l-77.641 102.279-47.916-63.522c-3.144-4.188-4.902-8.468-13.073-1.859-3.097 2.123.234-.361-3.969 2.881-3.884 3.064-4.105 8.598-.971 12.774 0 0 38.641 55.817 45.883 65.074 10.625 13.22 29.944 12.57 40.087 0 7.483-9.473 77.757-107.584 77.757-107.584 3.14-4.194 2.898-9.697-.965-12.566z'/%3E%3C/svg%3E"); 15 | } 16 | 17 | [is="ui-dialog"] { 18 | position: fixed; 19 | left: 0; 20 | top: 0; 21 | height: 100%; 22 | width: 100%; 23 | padding: 0; 24 | border: 0; 25 | background-color: rgba(25, 28, 34, 0.88); 26 | color: var(--ui-dark, #4c5161); 27 | font-size: var(--ui-font, 14px); 28 | overflow: auto; 29 | z-index: 19; 30 | display: grid; 31 | place-items: center; 32 | } 33 | 34 | [is="ui-dialog"]:not([open]) { 35 | display: none; 36 | } 37 | 38 | .ui-dialog-animation { 39 | animation: fadeIn var(--ui-animate-time, .2s) both; 40 | } 41 | 42 | /* 多个弹框出现的时候,隐藏后面弹框的背景 */ 43 | [is="ui-dialog"] + [is="ui-dialog"] { 44 | transition: background-color var(--ui-animate-time, .2s); 45 | background-color: transparent; 46 | } 47 | 48 | .ui-dialog { 49 | display: flex; 50 | flex-direction: column; 51 | min-width: min(400px, calc(100vw - 2rem)); 52 | max-width: calc(100vw - 16px); 53 | border-radius: var(--ui-radius, 4px); 54 | background-color: var(--ui-light, #f7f9fa); 55 | outline: none; 56 | position: relative; 57 | } 58 | .ui-dialog[style^="width:"], 59 | .ui-dialog[style*=" width:"] { 60 | min-width: initial; 61 | } 62 | 63 | .ui-dialog-animation .ui-dialog { 64 | animation: tinydown var(--ui-animate-time, .2s); 65 | } 66 | 67 | .ui-dialog-title { 68 | margin: 0; 69 | line-height: 30px; 70 | padding: 15px 50px 0 25px; 71 | font-weight: bold; 72 | font-size: var(--ui-font, 14px); 73 | color: var(--ui-dark, #4c5161); 74 | -webkit-user-select: none; 75 | -moz-user-select: none; 76 | -ms-user-select: none; 77 | user-select: none; 78 | cursor: default; 79 | } 80 | 81 | .ui-dialog-close { 82 | position: absolute; 83 | top: 8px; 84 | right: 7px; 85 | width: 40px; 86 | height: 40px; 87 | border: 0; 88 | background: none; 89 | font-size: 0; 90 | cursor: pointer; 91 | z-index: 1; 92 | } 93 | .ui-dialog-close::before { 94 | content: ''; 95 | position: absolute; 96 | left: 0; top: 0; 97 | width: inherit; height: inherit; 98 | background-color: var(--ui-gray, #a2a9b6); 99 | transition: background-color var(--ui-animate-time, .2s); 100 | -webkit-mask: var(--ui-url-close) no-repeat center / 24px; 101 | mask: var(--ui-url-close) no-repeat center / 24px; 102 | } 103 | 104 | .ui-dialog-close:hover::before { 105 | background-color: var(--ui-dark, #4c5161); 106 | } 107 | 108 | .ui-dialog-body { 109 | display: flow-root; 110 | min-height: 60px; 111 | padding: 10px 25px 20px; 112 | } 113 | 114 | .ui-dialog-title:empty ~ .ui-dialog-body { 115 | min-height: 40px; 116 | padding-top: 30px; 117 | } 118 | 119 | @supports not (display: flow-root) { 120 | .ui-dialog-body:after { 121 | content: ''; 122 | display: table; 123 | clear: both; 124 | } 125 | } 126 | 127 | .ui-dialog-footer { 128 | padding: 3px 25px 25px; 129 | margin-top: auto; 130 | text-align: right; 131 | max-height: 40px; 132 | opacity: 1; 133 | transition: max-height var(--ui-animate-time, .2s), opacity var(--ui-animate-time, .2s) var(--ui-animate-time, .2s); 134 | overflow: hidden; 135 | } 136 | 137 | .ui-dialog-footer:empty { 138 | max-height: 0; 139 | opacity: 0; 140 | } 141 | 142 | .ui-dialog-footer .ui-button { 143 | margin-left: 15px; 144 | } 145 | 146 | .ui-dialog-footer .ui-button:first-child { 147 | margin-left: 0; 148 | } 149 | 150 | .ui-dialog-stretch { 151 | max-height: 2000px; 152 | height: calc(100% - 50px); 153 | } 154 | 155 | .ui-dialog-stretch .ui-dialog-footer { 156 | position: absolute; 157 | left: 0; 158 | bottom: 0; 159 | right: 0; 160 | } 161 | 162 | .ui-dialog-stretch .ui-dialog-body { 163 | position: absolute; 164 | left: 0; 165 | right: 0; 166 | top: 50px; 167 | bottom: 90px; 168 | padding: 0 0 0 25px; 169 | overflow: auto; 170 | } 171 | 172 | /* alert | comfirm */ 173 | .ui-dialog-confirm::before, 174 | .ui-dialog-alert::before { 175 | content: ''; 176 | position: absolute; 177 | width: 40px; 178 | height: 40px; 179 | top: 0; 180 | left: 0; 181 | background-size: contain; 182 | background-repeat: no-repeat; 183 | background-position: 50% 50%; 184 | } 185 | 186 | .ui-dialog-success::before { 187 | background-image: var(--ui-dialog-success-url), none; 188 | } 189 | 190 | .ui-dialog-warning::before, 191 | .ui-dialog-danger::before, 192 | .ui-dialog-remind::before { 193 | -webkit-mask-image: var(--ui-dialog-icon-url); 194 | mask-image: var(--ui-dialog-icon-url); 195 | -webkit-mask-repeat: no-repeat; 196 | mask-repeat: no-repeat; 197 | -webkit-mask-position: 50% 50%; 198 | mask-position: 50% 50%; 199 | -webkit-mask-size: 40px; 200 | mask-size: 40px; 201 | } 202 | 203 | .ui-dialog-remind::before { 204 | background-color: var(--ui-blue, #2a80eb); 205 | } 206 | 207 | .ui-dialog-warning::before { 208 | background-color: var(--ui-orange, #f59b00); 209 | } 210 | 211 | .ui-dialog-danger::before { 212 | background-color: var(--ui-red, #eb4646); 213 | } 214 | 215 | .ui-dialog-alert, 216 | .ui-dialog-confirm { 217 | max-width: min(340px, calc(100vw - 2rem)); 218 | min-height: 40px; 219 | font-size: calc(var(--ui-font, 14px) + 2px); 220 | word-wrap: break-word; 221 | overflow: hidden; 222 | position: relative; 223 | } 224 | 225 | .ui-dialog-wrap > h6 { 226 | font-size: calc(var(--ui-font, 14px) + 1px); 227 | margin-bottom: 5px; 228 | margin-top: 0; 229 | } 230 | 231 | .ui-dialog-wrap > h6 ~ p { 232 | font-size: var(--ui-font, 14px); 233 | } 234 | 235 | .ui-dialog-wrap > p { 236 | margin: 0; 237 | } 238 | 239 | .ui-dialog-remind, 240 | .ui-dialog-success, 241 | .ui-dialog-warning, 242 | .ui-dialog-danger { 243 | display: flex; 244 | flex-direction: column; 245 | justify-content: center; 246 | margin-bottom: 20px; 247 | padding: 0 0 0 60px; 248 | background-repeat: no-repeat; 249 | background-position: 0 0; 250 | background-size: 40px 40px; 251 | } 252 | 253 | .ui-dialog-loading .ui-dialog-title, 254 | .ui-dialog-loading .ui-dialog-close, 255 | .ui-dialog-loading .ui-dialog-footer { 256 | visibility: hidden; 257 | } 258 | 259 | /* 触碰设备按钮点击区域扩大 */ 260 | @media (pointer: coarse) { 261 | .ui-dialog-footer { 262 | display: flex; 263 | } 264 | .ui-dialog-footer .ui-button { 265 | flex: 1; 266 | } 267 | } 268 | 269 | @media (prefers-reduced-motion: reduce) { 270 | .ui-dialog-animation, 271 | .ui-dialog-animation .ui-dialog { 272 | animation: none; 273 | } 274 | [is="ui-dialog"] + [is="ui-dialog"], 275 | .ui-dialog-close::before, 276 | .ui-dialog-footer { 277 | transition: none; 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Drop.css: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * @Drop.css 5 | * @author zhangxinxu 6 | * @create 20-12-15 7 | * 8 | **/ 9 | 10 | ui-drop[tabindex="0"] { 11 | cursor: pointer; 12 | } 13 | ui-drop ~ .ui-drop-target { 14 | position: absolute; 15 | z-index: 9; 16 | } 17 | ui-drop:not([open]) ~ .ui-drop-target { 18 | display: none; 19 | } 20 | 21 | /** 22 | * 23 | * @DropList.css 24 | * @author xinxuzhang 25 | * @create 15-07-01 26 | * @edit 19-10-20 sunmeiye 27 | * 28 | **/ 29 | .ui-droplist-x { 30 | position: absolute; 31 | width: 111px; 32 | padding: 7px 0; 33 | background-color: var(--ui-white, #ffffff); 34 | box-shadow: 0 2px 5px rgba(0, 0, 0, .25); 35 | --safe-area: 3px; 36 | border: 1px solid var(--ui-border, #d0d0d5); 37 | border-radius: var(--ui-radius, 4px); 38 | font-size: var(--ui-font, 14px); 39 | animation: fadeIn var(--ui-animate-time, .2s); 40 | z-index: 9; 41 | } 42 | 43 | .ui-droplist-li { 44 | display: block; 45 | line-height: 20px; 46 | padding: 7px 12px 8px; 47 | color: var(--ui-dark, #4c5161); 48 | text-decoration: none; 49 | cursor: pointer; 50 | white-space: nowrap; 51 | text-overflow: ellipsis; 52 | overflow: hidden; 53 | } 54 | 55 | .ui-droplist-hr { 56 | border: 0; 57 | border-bottom: 1px solid var(--ui-border, #d0d0d5); 58 | margin: 7px 12px; 59 | opacity: .4; 60 | } 61 | .ui-droplist-hr:first-child { 62 | display: none; 63 | } 64 | 65 | a.ui-droplist-li:hover { 66 | color: var(--ui-dark, #4c5161); 67 | background-color: var(--ui-list-hover, #f0f7ff); 68 | } 69 | a.ui-droplist-li:hover::after { 70 | background-position: 0 -20px; 71 | } 72 | 73 | span.ui-droplist-li { 74 | color: var(--ui-gray, #a2a9b6); 75 | cursor: default; 76 | } 77 | .ui-droplist-li[role="heading"] { 78 | font-weight: 700; 79 | padding-bottom: 5px; 80 | cursor: default; 81 | } 82 | [role="heading"] ~ .ui-droplist-li:not([role="heading"]) { 83 | padding-left: 24px; 84 | } 85 | .ui-droplist-li.disabled { 86 | opacity: var(--ui-opacity, .4); 87 | } 88 | 89 | .ui-droplist-li[data-sublist]::before { 90 | transform: rotate(-90deg); 91 | margin-top: 1px; 92 | float: right; 93 | } 94 | 95 | .ui-droplist-x > .selected { 96 | background-color: var(--ui-list-selected, #e0f0ff); 97 | } 98 | 99 | .selected + .ui-droplist-xx > .ui-droplist-x { 100 | display: block; 101 | } 102 | 103 | .ui-droplist-xx { 104 | position: relative; 105 | } 106 | .ui-droplist-xx > .ui-droplist-x { 107 | display: none; 108 | left: calc(100% - 5px); 109 | top: -35px; 110 | } 111 | .ui-droplist-xx > .reverse { 112 | left: auto; 113 | right: calc(100% - 5px); 114 | } 115 | 116 | .ui-droplist-arrow:empty, 117 | .ui-droplist-arrow:not(:empty)::after, 118 | .ui-droplist-li[data-sublist]::before { 119 | content: ''; 120 | display: inline-block; 121 | width: 20px; 122 | height: 20px; 123 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-205 197 200 400'%3E%3Cpath d='M-59.7 271.6c-4.2-4.1-11-4.1-15.3 0l-30.5 29.6-30.5-29.6c-4.2-4.1-11-4.1-15.3 0-4.2 4.1-4.2 10.7 0 14.8l38.2 37c4.2 4.1 11 4.1 15.3 0l38.2-37c4.1-4.1 4.1-10.7-.1-14.8z' fill='%23a2a9b6'/%3E%3Cpath d='M-58.7 471.6c-4.2-4.1-11-4.1-15.3 0l-30.5 29.6-30.5-29.6c-4.2-4.1-11-4.1-15.3 0-4.2 4.1-4.2 10.7 0 14.8l38.2 37c4.2 4.1 11 4.1 15.3 0l38.2-37c4.1-4.1 4.1-10.7-.1-14.8z' fill='%232a80eb'/%3E%3C/svg%3E"), none; 124 | background-size: 20px 40px; 125 | vertical-align: -5px; 126 | } 127 | 128 | a:hover .ui-droplist-arrow:empty, 129 | .ui-droplist-arrow:not(:empty):hover::after { 130 | background-position: 0 -20px; 131 | } 132 | 133 | /** 134 | * 135 | * @DropPanel.css 136 | * @author xinxuzhang 137 | * @create 15-07-01 138 | * 139 | **/ 140 | .ui-dropanel-x { 141 | position: absolute; 142 | width: 260px; 143 | padding: 20px; 144 | background-color: var(--ui-white, #ffffff); 145 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25); 146 | --safe-area: 3px; 147 | border: 1px solid var(--ui-border, #d0d0d5); 148 | border: 0 rgba(0, 0, 0, 0.2); 149 | font-size: var(--ui-font, 14px); 150 | animation: fadeIn var(--ui-animate-time, .2s); 151 | z-index: 9; 152 | } 153 | 154 | .ui-dropanel-title { 155 | line-height: 20px; 156 | margin-top: -2px; 157 | margin-bottom: 0; 158 | font-size: var(--ui-font, 14px); 159 | font-weight: bold; 160 | } 161 | 162 | .ui-dropanel-close { 163 | position: absolute; 164 | top: 12px; 165 | right: 12px; 166 | width: 20px; 167 | height: 20px; 168 | border: 0; 169 | padding: 0; 170 | background: none; 171 | cursor: pointer; 172 | z-index: 1; 173 | } 174 | .ui-dropanel-close::before { 175 | content: ''; 176 | position: absolute; 177 | left: 0; right: 0; top: 0; bottom: 0; 178 | background: var(--ui-dark-gray, #b6bbc6); 179 | transition: background-color var(--ui-animate-time, .2s); 180 | --mask-image: url("data:image/svg+xml,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22200%22%20height%3D%22200%22%20viewBox%3D%220%200%20200%20200%22%20%3E%3Cpath%20d%3D%22M116.152%2C99.999l36.482-36.486c2.881-2.881%2C2.881-7.54%2C0-10.42%20l-5.215-5.215c-2.871-2.881-7.539-2.881-10.42%2C0l-36.484%2C36.484L64.031%2C47.877c-2.881-2.881-7.549-2.881-10.43%2C0l-5.205%2C5.215%20c-2.881%2C2.881-2.881%2C7.54%2C0%2C10.42l36.482%2C36.486l-36.482%2C36.482c-2.881%2C2.881-2.881%2C7.549%2C0%2C10.43l5.205%2C5.215%20c2.881%2C2.871%2C7.549%2C2.871%2C10.43%2C0l36.484-36.488L137%2C152.126c2.881%2C2.871%2C7.549%2C2.871%2C10.42%2C0l5.215-5.215%20c2.881-2.881%2C2.881-7.549%2C0-10.43L116.152%2C99.999z%22%2F%3E%3C%2Fsvg%3E"); 181 | -webkit-mask: var(--mask-image) no-repeat center / 100% 100%; 182 | mask: var(--mask-image) no-repeat center / 100% 100%; 183 | } 184 | 185 | .ui-dropanel-close:hover::before { 186 | background-color: var(--ui-dark, #4c5161); 187 | } 188 | 189 | .ui-dropanel-content { 190 | display: block; 191 | min-height: 40px; 192 | padding: 10px 0 20px; 193 | } 194 | 195 | .ui-dropanel-footer { 196 | text-align: right; 197 | } 198 | 199 | .ui-dropanel-footer .ui-button { 200 | margin-left: 15px; 201 | } 202 | 203 | .ui-dropanel-footer .ui-button:first-child { 204 | margin-left: 0; 205 | } 206 | 207 | @media (prefers-reduced-motion: reduce) { 208 | .ui-droplist-x, 209 | .ui-dropanel-x { 210 | animation: none; 211 | } 212 | .ui-dropanel-close::before { 213 | transition: none; 214 | } 215 | } -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Input.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Input.css 5 | * @author zhangxinxu(.com) 6 | * @create 15-06-16 7 | * @edit 17-06-13 8 | 19-07-18 version pure 9 | 20-04-03 version edge 10 | * @editor lennonover 11 | */ 12 | /* input基础变量 */ 13 | :root { 14 | --ui-input-height: var(--ui-component-height, 40px); 15 | --ui-input-line-height: var(--ui-line-height, 20px); 16 | --ui-input-search-img: url("data:image/svg+xml,%3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M638.72 638.72a256 256 0 1 0-361.984-361.984A256 256 0 0 0 638.72 638.72zm58.71 119.04a384 384 0 1 1 85.418-95.573l202.24 202.24a64.256 64.256 0 0 1 .597 91.136 63.744 63.744 0 0 1-91.05-.598l-197.206-197.12z' fill='%23b6bbc6'/%3E%3C/svg%3E") no-repeat; 17 | } 18 | 19 | /* reset [type=search] ui */ 20 | [type="search"] { 21 | -webkit-appearance: none; 22 | } 23 | 24 | [type="search"]::-webkit-search-cancel-button { 25 | -webkit-appearance: none; 26 | width: 20px; 27 | height: 20px; 28 | margin-right: -2px; 29 | background: var(--ui-dark-gray, #b6bbc6) 30 | url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgMjAwIDIwMCI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNGRkYiIGQ9Ik0wIDB2MjAwaDIwMFYwSDB6bTE1MS42MzYgMTM2LjQ4MmE3LjM3NCA3LjM3NCAwIDAgMSAwIDEwLjQyN2wtNS4yMTIgNS4yMWE3LjM3MiA3LjM3MiAwIDAgMS0xMC40MjYgMGwtMzYuNDgzLTM2LjQ4NUw2My4wMyAxNTIuMTJhNy4zNyA3LjM3IDAgMCAxLTEwLjQyNCAwbC01LjIxLTUuMjFhNy4zNyA3LjM3IDAgMCAxIDAtMTAuNDI4TDgzLjg4IDEwMCA0Ny4zOTYgNjMuNTE0YTcuMzY4IDcuMzY4IDAgMCAxIDAtMTAuNDI1bDUuMjEtNS4yMWE3LjM2OCA3LjM2OCAwIDAgMSAxMC40MjYgMEw5OS41MTYgODQuMzYgMTM2IDQ3Ljg4YTcuMzcgNy4zNyAwIDAgMSAxMC40MjUgMGw1LjIxMiA1LjIxYTcuMzcgNy4zNyAwIDAgMSAwIDEwLjQyNUwxMTUuMTUzIDEwMGwzNi40ODMgMzYuNDgyeiIvPjwvc3ZnPg==) 31 | no-repeat center; 32 | background-size: 20px 20px; 33 | transition: background-color var(--ui-animate-time, .2s); 34 | cursor: pointer; 35 | } 36 | 37 | [type="search"]::-webkit-search-cancel-button:hover { 38 | background-color: var(--ui-dark, #4c5161); 39 | } 40 | 41 | input[type="search"]::-webkit-search-results-decoration { 42 | display: none; 43 | } 44 | 45 | input:-webkit-autofill { 46 | -webkit-box-shadow: 0 0 0 1000px var(--ui-white, #fff) inset; 47 | background-color: transparent; 48 | } 49 | 50 | input:disabled, 51 | input:read-only { 52 | cursor: default; 53 | } 54 | 55 | /* firefox */ 56 | input:-moz-read-only { 57 | cursor: default; 58 | } 59 | input.ui-input, 60 | .ui-input > input, 61 | [is="ui-input"] { 62 | height: var(--ui-input-height); 63 | line-height: var(--ui-input-line-height); 64 | padding: calc((var(--ui-input-height) - var(--ui-input-line-height) - 2px) / 2) 8px; 65 | border: 1px solid var(--ui-border, #d0d0d5); 66 | border-radius: var(--ui-radius, 4px); 67 | background-color: var(--ui-white, #fff); 68 | box-sizing: border-box; 69 | font-size: var(--ui-font, 14px); 70 | outline: none; 71 | color: var(--ui-dark, #4c5161); 72 | transition: border-color var(--ui-animate-time, .2s), background-color var(--ui-animate-time, .2s); 73 | } 74 | 75 | .ui-input:hover, 76 | .ui-input:hover > input, 77 | [is="ui-input"]:hover { 78 | border-color: var(--ui-dark-border, #ababaf); 79 | } 80 | 81 | .ui-input:focus, 82 | .ui-input > input:focus, 83 | [is="ui-input"]:focus { 84 | border-color: var(--ui-blue, #2a80eb); 85 | } 86 | 87 | span.ui-input { 88 | display: inline-block; 89 | } 90 | 91 | div.ui-input > input, 92 | input[width="100%"] { 93 | width: 100%; 94 | } 95 | 96 | /* input with count */ 97 | .ui-input-x { 98 | position: relative; 99 | } 100 | span.ui-input-x { 101 | display: inline-block; 102 | } 103 | 104 | .ui-input-x > input { 105 | display: block; 106 | width: 100%; 107 | padding-right: 56px; 108 | } 109 | 110 | input ~ .ui-input-count { 111 | line-height: 38px; 112 | padding: 0 2px; 113 | color: var(--ui-gray, #a2a9b6); 114 | font-size: calc(var(--ui-font, 14px) - 2px); 115 | white-space: nowrap; 116 | position: absolute; 117 | font-family: sans-serif; 118 | right: 8px; 119 | top: 1px; 120 | pointer-events: none; 121 | } 122 | .ui-input-count slash { 123 | margin: 0 1px; 124 | } 125 | 126 | /* type=[search] with icon */ 127 | .ui-input-search:not(input) { 128 | position: relative; 129 | } 130 | 131 | .ui-input-search > input:not(.ui-icon-search) { 132 | padding-left: 40px; 133 | } 134 | 135 | .ui-input-search[align="end"] > :not(.ui-icon-search) { 136 | padding-right: 40px; 137 | padding-left: 9px; 138 | } 139 | 140 | .ui-icon-search { 141 | position: absolute; 142 | left: 3px; 143 | top: 0; 144 | bottom: 0; 145 | margin: auto 0; 146 | width: 20px; 147 | height: 20px; 148 | color: var(--ui-dark-gray, #b6bbc6); 149 | background-color: transparent; 150 | border: solid transparent; 151 | border-width: 9px 8px; 152 | box-sizing: content-box; 153 | transition: color var(--ui-animate-time, .2s); 154 | padding: 0; 155 | text-indent: -99px; 156 | font-size: 0; 157 | cursor: pointer; 158 | outline: 0 none; 159 | overflow: hidden; 160 | } 161 | 162 | [align="end"] > .ui-icon-search { 163 | left: auto; 164 | right: 3px; 165 | } 166 | 167 | .ui-input-search:hover .ui-icon-search { 168 | color: var(--ui-gray, #a2a9b6); 169 | } 170 | .ui-input-search > :disabled ~ .ui-icon-search { 171 | color: var(--ui-disabled, #ccd0d7); 172 | cursor: default; 173 | } 174 | .ui-input-search > :focus ~ .ui-icon-search { 175 | color: var(--ui-blue, #2a80eb); 176 | } 177 | .ui-input-search > [is-error] ~ .ui-icon-search { 178 | color: var(--ui-red, #eb4646); 179 | } 180 | 181 | /** 182 | * 改成CSS绘制 183 | */ 184 | .ui-icon-search::before, 185 | .ui-icon-search::after { 186 | content: ""; 187 | position: absolute; 188 | } 189 | .ui-icon-search::before { 190 | width: 9px; 191 | height: 9px; 192 | border: 2px solid; 193 | border-radius: 50%; 194 | left: 2px; 195 | top: 2px; 196 | } 197 | .ui-icon-search::after { 198 | width: 6px; 199 | border-top: 2px solid; 200 | transform-origin: left; 201 | transform: scaleY(1.25) rotate(30deg); 202 | left: 13px; 203 | top: 11px; 204 | } 205 | 206 | /** 207 | * 按钮不支持伪元素,我们使用背景图片代替 208 | * 不建议使用标签按钮, 209 | */ 210 | input.ui-icon-search { 211 | border: 0; 212 | margin: auto 6px; 213 | width: 18px; 214 | height: 18px; 215 | -webkit-mask: var(--ui-input-search-img); 216 | mask: var(--ui-input-search-img); 217 | -webkit-mask-size: 100% 100%; 218 | mask-size: 100% 100%; 219 | background-color: var(--ui-dark-gray, #b6bbc6); 220 | cursor: pointer; 221 | } 222 | 223 | :focus ~ input.ui-icon-search { 224 | background-color: var(--ui-blue, #2a80eb); 225 | } 226 | [is-error] ~ input.ui-icon-search { 227 | background-color: var(--ui-red, #eb4646); 228 | } 229 | 230 | input.ui-input:disabled, 231 | [is="ui-input"]:disabled, 232 | .ui-input > input:disabled, 233 | .ui-input-x > :disabled ~ .ui-input { 234 | background-color: var(--ui-light, #f7f9fa); 235 | } 236 | 237 | input.ui-input:disabled, 238 | [is="ui-input"]:disabled, 239 | .ui-input > input:disabled, 240 | .ui-input-x > input:disabled { 241 | color: var(--ui-gray, #a2a9b6); 242 | } 243 | 244 | .ui-input:disabled:hover, 245 | [is="ui-input"]:disabled:hover, 246 | .ui-input > input:disabled:hover, 247 | .ui-input:hover > input:disabled { 248 | border-color: var(--ui-border, #d0d0d5); 249 | } 250 | .ui-input:read-only:hover, 251 | .ui-input:read-only:focus, 252 | [is="ui-input"]:read-only:hover, 253 | [is="ui-input"]:read-only:focus, 254 | .ui-input > input:read-only:hover, 255 | .ui-input > input:read-only:focus { 256 | border-color: var(--ui-border, #d0d0d5); 257 | } 258 | /* firefox */ 259 | .ui-input:-moz-read-only:hover, 260 | [is="ui-input"]:-moz-read-only:hover, 261 | .ui-input > input:-moz-read-only:hover, 262 | .ui-input:-moz-read-only:focus, 263 | [is="ui-input"]:-moz-read-only:focus, 264 | .ui-input > input:-moz-read-only:focus { 265 | border-color: var(--ui-border, #d0d0d5); 266 | } 267 | 268 | /* error */ 269 | .ui-input[is-error], 270 | [is="ui-input"][is-error], 271 | .ui-input > [is-error] { 272 | border-color: var(--ui-red, #eb4646) !important; 273 | } 274 | .ui-input-count > [is-error], 275 | .ui-input-count[is-error] { 276 | color: var(--ui-red, #eb4646); 277 | } 278 | 279 | @media (prefers-reduced-motion: reduce) { 280 | [type="search"]::-webkit-search-cancel-button, 281 | input.ui-input, 282 | .ui-input > input, 283 | [is="ui-input"], 284 | .ui-icon-search { 285 | transition: none; 286 | } 287 | } -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Keyboard.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @Keyboard.css 4 | * @author zhangxinxu 5 | * @create 17-06-13 6 | * 7 | **/ 8 | .ui-kbd-tips { 9 | position: absolute; 10 | left: -9em; 11 | top: -9em; 12 | font-family: consolas, "Liberation Mono", courier, monospace; 13 | font-size: 12px; 14 | border-radius: 2px; 15 | color: var(--ui-white, #ffffff); 16 | background: rgba(0, 0, 0, 0.75); 17 | opacity: 0.8; 18 | line-height: 13px; 19 | padding: 0 3px; 20 | z-index: 99; 21 | } 22 | 23 | .ui-kbd-tips kbd { 24 | font-family: inherit; 25 | } 26 | 27 | .ui-outline.ui-outline { 28 | outline: 1px dotted var(--ui-blue, #2a80eb); 29 | outline: 5px auto -webkit-focus-ring-color; 30 | } 31 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/LightTip.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @LightTip.css 4 | * @author xinxuzhang 5 | * @create 15-06-25 6 | * @edit 17-06-19 7 | * @edit 19-09-13 @ziven27 [去jQuery] 8 | * @edit 20-05-19 @popeyesailorman [add custom element support] 9 | **/ 10 | /* 11 | * 结构如下: 12 | * 13 | * 14 | */ 15 | /* lighttip基础变量 */ 16 | :root { 17 | --ui-lighttip-width: 25em; 18 | --ui-loading-lighttip: url("data:image/svg+xml,%3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M512 1024q-104 0-199-40-92-39-163-110T40 711Q0 616 0 512q0-15 10.5-25.5T36 476t25.5 10.5T72 512q0 90 35 171 33 79 94 140t140 95q81 34 171 34t171-35q79-33 140-94t95-140q34-81 34-171t-35-171q-33-79-94-140t-140-95q-81-34-171-34-15 0-25.5-10.5T476 36t10.5-25.5T512 0q104 0 199 40 92 39 163 110t110 163q40 95 40 199t-40 199q-39 92-110 163T711 984q-95 40-199 40z' fill='%232a80eb'/%3E%3C/svg%3E") no-repeat; 19 | } 20 | 21 | ui-lighttip { 22 | display: flex; 23 | justify-content: center; 24 | width: var(--ui-lighttip-width, 25em); 25 | font-size: var(--ui-font, 14px); 26 | text-align: left; 27 | line-height: 20px; 28 | color: var(--ui-white, #ffffff); 29 | background-color: var(--ui-dark, #4c5161); 30 | border-radius: calc(var(--ui-radius, 4px) - 2px); 31 | padding: 15px 10px; 32 | position: fixed; 33 | top: calc(var(--ui-sort-index, 0) * 60px + 10px); 34 | left: 50%; 35 | -webkit-transform: translate(-50%,0); 36 | transform: translate(-50%,0); 37 | z-index: 19; 38 | outline: none; 39 | cursor: default; 40 | transition: top var(--ui-animate-time, .2s); 41 | animation: fadeIn .25s both; 42 | } 43 | ui-lighttip:not([open]) { 44 | display: none; 45 | } 46 | 47 | ui-lighttip[type="success"] { 48 | background-color: var(--ui-green, #1cad70); 49 | } 50 | ui-lighttip[type="error"] { 51 | background-color: var(--ui-red, #eb4646); 52 | } 53 | ui-lighttip[type="warning"] { 54 | background-color: var(--ui-orange, #f59b00); 55 | } 56 | ui-lighttip[type="success"]::before, 57 | ui-lighttip[type="error"]::before, 58 | ui-lighttip[type="warning"]::before { 59 | content: ''; 60 | width: 20px; 61 | height: 20px; 62 | flex-shrink: 0; 63 | background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'%3E%3Cpath fill='%23FFF' d='M163.038 57.226c-5.217-4.162-5.713-4.289-11.674-7.244-2.683-1.344-6.633 2.113-8.569 4.67l-52.648 67.042-34.301-43.387c-1.94-2.558-5.516-3.499-8.2-2.293-6.11 3.095-5.496 2.992-10.715 7.029-2.386 1.883-2.535 5.245-.597 7.793 0 0 36.97 46.917 41.44 52.565 6.557 8.068 18.483 7.669 24.744 0 4.62-5.781 61.117-78.506 61.117-78.506 1.937-2.559 1.788-5.918-.597-7.669z'/%3E%3C/svg%3E") no-repeat; 64 | background-size: contain; 65 | transform: translate(-5px, 0); 66 | } 67 | ui-lighttip[type="error"]::before { 68 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'%3E%3Cpath fill='%23FFF' d='M116.153 99.999l36.484-36.486a7.369 7.369 0 0 0 0-10.423l-5.212-5.213a7.375 7.375 0 0 0-10.425 0l-36.484 36.485-36.485-36.485a7.374 7.374 0 0 0-10.424 0l-5.211 5.213a7.365 7.365 0 0 0 0 10.423L84.88 99.999l-36.483 36.485a7.369 7.369 0 0 0 0 10.426l5.211 5.213a7.38 7.38 0 0 0 10.424 0l36.485-36.486L137 152.122a7.38 7.38 0 0 0 10.425 0l5.212-5.213a7.372 7.372 0 0 0 0-10.426l-36.484-36.484z'/%3E%3C/svg%3E"); 69 | } 70 | ui-lighttip[type="warning"]::before { 71 | background-image: url("data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNDgiIGhlaWdodD0iNDgiPjxwYXRoIGQ9Ik00MTMgMTc4YzUuNSAwIDEwLjEgNC42IDEwLjEgMTAuMVY0MTNjMCA1LjUtNC42IDEwLjEtMTAuMSAxMC4xSDE4OC4xYy01LjUgMC0xMC4xLTQuNi0xMC4xLTEwLjFWMTg4LjFjMC01LjUgNC42LTEwLjEgMTAuMS0xMC4xSDQxM20wLTUwSDE4OC4xYy0zMy4xIDAtNjAuMSAyNy02MC4xIDYwLjFWNDEzYzAgMzMuMSAyNyA2MC4xIDYwLjEgNjAuMUg0MTNjMzMuMSAwIDYwLjEtMjcgNjAuMS02MC4xVjE4OC4xYzAtMzMuMS0yNy02MC4xLTYwLjEtNjAuMXptNDIzLjEgMzQ1LjFINjExLjJjLTMzLjEgMC02MC4xLTI3LTYwLjEtNjAuMVYxODguMWMwLTMzLjEgMjctNjAuMSA2MC4xLTYwLjFoMjI0LjljMzMuMSAwIDYwLjEgMjcgNjAuMSA2MC4xVjQxM2MwIDMzLTI3LjEgNjAuMS02MC4xIDYwLjF6TTQxMyA2MDEuM2M1LjUgMCAxMC4xIDQuNiAxMC4xIDEwLjF2MjI0LjljMCA1LjUtNC42IDEwLjEtMTAuMSAxMC4xSDE4OC4xYy01LjUgMC0xMC4xLTQuNi0xMC4xLTEwLjFWNjExLjRjMC01LjUgNC42LTEwLjEgMTAuMS0xMC4xSDQxM20wLTUwSDE4OC4xYy0zMy4xIDAtNjAuMSAyNy02MC4xIDYwLjF2MjI0LjljMCAzMy4xIDI3IDYwLjEgNjAuMSA2MC4xSDQxM2MzMy4xIDAgNjAuMS0yNyA2MC4xLTYwLjFWNjExLjRjMC0zMy0yNy02MC4xLTYwLjEtNjAuMXptNDIzLjEgNTBjNS41IDAgMTAuMSA0LjYgMTAuMSAxMC4xdjIyNC45YzAgNS41LTQuNiAxMC4xLTEwLjEgMTAuMUg2MTEuMmMtNS41IDAtMTAuMS00LjYtMTAuMS0xMC4xVjYxMS40YzAtNS41IDQuNi0xMC4xIDEwLjEtMTAuMWgyMjQuOW0wLTUwSDYxMS4yYy0zMy4xIDAtNjAuMSAyNy02MC4xIDYwLjF2MjI0LjljMCAzMy4xIDI3IDYwLjEgNjAuMSA2MC4xaDIyNC45YzMzLjEgMCA2MC4xLTI3IDYwLjEtNjAuMVY2MTEuNGMwLTMzLTI3LjEtNjAuMS02MC4xLTYwLjF6IiBmaWxsPSIjZmZmIi8+PC9zdmc+"); 72 | } 73 | 74 | /* 移动端居中呈现 */ 75 | @media (max-width: 640px) { 76 | ui-lighttip { 77 | width: auto; 78 | padding-left: 1rem; padding-right: 1rem; 79 | max-width: calc(100% - 2rem - 2em); 80 | } 81 | } 82 | 83 | /* 全局loading */ 84 | ui-lighttip[type="loading"] { 85 | top: 50%; 86 | left: 50%; 87 | width: auto; 88 | padding-right: calc(10px + .5em); 89 | max-width: calc(100% - 2rem - 2em); 90 | transform: translate(-50%, -50%); 91 | border-radius: var(--ui-radius, 4px); 92 | background-color: rgba(25, 28, 34, 0.88); 93 | visibility: hidden; 94 | opacity: 0; 95 | } 96 | ui-lighttip[type="loading"][open]::before { 97 | content: ''; 98 | display: inline-block; 99 | width: 20px; 100 | height: 20px; 101 | margin: 0 .5em; 102 | background: var(--ui-loading-lighttip) no-repeat center / 100%; 103 | animation: spin 1s linear infinite; 104 | filter: brightness(100); 105 | } 106 | ui-lighttip[type="loading"][open]{ 107 | visibility: visible; 108 | opacity: 1; 109 | } 110 | ui-lighttip[type="loading"]::before{ 111 | display: none; 112 | } 113 | 114 | @media (prefers-reduced-motion: reduce) { 115 | ui-lighttip { 116 | animation: none; 117 | } 118 | } -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Loading.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Loading.css 5 | * @author zhangxinxu 6 | * @create 15-06-23 7 | * @edit 19-09-24 add custom element support 8 | * @edit by littleLionGuoQing: 20-04-30 支持使用color变色 9 | * 10 | **/ 11 | /* 12 | * 结构如下: 13 | * 14 | * 15 | */ 16 | /* loading基础变量 */ 17 | :root { 18 | --ui-loading-img: url("data:image/svg+xml,%3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M512 1024q-104 0-199-40-92-39-163-110T40 711Q0 616 0 512q0-15 10.5-25.5T36 476t25.5 10.5T72 512q0 90 35 171 33 79 94 140t140 95q81 34 171 34t171-35q79-33 140-94t95-140q34-81 34-171t-35-171q-33-79-94-140t-140-95q-81-34-171-34-15 0-25.5-10.5T476 36t10.5-25.5T512 0q104 0 199 40 92 39 163 110t110 163q40 95 40 199t-40 199q-39 92-110 163T711 984q-95 40-199 40z' fill='%232a80eb'/%3E%3C/svg%3E") no-repeat; 19 | } 20 | 21 | ui-loading, 22 | .ui-loading { 23 | text-align: center; 24 | cursor: default; 25 | /* icon offset need */ 26 | box-sizing: border-box; 27 | } 28 | ui-loading { 29 | display: inline-block; 30 | font-size: var(--ui-font, 14px); 31 | line-height: 20px; 32 | vertical-align: middle; 33 | } 34 | 35 | ui-loading[rows] { 36 | display: block; 37 | } 38 | ui-loading:not([rows]):not([spin])::before { 39 | display: block; 40 | } 41 | ui-loading:not([rows]):not([spin])::after { 42 | display: none; 43 | } 44 | 45 | /* 更高高度使用style属性内容或者JS控制 */ 46 | ui-loading[rows="2"] { 47 | height: 40px; 48 | } 49 | ui-loading[rows="3"] { 50 | height: 60px; 51 | } 52 | ui-loading[rows="4"] { 53 | height: 80px; 54 | } 55 | ui-loading[rows="5"] { 56 | height: 100px; 57 | } 58 | ui-loading[rows="6"] { 59 | height: 120px; 60 | } 61 | ui-loading[rows="7"] { 62 | height: 140px; 63 | } 64 | ui-loading[rows="8"] { 65 | height: 160px; 66 | } 67 | ui-loading[rows="9"] { 68 | height: 180px; 69 | } 70 | ui-loading[rows="10"] { 71 | height: 200px; 72 | } 73 | ui-loading[rows="11"] { 74 | height: 220px; 75 | } 76 | ui-loading[rows="12"] { 77 | height: 240px; 78 | } 79 | ui-loading[rows="13"] { 80 | height: 260px; 81 | } 82 | ui-loading[rows="14"] { 83 | height: 280px; 84 | } 85 | ui-loading[rows="15"] { 86 | height: 300px; 87 | } 88 | ui-loading[width="100%"] { 89 | width: 100%; 90 | } 91 | ui-loading[height="100%"] { 92 | height: 100%; 93 | } 94 | 95 | ui-loading::after, 96 | .ui-loading::after { 97 | content: ''; 98 | display: inline-block; 99 | height: 100%; 100 | vertical-align: middle; 101 | } 102 | ui-loading::before, 103 | .ui-loading::before { 104 | content: ''; 105 | display: inline-block; 106 | width: 20px; 107 | height: 20px; 108 | margin: 0 .5em; 109 | background-color: var(--color,#2a80eb); 110 | -webkit-mask: var(--ui-loading-img); 111 | mask: var(--ui-loading-img); 112 | -webkit-mask-size: 100% 100%; 113 | mask-size: 100% 100%; 114 | animation: spin 1s linear infinite; 115 | vertical-align: -4px; 116 | } 117 | ui-loading[spin]::before, 118 | .ui-loading[spin]::before { 119 | display: none; 120 | } 121 | 122 | ui-loading[size="1"]::before, 123 | .ui-loading[size="1"]::before { 124 | width: 10px; height: 10px; 125 | vertical-align: 0; 126 | } 127 | ui-loading[size="3"]::before, 128 | .ui-loading[size="3"]::before { 129 | width: 30px; height: 30px; 130 | vertical-align: -8px; 131 | } 132 | ui-loading[size="4"]::before, 133 | .ui-loading[size="4"]::before { 134 | width: 40px; height: 40px; 135 | vertical-align: -12px; 136 | } 137 | 138 | @keyframes spin { 139 | from { 140 | transform: rotate(0); 141 | } 142 | to { 143 | transform: rotate(360deg); 144 | } 145 | } 146 | 147 | /* 文本点点点 */ 148 | ui-dot, 149 | [is-dot] { 150 | display: inline-block; 151 | height: 1em; line-height: 1; 152 | text-align: left; 153 | vertical-align: -.25em; 154 | overflow: hidden; 155 | } 156 | ui-dot::before, 157 | [is-dot]::before { 158 | display: block; 159 | content: '...\A..\A.'; 160 | white-space: pre-wrap; 161 | animation: dot 3s infinite step-start both; 162 | } 163 | @keyframes dot { 164 | 33% { 165 | transform: translateY(-2em); 166 | } 167 | 66% { 168 | transform: translateY(-1em); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Pagination.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @Pagination.css 4 | * @author xboxyan 5 | * @create 20-06-03 6 | * @editd 21-06-25 by zhangxinxu 7 | **/ 8 | 9 | ui-pagination:not(:defined), 10 | [is-pagination]:not([defined]){ 11 | display: flex; 12 | height: 30px; 13 | } -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Placeholder.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @Placeholder.css 3 | * @editor gandaochuan 4 | * @edit 20-04-10 5 | */ 6 | 7 | ::placeholder { 8 | transition: opacity var(--ui-animate-time, .2s); 9 | color: var(--ui-gray, #a2a9b6); 10 | font-size: var(--ui-font, 14px); 11 | opacity: 1; /* fix firefox */ 12 | } 13 | 14 | :focus::placeholder { 15 | opacity: var(--ui-opacity, .4); 16 | } 17 | 18 | @media (prefers-reduced-motion: reduce) { 19 | ::placeholder { 20 | transition: none; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Progress.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @Progress.css 4 | * @author zhangxinxu 5 | * @create 19-10-18 6 | * @editor gandaochuan 7 | * @edit 20-04-10 8 | * 9 | **/ 10 | 11 | /* progress基础变量 */ 12 | :root { 13 | --ui-progress-width: 10em; 14 | --ui-progress-height: .25em; 15 | --ui-progress-background-color: var(--ui-border, #d0d0d5); 16 | } 17 | 18 | .ui-progress, 19 | [is="ui-progress"] { 20 | display: inline-block; 21 | width: var(--ui-progress-width, 10em); 22 | height: var(--ui-progress-height, .25em); 23 | vertical-align: calc(.25em - 2px); 24 | border: 0; 25 | background-color: var(--ui-progress-background-color); 26 | border-radius: 1em; 27 | overflow: hidden; 28 | } 29 | .ui-progress::-moz-progress-bar, 30 | [is="ui-progress"]::-moz-progress-bar { 31 | background-color: var(--ui-blue); 32 | } 33 | .ui-progress::-webkit-progress-bar, 34 | [is="ui-progress"]::-webkit-progress-bar { 35 | background-color: var(--ui-progress-background-color); 36 | } 37 | .ui-progress::-webkit-progress-value, 38 | [is="ui-progress"]::-webkit-progress-value { 39 | background-color: var(--ui-blue); 40 | } 41 | 42 | progress[width="100%"] { 43 | width: 100%; 44 | } 45 | 46 | /* For firefox to match no [value] */ 47 | .ui-progress:indeterminate::-moz-progress-bar, 48 | [is="ui-progress"]:indeterminate::-moz-progress-bar { 49 | background-color: inherit; 50 | } 51 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Radio.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Radio.css 5 | * @author zhangxinxu 6 | * @create 15-06-17 7 | * @edit 17-06-14 focusable 8 | * @editor shanyerong 9 | * @edit 2020-04-30 description here 10 | **/ 11 | /* radio基础变量 */ 12 | :root { 13 | --ui-radio-width: 20px; 14 | --ui-radio-height: 20px; 15 | } 16 | 17 | [is="ui-radio"] { 18 | -moz-appearance: none; 19 | -webkit-appearance: none; 20 | width: var(--ui-radio-width, 20px); 21 | height: var(--ui-radio-height, 20px); 22 | cursor: pointer; 23 | display: inline-flex; 24 | outline: none; 25 | border: solid 1px var(--ui-border, #d0d0d5); 26 | background-color: var(--ui-white, #ffffff); 27 | border-radius: 100%; 28 | box-sizing: border-box; 29 | vertical-align: -0.5ex; 30 | -webkit-user-select: none; 31 | -ms-user-select: none; 32 | user-select: none; 33 | transition: border-color var(--ui-animate-time, .2s); 34 | } 35 | [is="ui-radio"]::after { 36 | content: ""; 37 | width: 100%; 38 | height: 100%; 39 | background-color: var(--ui-blue, #2a80eb); 40 | transform: scale(0); 41 | opacity: 0; 42 | border-radius: 100%; 43 | } 44 | 45 | [is="ui-radio"]:not(:disabled):hover { 46 | border-color: var(--ui-dark-border, #ababaf); 47 | } 48 | [is="ui-radio"]:focus { 49 | border-color: var(--ui-blue, #2a80eb); 50 | } 51 | [is="ui-radio"]:checked::after { 52 | transform: scale(.5); 53 | opacity: 1; 54 | } 55 | [is="ui-radio"]:disabled { 56 | border-color: var(--ui-dark-border, #ababaf); 57 | opacity: var(--ui-opacity, .4); 58 | cursor: default; 59 | } 60 | [is="ui-radio"][is-error] { 61 | border-color: var(--ui-red, #eb4646) !important; 62 | } 63 | 64 | @media (prefers-reduced-motion: reduce) { 65 | [is="ui-radio"] { 66 | transition: none; 67 | } 68 | } -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Range.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Range.css 5 | * @author xboxyan 6 | * @create 20-04-30 7 | **/ 8 | /* range基础变量 */ 9 | :root { 10 | --ui-range-track-hegiht: 4px; 11 | --ui-range-thumb-size: 16px; 12 | } 13 | 14 | /* range */ 15 | [is="ui-range"] { 16 | -webkit-appearance: none; 17 | appearance: none; 18 | margin: 0; 19 | outline: 0; 20 | background-color: transparent; 21 | vertical-align: middle; 22 | } 23 | [is="ui-range"]:disabled { 24 | opacity: var(--ui-opacity, .4); 25 | } 26 | [is="ui-range"]::-webkit-slider-runnable-track { 27 | display: flex; 28 | align-items: flex-start; 29 | position: relative; 30 | height: var(--ui-range-track-hegiht); 31 | border-radius: var(--ui-range-track-hegiht); 32 | background: linear-gradient(to right, var(--ui-blue, #2a80eb) calc(100% * var(--percent,100)), var(--ui-gray, #a2a9b6) 0% ); 33 | } 34 | [type="range" i]::-webkit-slider-container { 35 | display: flex; 36 | height: var(--ui-range-thumb-size); 37 | } 38 | [is="ui-range"]::-webkit-slider-thumb { 39 | -webkit-appearance: none; 40 | appearance: none; 41 | width: var(--ui-range-thumb-size); 42 | height: var(--ui-range-thumb-size); 43 | border-radius: 50%; 44 | background-color: #fff; 45 | box-shadow: 0 1px 3px 1px rgba(0, 0, 0, .25); 46 | transition: border-color var(-ui-animate-time, .2s), background-color var(-ui-animate-time, .2s); 47 | margin-top: calc((var(--ui-range-thumb-size) - var(--ui-range-track-hegiht)) * -0.5); 48 | } 49 | [is="ui-range"]::-webkit-slider-thumb:active { 50 | background-color: var(--ui-light,#f7f9fa); 51 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, .25); 52 | } 53 | 54 | /* Firefox */ 55 | [is="ui-range"]::-moz-range-track { 56 | background: var(--ui-light-border, #ededef); 57 | height: 4px; 58 | } 59 | 60 | [is="ui-rate"]::-moz-range-track { 61 | background: var(--ui-light-border, #ededef); 62 | height: inherit; 63 | } 64 | 65 | [is="ui-range"]::-moz-range-progress { 66 | background: var(--ui-blue, #2a80eb); 67 | height: 4px; 68 | } 69 | 70 | [is="ui-range"]::-moz-range-thumb { 71 | width: var(--ui-range-thumb-size); 72 | height: var(--ui-range-thumb-size); 73 | border: none; 74 | border-radius: 50%; 75 | background-color: #fff; 76 | box-shadow: 0 1px 3px 1px rgba(0, 0, 0, .25); 77 | } 78 | 79 | 80 | /* 黑色提示效果 */ 81 | input[data-tips]{ 82 | position: relative; 83 | } 84 | [is="ui-range"][data-tips] { 85 | box-sizing: border-box; 86 | border-style: solid; 87 | border-color: transparent; 88 | border-width: 0 calc(var(--ui-range-thumb-size) * 0.5); 89 | } 90 | [is="ui-range"][data-tips]::-webkit-slider-runnable-track { 91 | margin: 0 calc(var(--ui-range-thumb-size) * -0.5); 92 | } 93 | input[data-tips]::before, 94 | input[data-tips]::after { 95 | content: ''; 96 | display: block; 97 | position: absolute; 98 | z-index: 1; 99 | transform: translate(-50%, -20px); 100 | opacity: 0; 101 | transition: all .15s .15s,left 0s, top 0s; 102 | color: #373c42; 103 | visibility: hidden; 104 | pointer-events: none; 105 | } 106 | input[data-tips]::before { 107 | content: attr(data-tips); 108 | border-radius: 3px; 109 | padding: 6px 10px; 110 | line-height: 18px; 111 | text-align: left; 112 | background-color: #373c42; 113 | color: #fff; 114 | font-size: 12px; 115 | font-style: normal; 116 | width: max-content; 117 | max-width: 200px; 118 | left: calc( var(--percent,.5) * 100% ); 119 | bottom: 100%; 120 | transform: translate(-50%, -20px); 121 | } 122 | input[data-tips]::after { 123 | width: 0; 124 | height: 0; 125 | overflow: hidden; 126 | border: 6px solid transparent; 127 | left: calc( var(--percent,.5) * 100% ); 128 | bottom: 100%; 129 | transform: translate(-50%, -20px); 130 | margin-bottom: -12px; 131 | border-top-color: currentColor; 132 | } 133 | input[data-tips][reverse]::before { 134 | left: calc( var(--percent,.5) * 100% ); 135 | bottom: auto; 136 | top: 100%; 137 | transform: translate(-50%, 20px); 138 | } 139 | input[data-tips][reverse]::after { 140 | bottom: auto; 141 | top: 100%; 142 | transform: translate(-50%, 20px); 143 | margin-top: -12px; 144 | border-top-color: transparent; 145 | border-bottom-color: currentColor; 146 | } 147 | input[data-tips]:not([data-tips*="$"]):hover::before, 148 | input[data-tips]:not([data-tips*="$"]):hover::after, 149 | input[data-tips]:not([data-tips*="$"]):active::before, 150 | input[data-tips]:not([data-tips*="$"]):active::after { 151 | visibility: visible; 152 | opacity: 1; 153 | transform: translate(-50%, calc( var(--ui-range-thumb-size) * -1)); 154 | } 155 | input[data-tips][reverse]:not([data-tips*="$"]):hover::before, 156 | input[data-tips][reverse]:not([data-tips*="$"]):hover::after, 157 | input[data-tips][reverse]:not([data-tips*="$"]):active::before, 158 | input[data-tips][reverse]:not([data-tips*="$"]):active::after { 159 | transform: translate(-50%, var(--ui-range-thumb-size)); 160 | } 161 | 162 | /* 区域选择 */ 163 | [is="ui-range"][multiple]{ 164 | pointer-events: none; 165 | vertical-align: top; 166 | } 167 | [is="ui-range"][multiple]::-webkit-slider-runnable-track { 168 | background: linear-gradient(to right, var(--ui-gray, #a2a9b6) calc(1% * var(--from, 0)), var(--ui-blue, #2a80eb) calc(1% * var(--from, 0)) calc(1% * var(--to, 100)), var(--ui-gray, #a2a9b6) 0%); 169 | } 170 | 171 | [is="ui-range"][multiple][data-range="from"] { 172 | display: block; 173 | position: absolute; 174 | } 175 | [is="ui-range"][multiple][data-range="to"] { 176 | opacity: 1; 177 | } 178 | [is="ui-range"][multiple][data-range="to"]:disabled::-webkit-slider-thumb { 179 | box-shadow: 0 1px 3px 1px rgba(0, 0, 0, .1); 180 | } 181 | [is="ui-range"][multiple][data-range="to"]::-webkit-slider-runnable-track { 182 | background: none; 183 | } 184 | [is="ui-range"][multiple]::-webkit-slider-thumb { 185 | pointer-events: all; 186 | position: relative; 187 | } 188 | [is="ui-range"][multiple]::-webkit-slider-thumb:active { 189 | z-index: 1; 190 | } 191 | 192 | /* Firefox 范围选择 */ 193 | [is="ui-range"][multiple]::-moz-range-thumb { 194 | pointer-events: initial; 195 | } 196 | [is="ui-range"][multiple]::-moz-range-track { 197 | background: linear-gradient(to right, var(--ui-gray, #a2a9b6) calc(1% * var(--from, 0)), var(--ui-blue, #2a80eb) calc(1% * var(--from, 0)) calc(1% * var(--to, 100)), var(--ui-gray, #a2a9b6) 0%); 198 | } 199 | [is="ui-range"][multiple][data-range="to"]::-moz-range-progress { 200 | background: none; 201 | } 202 | 203 | /* 星星评分 */ 204 | [is="ui-rate"]:enabled { 205 | cursor: pointer; 206 | } 207 | [is="ui-rate"]:disabled { 208 | opacity: var(--ui-opacity, .4); 209 | } 210 | [is="ui-rate"] { 211 | -webkit-appearance: none; 212 | appearance: none; 213 | margin: 0; 214 | outline: 0; 215 | background-color: transparent; 216 | vertical-align: middle; 217 | width: calc(var(--number, 5) * 2em); 218 | --mask-url: url("data:image/svg+xml,%3Csvg width='12' height='11' viewBox='0 0 12 11' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 0l1.693 3.67 4.013.476L8.74 6.89l.788 3.964L6 8.88l-3.527 1.974.788-3.964L.294 4.146l4.013-.476L6 0z'/%3E%3C/svg%3E"); 219 | --mask: var(--mask-url) repeat-x left / 2em 100%; 220 | } 221 | 222 | [is="ui-rate"]::-webkit-slider-runnable-track { 223 | background: var(--ui-orange, #f59b00); 224 | height: 2em; 225 | -webkit-mask: var(--mask); 226 | mask: var(--mask); 227 | } 228 | 229 | [is="ui-rate"]::-webkit-slider-thumb { 230 | -webkit-appearance: none; 231 | width: 1px; 232 | height: 100%; 233 | box-shadow: 999em 0 0 999em var(--ui-light-border, #ededef); 234 | } 235 | 236 | [is="ui-rate"]:focus::-webkit-slider-thumb { 237 | box-shadow: 999em 0 0 999em var(--ui-light-border, #ededef); 238 | background: var(--ui-orange, #f59b00); 239 | } 240 | [is="ui-rate"][readonly] { 241 | cursor: default; 242 | pointer-events: none; 243 | } 244 | 245 | /* 兼容火狐浏览器 */ 246 | [is="ui-rate"], 247 | _::-moz-range-track { 248 | appearance: none; 249 | -webkit-mask: var(--mask); 250 | mask: var(--mask); 251 | height: 2em; 252 | } 253 | 254 | [is="ui-rate"]::-moz-range-progress { 255 | background: var(--ui-orange, #f59b00); 256 | height: inherit; 257 | } 258 | 259 | [is="ui-rate"]::-moz-range-thumb { 260 | width: 0; 261 | opacity: 0; 262 | } 263 | 264 | @media (prefers-reduced-motion: reduce) { 265 | [is="ui-range"]::-webkit-slider-thumb, 266 | input[data-tips]::before, 267 | input[data-tips]::after, 268 | [is="ui-range"][data-tips][vertical]::before, 269 | [is="ui-range"][data-tips][vertical]::after, 270 | [is="ui-range"][data-tips][vertical][reverse]::before, 271 | [is="ui-range"][data-tips][vertical][reverse]::after { 272 | transition: none; 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Select.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @Select.css 4 | * @author zhangxinxu(.com) 5 | * @create 15-06-18 6 | * @edited 19-08-27 7 | * 8 | **/ 9 | 10 | [is="ui-select"] { 11 | display: inline-block; 12 | height: 40px; 13 | margin: 0; 14 | border: 1px solid var(--ui-border, #d0d0d5); 15 | font-size: var(--ui-font, 14px); 16 | font-family: inherit; 17 | vertical-align: middle; 18 | } 19 | 20 | [is="ui-select"][width="100%"] { 21 | width: 100%; 22 | } 23 | 24 | [is="ui-select"] { 25 | transform-origin: left; 26 | /* OS X padding-right无效 */ 27 | border-right: 27px solid var(--ui-border, #d0d0d5); 28 | opacity: 0.0001; 29 | pointer-events: none; 30 | visibility: hidden; 31 | z-index: 1; 32 | } 33 | 34 | [is="ui-select"][multiple] { 35 | visibility: visible; 36 | pointer-events: auto; 37 | } 38 | 39 | [is="ui-select"] option { 40 | min-height: 38px; 41 | height: 38px; 42 | padding: 0; 43 | font-size: inherit; 44 | } 45 | 46 | [is="ui-select"][multiple] { 47 | height: auto; 48 | font-size: calc(34px - 1px); 49 | font-size: var(--ui-font, 14px); 50 | padding: 0; 51 | border-right-width: 13px; 52 | border-left: 13px solid; 53 | vertical-align: top; 54 | cursor: pointer; 55 | } 56 | 57 | [is="ui-select"][multiple] > option { 58 | min-height: 38px; 59 | height: 38px; 60 | padding: 0; 61 | font-size: inherit; 62 | } 63 | 64 | select[multiple] > option:disabled { 65 | cursor: default; 66 | } 67 | 68 | .ui-select { 69 | display: inline-block; 70 | height: 40px; 71 | line-height: 20px; 72 | vertical-align: middle; 73 | font-size: var(--ui-font, 14px); 74 | transition: opacity var(--ui-animate-time, .2s); 75 | text-align: start; 76 | position: relative; 77 | } 78 | 79 | [disabled] + .ui-select { 80 | pointer-events: none; 81 | } 82 | 83 | select[hidden], 84 | select[hidden] + .ui-select { 85 | display: none; 86 | } 87 | 88 | [is="ui-select"][multiple] + .ui-select { 89 | vertical-align: top; 90 | } 91 | 92 | .ui-select.active { 93 | z-index: 3; 94 | } 95 | 96 | .ui-select-button { 97 | display: block; 98 | height: 20px; 99 | padding: 9px 27px 9px 12px; 100 | color: var(--ui-dark, #4c5161); 101 | border: 1px solid var(--ui-border, #d0d0d5); 102 | border-radius: var(--ui-radius, 4px); 103 | background-color: var(--ui-white, #fff); 104 | text-decoration: none; 105 | transition: border-color var(--ui-animate-time, .2s), background-color var(--ui-animate-time, .2s); 106 | cursor: pointer; 107 | } 108 | 109 | .ui-select-button:hover { 110 | color: var(--ui-dark, #4c5161); 111 | border-color: var(--ui-dark-border, #ababaf); 112 | } 113 | 114 | :not(:disabled) + .ui-select > .ui-select-button:active { 115 | background-color: var(--ui-light, #f7f9fa); 116 | } 117 | 118 | .active > a.ui-select-button { 119 | border-color: var(--ui-blue, #2a80eb); 120 | border-radius: var(--ui-radius, 4px) var(--ui-radius, 4px) 0 0; 121 | } 122 | 123 | .reverse > a.ui-select-button { 124 | border-radius: 0 0 var(--ui-radius, 4px) var(--ui-radius, 4px); 125 | } 126 | 127 | .ui-select-text { 128 | display: block; 129 | width: 100%; 130 | text-overflow: ellipsis; 131 | white-space: nowrap; 132 | overflow: hidden; 133 | } 134 | 135 | .ui-select-icon, 136 | .ui-select-text:only-child::after, 137 | .ui-select-button:empty::after { 138 | position: absolute; 139 | width: 20px; 140 | height: 20px; 141 | background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'%3E%3Cpath fill='%232a80eb' d='M145.659 68.949a12.874 12.874 0 0 0-18.473 0L99.479 97.233 71.772 68.949a12.874 12.874 0 0 0-18.473 0c-5.099 5.208-5.099 13.648 0 18.857l46.18 47.14 46.181-47.14c5.099-5.208 5.099-13.649-.001-18.857z'/%3E%3C/svg%3E") 142 | no-repeat center; 143 | background-size: 20px 20px; 144 | right: 7px; 145 | top: 10px; 146 | } 147 | .ui-select-text:only-child::after, 148 | .ui-select-button:empty::after { 149 | content: ""; 150 | } 151 | 152 | .ui-select-datalist { 153 | position: absolute; 154 | left: 0; 155 | right: 0; 156 | top: 39px; 157 | display: none; 158 | box-sizing: border-box; 159 | max-height: 306px; 160 | padding: 0; 161 | border: 1px solid var(--ui-blue, #2a80eb); 162 | background-color: var(--ui-white, #fff); 163 | font-size: 14px; 164 | overflow: auto; 165 | overscroll-behavior: none; 166 | -ms-scroll-chaining: none; 167 | scrollbar-width: thin; 168 | text-align: left; 169 | } 170 | 171 | [multiple] ~ .ui-select > .ui-select-datalist { 172 | position: static; 173 | display: block; 174 | max-height: none; 175 | height: inherit; 176 | border-color: #d0d0d5; 177 | border-radius: var(--ui-radius, 4px); 178 | box-sizing: border-box; 179 | } 180 | 181 | [multiple]:hover ~ .ui-select > .ui-select-datalist { 182 | border-color: var(--ui-dark-border, #ababaf); 183 | } 184 | 185 | [multiple]:focus ~ .ui-select > .ui-select-datalist { 186 | border-color: var(--ui-blue, #2a80eb); 187 | } 188 | 189 | [data-custom-scroll="true"]::-webkit-scrollbar { 190 | width: 8px; 191 | height: 8px; 192 | } 193 | 194 | [data-custom-scroll="true"]::-webkit-scrollbar-thumb { 195 | background-color: #bbb; 196 | border-radius: calc(var(--ui-radius, 4px) + 4px); 197 | } 198 | 199 | [data-custom-scroll="true"]::-webkit-scrollbar-thumb:hover { 200 | background-color: #aaa; 201 | } 202 | 203 | [data-custom-scroll="true"]::-webkit-scrollbar-track-piece { 204 | background-color: #ddd; 205 | } 206 | 207 | .active > .ui-select-datalist, 208 | .ui-select-datalist.active { 209 | display: block; 210 | } 211 | 212 | .reverse > .ui-select-datalist { 213 | top: auto; 214 | bottom: 39px; 215 | } 216 | 217 | .ui-select-intent { 218 | text-indent: 1em; 219 | } 220 | 221 | .ui-select-datalist-li { 222 | display: block; 223 | line-height: 20px; 224 | padding: 9px 12px; 225 | color: var(--ui-dark, #4c5161); 226 | background-color: var(--ui-white, #fff); 227 | text-decoration: none; 228 | text-overflow: ellipsis; 229 | white-space: nowrap; 230 | transition: background-color var(--ui-animate-time, .2s); 231 | overflow: hidden; 232 | } 233 | h6.ui-select-datalist-li, 234 | .ui-select-datalist-li[role="heading"] { 235 | font-weight: 700; 236 | margin: 0; 237 | padding-bottom: 6px; 238 | } 239 | .ui-select-datalist-li[href] { 240 | cursor: pointer; 241 | } 242 | 243 | .ui-select-datalist-li:not(:only-child):empty { 244 | display: none; 245 | } 246 | 247 | .ui-select-datalist-hr:not(:first-child) { 248 | border: 0; 249 | height: 1px; 250 | padding: 7px 12px; 251 | background-color: var(--ui-white, #fff); 252 | } 253 | .ui-select-datalist-hr:not(:first-child)::before { 254 | content: ''; 255 | display: block; 256 | border-top: 1px solid var(--ui-border, #d0d0d5); 257 | opacity: var(--ui-opacity, .4); 258 | } 259 | 260 | /* reset default a:hover */ 261 | .ui-select-datalist-li:hover { 262 | color: var(--ui-dark, #4c5161); 263 | } 264 | 265 | .ui-select-datalist > .disabled { 266 | color: var(--ui-gray, #a2a9b6); 267 | cursor: default; 268 | } 269 | 270 | .ui-select-datalist > .selected { 271 | background-color: var(--ui-list-selected, #e0f0ff); 272 | } 273 | 274 | .ui-select-datalist-li[href]:hover, 275 | [multiple] ~ .ui-select .ui-select-datalist-li[href] { 276 | color: var(--ui-dark, #4c5161); 277 | background-color: var(--ui-list-hover, #f0f7ff); 278 | } 279 | 280 | /* disabled */ 281 | select:disabled { 282 | cursor: default; 283 | } 284 | 285 | select:disabled + .ui-select { 286 | opacity: var(--ui-opacity, .4); 287 | } 288 | 289 | select:disabled + .ui-select .ui-select-button, 290 | select:disabled + .ui-select .ui-select-datalist { 291 | cursor: default; 292 | border-color: var(--ui-dark-border, #ababaf); 293 | } 294 | 295 | /* error */ 296 | [is-error] .ui-select-button, 297 | [is-error][multiple] ~ .ui-select .ui-select-datalist, 298 | select[is-error] { 299 | border-color: var(--ui-red, #eb4646); 300 | } 301 | 302 | @media (prefers-reduced-motion: reduce) { 303 | .ui-select-button, 304 | .ui-select, 305 | .ui-select-datalist-li { 306 | transition: none; 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Switch.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Switch.css 5 | * @author zhangxinxu 6 | * @create 15-06-18 7 | * @edit 17-06-14 keyboard accessible 8 | * @editor shanyerong 9 | * @edit 2020-04-30 10 | **/ 11 | :root { 12 | --ui-switch-width: 44px; 13 | --ui-switch-height: 26px; 14 | } 15 | input[is="ui-switch"] { 16 | -webkit-appearance: none; 17 | display: inline-flex; 18 | outline: none; 19 | box-sizing: border-box; 20 | box-shadow: inset 0 1px, inset 1px 0, inset -1px 0, inset 0 -1px; 21 | background-clip: content-box; 22 | -webkit-appearance: none; 23 | width: var(--ui-switch-width, 44px); 24 | height: var(--ui-switch-height, 26px); 25 | border: 2px solid; 26 | border-radius: var(--ui-switch-height, 26px); 27 | background-color: currentColor; 28 | color: var(--ui-dark-gray, #b6bbc6); 29 | font-size: 0; 30 | transition: all var(--ui-animate-time, .2s); 31 | cursor: pointer; 32 | -webkit-user-select: none; 33 | -ms-user-select: none; 34 | user-select: none; 35 | -webkit-tap-highlight-color: transparent; 36 | } 37 | input[is="ui-switch"]:checked { 38 | color: var(--ui-blue, #2a80eb); 39 | background-color: var(--ui-blue, #2a80eb); 40 | } 41 | input[is="ui-switch"]::before { 42 | content: ''; 43 | flex: 0; 44 | transition: flex var(--ui-animate-time, .2s); 45 | } 46 | 47 | input[is="ui-switch"]::after { 48 | content: ""; 49 | width: 22px; 50 | height: 22px; 51 | border-radius: 100%; 52 | background-color: var(--ui-white, #ffffff); 53 | opacity: 1; 54 | visibility: visible; 55 | } 56 | 57 | input[is="ui-switch"]:active { 58 | box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.1); 59 | } 60 | 61 | input[is="ui-switch"]:checked::before { 62 | flex: 1; 63 | } 64 | 65 | input[is="ui-switch"]:disabled { 66 | opacity: var(--ui-opacity, .4); 67 | cursor: default; 68 | } 69 | 70 | input[is="ui-switch"]:focus:not(:disabled), 71 | input[is="ui-switch"]:hover:not(:disabled) { 72 | color: var(--ui-gray, #a2a9b6); 73 | } 74 | 75 | input[is="ui-switch"]:checked:focus:not(:disabled), 76 | input[is="ui-switch"]:checked:hover:not(:disabled) { 77 | color: var(--ui-dark-blue, #0057c3); 78 | background-color: var(--ui-dark-blue, #0057c3); 79 | } 80 | 81 | input[is="ui-switch"]:checked:focus:disabled, 82 | input[is="ui-switch"]:checked:disabled:hover { 83 | color: var(--ui-blue, #2a80eb); 84 | background-color: var(--ui-blue, #2a80eb); 85 | } 86 | 87 | @media (prefers-reduced-motion: reduce) { 88 | input[is="ui-switch"], 89 | input[is="ui-switch"]::before { 90 | transition: none; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Tab.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @Tab.css 4 | * @author xinxuzhang 5 | * @create 15-06-12 6 | */ 7 | /* tabs */ 8 | 9 | ui-tab { 10 | cursor: pointer; 11 | } 12 | 13 | .ui-tab-tabs { 14 | height: 40px; 15 | line-height: 40px; 16 | border-bottom: 1px solid var(--ui-border, #d0d0d5); 17 | position: relative; 18 | display: flex; 19 | } 20 | 21 | .ui-tab-tab { 22 | margin-right: 50px; 23 | font-size: calc(var(--ui-font, 14px) + 2px); 24 | text-align: center; 25 | color: var(--ui-dark, #4c5161); 26 | text-decoration: none; 27 | border: 0; 28 | background: none; 29 | overflow: hidden; 30 | cursor: pointer; 31 | } 32 | 33 | .ui-tab-tab a { 34 | display: block; 35 | color: inherit; 36 | } 37 | 38 | .ui-tab-tab:hover { 39 | color: var(--ui-blue, #2a80eb); 40 | } 41 | 42 | .ui-tab-tabs [open] { 43 | line-height: 36px; 44 | padding-top: 2px; 45 | margin-bottom: -1px; 46 | border-bottom: solid; 47 | color: var(--ui-blue, #2a80eb); 48 | cursor: default; 49 | } 50 | .ui-tab-tabs[style*="--ui-tab"]::after { 51 | content: ""; 52 | position: absolute; 53 | bottom: -1px; 54 | left: calc(1px * var(--ui-tab-left)); 55 | width: calc(1px * var(--ui-tab-width)); 56 | border-bottom: solid var(--ui-blue, #2a80eb); 57 | transition: all var(--ui-animate-time, .2s); 58 | } 59 | 60 | [style*="--ui-tab"] > .ui-tab-tab { 61 | line-height: 40px; 62 | padding-top: 0; 63 | border-bottom: 0; 64 | margin-bottom: 0; 65 | } 66 | 67 | /* contents */ 68 | .ui-tab-contents { 69 | margin-top: 30px; 70 | } 71 | 72 | /* 有role属性表示JS已经介入了初始化,锚点hash显示功能去除 */ 73 | .ui-tab-content[role]:not(.active), 74 | .ui-tab-content:not([role]):not(:target) { 75 | display: none; 76 | } 77 | 78 | .ui-tab-contents:target-within .ui-tab-content:not(:target) { 79 | display: none; 80 | } 81 | 82 | @media (prefers-reduced-motion: reduce) { 83 | .ui-tab-tabs[style*="--ui-tab"]::after { 84 | transition: none; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Table.css: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @Table.css 4 | * @author xinxuzhang 5 | * @create 15-06-24 6 | * 7 | **/ 8 | /* table基础变量 */ 9 | :root { 10 | --ui-table-cell-height: 50px; 11 | --ui-table-line-height: var(--ui-line-height, 20px); 12 | } 13 | 14 | .ui-table, 15 | [is="ui-table"] { 16 | width: -webkit-fill-available; 17 | width: -moz-available; 18 | width: stretch; 19 | line-height: var(--ui-table-line-height); 20 | table-layout: fixed; 21 | border-spacing: 0; 22 | font-size: var(--ui-font, 14px); 23 | border: 1px solid var(--ui-border, #d0d0d5); 24 | } 25 | .ui-table[width="100%"], 26 | [is="ui-table"][width="100%"] { 27 | width: 100%; 28 | } 29 | 30 | .ui-table thead td, 31 | .ui-table th, 32 | [is="ui-table"] thead td, 33 | [is="ui-table"] th { 34 | background-color: var(--ui-light, #f7f9fa); 35 | border-bottom: 1px solid var(--ui-light-border, #ededef); 36 | font-weight: normal; 37 | font-style: normal; 38 | margin: 0; 39 | } 40 | .ui-table thead td:not([class]):not([align]), 41 | .ui-table th:not([class]):not([align]), 42 | [is="ui-table"] thead td:not([class]):not([align]), 43 | [is="ui-table"] th:not([class]):not([align]) { 44 | text-align: left; 45 | } 46 | 47 | .ui-table tbody td, 48 | [is="ui-table"] tbody td { 49 | background-color: var(--ui-white, #ffffff); 50 | border-bottom: 1px solid var(--ui-light-border, #ededef); 51 | } 52 | 53 | .ui-table td, 54 | .ui-table th, 55 | [is="ui-table"] td, 56 | [is="ui-table"] th { 57 | padding-top: calc((var(--ui-table-cell-height) - var(--ui-table-line-height)) / 2); 58 | padding-bottom: calc((var(--ui-table-cell-height) - var(--ui-table-line-height)) / 2 - 1px); 59 | padding-right: 20px; 60 | } 61 | .ui-table td:first-child, 62 | .ui-table th:first-child, 63 | [is="ui-table"] td:first-child, 64 | [is="ui-table"] th:first-child { 65 | padding-left: 20px; 66 | } 67 | 68 | .ui-table tr, 69 | [is="ui-table"] tr { 70 | cursor: default; 71 | } 72 | 73 | .ui-table tr:last-child td, 74 | [is="ui-table"] tr:last-child td { 75 | padding-bottom: calc((var(--ui-table-cell-height) - var(--ui-table-line-height)) / 2); 76 | border-bottom: 0; 77 | } 78 | 79 | .ui-table ~ .ui-loading, 80 | [is="ui-table"] ~ .ui-loading { 81 | height: 300px; 82 | } 83 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Textarea.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Textarea.css 5 | * @author xinxuzhang 6 | * @create 15-06-17 7 | * @edit 20-04-03 version edge 8 | * @editor lennonover 9 | **/ 10 | 11 | :root { 12 | --ui-textarea-line-height: var(--ui-line-height, 20px); 13 | } 14 | 15 | textarea { 16 | font-family: inherit; 17 | } 18 | 19 | textarea.ui-textarea, 20 | [is="ui-textarea"], 21 | .ui-textarea > textarea, 22 | textarea ~ .ui-textarea-count { 23 | line-height: var(--ui-textarea-line-height); 24 | padding: 9px 8px; 25 | border: 1px solid var(--ui-border, #d0d0d5); 26 | border-radius: var(--ui-radius, 4px); 27 | background-color: var(--ui-white, #ffffff); 28 | outline: none; 29 | color: var(--ui-dark, #4c5161); 30 | font-size: var(--ui-font, 14px); 31 | transition: border-color var(--ui-animate-time, .2s), background-color var(--ui-animate-time, .2s); 32 | word-break: break-all; 33 | vertical-align: top; 34 | box-sizing: border-box; 35 | max-width: 100%; 36 | resize: none; 37 | overflow: auto; 38 | } 39 | 40 | textarea[resize] { 41 | resize: both; 42 | } 43 | textarea[resize="vertical"] { 44 | resize: vertical; 45 | } 46 | textarea[resize="horizontal"] { 47 | resize: horizontal; 48 | } 49 | 50 | div.ui-textarea > textarea, 51 | textarea[width="100%"] { 52 | width: 100%; 53 | } 54 | 55 | /* hover */ 56 | .ui-textarea:hover, 57 | .ui-textarea > textarea:hover, 58 | [is="ui-textarea"]:hover, 59 | :hover > .ui-textarea-count { 60 | border-color: var(--ui-dark-border, #ababaf); 61 | } 62 | 63 | /* focus */ 64 | .ui-textarea:focus, 65 | .ui-textarea > textarea:focus, 66 | [is="ui-textarea"]:focus, 67 | :focus ~ .ui-textarea-count { 68 | border-color: var(--ui-blue, #2a80eb); 69 | } 70 | 71 | /* textarea with count */ 72 | .ui-textarea-x { 73 | position: relative; 74 | z-index: 0; 75 | overflow: hidden; 76 | } 77 | span.ui-textarea-x { 78 | display: inline-block; 79 | } 80 | .ui-textarea-x > textarea:only-child { 81 | padding-bottom: 32px; 82 | } 83 | .ui-textarea-x > textarea:not(:only-child) { 84 | padding-bottom: 0; 85 | margin: 1px 1px 33px; 86 | width: calc(100% - 2px); 87 | border: 0; 88 | background: none; 89 | } 90 | .ui-textarea-x > textarea { 91 | display: block; 92 | width: 100%; 93 | /* for Firefox */ 94 | margin: 0; 95 | } 96 | 97 | textarea ~ .ui-textarea-count { 98 | position: absolute; 99 | left: 0; right: 0; bottom: 0; top: 0; 100 | padding-bottom: 5px; 101 | color: var(--ui-gray, #a2a9b6); 102 | font-size: calc(var(--ui-font, 14px) - 2px); 103 | display: flex; 104 | align-items: flex-end; 105 | justify-content: flex-end; 106 | z-index: -1; 107 | } 108 | .ui-textarea-count slash { 109 | margin: 0 1px; 110 | } 111 | 112 | /* disabled */ 113 | .ui-textarea:disabled, 114 | [is="ui-textarea"]:disabled, 115 | .ui-textarea > textarea:disabled, 116 | :disabled ~ .ui-textarea-count { 117 | background-color: var(--ui-light, #f7f9fa); 118 | } 119 | .ui-textarea:read-only, 120 | [is="ui-textarea"]:read-only, 121 | .ui-textarea > textarea:read-only, 122 | :read-only ~ .ui-textarea-count { 123 | background-color: var(--ui-white, #ffffff); 124 | } 125 | /* firefox */ 126 | .ui-textarea:-moz-read-only, 127 | [is="ui-textarea"]:-moz-read-only, 128 | .ui-textarea > textarea:-moz-read-only, 129 | :-moz-read-only ~ .ui-textarea-count { 130 | background-color: var(--ui-white, #ffffff); 131 | } 132 | 133 | .ui-textarea:disabled:hover, 134 | [is="ui-textarea"]:disabled:hover, 135 | .ui-textarea > textarea:disabled:hover, 136 | .ui-textarea-x:hover :disabled ~ .ui-textarea-count { 137 | border-color: var(--ui-border, #d0d0d5); 138 | } 139 | 140 | .ui-textarea:read-only:hover, 141 | .ui-textarea:read-only:focus, 142 | [is="ui-textarea"]:read-only:hover, 143 | [is="ui-textarea"]:read-only:focus, 144 | .ui-textarea > textarea:read-only:hover, 145 | .ui-textarea > textarea:read-only:focus, 146 | :read-only ~ .ui-textarea-count:hover, 147 | :read-only ~ .ui-textarea-count:focus { 148 | border-color: var(--ui-border, #d0d0d5); 149 | } 150 | /* firefox */ 151 | .ui-textarea:-moz-read-only:hover, 152 | .ui-textarea:-moz-read-only:focus, 153 | [is="ui-textarea"]:-moz-read-only:hover, 154 | [is="ui-textarea"]:-moz-read-only:focus, 155 | .ui-textarea > textarea:-moz-read-only:hover, 156 | .ui-textarea > textarea:-moz-read-only:focus { 157 | border-color: var(--ui-border, #d0d0d5); 158 | } 159 | 160 | textarea:read-only, 161 | textarea:disabled { 162 | resize: none; 163 | } 164 | 165 | /* firefox */ 166 | textarea:-moz-read-only { 167 | resize: none; 168 | } 169 | /* error */ 170 | .ui-textarea[is-error], 171 | [is="ui-textarea"][is-error], 172 | .ui-textarea > [is-error], 173 | [is-error] ~ .ui-textarea-count { 174 | border-color: var(--ui-red, #eb4646) !important; 175 | } 176 | .ui-textarea-count > [is-error], 177 | .ui-textarea-count[is-error] { 178 | color: var(--ui-red, #eb4646); 179 | } 180 | 181 | @media (prefers-reduced-motion: reduce) { 182 | textarea.ui-textarea, 183 | [is="ui-textarea"], 184 | .ui-textarea > textarea, 185 | textarea ~ .ui-textarea-count { 186 | transition: none; 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/ui/Tips.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @Tips.css 5 | * @author xinxuzhang 6 | * @create 15-06-25 7 | * 8 | **/ 9 | 10 | :root { 11 | --ui-tips-triangle-size: 6px; /* 底为 6*2,高为 6 */ 12 | --ui-tips-bg: #373c42; 13 | --ui-tips-error-bg: linear-gradient(90deg, #ff8da2, #ec5b60); 14 | 15 | } 16 | 17 | .ui-tips[data-title], 18 | [is-tips="css"][data-title] { 19 | text-indent: 0; 20 | position: relative; 21 | overflow: visible; 22 | } 23 | 24 | .ui-tips[data-title]::before, 25 | .ui-tips[data-title]::after, 26 | [is-tips="css"][data-title]::before, 27 | [is-tips="css"][data-title]::after { 28 | position: absolute; 29 | left: 50%; 30 | -ms-pointer-events: none; 31 | pointer-events: none; 32 | -ms-transform: translateX(-50%); 33 | transform: translateX(-50%); 34 | visibility: hidden; 35 | content: attr(data-title); 36 | bottom: calc(100% + 6px); 37 | max-width: 250px; 38 | /* 四边都预留出三角形的位置 */ 39 | padding: calc(6px + var(--ui-tips-triangle-size)) calc(10px + var(--ui-tips-triangle-size)); 40 | 41 | line-height: 18px; 42 | background: var(--ui-tips-bg); 43 | text-align: left; 44 | color: var(--ui-white, #ffffff); 45 | font-size: calc(var(--ui-font, 14px) - 2px); 46 | font-style: normal; 47 | white-space: nowrap; 48 | } 49 | 50 | .ui-tips[data-title]::before, 51 | [is-tips="css"][data-title]::before { 52 | /* 切割出框体,带 border-radius */ 53 | clip-path: inset( 54 | var(--ui-tips-triangle-size) 55 | var(--ui-tips-triangle-size) 56 | var(--ui-tips-triangle-size) 57 | var(--ui-tips-triangle-size) 58 | round calc(var(--ui-radius, 4px) - 1px)); 59 | } 60 | 61 | .ui-tips[data-title]::after, 62 | [is-tips="css"][data-title]::after { 63 | /* 默认是在框体下方居中位置,多 1 像素避免缝隙 */ 64 | clip-path: polygon( 65 | calc(50% - var(--ui-tips-triangle-size)) calc(100% - (var(--ui-tips-triangle-size) + 1px)), 66 | calc(50% + var(--ui-tips-triangle-size)) calc(100% - (var(--ui-tips-triangle-size) + 1px)), 67 | 50% 100% 68 | ); 69 | } 70 | 71 | .ui-tips[data-title]:hover::before, 72 | .ui-tips[data-title]:hover::after, 73 | .ui-tips[data-title]:focus::before, 74 | .ui-tips[data-title]:focus::after, 75 | [is-tips="css"][data-title]:hover::before, 76 | [is-tips="css"][data-title]:hover::after, 77 | [is-tips="css"][data-title]:focus::before, 78 | [is-tips="css"][data-title]:focus::after { 79 | transition: visibility var(--ui-animate-time, .2s) var(--ui-animate-time, .2s); 80 | visibility: visible; 81 | } 82 | 83 | .ui-tips[data-title]:hover, 84 | [is-tips="css"][data-title]:hover { 85 | outline: none; 86 | } 87 | 88 | /* 朝下的情况 */ 89 | .reverse.ui-tips[data-title]::before, 90 | .reverse.ui-tips[data-title]::after, 91 | .reverse[is-tips="css"][data-title]::before, 92 | .reverse[is-tips="css"][data-title]::after { 93 | bottom: auto; 94 | top: calc(100% + 6px); 95 | } 96 | 97 | .reverse.ui-tips[data-title]::after, 98 | .reverse[is-tips="css"][data-title]::after { 99 | clip-path: polygon( 100 | calc(50% - var(--ui-tips-triangle-size)) calc(0% + var(--ui-tips-triangle-size) + 1px), 101 | calc(50% + var(--ui-tips-triangle-size)) calc(0% + var(--ui-tips-triangle-size) + 1px), 102 | 50% 0% 103 | ); 104 | } 105 | 106 | 107 | /* JS生成的,和CSS定位样式不合并,保持独立 */ 108 | .ui-tips-x { 109 | position: absolute; 110 | width: fit-content; 111 | z-index: 99; 112 | margin-top: -6px; 113 | max-width: 20em; 114 | padding: calc(6px + var(--ui-tips-triangle-size)) calc(10px + var(--ui-tips-triangle-size)); 115 | line-height: 18px; 116 | color: var(--ui-white, #fff); 117 | font-size: calc(var(--ui-font, 14px) - 2px); 118 | font-style: normal; 119 | text-align: left; 120 | } 121 | .ui-tips-x::before, 122 | .ui-tips-x::after { 123 | content: ""; 124 | display: block; 125 | position: absolute; 126 | width: 100%; 127 | height: 100%; 128 | left: 0; 129 | top: 0; 130 | background: var(--ui-tips-bg); 131 | } 132 | .ui-tips-x::before { 133 | z-index:-1; 134 | clip-path: inset( 135 | var(--ui-tips-triangle-size) 136 | var(--ui-tips-triangle-size) 137 | var(--ui-tips-triangle-size) 138 | var(--ui-tips-triangle-size) 139 | round calc(var(--ui-radius, 4px) - 1px)); 140 | } 141 | .ui-tips-x::after { 142 | clip-path: polygon( 143 | calc(50% - var(--ui-tips-triangle-size)) calc(100% - (var(--ui-tips-triangle-size) + 1px)), 144 | calc(50% + var(--ui-tips-triangle-size)) calc(100% - (var(--ui-tips-triangle-size) + 1px)), 145 | 50% 100% 146 | );} 147 | 148 | 149 | 150 | @media (any-hover: none) { 151 | html { 152 | --hoverNone: 'true'; 153 | } 154 | } 155 | 156 | /* 悬浮在左右侧的,限定最大宽度 */ 157 | .ui-tips-x[data-align="8-6"], 158 | .ui-tips-x[data-align="6-8"] { 159 | max-width: 600px; 160 | } 161 | 162 | 163 | /* 悬浮在目标正下方,箭头在框体 50% 0 位置 */ 164 | .ui-tips-x[data-align="7-5"] { 165 | margin-top: 6px; 166 | } 167 | 168 | .ui-tips-x[data-align="7-5"]::after { 169 | clip-path: polygon( 170 | calc(50% - var(--ui-tips-triangle-size)) calc(0% + (var(--ui-tips-triangle-size) + 1px)), 171 | calc(50% + var(--ui-tips-triangle-size)) calc(0% + (var(--ui-tips-triangle-size) + 1px)), 172 | 50% 0% 173 | ); 174 | } 175 | 176 | /* 悬浮在目标左上,箭头在框体 100% -16px, 100% 位置 */ 177 | .ui-tips-x[data-align="2-3"] { 178 | margin-left: 12px; 179 | margin-top: -6px; 180 | } 181 | 182 | .ui-tips-x[data-align="2-3"]::after { 183 | clip-path: polygon( 184 | calc(100% - 16px) calc(100% - (var(--ui-tips-triangle-size) + 1px)), 185 | calc(100% - (16px + var(--ui-tips-triangle-size)*2)) calc(100% - (var(--ui-tips-triangle-size) + 1px)), 186 | calc(100% - (16px + var(--ui-tips-triangle-size))) 100% 187 | ); 188 | } 189 | 190 | /* 悬浮在目标右上,箭头在框体 16px, 100% 位置 */ 191 | .ui-tips-x[data-align="1-4"] { 192 | margin-left: -12px; 193 | margin-top: -6px; 194 | } 195 | .ui-tips-x[data-align="1-4"]::after { 196 | clip-path: polygon( 197 | 16px calc(100% - (var(--ui-tips-triangle-size) + 1px)), 198 | calc(16px + var(--ui-tips-triangle-size)*2) calc(100% - (var(--ui-tips-triangle-size) + 1px)), 199 | calc(16px + var(--ui-tips-triangle-size)) 100% 200 | ); 201 | } 202 | 203 | /* 悬浮在目标左侧,箭头在框体 100%, 50% 位置 */ 204 | .ui-tips-x[data-align="8-6"] { 205 | margin-left: -6px; 206 | margin-top: 0; 207 | } 208 | 209 | .ui-tips-x[data-align="8-6"]::after { 210 | clip-path: polygon( 211 | calc(100% - (var(--ui-tips-triangle-size) + 1px)) calc(50% - var(--ui-tips-triangle-size)), 212 | calc(100% - (var(--ui-tips-triangle-size) + 1px)) calc(50% + var(--ui-tips-triangle-size)), 213 | 100% 50% 214 | ); 215 | } 216 | /* 悬浮在目标右侧,箭头在框体 0%, 50% 位置 */ 217 | .ui-tips-x[data-align="6-8"] { 218 | margin-left: 6px; 219 | margin-top: 0; 220 | } 221 | 222 | .ui-tips-x[data-align="6-8"]::after { 223 | clip-path: polygon( 224 | calc(0% + (var(--ui-tips-triangle-size) + 1px)) calc(50% - var(--ui-tips-triangle-size)), 225 | calc(0% + (var(--ui-tips-triangle-size) + 1px)) calc(50% + var(--ui-tips-triangle-size)), 226 | 0% 50% 227 | ); 228 | } 229 | 230 | /* 悬浮在目标左下侧,箭头在框体 100% - 16px, 0% 位置 */ 231 | .ui-tips-x[data-align="3-2"] { 232 | margin-left: 12px; 233 | margin-top: 6px; 234 | } 235 | 236 | .ui-tips-x[data-align="3-2"]::after { 237 | clip-path: polygon( 238 | calc(100% - 16px) calc(0% + (var(--ui-tips-triangle-size) + 1px)), 239 | calc(100% - (16px + var(--ui-tips-triangle-size)*2)) calc(0% + (var(--ui-tips-triangle-size) + 1px)), 240 | calc(100% - (16px + var(--ui-tips-triangle-size))) 0% 241 | ); 242 | } 243 | 244 | /* 悬浮在目标右下侧,箭头在框体 16px, 0% 位置*/ 245 | .ui-tips-x[data-align="4-1"] { 246 | margin-left: -12px; 247 | margin-top: 6px; 248 | } 249 | 250 | .ui-tips-x[data-align="4-1"]::after { 251 | clip-path: polygon( 252 | 16px calc(0% + (var(--ui-tips-triangle-size) + 1px)), 253 | calc(16px + var(--ui-tips-triangle-size)*2) calc(0% + (var(--ui-tips-triangle-size) + 1px)), 254 | calc(16px + var(--ui-tips-triangle-size)) 0% 255 | ); 256 | } 257 | 258 | 259 | /* 错误提示的tips效果 */ 260 | .ui-tips-error:not(.none) { 261 | animation: fadeIn var(--ui-animate-time, .2s), fallDown var(--ui-animate-time, .2s); 262 | } 263 | 264 | .ui-tips-error.ui-tips-x::before, 265 | .ui-tips-error.ui-tips-x::after { 266 | background: var(--ui-tips-error-bg); 267 | /*background-color: var(--ui-red, #eb4646);*/ 268 | } 269 | 270 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/css/common/variables.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /** 3 | * 4 | * @variables.css 5 | * @author zhangxinxu 6 | * @edited yangfan 7 | * @create 20-03-17 8 | **/ 9 | 10 | :root { 11 | /* 基础颜色变量 */ 12 | --ui-blue: #2a80eb; 13 | --ui-dark-blue: #0057c3; 14 | --ui-dark: #4c5161; 15 | --ui-gray: #a2a9b6; 16 | --ui-dark-gray: #b6bbc6; 17 | --ui-light: #f7f9fa; 18 | --ui-white: #ffffff; 19 | --ui-green: #1cad70; 20 | --ui-orange: #f59b00; 21 | --ui-red: #eb4646; 22 | /* hover的颜色 */ 23 | --ui-list-hover: #f0f7ff; 24 | /* selected的颜色 */ 25 | --ui-list-selected: #e0f0ff; 26 | /* disabled禁用色 */ 27 | --ui-disabled: #ccd0d7; 28 | /* 边框颜色 */ 29 | --ui-border: #d0d0d5; 30 | /* 深一点的边框颜色 */ 31 | --ui-dark-border: #ababaf; 32 | /* 浅一点的边框颜色 */ 33 | --ui-light-border: #ededef; 34 | /* 透明度 */ 35 | --ui-opacity: .4; 36 | /* 圆角变量 */ 37 | --ui-radius: 4px; 38 | /* 基础字号 */ 39 | --ui-font: 14px; 40 | /* 动画时间 */ 41 | --ui-animate-time: .2s; 42 | /* 基本尺寸单元 */ 43 | --ui-line-height: 20px; 44 | --ui-component-height: 40px; 45 | } 46 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/index.js: -------------------------------------------------------------------------------- 1 | import './js/common/all' 2 | import './css/common/ui.css' 3 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/js/common/comp/Form.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @Form.js 3 | * @author zhangxinxu 4 | * @version 5 | * @created 16-03-01 6 | * @edited 19-12-02 ES5原生语法支持 7 | */ 8 | /** 9 | * 表单解决方案组件 10 | * @使用示例 11 | *
12 | */ 13 | 14 | import LightTip from '../ui/LightTip.js' 15 | import Validate from '../ui/Validate.js' 16 | import '../ui/Loading.js' 17 | 18 | // 表单 19 | class Form extends HTMLFormElement { 20 | constructor() { 21 | super() 22 | 23 | this.element = this.element || {} 24 | this.params = 25 | this.params || 26 | { 27 | // 验证成功之后,请求发送前的条件约束 28 | // avoidSend: function () {} 29 | } 30 | // 回调方法们 31 | this.callback = this.callback || {} 32 | 33 | Object.defineProperty(this.params, 'validate', { 34 | set(value) { 35 | if (this.validate) { 36 | this.validate.setCustomValidity(value) 37 | } 38 | } 39 | }) 40 | 41 | return this 42 | } 43 | 44 | /** 45 | * 表单提交的处理 46 | * @return {[type]} [description] 47 | */ 48 | ajax() { 49 | // 回调 50 | // optionCallback可以是对象也可以直接是成功回调 51 | /* 52 | optionCallback = { 53 | success: function () {}, 54 | error: function () {}, 55 | complete: function () {} 56 | }; 57 | */ 58 | let optionCallback = this.callback 59 | optionCallback = optionCallback || function () {} 60 | if (typeof optionCallback == 'function') { 61 | optionCallback = { 62 | success: optionCallback 63 | } 64 | } 65 | // 元素 66 | let eleButton = null 67 | let eleSubmit = this.element.submit 68 | 69 | // 我们肉眼所见的按钮,进行一些状态控制 70 | eleButton = eleSubmit.id && document.querySelector('label[for=' + eleSubmit.id + ']') 71 | if (!eleButton) { 72 | eleButton = eleSubmit 73 | } 74 | this.element.button = eleButton 75 | 76 | // 请求地址 77 | let strUrl = this.action.split('#')[0] || location.href.split('#')[0] 78 | // 请求类型 79 | let strMethod = this.method || 'POST' 80 | let strEnctype = this.enctype 81 | 82 | // 提交数据 83 | // 1. 菊花转起来 84 | eleButton.loading = true 85 | // 2. 提交按钮禁用 86 | eleSubmit.setAttribute('disabled', 'disabled') 87 | 88 | // 3. 数据 89 | let objFormData = new FormData(this) 90 | // 支持外部传入额外的请求参数 91 | if (this.params.data) { 92 | Object.keys(this.params.data).forEach((key) => { 93 | objFormData.append(key, this.params.data[key]) 94 | }) 95 | } 96 | 97 | // 请求类型不同,数据地址也不一样 98 | let strSearchParams = new URLSearchParams(objFormData).toString() 99 | 100 | if (strMethod.toLowerCase() == 'get') { 101 | if (strUrl.split('?').length > 1) { 102 | strUrl = strUrl + '&' + strSearchParams 103 | } else { 104 | strUrl = strUrl + '?' + strSearchParams 105 | } 106 | } 107 | 108 | // 4. 请求走起来 109 | let xhr = new XMLHttpRequest() 110 | xhr.open(strMethod, strUrl) 111 | 112 | if (strEnctype) { 113 | xhr.setRequestHeader('Content-Type', strEnctype) 114 | } 115 | 116 | if (optionCallback.beforeSend) { 117 | optionCallback.beforeSend.call(this, xhr, objFormData) 118 | } 119 | 120 | // 请求结束 121 | xhr.onload = () => { 122 | let json = {} 123 | 124 | try { 125 | json = JSON.parse(xhr.responseText) 126 | } catch (event) { 127 | new LightTip('返回数据解析出错。', 'error') 128 | // 回调 129 | if (optionCallback.error) { 130 | optionCallback.error.call(this, event) 131 | } 132 | 133 | // 触发出错自定义事件 134 | this.dispatchEvent( 135 | new CustomEvent('error', { 136 | detail: { 137 | data: { 138 | code: -1, 139 | msg: '解析出错' 140 | } 141 | } 142 | }) 143 | ) 144 | 145 | return 146 | } 147 | 148 | if (json && (json.code === 0 || json.error === 0)) { 149 | // 成功回调 150 | if (optionCallback.success) { 151 | optionCallback.success.call(this, json) 152 | } else { 153 | // 如果没有成功回调,组件自己提示成功 154 | new LightTip(json.msg || '操作成功。', 'success') 155 | // 表单重置 156 | this.reset() 157 | } 158 | 159 | // 支持绑定success事件 160 | this.dispatchEvent( 161 | new CustomEvent('success', { 162 | detail: { 163 | data: json 164 | } 165 | }) 166 | ) 167 | } else { 168 | new LightTip((json && json.msg) || '返回数据格式不符合要求。', 'error') 169 | 170 | // 失败回调 171 | if (optionCallback.error) { 172 | optionCallback.error.call(this, json) 173 | } 174 | 175 | // 触发出错自定义事件 176 | this.dispatchEvent( 177 | new CustomEvent('error', { 178 | detail: { 179 | data: json 180 | } 181 | }) 182 | ) 183 | } 184 | } 185 | 186 | // 请求错误 187 | xhr.onerror = () => { 188 | new LightTip('网络异常,刚才的操作没有成功,您可以稍后重试。', 'error') 189 | // 回调 190 | if (optionCallback.error) { 191 | optionCallback.error.apply(this, arguments) 192 | } 193 | // 触发出错自定义事件 194 | this.dispatchEvent( 195 | new CustomEvent('error', { 196 | detail: { 197 | code: -1, 198 | msg: '网络异常' 199 | } 200 | }) 201 | ) 202 | } 203 | 204 | // 请求结束,无论成功还是失败 205 | xhr.onloadend = () => { 206 | // 菊花关闭 207 | eleButton.loading = false 208 | // 表单恢复提交 209 | eleSubmit.removeAttribute('disabled') 210 | // 回调 211 | if (optionCallback.complete) { 212 | optionCallback.complete.apply(this, arguments) 213 | } 214 | 215 | // 支持绑定complete事件 216 | this.dispatchEvent(new CustomEvent('complete')) 217 | } 218 | 219 | if (strEnctype && strEnctype.toLowerCase() === 'application/x-www-form-urlencoded') { 220 | xhr.send(strSearchParams) 221 | } else { 222 | xhr.send(objFormData) 223 | } 224 | } 225 | 226 | connectedCallback() { 227 | // 表单提交按钮元素的获取 228 | let eleSubmit = 229 | [...this.elements].filter(function (control) { 230 | return control.type && /^(?:submit|image)$/i.test(control.type) 231 | })[0] || this.querySelector('button:nth-last-of-type(1)') 232 | 233 | if (!eleSubmit) { 234 | eleSubmit = (() => { 235 | let ele = document.createElement('button') 236 | ele.type = 'submit' 237 | ele.setAttribute('hidden', '') 238 | this.appendChild(ele) 239 | 240 | return ele 241 | })() 242 | } 243 | 244 | this.element.submit = eleSubmit 245 | 246 | // 绑定表单验证 247 | this.validate = new Validate( 248 | this, 249 | () => { 250 | let funAvoidSend = this.params.avoidSend || this.callback.avoidSend 251 | // 验证成功之后 252 | if (!funAvoidSend || !funAvoidSend(this)) { 253 | this.ajax() 254 | } 255 | }, 256 | this.params.validate || {} 257 | ) 258 | 259 | // 全局事件 260 | this.dispatchEvent( 261 | new CustomEvent('connected', { 262 | detail: { 263 | type: 'ui-form' 264 | } 265 | }) 266 | ) 267 | 268 | this.isConnectedCallback = true 269 | 270 | this.dispatchEvent(new CustomEvent('DOMContentLoaded')) 271 | } 272 | } 273 | 274 | if (!customElements.get('ui-form')) { 275 | customElements.define('ui-form', Form, { 276 | extends: 'form' 277 | }) 278 | } 279 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/js/common/safari-polyfill.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | class AnyClass extends HTMLBRElement { 3 | constructor () { 4 | super(); 5 | 6 | this.someMethod = true; 7 | } 8 | } 9 | 10 | if (!customElements.get('any-class')) { 11 | customElements.define('any-class', AnyClass, { 12 | extends: 'br' 13 | }); 14 | } 15 | 16 | // support build-in custom element 17 | // so return 18 | const isSupportBuildIn = document.createElement('br', { 19 | is: 'any-class' 20 | }).someMethod; 21 | 22 | // https://github.com/WebReflection/custom-elements-builtin 23 | (function () { 24 | 'use strict'; 25 | 26 | if (isSupportBuildIn) { 27 | return; 28 | } 29 | 30 | var attributesObserver = (whenDefined, MutationObserver) => { 31 | 32 | const attributeChanged = records => { 33 | for (let i = 0, {length} = records; i < length; i++) 34 | dispatch(records[i]); 35 | }; 36 | 37 | const dispatch = ({target, attributeName, oldValue}) => { 38 | target.attributeChangedCallback( 39 | attributeName, 40 | oldValue, 41 | target.getAttribute(attributeName) 42 | ); 43 | }; 44 | 45 | return (target, is) => { 46 | const {observedAttributes: attributeFilter} = target.constructor; 47 | if (attributeFilter) { 48 | whenDefined(is).then(() => { 49 | new MutationObserver(attributeChanged).observe(target, { 50 | attributes: true, 51 | attributeOldValue: true, 52 | attributeFilter 53 | }); 54 | for (let i = 0, {length} = attributeFilter; i < length; i++) { 55 | if (target.hasAttribute(attributeFilter[i])) 56 | dispatch({target, attributeName: attributeFilter[i], oldValue: null}); 57 | } 58 | }); 59 | } 60 | return target; 61 | }; 62 | }; 63 | 64 | const {keys} = Object; 65 | 66 | const expando = element => { 67 | const key = keys(element); 68 | const value = []; 69 | const {length} = key; 70 | for (let i = 0; i < length; i++) { 71 | value[i] = element[key[i]]; 72 | delete element[key[i]]; 73 | } 74 | return () => { 75 | for (let i = 0; i < length; i++) 76 | element[key[i]] = value[i]; 77 | }; 78 | }; 79 | 80 | const {document, MutationObserver, Set, WeakMap} = self; 81 | 82 | const elements = element => 'querySelectorAll' in element; 83 | const {filter} = []; 84 | 85 | var qsaObserver = options => { 86 | const live = new WeakMap; 87 | const callback = records => { 88 | const {query} = options; 89 | if (query.length) { 90 | for (let i = 0, {length} = records; i < length; i++) { 91 | loop(filter.call(records[i].addedNodes, elements), true, query); 92 | loop(filter.call(records[i].removedNodes, elements), false, query); 93 | } 94 | } 95 | }; 96 | const drop = elements => { 97 | for (let i = 0, {length} = elements; i < length; i++) 98 | live.delete(elements[i]); 99 | }; 100 | const flush = () => { 101 | callback(observer.takeRecords()); 102 | }; 103 | const loop = (elements, connected, query, set = new Set) => { 104 | for (let selectors, element, i = 0, {length} = elements; i < length; i++) { 105 | // guard against repeated elements within nested querySelectorAll results 106 | if (!set.has(element = elements[i])) { 107 | set.add(element); 108 | if (connected) { 109 | for (let q, m = matches(element), i = 0, {length} = query; i < length; i++) { 110 | if (m.call(element, q = query[i])) { 111 | if (!live.has(element)) 112 | live.set(element, new Set); 113 | selectors = live.get(element); 114 | // guard against selectors that were handled already 115 | if (!selectors.has(q)) { 116 | selectors.add(q); 117 | options.handle(element, connected, q); 118 | } 119 | } 120 | } 121 | } 122 | // guard against elements that never became live 123 | else if (live.has(element)) { 124 | selectors = live.get(element); 125 | live.delete(element); 126 | selectors.forEach(q => { 127 | options.handle(element, connected, q); 128 | }); 129 | } 130 | loop(querySelectorAll(element), connected, query, set); 131 | } 132 | } 133 | }; 134 | const matches = element => ( 135 | element.matches || 136 | element.webkitMatchesSelector || 137 | element.msMatchesSelector 138 | ); 139 | const parse = (elements, connected = true) => { 140 | loop(elements, connected, options.query); 141 | }; 142 | const querySelectorAll = root => query.length ? 143 | root.querySelectorAll(query) : query; 144 | const observer = new MutationObserver(callback); 145 | const root = options.root || document; 146 | const {query} = options; 147 | observer.observe(root, {childList: true, subtree: true}); 148 | parse(querySelectorAll(root)); 149 | return {drop, flush, observer, parse}; 150 | }; 151 | 152 | const { 153 | customElements, document: document$1, 154 | Element, MutationObserver: MutationObserver$1, Object: Object$1, Promise, 155 | Map, Set: Set$1, WeakMap: WeakMap$1, Reflect 156 | } = self; 157 | 158 | const {attachShadow} = Element.prototype; 159 | const {createElement} = document$1; 160 | const {define, get} = customElements; 161 | const {construct} = Reflect || {construct(HTMLElement) { 162 | return HTMLElement.call(this); 163 | }}; 164 | 165 | const {defineProperty, keys: keys$1, getOwnPropertyNames, setPrototypeOf} = Object$1; 166 | 167 | const shadowRoots = new WeakMap$1; 168 | const shadows = new Set$1; 169 | 170 | const classes = new Map; 171 | const defined = new Map; 172 | const prototypes = new Map; 173 | const registry = new Map; 174 | 175 | const shadowed = []; 176 | const query = []; 177 | 178 | const getCE = is => registry.get(is) || get.call(customElements, is); 179 | 180 | const handle = (element, connected, selector) => { 181 | const proto = prototypes.get(selector); 182 | if (connected && !proto.isPrototypeOf(element)) { 183 | const redefine = expando(element); 184 | override = setPrototypeOf(element, proto); 185 | try { new proto.constructor; } 186 | finally { 187 | override = null; 188 | redefine(); 189 | } 190 | } 191 | const method = `${connected ? '' : 'dis'}connectedCallback`; 192 | if (method in proto) 193 | element[method](); 194 | }; 195 | 196 | const {parse} = qsaObserver({query, handle}); 197 | 198 | const {parse: parseShadowed} = qsaObserver({ 199 | query: shadowed, 200 | handle(element, connected) { 201 | if (shadowRoots.has(element)) { 202 | if (connected) 203 | shadows.add(element); 204 | else 205 | shadows.delete(element); 206 | if (query.length) 207 | parseShadow.call(query, element); 208 | } 209 | } 210 | }); 211 | 212 | const whenDefined = name => { 213 | if (!defined.has(name)) { 214 | let _, $ = new Promise($ => { _ = $; }); 215 | defined.set(name, {$, _}); 216 | } 217 | return defined.get(name).$; 218 | }; 219 | 220 | const augment = attributesObserver(whenDefined, MutationObserver$1); 221 | 222 | let override = null; 223 | 224 | getOwnPropertyNames(self) 225 | .filter(k => /^HTML/.test(k)) 226 | .forEach(k => { 227 | const HTMLElement = self[k]; 228 | function HTMLBuiltIn() { 229 | const {constructor} = this; 230 | if (!classes.has(constructor)) 231 | throw new TypeError('Illegal constructor'); 232 | const {is, tag} = classes.get(constructor); 233 | if (is) { 234 | if (override) 235 | return augment(override, is); 236 | const element = createElement.call(document$1, tag); 237 | element.setAttribute('is', is); 238 | return augment(setPrototypeOf(element, constructor.prototype), is); 239 | } 240 | else 241 | return construct.call(this, HTMLElement, [], constructor); 242 | } 243 | setPrototypeOf(HTMLBuiltIn, HTMLElement); 244 | defineProperty( 245 | HTMLBuiltIn.prototype = HTMLElement.prototype, 246 | 'constructor', 247 | {value: HTMLBuiltIn} 248 | ); 249 | defineProperty(self, k, {value: HTMLBuiltIn}); 250 | }); 251 | 252 | defineProperty(document$1, 'createElement', { 253 | configurable: true, 254 | value(name, options) { 255 | const is = options && options.is; 256 | if (is) { 257 | const Class = registry.get(is); 258 | if (Class && classes.get(Class).tag === name) 259 | return new Class; 260 | } 261 | const element = createElement.call(document$1, name); 262 | if (is) 263 | element.setAttribute('is', is); 264 | return element; 265 | } 266 | }); 267 | 268 | if (attachShadow) 269 | defineProperty(Element.prototype, 'attachShadow', { 270 | configurable: true, 271 | value() { 272 | const root = attachShadow.apply(this, arguments); 273 | const {parse} = qsaObserver({query, root, handle}); 274 | shadowRoots.set(this, {root, parse}); 275 | return root; 276 | } 277 | }); 278 | 279 | defineProperty(customElements, 'get', { 280 | configurable: true, 281 | value: getCE 282 | }); 283 | 284 | defineProperty(customElements, 'whenDefined', { 285 | configurable: true, 286 | value: whenDefined 287 | }); 288 | 289 | defineProperty(customElements, 'define', { 290 | configurable: true, 291 | value(is, Class, options) { 292 | if (getCE(is)) 293 | throw new Error(`'${is}' has already been defined as a custom element`); 294 | let selector; 295 | const tag = options && options.extends; 296 | classes.set(Class, tag ? {is, tag} : {is: '', tag: is}); 297 | if (tag) { 298 | selector = `${tag}[is="${is}"]`; 299 | prototypes.set(selector, Class.prototype); 300 | registry.set(is, Class); 301 | query.push(selector); 302 | } 303 | else { 304 | define.apply(customElements, arguments); 305 | shadowed.push(selector = is); 306 | } 307 | whenDefined(is).then(() => { 308 | if (tag) { 309 | parse(document$1.querySelectorAll(selector)); 310 | shadows.forEach(parseShadow, [selector]); 311 | } 312 | else 313 | parseShadowed(document$1.querySelectorAll(selector)); 314 | }); 315 | defined.get(is)._(Class); 316 | } 317 | }); 318 | 319 | function parseShadow(element) { 320 | const {parse, root} = shadowRoots.get(element); 321 | parse(root.querySelectorAll(this), element.isConnected); 322 | } 323 | 324 | }()); 325 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/js/common/ui/ErrorTip.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ErrorTip.js 3 | * @author zhangxinxu 4 | * @version 5 | * @created: 15-07-01 6 | * @edited: 20-07-07 edit by peter.qiyuanhao 7 | */ 8 | 9 | import './Follow.js' 10 | 11 | class ErrorTip { 12 | static allHide(exclude) { 13 | ErrorTip.collectionErrorTip.forEach((obj) => { 14 | if (exclude != obj) { 15 | obj.hide() 16 | } 17 | }) 18 | } 19 | 20 | constructor(element, content, options) { 21 | const defaults = { 22 | unique: true, 23 | onShow: () => {}, 24 | onHide: () => {} 25 | } 26 | 27 | // 参数 28 | const objParams = { 29 | ...defaults, 30 | ...options 31 | } 32 | 33 | // 显示字符内容的处理 34 | let strContent = content 35 | 36 | // 支持Function类型 37 | if (typeof strContent == 'function') { 38 | strContent = strContent() 39 | } 40 | if (typeof strContent != 'string') { 41 | return this 42 | } 43 | 44 | // 一些元素 45 | const eleTrigger = element 46 | 47 | let objErrorTip = eleTrigger.data && eleTrigger.data.errorTip 48 | // 如果当前元素之前有过出错提示实例,则重复使用,无需再构造 49 | if (objErrorTip) { 50 | objErrorTip.content = strContent 51 | objErrorTip.callback = { 52 | show: objParams.onShow, 53 | hide: objParams.onHide 54 | } 55 | objErrorTip.element.tips.trigger = eleTrigger 56 | objErrorTip.show() 57 | 58 | return this 59 | } 60 | 61 | // eleTips指的是红色出错提示元素 62 | let eleTips 63 | // 为了单出错提示模式下,所有的红色都能取消的处理 64 | // 所有提示过的实例对象合在一起隐藏 65 | let collectionErrorTip = ErrorTip.collectionErrorTip 66 | // 全局的出错实例 67 | const objUniqueErrorTip = collectionErrorTip[collectionErrorTip.length - 1] 68 | 69 | // 如果是唯一模式,则看看全局出错的对象 70 | if (objParams.unique == true && objUniqueErrorTip) { 71 | // window.errorTip存储的是唯一的红色提示元素 72 | // 改变存储的触发元素 73 | eleTips = objUniqueErrorTip.element.tips 74 | } else if (objParams.unique == false && eleTrigger.data && eleTrigger.data.errorTip) { 75 | eleTips = eleTrigger.data.errorTip.element.tips 76 | } else { 77 | eleTips = this.create() 78 | } 79 | 80 | // 如果是唯一模式,全局存储 81 | if (objParams.unique == true && collectionErrorTip.includes(this) == false) { 82 | collectionErrorTip.push(this) 83 | } 84 | 85 | // 更新提示元素对应的触发元素 86 | eleTips.trigger = eleTrigger 87 | 88 | this.element = { 89 | trigger: eleTrigger, 90 | tips: eleTips 91 | } 92 | this.callback = { 93 | show: objParams.onShow, 94 | hide: objParams.onHide 95 | } 96 | 97 | this.params = { 98 | unique: objParams.unique 99 | } 100 | 101 | // 暴露在外 102 | this.content = strContent 103 | 104 | // 在DOM对象上暴露对应的实例对象 105 | if (!eleTrigger.data) { 106 | eleTrigger.data = {} 107 | } 108 | eleTrigger.data.errorTip = this 109 | 110 | // 显示 111 | this.show() 112 | } 113 | 114 | /** 115 | * 红色出错提示元素的创建 116 | */ 117 | create() { 118 | // 首次 119 | let eleTips = document.createElement('div') 120 | eleTips.className = 'ui-tips-x ui-tips-error' 121 | document.body.appendChild(eleTips) 122 | 123 | // 事件 124 | this.events(eleTips) 125 | 126 | return eleTips 127 | } 128 | 129 | /** 130 | * 无论是键盘操作,还是按下,都隐藏出错提示 131 | * @param {Element} eleTips 表示创建的红色提示元素 132 | */ 133 | events(eleTips) { 134 | // 任何键盘操作,点击,或者拉伸都会隐藏错误提示框 135 | document.addEventListener('keydown', (event) => { 136 | // ctrl/shift键不隐藏 137 | if (!/Control|Shift/i.test(event.code)) { 138 | ErrorTip.allHide(this) 139 | this.hide() 140 | } 141 | }) 142 | 143 | document.addEventListener('mousedown', (event) => { 144 | const eleActiveElement = document.activeElement 145 | 146 | const eleActiveTrigger = eleTips.trigger 147 | const eleTarget = event.target 148 | 149 | // 如果点击的就是触发的元素,且处于激活态,则忽略 150 | if ( 151 | eleActiveElement && 152 | eleActiveTrigger && 153 | eleActiveElement == eleTarget && 154 | eleActiveElement == eleActiveTrigger && 155 | // 这个与Datalist.js关联 156 | !eleActiveTrigger.getAttribute('data-focus') 157 | ) { 158 | return 159 | } 160 | 161 | ErrorTip.allHide(this) 162 | this.hide() 163 | }) 164 | 165 | window.addEventListener('resize', () => { 166 | ErrorTip.allHide(this) 167 | this.hide() 168 | }) 169 | } 170 | 171 | /** 172 | * 错误tips提示显示方法 173 | */ 174 | show() { 175 | const objElement = this.element 176 | // 触发元素和提示元素 177 | const eleTips = objElement.tips 178 | const eleTrigger = objElement.trigger 179 | 180 | // 修改content内容 181 | eleTips.innerHTML = this.content 182 | 183 | // 提示元素显示 184 | eleTips.style.display = '' 185 | 186 | // 定位 187 | eleTrigger.follow(eleTips, { 188 | // trigger-target 189 | position: '5-7', 190 | // 边界溢出不自动修正 191 | edgeAdjust: false 192 | }) 193 | 194 | // aria无障碍访问增强 195 | eleTrigger.setAttribute('aria-label', '错误提示:' + this.content) 196 | // 两个重要标志类名 197 | eleTrigger.toggleAttribute('is-error', true) 198 | eleTrigger.classList.add('valided') 199 | 200 | this.display = true 201 | 202 | // 显示的回调 203 | if (this.callback && this.callback.show) { 204 | this.callback.show.call(this, eleTrigger, eleTips) 205 | } 206 | 207 | // 触发自定义的 show 事件 208 | eleTrigger.dispatchEvent( 209 | new CustomEvent('show', { 210 | detail: { 211 | type: 'ui-errortip', 212 | content: this.content 213 | } 214 | }) 215 | ) 216 | } 217 | 218 | /** 219 | * 错误tips提示隐藏方法 220 | * @return {Object} 返回当前实例对象 221 | */ 222 | hide() { 223 | // 避免重复隐藏执行 224 | if (!this.display) { 225 | return 226 | } 227 | 228 | const eleTips = this.element.tips 229 | const eleTrigger = this.element.trigger 230 | 231 | eleTrigger.removeAttribute('aria-label') 232 | eleTrigger.removeAttribute('is-error') 233 | 234 | eleTips.style.display = 'none' 235 | 236 | this.display = false 237 | 238 | // 隐藏的回调 239 | if (this.callback && this.callback.hide) { 240 | this.callback.hide.call(this, eleTrigger, eleTips) 241 | } 242 | 243 | // 触发自定义的 hide 事件 244 | eleTrigger.dispatchEvent( 245 | new CustomEvent('hide', { 246 | detail: { 247 | type: 'ui-errortip' 248 | } 249 | }) 250 | ) 251 | } 252 | } 253 | 254 | ErrorTip.collectionErrorTip = [] 255 | 256 | window.ErrorTip = ErrorTip 257 | 258 | /** 259 | * 给任意 dom 注入 errorTip 方法 260 | * @param content String 261 | * @param options { unique, onShow, onHide } 262 | */ 263 | HTMLElement.prototype.errorTip = function (content, options = {}) { 264 | new ErrorTip(this, content, options) 265 | 266 | return this 267 | } 268 | 269 | export default ErrorTip 270 | -------------------------------------------------------------------------------- /src/libs/lulu-ui/js/common/ui/Keyboard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @Keyboard.js 3 | * @author zhangxinxu 4 | * @version 5 | * Created: 17-06-13 6 | */ 7 | ;(function (doc, win) { 8 | if (win.isKeyEventBind || !doc.addEventListener) { 9 | return {} 10 | } 11 | 12 | /* 13 | ** HTML accesskey辅助增强脚本 14 | ** 作用包括: 15 | ** 1. 统一IE浏览器和其它浏览器的快捷访问行为; 16 | ** 2. 增加单独accesskey属性值对应按键按下的focus行为; 17 | ** 3. windows系统下Firefox也支持 Alt + key的访问能力; 18 | ** 4. 增加shift + '?'(keyCode=191)键的提示行为支持; 19 | */ 20 | 21 | // 操作系统和浏览器设备检测 22 | var ua = navigator.platform || navigator.userAgent 23 | 24 | var system = 'windows' 25 | 26 | if (/mac/i.test(ua)) { 27 | system = 'mac' 28 | } 29 | 30 | // 浏览器判断 31 | var browser = 'chrome' 32 | if (typeof doc.mozFullScreen != 'undefined') { 33 | browser = 'moz' 34 | } else if (typeof doc.msHidden != 'undefined' || typeof doc.hidden == 'undefined') { 35 | browser = 'ie' 36 | } 37 | 38 | // 快捷键组合 39 | var keyPrefix = { 40 | windows: { 41 | ctrlKey: false, 42 | altKey: true, 43 | shiftKey: false 44 | }, 45 | mac: { 46 | ctrlKey: true, 47 | altKey: true, 48 | shiftKey: false 49 | } 50 | }[system] 51 | 52 | // 获取字符Unicode值方法 53 | var U = function (a, b) { 54 | if (!a) { 55 | return '' 56 | } 57 | b = b || 'x' 58 | var c = '' 59 | var d = 0 60 | var e 61 | 62 | for (d; d < a.length; d += 1) 63 | a.charCodeAt(d) >= 55296 && a.charCodeAt(d) <= 56319 64 | ? ((e = (65536 + 1024 * (Number(a.charCodeAt(d)) - 55296) + Number(a.charCodeAt(d + 1)) - 56320).toString(16)), (d += 1)) 65 | : (e = a.charCodeAt(d).toString(16)), 66 | (c += b + e) 67 | 68 | return c.substr(b.length) 69 | } 70 | 71 | // 提示当前元素快捷键的方法 72 | var timerTips = null 73 | var tips = function (arrEles) { 74 | // 已经显示中,忽略 75 | if (doc.hasTipsShow) { 76 | return 77 | } 78 | // 页面的滚动高度 79 | var scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop 80 | var scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft 81 | 82 | // 遍历创建提示元素 83 | arrEles.forEach(function (ele) { 84 | // 如果元素隐藏,也忽略 85 | if (ele.clientHeight * ele.clientWidth == 0) { 86 | return 87 | } 88 | 89 | var accesskey = ele.getAttribute('accesskey') 90 | var arrAccesskey = [] 91 | for (var key in keyPrefix) { 92 | if (keyPrefix[key]) { 93 | arrAccesskey.push(key) 94 | } 95 | } 96 | arrAccesskey.push(accesskey) 97 | 98 | // 当前元素相对于文档的偏移 99 | var bounding = ele.getBoundingClientRect() 100 | 101 | // 创建tips提示元素 102 | var div = doc.createElement('div') 103 | div.className = 'ui-kbd-tips AK_Tips' 104 | div.setAttribute('style', 'top:' + (bounding.top + scrollTop) + 'px;left:' + (bounding.left + scrollLeft) + 'px;') 105 | div.innerHTML = arrAccesskey 106 | .map(function (key) { 107 | return '' + key.replace('Key', '') + '' 108 | }) 109 | .join('+') 110 | 111 | doc.body.appendChild(div) 112 | 113 | div.fromTarget = ele 114 | }) 115 | 116 | // 标记,避免重复生成 117 | doc.hasTipsShow = true 118 | 119 | // 一段时间隐藏 120 | timerTips = setTimeout(function () { 121 | removeTips() 122 | }, 3000) 123 | } 124 | // 隐藏tips 125 | var removeTips = function () { 126 | clearTimeout(timerTips) 127 | // 移除所有的快捷键提示 128 | var elesTips = doc.querySelectorAll('.AK_Tips') 129 | ;[].slice.call(elesTips).forEach(function (ele) { 130 | if (ele.fromTarget) { 131 | ele.fromTarget.hasTipsShow = null 132 | } 133 | doc.body.removeChild(ele) 134 | }) 135 | doc.hasTipsShow = null 136 | } 137 | 138 | // accesskey键盘处理 139 | doc.addEventListener('keydown', function (event) { 140 | // 当前元素是否是可输入的input或者textarea 141 | var isTargetInputable = false 142 | var eleTarget = event.target || doc.activeElement 143 | var tagName = eleTarget.tagName.toLowerCase() 144 | if (tagName == 'textarea' || (tagName == 'input' && /checkbox|radio|select|file|button|image|hidden/i.test(eleTarget.type) == false)) { 145 | isTargetInputable = true 146 | } 147 | 148 | // 遍历所有设置了accesskey的符合HTML4.0.1规范的元素 149 | // 包括, ,