├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md └── images │ ├── alipay.jpg │ └── wcpay.jpg ├── .gitignore ├── .scripts ├── _travis-fold.sh └── map_sources.js ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── LICENSE ├── README.md ├── angular.json ├── browserslist ├── license-banner.txt ├── package-lock.json ├── package.json ├── publish.sh ├── src ├── app │ ├── app.environment.ts │ ├── app.module.ts │ ├── core │ │ ├── core.module.ts │ │ ├── page.ts │ │ ├── result.error.ts │ │ ├── result.ts │ │ └── rxjs │ │ │ └── operators │ │ │ └── to-result.ts │ ├── shared │ │ ├── abstract.service.ts │ │ ├── directive │ │ │ ├── phone.validator.directive.ts │ │ │ ├── range.validator.directive.ts │ │ │ └── url.validator.directive.ts │ │ ├── pipe │ │ │ ├── array.filter.pipe.ts │ │ │ ├── filesize.pipe.ts │ │ │ ├── format.date.pipe.ts │ │ │ ├── intl.ts │ │ │ ├── invalid_pipe_argument_error.ts │ │ │ └── safe.html.pipe.ts │ │ ├── shared.module.ts │ │ └── utils │ │ │ ├── file.utils.ts │ │ │ ├── lang.ts │ │ │ └── string.utils.ts │ └── weui │ │ ├── css │ │ ├── README.md │ │ ├── angular-weui.full.min.css │ │ └── angular-weui.min.css │ │ ├── index.ts │ │ ├── package.json │ │ ├── public_api.ts │ │ ├── rollup.config.js │ │ ├── sass │ │ ├── _function.scss │ │ ├── _mixins.scss │ │ └── _variables.scss │ │ ├── src │ │ ├── actionsheet │ │ │ └── weui.actionsheet.ts │ │ ├── badge │ │ │ └── weui.badge.ts │ │ ├── button │ │ │ └── weui.button.ts │ │ ├── core │ │ │ ├── anim.frame.ts │ │ │ ├── errors │ │ │ │ └── error.ts │ │ │ └── service │ │ │ │ └── update.class.service.ts │ │ ├── dialog │ │ │ └── weui.dialog.ts │ │ ├── footer │ │ │ └── weui.footer.ts │ │ ├── form │ │ │ ├── abstract.form.ts │ │ │ ├── form.directive.ts │ │ │ ├── form.error.ts │ │ │ └── message.formater.ts │ │ ├── gallery │ │ │ └── weui.gallery.ts │ │ ├── input │ │ │ ├── weui.checkbox.ts │ │ │ ├── weui.input.ts │ │ │ ├── weui.radio.ts │ │ │ ├── weui.select.ts │ │ │ └── weui.switch.ts │ │ ├── list │ │ │ ├── weui.item.ts │ │ │ ├── weui.items.ts │ │ │ ├── weui.link.ts │ │ │ ├── weui.tips.ts │ │ │ └── weui.title.ts │ │ ├── loadmore │ │ │ └── weui.loadmore.ts │ │ ├── navbar │ │ │ ├── weui.navbar.item.ts │ │ │ └── weui.navbar.ts │ │ ├── overlay │ │ │ ├── LayerInjector.ts │ │ │ └── layer.ts │ │ ├── picker │ │ │ ├── cron.ts │ │ │ ├── weui-picker-group.ts │ │ │ ├── weui.date.picker.ts │ │ │ ├── weui.picker.service.ts │ │ │ └── weui.picker.ts │ │ ├── progress │ │ │ ├── weui.circle.ts │ │ │ └── weui.progress.ts │ │ ├── searchbar │ │ │ └── weui.searchbar.ts │ │ ├── slider │ │ │ └── weui.slider.ts │ │ ├── tabbar │ │ │ ├── weui.tabbar.item.ts │ │ │ └── weui.tabbar.ts │ │ ├── toast │ │ │ └── weui.toast.ts │ │ ├── toptips │ │ │ └── weui.toptip.ts │ │ ├── uploader │ │ │ └── weui.uploader.ts │ │ ├── util │ │ │ ├── classnames.ts │ │ │ ├── lang.ts │ │ │ └── string.utils.ts │ │ ├── weui.module.ts │ │ └── weui.ts │ │ ├── tsconfig.json │ │ └── weui.scss ├── assets │ ├── css │ │ ├── animate.min.css │ │ ├── app.scss │ │ └── format.css │ └── weui-example │ │ ├── example.css │ │ ├── images │ │ ├── icon_footer.png │ │ ├── icon_footer_link.png │ │ ├── icon_intro.png │ │ ├── icon_nav_actionSheet.png │ │ ├── icon_nav_article.png │ │ ├── icon_nav_button.png │ │ ├── icon_nav_cell.png │ │ ├── icon_nav_dialog.png │ │ ├── icon_nav_feedback.png │ │ ├── icon_nav_flow.png │ │ ├── icon_nav_form.png │ │ ├── icon_nav_icons.png │ │ ├── icon_nav_layout.png │ │ ├── icon_nav_msg.png │ │ ├── icon_nav_nav.png │ │ ├── icon_nav_panel.png │ │ ├── icon_nav_progress.png │ │ ├── icon_nav_search.png │ │ ├── icon_nav_search_bar.png │ │ ├── icon_nav_special.png │ │ ├── icon_nav_tab.png │ │ ├── icon_nav_toast.png │ │ ├── icon_nav_z-index.png │ │ ├── icon_nav_zindex.png │ │ ├── icon_tabbar.png │ │ ├── layers │ │ │ ├── content.png │ │ │ ├── navigation.png │ │ │ ├── popout.png │ │ │ └── transparent.gif │ │ ├── logo.png │ │ ├── pic_160.png │ │ ├── pic_article.png │ │ └── vcode.jpg │ │ └── snapshot │ │ ├── actionSheet.png │ │ ├── button.png │ │ ├── cell.png │ │ ├── dialog1.png │ │ ├── dialog2.png │ │ ├── grid.png │ │ ├── icons.png │ │ ├── progress.png │ │ ├── qrcode.png │ │ ├── result.png │ │ ├── text.png │ │ ├── toast1.png │ │ └── toast2.png ├── declarations.d.ts ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── pages │ ├── images │ │ ├── avatar-1.jpg │ │ ├── avatar-2.jpg │ │ ├── icon_tabbar.png │ │ ├── pic_160.png │ │ ├── pic_article.png │ │ └── zhenhuan.jpg │ ├── readme.md │ └── weui │ │ ├── abstract-page.ts │ │ ├── actionsheet │ │ ├── example.html │ │ └── example.ts │ │ ├── article │ │ ├── example.html │ │ └── example.ts │ │ ├── badge │ │ ├── example.html │ │ └── example.ts │ │ ├── button │ │ ├── example.html │ │ └── example.ts │ │ ├── dialog │ │ ├── example.html │ │ └── example.ts │ │ ├── flex │ │ ├── example.html │ │ └── example.ts │ │ ├── footer │ │ ├── example.html │ │ └── example.ts │ │ ├── gallery │ │ ├── example.html │ │ └── example.ts │ │ ├── grid │ │ ├── example.html │ │ └── example.ts │ │ ├── icons │ │ ├── example.html │ │ └── example.ts │ │ ├── input │ │ ├── example.html │ │ └── example.ts │ │ ├── list │ │ ├── example.html │ │ └── example.ts │ │ ├── loadmore │ │ ├── example.html │ │ └── example.ts │ │ ├── msg │ │ ├── example.html │ │ ├── example.ts │ │ ├── succ_example.html │ │ └── warn_example.html │ │ ├── navbar │ │ ├── example.html │ │ └── example.ts │ │ ├── panel │ │ ├── example.html │ │ └── example.ts │ │ ├── picker │ │ ├── example.html │ │ └── example.ts │ │ ├── preview │ │ ├── example.html │ │ └── example.ts │ │ ├── progress │ │ ├── example.html │ │ └── example.ts │ │ ├── searchbar │ │ ├── example.html │ │ └── example.ts │ │ ├── slider │ │ ├── example.html │ │ └── example.ts │ │ ├── tabbar │ │ ├── example.html │ │ └── example.ts │ │ ├── toast │ │ ├── example.html │ │ └── example.ts │ │ ├── uploader │ │ ├── example.html │ │ └── example.ts │ │ ├── weui.example.html │ │ ├── weui.example.module.ts │ │ ├── weui.example.routing.module.ts │ │ └── weui.example.ts ├── polyfills.ts ├── styles.scss ├── theme │ └── variables.scss └── tsconfig.app.json ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = true 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # don't ever lint node_modules 2 | node_modules 3 | # don't lint build output (make sure it's set to your correct build folder name) 4 | dist 5 | # don't lint nyc coverage output 6 | coverage 7 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | plugins: [ 5 | '@typescript-eslint', 6 | ], 7 | extends: [ 8 | 'eslint:recommended', 9 | 'plugin:@typescript-eslint/recommended', 10 | 'prettier/@typescript-eslint', 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Angular4-WeUI 2 | 3 | The following is a set of guidelines for contributing to Angular4-WeUI. Please spend several minutes in reading these guidelines before you create an issue or pull request. 4 | 5 | Anyway, these are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request. 6 | 7 | 8 | ## Do your homework before asking a question 9 | 10 | It's a great idea to read Eric Steven Raymond's [How To Ask Questions The Smart Way](http://www.catb.org/esr/faqs/smart-questions.html) twice before asking a question. But if you are busy now, I recommend to read [Don't post homework questions](http://www.catb.org/esr/faqs/smart-questions.html#homework) first. 11 | 12 | The following guidelines are about *How to avoid Homework Questions*. 13 | 14 | ### 1. Read the documentation. 15 | 16 | It sad but true that someone just glance(not read) [Angular4-WeUI's documentation](https://github.com/fbchen/angular4-weui). Please read the documentation closely. What's more, you can modify and run our demo with [CodePen]. It's helpful to understand our documentation. 17 | 18 | Tips: choose the corresponding documentation with versions selector which in the bottom-right corner. 19 | 20 | ### 2. Make sure that your question is about Angular4-WeUI, not Angular4 21 | 22 | Someone may think all of the questions that he/she meets in developing are about Angular4-WeUI, but it's not true. So, please read [Angular4's documentation](https://angular.io/docs/ts/latest/quickstart.html) or just Google (not Baidu, seriously) your questions with keyword *Angular* first. If you are sure that your question is about Angular4-WeUI, go ahead. 23 | 24 | ### 3. Read the FAQ and search the issues list of Angular4-WeUI 25 | 26 | Your questions may be asked and solved by others. So please spend several minutes on searching. Remember [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself), both code and questions. 27 | 28 | P.S. 29 | 30 | 1. [FAQ](https://github.com/fbchen/angular4-weui/wiki/FAQ) 31 | 1. [Issues list](https://github.com/fbchen/angular4-weui/issues) 32 | 33 | ## Close your issue if it's solved 34 | 35 | It is a good habit which will save maintainers' time. Thank you! 36 | 37 | ## Providing a demo while reporting a bug 38 | 39 | It would be helpful to provide a demo which can re-produce the bug 100%. Please fork this [CodePen] and re-produce the bug you met. Then, create an issue. The most important thing is: double check before claiming that you have found a bug. 40 | 41 | 42 | ## Tips about Feature Request 43 | 44 | If you believe that Angular4-WeUI should provide some features, but it does not. You could create an issue to discuss. However, Angular4-WeUI is not Swiss Army Knife, there are some features which Angular4-WeUI will not support: 45 | 46 | 1. Request or operate data 47 | 48 | 49 | ## Tips about Pull Request 50 | 51 | **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 52 | 53 | It's welcomed to pull request. And there are some tips about that: 54 | 55 | 1. It is a good habit to create a feature request issue to discuss whether the feature is necessary before you implement it. However, it's unnecessary to create an issue to claim that you found a typo or improved the readability of documentation, just create a pull request. 56 | 1. Run `npm run lint` and fix those errors before committing in order to keep consistent code style. 57 | 1. Rebase before creating a PR to keep commit history clear. 58 | 1. Add some descriptions and refer relative issues for you PR. 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | #### 发生问题的环境是: 13 | 14 | 15 | 16 | - Angular/WeUI 版本: 17 | - 操作系统及其版本: 18 | - 浏览器及其版本: 19 | 20 | #### 您做了什么?请提供尽可能详细的重现步骤。 21 | 22 | 23 | 24 | #### 您期待的结果是: 25 | 26 | 27 | 28 | #### 实际上的结果是: 29 | 30 | 31 | 32 | #### 可重现的在线演示 33 | 34 | 35 | -------------------------------------------------------------------------------- /.github/images/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/.github/images/alipay.jpg -------------------------------------------------------------------------------- /.github/images/wcpay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/.github/images/wcpay.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /.scripts/_travis-fold.sh: -------------------------------------------------------------------------------- 1 | # private variable to track folds within this script 2 | travisFoldStack=() 3 | 4 | function travisFoldStart() { 5 | local foldName="${0#./} ${1}" 6 | # get current time as nanoseconds since the beginning of the epoch 7 | foldStartTime=$(date +%s%N) 8 | # convert all non alphanum chars except for "-" and "." to "--" 9 | local sanitizedFoldName=${foldName//[^[:alnum:]\-\.]/--} 10 | # strip trailing "-" 11 | sanitizedFoldName=${sanitizedFoldName%-} 12 | # push the foldName onto the stack 13 | travisFoldStack+=("${sanitizedFoldName}|${foldStartTime}") 14 | 15 | echo "" 16 | if [[ ${TRAVIS:-} ]]; then 17 | echo "travis_fold:start:${sanitizedFoldName}" 18 | echo "travis_time:start:${sanitizedFoldName}" 19 | fi 20 | local enterArrow="===> ${foldName} ==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>" 21 | # keep all messages consistently wide 80chars regardless of the foldName 22 | echo ${enterArrow:0:100} 23 | if [[ ${2:-} != "no-xtrace" ]]; then 24 | # turn on verbose mode so that we have better visibility into what's going on 25 | # http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html#table_02_01 26 | set -x 27 | fi 28 | } 29 | 30 | function travisFoldEnd() { 31 | set +x 32 | local foldName="${0#./} ${1}" 33 | # convert all non alphanum chars except for "-" and "." to "--" 34 | local sanitizedFoldName=${foldName//[^[:alnum:]\-\.]/--} 35 | # strip trailing "-" 36 | sanitizedFoldName=${sanitizedFoldName%-} 37 | 38 | # consult and update travisFoldStack 39 | local lastFoldIndex=$(expr ${#travisFoldStack[@]} - 1) 40 | local lastFoldString=${travisFoldStack[$lastFoldIndex]} 41 | # split the string by | and then turn that into an array 42 | local lastFoldArray=(${lastFoldString//\|/ }) 43 | local lastSanitizedFoldName=${lastFoldArray[0]} 44 | 45 | if [[ ${TRAVIS:-} ]]; then 46 | local lastFoldStartTime=${lastFoldArray[1]} 47 | local foldFinishTime=$(date +%s%N) 48 | local foldDuration=$(expr ${foldFinishTime} - ${lastFoldStartTime}) 49 | 50 | # write into build-perf.log file 51 | local logIndent=$(expr ${lastFoldIndex} \* 2) 52 | printf "%6ss%${logIndent}s: %s\n" $(expr ${foldDuration} / 1000000000) " " "${foldName}" >> ${LOGS_DIR}/build-perf.log 53 | fi 54 | 55 | # pop 56 | travisFoldStack=(${travisFoldStack[@]:0:lastFoldIndex}) 57 | 58 | # check for misalignment 59 | if [[ ${lastSanitizedFoldName} != ${sanitizedFoldName} ]]; then 60 | echo "Travis fold mis-alignment detected! travisFoldEnd expected sanitized fold name '${lastSanitizedFoldName}', but received '${sanitizedFoldName}' (after sanitization)" 61 | exit 1 62 | fi 63 | 64 | local returnArrow="<=== ${foldName} <==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==" 65 | # keep all messages consistently wide 80chars regardless of the foldName 66 | echo ${returnArrow:0:100} 67 | echo "" 68 | if [[ ${TRAVIS:-} ]]; then 69 | echo "travis_time:end:${sanitizedFoldName}:start=${lastFoldStartTime},finish=${foldFinishTime},duration=${foldDuration}" 70 | echo "travis_fold:end:${sanitizedFoldName}" 71 | fi 72 | } 73 | 74 | 75 | function travisFoldReturnArrows() { 76 | # print out return arrows so that it's easy to see the end of the script in the log 77 | echo "" 78 | returnArrow="<=== ${0#./} <==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==" 79 | # keep all messages consistently wide 80chars regardless of the foldName 80 | echo ${returnArrow:0:100} 81 | echo "<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==<===" 82 | echo "" 83 | } 84 | -------------------------------------------------------------------------------- /.scripts/map_sources.js: -------------------------------------------------------------------------------- 1 | 2 | var path = require('path'); 3 | var sorcery = require('sorcery'); 4 | var yargs = require('yargs'); 5 | 6 | var argv = require('yargs') 7 | .alias('f', 'file') 8 | .argv; 9 | 10 | 11 | sorcery.load(argv.file).then(function(chain) { 12 | chain.write(); 13 | }); 14 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [{ 7 | "type": "node", 8 | "request": "launch", 9 | "name": "启动程序", 10 | "cwd": "${workspaceRoot}", 11 | "program": "${workspaceRoot}/node_modules/.bin/ng", 12 | "args": [ 13 | "serve" 14 | ] 15 | }, 16 | { 17 | "type": "node", 18 | "request": "launch", 19 | "name": "打包程序", 20 | "cwd": "${workspaceRoot}", 21 | "program": "${workspaceRoot}/node_modules/.bin/ng", 22 | "args": [ 23 | "build", "-prod", "--aot" 24 | ] 25 | }, 26 | { 27 | "type": "node", 28 | "request": "launch", 29 | "name": "检测语法", 30 | "cwd": "${workspaceRoot}", 31 | "program": "${workspaceRoot}/node_modules/.bin/ng", 32 | "args": [ 33 | "lint" 34 | ] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // 将设置放入此文件中以覆盖默认值和用户设置。 2 | { 3 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "tslint", 9 | "problemMatcher": { 10 | "base": "$tslint5", 11 | "fileLocation": "relative" 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2017-2020 厦门乾元盛世科技有限公司. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular4-WeUI 2 | Angular4-WeUI 是基于Angular(4.*)实现的、针对手机端(如微信)Web应用开发的UI框架。 3 | 4 | [WeUI](https://weui.io/) 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。 5 | 6 | [Angular](https://github.com/angular/angular) is a development platform for building mobile and desktop web applications using Typescript/JavaScript (JS) and other languages. 7 | 8 | Angular4-WeUI 是采用Angular对WeUI重写的UI库,包含了全部WeUI官方的CSS组件,如Picker、DatePicker、ActionSheet、Dialog等,通过Angular提供的数据绑定(MVVM)、依赖注入(DI)、标签自定义(Directive)等机制,封装后的WeUI组件更加灵活方便,使开发人员可以更加专注于业务的实现,可以极大减少前端开发时间。 9 | 10 | ## Install 11 | 12 | ```bash 13 | npm install angular4-weui --save 14 | ``` 15 | 16 | 如果下载速度较慢,可以尝试加入[淘宝 NPM 镜像](http://npm.taobao.org),以加快模块下载速度。 17 | 18 | ```bash 19 | npm install -g cnpm --registry=https://registry.npm.taobao.org 20 | ``` 21 | 22 | 然后通过cnpm命令来安装: 23 | ```bash 24 | cnpm install angular4-weui --save 25 | ``` 26 | 27 | ## Quickstart 28 | 29 | 直接下载本工程,并启动运行查看Demo: 30 | ```bash 31 | git clone https://github.com/fbchen/angular4-weui.git 32 | cd angular4-weui 33 | cnpm install 34 | ``` 35 | 36 | 下载angular4-weui后,通过开发工具[VSCode](http://code.visualstudio.com/Download)打开安装目录,点击调试“启动程序”,然后在浏览器中输入 http://localhost:4200/ 直接预览效果。 37 | 38 | ## Usage 39 | 40 | ```ts 41 | import { NgModule } from '@angular/core'; 42 | import { FormsModule } from '@angular/forms'; 43 | import { BrowserModule } from '@angular/platform-browser'; 44 | 45 | import { WeUIModule } from 'angular4-weui'; 46 | 47 | import { AppComponent } from './app.component'; 48 | 49 | @NgModule({ 50 | imports: [ 51 | FormsModule, 52 | BrowserModule, 53 | WeUIModule 54 | ], 55 | declarations: [ 56 | AppComponent 57 | ], 58 | providers: [], 59 | bootstrap: [ AppComponent ] 60 | }) 61 | export class AppModule { } 62 | ``` 63 | 64 | # Live Example 65 | Open Chrome, and visits: 66 | [https://fbchen.github.io/angular4-weui](https://fbchen.github.io/angular4-weui/index.html) 67 | 68 | Demo Project: 69 | [https://github.com/fbchen/angular4-weui-demo](https://github.com/fbchen/angular4-weui-demo) 70 | 71 | 72 | # License 73 | 74 | 基于 [MIT](./LICENSE) 协议发布,免费开源 75 | 76 | # Contributing 77 | Thanks for your interest in contributing! :tada: Read up on our guidelines for [contributing][contributing] and then look through our issues with a help [help wanted](https://github.com/fbchen/angular4-weui/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) 78 | label. 79 | 80 | 我们欢迎任何形式的贡献,有任何建议或意见您可以进行 [Pull Request](https://github.com/fbchen/angular4-weui/pulls),或者给我们 [提问](https://github.com/fbchen/angular4-weui/issues)。 81 | 82 | ##DONATIONS 83 | 84 | If you find Angular4-WeUI helpful, please consider making a donation (of cash, 85 | software, or hardware) to support continued work on the project. You can 86 | donate through 支付宝/Alipay or 微信/WeChat by scanning qrcodes as follows: 87 | 88 | ![image](https://github.com/fbchen/angular4-weui/raw/master/.github/images/alipay.jpg) 89 | ![image](https://github.com/fbchen/angular4-weui/raw/master/.github/images/wcpay.jpg) 90 | 91 | 92 | [contributing]: https://github.com/fbchen/angular4-weui/.github/CONTRIBUTING.md 93 | -------------------------------------------------------------------------------- /browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /license-banner.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular4-weui", 3 | "version": "2.0.0", 4 | "license": "MIT", 5 | "author": "32674406@qq.com", 6 | "scripts": { 7 | "ng": "ng", 8 | "start": "ng serve --host 0.0.0.0 --port 4802", 9 | "package": "ng build --prod --aot", 10 | "lint": "npx eslint . --ext .js,.jsx,.ts,.tsx" 11 | }, 12 | "private": false, 13 | "dependencies": { 14 | "@angular/animations": "^9.1.2", 15 | "@angular/cdk": "^9.1.2", 16 | "@angular/common": "^9.1.2", 17 | "@angular/compiler": "^9.1.2", 18 | "@angular/core": "^9.1.2", 19 | "@angular/forms": "^9.1.2", 20 | "@angular/platform-browser": "^9.1.2", 21 | "@angular/platform-browser-dynamic": "^9.1.2", 22 | "@angular/router": "^9.1.2", 23 | "core-js": "^3.6.5", 24 | "rxjs": "~6.5.5", 25 | "zone.js": "~0.10.3", 26 | "weui": "^1.1.2", 27 | "web-animations-js": "2.3.2" 28 | }, 29 | "devDependencies": { 30 | "@angular-devkit/build-angular": "~0.901.1", 31 | "@angular/cli": "~9.1.1", 32 | "@angular/compiler-cli": "~9.1.1", 33 | "@angular/language-service": "~9.1.1", 34 | "@types/crypto-js": "^3.1.0", 35 | "@types/node": "^12.11.1", 36 | "@types/jasmine": "^3.5.10", 37 | "codelyzer": "^5.2.0", 38 | "sorcery": "^0.10.0", 39 | "source-map": "^0.7.3", 40 | "source-map-support": "^0.5.12", 41 | "source-map-loader": "^0.2.4", 42 | "rollup": "^1.13.1", 43 | "rollup-plugin-commonjs": "^10.0.0", 44 | "rollup-plugin-node-resolve": "^5.2.0", 45 | "rollup-plugin-uglify": "^6.0.0", 46 | "ts-node": "~8.8.2", 47 | "eslint": "^7.3.1", 48 | "@typescript-eslint/parser": "^3.4.0", 49 | "@typescript-eslint/eslint-plugin": "^3.4.0", 50 | "typescript": "~3.8.3", 51 | "tsickle": "^0.38.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app/app.environment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Injectable } from '@angular/core'; 10 | 11 | /** 12 | * App环境变量 13 | */ 14 | @Injectable() 15 | export class AppEnvironment { 16 | 17 | /** 18 | * 获取系统版本 19 | */ 20 | public get version(): string { 21 | return '1.0.0'; 22 | } 23 | 24 | /** 25 | * 获取数据服务器URL路径 26 | */ 27 | public get BaseUrl(): string { 28 | return 'http://127.0.0.1:9999/'; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { NgModule } from '@angular/core'; 10 | import { HttpClientModule } from '@angular/common/http'; 11 | import { RouterModule } from '@angular/router'; 12 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 13 | 14 | import { CoreModule } from './core/core.module'; 15 | 16 | /* WeUI Module */ 17 | import { WeUIModule } from './weui'; // 'angular-weui' 18 | 19 | /* WeUI Example Module */ 20 | import { WeUIExampleModule } from '../pages/weui/weui.example.module'; 21 | import { WeUIExampleComponent } from '../pages/weui/weui.example'; 22 | 23 | 24 | @NgModule({ 25 | imports: [ 26 | HttpClientModule, 27 | CoreModule, 28 | BrowserAnimationsModule, 29 | WeUIModule, 30 | WeUIExampleModule, 31 | RouterModule.forRoot([]) 32 | ], 33 | declarations: [ 34 | // AppComponent 35 | ], 36 | entryComponents: [ 37 | // AppComponent 38 | ], 39 | providers: [ 40 | 41 | ], 42 | bootstrap: [ 43 | WeUIExampleComponent 44 | ] 45 | }) 46 | export class AppModule { } 47 | -------------------------------------------------------------------------------- /src/app/core/core.module.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { NgModule, Optional, SkipSelf } from '@angular/core'; 10 | import { BrowserModule } from '@angular/platform-browser'; 11 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 12 | 13 | 14 | /** 15 | * @name CoreModule 16 | * @description 17 | * CoreModule is an NgModule that provides Core Components, Directive and Pipes. 18 | * 19 | * @author fbchen 2017-03-08 20 | */ 21 | @NgModule({ 22 | imports: [ 23 | BrowserModule, 24 | BrowserAnimationsModule 25 | ], 26 | declarations: [], 27 | exports: [], 28 | providers: [] 29 | }) 30 | export class CoreModule { 31 | 32 | constructor( @Optional() @SkipSelf() parentModule: CoreModule) { 33 | if (parentModule) { 34 | throw new Error( 35 | 'CoreModule is already loaded. Import it in the AppModule only'); 36 | } 37 | } 38 | 39 | } 40 | 41 | 42 | /** Export Class */ 43 | export { Page } from './page'; 44 | export { Result } from './result'; 45 | export { toResult } from './rxjs/operators/to-result'; 46 | 47 | -------------------------------------------------------------------------------- /src/app/core/page.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | /** 10 | * 分页设置 11 | * 12 | * @author fbchen 13 | * @version 1.0 2016-11-20 14 | */ 15 | export class Page { 16 | 17 | /** 18 | * 当前页码,基于1 19 | */ 20 | pageNo = 1; 21 | 22 | /** 23 | * 每页最多显示记录数 24 | */ 25 | pageSize = 10; 26 | 27 | /** 28 | * 总页数 29 | */ 30 | pageCount = 0; 31 | 32 | /** 33 | * 总记录 34 | */ 35 | totalCount = 0; 36 | 37 | /** 38 | * 当前页的记录数 39 | */ 40 | recordCount = 0; 41 | 42 | /** 43 | * 当前页的开始记录位置,如:1 44 | */ 45 | recordStart = 1; 46 | 47 | /** 更新内部数据 */ 48 | public update(data: any): void { 49 | Object.assign(this, data); 50 | } 51 | 52 | /** 数据显示范围 */ 53 | public range(range: number[], total: number): string { 54 | const min = Math.min(range[0], this.totalCount); 55 | const max = Math.min(range[1], this.totalCount); 56 | return `${min} - ${max}`; 57 | } 58 | 59 | /** 减少一个记录 */ 60 | public reduce(count = 1): void { 61 | this.totalCount -= count; 62 | this.recordCount -= count; 63 | } 64 | 65 | /** 增加一个记录 */ 66 | public increase(count = 1): void { 67 | this.totalCount += count; 68 | this.recordCount += count; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/app/core/result.error.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Result } from './result'; 10 | 11 | /** 12 | * ResultError:扩展自Error 13 | * 14 | * @author fbchen 15 | * @version 1.0 2016-11-28 16 | */ 17 | export class ResultError extends Error { 18 | 19 | public result: Result; 20 | 21 | constructor(result: Result) { 22 | super(); 23 | this.result = result; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/app/core/result.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Page } from './page'; 10 | 11 | /** 12 | * 操作响应结果 13 | * 14 | * @author fbchen 15 | * @version 1.0 2016-11-20 16 | */ 17 | export class Result { 18 | 19 | /** 20 | * 操作结果 21 | */ 22 | success = true; 23 | 24 | /** 25 | * 错误码 26 | */ 27 | code?: string | number; 28 | 29 | /** 30 | * 错误描述 31 | */ 32 | msg?: string; 33 | 34 | /** 35 | * 新增或修改对象后返回的ID 36 | */ 37 | id?: string | number; 38 | 39 | /** 40 | * 结果集 41 | */ 42 | list?: any; 43 | 44 | /** 45 | * 分页信息 46 | */ 47 | page?: Page; 48 | 49 | /** 50 | * 数据 51 | */ 52 | data?: any; 53 | 54 | /** 55 | * 其它任意成员 56 | */ 57 | [propName: string]: any; 58 | 59 | /** 60 | * 通过静态方法创建 61 | */ 62 | public static fail(code?: string | number, msg?: string): Result { 63 | const r = new Result(false); 64 | r.code = code; 65 | r.msg = msg; 66 | return r; 67 | } 68 | 69 | /** 70 | * 创建 71 | */ 72 | public constructor(success: boolean = true, code?: string | number, msg?: string) { 73 | this.success = success; 74 | this.code = code; 75 | this.msg = msg; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/app/core/rxjs/operators/to-result.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | import { Observable } from 'rxjs'; 9 | import { Result } from '../../result'; 10 | 11 | /** 12 | * an operator that take result from Response 13 | */ 14 | export const toResult = () => (source: Observable) => 15 | new Observable(observer => { 16 | return source.subscribe({ 17 | next(x) { 18 | // tslint:disable-next-line:no-string-literal 19 | if (x['error']) { 20 | // tslint:disable-next-line:no-string-literal 21 | observer.error(x['error']); 22 | return; 23 | } 24 | // tslint:disable-next-line:no-string-literal 25 | observer.next(x['result']); 26 | }, 27 | error(err) { observer.error(err); }, 28 | complete() { observer.complete(); } 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /src/app/shared/abstract.service.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Http, Response } from '@angular/http'; 10 | import { Observable } from 'rxjs'; 11 | 12 | import { AppEnvironment } from '../app.environment'; 13 | import { Result } from '../core/result'; 14 | import { ResultError } from '../core/result.error'; 15 | 16 | 17 | /** 18 | * 抽象服务 19 | */ 20 | export class AbstractService { 21 | protected BaseUrl: string = this.environment.BaseUrl; 22 | 23 | constructor( 24 | protected http: Http, 25 | protected environment: AppEnvironment) { 26 | 27 | } 28 | 29 | /** 30 | * 从Response抽取数据 31 | * 32 | * @param response Response对象 33 | */ 34 | public extractData(response: Response): Observable { 35 | if (response['error']) { 36 | throw new ResultError(response['error'] as Result); 37 | // return Observable.throw(response['error'] as Result); 38 | } 39 | return response['result']; 40 | } 41 | 42 | /** 43 | * 捕获异常,并转换为Result 44 | * 45 | * @param err 可能是Response、Result,或Error等 46 | * @param caught Observable对象 47 | */ 48 | public catchError(err: any, caught?: Observable): Observable { 49 | let result: Result; 50 | if (err instanceof ResultError) { 51 | result = err.result; 52 | } else if (err.error instanceof Result) { 53 | result = err.error; 54 | } else if (err instanceof Response) { 55 | result = Result.fail('900', err.statusText || '服务器异常,请稍后重试'); 56 | } else { 57 | const errMsg = err.message ? err.message : err.toString(); 58 | result = Result.fail('900', errMsg); 59 | } 60 | return Observable.throw(result); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/app/shared/directive/phone.validator.directive.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 10 | 11 | /** 12 | * 手机号码验证 13 | */ 14 | export function phoneNumberValidator(): ValidatorFn { 15 | const mobileRe: RegExp = /^13[0-9]{9}$|14[0-9]{9}|15[0-9]{9}$|1[78][0-9]{9}$/; 16 | return (control: AbstractControl): { [key: string]: any } => { 17 | const value = control.value; 18 | if (!value) { // 为空时不验证合法性 19 | return null; 20 | } 21 | const valid = mobileRe.test(value); 22 | return !valid ? { 'phoneNumber': { value } } : null; 23 | }; 24 | } 25 | 26 | 27 | import { Directive } from '@angular/core'; 28 | import { Validator, NG_VALIDATORS } from '@angular/forms'; 29 | 30 | /** 31 | * 手机号码验证 32 | * 33 | * @author fbchen 34 | * @version 1.0 2016-12-02 35 | */ 36 | @Directive({ 37 | selector: '[phoneNumber]', 38 | providers: [{ provide: NG_VALIDATORS, useExisting: PhoneNumberValidatorDirective, multi: true }] 39 | }) 40 | export class PhoneNumberValidatorDirective implements Validator { 41 | 42 | private validateAt = phoneNumberValidator(); 43 | 44 | /** 45 | * 验证控件 46 | */ 47 | validate(control: AbstractControl): { [key: string]: any } { 48 | return this.validateAt(control); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/app/shared/directive/range.validator.directive.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Input } from '@angular/core'; 10 | import { FormControl, ValidatorFn, Validators } from '@angular/forms'; 11 | import { isPresent } from '../utils/lang'; 12 | 13 | /** 14 | * 数字大小验证 15 | */ 16 | export function numberValidator(prms: { min?: number, max?: number } = {}): ValidatorFn { 17 | return (control: FormControl): { [key: string]: any } => { 18 | if (isPresent(Validators.required(control))) { 19 | return null; 20 | } 21 | 22 | let min: number, max: number; 23 | const value: number = +control.value; 24 | if (isNaN(value)) { 25 | return { 'number': { value } }; 26 | } 27 | if (!isNaN(prms.min) && value < (min = +prms.min)) { 28 | return { 'number': { value, min } }; 29 | } 30 | if (!isNaN(prms.max) && value > (max = +prms.max)) { 31 | return { 'number': { value, max } }; 32 | } 33 | return null; 34 | }; 35 | } 36 | 37 | 38 | import { Directive } from '@angular/core'; 39 | import { Validator, NG_VALIDATORS } from '@angular/forms'; 40 | 41 | /** 42 | * 数字大小验证 43 | * 44 | * @author fbchen 45 | * @version 1.0 2016-12-02 46 | */ 47 | @Directive({ 48 | selector: '[max],[min]', 49 | providers: [{ provide: NG_VALIDATORS, useExisting: RangeValidatorDirective, multi: true }] 50 | }) 51 | export class RangeValidatorDirective implements Validator { 52 | 53 | @Input() max: number; 54 | @Input() min: number; 55 | 56 | /** 57 | * 验证控件 58 | */ 59 | validate(control: FormControl): { [key: string]: any } { 60 | return numberValidator({ min: this.min, max: this.max })(control); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/app/shared/directive/url.validator.directive.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 10 | 11 | /** 12 | * URL验证 13 | */ 14 | export function urlValidator(): ValidatorFn { 15 | // tslint:disable-next-line:max-line-length 16 | const urlRe: RegExp = /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i; 17 | return (control: AbstractControl): { [key: string]: any } => { 18 | const value = control.value; 19 | if (!value) { // 为空时不验证合法性 20 | return null; 21 | } 22 | const valid = urlRe.test(value); 23 | return !valid ? { 'url': { value } } : null; 24 | }; 25 | } 26 | 27 | 28 | import { Directive } from '@angular/core'; 29 | import { Validator, NG_VALIDATORS } from '@angular/forms'; 30 | 31 | /** 32 | * URL验证 33 | * 34 | * @author fbchen 35 | * @version 1.0 2016-12-02 36 | */ 37 | @Directive({ 38 | selector: '[url]', 39 | providers: [{ provide: NG_VALIDATORS, useExisting: URLValidatorDirective, multi: true }] 40 | }) 41 | export class URLValidatorDirective implements Validator { 42 | 43 | private validateAt = urlValidator(); 44 | 45 | /** 46 | * 验证控件 47 | */ 48 | validate(control: AbstractControl): { [key: string]: any } { 49 | return this.validateAt(control); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/app/shared/pipe/array.filter.pipe.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Pipe, PipeTransform } from '@angular/core'; 10 | 11 | /** 12 | * 数组过滤(提供function) 13 | * 14 | * @author fbchen 15 | * @version 1.0 2016-12-06 16 | */ 17 | @Pipe({ name: 'arrayfilter' }) 18 | export class ArrayFilterPipe implements PipeTransform { 19 | 20 | transform(array: Array, fn: (value: any, index: number, array: any[]) => boolean): any { 21 | return array ? array.filter(fn) : array; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/app/shared/pipe/filesize.pipe.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Pipe, PipeTransform } from '@angular/core'; 10 | import { FileUtils } from '../utils/file.utils'; 11 | 12 | /** 13 | * 根据文件大小(B),输出可阅读的文件大小(如:2.14 GB、2.5 MB、87 KB等) 14 | * 15 | * @author fbchen 16 | * @version 1.0 2016-12-06 17 | */ 18 | @Pipe({ name: 'filesize' }) 19 | export class FileSizePipe implements PipeTransform { 20 | 21 | transform(filesize: number): string { 22 | return FileUtils.getFileSize(filesize); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/app/shared/pipe/format.date.pipe.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | 10 | import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core'; 11 | 12 | import { DateFormatter } from './intl'; 13 | import { invalidPipeArgumentError } from './invalid_pipe_argument_error'; 14 | import { StringUtils } from '../utils/string.utils'; 15 | 16 | /** 17 | * @ngModule SharedModule 18 | * @whatItDoes Formats a date according to locale rules. 19 | * @howToUse `date_expression | formatDate[:to-format][:from-format]` 20 | * @author fbchen 21 | * @version 1.0 2016-12-06 22 | * @description 23 | * 24 | * 25 | * ### Examples 26 | * 27 | * Assuming `dateStr` is "2016-09-12 23:15:00" (year: 2016, month: 9, day: 12, hour: 23, minute: 15, second: 0) 28 | * in the _local_ time and locale is 'zh-CN': 29 | * 30 | * ``` 31 | * {{ dateStr | formatDate: 'y年M月d日' : 'y-MM-dd HH:mm:ss' }} // output is '2016年9月12日' 32 | * {{ dateStr | formatDate: 'y年M月d日' }} // output is '2016年9月12日' 33 | * ``` 34 | * 35 | */ 36 | @Pipe({ name: 'formatDate' }) 37 | export class FormatDatePipe implements PipeTransform { 38 | 39 | static _ALIASES: {[key: string]: string} = { 40 | 'medium': 'yMMMdjms', 41 | 'short': 'yMdjm', 42 | 'fullDate': 'yMMMMEEEEd', 43 | 'longDate': 'yMMMMd', 44 | 'mediumDate': 'yMMMd', 45 | 'shortDate': 'yMd', 46 | 'mediumTime': 'jms', 47 | 'shortTime': 'jm' 48 | }; 49 | 50 | constructor( @Inject(LOCALE_ID) private _locale: string) { 51 | 52 | } 53 | 54 | transform(value: any, toPattern = 'y-MM-dd', fromPattern = 'y-MM-dd HH:mm:ss'): string { 55 | let date: Date; 56 | let localValue: any = value; 57 | 58 | if (StringUtils.isBlank(localValue)) { 59 | return null; 60 | } 61 | 62 | if (typeof localValue === 'string') { 63 | localValue = localValue.trim(); 64 | } 65 | 66 | if (typeof localValue.getTime !== 'undefined') { 67 | date = localValue; 68 | } else if (typeof localValue === 'number') { 69 | date = new Date(localValue); 70 | } else if (typeof localValue === 'string') { 71 | /** 72 | * For ISO Strings without time the day, month and year must be extracted from the ISO String 73 | * before Date creation to avoid time offset and errors in the new Date. 74 | * If we only replace '-' with ',' in the ISO String ("2015,01,01"), and try to create a new 75 | * date, some browsers (e.g. IE 9) will throw an invalid Date error 76 | * If we leave the '-' ("2015-01-01") and try to create a new Date("2015-01-01") the timeoffset 77 | * is applied 78 | * Note: ISO months are 0 for January, 1 for February, ... 79 | */ 80 | try { 81 | date = StringUtils.parseDate(localValue, fromPattern); 82 | } catch (e) { 83 | console.error(e); 84 | } 85 | if (!date) { 86 | date = new Date(localValue); 87 | } 88 | } 89 | 90 | if (date == null || date === undefined) { 91 | date = new Date(localValue); 92 | } 93 | 94 | if (typeof date.getTime === 'undefined') { 95 | throw invalidPipeArgumentError(FormatDatePipe, localValue); 96 | } 97 | 98 | return DateFormatter.format(date, this._locale, FormatDatePipe._ALIASES[toPattern] || toPattern); 99 | } 100 | 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/app/shared/pipe/invalid_pipe_argument_error.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | 9 | import {Type, ɵstringify as stringify} from '@angular/core'; 10 | 11 | export function invalidPipeArgumentError(type: Type, value: Object) { 12 | return Error(`InvalidPipeArgument: '${value}' for pipe '${stringify(type)}'`); 13 | } 14 | -------------------------------------------------------------------------------- /src/app/shared/pipe/safe.html.pipe.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Pipe, PipeTransform } from '@angular/core'; 10 | import { DomSanitizer } from '@angular/platform-browser'; 11 | 12 | /** 13 | * Safe Html Pipe 14 | * 15 | * @author fbchen 16 | * @version 1.0 2017-09-01 17 | */ 18 | @Pipe({ name: 'safeHtml' }) 19 | export class SafeHtmlPipe implements PipeTransform { 20 | 21 | constructor(private sanitized: DomSanitizer) { } 22 | 23 | transform(value) { 24 | return this.sanitized.bypassSecurityTrustHtml(value); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { NgModule } from '@angular/core'; 10 | import { CommonModule } from '@angular/common'; 11 | import { FormsModule } from '@angular/forms'; 12 | 13 | import { FileSizePipe } from './pipe/filesize.pipe'; 14 | import { FormatDatePipe } from './pipe/format.date.pipe'; 15 | import { ArrayFilterPipe } from './pipe/array.filter.pipe'; 16 | import { SafeHtmlPipe } from './pipe/safe.html.pipe'; 17 | 18 | import { RangeValidatorDirective } from './directive/range.validator.directive'; 19 | import { PhoneNumberValidatorDirective } from './directive/phone.validator.directive'; 20 | import { URLValidatorDirective } from './directive/url.validator.directive'; 21 | 22 | export { isPresent, isDate, isNumeric, isInteger, isPrice, isEmptyArray, arrayEquals, toArray, toArrayBuffer } from './utils/lang'; 23 | export { StringUtils } from './utils/string.utils'; 24 | export { FileUtils } from './utils/file.utils'; 25 | 26 | /** 27 | * @name SharedModule 28 | * @description 29 | * SharedModule is an NgModule that provides SHARED Components, Directive and Pipes. 30 | *
    31 | *
  • 它导入了CommonModule,这是因为它的组件需要这些公共指令;
  • 32 | *
  • 正如我们所期待的,它声明并导出了工具性的管道、指令和组件类;
  • 33 | *
  • 它重新导出了CommonModule和FormsModule。通过让SharedModule重新导出CommonModule和FormsModule模块,我们可以消除其它组件的模块重复导入。
  • 34 | *
35 | * {@link https://angular.cn/docs/ts/latest/guide/ngmodule.html#!#shared-module} 36 | * 37 | * @author fbchen 2017-03-08 38 | */ 39 | @NgModule({ 40 | imports: [ 41 | CommonModule 42 | ], 43 | declarations: [ 44 | RangeValidatorDirective, 45 | PhoneNumberValidatorDirective, 46 | URLValidatorDirective, 47 | 48 | FileSizePipe, 49 | FormatDatePipe, 50 | ArrayFilterPipe, 51 | SafeHtmlPipe 52 | ], 53 | exports: [ 54 | CommonModule, 55 | FormsModule, 56 | 57 | RangeValidatorDirective, 58 | PhoneNumberValidatorDirective, 59 | URLValidatorDirective, 60 | 61 | FileSizePipe, 62 | FormatDatePipe, 63 | ArrayFilterPipe, 64 | SafeHtmlPipe 65 | ], 66 | entryComponents: [ 67 | 68 | ] 69 | }) 70 | export class SharedModule { } 71 | -------------------------------------------------------------------------------- /src/app/shared/utils/file.utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | 10 | const FILE_SIZE_UINTS = ['KB', 'MB', 'GB', 'TB', 'PB']; 11 | 12 | /** 13 | * 文件处理函数工具 14 | * 15 | * @author fbchen 16 | * @version 1.0 2016-12-02 17 | */ 18 | export class FileUtils { 19 | 20 | /** 21 | * 下载Blob内容 22 | */ 23 | static download(fileName: string, type: string, data: any): void { 24 | const blob = new Blob([data], { type }); 25 | if (window.navigator.msSaveOrOpenBlob) { 26 | navigator.msSaveBlob(blob, fileName); 27 | } else { 28 | const link = document.createElement('a'); 29 | link.href = window.URL.createObjectURL(blob); 30 | link.download = fileName; 31 | link.click(); 32 | window.URL.revokeObjectURL(link.href); 33 | } 34 | } 35 | 36 | /** 37 | * 计算文件大小 38 | */ 39 | static getFileSize(filesize: number): string { 40 | const max = 5; // KB, MB, GB, TB, PB 41 | for (let i = max; i >= 0; i--) { 42 | const base = Math.pow(1024, i); 43 | const value = filesize / base; 44 | if (value >= 1) { 45 | if (i === 0) { 46 | return `${Math.round(value)} ${FILE_SIZE_UINTS[i - 1]}`; 47 | } 48 | return `${Math.round(value * 100) / 100} ${FILE_SIZE_UINTS[i - 1]}`; 49 | } 50 | } 51 | return `0 KB`; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/app/shared/utils/lang.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | export function isPresent(obj: any): boolean { 10 | return obj !== undefined && obj !== null; 11 | } 12 | 13 | export function isDate(obj: any): boolean { 14 | return !/Invalid|NaN/.test(new Date(obj).toString()); 15 | } 16 | 17 | export function isNumeric(value: any): boolean { 18 | return !isNaN(value - parseFloat(value)); 19 | } 20 | 21 | /** 任何整数都会被1整除,即余数是0。利用这个规则来判断是否是整数 */ 22 | export function isInteger(value: number): boolean { 23 | if (typeof value !== 'number' || isNaN(value)) { 24 | return false; 25 | } 26 | return value % 1 === 0; 27 | } 28 | 29 | /** 是否金额 */ 30 | export function isPrice(value: number): boolean { 31 | if (typeof value !== 'number' || isNaN(value)) { 32 | return false; 33 | } 34 | const re = /^[\d]+(\.[\d]{1,2})?$/; // 金额格式 35 | if (!re.test(value + '')) { 36 | return false; 37 | } 38 | return true; 39 | } 40 | 41 | export function isEmptyArray(arr: any): boolean { 42 | if (Array.isArray(arr)) { 43 | return arr.length === 0 || arr.every(i => !i); 44 | } 45 | return false; 46 | } 47 | 48 | export function arrayEquals(array1: any[], array2: any[]): boolean { 49 | if (!array1 || !array2 || array1.length !== array2.length) { 50 | return false; 51 | } 52 | 53 | const len = array1.length; 54 | for (let i = 0; i < len; i++) { 55 | if (array1[i] !== array2[i]) { 56 | return false; 57 | } 58 | } 59 | return true; 60 | } 61 | 62 | export function toArray(value: any): any[] { 63 | let ret = value; 64 | if (value === undefined || value === null) { 65 | ret = []; 66 | } else if (!Array.isArray(value)) { 67 | ret = [value]; 68 | } 69 | return ret; 70 | } 71 | 72 | 73 | export function toArrayBuffer(binary: any): ArrayBuffer { 74 | const length = binary.length; 75 | const buf = new ArrayBuffer(length); 76 | const arr = new Uint8Array(buf); 77 | for (let i = 0; i < length; i++) { 78 | arr[i] = binary.charCodeAt(i); 79 | } 80 | return buf; 81 | } 82 | -------------------------------------------------------------------------------- /src/app/weui/css/README.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | - angular-weui.min.css 4 | 不包含微信WeUI的weui.min.css的代码,需要自己额外引入; 5 | - angular-weui.full.min.css 6 | 已包含微信WeUI的weui.min.css的代码,只引入该文件即可。 7 | 8 | -------------------------------------------------------------------------------- /src/app/weui/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | // This file is not used to build this module. It is only used during editing 10 | // by the TypeScript language service and during build for verification. `ngc` 11 | // replaces this file with production index.ts when it rewrites private symbol 12 | // names. 13 | 14 | export * from './public_api'; 15 | -------------------------------------------------------------------------------- /src/app/weui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular4-weui", 3 | "version": "0.0.0-PLACEHOLDER", 4 | "license": "MIT", 5 | "author": "32674406@qq.com", 6 | "description": "Angular4-WeUI - a development UI library for building mobile web applications with Angular", 7 | "keywords": ["angular-weui", "mobile", "framework", "webapp", "wechat"], 8 | "private": false, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/fbchen/angular4-weui.git" 12 | }, 13 | "main": "./bundles/index.umd.js", 14 | "module": "./es2015/index.es5.js", 15 | "es2015": "./es2015/index.js", 16 | "typings": "./index.d.ts" 17 | } 18 | -------------------------------------------------------------------------------- /src/app/weui/public_api.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | 10 | /** 11 | * @module 12 | * @description 13 | * Entry point for all public APIs of the weui package. 14 | */ 15 | export * from './src/weui'; 16 | 17 | // This file only reexports content of the `src` folder. Keep it that way. 18 | -------------------------------------------------------------------------------- /src/app/weui/rollup.config.js: -------------------------------------------------------------------------------- 1 | // import rollup from 'rollup'; 2 | import nodeResolve from 'rollup-plugin-node-resolve'; 3 | import commonjs from 'rollup-plugin-commonjs'; 4 | import { uglify } from 'rollup-plugin-uglify'; 5 | 6 | export default { 7 | input: '../../../dist/publish-dist/angular-weui/es2015/index.es5.js', 8 | output: { 9 | file: '../../../dist/publish-dist/angular-weui/bundles/index.umd.js', 10 | format: 'umd', 11 | sourcemap: false, 12 | name: 'angular.weui', 13 | exports: 'named', 14 | globals: { 15 | '@angular/core': 'ng.core', 16 | '@angular/common': 'ng.common', 17 | '@angular/forms': 'ng.forms', 18 | 'rxjs/Observable': 'Rx', 19 | 'rxjs/Subject': 'Rx', 20 | 'rxjs/add/operator/debounceTime': 'Rx.Observable.prototype', 21 | 'rxjs/add/operator/distinctUntilChanged': 'Rx.Observable.prototype' 22 | } 23 | }, 24 | onwarn: function (warning) { 25 | // Suppress this error message... there are hundreds of them. Angular team says to ignore it. 26 | // https://github.com/rollup/rollup/wiki/Troubleshooting#this-is-undefined 27 | if (warning.code === 'THIS_IS_UNDEFINED') { 28 | return; 29 | } 30 | // intercepts in some rollup versions 31 | if ( warning.message.indexOf("The 'this' keyword is equivalent to 'undefined'") > -1 ) { 32 | return; 33 | } 34 | console.error(warning.message); 35 | }, 36 | plugins: [ 37 | nodeResolve({ 38 | 39 | // the fields to scan in a package.json to determine the entry point 40 | // if this list contains "browser", overrides specified in "pkg.browser" 41 | // will be used 42 | mainFields: ['module', 'main', 'jsnext'], 43 | 44 | // some package.json files have a "browser" field which specifies 45 | // alternative files to load for people bundling for the browser. If 46 | // that's you, either use this option or add "browser" to the 47 | // "mainfields" option, otherwise pkg.browser will be ignored 48 | browser: true 49 | }), 50 | commonjs({ 51 | include: '../../../node_modules/**' 52 | }), 53 | uglify() 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /src/app/weui/sass/_mixins.scss: -------------------------------------------------------------------------------- 1 | 2 | /** --- weui-btn --- */ 3 | @mixin weui-btn-default($color-name, $color-base, $color-contrast) { 4 | $bg-color: $color-base; 5 | $bg-color-activated: color-shade($bg-color); 6 | $bg-color-disabled: color-shade($bg-color, 50%); 7 | 8 | .weui-btn_#{$color-name} { 9 | background-color: $bg-color; 10 | } 11 | .weui-btn_#{$color-name}:not(.weui-btn_disabled):active { 12 | color: rgba(255, 255, 255, 0.6); 13 | background-color: $bg-color-activated; 14 | } 15 | .weui-btn_disabled.weui-btn_#{$color-name} { 16 | background-color: $bg-color-disabled; 17 | } 18 | .weui-btn_loading.weui-btn_#{$color-name} { 19 | background-color: $bg-color-activated; 20 | } 21 | 22 | .weui-btn_plain-#{$color-name} { 23 | color: $bg-color; 24 | border: 1px solid $color-base; 25 | } 26 | .weui-btn_plain-#{$color-name}:not(.weui-btn_plain-disabled):active { 27 | color: $bg-color-activated; 28 | border-color: $bg-color-activated; 29 | } 30 | } 31 | 32 | /** --- weui-text-counter --- */ 33 | @mixin weui-text-counter($color-name, $color-base, $color-contrast) { 34 | .weui-cell_#{$color-name} .weui-text-counter { 35 | color: $color-base; 36 | } 37 | } 38 | 39 | /** --- weui-slider --- */ 40 | @mixin weui-slider($color-name, $color-base, $color-contrast) { 41 | .weui-slider_#{$color-name} .weui-slider__track { 42 | background-color: $color-base; 43 | } 44 | } 45 | 46 | /** --- weui-progress --- */ 47 | @mixin weui-progress($color-name, $color-base, $color-contrast) { 48 | .weui-progress_#{$color-name} .weui-progress__inner-bar { 49 | background-color: $color-base; 50 | } 51 | } 52 | 53 | /** --- weui-badge --- */ 54 | @mixin weui-badge($color-name, $color-base, $color-contrast) { 55 | .weui-badge_#{$color-name} { 56 | background-color: $color-base; 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/app/weui/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Variables 3 | // -------------------------------------------------- 4 | 5 | $font-size-base: 62.5% !default; 6 | 7 | $colors: ( 8 | primary: #1AAD19, 9 | warn: #E64340 10 | ) !default; 11 | -------------------------------------------------------------------------------- /src/app/weui/src/badge/weui.badge.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, ElementRef, Renderer2, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | import { toBoolean } from '../util/lang'; 12 | 13 | /** 14 | * 徽章 15 | */ 16 | @Component({ 17 | selector: 'weui-badge', 18 | preserveWhitespaces: false, 19 | providers: [ UpdateClassService ], 20 | template: `` 21 | }) 22 | export class WeUIBadge implements OnInit { 23 | 24 | /** 25 | * 颜色,取值:default、primary、warn等。默认为default。
26 | * 自定义的颜色名称与色值,可以定义在 工程根目录/src/theme/variables.scss 文件中的 $colors 对象。 27 | */ 28 | @Input() 29 | get color(): string { 30 | return this._color; 31 | } 32 | set color(color: string) { 33 | if (this._color !== color) { 34 | this._color = color; 35 | this.updateClassMap(); 36 | } 37 | } 38 | private _color = 'default'; 39 | 40 | 41 | /** 不展示数字,只有一个小红点。 whether to show red dot without number */ 42 | @Input() 43 | get dot(): boolean { 44 | return this._dot; 45 | } 46 | set dot(dot: boolean) { 47 | const value = toBoolean(dot); 48 | if (this._dot !== value) { 49 | this._dot = value; 50 | this.updateClassMap(); 51 | } 52 | } 53 | private _dot = false; 54 | 55 | 56 | constructor( 57 | protected renderer: Renderer2, 58 | protected el: ElementRef, 59 | protected updateClassService: UpdateClassService) { 60 | 61 | } 62 | 63 | ngOnInit(): void { 64 | this.updateClassMap(); 65 | } 66 | 67 | private updateClassMap(): void { 68 | const classes = { 69 | [`weui-badge`]: true, 70 | [`weui-badge_dot`]: this.dot, 71 | [`weui-badge_${this.color}`]: this.color 72 | }; 73 | this.updateClassService.update(this.el.nativeElement, classes); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/app/weui/src/core/anim.frame.ts: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 下一帧执行回调函数 4 | * 5 | * @param callback Function 6 | */ 7 | export function onNextFrame(callback: FrameRequestCallback): number { 8 | if (window.requestAnimationFrame) { 9 | return window.requestAnimationFrame(callback); 10 | } 11 | return window.setTimeout(callback, 1); 12 | } 13 | 14 | /** 15 | * 清除执行任务 16 | * 17 | * @param nextFrameId 任务ID 18 | */ 19 | export function clearNextFrameAction(nextFrameId: number): void { 20 | if (window.cancelAnimationFrame) { 21 | window.cancelAnimationFrame(nextFrameId); 22 | } else { 23 | window.clearTimeout(nextFrameId); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/app/weui/src/core/errors/error.ts: -------------------------------------------------------------------------------- 1 | // TODO(kara): Revisit why error messages are not being properly set. 2 | 3 | /** 4 | * Wrapper around Error that sets the error message. 5 | * @docs-private 6 | */ 7 | export class WeUIError extends Error { 8 | constructor(value: string) { 9 | super(); 10 | this.message = value; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/app/weui/src/core/service/update.class.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { replaceClass } from '../../util/classnames'; 3 | 4 | /** 5 | * 用于更新Host组件的样式 6 | */ 7 | @Injectable() 8 | export class UpdateClassService { 9 | 10 | private classMap: any; 11 | 12 | /** 13 | * 更新Host组件的样式 14 | * @param el HOST组件的Element 15 | * @param newClass 新的样式,可以是string, object等 16 | */ 17 | update(el: HTMLElement, newClass: any): void { 18 | replaceClass(el, newClass, this.classMap); 19 | this.classMap = newClass; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/app/weui/src/footer/weui.footer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Renderer2, ElementRef, Directive, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | import { toBoolean } from '../util/lang'; 12 | 13 | 14 | /** 15 | * 页脚 16 | */ 17 | @Component({ 18 | selector: 'weui-footer,[weui-footer]', 19 | preserveWhitespaces: false, 20 | providers: [ UpdateClassService ], 21 | template: '' 22 | }) 23 | export class WeUIFooter implements OnInit { 24 | 25 | /** 26 | * 固定在底部 27 | */ 28 | @Input() 29 | get fixedAtBottom(): boolean { 30 | return this._fixedAtBottom; 31 | } 32 | set fixedAtBottom(fixedAtBottom: boolean) { 33 | const value = toBoolean(fixedAtBottom); 34 | if (this._fixedAtBottom !== value) { 35 | this._fixedAtBottom = value; 36 | this.updateClassMap(); 37 | } 38 | } 39 | private _fixedAtBottom = false; 40 | 41 | 42 | constructor( 43 | protected renderer: Renderer2, 44 | protected el: ElementRef, 45 | protected updateClassService: UpdateClassService) { 46 | 47 | } 48 | 49 | ngOnInit(): void { 50 | this.updateClassMap(); 51 | } 52 | 53 | private updateClassMap(): void { 54 | const classes = { 55 | [`weui-footer`]: true, 56 | [`weui-footer_fixed-bottom`]: this.fixedAtBottom 57 | }; 58 | this.updateClassService.update(this.el.nativeElement, classes); 59 | } 60 | 61 | } 62 | 63 | @Directive({ 64 | // tslint:disable-next-line:directive-selector 65 | selector: `weui-footer-text, [weui-footer-text]` 66 | }) 67 | export class WeUIFooterText { 68 | 69 | constructor( 70 | protected renderer: Renderer2, 71 | protected elementRef: ElementRef) { 72 | renderer.addClass(elementRef.nativeElement, 'weui-footer__text'); 73 | } 74 | 75 | } 76 | 77 | @Directive({ 78 | // tslint:disable-next-line:directive-selector 79 | selector: `weui-footer-links, [weui-footer-links]` 80 | }) 81 | export class WeUIFooterLinks { 82 | 83 | constructor( 84 | protected renderer: Renderer2, 85 | protected elementRef: ElementRef) { 86 | renderer.addClass(elementRef.nativeElement, 'weui-footer__links'); 87 | } 88 | 89 | } 90 | 91 | @Directive({ 92 | // tslint:disable-next-line:directive-selector 93 | selector: `a[weui-footer-link]` 94 | }) 95 | export class WeUIFooterLink { 96 | 97 | constructor( 98 | protected renderer: Renderer2, 99 | protected elementRef: ElementRef) { 100 | renderer.addClass(elementRef.nativeElement, 'weui-footer__link'); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/app/weui/src/form/abstract.form.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Optional, Self, Input } from '@angular/core'; 10 | import { NgForm } from '@angular/forms'; 11 | 12 | 13 | import { FieldMessage, FieldMessages, MessageFormater } from './message.formater'; 14 | 15 | /** 16 | * 提供了表单验证的统一方法:validate() 17 | * 18 | * @author fbchen 19 | * @version 1.0 2016-11-26 20 | */ 21 | export abstract class AbstractForm { 22 | 23 | /** 自定义错误消息 */ 24 | @Input() messages: FieldMessages = {}; 25 | 26 | /** 验证结果,例如: [{username: '必须填写'}, {password: '输入非法'}] */ 27 | protected formErrors: FieldMessage[] = []; 28 | 29 | private messageFormatter = new MessageFormater(); 30 | 31 | constructor( @Optional() @Self() protected form: NgForm) { 32 | form.ngSubmit.subscribe(this.onSubmit.bind(this)); 33 | } 34 | 35 | /** Form验证后,自动执行消息提示匹配 */ 36 | onSubmit(): void { 37 | this.validate(); 38 | } 39 | 40 | 41 | public validateControl(name: string): void { 42 | this.formErrors = this.formErrors.filter(e => e.name !== name); 43 | const control = this.form.controls[name]; 44 | 45 | const errors = control && control.errors || {}; 46 | if (control && control.invalid && (control.dirty || this.form.submitted)) { 47 | const messages = (this.messages && this.messages[name]) || {}; 48 | const message = this.messageFormatter.getMessage(errors, messages); 49 | this.formErrors.push({ name, message }); 50 | } 51 | } 52 | 53 | validateControlOnDirty(name: string): void { 54 | const c = this.form.controls[name]; 55 | if (c && ((c.dirty && c.touched) || this.isSubmitted())) { 56 | this.validateControl(name); 57 | } 58 | } 59 | 60 | /** 61 | * 验证表单,结果存入formErrors 62 | * 63 | * @return 验证结果: true-success, false-fail 64 | */ 65 | public validate(): boolean | null { 66 | const form: NgForm = this.form; 67 | for (const name in form.controls) { 68 | if (form.controls.hasOwnProperty(name)) { 69 | this.validateControl(name); 70 | } 71 | } 72 | return form.valid; 73 | } 74 | 75 | /** 是否已submitted */ 76 | public isSubmitted(): boolean { 77 | return this.form.submitted; 78 | } 79 | 80 | /** 81 | * 是否存在错误 82 | * 83 | * @param name 指定控件的名称,可选。若为空则检查表单是否存在错误。 84 | */ 85 | public hasError(name?: string): boolean { 86 | if (name) { 87 | // 对控件单独校验 88 | this.validateControlOnDirty(name); 89 | return this.getError(name) !== null; 90 | } 91 | return this.formErrors.length > 0; 92 | } 93 | 94 | /** 95 | * 当存在多个错误消息时,用此方法获取其中的第一个非空错误显示 96 | */ 97 | public firstError(): string | null { 98 | const err = this.formErrors[0]; 99 | return (err && err.message) || null; 100 | } 101 | 102 | /** 103 | * 获取控件的一个错误 104 | * 105 | * @param name 控件name 106 | * @return 控件错误消息,或者空(没有错误) 107 | */ 108 | public getError(name: string): string | null { 109 | const err = this.formErrors.find(e => e.name === name); 110 | return (err && err.message) || null; 111 | } 112 | 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/app/weui/src/gallery/weui.gallery.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Output, EventEmitter, ElementRef, Renderer2, OnInit, HostBinding, HostListener } from '@angular/core'; 10 | import { animate, state, style, transition, trigger } from '@angular/animations'; 11 | import { WeUIFile } from '../uploader/weui.uploader'; 12 | import { UpdateClassService } from '../core/service/update.class.service'; 13 | 14 | @Component({ 15 | selector: 'weui-gallery,[weui-gallery]', 16 | preserveWhitespaces: false, 17 | providers: [ UpdateClassService ], 18 | template: ` 19 | 20 | 25 | `, 26 | animations: [ 27 | trigger('visibility', [ 28 | state('show', style({ opacity: 1 })), 29 | state('hide', style({ opacity: 0 })), 30 | transition('hide <=> show', [animate(200)]) 31 | ]) 32 | ] 33 | }) 34 | export class WeUIGallery implements OnInit { 35 | 36 | /** 37 | * 背景图片,如:url(./images/pic_160.png) 38 | */ 39 | @Input() image: WeUIFile; 40 | 41 | /** 42 | * 是否显示删除按钮 43 | */ 44 | @Input() canDelete = true; 45 | 46 | /** 47 | * 删除事件 48 | */ 49 | @Output() delete = new EventEmitter(); 50 | 51 | /** 52 | * 已显示否 53 | */ 54 | public shown = false; 55 | 56 | constructor( 57 | protected renderer: Renderer2, 58 | protected el: ElementRef, 59 | protected updateClassService: UpdateClassService) { 60 | 61 | } 62 | 63 | /** 64 | * 用于控制动画的触发(trigger) 65 | */ 66 | @HostBinding('@visibility') get visibility(): string { 67 | return this.shown ? 'show' : 'hide'; 68 | } 69 | 70 | @HostListener('@visibility.done') 71 | onVisibleChange(): void { 72 | if (!this.shown) { 73 | this.renderer.setStyle(this.el.nativeElement, 'display', 'none'); 74 | } 75 | } 76 | 77 | ngOnInit(): void { 78 | this.updateClassMap(); 79 | } 80 | 81 | private updateClassMap(): void { 82 | const classes = { 83 | [`weui-gallery`]: true, 84 | [`weui-transition-opacity`]: true 85 | }; 86 | this.updateClassService.update(this.el.nativeElement, classes); 87 | } 88 | 89 | 90 | /** 删除照片 */ 91 | deleteImage(event: Event): void { 92 | this.delete.emit(this.image); 93 | event.preventDefault(); 94 | } 95 | 96 | /** 显示图片 */ 97 | show(): void { 98 | this.renderer.setStyle(this.el.nativeElement, 'display', 'block'); 99 | this.shown = true; 100 | } 101 | 102 | /** 隐藏图片 */ 103 | hide(): void { 104 | this.shown = false; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/app/weui/src/input/weui.checkbox.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Renderer2, ElementRef, forwardRef, Optional, Inject, OnInit } from '@angular/core'; 10 | import { DefaultValueAccessor, NG_VALUE_ACCESSOR, COMPOSITION_BUFFER_MODE } from '@angular/forms'; 11 | import { UpdateClassService } from '../core/service/update.class.service'; 12 | import { toArray } from '../util/lang'; 13 | 14 | const WEUI_FORM_CONTROL_VALUE_ACCESSOR: any = { 15 | provide: NG_VALUE_ACCESSOR, 16 | useExisting: forwardRef(() => WeUICheckbox), 17 | multi: true 18 | }; 19 | 20 | @Component({ 21 | selector: 'weui-checkbox', 22 | preserveWhitespaces: false, 23 | providers: [ UpdateClassService, WEUI_FORM_CONTROL_VALUE_ACCESSOR ], 24 | template: ` 25 | 35 | ` 36 | }) 37 | export class WeUICheckbox extends DefaultValueAccessor implements OnInit { 38 | public static count = 0; 39 | 40 | @Input() id: string; 41 | 42 | @Input() name: string; 43 | 44 | @Input() value: any = 'on'; 45 | 46 | /** 47 | * 控件 label 48 | */ 49 | @Input() label: string; 50 | 51 | /** 52 | * 是否禁用 53 | */ 54 | @Input() disabled = false; 55 | 56 | /** 选中的值(可以多选,因此存储为数组) */ 57 | private values: any[] = []; 58 | 59 | /** 是否已选中 */ 60 | public get checked(): boolean { 61 | return this._checked; 62 | } 63 | public set checked(checked: boolean) { 64 | this._checked = checked; 65 | this.emitValue(); 66 | } 67 | private _checked = false; 68 | 69 | constructor( 70 | protected renderer: Renderer2, 71 | protected el: ElementRef, 72 | protected updateClassService: UpdateClassService, 73 | @Optional() @Inject(COMPOSITION_BUFFER_MODE) protected compositionMode: boolean) { 74 | super(renderer, el, compositionMode); 75 | this.id = `weui-checkbox-${++WeUICheckbox.count}`; 76 | } 77 | 78 | ngOnInit(): void { 79 | this.updateClassMap(); 80 | } 81 | 82 | private updateClassMap(): void { 83 | const classes = { 84 | [`weui-cell`]: 1, 85 | [`weui-check__label`]: 1 86 | }; 87 | this.updateClassService.update(this.el.nativeElement, classes); 88 | } 89 | 90 | /** 91 | * Write a new value to the element. (From ControlValueAccessor interface) 92 | */ 93 | writeValue(value: any): void { 94 | this.values = toArray(value); 95 | this._checked = this.values.indexOf(this.value) >= 0; 96 | } 97 | 98 | /** 勾选框的选择状态发生变化时,发射出实际值 */ 99 | emitValue(): void { 100 | const index = this.values.indexOf(this.value); 101 | if (this.checked && index === -1) { 102 | this.values.push(this.value); 103 | } else if (!this.checked && index >= 0) { 104 | this.values.splice(index, 1); 105 | } 106 | // view -> model -> outside world (ie. NgModel on this control) 107 | this.onChange(this.values); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/app/weui/src/input/weui.radio.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Renderer2, ElementRef, forwardRef, Optional, Inject, OnInit } from '@angular/core'; 10 | import { DefaultValueAccessor, NG_VALUE_ACCESSOR, COMPOSITION_BUFFER_MODE } from '@angular/forms'; 11 | import { UpdateClassService } from '../core/service/update.class.service'; 12 | 13 | const WEUI_FORM_CONTROL_VALUE_ACCESSOR: any = { 14 | provide: NG_VALUE_ACCESSOR, 15 | useExisting: forwardRef(() => WeUIRadio), 16 | multi: true 17 | }; 18 | 19 | @Component({ 20 | selector: 'weui-radio', 21 | preserveWhitespaces: false, 22 | providers: [ UpdateClassService, WEUI_FORM_CONTROL_VALUE_ACCESSOR ], 23 | template: ` 24 | 35 | ` 36 | }) 37 | export class WeUIRadio extends DefaultValueAccessor implements OnInit { 38 | 39 | public static count = 0; 40 | 41 | @Input() id: string; 42 | 43 | @Input() name: string; 44 | 45 | @Input() value: any = 'on'; 46 | 47 | /** 48 | * 控件 label 49 | */ 50 | @Input() label: string; 51 | 52 | /** 53 | * 是否禁用 54 | */ 55 | @Input() disabled = false; 56 | 57 | /** 是否已选中 */ 58 | public get checkedValue(): string { 59 | return this._checkedValue; 60 | } 61 | public set checkedValue(checkedValue: string) { 62 | this._checkedValue = checkedValue; 63 | this.emitValue(); 64 | } 65 | private _checkedValue: string; 66 | 67 | 68 | constructor( 69 | protected renderer: Renderer2, 70 | protected el: ElementRef, 71 | protected updateClassService: UpdateClassService, 72 | @Optional() @Inject(COMPOSITION_BUFFER_MODE) protected compositionMode: boolean) { 73 | super(renderer, el, compositionMode); 74 | this.id = `weui-radio-${++WeUIRadio.count}`; 75 | } 76 | 77 | ngOnInit(): void { 78 | this.updateClassMap(); 79 | } 80 | 81 | private updateClassMap(): void { 82 | const classes = { 83 | [`weui-cell`]: 1, 84 | [`weui-check__label`]: 1 85 | }; 86 | this.updateClassService.update(this.el.nativeElement, classes); 87 | } 88 | 89 | /** 90 | * Write a new value to the element. (From ControlValueAccessor interface) 91 | */ 92 | writeValue(value: any): void { 93 | this._checkedValue = value; 94 | } 95 | 96 | /** 勾选框的选择状态发生变化时,发射出实际值 */ 97 | emitValue(): void { 98 | if (this.checkedValue === this.value) { 99 | // view -> model -> outside world (ie. NgModel on this control) 100 | this.onChange(this.value); 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/app/weui/src/input/weui.select.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Directive, Renderer2, ElementRef } from '@angular/core'; 10 | 11 | @Directive({ 12 | // tslint:disable-next-line:directive-selector 13 | selector: 'select[weui-select]' 14 | }) 15 | export class WeUISelect { 16 | 17 | constructor( 18 | public renderer: Renderer2, 19 | public el: ElementRef) { 20 | this.updateClasses(); 21 | } 22 | 23 | getHostElement(): HTMLElement { 24 | return this.el.nativeElement as HTMLElement; 25 | } 26 | 27 | updateClasses(): void { 28 | const nativeEl = this.el.nativeElement as HTMLElement; 29 | this.renderer.addClass(nativeEl, 'weui-select'); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/app/weui/src/input/weui.switch.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Renderer2, ElementRef, forwardRef, Optional, Inject, OnInit } from '@angular/core'; 10 | import { DefaultValueAccessor, NG_VALUE_ACCESSOR, COMPOSITION_BUFFER_MODE } from '@angular/forms'; 11 | import { UpdateClassService } from '../core/service/update.class.service'; 12 | 13 | 14 | const WEUI_FORM_CONTROL_VALUE_ACCESSOR: any = { 15 | provide: NG_VALUE_ACCESSOR, 16 | useExisting: forwardRef(() => WeUISwitch), 17 | multi: true 18 | }; 19 | 20 | @Component({ 21 | selector: 'weui-switch', 22 | preserveWhitespaces: false, 23 | providers: [ UpdateClassService, WEUI_FORM_CONTROL_VALUE_ACCESSOR ], 24 | template: ` 25 |
26 | {{label}} 27 |
28 |
29 | 34 |
35 | ` 36 | }) 37 | export class WeUISwitch extends DefaultValueAccessor implements OnInit { 38 | public static count = 0; 39 | 40 | @Input() id: string; 41 | 42 | @Input() name: string; 43 | 44 | @Input() value: any = 'on'; 45 | 46 | /** 47 | * 控件 label 48 | */ 49 | @Input() label: string; 50 | 51 | /** 52 | * 是否禁用 53 | */ 54 | @Input() disabled = false; 55 | 56 | /** 是否已选中 */ 57 | public get checked(): boolean { 58 | return this._checked; 59 | } 60 | public set checked(checked: boolean) { 61 | this._checked = checked; 62 | this.emitValue(); 63 | } 64 | private _checked = false; 65 | 66 | constructor( 67 | protected renderer: Renderer2, 68 | protected el: ElementRef, 69 | protected updateClassService: UpdateClassService, 70 | @Optional() @Inject(COMPOSITION_BUFFER_MODE) protected compositionMode: boolean) { 71 | super(renderer, el, compositionMode); 72 | this.id = `weui-switch-${++WeUISwitch.count}`; 73 | } 74 | 75 | ngOnInit(): void { 76 | this.updateClassMap(); 77 | } 78 | 79 | private updateClassMap(): void { 80 | const classes = { 81 | [`weui-cell`]: 1, 82 | [`weui-cell_switch`]: 1 83 | }; 84 | this.updateClassService.update(this.el.nativeElement, classes); 85 | } 86 | 87 | /** 88 | * Write a new value to the element. (From ControlValueAccessor interface) 89 | */ 90 | writeValue(value: any): void { 91 | this.checked = this.value === value; 92 | } 93 | 94 | /** 勾选框的选择状态发生变化时,发射出实际值 */ 95 | emitValue(): void { 96 | const value = this.checked ? this.value : null; 97 | // view -> model -> outside world (ie. NgModel on this control) 98 | this.onChange(value); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/app/weui/src/list/weui.item.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Renderer2, ElementRef, OnInit, AfterContentInit, ContentChildren, QueryList } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | import { WeUISelect } from '../input/weui.select'; 12 | 13 | @Component({ 14 | selector: 'weui-item,[weui-item]', 15 | preserveWhitespaces: false, 16 | providers: [UpdateClassService], 17 | template: ` 18 |
19 | 20 |
21 |
22 | 23 | 24 |
25 |
26 | 27 |
28 | ` 29 | }) 30 | export class WeUIItem implements OnInit, AfterContentInit { 31 | 32 | /** 样式 */ 33 | @Input() 34 | get baseCls(): string { 35 | return this._baseCls; 36 | } 37 | set baseCls(baseCls: string) { 38 | if (this._baseCls !== baseCls) { 39 | this._baseCls = baseCls; 40 | this.updateClassMap(); 41 | } 42 | } 43 | private _baseCls: string; 44 | 45 | 46 | /** 选择控件 */ 47 | @ContentChildren(WeUISelect) selects: QueryList; 48 | 49 | 50 | constructor( 51 | protected renderer: Renderer2, 52 | protected el: ElementRef, 53 | protected updateClassService: UpdateClassService) { 54 | } 55 | 56 | getHostElement(): HTMLElement { 57 | return this.el.nativeElement as HTMLElement; 58 | } 59 | 60 | ngOnInit(): void { 61 | this.updateClassMap(); 62 | } 63 | 64 | private updateClassMap(): void { 65 | const classes = { 66 | [`weui-cell`]: 1, 67 | [`weui-item`]: 1, 68 | [`weui-cell_${this.baseCls}`]: this.baseCls 69 | }; 70 | this.updateClassService.update(this.el.nativeElement, classes); 71 | } 72 | 73 | // 存在选择控件,需特殊处理 74 | ngAfterContentInit(): void { 75 | if (this.selects && this.selects.length) { 76 | this.addClass('weui-cell_select'); 77 | 78 | const hostEl = this.getHostElement(); 79 | this.selects.forEach(sel => { 80 | const selEl = sel.getHostElement(); 81 | if (selEl.hasAttribute('weui-start')) { 82 | this.addClass('weui-cell_select-before'); 83 | } 84 | if (selEl.hasAttribute('weui-content') && hostEl.querySelectorAll('[weui-start]').length) { 85 | this.addClass('weui-cell_select-after'); 86 | } 87 | }); 88 | } 89 | } 90 | 91 | addClass(cls: string): void { 92 | this.renderer.addClass(this.el.nativeElement, cls); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/app/weui/src/list/weui.items.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, ElementRef, Renderer2, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | 12 | 13 | @Component({ 14 | selector: 'weui-items,[weui-items]', 15 | preserveWhitespaces: false, 16 | providers: [ UpdateClassService ], 17 | template: `` 18 | }) 19 | export class WeUIItems implements OnInit { 20 | 21 | /** 22 | * 控件样式,如:'form'对应的样式类为'weui-cells_form' 23 | */ 24 | @Input() 25 | get baseCls(): string { 26 | return this._baseCls; 27 | } 28 | set baseCls(baseCls: string) { 29 | if (this._baseCls !== baseCls) { 30 | this._baseCls = baseCls; 31 | this.updateClassMap(); 32 | } 33 | } 34 | private _baseCls: string; 35 | 36 | 37 | constructor( 38 | protected renderer: Renderer2, 39 | protected el: ElementRef, 40 | protected updateClassService: UpdateClassService) { 41 | 42 | } 43 | 44 | ngOnInit(): void { 45 | this.updateClassMap(); 46 | } 47 | 48 | private updateClassMap(): void { 49 | const classes = { 50 | [`weui-cells`]: true, 51 | [`weui-cells_${this.baseCls}`]: this.baseCls 52 | }; 53 | this.updateClassService.update(this.el.nativeElement, classes); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/app/weui/src/list/weui.link.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, ElementRef, Renderer2, OnInit } from '@angular/core'; 10 | import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; 11 | import { UpdateClassService } from '../core/service/update.class.service'; 12 | import { toBoolean } from '../util/lang'; 13 | 14 | @Component({ 15 | selector: 'weui-link', 16 | preserveWhitespaces: false, 17 | providers: [ UpdateClassService ], 18 | template: ` 19 | 20 |
21 | 22 |
23 |
24 | 25 | 26 |
27 |
28 | 29 |
30 |
31 | ` 32 | }) 33 | export class WeUILink implements OnInit { 34 | 35 | /** 36 | * 不显示最右边的箭头。默认为false,即:显示箭头。 37 | */ 38 | @Input() 39 | get noPushArrow(): boolean { 40 | return this._noPushArrow; 41 | } 42 | set noPushArrow(noPushArrow: boolean) { 43 | const value = toBoolean(noPushArrow); 44 | if (this._noPushArrow !== value) { 45 | this._noPushArrow = value; 46 | this.updateClassMap(); 47 | } 48 | } 49 | private _noPushArrow = false; 50 | 51 | /** 52 | * 样式 53 | */ 54 | @Input() 55 | get baseCls(): string { 56 | return this._baseCls; 57 | } 58 | set baseCls(baseCls: string) { 59 | if (this._baseCls !== baseCls) { 60 | this._baseCls = baseCls; 61 | this.updateClassMap(); 62 | } 63 | } 64 | private _baseCls: string; 65 | 66 | /** 67 | * 链接 68 | */ 69 | @Input() set href(href: string | SafeUrl) { 70 | if (typeof href === 'string') { 71 | this._href = this.sanitizer.bypassSecurityTrustUrl(href); 72 | } else { 73 | this._href = href; 74 | } 75 | } 76 | public _href: SafeUrl = this.sanitizer.bypassSecurityTrustUrl('javascript:;'); 77 | 78 | constructor( 79 | protected renderer: Renderer2, 80 | protected el: ElementRef, 81 | protected updateClassService: UpdateClassService, 82 | private sanitizer: DomSanitizer) { 83 | 84 | } 85 | 86 | ngOnInit(): void { 87 | this.updateClassMap(); 88 | } 89 | 90 | private updateClassMap(): void { 91 | const classes = { 92 | [`weui-cell`]: true, 93 | [`weui-item`]: true, 94 | [`weui-cell_access`]: true, 95 | [`weui-cell_access-noarrow`]: this.noPushArrow, 96 | [`weui-cell_${this.baseCls}`]: this.baseCls 97 | }; 98 | this.updateClassService.update(this.el.nativeElement, classes); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/app/weui/src/list/weui.tips.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, Renderer2, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | 12 | @Component({ 13 | selector: 'weui-tips', 14 | preserveWhitespaces: false, 15 | providers: [ UpdateClassService ], 16 | template: `` 17 | }) 18 | export class WeUITips implements OnInit { 19 | 20 | constructor( 21 | protected renderer: Renderer2, 22 | protected el: ElementRef, 23 | protected updateClassService: UpdateClassService) { 24 | 25 | } 26 | 27 | ngOnInit(): void { 28 | this.updateClassMap(); 29 | } 30 | 31 | private updateClassMap(): void { 32 | const classes = { 33 | [`weui-cells__tips`]: true 34 | }; 35 | this.updateClassService.update(this.el.nativeElement, classes); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/app/weui/src/list/weui.title.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, Renderer2, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | 12 | @Component({ 13 | selector: 'weui-title', 14 | preserveWhitespaces: false, 15 | providers: [ UpdateClassService ], 16 | template: `` 17 | }) 18 | export class WeUITitle implements OnInit { 19 | 20 | constructor( 21 | protected renderer: Renderer2, 22 | protected el: ElementRef, 23 | protected updateClassService: UpdateClassService) { 24 | 25 | } 26 | 27 | ngOnInit(): void { 28 | this.updateClassMap(); 29 | } 30 | 31 | private updateClassMap(): void { 32 | const classes = { 33 | [`weui-cells__title`]: true 34 | }; 35 | this.updateClassService.update(this.el.nativeElement, classes); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/app/weui/src/loadmore/weui.loadmore.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, ElementRef, Renderer2, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | import { toBoolean } from '../util/lang'; 12 | 13 | /** 14 | * 加载更多 15 | */ 16 | @Component({ 17 | selector: 'weui-loadmore', 18 | preserveWhitespaces: false, 19 | providers: [ UpdateClassService ], 20 | template: ` 21 | 22 | 23 | {{loadingText}} 24 | 25 | `, 26 | styles: [` 27 | :host { display: block; } 28 | `] 29 | }) 30 | export class WeUILoadmore implements OnInit { 31 | 32 | /** 显示为分割线 */ 33 | @Input() 34 | get line(): boolean { 35 | return this._line; 36 | } 37 | set line(line: boolean) { 38 | const value = toBoolean(line); 39 | if (this._line !== value) { 40 | this._line = value; 41 | this.updateClassMap(); 42 | } 43 | } 44 | private _line = false; 45 | 46 | /** 不展示文字,只有一个小点 */ 47 | @Input() 48 | get dot(): boolean { 49 | return this._dot; 50 | } 51 | set dot(dot: boolean) { 52 | const value = toBoolean(dot); 53 | if (this._dot !== value) { 54 | this._dot = value; 55 | this.updateClassMap(); 56 | } 57 | } 58 | private _dot = false; 59 | 60 | /** 是否正在加载 */ 61 | @Input() 62 | get loading(): boolean { 63 | return this._loading; 64 | } 65 | set loading(loading: boolean) { 66 | const value = toBoolean(loading); 67 | if (this._loading !== value) { 68 | this._loading = value; 69 | this.updateClassMap(); 70 | } 71 | } 72 | private _loading = false; 73 | 74 | /** 加载中显示文本,默认为空,即不显示 */ 75 | @Input() loadingText: string; 76 | 77 | 78 | constructor( 79 | protected renderer: Renderer2, 80 | protected el: ElementRef, 81 | protected updateClassService: UpdateClassService) { 82 | 83 | } 84 | 85 | ngOnInit(): void { 86 | this.updateClassMap(); 87 | } 88 | 89 | private updateClassMap(): void { 90 | const classes = { 91 | [`weui-loadmore`]: true, 92 | [`weui-loadmore_line`]: this.line, 93 | [`weui-loadmore_dot`]: this.dot, 94 | [`weui-loadmore_loading`]: this.loading 95 | }; 96 | this.updateClassService.update(this.el.nativeElement, classes); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/app/weui/src/navbar/weui.navbar.item.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Host, Input, ElementRef, Renderer2, HostListener, Optional, Inject, forwardRef, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | 12 | import { WeUINavBar } from './weui.navbar'; 13 | 14 | @Component({ 15 | // tslint:disable-next-line:directive-selector 16 | selector: 'weui-navbar-item,[weui-navbar-item]', 17 | preserveWhitespaces: false, 18 | providers: [ UpdateClassService ], 19 | template: `` 20 | }) 21 | export class WeUINavBarItem implements OnInit { 22 | 23 | /** 24 | * 任意值,当激活时传递给父级控件 25 | */ 26 | @Input() value: any; 27 | 28 | // 用于设置激活样式 29 | public get activated(): boolean { 30 | return this._activated; 31 | } 32 | public set activated(activated: boolean) { 33 | this._activated = activated; 34 | this.updateClassMap(); 35 | } 36 | private _activated = false; 37 | 38 | /** 39 | * 点击触发激活 40 | * 41 | * @param event 点击事件 42 | */ 43 | @HostListener('click', ['$event']) 44 | onClick(event: Event): void { 45 | if (this.navbar) { 46 | this.navbar.activate(this); 47 | } 48 | } 49 | 50 | constructor( 51 | protected renderer: Renderer2, 52 | protected el: ElementRef, 53 | protected updateClassService: UpdateClassService, 54 | @Optional() @Host() @Inject(forwardRef(() => WeUINavBar)) private navbar: WeUINavBar) { 55 | 56 | } 57 | 58 | ngOnInit(): void { 59 | this.updateClassMap(); 60 | } 61 | 62 | private updateClassMap(): void { 63 | const classes = { 64 | [`weui-navbar__item`]: true, 65 | [`weui-bar__item_on`]: this.activated 66 | }; 67 | this.updateClassService.update(this.el.nativeElement, classes); 68 | } 69 | 70 | /** 71 | * 由父级控件传入 72 | * 73 | * @param activated 激活状态 74 | */ 75 | activate(activated: boolean): void { 76 | this.activated = activated; 77 | } 78 | 79 | isActivated(): boolean { 80 | return this.activated; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/app/weui/src/navbar/weui.navbar.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { 10 | Component, Input, Output, EventEmitter, ElementRef, Renderer2, 11 | OnInit, AfterViewInit, ContentChildren, QueryList 12 | } from '@angular/core'; 13 | import { onNextFrame } from '../core/anim.frame'; 14 | import { UpdateClassService } from '../core/service/update.class.service'; 15 | 16 | import { WeUINavBarItem } from './weui.navbar.item'; 17 | 18 | @Component({ 19 | selector: 'weui-navbar,[weui-navbar]', 20 | preserveWhitespaces: false, 21 | providers: [ UpdateClassService ], 22 | template: `` 23 | }) 24 | export class WeUINavBar implements OnInit, AfterViewInit { 25 | 26 | /** 27 | * 初始激活的子对象 28 | */ 29 | @Input() activeIndex = 0; 30 | 31 | /** 内部子对象 */ 32 | @ContentChildren(WeUINavBarItem) items: QueryList; 33 | 34 | /** 35 | * 激活事件 36 | */ 37 | @Output() activated = new EventEmitter(); 38 | 39 | private _activated: any; 40 | 41 | constructor( 42 | protected renderer: Renderer2, 43 | protected el: ElementRef, 44 | protected updateClassService: UpdateClassService) { 45 | 46 | } 47 | 48 | ngOnInit(): void { 49 | this.updateClassMap(); 50 | } 51 | 52 | private updateClassMap(): void { 53 | const classes = { 54 | [`weui-navbar`]: true 55 | }; 56 | this.updateClassService.update(this.el.nativeElement, classes); 57 | } 58 | 59 | ngAfterViewInit(): void { 60 | onNextFrame(() => { 61 | this.activateAt(this.activeIndex); 62 | }); 63 | } 64 | 65 | getAt(index: number): WeUINavBarItem { 66 | return this.items.find((item: WeUINavBarItem, i: number) => i === index) as WeUINavBarItem; 67 | } 68 | 69 | activate(item: any): void { 70 | this._activated = item; 71 | this.items.forEach(child => { 72 | child.activate(child === item); 73 | }); 74 | 75 | this.activated.emit(item); 76 | } 77 | 78 | activateAt(index: number): void { 79 | const item = this.getAt(index); 80 | if (item) { 81 | this.activate(item); 82 | } 83 | } 84 | 85 | isActivated(item: WeUINavBarItem): boolean { 86 | return item.isActivated(); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/app/weui/src/overlay/LayerInjector.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Injector, Type, InjectionToken, InjectFlags } from '@angular/core'; 10 | 11 | export class LayerInjector implements Injector { 12 | 13 | constructor(private _parentInjector: Injector, private _additionalTokens: WeakMap) { 14 | 15 | } 16 | 17 | get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): T; 18 | 19 | get(token: any, notFoundValue?: any); 20 | 21 | get(token: any, notFoundValue?: any, flags?: any) { 22 | const value = this._additionalTokens.get(token); 23 | 24 | if (value) { 25 | return value; 26 | } 27 | 28 | return this._parentInjector.get(token, notFoundValue); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/weui/src/progress/weui.progress.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Output, EventEmitter, ElementRef, Renderer2, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | 12 | @Component({ 13 | selector: 'weui-progress-bar', 14 | preserveWhitespaces: false, 15 | providers: [ UpdateClassService ], 16 | template: ` 17 |
18 |
19 |
20 | 21 | 22 | 23 | ` 24 | }) 25 | export class WeUIProgressBar implements OnInit { 26 | 27 | /** 28 | * 颜色,取值:default、primary、warn等。默认为default。
29 | * 自定义的颜色名称与色值,可以定义在 工程根目录/src/theme/variables.scss 文件中的 $colors 对象。 30 | */ 31 | @Input() 32 | get color(): string { 33 | return this._color; 34 | } 35 | set color(color: string) { 36 | if (this._color !== color) { 37 | this._color = color; 38 | this.updateClassMap(); 39 | } 40 | } 41 | private _color = 'default'; 42 | 43 | /** 44 | * Type of the progress bar.
45 | * Input must be one of these values: determinate, indeterminate. Defaults to 'determinate'.
46 | * 47 | *

In the "determinate" mode, the progress is set via the value property, which can be a whole number between 0 and 100.

48 | *

In the "indeterminate" mode, the progress bar indicates that something is happening without conveying a discrete progress.

49 | *

In the "indeterminate" mode, the value property is ignored.

50 | */ 51 | // @Input() type: string = 'determinate'; 52 | 53 | /** 54 | * Value of the progressbar. Defaults to zero. 55 | */ 56 | @Input() value = 0; 57 | 58 | /** 59 | * 是否可终止 (若为true,则显示关闭按钮) 60 | */ 61 | @Input() canTerminate = true; 62 | 63 | /** 64 | * 终止事件 65 | */ 66 | @Output() terminate = new EventEmitter(); 67 | 68 | constructor( 69 | protected renderer: Renderer2, 70 | protected el: ElementRef, 71 | protected updateClassService: UpdateClassService) { 72 | 73 | } 74 | 75 | ngOnInit(): void { 76 | this.updateClassMap(); 77 | } 78 | 79 | private updateClassMap(): void { 80 | const classes = { 81 | [`weui-progress`]: true, 82 | [`weui-progress_${this.color}`]: this.color 83 | }; 84 | this.updateClassService.update(this.el.nativeElement, classes); 85 | } 86 | 87 | onTerminate(): void { 88 | this.terminate.emit(this); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/app/weui/src/tabbar/weui.tabbar.item.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, ElementRef, Renderer2, Host, HostListener, Optional, Inject, forwardRef, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | 12 | import { WeUITabBar } from './weui.tabbar'; 13 | 14 | 15 | @Component({ 16 | // tslint:disable-next-line:directive-selector 17 | selector: 'weui-tabbar-item,[weui-tabbar-item]', 18 | preserveWhitespaces: false, 19 | providers: [ UpdateClassService ], 20 | template: `` 21 | }) 22 | export class WeUITabBarItem implements OnInit { 23 | 24 | /** 25 | * 任意值,当激活时传递给父级控件 26 | */ 27 | @Input() value: any; 28 | 29 | // 用于设置激活样式 30 | public get activated(): boolean { 31 | return this._activated; 32 | } 33 | public set activated(activated: boolean) { 34 | this._activated = activated; 35 | this.updateClassMap(); 36 | } 37 | private _activated = false; 38 | 39 | /** 40 | * 点击触发激活 41 | * 42 | * @param event 点击事件 43 | */ 44 | @HostListener('click', ['$event']) 45 | onClick(event: Event): void { 46 | if (this.tabbar) { 47 | this.tabbar.activate(this); 48 | } 49 | } 50 | 51 | constructor( 52 | protected renderer: Renderer2, 53 | protected el: ElementRef, 54 | protected updateClassService: UpdateClassService, 55 | @Optional() @Host() @Inject(forwardRef(() => WeUITabBar)) private tabbar: WeUITabBar) { 56 | 57 | } 58 | 59 | ngOnInit(): void { 60 | this.updateClassMap(); 61 | } 62 | 63 | private updateClassMap(): void { 64 | const classes = { 65 | [`weui-tabbar__item`]: true, 66 | [`weui-bar__item_on`]: this.activated 67 | }; 68 | this.updateClassService.update(this.el.nativeElement, classes); 69 | } 70 | 71 | /** 72 | * 由父级控件传入 73 | * 74 | * @param activated 激活状态 75 | */ 76 | activate(activated: boolean): void { 77 | this.activated = activated; 78 | } 79 | 80 | isActivated(): boolean { 81 | return this.activated; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/app/weui/src/tabbar/weui.tabbar.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { 10 | Component, Input, Output, EventEmitter, ElementRef, Renderer2, 11 | AfterViewInit, ContentChildren, QueryList, OnInit 12 | } from '@angular/core'; 13 | import { UpdateClassService } from '../core/service/update.class.service'; 14 | 15 | import { WeUITabBarItem } from './weui.tabbar.item'; 16 | 17 | @Component({ 18 | selector: 'weui-tabbar', 19 | preserveWhitespaces: false, 20 | providers: [ UpdateClassService ], 21 | template: `` 22 | }) 23 | export class WeUITabBar implements OnInit, AfterViewInit { 24 | 25 | /** 26 | * 初始激活的子对象 27 | */ 28 | @Input() activeIndex = 0; 29 | 30 | /** 内部子对象 */ 31 | @ContentChildren(WeUITabBarItem) items: QueryList; 32 | 33 | /** 34 | * 激活事件 35 | */ 36 | @Output() activated = new EventEmitter(); 37 | 38 | private _activated: any; 39 | 40 | constructor( 41 | protected renderer: Renderer2, 42 | protected el: ElementRef, 43 | protected updateClassService: UpdateClassService) { 44 | 45 | } 46 | 47 | ngOnInit(): void { 48 | this.updateClassMap(); 49 | } 50 | 51 | private updateClassMap(): void { 52 | const classes = { 53 | [`weui-tabbar`]: true 54 | }; 55 | this.updateClassService.update(this.el.nativeElement, classes); 56 | } 57 | 58 | ngAfterViewInit(): void { 59 | setTimeout(() => { 60 | this.activateAt(this.activeIndex); 61 | }, 1); 62 | } 63 | 64 | getAt(index: number): WeUITabBarItem { 65 | return this.items.find((item: WeUITabBarItem, i: number) => i === index) as WeUITabBarItem; 66 | } 67 | 68 | activate(item: any): void { 69 | this._activated = item; 70 | this.items.forEach(child => { 71 | child.activate(child === item); 72 | }); 73 | 74 | this.activated.emit(item); 75 | } 76 | 77 | activateAt(index: number): void { 78 | const item = this.getAt(index); 79 | if (item) { 80 | this.activate(item); 81 | } 82 | } 83 | 84 | isActivated(item: WeUITabBarItem): boolean { 85 | return item.isActivated(); 86 | } 87 | 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/app/weui/src/toptips/weui.toptip.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, Input, Output, EventEmitter, ElementRef, Renderer2, HostBinding, OnInit } from '@angular/core'; 10 | import { UpdateClassService } from '../core/service/update.class.service'; 11 | 12 | 13 | /** 14 | * TopTips - 顶部提示 15 | */ 16 | @Component({ 17 | selector: 'weui-toptips', 18 | preserveWhitespaces: false, 19 | providers: [ UpdateClassService ], 20 | template: `{{content}}` 21 | }) 22 | export class WeUITopTips implements OnInit { 23 | 24 | /** 25 | * 内容 26 | */ 27 | @Input() content: string; 28 | 29 | /** 30 | * 隐藏对象 31 | */ 32 | @Output() close = new EventEmitter(); 33 | 34 | /** 35 | * 样式控制 36 | */ 37 | @HostBinding('style.display') 38 | get display(): string { 39 | return this.shown ? 'block' : 'none'; 40 | } 41 | 42 | /** 已显示否 */ 43 | private shown = false; 44 | 45 | constructor( 46 | protected renderer: Renderer2, 47 | protected el: ElementRef, 48 | protected updateClassService: UpdateClassService) { 49 | 50 | } 51 | 52 | ngOnInit(): void { 53 | this.updateClassMap(); 54 | } 55 | 56 | private updateClassMap(): void { 57 | const classes = { 58 | [`weui-toptips`]: true, 59 | [`weui-toptips_warn`]: true 60 | }; 61 | this.updateClassService.update(this.el.nativeElement, classes); 62 | } 63 | 64 | /** 65 | * 显示 66 | */ 67 | show(): void { 68 | this.shown = true; 69 | setTimeout(() => { this.hide(); }, 2000); 70 | } 71 | 72 | /** 73 | * 隐藏 74 | */ 75 | hide(): void { 76 | this.shown = false; 77 | this.close.emit(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/app/weui/src/util/classnames.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | const hasOwn = {}.hasOwnProperty; 10 | 11 | /** 12 | * 将字符串、数字、数字、map形式的样式,转换为string格式的字符串 13 | */ 14 | export function classnames(..._arguments: any[]): string { 15 | const classes: any[] = []; 16 | 17 | for (const arg of _arguments) { 18 | if (!arg) { 19 | continue; 20 | } 21 | 22 | const argType = typeof arg; 23 | 24 | if (argType === 'string' || argType === 'number') { 25 | classes.push(arg); 26 | } else if (Array.isArray(arg)) { 27 | classes.push(classnames.apply(null, arg)); 28 | } else if (argType === 'object') { 29 | for (const key in arg) { 30 | if (hasOwn.call(arg, key) && arg[key]) { 31 | classes.push(key); 32 | } 33 | } 34 | } 35 | } 36 | 37 | return classes.join(' '); 38 | } 39 | 40 | /** 替换样式 */ 41 | export function replaceClass(el: HTMLElement, newClass: any, oldClass?: any): void { 42 | const oldcls = classnames(oldClass); 43 | const newcls = classnames(newClass); 44 | if (oldcls === newcls) { 45 | return; 46 | } 47 | 48 | if (oldcls) { 49 | el.classList.remove(...oldcls.split(' ')); 50 | } 51 | if (newcls) { 52 | el.classList.add(...newcls.split(' ')); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/app/weui/src/util/lang.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion'; 9 | 10 | export function isPresent(obj: any): boolean { 11 | return obj !== undefined && obj !== null; 12 | } 13 | 14 | export function isDate(obj: any): boolean { 15 | return !/Invalid|NaN/.test(new Date(obj).toString()); 16 | } 17 | 18 | export function isNumeric(value: any): boolean { 19 | return !isNaN(value - parseFloat(value)); 20 | } 21 | 22 | 23 | export function isEmptyArray(arr: any): boolean { 24 | if (Array.isArray(arr)) { 25 | return arr.length === 0 || arr.every(i => !i); 26 | } 27 | return false; 28 | } 29 | 30 | export function arrayEquals(array1: T[], array2: T[]): boolean { 31 | if (!array1 || !array2 || array1.length !== array2.length) { 32 | return false; 33 | } 34 | 35 | const len = array1.length; 36 | for (let i = 0; i < len; i++) { 37 | if (array1[i] !== array2[i]) { 38 | return false; 39 | } 40 | } 41 | return true; 42 | } 43 | 44 | export function toArray(value: T | T[]): T[] { 45 | let ret: T[]; 46 | if (value === undefined || value == null) { 47 | ret = []; 48 | } else if (!Array.isArray(value)) { 49 | ret = [value]; 50 | } else { 51 | ret = value; 52 | } 53 | return ret; 54 | } 55 | 56 | export function toBoolean(value: boolean | string): boolean { 57 | return coerceBooleanProperty(value); 58 | } 59 | 60 | export function toNumber(value: number | string, fallback: D): number | D { 61 | return coerceNumberProperty(value, fallback); 62 | } 63 | -------------------------------------------------------------------------------- /src/app/weui/src/weui.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | /** 10 | * @module 11 | * @description 12 | * Entry point for all public APIs of the weui package. 13 | */ 14 | export { WeUIBadge } from './badge/weui.badge'; 15 | export { WeUIButton } from './button/weui.button'; 16 | export { WeUICheckbox } from './input/weui.checkbox'; 17 | export { WeUICircle } from './progress/weui.circle'; 18 | export { WeUIDatePicker } from './picker/weui.date.picker'; 19 | export { WeUIFooter, WeUIFooterText, WeUIFooterLinks, WeUIFooterLink } from './footer/weui.footer'; 20 | export { WeUIGallery } from './gallery/weui.gallery'; 21 | export { WeUIInput } from './input/weui.input'; 22 | export { WeUIItems } from './list/weui.items'; 23 | export { WeUIItem } from './list/weui.item'; 24 | export { WeUILink } from './list/weui.link'; 25 | export { WeUILoadmore } from './loadmore/weui.loadmore'; 26 | export { WeUINavBar } from './navbar/weui.navbar'; 27 | export { WeUINavBarItem } from './navbar/weui.navbar.item'; 28 | export { WeUIPicker } from './picker/weui.picker'; 29 | export { WeUIPickerGroup } from './picker/weui-picker-group'; 30 | export { WeUIProgressBar } from './progress/weui.progress'; 31 | export { WeUIRadio } from './input/weui.radio'; 32 | export { WeUISearchBar } from './searchbar/weui.searchbar'; 33 | export { WeUISelect } from './input/weui.select'; 34 | export { WeUISlider } from './slider/weui.slider'; 35 | export { WeUISwitch } from './input/weui.switch'; 36 | export { WeUITabBar } from './tabbar/weui.tabbar'; 37 | export { WeUITabBarItem } from './tabbar/weui.tabbar.item'; 38 | export { WeUITips } from './list/weui.tips'; 39 | export { WeUITitle } from './list/weui.title'; 40 | export { WeUIUploader, WeUIFile } from './uploader/weui.uploader'; 41 | export { WeUIActionSheet } from './actionsheet/weui.actionsheet'; 42 | export { WeUIDialog } from './dialog/weui.dialog'; 43 | export { WeUIToast } from './toast/weui.toast'; 44 | export { WeUITopTips } from './toptips/weui.toptip'; 45 | export { Layer } from './overlay/layer'; 46 | export { WeUIPickerService } from './picker/weui.picker.service'; 47 | 48 | export { onNextFrame, clearNextFrameAction } from './core/anim.frame'; 49 | 50 | export { WeUIModule } from './weui.module'; 51 | -------------------------------------------------------------------------------- /src/app/weui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | "stripInternal": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "suppressImplicitAnyIndexErrors": true, 11 | "target": "es2015", 12 | "module": "es2015", 13 | "moduleResolution": "node", 14 | "outDir": "../../../dist/packages/angular-weui", 15 | "paths": { 16 | "rxjs/*": [ 17 | "../../../node_modules/rxjs/*" 18 | ], 19 | "@angular/*": [ 20 | "../../../node_modules/@angular/*" 21 | ] 22 | }, 23 | "rootDir": ".", 24 | "sourceMap": true, 25 | "inlineSources": true, 26 | "skipDefaultLibCheck": true, 27 | "skipLibCheck": true, 28 | "lib": ["es2015", "dom"], 29 | // don't auto-discover @types/node, it results in a /// h1:first-child, .fmt blockquote:first-child, .fmt h2:first-child, 46 | .fmt h3:first-child, .fmt h4:first-child, .fmt ol:first-child, .fmt p:first-child, 47 | .fmt pre:first-child, .fmt ul:first-child { 48 | margin-top: 0 49 | } 50 | 51 | .fmt ol, .fmt ul { 52 | margin-left: 3em; 53 | padding-left: 0 54 | } 55 | 56 | .fmt ol li, .fmt ul li { 57 | margin: .3em 0 58 | } 59 | 60 | .fmt ol ol, .fmt ol ul, .fmt ul ol, .fmt ul ul { 61 | margin-top: 0; 62 | margin-bottom: 0 63 | } 64 | 65 | .fmt ol p, .fmt ul p { 66 | margin: 0 67 | } 68 | 69 | .fmt p:last-child { 70 | margin-bottom: 0 71 | } 72 | 73 | .fmt div > br:only-child, .fmt div > div:empty, .fmt div > p:empty, .fmt img + br, 74 | .fmt p + br, .fmt p > br:only-child, .fmt p > div:empty, .fmt p > p:empty { 75 | display: none 76 | } 77 | 78 | .fmt audio, .fmt img, .fmt video { 79 | position: static !important; 80 | max-width: 100% 81 | } 82 | 83 | .fmt img { 84 | padding: 3px; 85 | border: 1px solid #ddd 86 | } 87 | 88 | .fmt img.emoji { 89 | padding: 0; 90 | border: none 91 | } 92 | 93 | .fmt blockquote { 94 | border-left: 2px solid #009a61; 95 | background: #f6f6f6; 96 | color: #555; 97 | font-size: 1em 98 | } 99 | 100 | .fmt code, .fmt pre { 101 | font-size: .93em 102 | } 103 | 104 | .fmt pre { 105 | padding: 1em; 106 | border: none; 107 | overflow: auto; 108 | line-height: 1.3; 109 | max-height: 35em; 110 | position: relative; 111 | background: url(../img/blueprint.png) #f6f6f6; 112 | background-size: 30px, 30px 113 | } 114 | 115 | .fmt pre code { 116 | background: none; 117 | font-size: 1em; 118 | overflow-wrap: normal; 119 | white-space: inherit 120 | } 121 | 122 | .fmt hr { 123 | margin: 1.5em auto; 124 | border-top: 2px dotted #eee 125 | } 126 | 127 | .fmt kbd { 128 | margin: 0 4px; 129 | padding: 3px 4px; 130 | background: #eee; 131 | color: #555 132 | } 133 | 134 | .fmt .x-scroll { 135 | overflow-x: auto 136 | } 137 | 138 | .fmt table { 139 | width: 100% 140 | } 141 | 142 | .fmt table td, .fmt table th { 143 | border: 1px solid #e6e6e6; 144 | padding: 5px 8px; 145 | word-break: normal 146 | } 147 | 148 | .fmt table th { 149 | background: #f3f3f3 150 | } 151 | 152 | -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_footer.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_footer_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_footer_link.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_intro.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_actionSheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_actionSheet.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_article.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_button.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_cell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_cell.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_dialog.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_feedback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_feedback.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_flow.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_form.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_icons.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_layout.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_msg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_msg.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_nav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_nav.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_panel.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_progress.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_search.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_search_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_search_bar.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_special.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_special.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_tab.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_toast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_toast.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_z-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_z-index.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_nav_zindex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_nav_zindex.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/icon_tabbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/icon_tabbar.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/layers/content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/layers/content.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/layers/navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/layers/navigation.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/layers/popout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/layers/popout.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/layers/transparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/layers/transparent.gif -------------------------------------------------------------------------------- /src/assets/weui-example/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/logo.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/pic_160.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/pic_160.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/pic_article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/pic_article.png -------------------------------------------------------------------------------- /src/assets/weui-example/images/vcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/images/vcode.jpg -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/actionSheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/actionSheet.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/button.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/cell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/cell.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/dialog1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/dialog1.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/dialog2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/dialog2.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/grid.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/icons.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/progress.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/qrcode.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/result.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/text.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/toast1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/toast1.png -------------------------------------------------------------------------------- /src/assets/weui-example/snapshot/toast2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/assets/weui-example/snapshot/toast2.png -------------------------------------------------------------------------------- /src/declarations.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Declaration files are how the Typescript compiler knows about the type information(or shape) of an object. 3 | They're what make intellisense work and make Typescript know all about your code. 4 | 5 | A wildcard module is declared below to allow third party libraries to be used in an app even if they don't 6 | provide their own type declarations. 7 | 8 | To learn more about using third party libraries in an Ionic app, check out the docs here: 9 | http://ionicframework.com/docs/v2/resources/third-party-libs/ 10 | 11 | For more info on type definition files, check out the Typescript docs here: 12 | https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html 13 | */ 14 | declare module '*'; 15 | -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular-WeUI 6 | 7 | 8 | 9 | 10 | 11 | Loading... 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /src/pages/images/avatar-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/pages/images/avatar-1.jpg -------------------------------------------------------------------------------- /src/pages/images/avatar-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/pages/images/avatar-2.jpg -------------------------------------------------------------------------------- /src/pages/images/icon_tabbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/pages/images/icon_tabbar.png -------------------------------------------------------------------------------- /src/pages/images/pic_160.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/pages/images/pic_160.png -------------------------------------------------------------------------------- /src/pages/images/pic_article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/pages/images/pic_article.png -------------------------------------------------------------------------------- /src/pages/images/zhenhuan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fbchen/angular4-weui/06c6c1c9d352fa9d37b371128eb69449dbf8b038/src/pages/images/zhenhuan.jpg -------------------------------------------------------------------------------- /src/pages/readme.md: -------------------------------------------------------------------------------- 1 | 2 | This folder is used for demo. 3 | 4 | -------------------------------------------------------------------------------- /src/pages/weui/abstract-page.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { OnInit, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute, UrlSegment } from '@angular/router'; 11 | 12 | export abstract class AbstractPage implements OnInit { 13 | 14 | constructor( 15 | public element: ElementRef, 16 | public router: Router, 17 | public route: ActivatedRoute) { 18 | 19 | } 20 | 21 | ngOnInit() { 22 | const el: HTMLElement = this.element.nativeElement; 23 | const page: Element = el.firstElementChild; 24 | 25 | this.route.url.forEach((value: UrlSegment[]) => { 26 | page.classList.add('slideIn', value[0].path); 27 | }); 28 | 29 | page.addEventListener('animationend', () => { 30 | page.classList.remove('slideIn'); 31 | page.classList.add('js_show'); 32 | }); 33 | } 34 | 35 | home(): void { 36 | this.router.navigate(['/']); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/pages/weui/actionsheet/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

ActionSheet

4 |

弹出式菜单 (原链接

5 |
6 | 14 | 15 |
16 | 17 |
18 |
19 | -------------------------------------------------------------------------------- /src/pages/weui/actionsheet/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUIActionSheet, Layer } from '../../../app/weui'; 14 | 15 | @Component({ 16 | templateUrl: 'example.html' 17 | }) 18 | export class ActionsheetExamplePageComponent extends AbstractPage { 19 | 20 | public actionsheetMenu = [ 21 | {text: '示例菜单1', value: '01', foo: 'dd', bar: '123'}, 22 | {text: '示例菜单2', value: '02'}, 23 | {text: '示例菜单3', value: '03'}, 24 | {text: '示例菜单4', value: '04'} 25 | ]; 26 | 27 | @ViewChild('actionsheet1') actionsheet1: WeUIActionSheet; 28 | @ViewChild('actionsheet2') actionsheet2: WeUIActionSheet; 29 | 30 | constructor( 31 | public element: ElementRef, 32 | public router: Router, 33 | public route: ActivatedRoute, 34 | public layer: Layer) { 35 | super(element, router, route); 36 | } 37 | 38 | showIOSActionSheet(): void { 39 | this.actionsheet1.show().then((menu: any) => { 40 | console.log('您刚刚选择了:', menu); 41 | }); 42 | } 43 | 44 | showAndroidActionSheet(): void { 45 | this.actionsheet2.show().then((menu: any) => { 46 | console.log('您刚刚选择了:', menu); 47 | }); 48 | } 49 | 50 | showIOSActionSheet2(): void { 51 | const actionsheetMenu = [ 52 | {text: '示例菜单5', value: '05'}, 53 | {text: '示例菜单6', value: '06'}, 54 | {text: '示例菜单7', value: '07'} 55 | ]; 56 | this.layer.showActionsheet(actionsheetMenu).then((menu: any) => { 57 | console.log('您刚刚选择了:', menu); 58 | }); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/pages/weui/article/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Article

4 |

文章 (原链接

5 |
6 |
7 |
8 |

大标题

9 |
10 |

章标题

11 |
12 |

1.1 节标题

13 |

14 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 15 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 16 | quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 17 | consequat. 18 |

19 |

20 | 21 | 22 |

23 |
24 |
25 |

1.2 节标题

26 |

27 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod 28 | tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 29 | cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 30 | proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 31 |

32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 | -------------------------------------------------------------------------------- /src/pages/weui/article/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class ArticleExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/badge/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Badge

4 |

徽章 (原链接

5 |
6 |
7 | 新消息提示跟摘要信息后,统一在列表右侧 8 | 9 | 10 |

单行列表

11 |

12 | 详细信息 13 | 14 |

15 |
16 | 17 |

单行列表

18 |

19 | 详细信息 20 | 21 |

22 |
23 |
24 | 25 | 26 | 未读数红点跟在主题信息后,统一在列表左侧 27 | 28 | 29 |
30 | 31 | 8 32 |
33 |
34 | 联系人名称 35 |

摘要信息

36 |
37 |
38 | 39 |
40 | 单行列表 41 | 8 42 |
43 |
44 | 45 |
46 | 单行列表 47 | 8 48 |
49 |
50 | 详细信息 51 |
52 |
53 | 54 |
55 | 单行列表 56 | New 57 |
58 |
59 |
60 |
61 |
62 |
63 | 64 |
65 |
66 | -------------------------------------------------------------------------------- /src/pages/weui/badge/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class BadgeExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/button/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Button

4 |

按钮 (原链接

5 |
6 | 31 |
32 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /src/pages/weui/button/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUIButton } from '../../../app/weui'; 14 | 15 | @Component({ 16 | templateUrl: 'example.html' 17 | }) 18 | export class ButtonExamplePageComponent extends AbstractPage { 19 | 20 | @ViewChild('button') 21 | private button: WeUIButton; 22 | 23 | constructor( 24 | public element: ElementRef, 25 | public router: Router, 26 | public route: ActivatedRoute) { 27 | super(element, router, route); 28 | } 29 | 30 | /** 31 | * 切换“正在加载/加载完毕” 32 | */ 33 | toggleLoading($event): void { 34 | this.button.loading = !this.button.loading; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/pages/weui/dialog/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Dialog

4 |

对话框 (原链接

5 |
6 |
7 | iOS Dialog样式一 8 | iOS Dialog样式二 9 | Android Dialog样式一 10 | Android Dialog样式二 11 | 12 | showAlert 13 | showConfirm 14 | 15 |
16 | success 17 | info 18 | error 19 | warning 20 | default 21 | 22 | 23 | 26 | 27 | 30 | 31 | 34 | 35 | 38 | 39 |
40 |
41 | 42 |
43 | 44 |
45 | -------------------------------------------------------------------------------- /src/pages/weui/dialog/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUIDialog, Layer } from '../../../app/weui'; 14 | 15 | @Component({ 16 | templateUrl: 'example.html' 17 | }) 18 | export class DialogExamplePageComponent extends AbstractPage { 19 | 20 | @ViewChild('dialog1') dialog1: WeUIDialog; 21 | @ViewChild('dialog2') dialog2: WeUIDialog; 22 | @ViewChild('dialog3') dialog3: WeUIDialog; 23 | @ViewChild('dialog4') dialog4: WeUIDialog; 24 | 25 | constructor( 26 | public element: ElementRef, 27 | public router: Router, 28 | public route: ActivatedRoute, 29 | public layer: Layer) { 30 | super(element, router, route); 31 | console.log(layer); 32 | } 33 | 34 | showIOSDialog1(): void { 35 | this.dialog1.show().then(() => { 36 | console.log('您刚刚选择了: OK'); 37 | }, () => { 38 | console.log('您刚刚选择了: NO'); 39 | }); 40 | } 41 | 42 | showIOSDialog2(): void { 43 | this.dialog2.show().then(() => { 44 | console.log('您刚刚选择了: OK'); 45 | }, () => { 46 | console.log('您刚刚选择了: NO'); 47 | }); 48 | } 49 | 50 | showAndroidDialog1(): void { 51 | this.dialog3.show().then(() => { 52 | console.log('您刚刚选择了: OK'); 53 | }, () => { 54 | console.log('您刚刚选择了: NO'); 55 | }); 56 | } 57 | 58 | showAndroidDialog2(): void { 59 | this.dialog4.show().then(() => { 60 | console.log('您刚刚选择了: OK'); 61 | }, () => { 62 | console.log('您刚刚选择了: NO'); 63 | }); 64 | } 65 | 66 | 67 | showAlert(): void { 68 | this.layer.showAlert('你好,世界!').then(() => { 69 | console.log('您刚刚选择了: OK'); 70 | }, () => { 71 | console.log('您刚刚选择了: NO'); 72 | }); 73 | } 74 | 75 | showConfirm(): void { 76 | this.layer.showConfirm({content: '你好,世界?', title: '系统消息', btnOKText: '朕知道了'}).then(() => { 77 | console.log('您刚刚选择了: OK'); 78 | }, () => { 79 | console.log('您刚刚选择了: NO'); 80 | }); 81 | } 82 | 83 | showSuccess(): void { 84 | this.layer.success('操作成功!', '标题'); 85 | } 86 | 87 | showInfo(): void { 88 | this.layer.info('操作成功!', '标题'); 89 | } 90 | 91 | showError(): void { 92 | this.layer.error('操作失败!', '标题'); 93 | } 94 | 95 | showWarning(): void { 96 | this.layer.warning('操作失败!', '标题'); 97 | } 98 | 99 | showDefault(): void { 100 | this.layer.showAlert('操作失败!', '标题', 'default'); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/pages/weui/flex/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Flex

4 |

Flex布局 (原链接

5 |
6 |
7 |
8 |
weui
9 |
10 |
11 |
weui
12 |
weui
13 |
14 |
15 |
weui
16 |
weui
17 |
weui
18 |
19 |
20 |
weui
21 |
weui
22 |
weui
23 |
weui
24 |
25 |
26 |
weui
27 |
weui
28 |
weui
29 |
30 |
31 |
32 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /src/pages/weui/flex/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class FlexExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/footer/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Footer

4 |

页脚 (原链接

5 |
6 |
7 | 8 | Copyright © 2008-2016 weui.io 9 | 10 |
11 |
12 | 13 | 14 | 15 | 底部链接 16 | 17 | Copyright © 2008-2016 weui.io 18 | 19 |
20 |
21 | 22 | 23 | 24 | 底部链接 25 | 底部链接 26 | 27 | Copyright © 2008-2016 weui.io 28 | 29 |
30 |
31 | 32 | 33 | 34 | WeUI首页 35 | 36 | Copyright © 2008-2016 weui.io 37 | 38 |
39 |
40 | -------------------------------------------------------------------------------- /src/pages/weui/footer/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class FooterExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/gallery/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Gallery

4 |

画廊,可实现上传图片的展示或幻灯片播放 (原链接

5 |
6 |
7 |
8 | 再次显示 9 |
10 |
11 | 12 |
13 | -------------------------------------------------------------------------------- /src/pages/weui/gallery/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild, OnInit } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUIGallery } from '../../../app/weui'; 14 | 15 | 16 | @Component({ 17 | templateUrl: 'example.html' 18 | }) 19 | export class GalleryExamplePageComponent extends AbstractPage implements OnInit { 20 | 21 | /** 22 | * 图片预览控件 23 | */ 24 | @ViewChild(WeUIGallery) gallery: WeUIGallery; 25 | 26 | public image: any = { 27 | fileURL: 'url(pages/images/zhenhuan.jpg)' 28 | }; 29 | 30 | constructor( 31 | public element: ElementRef, 32 | public router: Router, 33 | public route: ActivatedRoute) { 34 | super(element, router, route); 35 | } 36 | 37 | ngOnInit() { 38 | super.ngOnInit(); 39 | setTimeout(() => { 40 | this.gallery.show(); 41 | }, 600); 42 | } 43 | 44 | /** 45 | * 删除文件 46 | * @param {file} 需要从列表中删除的图片 47 | */ 48 | onDelete(file: any): void { 49 | alert('Your File has been DELETED!'); 50 | } 51 | 52 | show(): void { 53 | this.gallery.show(); 54 | } 55 | 56 | hide(): void { 57 | this.gallery.hide(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/pages/weui/grid/example.html: -------------------------------------------------------------------------------- 1 | 63 | -------------------------------------------------------------------------------- /src/pages/weui/grid/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class GridExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/icons/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Icons

4 |

图标(原链接

5 |
6 |
7 |
8 | 9 |
10 |

成功

11 |

用于表示操作顺利达成

12 |
13 |
14 |
15 | 16 |
17 |

提示

18 |

用于表示信息提示;也常用于缺乏条件的操作拦截,提示用户所需信息

19 |
20 |
21 |
22 | 23 |
24 |

普通警告

25 |

用于表示操作后将引起一定后果的情况

26 |
27 |
28 |
29 | 30 |
31 |

强烈警告

32 |

用于表示操作后将引起严重的不可挽回的后果的情况

33 |
34 |
35 |
36 | 37 |
38 |

等待

39 |

用于表示等待

40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 |
53 |
54 | 55 |
56 |
57 | -------------------------------------------------------------------------------- /src/pages/weui/icons/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class IconsExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/input/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | import { WeUITopTips, Layer } from '../../../app/weui'; 15 | 16 | @Component({ 17 | templateUrl: 'example.html' 18 | }) 19 | export class InputExamplePageComponent extends AbstractPage { 20 | 21 | public data: any = { 22 | radio1: '2', 23 | checkbox1: ['1'], 24 | name: '', 25 | card: 'weui input error', 26 | num: null, 27 | text1: 'text1 message', 28 | text2: 'text2 message', 29 | select1: '1', 30 | select2: '1', 31 | select3: '1', 32 | switch2: 'open' 33 | }; 34 | 35 | @ViewChild('weuiToptips') toptips: WeUITopTips; 36 | 37 | constructor( 38 | public element: ElementRef, 39 | public router: Router, 40 | public route: ActivatedRoute, 41 | public layer: Layer) { 42 | super(element, router, route); 43 | } 44 | 45 | /** 46 | * 显示错误提示 47 | */ 48 | showError(): void { 49 | this.toptips.show(); 50 | } 51 | 52 | showError2(): void { 53 | this.layer.showError('用户名不能为空!'); 54 | } 55 | 56 | /** 57 | * 测试事件 58 | */ 59 | onEvent(event: Event): void { 60 | const target = event.target as HTMLInputElement; 61 | console.log(`${event.type}: ${target.name}=${target.value}`); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/pages/weui/list/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class ListExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | /** 27 | * 测试事件 28 | */ 29 | onClickLink(event: Event): void { 30 | console.log(event); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/weui/loadmore/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Loadmore

4 |

加载更多 (原链接

5 |
6 |
7 | 正在加载 8 | 9 | 暂无数据 10 | 11 | 12 | 13 | {{loadmoreText}} 14 |
15 | 开始加载 16 |
17 | 18 |
19 |
20 | 21 |
22 |
23 | -------------------------------------------------------------------------------- /src/pages/weui/loadmore/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUILoadmore } from '../../../app/weui'; 14 | 15 | @Component({ 16 | templateUrl: 'example.html' 17 | }) 18 | export class LoadmoreExamplePageComponent extends AbstractPage { 19 | 20 | @ViewChild('loadmore') loadmore: WeUILoadmore; 21 | 22 | public loadmoreText: string; 23 | 24 | constructor( 25 | public element: ElementRef, 26 | public router: Router, 27 | public route: ActivatedRoute) { 28 | super(element, router, route); 29 | } 30 | 31 | load(): void { 32 | this.loadmore.line = null; 33 | this.loadmore.loading = true; 34 | this.loadmoreText = '正在加载'; 35 | setTimeout(() => { 36 | this.loadmore.line = true; 37 | this.loadmore.loading = false; 38 | this.loadmoreText = '暂无数据'; 39 | 40 | }, 2000); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/pages/weui/msg/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Msg

4 |

提示页(原链接

5 |
6 | 10 |
11 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /src/pages/weui/msg/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class MsgExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | 28 | 29 | @Component({ 30 | templateUrl: 'succ_example.html' 31 | }) 32 | export class MsgSuccExamplePageComponent extends AbstractPage { 33 | 34 | constructor( 35 | public element: ElementRef, 36 | public router: Router, 37 | public route: ActivatedRoute) { 38 | super(element, router, route); 39 | } 40 | 41 | } 42 | 43 | 44 | @Component({ 45 | templateUrl: 'warn_example.html' 46 | }) 47 | export class MsgWarnExamplePageComponent extends AbstractPage { 48 | 49 | constructor( 50 | public element: ElementRef, 51 | public router: Router, 52 | public route: ActivatedRoute) { 53 | super(element, router, route); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/pages/weui/msg/succ_example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

操作成功

6 |

内容详情,可根据实际需要安排,如果换行则不超过规定长度,居中展现文字链接

7 |
8 |
9 |

10 | 推荐操作 11 | 辅助操作 12 |

13 |
14 |
15 | 16 | 17 | 底部链接文本 18 | 19 | Copyright © 2008-2016 weui.io 20 | 21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /src/pages/weui/msg/warn_example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

操作失败

6 |

内容详情,可根据实际需要安排,如果换行则不超过规定长度,居中展现文字链接

7 |
8 |
9 |

10 | 推荐操作 11 | 辅助操作 12 |

13 |
14 |
15 | 16 | 17 | 底部链接文本 18 | 19 | Copyright © 2008-2016 weui.io 20 | 21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /src/pages/weui/navbar/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 选项一 6 | 选项二 7 | 选项三 8 | 9 |
10 |
11 |
12 |

Navbar

13 |

导航栏 (原链接

14 |

15 |

这是第一页

16 |
17 |
18 |
19 |
20 |

这是第二页

21 |
22 |
23 |
24 |
25 |

这是第三页

26 |
27 |
28 |
29 |
30 |
31 |
32 | 33 |
34 |
35 | -------------------------------------------------------------------------------- /src/pages/weui/navbar/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, OnInit } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | import { WeUINavBarItem } from '../../../app/weui'; 15 | 16 | @Component({ 17 | templateUrl: 'example.html' 18 | }) 19 | export class NavBarExamplePageComponent extends AbstractPage implements OnInit { 20 | 21 | public activeValue: string; 22 | 23 | constructor( 24 | public element: ElementRef, 25 | public router: Router, 26 | public route: ActivatedRoute) { 27 | super(element, router, route); 28 | } 29 | 30 | onActivated(item: WeUINavBarItem): void { 31 | this.activeValue = item.value; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/pages/weui/panel/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class PanelExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/picker/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Picker

4 |

多列选择器 (原链接

5 |
6 |
7 | 单列选择器 8 | 多列选择器 9 | 日期选择器 10 | 11 | 12 | 13 | 14 |
15 |
16 | 17 |
18 | 19 |
20 | -------------------------------------------------------------------------------- /src/pages/weui/picker/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild, OnInit } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUIPicker, WeUIDatePicker } from '../../../app/weui'; 14 | 15 | @Component({ 16 | templateUrl: 'example.html' 17 | }) 18 | export class PickerExamplePageComponent extends AbstractPage implements OnInit { 19 | 20 | public menu1: any[] = [{ 21 | label: '飞机票', 22 | value: 0 23 | }, { 24 | label: '火车票', 25 | value: 1 26 | }, { 27 | label: '的士票', 28 | value: 2 29 | }, { 30 | label: '公交票 (disabled)', 31 | disabled: true, 32 | value: 3 33 | }, { 34 | label: '其他', 35 | value: 4 36 | }]; 37 | 38 | public menu2: any = []; 39 | 40 | @ViewChild('picker1') picker1: WeUIPicker; 41 | @ViewChild('picker2') picker2: WeUIPicker; 42 | @ViewChild('picker3') picker3: WeUIDatePicker; 43 | 44 | constructor( 45 | public element: ElementRef, 46 | public router: Router, 47 | public route: ActivatedRoute) { 48 | super(element, router, route); 49 | } 50 | 51 | ngOnInit(): void { 52 | super.ngOnInit(); 53 | 54 | const charCode = 'A'.charCodeAt(0); 55 | const options1: any[] = []; 56 | for (let i = 0; i < 26; i++) { 57 | const c = String.fromCharCode(charCode + i); 58 | options1[i] = { label: '字母' + c, value: c }; 59 | } 60 | 61 | const options2: any[] = []; 62 | for (let i = 0; i < 100; i++) { 63 | options2[i] = { label: '数字' + (i + 1), value: i + 1 }; 64 | } 65 | this.menu2 = [options1, options2]; 66 | } 67 | 68 | showPicker(): void { 69 | this.picker1.show().then((value: any) => { 70 | console.log('您刚刚选择了: ', value); 71 | }); 72 | } 73 | 74 | showMultiPicker(): void { 75 | this.picker2.show().then((value: any) => { 76 | console.log('您刚刚选择了: ', value); 77 | }); 78 | } 79 | 80 | showDatePicker(): void { 81 | this.picker3.show().then((value: any) => { 82 | console.log('您刚刚选择了: ', value); 83 | }); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/pages/weui/preview/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Preview

4 |

表单预览(原链接

5 |
6 |
7 |
8 |
9 |
10 | 11 | ¥2400.00 12 |
13 |
14 |
15 |
16 | 17 | 电动打蛋机 18 |
19 |
20 | 21 | 名字名字名字 22 |
23 |
24 | 25 | 很长很长的名字很长很长的名字很长很长的名字很长很长的名字很长很长的名字 26 |
27 |
28 |
29 | 操作 30 |
31 |
32 |
33 |
34 |
35 | 36 | ¥2400.00 37 |
38 |
39 |
40 | 41 | 电动打蛋机 42 |
43 |
44 | 45 | 名字名字名字 46 |
47 |
48 | 49 | 很长很长的名字很长很长的名字很长很长的名字很长很长的名字很长很长的名字 50 |
51 |
52 |
53 | 辅助操作 54 | 55 |
56 |
57 |
58 |
59 | 60 |
61 |
62 | -------------------------------------------------------------------------------- /src/pages/weui/preview/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class PreviewExamplePageComponent extends AbstractPage { 18 | 19 | constructor( 20 | public element: ElementRef, 21 | public router: Router, 22 | public route: ActivatedRoute) { 23 | super(element, router, route); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/weui/progress/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Progress

4 |

进度条 (原链接

5 |
6 |
7 | 8 | 9 |
10 | 11 |
12 | 13 |
14 | 15 |
16 | 17 |
18 | 上传 19 |
20 |
21 |
22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /src/pages/weui/progress/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUIProgressBar } from '../../../app/weui'; 14 | 15 | 16 | @Component({ 17 | templateUrl: 'example.html' 18 | }) 19 | export class ProgressExamplePageComponent extends AbstractPage { 20 | 21 | public data: any = { 22 | value1: 0, 23 | value2: 50, 24 | value3: 100, 25 | value4: 70 26 | }; 27 | 28 | private uploading = false; 29 | 30 | constructor( 31 | public element: ElementRef, 32 | public router: Router, 33 | public route: ActivatedRoute) { 34 | super(element, router, route); 35 | } 36 | 37 | onTerminate(progress: WeUIProgressBar): void { 38 | alert('你点击了终止按钮'); 39 | } 40 | 41 | upload(): void { 42 | if (this.uploading) { 43 | return; 44 | } 45 | 46 | this.uploading = true; 47 | this.data.value1 = 0; 48 | this.data.value2 = 0; 49 | this.data.value3 = 0; 50 | this.data.value4 = 0; 51 | setTimeout(this.next.bind(this), 20); 52 | } 53 | 54 | next(): void { 55 | this.data.value1++; 56 | this.data.value2++; 57 | this.data.value3++; 58 | this.data.value4++; 59 | if (this.data.value1 >= 100) { 60 | return; 61 | } 62 | setTimeout(this.next.bind(this), 20); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/pages/weui/searchbar/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

SearchBar

4 |

搜索栏 (原链接

5 |
6 |
7 | 8 | 9 | 10 |
11 |
12 |
13 |

{{item.title}}

14 |
15 |
16 |
17 |
18 |
19 | 20 |
21 |
22 | -------------------------------------------------------------------------------- /src/pages/weui/searchbar/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, OnInit } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | import { HttpClient } from '@angular/common/http'; 12 | 13 | import { AbstractPage } from '../abstract-page'; 14 | 15 | export interface POST { 16 | userId: number; 17 | id: number; 18 | title: string; 19 | body: string; 20 | } 21 | 22 | @Component({ 23 | templateUrl: 'example.html' 24 | }) 25 | export class SearchBarExamplePageComponent extends AbstractPage implements OnInit { 26 | 27 | public list: any[]; 28 | 29 | private value = ''; 30 | 31 | public get showResult(): boolean { 32 | return this.value.length > 0; 33 | } 34 | 35 | constructor( 36 | public element: ElementRef, 37 | public router: Router, 38 | public route: ActivatedRoute, 39 | private http: HttpClient) { 40 | super(element, router, route); 41 | } 42 | 43 | ngOnInit(): void { 44 | super.ngOnInit(); 45 | 46 | // 查询博客 47 | this.http.get('https://jsonplaceholder.typicode.com/posts').subscribe((posts: POST[]) => { 48 | this.list = posts; 49 | }); 50 | } 51 | 52 | search(value: string): void { 53 | this.value = value; 54 | } 55 | 56 | filter(item: any): boolean { 57 | if (!this.value) { 58 | return true; 59 | } 60 | return item.title.toUpperCase().indexOf(this.value.toUpperCase()) >= 0; 61 | } 62 | 63 | get _filterFn(): () => boolean { 64 | return this.filter.bind(this); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/pages/weui/slider/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Slider

4 |

滑块 (原链接

5 |
6 |
7 | 8 |
9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 |
结果输出:
22 |
{{ data | json }}
23 |
24 | 25 |
26 | 27 |
28 |
29 | -------------------------------------------------------------------------------- /src/pages/weui/slider/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | @Component({ 15 | templateUrl: 'example.html' 16 | }) 17 | export class SliderExamplePageComponent extends AbstractPage { 18 | 19 | public data: any = { 20 | slider1: 50, 21 | slider2: 50, 22 | slider3: 500 23 | }; 24 | 25 | constructor( 26 | public element: ElementRef, 27 | public router: Router, 28 | public route: ActivatedRoute) { 29 | super(element, router, route); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/weui/tabbar/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 8 13 | 14 |

微信

15 |
16 | 17 | 18 |

通讯录

19 |
20 | 21 | 22 | 23 | 24 | 25 |

发现

26 |
27 | 28 | 29 | 30 | 31 |

32 |
33 |
34 | 35 |
36 |
37 |
38 | 39 |
40 |
41 | -------------------------------------------------------------------------------- /src/pages/weui/tabbar/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, OnInit } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | 14 | import { WeUITabBarItem } from '../../../app/weui'; 15 | 16 | @Component({ 17 | templateUrl: 'example.html' 18 | }) 19 | export class TabBarExamplePageComponent extends AbstractPage implements OnInit { 20 | 21 | public activeValue: string; 22 | 23 | constructor( 24 | public element: ElementRef, 25 | public router: Router, 26 | public route: ActivatedRoute) { 27 | super(element, router, route); 28 | } 29 | 30 | onActivated(item: WeUITabBarItem): void { 31 | this.activeValue = item.value; 32 | console.log(`当前选中的是:${item.value}`); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/pages/weui/toast/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Toast

4 |

弹出式提示 (原链接

5 |
6 |
7 | 成功提示 8 | 加载中提示 9 | 10 | 成功提示2 11 | 加载中提示2 12 | 13 | 14 | 15 |
16 |
17 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /src/pages/weui/toast/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | 12 | import { AbstractPage } from '../abstract-page'; 13 | import { WeUIToast, Layer } from '../../../app/weui'; 14 | 15 | @Component({ 16 | templateUrl: 'example.html' 17 | }) 18 | export class ToastExamplePageComponent extends AbstractPage { 19 | 20 | @ViewChild('toast1') toast1: WeUIToast; 21 | @ViewChild('toast2') toast2: WeUIToast; 22 | 23 | constructor( 24 | public element: ElementRef, 25 | public router: Router, 26 | public route: ActivatedRoute, 27 | public layer: Layer) { 28 | super(element, router, route); 29 | } 30 | 31 | showToast(): void { 32 | this.toast1.show(); 33 | } 34 | 35 | showLoadingToast(): void { 36 | this.toast2.show(); 37 | 38 | // 隐藏Toast 39 | setTimeout(() => { 40 | this.toast2.hide(); 41 | }, 2000); 42 | } 43 | 44 | showToast2(): void { 45 | this.layer.showSuccess(); 46 | } 47 | 48 | showLoadingToast2(): void { 49 | const toast = this.layer.showLoading(); 50 | 51 | setTimeout(() => { 52 | toast.hide(); // 隐藏Toast 53 | }, 2000); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/pages/weui/uploader/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Uploader (原链接

4 |

上传组件,一般配合组件Gallery来使用。

5 |
6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 上传 15 |
16 | 17 |
18 |
19 | 20 |
21 |
22 | -------------------------------------------------------------------------------- /src/pages/weui/uploader/example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, ElementRef, ViewChild } from '@angular/core'; 10 | import { Router, ActivatedRoute } from '@angular/router'; 11 | import { Subject, from } from 'rxjs'; 12 | import { filter, concatMap } from 'rxjs/operators'; 13 | 14 | import { AbstractPage } from '../abstract-page'; 15 | 16 | import { WeUIUploader, WeUIFile } from '../../../app/weui'; 17 | 18 | @Component({ 19 | templateUrl: 'example.html' 20 | }) 21 | export class UploaderExamplePageComponent extends AbstractPage { 22 | 23 | @ViewChild('uploader') uploader: WeUIUploader; 24 | 25 | private timer: any; 26 | 27 | constructor( 28 | public element: ElementRef, 29 | public router: Router, 30 | public route: ActivatedRoute) { 31 | super(element, router, route); 32 | } 33 | 34 | upload(): void { 35 | const files: WeUIFile[] = this.uploader.files; 36 | if (!files.length) { 37 | alert('Please select images to upload!'); 38 | return; 39 | } 40 | 41 | from(files) 42 | .pipe( 43 | filter((file: WeUIFile): boolean => !file.isUploaded), 44 | concatMap((file: WeUIFile, index: number) => this.uploadFile(file, index)) 45 | ) 46 | .subscribe((file: WeUIFile) => { 47 | if (file.hasError()) { 48 | console.log(`文件“${file.file.name}”上传失败,原因:${file.error}`); 49 | } else { 50 | console.log(`文件“${file.file.name}”上传成功!`); 51 | } 52 | }, (err: any) => { 53 | console.error(err); 54 | }); 55 | } 56 | 57 | uploadFile(file: WeUIFile, index: number): Subject | ArrayLike { 58 | file.reset(); // 重置进度等 59 | file.isUploading = true; 60 | const subject = new Subject(); 61 | 62 | this.timer = setInterval(() => { 63 | file.progress += 10; 64 | 65 | // 上传成功的例子 66 | if (file.progress >= 100) { 67 | clearInterval(this.timer); 68 | file.isUploading = false; 69 | file.isUploaded = true; 70 | subject.next(file); 71 | subject.complete(); 72 | } 73 | 74 | // 上传失败的例子 75 | if (index % 2 === 1 && file.progress >= 90) { 76 | clearInterval(this.timer); 77 | file.isUploading = false; 78 | file.isUploaded = false; 79 | file.error = '服务器错误'; 80 | subject.next(file); 81 | subject.complete(); 82 | } 83 | }, 200); 84 | 85 | return subject; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/pages/weui/weui.example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 厦门乾元盛世科技有限公司 All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file. 7 | */ 8 | 9 | import { Component, OnInit, ElementRef } from '@angular/core'; 10 | import { Router } from '@angular/router'; 11 | 12 | @Component({ 13 | selector: 'weui-example', 14 | templateUrl: './weui.example.html' 15 | }) 16 | export class WeUIExampleComponent implements OnInit { 17 | 18 | constructor(public element: ElementRef, private router: Router) { 19 | } 20 | 21 | ngOnInit(): void { 22 | const el: HTMLElement = this.element.nativeElement; 23 | const page: Element = el.firstElementChild; 24 | page.classList.add('slideIn', 'home'); 25 | page.addEventListener('animationend', () => { 26 | page.classList.remove('slideIn'); 27 | page.classList.add('js_show'); 28 | }); 29 | } 30 | 31 | toggleCategory($event: Event): void { 32 | const el = $event.currentTarget as HTMLElement; 33 | const parent = el.parentElement; 34 | if (parent.classList.contains('js_show')) { 35 | parent.classList.remove('js_show'); 36 | } else { 37 | const children = parent.parentElement.children; 38 | for (let i = 0; i < children.length; i++) { 39 | children.item(i).classList.remove('js_show'); 40 | } 41 | parent.classList.add('js_show'); 42 | } 43 | } 44 | 45 | navigate($event): void { 46 | const el = $event.currentTarget as HTMLElement; 47 | const name: string = el.dataset.id; 48 | this.router.navigate([name]); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | 65 | /** 66 | * Date, currency, decimal and percent pipes. 67 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 68 | */ 69 | // import 'intl'; // Run `npm install --save intl`. 70 | /** 71 | * Need to import at least one locale-data with intl. 72 | */ 73 | // import 'intl/locale-data/jsonp/zh-Hans-CN'; 74 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | /* WeUI style sheet */ 4 | @import '../node_modules/weui/dist/style/weui.css'; 5 | 6 | /* WeUI Exmple style sheet */ 7 | @import '../node_modules/weui/dist/example/example.css'; 8 | 9 | /* WeUI style sheet */ 10 | @import './app/weui/weui.scss'; 11 | 12 | /* font-awesome.min.css */ 13 | // @import '../node_modules/font-awesome/css/font-awesome.min.css'; 14 | -------------------------------------------------------------------------------- /src/theme/variables.scss: -------------------------------------------------------------------------------- 1 | // Shared Variables 2 | // -------------------------------------------------- 3 | // To customize the look and feel of this app, you can override 4 | // the Sass variables found in Angular-WeUI's source scss files. 5 | 6 | 7 | 8 | // Named Color Variables 9 | // -------------------------------------------------- 10 | // Named colors makes it easy to reuse colors on various components. 11 | // It's highly recommended to change the default colors 12 | // to match your app's branding. Angular-WeUI uses a Sass map of 13 | // colors so you can add, rename and remove colors as needed. 14 | 15 | $colors: ( 16 | primary: #1AAD19, 17 | warn: #E64340, 18 | //secondary: #32db64, 19 | //danger: #f53d3d, 20 | //light: #f4f4f4, 21 | //dark: #222, 22 | //stable: #f8f8f8, 23 | //positive: #4a87ee, 24 | //assertive: #ef4e3a, 25 | //balanced: #66cc33, 26 | //energized: #f0b840, 27 | //royal: #8a6de9, 28 | //calm: #43cee6, 29 | //brighten: #f39800 30 | ); 31 | 32 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "exclude": [ 8 | "test.ts", 9 | "**/*.spec.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "emitDecoratorMetadata": true, 13 | "experimentalDecorators": true, 14 | "importHelpers": true, 15 | "target": "es2015", 16 | "lib": [ 17 | "es2018", 18 | "dom" 19 | ] 20 | }, 21 | "angularCompilerOptions": { 22 | "fullTemplateTypeCheck": true, 23 | "strictInjectionParameters": true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------