├── .babelrc
├── .editorconfig
├── .gitignore
├── LICENSE
├── app
├── app.js
├── entry.js
├── index.html
├── root.js
└── views
│ ├── home
│ └── index.js
│ └── tabs
│ └── index.js
├── karma.conf.js
├── less
├── all.less
├── fonts
│ ├── webui_iconfont.eot
│ ├── webui_iconfont.svg
│ ├── webui_iconfont.ttf
│ └── webui_iconfont.woff
├── sui
│ ├── accordion.less
│ ├── badges.less
│ ├── bars.less
│ ├── base.less
│ ├── buttons.less
│ ├── calendar.less
│ ├── cards.less
│ ├── colors.less
│ ├── content-block.less
│ ├── demos.less
│ ├── docs-baichuan.less
│ ├── docs.less
│ ├── fonts.less
│ ├── forms.less
│ ├── grid.less
│ ├── icons.less
│ ├── infinite.less
│ ├── lists.less
│ ├── mixins.less
│ ├── modal.less
│ ├── normalize.less
│ ├── pages.less
│ ├── panels.less
│ ├── photo-browser.less
│ ├── picker.less
│ ├── preloader.less
│ ├── pull-to-refresh.less
│ ├── push.less
│ ├── rem.less
│ ├── scroller.less
│ ├── searchbar.less
│ ├── sm-extend.less
│ ├── sm.less
│ ├── swiper.less
│ ├── tabs.less
│ ├── text.less
│ ├── themes.less
│ └── variables.less
└── webui
│ └── index.less
├── package.json
├── src
├── Button.js
├── ButtonRow.js
├── Col.js
├── Icon.js
├── Image.js
├── Row.js
├── constant.js
├── core
│ └── createEnhance.js
├── enhance
│ ├── css.js
│ ├── dom.js
│ ├── index.js
│ └── pureRender.js
├── footer
│ ├── Footer.js
│ └── FooterItem.js
├── header
│ ├── Header.js
│ └── HeaderItem.js
├── tabs
│ ├── Tab.js
│ ├── TabNav.js
│ └── Tabs.js
└── utils
│ ├── shallowCompare.js
│ └── shallowEqual.js
├── test
├── ButtonSpec.js
└── index.js
├── webpack.config.js
└── webpack.dev.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "stage": 0,
3 | "optional": ["runtime"],
4 | "loose": ["all"]
5 | }
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | #EditorConfig是一套用于统一代码工具的解决方案
2 | #EditorConfig可以帮助开发者在不同的编辑器和IDE之间定义和维护一致的代码风格。
3 | #EditorConfig包含一个用于定义代码格式的文件和一批编辑器插件,
4 | #这些插件可以让编辑器读取配置文件并依此格式化代码
5 |
6 | #常见配置
7 | #
8 | # indent_style:tab为hard-tabs,space为soft-tabs。
9 | #
10 | # indent_size:设置整数表示规定每级缩进的列数和soft-tabs的宽度(译注:空格数)
11 | # 。如果设定为tab,则会使用tab_width的值(如果已指定)。
12 | #
13 | # tab_width:设置整数用于指定替代tab的列数。默认值就是indent_size的值,一般无需指定。
14 | #
15 | # end_of_line:定义换行符,支持lf、cr和crlf。
16 | #
17 | # charset:编码格式,支持latin1、utf-8、utf-8-bom、utf-16be和utf-16le,不建议使用uft-8-bom。
18 | #
19 | # trim_trailing_whitespace:设为true表示会除去换行行首的任意空白字符,false反之。
20 | #
21 | # insert_final_newline:设为true表明使文件以一个空白行结尾,false反之。
22 | #
23 | # root:表明是最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件。
24 |
25 | root=true
26 |
27 | [*]
28 | end_of_line = lf
29 | insert_final_newline = true
30 |
31 | [*.js]
32 | charset = utf-8
33 | indent_style = space
34 | indent_size = 4
35 |
36 | [{package.json}]
37 | indent_style = space
38 | indent_size = 4
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### SublimeText ###
2 | *.sublime-workspace
3 | /.idea/
4 |
5 | ### OSX ###
6 | .DS_Store
7 | .AppleDouble
8 | .LSOverride
9 | Icon
10 |
11 | # Thumbnails
12 | ._*
13 |
14 | # Files that might appear on external disk
15 | .Spotlight-V100
16 | .Trashes
17 |
18 | ### Windows ###
19 | # Windows image file caches
20 | Thumbs.db
21 | ehthumbs.db
22 |
23 | # Folder config file
24 | Desktop.ini
25 |
26 | # Recycle Bin used on file shares
27 | $RECYCLE.BIN/
28 |
29 | # App specific
30 |
31 | node_modules/
32 | .tmp
33 | /dist/
34 | /src/main.js
35 | app/scripts/vendor/zepto/
36 |
37 | #lib#
38 | /lib/
39 |
40 | #npm#
41 | /npm-debug.log
42 |
43 | /app/extras/release/
44 |
45 | /app/extras/build/
46 |
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | require("../less/all.less");
3 | export default class App extends Component{
4 | render=()=>{
5 | return (
6 |
7 | {this.props.children}
8 |
9 | );
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/entry.js:
--------------------------------------------------------------------------------
1 | import { render } from 'react-dom';
2 | import Root from './root.js';
3 | import createBrowserHistory from 'history/lib/createHashHistory';
4 | let history = createBrowserHistory();
5 |
6 |
7 | /*document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);*/
8 | render(
9 | ,
10 | document.getElementById('container')
11 | );
12 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | React-mui
11 |
12 |
13 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/root.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by liubo on 15/7/28.
3 | */
4 |
5 | import React, { Component, PropTypes } from 'react';
6 | import { Router, Route, Redirect } from 'react-router';
7 |
8 |
9 | //视图
10 | import App from './app.js';
11 | import Home from './views/home/index.js';
12 | import Tabs from './views/tabs/index.js';
13 |
14 | const routes = (
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | )
23 |
24 |
25 | //自定义createElement方法
26 | const createElement = (Component, props) => {
27 | return
28 | }
29 |
30 | //Root
31 | export default class Root extends Component {
32 | render =()=> {
33 |
34 | return (
35 |
36 |
37 |
38 | );
39 | }
40 | }
41 | Root.propTypes = {
42 | history: PropTypes.object.isRequired
43 | };
44 |
--------------------------------------------------------------------------------
/app/views/home/index.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import Button from '../../../src/Button';
3 | import ButtonRow from '../../../src/ButtonRow';
4 | import Header from '../../../src/header/Header';
5 | import HeaderItem from '../../../src/header/HeaderItem';
6 | import Footer from '../../../src/footer/Footer';
7 | import FooterItem from '../../../src/footer/FooterItem';
8 | export default class Home extends Component {
9 |
10 | render=()=>{
11 | return (
12 |
13 | 按钮
14 | 按钮
15 | 按钮
16 |
17 | 全部活动
18 | 与我相关
19 | 其他
20 |
21 | {/*
25 | xxx
26 |
30 | */}
31 |
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/views/tabs/index.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 |
3 | import Tabs from '../../../src/tabs/Tabs';
4 | import Tab from '../../../src/tabs/Tab';
5 | import Header from '../../../src/header/Header';
6 | import HeaderItem from '../../../src/header/HeaderItem';
7 | import Footer from '../../../src/footer/Footer';
8 | import FooterItem from '../../../src/footer/FooterItem';
9 | import ReactGestures from 'react-gestures';
10 | export default class Home extends Component {
11 | constructor(){
12 | super();
13 | this.state={
14 | activeKey:"1"
15 | }
16 | }
17 | onTabChange=(key)=>{
18 |
19 | }
20 | onSwipeLeft=()=>{
21 | alert("x11x");
22 | }
23 | render=()=>{
24 | let { activeKey } = this.state;
25 | return (
26 |
27 |
31 |
35 |
36 |
37 |
38 |
39 | 这是全部的标签页
40 |
41 |
42 |
43 | 这是未付款的标签页
44 | 这是已付款的标签页
45 |
46 |
47 |
48 |
49 | );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | module.exports = function(config){
3 | config.set({
4 | basePath: '',
5 | frameworks: [
6 | 'mocha',
7 | 'sinon-chai'
8 | ],
9 | files: [
10 | 'test/index.js'
11 | ],
12 | webpack:{
13 | devtool: 'inline-source-map',
14 | module: {
15 | loaders: [
16 | {
17 | test: /\.js$/,
18 | loader: 'babel-loader',
19 | exclude: /node_modules/
20 | }
21 | ]
22 | }
23 | },
24 | preprocessors: {
25 | 'test/index.js': [ 'webpack', 'sourcemap' ]
26 | },
27 | webpackServer: {
28 | noInfo: true
29 | },
30 | autoWatch: true,
31 | singleRun: true,
32 | port: 9876,
33 | colors: true,
34 | browsers: [ 'Chrome' ],
35 |
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/less/all.less:
--------------------------------------------------------------------------------
1 | @import url("sui/fonts.less");
2 | @import url("sui/variables.less");
3 |
4 | // Mixins
5 | @import url("sui/mixins.less");
6 |
7 | // Normalize & Base CSS
8 | @import url("sui/rem.less");
9 | @import url("sui/normalize.less");
10 | @import url("sui/base.less");
11 | @import url("sui/content-block.less");
12 |
13 | @import url("sui/grid.less");
14 |
15 |
16 | // Components
17 | //@import url("sui/text.less");
18 | @import url("sui/bars.less");
19 | //@import url("sui/badges.less");
20 | //@import url("sui/lists.less");
21 | //@import url("sui/forms.less");
22 | //@import url("sui/searchbar.less");
23 | @import url("sui/buttons.less");
24 | //@import url("sui/tabs.less");
25 |
26 | @import url("sui/pages.less");
27 | //@import url("sui/scroller.less");
28 | //@import url("sui/pull-to-refresh.less");
29 | //@import url("sui/infinite.less");
30 | //@import url("sui/modal.less");
31 | //@import url("sui/preloader.less");
32 | //@import url("sui/lists.less");
33 | //@import url("sui/cards.less");
34 | //@import url("sui/panels.less");
35 | //@import url("sui/calendar.less");
36 | //@import url("sui/picker.less");
37 |
38 |
39 |
40 | @import url("sui/themes.less");
41 | @import url("sui/colors.less");
42 |
43 |
44 |
45 | @import url("webui/index.less");
46 |
--------------------------------------------------------------------------------
/less/fonts/webui_iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liugenpeng/react-webui/31a06db62af65b2801272817871cd271ffae70bb/less/fonts/webui_iconfont.eot
--------------------------------------------------------------------------------
/less/fonts/webui_iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liugenpeng/react-webui/31a06db62af65b2801272817871cd271ffae70bb/less/fonts/webui_iconfont.ttf
--------------------------------------------------------------------------------
/less/fonts/webui_iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liugenpeng/react-webui/31a06db62af65b2801272817871cd271ffae70bb/less/fonts/webui_iconfont.woff
--------------------------------------------------------------------------------
/less/sui/accordion.less:
--------------------------------------------------------------------------------
1 | /* === Accordion === */
2 | .list-block {
3 | .accordion-item-toggle {
4 | cursor: pointer;
5 | transition-duration: 300ms;
6 | .item-inner {
7 | padding-right: 1.75rem;
8 | background: no-repeat -webkit-calc(~"100% - 15px") center;
9 | background: no-repeat calc(~"100% - 15px") center;
10 | .encoded-svg-background(" ");
11 | background-size: 0.5rem 1rem;
12 |
13 | }
14 | html:not(.watch-active-state) &:active, &.active-state {
15 | transition-duration: 0ms;
16 | background-color: #d9d9d9;
17 | > .item-inner {
18 | .hairline-color(bottom, transparent);
19 | }
20 | }
21 | }
22 | .accordion-item-toggle, .accordion-item > .item-link {
23 | .item-inner {
24 | transition-duration: 300ms;
25 | &:after {
26 | transition-duration: 300ms;
27 | }
28 | -webkit-transition-property: background-color;
29 | transition-property: background-color;
30 | }
31 | }
32 | .accordion-item-expanded {
33 | .accordion-item-toggle .item-inner, > .item-link .item-inner {
34 | .encoded-svg-background(" ");
35 | background-size: 1rem 1rem;
36 | .hairline-color(bottom, transparent);
37 | }
38 | }
39 | .accordion-item {
40 | .content-block, .list-block {
41 | margin-top: 0;
42 | margin-bottom: 0;
43 | }
44 | ul {
45 | padding-left: 0;
46 | }
47 | }
48 | }
49 | .accordion-item-content {
50 | position: relative;
51 | overflow: hidden;
52 | height: 0;
53 | font-size: 0.7rem;
54 | transition-duration: 300ms;
55 | transform: translate3d(0,0,0);
56 | .accordion-item-expanded > &{
57 | height: auto;
58 | }
59 | html.android-4 & {
60 | transform: none;
61 | }
62 | }
63 | .custom-accordion {
64 | padding-left: 0;
65 | padding-right: 0;
66 | .accordion-item-toggle {
67 | padding: 0 0.75rem;
68 | height: 2.2rem;
69 | line-height: 2.2rem;
70 | font-size: 0.85rem;
71 | color: @color-text;
72 | border-bottom: 1px solid rgba(0, 0, 0, 0.15);
73 | cursor: pointer;
74 | &:active {
75 | background: rgba(0, 0, 0, 0.15);
76 | }
77 | span {
78 | display: inline-block;
79 | margin-left: 0.75rem;
80 | }
81 | }
82 | .accordion-item{
83 | &:last-child{
84 | .accordion-item-toggle {
85 | border-bottom: none;
86 | }
87 | }
88 | }
89 | .icon-plus,
90 | .icon-minus {
91 | display: inline-block;
92 | width: 1.1rem;
93 | height: 1.1rem;
94 | border: 1px solid @color-text;
95 | border-radius: 100%;
96 | line-height: 1rem;
97 | text-align: center;
98 | &:before{
99 | content: "";
100 | }
101 | }
102 | .icon-minus {
103 | display: none;
104 | }
105 | .accordion-item-expanded{
106 | .icon-minus {
107 | display: inline-block;
108 | }
109 | .icon-plus {
110 | display: none;
111 | }
112 | }
113 | .accordion-item-content {
114 | padding: 0 0.75rem;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/less/sui/badges.less:
--------------------------------------------------------------------------------
1 | //
2 | // Badges
3 | // --------------------------------------------------
4 |
5 | .badge {
6 | display: inline-block;
7 | padding: 0.1rem 0.45rem 0.15rem;
8 | font-size: 0.6rem;
9 | line-height: 1;
10 | color: @color-text;
11 | background-color: rgba(0, 0, 0,.15);
12 | border-radius: 5rem;
13 |
14 | // Inverted badges have no background.
15 | &.badge-inverted {
16 | padding: 0 0.25rem 0 0;
17 | background-color: transparent;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/less/sui/bars.less:
--------------------------------------------------------------------------------
1 | //
2 | // Bars
3 | // --------------------------------------------------
4 |
5 | .bar {
6 | position: absolute;
7 | right: 0;
8 | left: 0;
9 | z-index: 10;
10 | height: @bar-base-height;
11 | padding-right: @bar-side-spacing;
12 | padding-left: @bar-side-spacing;
13 | background-color: #f7f7f8;
14 | .hairline(bottom, @border-default-color);
15 | -webkit-backface-visibility: hidden; // Make sure the bar is visible when a modal animates in.
16 | backface-visibility: hidden;
17 | }
18 |
19 | // Modifier class to dock any bar below .bar-nav
20 | .bar-header-secondary {
21 | top: @bar-base-height;
22 | }
23 |
24 | // Modifier class for footer bars
25 | .bar-footer {
26 | bottom: 0;
27 | }
28 |
29 |
30 | // Modifier class to dock any bar above a standard bar
31 | .bar-footer-secondary {
32 | bottom: @bar-base-height;
33 | }
34 |
35 | // Modifier class to dock any bar above a .bar-tab
36 | .bar-footer-secondary-tab {
37 | bottom: @bar-tab-height;
38 | }
39 |
40 | // Give the footers the correct border
41 | .bar-footer,
42 | .bar-footer-secondary,
43 | .bar-footer-secondary-tab {
44 | .hairline(top, @border-default-color);
45 | .hairline-remove(bottom);
46 | }
47 |
48 |
49 | // Nav bar
50 | // --------------------------------------------------
51 |
52 | // Bar docked to top of viewport for showing page title and actions
53 | .bar-nav {
54 | top: 0;
55 | }
56 |
57 | // Centered text in the .bar-nav
58 | //
59 | // We position the absolutely to make sure the title is always centered
60 | .title {
61 | position: absolute;
62 | display: block;
63 | width: 100%;
64 | padding: 0;
65 | margin: 0 (-@bar-side-spacing);
66 | font-size: @font-size-default;
67 | font-weight: @font-weight;
68 | line-height: @bar-base-height;
69 | color: @color-text;
70 | text-align: center;
71 | white-space: nowrap;
72 | }
73 | // Retain specified title color
74 | .title a {
75 | color: inherit;
76 | }
77 |
78 |
79 | // Tab bar
80 | // --------------------------------------------------
81 |
82 | // Bar docked to bottom and used for primary app navigation
83 | .bar-tab {
84 | bottom: 0;
85 | width: 100%;
86 | height: @bar-tab-height;
87 | padding: 0;
88 | table-layout: fixed;
89 | .hairline(top, @border-default-color);
90 | .hairline-remove(bottom);
91 |
92 | // Navigational tab (Nested to be more specific for the icons in tab-items)
93 | .tab-item {
94 | position: relative;
95 | display: table-cell;
96 | width: 1%;
97 | height: @bar-tab-height;
98 | color: #929292;
99 | text-align: center;
100 | vertical-align: middle;
101 |
102 | // Active states for the tab bar
103 | &.active,
104 | &:active {
105 | color: @color-primary;
106 | }
107 |
108 | // Activity badge on an icon
109 | .badge {
110 | position: absolute;
111 | top: .1rem;
112 | left: 50%;
113 | z-index: 100;
114 | height: .8rem;
115 | min-width: .8rem;
116 | padding: 0 .2rem;
117 | font-size: .6rem;
118 | line-height: .8rem;
119 | color: white;
120 | vertical-align: top;
121 | background: red;
122 | border-radius: .5rem;
123 | margin-left: .1rem;
124 | }
125 |
126 | // Tab icon
127 | .icon {
128 | top: 0.15rem;
129 | width: 1.2rem;
130 | height: 1.2rem;
131 | font-size: 1.2rem;
132 | line-height: 1.2rem;
133 | padding-top: 0;
134 | padding-bottom: 0;
135 |
136 | // Make the text smaller if it's used with an icon '
137 | ~ .tab-label {
138 | display: block;
139 | font-size: 0.55rem;
140 | position: relative;
141 | top: 0.15rem;
142 | }
143 | }
144 | }
145 | }
146 |
147 | // Bars with buttons
148 | // --------------------------------------------------
149 |
150 | .bar .button {
151 | position: relative;
152 | top: 0.35rem;
153 | z-index: 20; // Position the buttons on top of .title
154 | margin-top: 0;
155 | font-weight: @font-weight-light;
156 |
157 | // Give buttons that are floated left and right side margin
158 | &.pull-right {
159 | margin-left: @bar-side-spacing;
160 | }
161 | &.pull-left {
162 | margin-right: @bar-side-spacing;
163 | }
164 | }
165 |
166 | // Bars with link buttons (Line the text up with content)
167 | .bar .button-link {
168 | top: 0;
169 | padding: 0;
170 | font-size: 0.8rem;
171 | line-height: @bar-base-height;
172 | height: @bar-base-height;
173 | color: @color-primary;
174 | border: 0;
175 |
176 | &:active,
177 | &.active {
178 | color: darken(@color-primary, 10%);
179 | }
180 | }
181 |
182 | // Bars with block buttons
183 | //
184 | // Add proper padding
185 | .bar .button-block {
186 | top: 0.35rem;
187 | font-size: 0.8rem; // Scale down font size to fit in bar.
188 | width: 100%;
189 | }
190 |
191 | // Nav buttons (Only applicable within bars)
192 | //
193 | // Buttons inside bars that sit closer against the viewport.
194 | .bar .button-nav {
195 | &.pull-left {
196 | margin-left: -0.25rem;
197 |
198 | .icon-left-nav {
199 | margin-right: -0.15rem;
200 | }
201 | }
202 | &.pull-right {
203 | margin-right: -0.25rem;
204 |
205 | .icon-right-nav {
206 | margin-left: -0.15rem;
207 | }
208 | }
209 | }
210 |
211 |
212 | // Bars with Ratchicons
213 | // --------------------------------------------------
214 |
215 | .bar {
216 | .icon {
217 | position: relative;
218 | z-index: 20; // Position the buttons on top of .title
219 | padding: .5rem .1rem;
220 | font-size: 1rem;
221 | line-height: 1.2rem;
222 | }
223 |
224 | // Vertical center the larger icons in buttons.
225 | .button .icon {
226 | padding: 0;
227 | }
228 |
229 | // Handle carets in the titles
230 | .title .icon {
231 | padding: 0;
232 |
233 | // Specific postioning of the caret icon within a title. Used with popover.js.
234 | &.icon-caret {
235 | top: 0.2rem;
236 | margin-left: -0.25rem;
237 | }
238 | }
239 | }
240 |
241 | .bar-footer .icon {
242 | font-size: 1.2rem;
243 | line-height: 1.2rem;
244 | }
245 |
246 | // Bars for search forms
247 | // --------------------------------------------------
248 |
249 | // Position/size search bar within the bar
250 | .bar input[type="search"] {
251 | height: 1.45rem;
252 | margin: 0.3rem 0;
253 | }
254 |
--------------------------------------------------------------------------------
/less/sui/base.less:
--------------------------------------------------------------------------------
1 | //
2 | // Base styles
3 | // --------------------------------------------------
4 |
5 | // Use box sizing on all the things!
6 | * {
7 | box-sizing: border-box;
8 | -webkit-tap-highlight-color: rgba(0,0,0,0);
9 | -webkit-touch-callout:none;
10 | }
11 |
12 | // We fix position the body and scroll `.content`.
13 | body {
14 | position: absolute;
15 | top: 0;
16 | right: 0;
17 | bottom: 0;
18 | left: 0;
19 | font-family: @font-family-default;
20 | font-size: @font-size-default;
21 | line-height: 1.5;
22 | color: @color-text;
23 | background: @color-bg;
24 | overflow: hidden;
25 | }
26 |
27 | a, input, textarea, select, button {
28 | outline: 0;
29 | }
30 |
31 | p {
32 | margin: 1em 0;
33 | }
34 |
35 | // Universal link styling
36 | a {
37 | color: @color-link;
38 | text-decoration: none;
39 | -webkit-tap-highlight-color: rgba(0,0,0,0); // Removes the dark touch outlines on links in webkit browsers.
40 |
41 | &:active {
42 | color: @color-link-active;
43 | }
44 | }
45 |
46 | .page {
47 | position: absolute;
48 | top: 0;
49 | right: 0;
50 | bottom: 0;
51 | left: 0;
52 | background: @color-bg;
53 | z-index: 2000;
54 | }
55 |
56 | // Wrapper to be used around all content not in .bar-title and .bar-tab
57 | .content {
58 | position: absolute;
59 | top: 0;
60 | right: 0;
61 | bottom: 0;
62 | left: 0;
63 | overflow: auto;
64 | -webkit-overflow-scrolling: touch;
65 | }
66 |
67 | // Hack to force all relatively and absolutely positioned elements still render while scrolling
68 | // Note: This is a bug for "-webkit-overflow-scrolling: touch"
69 | .content > * {
70 | //transform: translateZ(0); //这一行会导致三星 S4 android 4.2 无法滚动
71 | }
72 |
73 | // Pad top/bottom of content so it doesn't hide behind bars.
74 | // Note: For these to work, content must come after both bars in the markup
75 | .bar-nav ~ .content {
76 | top: @bar-base-height;
77 | }
78 | .bar-header-secondary ~ .content {
79 | top: (@bar-base-height*2);
80 | }
81 |
82 | // Footer bar margin
83 | .bar-footer ~ .content {
84 | bottom: @bar-base-height;
85 | }
86 | .bar-footer-secondary ~ .content {
87 | bottom: (@bar-base-height*2);
88 | }
89 |
90 | // Tab bar margin
91 | .bar-tab ~ .content {
92 | bottom: @bar-tab-height;
93 | }
94 | .bar-footer-secondary-tab ~ .content {
95 | bottom: (@bar-tab-height+@bar-base-height);
96 | }
97 |
98 | // Utility classes
99 | .content-padded {
100 | margin: @bar-side-spacing;
101 | }
102 | .text-center {
103 | text-align: center;
104 | }
105 | .pull-left {
106 | float: left;
107 | }
108 | .pull-right {
109 | float: right;
110 | }
111 | .clearfix {
112 | .clearfix();
113 | }
114 |
--------------------------------------------------------------------------------
/less/sui/buttons.less:
--------------------------------------------------------------------------------
1 | //Buttons
2 | .button {
3 | @btn-height: 1.35rem;
4 | @btn-big-height: 2.4rem;
5 | border: 1px solid @color-primary;
6 | color: @color-primary;
7 | text-decoration: none;
8 | text-align: center;
9 | display: block;
10 | border-radius: 0.25rem;
11 | line-height: (@btn-height - 0.1rem);
12 | box-sizing: border-box;
13 | -webkit-appearance: none;
14 | -moz-appearance: none;
15 | -ms-appearance: none;
16 | appearance: none;
17 | background: none;
18 | padding: 0 0.5rem;
19 | margin: 0;
20 | height: @btn-height;
21 | white-space: nowrap;
22 | position: relative;
23 | text-overflow:ellipsis;
24 | font-size: 0.7rem;
25 | font-family: inherit;
26 | cursor: pointer;
27 | input[type="submit"]&, input[type="button"]&{
28 | width: 100%;
29 | }
30 |
31 | &:active {
32 | color: @color-primary-active;
33 | border-color: @color-primary-active;
34 | }
35 | &.button-round {
36 | border-radius: (@btn-height - 0.1rem);
37 | }
38 | &.active {
39 | &, &:active {
40 | color: @color-primary-active;
41 | border-color: @color-primary-active;
42 | }
43 | }
44 | &.button-big {
45 | font-size: 0.85rem;
46 | height: @btn-big-height;
47 | line-height: (@btn-big-height - 0.1rem);
48 | }
49 | &.button-fill {
50 | color:#fff;
51 | background: @color-primary;
52 | border: none;
53 | line-height: @btn-height;
54 | &.active, &:active {
55 | background: @color-primary-active;
56 | }
57 | &.button-big {
58 | line-height: @btn-big-height;
59 | }
60 | }
61 | .button-link {
62 | padding-top: 0.3rem;
63 | padding-bottom: 0.3rem;
64 | color: @color-primary;
65 | background-color: transparent;
66 | border: 0;
67 | }
68 | i.icon {
69 | &:first-child {
70 | margin-right: 0.5rem;
71 | }
72 | &:last-child {
73 | margin-left: 0.5rem;
74 | }
75 | &:first-child:last-child {
76 | margin-left: 0;
77 | margin-right: 0;
78 | }
79 | }
80 | }
81 |
82 | .button-variant(@color, @color-active) {
83 | border-color: @color;
84 | color: @color;
85 | &:active {
86 | border-color: @color-active;
87 | color: @color-active;
88 | }
89 | &.button-fill {
90 | color: white;
91 | background-color: @color;
92 | &:active {
93 | background-color: @color-active;
94 | }
95 | }
96 | }
97 | .button-themes() {
98 | &.button-light {
99 | .button-variant(@color-text-gray-light, @color-primary-active);
100 | color: @color-text-secondary;
101 | }
102 | &.button-dark {
103 | .button-variant(#6e727b, @color-primary-active);
104 | color: @color-text-secondary;
105 | }
106 | &.button-success {
107 | .button-variant(@color-success, @color-success-active);
108 | }
109 | &.button-danger {
110 | .button-variant(@color-danger, @color-danger-active);
111 | }
112 | &.button-warning {
113 | .button-variant(@color-warning, @color-warning-active);
114 | }
115 | }
116 | .button-themes();
117 |
118 | .button {
119 | &,
120 | &.button-primary,
121 | &.button-success,
122 | &.button-danger,
123 | &.button-warning {
124 | &.disabled {
125 | .button-variant(#c8c9cb, #c8c9cb);
126 | cursor: not-allowed;
127 | }
128 | }
129 | }
130 |
131 | .buttons-row,
132 | .buttons-tab {
133 | .align-self(center);
134 | .flexbox();
135 | .flex-wrap(nowrap);
136 | }
137 |
138 | .buttons-row {
139 | .button {
140 | border-radius: 0 0 0 0;
141 | margin-left: -1px;
142 | width: 100%;
143 | -webkit-box-flex:1;
144 | -ms-flex:1;
145 | border-color: @color-primary;
146 | color: @color-primary;
147 | &.active {
148 | background-color: @color-primary;
149 | color: white;
150 | z-index: 100;
151 | }
152 | &:active {
153 | }
154 | }
155 | .button:first-child {
156 | border-radius: 0.25rem 0 0 0.25rem;
157 | margin-left: 0;
158 | border-left-width: 1px;
159 | border-left-style: solid;
160 | }
161 | .button:last-child {
162 | border-radius: 0 0.25rem 0.25rem 0;
163 | }
164 | .button.button-round:first-child {
165 | border-radius: 1.35rem 0 0 1.35rem;
166 | }
167 | .button.button-round:last-child {
168 | border-radius: 0 1.35rem 1.35rem 0;
169 | }
170 | }
171 |
172 | .buttons-tab {
173 | background: white;
174 | position: relative;
175 | .hairline(bottom, #d0d0d0);
176 | .button {
177 | color: @color-text-secondary;
178 | font-size: 0.8rem;
179 | width: 100%;
180 | height: 2rem;
181 | line-height: 2rem;
182 | -webkit-box-flex:1;
183 | -ms-flex:1;
184 | border: 0;
185 | border-bottom: 2px solid transparent;
186 | border-radius: 0;
187 |
188 | &.active {
189 | color: @color-primary;
190 | border-color: @color-primary;
191 | z-index: 100;
192 | }
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/less/sui/calendar.less:
--------------------------------------------------------------------------------
1 | /* === Calendar === */
2 | .picker-calendar {
3 | background: #fff;
4 | height: 300px;
5 | width: 100%;
6 | overflow: hidden;
7 | @media (orientation: landscape) and (max-height: 415px) {
8 | &:not(.picker-modal-inline) {
9 | height: 220px;
10 | }
11 | }
12 | .picker-modal-inner {
13 | overflow: hidden;
14 | }
15 | }
16 | .popover.popover-picker-calendar {
17 | width: 320px;
18 | }
19 |
20 | .picker-calendar-week-days {
21 | height: 18px;
22 | background: #f7f7f8;
23 | .flexbox();
24 | .hairline(bottom, #c4c4c4);
25 | font-size: 11px;
26 | box-sizing: border-box;
27 | position: relative;
28 | .picker-calendar-week-day {
29 | .flex-shrink(1);
30 | width: 100% / 7;
31 | width: ~"-webkit-calc(100% / 7)";
32 | width: ~"-moz-calc(100% / 7)";
33 | width: ~"calc(100% / 7)";
34 | line-height: 17px;
35 | text-align: center;
36 | }
37 | + .picker-calendar-months {
38 | height: ~"-webkit-calc(100% - 18px)";
39 | height: ~"-moz-calc(100% - 18px)";
40 | height: ~"calc(100% - 18px)";
41 | }
42 | }
43 | .picker-calendar-months {
44 | width: 100%;
45 | height: 100%;
46 | overflow: hidden;
47 | position: relative;
48 | }
49 | .picker-calendar-months-wrapper {
50 | position: relative;
51 | width: 100%;
52 | height: 100%;
53 | transition: 300ms;
54 | }
55 | .picker-calendar-month {
56 | .flexbox();
57 | -webkit-box-orient: vertical;
58 | -moz-box-orient: vertical;
59 | -ms-flex-direction: column;
60 | -webkit-flex-direction: column;
61 | flex-direction: column;
62 | width: 100%;
63 | height: 100%;
64 | position: absolute;
65 | left: 0;
66 | top: 0;
67 | }
68 | .picker-calendar-row {
69 | height: 100% / 6;
70 | height: ~"-webkit-calc(100% / 6)";
71 | height: ~"-moz-calc(100% / 6)";
72 | height: ~"calc(100% / 6)";
73 | .flexbox();
74 | .flex-shrink(1);
75 | width: 100%;
76 | position: relative;
77 | .hairline(bottom, #ccc);
78 | &:last-child {
79 | .hairline-remove(bottom);
80 | }
81 | }
82 | .picker-calendar-day {
83 | .flex-shrink(1);
84 | .flexbox();
85 | .justify-content(center);
86 | .align-items(center);
87 | box-sizing: border-box;
88 | width: 100% / 7;
89 | width: ~"-webkit-calc(100% / 7)";
90 | width: ~"-moz-calc(100% / 7)";
91 | width: ~"calc(100% / 7)";
92 | text-align: center;
93 | color:@color-text;
94 | font-size: 15px;
95 | cursor: pointer;
96 | &.picker-calendar-day-weekend {
97 | }
98 | &.picker-calendar-day-prev, &.picker-calendar-day-next {
99 | color: @color-text-gray-light;
100 | }
101 | .picker-calendar-month-prev &, .picker-calendar-month-next & {
102 |
103 | }
104 | &.picker-calendar-day-disabled {
105 | color: #d4d4d4;
106 | cursor: auto;
107 | }
108 | &.picker-calendar-day-today span {
109 | background: #e3e3e3;
110 | }
111 | &.picker-calendar-day-selected span {
112 | background: @color-primary;
113 | color:#fff;
114 | }
115 | span {
116 | display: inline-block;
117 | border-radius: 100%;
118 | width: 30px;
119 | height: 30px;
120 | line-height: 30px;
121 |
122 | }
123 | }
124 | .picker-calendar-month-picker, .picker-calendar-year-picker {
125 | .flexbox();
126 | .align-items(center);
127 | .justify-content(space-between);
128 | width: 50%;
129 | max-width: 200px;
130 | .flex-shrink(10);
131 | a.icon-only {
132 | min-width: 36px;
133 | }
134 | span {
135 | .flex-shrink(1);
136 | position: relative;
137 | overflow: hidden;
138 | text-overflow: ellipsis;
139 | }
140 | }
141 | // Inline and popover borders
142 | .popover .picker-calendar, .picker-calendar.picker-modal-inline {
143 | .picker-calendar-week-days {
144 | background: none;
145 | }
146 | .toolbar, .picker-calendar-week-days {
147 | .hairline-remove(top);
148 | .hairline-remove(bottom);
149 | }
150 | .toolbar ~ .picker-modal-inner .picker-calendar-months, .picker-calendar-week-days ~ .picker-calendar-months {
151 | .hairline(top, #c4c4c4);
152 | }
153 | }
154 |
155 | //修复toolbar
156 | .picker-modal .toolbar-inner {
157 | height: 2.2rem;
158 | .flexbox();
159 | text-align: center;
160 | }
161 |
162 | //修复Android 4.1 上 toolbar元素宽度错误
163 | //因为它不能对 inline 的元素设置宽度
164 | .picker-calendar-month-picker, .picker-calendar-year-picker {
165 | display: block;
166 | line-height: 2.2rem;
167 |
168 | a.icon-only {
169 | float: left;
170 | width: 25%;
171 | height: 2.2rem;
172 | line-height: 2rem; //不知道为什么 2.2rem 无法上下对齐;
173 | }
174 | .current-month-value, .current-year-value {
175 | float: left;
176 | width: 50%;
177 | height: 2.2rem;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/less/sui/cards.less:
--------------------------------------------------------------------------------
1 | /* === Cards === */
2 | .cards-list, .card .list-block {
3 | ul {
4 | background: none;
5 | }
6 | > ul {
7 | .hairline-remove(top);
8 | .hairline-remove(bottom);
9 | }
10 | }
11 | .card {
12 | background: #fff;
13 | box-shadow: 0 0.05rem 0.1rem rgba(0,0,0,0.3);
14 | margin: 0.5rem;
15 | position: relative;
16 | border-radius: 0.1rem;
17 | font-size: 0.7rem;
18 | .list-block, .content-block {
19 | margin: 0;
20 | }
21 | .row:not(.no-gutter) .col > & {
22 | margin-left: 0;
23 | margin-right: 0;
24 | }
25 | }
26 | .card-content {
27 | position: relative;
28 | }
29 | .card-content-inner {
30 | padding: 0.75rem;
31 | position: relative;
32 | > p:first-child {
33 | margin-top: 0;
34 | }
35 | > p:last-child {
36 | margin-bottom: 0;
37 | }
38 | > .list-block, >.content-block {
39 | margin: -0.75rem;
40 | }
41 | }
42 | .card-header, .card-footer {
43 | min-height: 2.2rem;
44 | position: relative;
45 | padding: 0.5rem 0.75rem;
46 | box-sizing: border-box;
47 | .flexbox();
48 | .justify-content(space-between);
49 | .align-items(center);
50 | &[valign="top"] {
51 | .align-items(flex-start);
52 | }
53 | &[valign="bottom"] {
54 | .align-items(flex-end);
55 | }
56 | a.link {
57 | line-height: 2.2rem;
58 | height: 2.2rem;
59 | text-decoration: none;
60 | position: relative;
61 | margin-top: -0.5rem;
62 | margin-bottom: -0.5rem;
63 | .flexbox();
64 | .justify-content(flex-start);
65 | .align-items(center);
66 | transition-duration: 300ms;
67 | html:not(.watch-active-state) &:active, &.active-state {
68 | opacity: 0.3;
69 | transition-duration: 0ms;
70 | }
71 | i+span, i+i, span+i, span+span {
72 | margin-left: 0.35rem;
73 | }
74 | i.icon {
75 | display: block;
76 | }
77 | }
78 | a.icon-only {
79 | min-width: 2.2rem;
80 | .flexbox();
81 | .justify-content(center);
82 | .align-items(center);
83 | margin: 0;
84 | }
85 | }
86 | .card-header {
87 | border-radius: 0.1rem 0.1rem 0 0;
88 | font-size: 0.85rem;
89 | .hairline(bottom, #e1e1e1);
90 | .card-cover {
91 | width: 100%;
92 | display: block;
93 | }
94 | &.no-border {
95 | .hairline-remove(bottom);
96 | }
97 | &.no-padding {
98 | padding: 0;
99 | }
100 | }
101 | .card-footer {
102 | border-radius: 0 0 0.1rem 0.1rem;
103 | color: @color-text-secondary;
104 | .hairline(top, #e1e1e1);
105 | &.no-border {
106 | .hairline-remove(top);
107 | }
108 |
109 | }
110 |
111 | .facebook-card{
112 | .card-header {
113 | display: block;
114 | padding: 0.5rem;
115 | }
116 | .facebook-avatar {
117 | float: left;
118 | }
119 | .facebook-name {
120 | margin-left: 2.2rem;
121 | font-size: 0.7rem;
122 | font-weight: 500;
123 | }
124 | .facebook-date {
125 | margin-left: 2.2rem;
126 | font-size: 0.65rem;
127 | color: @color-text-secondary;
128 | }
129 | .card-footer {
130 | background: #fafafa;
131 | }
132 | .card-footer{
133 | a {
134 | color: @color-text-secondary;
135 | font-weight: 500;
136 | }
137 | }
138 | .card-content {
139 | img {
140 | display: block;
141 | }
142 | }
143 | .card-content-inner {
144 | padding: 0.75rem 0.5rem;
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/less/sui/colors.less:
--------------------------------------------------------------------------------
1 | /* === Color Themes === */
2 | .theme-mixin(@colorName, @color, @colorHex) {
3 | //Plain color and links
4 | //Buttons
5 | .theme-@{colorName} .button:not(.button-fill) {
6 | border-color: @color;
7 | color: @color;
8 | &:active {
9 | background-color: rgba(red(@color), green(@color), blue(@color), 0.15);
10 | }
11 | &.active {
12 | background-color: @color;
13 | color:#fff;
14 | }
15 | //恢复功能按钮的颜色
16 | .button-themes();
17 | }
18 | .theme-@{colorName} .button.button-fill {
19 | background: @color;
20 | color:#fff;
21 | //恢复功能按钮的颜色
22 | .button-themes();
23 | }
24 | //Icons
25 | .theme-@{colorName} {
26 | i.icon, i.icon& {
27 | color:@color;
28 | }
29 | }
30 | // Theme
31 | .theme-@{colorName} {
32 | a, .item-link.list-button {
33 | color: @color;
34 | }
35 | .bar& {
36 | a, a i {
37 | color:inherit;
38 | }
39 | a.active, a.active i {
40 | color:@color;
41 | }
42 | }
43 | .tab-item.active {
44 | color: @color;
45 | }
46 | .range-slider, .range-slider& {
47 | input[type="range"]::-webkit-slider-thumb:before {
48 | background-color: @color;
49 | }
50 | }
51 | .picker-calendar-day.picker-calendar-day-selected span {
52 | background-color: @color !important;
53 | }
54 | .buttons-tab:after {
55 | background: @color;
56 | }
57 |
58 | .modal-button {
59 | color: @color;
60 | }
61 | .actions-modal-button:not(.color-danger):not(.bg-danger) {
62 | color: @color;
63 | }
64 | }
65 | .swiper-pagination {
66 | .theme-@{colorName} & {
67 | .swiper-pagination-bullet-active {
68 | background-color: @color;
69 | }
70 | }
71 | }
72 | .swiper-button-next, .swiper-container-rtl .swiper-button-prev {
73 | .theme-@{colorName} & {
74 | .encoded-svg-background(" ");
75 | }
76 | }
77 | .swiper-button-prev, .swiper-container-rtl .swiper-button-next {
78 | .theme-@{colorName} & {
79 | .encoded-svg-background(" ");
80 | }
81 | }
82 | }
83 | .theme-mixin(e('green'), #3cac46, '3cac46');
84 | .theme-mixin(e('pink'), #d94b73, 'd94b73');
85 | .theme-mixin(e('yellow'), #efb51e, 'efb51e');
86 |
--------------------------------------------------------------------------------
/less/sui/content-block.less:
--------------------------------------------------------------------------------
1 | /* === Content Block === */
2 | @contentBlockBorderColor: #c8c7cc;
3 | @contentBlockColor: #6d6d72;
4 | @contentBlockTitle: @contentBlockColor;
5 | .content-block {
6 | margin: 1.75rem 0;
7 | padding: 0 0.75rem;
8 | color: @contentBlockTitle;
9 |
10 | }
11 | .content-block-title {
12 | position: relative;
13 | overflow: hidden;
14 | margin: 0;
15 | white-space: nowrap;
16 | text-overflow: ellipsis;
17 | font-size: 0.7rem;
18 | text-transform: uppercase;
19 | line-height: 1;
20 | color: @contentBlockColor;
21 | margin: 1.75rem 0.75rem 0.5rem;
22 | + .list-block, + .content-block, +.card {
23 | margin-top: 0.5rem;
24 | }
25 | }
26 | .content-block-inner {
27 | background: #fff;
28 | padding: 0.5rem 0.75rem;
29 | margin-left: -0.75rem;
30 | width: 100%;
31 | position: relative;
32 | .hairline(top, @contentBlockBorderColor);
33 | .hairline(bottom, @contentBlockBorderColor);
34 | color: @color-text;
35 | }
36 | .content-block.inset {
37 | margin-left: 0.75rem;
38 | margin-right: 0.75rem;
39 | border-radius: 0.35rem;
40 | .content-block-inner {
41 | .hairline-remove(top);
42 | .hairline-remove(bottom);
43 | border-radius: 0.35rem;
44 | }
45 | }
46 | @media all and (min-width:768px) {
47 | .content-block.tablet-inset {
48 | margin-left: 0.75rem;
49 | margin-right: 0.75rem;
50 | border-radius: 0.35rem;
51 | }
52 |
53 | .content-block.tablet-inset .content-block-inner {
54 | .hairline-remove(top);
55 | .hairline-remove(bottom);
56 | border-radius: 0.35rem;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/less/sui/demos.less:
--------------------------------------------------------------------------------
1 | .grid-demo .row {
2 | text-align: center;
3 | +.row {
4 | margin-top: 0.75rem;
5 | }
6 | > [class*=col-] {
7 | border: 1px solid #ddd;
8 | }
9 | }
10 |
11 | .icons-demo .icon {
12 | width: 2.5rem;
13 | height: 2.5rem;
14 | margin: 0.15rem;
15 | font-size: 1.2rem;
16 | line-height: 2.5rem;
17 | text-align: center;
18 | background-color: #fff;
19 | border: 1px solid #ddd;
20 | border-radius: 1.25rem;
21 | display: inline-block;
22 | }
23 |
--------------------------------------------------------------------------------
/less/sui/docs-baichuan.less:
--------------------------------------------------------------------------------
1 | @blue: #0089cd;
2 | .page-baichuan {
3 | color: #333;
4 |
5 | a {
6 | color: @blue;
7 | &:hover {
8 | color: #f60;
9 | }
10 | }
11 | .header {
12 | color: white;
13 | text-align: center;
14 | position: relative;
15 | height: 300px;
16 |
17 | .bg, .overlay {
18 | position: absolute;
19 | top: 0;
20 | right: 0;
21 | bottom: 0;
22 | left: 0;
23 | z-index: 1;
24 | }
25 | .bg {
26 | background: url(//gtms04.alicdn.com/tps/i4/TB15BwTIpXXXXXtXXXXdrcn8XXX-1196-304.png);
27 | background-repeat: no-repeat;
28 | background-position: center center;
29 | }
30 | .overlay {
31 | z-index: 2;
32 | background: radial-gradient(rgba(0,0,0,.6), rgba(0,0,0,.8));
33 | }
34 | h2 {
35 | position: absolute;
36 | z-index: 3;
37 | font-size: 48px;
38 | font-weight: normal;
39 | margin: 0;
40 | padding: 0;
41 | top: 50%;
42 | left: 50%;
43 | margin-top: -36px;
44 | margin-left: -200px;
45 | }
46 | }
47 | p {
48 | margin: 0.5em 0;
49 | }
50 | .sub-header {
51 | background: #efefef;
52 | text-align: center;
53 | padding: 26px 0;
54 | font-size: 16px;
55 | h2 {
56 | font-size: 30px;
57 | font-weight: normal;
58 | margin: 10px;
59 | }
60 | }
61 | article {
62 | overflow: hidden;
63 | height: 510px;
64 |
65 | .article-inner {
66 | width: 960px;
67 | margin: auto;
68 | }
69 |
70 | &:nth-child(even) {
71 | background: rgba(0, 0, 0, .1);
72 |
73 | .monitor {
74 | float: right;
75 | }
76 |
77 | .phone {
78 | margin-left: 100px;
79 | }
80 |
81 | .text {
82 | padding-left: 50px;
83 | }
84 | }
85 | .monitor, .text {
86 | float: left;
87 | width: 50%;
88 | text-align: center;
89 | }
90 |
91 | .text {
92 | text-align: left;
93 | padding: 115px 0;
94 | font-size: 16px;
95 | h4 {
96 | font-size: 20px;
97 | margin: 10px 0;
98 | }
99 | .text-gray {
100 | margin: 30px 0 15px;
101 | font-size: 14px;
102 | }
103 | }
104 |
105 | .phone {
106 | margin-top: 110px;
107 | width: 228px;
108 | height: 401px;
109 | position: relative;
110 | border: 1px solid #999;
111 | border-radius: 28px 28px 0 0;
112 | background: white;
113 | &:after {
114 | content: " ";
115 | background: url(//gtms01.alicdn.com/tps/i1/TB1MT84IFXXXXaBXVXXG_XNJXXX-79-33.png) no-repeat;
116 | width: 79px;
117 | height: 33px;
118 | position: absolute;
119 | top: 10px;
120 | left: 50%;
121 | margin-left: -36px;
122 | }
123 | img {
124 | width: 198px;
125 | margin-top: 50px;
126 | border: 1px solid #aaa;
127 | border-bottom: 0;
128 | }
129 | .indicator {
130 | background: rgba(5, 200, 200, .3);
131 | border: 2px solid #12c1fa;
132 | position: absolute;
133 | top: 65px;
134 | left: 14px;
135 | width: 200px;
136 | height: 31px;
137 | display: none;
138 | }
139 | }
140 | .code {
141 | box-shadow: 0 0 3px 3px rgba(0,0,0,.1);
142 | width: 150px;
143 | }
144 | }
145 |
146 | .text-gray {
147 | color: #999;
148 | }
149 |
150 | .tabs {
151 | list-style: none;
152 | margin: 0 auto;
153 | max-width: 1400px;
154 | font-size: 20px;
155 | font-weight: bold;
156 | height: 80px;
157 |
158 | li {
159 | float: left;
160 | }
161 |
162 | a {
163 | display: inline-block;
164 | height: 80px;
165 | line-height: 40px;
166 | padding: 20px;
167 | color: #333;
168 | }
169 |
170 | li.active a {
171 | background: #319af5;
172 | color: white;
173 | }
174 | }
175 |
176 | .footer-second {
177 | //background: #3f4a53;
178 | background: #efefef;
179 | overflow: hidden;
180 | padding: 50px;
181 | text-align: center;
182 | font-size: 18px;
183 |
184 | .btn {
185 | display: inline-block;
186 | height: 42px;
187 | line-height: 42px;
188 | width: 120px;
189 | background: @blue;
190 | color: white;
191 | margin-top: 20px;
192 |
193 | &:hover {
194 | background: darken(@blue, 5%);
195 | }
196 | }
197 |
198 | &.fixed {
199 | position: fixed;
200 | bottom: 0;
201 | left: 0;
202 | right: 0;
203 | opacity: .8;
204 | }
205 | }
206 |
207 | .design {
208 | padding: 20px 0 70px 0;
209 | text-align: left;
210 | width: 960px;
211 | margin: auto;
212 |
213 | ul {
214 | margin: 0;
215 | padding: 0;
216 | list-style: none;
217 | }
218 |
219 | li {
220 | border: 2px solid #ccc;
221 | display: inline-block;
222 | position: relative;
223 | text-align: center;
224 |
225 | }
226 |
227 | a {
228 | display: block;
229 | width: 450px;
230 | margin: 0 auto;
231 | position: relative;
232 | color: #333;
233 | padding: 30px 50px;
234 | }
235 |
236 | .icon {
237 | position: absolute;
238 | height: 84px;
239 | line-height: 84px;
240 | width: 84px;
241 | border: 2px solid #ccc;
242 | border-radius: 100%;
243 | top: 50%;
244 | margin-top: -40px;
245 | left: 90px;
246 | font-size: 36px;
247 | color: #ccc;
248 | }
249 |
250 | .contents {
251 | margin-left: 160px;
252 | text-align: left;
253 |
254 | h4 {
255 | font-size: 20px;
256 | font-weight: normal;
257 | margin: 0;
258 | }
259 | }
260 |
261 | h2 {
262 | font-size: 20px;
263 | font-weight: normal;
264 | }
265 | p {
266 | font-size: 14px;
267 | color: #999;
268 | }
269 |
270 | li:hover {
271 | border-color: @blue;
272 | .icon {
273 | border-color: @blue;
274 | color: @blue;
275 | }
276 | }
277 | }
278 |
279 | .share {
280 | padding: 40px 0 70px 0;
281 | width: 960px;
282 | margin: auto;
283 |
284 | h2 {
285 | margin: 20px 0;
286 | font-size: 20px;
287 | }
288 |
289 | .img {
290 | width: 224px;
291 | height: 127px;
292 | display: block;
293 | border: 1px solid #ccc;
294 | position: relative;
295 | }
296 |
297 | .overlay {
298 | position: absolute;
299 | left: 0;
300 | right: 0;
301 | top: 0;
302 | bottom: 0;
303 | display: none;
304 | background: rgba(44, 120, 255, .8);
305 |
306 | .download {
307 | width: 100px;
308 | height: 38px;
309 | line-height: 38px;
310 | text-align: center;
311 | border: 1px solid white;
312 | color: white;
313 | position: absolute;
314 | left: 50%;
315 | top: 50%;
316 | margin-left: -50px;
317 | margin-top: -16px;
318 | font-size: 16px;
319 | }
320 | }
321 |
322 | .img:hover .overlay {
323 | display: block;
324 | }
325 |
326 | img {
327 | display: block;
328 | }
329 |
330 | ul {
331 | font-size: 14px;
332 | list-style: none;
333 | margin: 0;
334 | padding: 0;
335 | overflow: hidden;
336 | }
337 |
338 | li {
339 | text-align: center;
340 | float: left;
341 | width: 224px;
342 | overflow: hidden;
343 | + li {
344 | margin-left: 21px;
345 | }
346 | }
347 |
348 | h4 {
349 | font-size: 14px;
350 | margin-top: 10px;
351 | margin-bottom: 0;
352 | width: 300px;
353 | margin-left: -38px;
354 | }
355 | p {
356 | margin: 0;
357 | }
358 | }
359 |
360 | .footer {
361 | background: #3f4a53;
362 | overflow: hidden;
363 | text-align: center;
364 | color: white;
365 | padding: 30px 0;
366 |
367 | .links,
368 | .copyright {
369 | margin: 10px 0;
370 | }
371 |
372 | a {
373 | display: inline-block;
374 | margin: 0 10px;
375 | }
376 | a {
377 | color: white;
378 | &:hover {
379 | text-decoration: underline;
380 | }
381 | }
382 | }
383 | }
384 |
--------------------------------------------------------------------------------
/less/sui/fonts.less:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "iconfont-sm";
3 | src: url('../fonts/webui_iconfont.eot'); /* IE9*/
4 | src: url('../fonts/webui_iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('../fonts/webui_iconfont.woff') format('woff'), /* chrome、firefox */
6 | url('../fonts/webui_iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
7 | url('../fonts/webui_iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .icon {
11 | font-family:"iconfont-sm" !important;
12 | font-style:normal;
13 | -webkit-font-smoothing: antialiased;
14 | -webkit-text-stroke-width: 0.2px;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | .icon-app:before { content: "\e605"; }
19 | .icon-browser:before { content: "\e606"; }
20 | .icon-card:before { content: "\e607"; }
21 | .icon-cart:before { content: "\e600"; }
22 | .icon-code:before { content: "\e609"; }
23 | .icon-computer:before { content: "\e616"; }
24 | .icon-remove:before { content: "\e60a"; }
25 | .icon-download:before { content: "\e60b"; }
26 | .icon-edit:before { content: "\e60c"; }
27 | .icon-emoji:before { content: "\e615"; }
28 | .icon-star:before { content: "\e60e"; }
29 | .icon-friends:before { content: "\e601"; }
30 | .icon-gift:before { content: "\e618"; }
31 | .icon-phone:before { content: "\e60f"; }
32 | .icon-clock:before { content: "\e619"; }
33 | .icon-home:before { content: "\e602"; }
34 | .icon-menu:before { content: "\e60d"; }
35 | .icon-message:before { content: "\e617"; }
36 | .icon-me:before { content: "\e603"; }
37 | .icon-picture:before { content: "\e61a"; }
38 | .icon-share:before { content: "\e61b"; }
39 | .icon-settings:before { content: "\e604"; }
40 | .icon-refresh:before { content: "\e61c"; }
41 | .icon-caret:before { content: "\e610"; }
42 | .icon-down:before { content: "\e611"; }
43 | .icon-up:before { content: "\e612"; }
44 | .icon-right:before { content: "\e613"; }
45 | .icon-left:before { content: "\e614"; }
46 | .icon-check:before { content: "\e608"; }
47 | .icon-search:before { content: "\e61d"; }
48 | .icon-new:before { content: "\e61e"; }
49 |
--------------------------------------------------------------------------------
/less/sui/forms.less:
--------------------------------------------------------------------------------
1 | /* === Forms === */
2 | // Inputs
3 | .list-block {
4 | input[type="text"], input[type="password"], input[type="search"], input[type="email"], input[type="tel"], input[type="url"], input[type="date"], input[type="datetime-local"], input[type="time"], input[type="number"], select, textarea {
5 | -webkit-appearance: none;
6 | -moz-appearance: none;
7 | -ms-appearance: none;
8 | appearance: none;
9 | box-sizing: border-box;
10 | border: none;
11 | background: none;
12 | border-radius: 0 0 0 0;
13 | box-shadow: none;
14 | display: block;
15 | padding: 0 0 0 0.25rem;
16 | margin: 0;
17 | width: 100%;
18 | height: 2.15rem;
19 | color: @color-text;
20 | font-size: 0.85rem;
21 | font-family: inherit;
22 | }
23 | input[type="date"], input[type="datetime-local"] {
24 | line-height: 2.2rem;
25 | }
26 | select {
27 | -webkit-appearance: none;
28 | -moz-appearance: none;
29 | -ms-appearance: none;
30 | appearance: none;
31 | }
32 | .label {
33 | vertical-align: top;
34 | }
35 | textarea {
36 | height: 5rem;
37 | resize:none;
38 | line-height: 1.4;
39 | padding-top: 0.4rem;
40 | padding-bottom: 0.35rem;
41 | }
42 | }
43 |
44 | //Switch
45 | .label-switch {
46 | display: inline-block;
47 | vertical-align: middle;
48 | width: 2.6rem;
49 | border-radius: 0.8rem;
50 | box-sizing: border-box;
51 | height: 1.6rem;
52 | position: relative;
53 | cursor: pointer;
54 | .align-self(center);
55 | .checkbox {
56 | width: 2.6rem;
57 | border-radius: 0.8rem;
58 | box-sizing: border-box;
59 | height: 1.6rem;
60 | background: #e5e5e5;
61 | z-index: 0;
62 | margin: 0;
63 | padding: 0;
64 | -webkit-appearance: none;
65 | -moz-appearance: none;
66 | -ms-appearance: none;
67 | appearance: none;
68 | border:none;
69 | cursor: pointer;
70 | position: relative;
71 | transition-duration: 300ms;
72 | &:before {
73 | content:' ';
74 | position: absolute;
75 | left: 0.1rem;
76 | top: 0.1rem;
77 | width: 2.4rem;
78 | border-radius: 0.8rem;
79 | box-sizing: border-box;
80 | height: 1.4rem;
81 | background: #fff;
82 | z-index: 1;
83 | transition-duration: 300ms;
84 | transform: scale(1);
85 | }
86 | &:after {
87 | content:' ';
88 | height: 1.4rem;
89 | width: 1.4rem;
90 | border-radius: 1.4rem;
91 | background: #fff;
92 | position: absolute;
93 | z-index: 2;
94 | top: 0.1rem;
95 | left: 0.1rem;
96 | box-shadow: 0 0.1rem 0.25rem rgba(0,0,0,0.4);
97 | transform: translateX(0px);
98 | transition-duration: 300ms;
99 | }
100 | }
101 | input[type="checkbox"] {
102 | opacity: 0;
103 | position: absolute;
104 | width: 2.6rem;
105 | height: 1.6rem;
106 | z-index: 1;
107 | &:checked {
108 | &+ .checkbox {
109 | background: @color-success;
110 | &:before {
111 | transform: scale(0);
112 | }
113 | &:after {
114 | transform: translateX(1.1rem);
115 | }
116 | }
117 | }
118 | }
119 | }
120 | html.android {
121 | .label-switch input[type="checkbox"] {
122 | &+ .checkbox {
123 | transition-duration: 0;
124 | &:after, &:before {
125 | transition-duration: 0;
126 | }
127 | }
128 | }
129 | }
130 |
131 | // Slider
132 | .range-slider {
133 | width: 100%;
134 | position: relative;
135 | overflow: hidden;
136 | padding-left: 0.15rem;
137 | padding-right: 0.15rem;
138 | margin-left: -1px;
139 | .align-self(center);
140 | input[type="range"] {
141 | position: relative;
142 | height: 1.4rem;
143 | width: 100%;
144 | margin: 0.2rem 0 0.25rem 0;
145 | -webkit-appearance: none;
146 | -moz-appearance: none;
147 | -ms-appearance: none;
148 | appearance: none;
149 | background: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(0, #b7b8b7), color-stop(100%, #b7b8b7));
150 | background: linear-gradient(to right, #b7b8b7 0, #b7b8b7 100%);
151 | background-position: center;
152 | background-size: 100% 0.1rem;
153 | background-repeat: no-repeat;
154 | outline: 0;
155 | }
156 | input[type="range"]:after {
157 | height: 0.1rem;
158 | background: #fff;
159 | content:' ';
160 | width: 0.25rem;
161 | top: 50%;
162 | margin-top: -1px;
163 | left: -0.25rem;
164 | z-index: 1;
165 | position: absolute;
166 | }
167 | input[type="range"]::-webkit-slider-thumb {
168 | -webkit-appearance: none;
169 | -moz-appearance: none;
170 | -ms-appearance: none;
171 | appearance: none;
172 | border: none;
173 | height: 1.4rem;
174 | width: 1.4rem;
175 | position: relative;
176 | background: none;
177 | }
178 | input[type="range"]::-webkit-slider-thumb:after {
179 | height: 1.4rem;
180 | width: 1.4rem;
181 | border-radius: 1.4rem;
182 | background: #fff;
183 | z-index: 10;
184 | box-shadow: 0 0.1rem 0.2rem rgba(0,0,0,0.4);
185 | position: absolute;
186 | left: 0;
187 | top: 0;
188 | content: ' ';
189 | }
190 |
191 | input[type="range"]::-webkit-slider-thumb:before {
192 | position: absolute;
193 | top: 50%;
194 | right: 100%;
195 | width: 100rem;
196 | height: 0.1rem;
197 | margin-top: -1px;
198 | z-index: 1;
199 | background: @color-primary;
200 | content: ' ';
201 | }
202 | }
203 |
204 | // Checkboxes
205 | label.label-checkbox {
206 | cursor: pointer;
207 | i.icon-form-checkbox {
208 | width: 1.1rem;
209 | height: 1.1rem;
210 | position: relative;
211 | border-radius: 1.1rem;
212 | border: 1px solid #c7c7cc;
213 | box-sizing: border-box;
214 |
215 | &:after {
216 | content:' ';
217 | position: absolute;
218 | left: 50%;
219 | margin-left: -0.3rem;
220 | top: 50%;
221 | margin-top: -0.2rem;
222 | width: 0.6rem;
223 | height: 0.45rem;
224 | }
225 | }
226 | input[type="checkbox"], input[type="radio"] {
227 | display: none;
228 | &:checked + .item-media{
229 | i.icon-form-checkbox {
230 | border: none;
231 | background-color: @color-primary;
232 | }
233 | i.icon-form-checkbox:after {
234 | background: no-repeat center;
235 | .encoded-svg-background(" ");
236 | -webkit-background-size: 0.6rem 0.45rem;
237 | background-size: 0.6rem 0.45rem;
238 | }
239 | }
240 | }
241 | }
242 | label.label-checkbox {
243 | transition-duration: 300ms;
244 | html:not(.watch-active-state) &:active, &.active-state {
245 | transition: 0ms;
246 | background-color: #d9d9d9;
247 | .item-inner {
248 | .hairline-color(bottom, transparent);
249 | }
250 | }
251 | }
252 |
253 | // Smart selects
254 | .smart-select {
255 | select {
256 | display: none;
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/less/sui/grid.less:
--------------------------------------------------------------------------------
1 | /* === Grid === */
2 | .row {
3 | overflow: hidden;
4 | margin-left: -4%;
5 | > [class*="col-"], > [class*="tablet-"] {
6 | box-sizing: border-box;
7 | float: left;
8 | }
9 | &.no-gutter {
10 | margin-left: 0;
11 | }
12 | }
13 | @cols: 5, 10, 15, 20, 25, 100/3, 40, 50, 60, 100*(2/3), 75, 80, 85, 90, 95, 100;
14 | .row {
15 | .-(@i: length(@cols)) when (@i > 0) {
16 | @divider: e(extract(@cols, @i));
17 | @className: `Math.floor(@{divider})`;
18 | @n: `100/parseFloat(@{divider})`;
19 | @n-1: @n - 1;
20 | @gutter: `4.0`;
21 | @d: `(100-@{gutter}*@{n})/@{n}`;
22 | .col-@{className} {
23 | width: ~"@{d}%";
24 | margin-left: ~"@{gutter}%";
25 | }
26 | &.no-gutter {
27 | @d: `100/@{n}`;
28 | .col-@{className} {
29 | width: ~"@{d}%";
30 | margin: 0;
31 | }
32 | }
33 | .-((@i - 1));
34 | } .-;
35 | }
36 | @media all and (min-width:768px) {
37 | .row {
38 | margin-left: -2%;
39 | }
40 | .row {
41 | .-(@i: length(@cols)) when (@i > 0) {
42 | @divider: e(extract(@cols, @i));
43 | @className: `Math.floor(@{divider})`;
44 | @n: `100/parseFloat(@{divider})`;
45 | @n-1: @n - 1;
46 | @gutter: `2.0`;
47 | @d: `(100-@{gutter}*@{n})/@{n}`;
48 | .col-@{className} {
49 | width: ~"@{d}%";
50 | margin-left: ~"@{gutter}%";
51 | }
52 | &.no-gutter {
53 | @d: `100/@{n}`;
54 | .col-@{className} {
55 | width: ~"@{d}%";
56 | margin: 0;
57 | }
58 | }
59 | .-((@i - 1));
60 | } .-;
61 | }
62 | .row {
63 | .-(@i: length(@cols)) when (@i > 0) {
64 | @divider: e(extract(@cols, @i));
65 | @className: `Math.floor(@{divider})`;
66 | @n: `100/parseFloat(@{divider})`;
67 | @n-1: @n - 1;
68 | @gutter: `2.0`;
69 | @d: `(100-@{gutter}*@{n})/@{n}`;
70 | .tablet-@{className} {
71 | width: ~"@{d}%";
72 | margin-left: ~"@{gutter}%";
73 | }
74 | &.no-gutter {
75 | @d: `100/@{n}`;
76 | .tablet-@{className} {
77 | width: ~"@{d}%";
78 | margin: 0;
79 | }
80 | }
81 | .-((@i - 1));
82 | } .-;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/less/sui/icons.less:
--------------------------------------------------------------------------------
1 | /* === Icons === */
2 | i.icon {
3 | display: inline-block;
4 | vertical-align: middle;
5 | background-size: 100% auto;
6 | background-position: center;
7 | background-repeat: no-repeat;
8 | font-style: normal;
9 | position: relative;
10 |
11 |
12 | &.icon-next, &.icon-prev {
13 | width: 0.75rem;
14 | height: 0.75rem;
15 | }
16 | &.icon-next {
17 | .encoded-svg-background(" ");
18 | }
19 | &.icon-prev {
20 | .encoded-svg-background(" ");
21 | }
22 | &.icon-plus {
23 | width: 1.25rem;
24 | height: 1.25rem;
25 | font-size: 1.55rem;
26 | line-height: 1rem;
27 | text-align: center;
28 | font-weight: 100;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/less/sui/infinite.less:
--------------------------------------------------------------------------------
1 | .infinite-scroll-preloader {
2 | margin: 0.5rem;
3 | text-align: center;
4 | .preloader {
5 | width: 1.5rem;
6 | height: 1.5rem;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/less/sui/lists.less:
--------------------------------------------------------------------------------
1 | /* === Lists === */
2 | @listBlockBorderColor: @color-split;
3 | @listBlockBg: #fff;
4 | @dividerBg: #F7F7F7;
5 | @dividerColor: @color-split;
6 | .list-block {
7 | margin: 1.75rem 0;
8 | font-size: 0.85rem;
9 | ul {
10 | background: @listBlockBg;
11 | list-style: none;
12 | padding: 0;
13 | margin: 0;
14 | position: relative;
15 | .hairline(top, @listBlockBorderColor);
16 | .hairline(bottom, @listBlockBorderColor);
17 | ul {
18 | .hairline-remove(top);
19 | .hairline-remove(bottom);
20 | padding-left: 2.25rem;
21 | }
22 | }
23 |
24 | .align-top, .align-top .item-content, .align-top .item-inner {
25 | .align-items(flex-start);
26 | }
27 |
28 | .inset() {
29 | margin-left: 0.75rem;
30 | margin-right: 0.75rem;
31 | border-radius: 0.35rem;
32 | .content-block-title {
33 | margin-left: 0;
34 | margin-right: 0;
35 | }
36 | ul {
37 | border-radius: 0.35rem;
38 | .hairline-remove(top);
39 | .hairline-remove(bottom);
40 | }
41 | li:first-child > a{
42 | border-radius: 0.35rem 0.35rem 0 0;
43 | }
44 | li:last-child > a{
45 | border-radius: 0 0 0.35rem 0.35rem;
46 | }
47 | li:first-child:last-child > a {
48 | border-radius: 0.35rem;
49 | }
50 | }
51 | &.inset {
52 | .inset()
53 | }
54 | &.tablet-inset {
55 | @media all and (min-width:768px) {
56 | .inset();
57 | }
58 | }
59 |
60 | // List items
61 | li {
62 | box-sizing: border-box;
63 | position: relative;
64 | }
65 |
66 | .item-media {
67 | .flexbox();
68 | .flex-shrink(0);
69 | .flex-wrap(nowrap);
70 | box-sizing: border-box;
71 | .align-items(center);
72 | padding-top: 0.35rem;
73 | padding-bottom: 0.4rem;
74 | i + i {
75 | margin-left: 0.25rem;
76 | }
77 | i + img {
78 | margin-left: 0.25rem;
79 | }
80 | }
81 | .item-media + .item-inner {
82 | margin-left: 0.75rem;
83 | }
84 | .item-inner {
85 | padding-right: 0.75rem;
86 | position: relative;
87 | .hairline(bottom, @listBlockBorderColor);
88 | width: 100%;
89 | padding-top: 0.4rem;
90 | padding-bottom: 0.35rem;
91 | min-height: 2.2rem;
92 | box-sizing: border-box;
93 | .flexbox();
94 | -webkit-box-flex:1;
95 | -ms-flex:1;
96 | .justify-content(space-between);
97 | .align-items(center);
98 | }
99 | .item-title {
100 | .flex-shrink(1);
101 | white-space: nowrap;
102 | position: relative;
103 | overflow: hidden;
104 | text-overflow: ellipsis;
105 | max-width: 100%;
106 |
107 | &.label {
108 | width: 35%;
109 | .flex-shrink(0);
110 | margin: 4px 0;
111 | }
112 | }
113 | .item-input {
114 | width: 100%;
115 | margin-top: -0.4rem;
116 | margin-bottom: -0.35rem;
117 | -webkit-box-flex:1;
118 | -ms-flex:1;
119 | .flex-shrink(1);
120 | }
121 | .item-after {
122 | white-space: nowrap;
123 | color: @color-text-secondary;
124 | .flex-shrink(0);
125 | margin-left: 0.25rem;
126 | .flexbox();
127 | max-height: 1.4rem;
128 | }
129 | .smart-select .item-after {
130 | max-width: 70%;
131 | overflow: hidden;
132 | text-overflow:ellipsis;
133 | position: relative;
134 | }
135 | .item-link {
136 | transition-duration: 300ms;
137 | display: block;
138 | color: inherit;
139 |
140 | .item-inner {
141 | padding-right: 1.5rem;
142 | background-image: url("@{imgBaseUrl}/i-list-chevron-right.png");
143 | background-size: 0.7rem;
144 | background-repeat: no-repeat;
145 | background-position: 97% center;
146 | background-position: -webkit-calc(~"100% - .5rem") center;
147 | background-position: calc(~"100% - .5rem") center;
148 | }
149 |
150 | html:not(.watch-active-state) &:active, &.active-state {
151 | transition-duration: 0ms;
152 | background-color: #d9d9d9;
153 | .item-inner {
154 | .hairline-color(bottom, transparent);
155 | }
156 | }
157 | &.list-button {
158 | padding: 0 0.75rem;
159 | text-align: center;
160 | color: @color-primary;
161 | display: block;
162 | .hairline(bottom, @listBlockBorderColor);
163 | line-height: 2.15rem;
164 | }
165 | }
166 | .item-content {
167 | box-sizing: border-box;
168 | padding-left: 0.75rem;
169 | min-height: 2.2rem;
170 | .flexbox();
171 | .justify-content(space-between);
172 | .align-items(center);
173 | }
174 | // Label after List block
175 | .list-block-label {
176 | margin: 0.5rem 0 1.75rem;
177 | padding: 0 0.75rem;
178 | font-size: 0.7rem;
179 | color: @color-text-secondary;
180 | }
181 |
182 | // Swipe outs
183 | .swipeout {
184 | overflow: hidden;
185 | -webkit-transform-style: preserve-3d;
186 | transform-style: preserve-3d;
187 | }
188 | .swipeout.deleting {
189 | transition-duration: 300ms;
190 | .swipeout-content {
191 | transform: translateX(-100%);
192 | }
193 | }
194 | .swipeout.transitioning {
195 | .swipeout-content, .swipeout-actions-right a, .swipeout-actions-left a, .swipeout-overswipe {
196 | -webkit-transition: 300ms;
197 | transition: 300ms;
198 | }
199 | }
200 | .swipeout-content {
201 | position: relative;
202 | z-index: 10;
203 | }
204 | .swipeout-overswipe {
205 | -webkit-transition: 200ms left;
206 | transition: 200ms left;
207 | }
208 | .swipeout-actions-left, .swipeout-actions-right {
209 | position: absolute;
210 | top: 0;
211 | height: 100%;
212 | .flexbox();
213 | a {
214 | padding: 0 1.5rem;
215 | color:#fff;
216 | background: #c7c7cc;
217 | .flexbox();
218 | .align-items(center);
219 | position: relative;
220 | left: 0;
221 | &:after {
222 | content:'';
223 | position: absolute;
224 | top: 0;
225 | width: 600%;
226 | height: 100%;
227 | background: inherit;
228 | z-index: -1;
229 | }
230 | }
231 | a.swipeout-delete {
232 | background: @color-danger;
233 | }
234 | }
235 | .swipeout-actions-right {
236 | right: 0%;
237 | transform: translateX(100%);
238 | a:after {
239 | left: 100%;
240 | margin-left: -1px;
241 | }
242 | }
243 | .swipeout-actions-left {
244 | left: 0%;
245 | transform: translateX(-100%);
246 | a:after {
247 | right: 100%;
248 | margin-right: -1px;
249 | }
250 | }
251 | .item-subtitle {
252 | font-size: 0.75rem;
253 | position: relative;
254 | overflow: hidden;
255 | white-space: nowrap;
256 | max-width: 100%;
257 | text-overflow: ellipsis;
258 | }
259 | .item-text {
260 | font-size: 0.75rem;
261 | color: @color-text-secondary;
262 | line-height: 1.05rem;
263 | position: relative;
264 | overflow: hidden;
265 | height: 2.1rem;
266 | text-overflow:ellipsis;
267 | -webkit-line-clamp: 2;
268 | -webkit-box-orient: vertical;
269 | display: -webkit-box;
270 | }
271 | &.media-list, li.media-item {
272 | .item-title {
273 | font-weight: 500;
274 | }
275 | .item-inner {
276 | display: block;
277 | padding-top: 0.5rem;
278 | padding-bottom: 0.45rem;
279 | .align-self(stretch);
280 | }
281 | .item-media {
282 | padding-top: 0.45rem;
283 | padding-bottom: 0.5rem;
284 | img {
285 | display: block;
286 | }
287 | }
288 | .item-title-row {
289 | .flexbox();
290 | .justify-content(space-between);
291 | }
292 | }
293 | .list-group {
294 | ul {
295 | &:after, &:before {
296 | z-index: 11;
297 | }
298 | }
299 | + .list-group ul {
300 | .hairline-remove(top);
301 | }
302 | }
303 | .item-divider, .list-group-title {
304 | background: @dividerBg;
305 | .hairline(top, @listBlockBorderColor);
306 | margin-top: -1px;
307 | padding: 0.2rem 0.75rem;
308 | white-space: nowrap;
309 | position: relative;
310 | max-width: 100%;
311 | text-overflow: ellipsis;
312 | overflow: hidden;
313 | color: @dividerColor;
314 | }
315 | .list-group-title {
316 | position: relative;
317 | position: -webkit-sticky;
318 | position: -moz-sticky;
319 | position: sticky;
320 | top: 0;
321 | z-index: 20;
322 | margin-top: 0;
323 | .hairline-remove(top);
324 | }
325 | // Sortable
326 |
327 | .sortable-handler {
328 | position: absolute;
329 | right: 0;
330 | top: 0;
331 | bottom: 1px;
332 | z-index: 10;
333 | background-repeat: no-repeat;
334 | background-size: 0.9rem 0.6rem;
335 | background-image: url("@{imgBaseUrl}/i-sortable-handler.png");
336 | background-position: center;
337 | width: 1.75rem;
338 | opacity: 0;
339 | visibility: hidden;
340 | right: 0;
341 | }
342 | &.sortable {
343 | .item-inner {
344 | transition-duration: 300ms;
345 | }
346 | }
347 | &.sortable-opened {
348 | .sortable-handler {
349 | visibility: visible;
350 | opacity: 1;
351 | }
352 | .item-inner, .item-link .item-inner {
353 | padding-right: 1.5rem;
354 | }
355 | .item-link .item-inner, .item-link .item-title-row {
356 | background-image: none;
357 | }
358 | }
359 | &.sortable-sorting {
360 | li {
361 | transition-duration: 300ms;
362 | }
363 | }
364 | li.sorting {
365 | z-index: 50;
366 | background: rgba(255,255,255,0.8);
367 | box-shadow: 0 0.1rem 0.4rem rgba(0,0,0,0.6);
368 | transition-duration: 0ms;
369 | .item-inner {
370 | .hairline-remove(bottom);
371 | }
372 | }
373 |
374 | // Last-childs
375 | li {
376 | &:last-child {
377 | .list-button {
378 | .hairline-remove(bottom);
379 | }
380 | }
381 | &:last-child, &:last-child li:last-child {
382 | .item-inner {
383 | .hairline-remove(bottom);
384 | }
385 | }
386 | li:last-child, &:last-child li {
387 | .item-inner {
388 | .hairline(bottom, @listBlockBorderColor);
389 | }
390 | }
391 | }
392 | }
393 |
--------------------------------------------------------------------------------
/less/sui/mixins.less:
--------------------------------------------------------------------------------
1 | .scrollable(){
2 | overflow: auto;
3 | -webkit-overflow-scrolling: touch;
4 | }
5 | .flexbox() {
6 | display: -webkit-box;
7 | display: -ms-flexbox;
8 | display: -webkit-flex;
9 | display: flex;
10 | }
11 | .flex-wrap(@fw) when (@fw = nowrap) {
12 | -webkit-box-lines: single;
13 | -moz-box-lines: single;
14 | -webkit-flex-wrap: nowrap;
15 | -ms-flex-wrap: none;
16 | -ms-flex-wrap: nowrap;
17 | flex-wrap: nowrap;
18 | }
19 | .flex-wrap(@fw) when (@fw = wrap) {
20 | -webkit-box-lines: multiple;
21 | -moz-box-lines: multiple;
22 | -webkit-flex-wrap: wrap;
23 | -ms-flex-wrap: wrap;
24 | flex-wrap: wrap;
25 | }
26 | .flex-wrap(@fw) when not (@fw = wrap) and not (@fw = nowrap) {
27 | -webkit-flex-wrap: @fw;
28 | -ms-flex-wrap: @fw;
29 | flex-wrap: @fw;
30 | }
31 | .flex-shrink(@fs) {
32 | -webkit-flex-shrink: @fs;
33 | -ms-flex: 0 @fs auto;
34 | flex-shrink: @fs;
35 | }
36 | .justify-content(@jc) when (@jc = flex-start) {
37 | -webkit-box-pack: start;
38 | -ms-flex-pack: start;
39 | -webkit-justify-content: flex-start;
40 | justify-content: flex-start;
41 | }
42 | .justify-content(@jc) when (@jc = flex-end) {
43 | -webkit-box-pack: end;
44 | -ms-flex-pack: end;
45 | -webkit-justify-content: flex-end;
46 | justify-content: flex-end;
47 | }
48 | .justify-content(@jc) when (@jc = space-between) {
49 | -webkit-box-pack: justify;
50 | -ms-flex-pack: justify;
51 | -webkit-justify-content: space-between;
52 | justify-content: space-between;
53 | }
54 | .justify-content(@jc) when not (@jc = flex-start) and not (@jc = flex-end) and not (@jc = space-between) {
55 | -webkit-box-pack: @jc;
56 | -ms-flex-pack: @jc;
57 | -webkit-justify-content: @jc;
58 | justify-content: @jc;
59 | }
60 | .align-items(@ai) when (@ai = flex-start) {
61 | -webkit-box-align: start;
62 | -ms-flex-align: start;
63 | -webkit-align-items: flex-start;
64 | align-items: flex-start;
65 | }
66 | .align-items(@ai) when (@ai = flex-end) {
67 | -webkit-box-align: end;
68 | -ms-flex-align: end;
69 | -webkit-align-items: flex-end;
70 | align-items: flex-end;
71 | }
72 | .align-items(@ai) when not (@ai = flex-start) and not (@ai = flex-end) {
73 | -webkit-box-align: @ai;
74 | -ms-flex-align: @ai;
75 | -webkit-align-items: @ai;
76 | align-items: @ai;
77 | }
78 | .align-content(@ai) {
79 | -ms-flex-line-pack: @ai;
80 | -webkit-align-content: @ai;
81 | align-content: @ai;
82 | }
83 | .align-self(@as) {
84 | -ms-flex-item-align: @as;
85 | -webkit-align-self: @as;
86 | align-self: @as;
87 | }
88 | .clearfix() {
89 | &:before,
90 | &:after {
91 | content: " ";
92 | display: table;
93 | }
94 | &:after {
95 | clear: both;
96 | }
97 | }
98 | .hairline(@position, @color) when (@position = top) {
99 | &:before {
100 | content: '';
101 | position: absolute;
102 | left: 0;
103 | top: 0;
104 | bottom: auto;
105 | right: auto;
106 | height: 1px;
107 | width: 100%;
108 | background-color: @color;
109 | display: block;
110 | z-index: 15;
111 | transform-origin: 50% 0%;
112 | @media only screen and (-webkit-min-device-pixel-ratio: 2) {
113 | transform: scaleY(0.5);
114 | }
115 | @media only screen and (-webkit-min-device-pixel-ratio: 3) {
116 | transform: scaleY(0.33);
117 | }
118 | }
119 | }
120 | .hairline(@position, @color) when (@position = left) {
121 | &:before {
122 | content: '';
123 | position: absolute;
124 | left: 0;
125 | top: 0;
126 | bottom: auto;
127 | right: auto;
128 | width: 1px;
129 | height: 100%;
130 | background-color: @color;
131 | display: block;
132 | z-index: 15;
133 | transform-origin: 0% 50%;
134 | @media only screen and (-webkit-min-device-pixel-ratio: 2) {
135 | transform: scaleY(0.5);
136 | }
137 | @media only screen and (-webkit-min-device-pixel-ratio: 3) {
138 | transform: scaleY(0.33);
139 | }
140 | }
141 | }
142 | .hairline(@position, @color) when (@position = bottom) {
143 | &:after {
144 | content: '';
145 | position: absolute;
146 | left: 0;
147 | bottom: 0;
148 | right: auto;
149 | top: auto;
150 | height: 1px;
151 | width: 100%;
152 | background-color: @color;
153 | display: block;
154 | z-index: 15;
155 | transform-origin: 50% 100%;
156 | @media only screen and (-webkit-min-device-pixel-ratio: 2) {
157 | transform: scaleY(0.5);
158 | }
159 | @media only screen and (-webkit-min-device-pixel-ratio: 3) {
160 | transform: scaleY(0.33);
161 | }
162 | }
163 | }
164 | .hairline(@position, @color) when (@position = right) {
165 | &:after {
166 | content: '';
167 | position: absolute;
168 | right: 0;
169 | top: 0;
170 | left: auto;
171 | bottom: auto;
172 | width: 1px;
173 | height: 100%;
174 | background-color: @color;
175 | display: block;
176 | z-index: 15;
177 | transform-origin: 100% 50%;
178 | @media only screen and (-webkit-min-device-pixel-ratio: 2) {
179 | transform: scaleY(0.5);
180 | }
181 | @media only screen and (-webkit-min-device-pixel-ratio: 3) {
182 | transform: scaleY(0.33);
183 | }
184 | }
185 | }
186 | // For right and bottom
187 | .hairline-remove(@position) when not (@position = left) and not (@position = top) {
188 | &:after {
189 | display: none;
190 | }
191 | }
192 | // For left and top
193 | .hairline-remove(@position) when not (@position = right) and not (@position = bottom) {
194 | &:before {
195 | display: none;
196 | }
197 | }
198 | // For right and bottom
199 | .hairline-color(@position, @color) when not (@position = left) and not (@position = top) {
200 | &:after {
201 | background-color: @color;
202 | }
203 | }
204 | // For left and top
205 | .hairline-color(@position, @color) when not (@position = right) and not (@position = bottom) {
206 | &:before {
207 | background-color: @color;
208 | }
209 | }
210 |
211 | // Encoded SVG Background
212 | .encoded-svg-background(@svg) {
213 | @url: `encodeURIComponent(@{svg})`;
214 | background-image: url("data:image/svg+xml;charset=utf-8,@{url}");
215 | }
216 |
217 | // Preserve3D
218 | .preserve3d() {
219 | -webkit-transform-style: preserve-3d;
220 | -moz-transform-style: preserve-3d;
221 | -ms-transform-style: preserve-3d;
222 | transform-style: preserve-3d;
223 | }
224 |
225 | //from ratchet
226 | .linear-gradient(@color-from, @color-to) {
227 | background-color: @color-from; // Old browsers
228 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,@color-from), color-stop(100%,@color-to)); // Chrome, Safari4+
229 | background-image: -webkit-linear-gradient(top, @color-from 0%, @color-to 100%); // Chrome10+, Safari5.1+
230 | background-image: -moz-linear-gradient(top, @color-from 0%, @color-to 100%); // FF3.6+
231 | background-image: -ms-linear-gradient(top, @color-from 0%, @color-to 100%); // IE10+
232 | background-image: -o-linear-gradient(top, @color-from 0%, @color-to 100%); // Opera 11.10+
233 | background-image: linear-gradient(to bottom, @color-from 0%, @color-to 100%); // W3C
234 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#{@color-from}', endColorstr='#{@color-to}', GradientType=0 ); // IE6-9
235 | }
236 | .directional-gradient(@color-from, @color-to, @deg: 45deg) {
237 | background-color: @color-from; // Old browsers
238 | background-image: -webkit-gradient(linear, left bottom, right top, color-stop(0%,@color-from), color-stop(100%,@color-to)); // Chrome, Safari4+
239 | background-image: -webkit-linear-gradient(@deg, @color-from 0%, @color-to 100%); // Chrome10+, Safari5.1+
240 | background-image: -moz-linear-gradient(@deg, @color-from 0%, @color-to 100%); // FF3.6+
241 | background-image: -ms-linear-gradient(@deg, @color-from 0%, @color-to 100%); // IE10+
242 | background-image: -o-linear-gradient(@deg, @color-from 0%, @color-to 100%); // Opera 11.10+
243 | background-image: linear-gradient(@deg, @color-from 0%, @color-to 100%); // W3C
244 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#{@color-from}', endColorstr='#{@color-to}', GradientType=1 ); // IE6-9
245 | }
246 |
247 | .hairline(@type, @color, @offset) when (@type = single) {
248 | background-image: url("data:image/svg+xml;utf8, ");
249 | background-position: @offset 100%;
250 | }
251 | .hairline(@type, @color, @offset) when (@type = double) {
252 | background-image: url("data:image/svg+xml;utf8, "),
253 | url("data:image/svg+xml;utf8, ");
254 | background-position: @offset 100%, @offset 0;
255 | background-repeat: no-repeat;
256 | }
257 |
258 |
259 | //已删除的mixin
260 | /*.transition(@d) {
261 | -webkit-transition-duration: @d;
262 | transition-duration: @d;
263 | }
264 | .delay(@d) {
265 | -webkit-transition-delay: @d;
266 | transition-delay: @d;
267 | }
268 | .transform(@t) {
269 | -webkit-transform: @t;
270 | transform: @t;
271 | }
272 | .transform-origin(@to) {
273 | -webkit-transform-origin: @to;
274 | transform-origin: @to;
275 | }
276 | .translate3d(@x:0, @y:0, @z:0) {
277 | -webkit-transform: translate3d(@x,@y,@z);
278 | transform: translate3d(@x,@y,@z);
279 | }
280 | .animation(@a) {
281 | -webkit-animation: @a;
282 | animation: @a;
283 | }
284 | .border-box(){
285 | -webkit-box-sizing: border-box;
286 | -moz-box-sizing: border-box;
287 | box-sizing: border-box;
288 | }
289 | .box-shadow(@bs) {
290 | -webkit-box-shadow: @bs;
291 | box-shadow: @bs;
292 | }
293 | .animation-name(@name) {
294 | -webkit-animation-name: @name;
295 | -moz-animation-name: @name;
296 | animation-name: @name;
297 | }
298 | .animation-duration(@duration) {
299 | -webkit-animation-duration: @duration;
300 | -moz-animation-duration: @duration;
301 | animation-duration: @duration;
302 | }
303 | .animation-direction(@direction) {
304 | -webkit-animation-direction: @direction;
305 | -moz-animation-direction: @direction;
306 | animation-direction: @direction;
307 | }
308 | */
309 |
--------------------------------------------------------------------------------
/less/sui/modal.less:
--------------------------------------------------------------------------------
1 | /* === Modals === */
2 | @modalBgColor:#e8e8e8;
3 | @modalButonColor : @color-primary;
4 | @modalButonBg: @modalBgColor;
5 | @modalButonActiveBg:#d4d4d4;
6 | @modalDuration:400ms;
7 | @actionsModalDuration:300ms;
8 | @actionsModalButtonBg: rgba(243,243,243,0.95);
9 | @actionsModalActiveButtonBg:#dcdcdc;
10 | @popoverBg: rgba(255,255,255,0.95);
11 | @popupDuration: 400ms;
12 | @gray: #8e8e93;
13 | .modal-overlay, .preloader-indicator-overlay, .popup-overlay {
14 | position: absolute;
15 | left: 0;
16 | top: 0;
17 | width: 100%;
18 | height: 100%;
19 | background: rgba(0,0,0,0.4);
20 | z-index: 10600;
21 | visibility: hidden;
22 | opacity: 0;
23 | transition-duration: @modalDuration;
24 | &.modal-overlay-visible {
25 | visibility: visible;
26 | opacity: 1;
27 | }
28 | }
29 | .popup-overlay {
30 | z-index: 10200;
31 | }
32 | .modal {
33 | width: 13.5rem;
34 | position: absolute;
35 | z-index: 11000;
36 | left: 50%;
37 | margin-left: -6.75rem;
38 | margin-top: 0;
39 | top: 50%;
40 | text-align: center;
41 | border-radius: 0.35rem;
42 | opacity: 0;
43 | transform: translate3d(0,0,0) scale(1.185);
44 | transition-property: transform, opacity;
45 | color: @color-text;
46 | display: none;
47 | &.modal-in {
48 | opacity: 1;
49 | transition-duration: @modalDuration;
50 | transform: translate3d(0,0,0) scale(1);
51 | }
52 | &.modal-out {
53 | opacity: 0;
54 | z-index: 11000-1;
55 | transition-duration: @modalDuration;
56 | transform: translate3d(0,0,0) scale(0.815);
57 | }
58 | }
59 | .modal-inner {
60 | padding: 0.75rem;
61 | .hairline(bottom, #b5b5b5);
62 | border-radius: 0.35rem 0.35rem 0 0;
63 | position: relative;
64 | background: @modalBgColor;
65 | }
66 | .modal-title {
67 | font-weight: 500;
68 | font-size: 0.9rem;
69 | text-align: center;
70 | +.modal-text {
71 | margin-top: 0.25rem;
72 | }
73 | }
74 | .modal-buttons {
75 | height: 2.2rem;
76 | overflow: hidden;
77 | .flexbox();
78 | .justify-content(center);
79 | &.modal-buttons-vertical {
80 | display: block;
81 | height: auto;
82 | }
83 | }
84 | .modal-button {
85 | width: 100%;
86 | padding: 0 0.25rem;
87 | height: 2.2rem;
88 | font-size: 0.85rem;
89 | line-height: 2.2rem;
90 | text-align: center;
91 | color: @modalButonColor;
92 | background: @modalButonBg;
93 | display: block;
94 | position: relative;
95 | white-space: nowrap;
96 | text-overflow:ellipsis;
97 | overflow: hidden;
98 | cursor: pointer;
99 | box-sizing: border-box;
100 | .hairline(right, #b5b5b5);
101 | -webkit-box-flex:1;
102 | -ms-flex:1;
103 | &:first-child {
104 | border-radius: 0 0 0 0.35rem;
105 | }
106 | &:last-child {
107 | .hairline-remove(right);
108 | border-radius: 0 0 0.35rem 0;
109 | }
110 | &:first-child:last-child {
111 | border-radius: 0 0 0.35rem 0.35rem;
112 | }
113 | &.modal-button-bold {
114 | font-weight: 500;
115 | }
116 | html:not(.watch-active-state) &:active, &.active-state {
117 | background: @modalButonActiveBg;
118 | }
119 | .modal-buttons-vertical & {
120 | .hairline-remove(right);
121 | .hairline-remove(top);
122 | .hairline(bottom, #b5b5b5);
123 | border-radius: 0;
124 | &:last-child {
125 | border-radius: 0 0 0.35rem 0.35rem;
126 | .hairline-remove(bottom);
127 | }
128 | }
129 | }
130 | .modal-no-buttons {
131 | .modal-inner {
132 | border-radius: 0.35rem;
133 | .hairline-remove(bottom);
134 | }
135 | .modal-buttons {
136 | display: none;
137 | }
138 | }
139 | // Action sheet
140 | .actions-modal {
141 | position: absolute;
142 | left: 0;
143 | bottom: 0;
144 | z-index: 11000;
145 | width: 100%;
146 | transform: translate3d(0,100%,0);
147 | &.modal-in {
148 | transition-duration: @actionsModalDuration;
149 | transform: translate3d(0,0,0);
150 | }
151 | &.modal-out {
152 | z-index: 11000-1;
153 | transition-duration: @actionsModalDuration;
154 | transform: translate3d(0,100%,0);
155 | }
156 | }
157 | .actions-modal-group {
158 | margin: 0.4rem;
159 | }
160 | .actions-modal-button, .actions-modal-label {
161 | width: 100%;
162 | text-align: center;
163 | font-weight: normal;
164 | margin: 0;
165 | background: @actionsModalButtonBg;
166 | box-sizing: border-box;
167 | display: block;
168 | position: relative;
169 | .hairline(bottom, #d2d2d6);
170 | a {
171 | text-decoration: none;
172 | color: inherit;
173 | }
174 | b {
175 | font-weight: 500;
176 | }
177 | &.actions-modal-button-bold {
178 | font-weight: 500;
179 | }
180 | &.actions-modal-button-danger {
181 | color: @color-danger;
182 | }
183 | &.color-danger {
184 | color: @color-danger;
185 | }
186 | &.bg-danger {
187 | background: @color-danger;
188 | color: white;
189 | &:active {
190 | background: @color-danger-active;
191 | }
192 | }
193 | &:first-child {
194 | border-radius: 0.2rem 0.2rem 0 0;
195 | }
196 | &:last-child {
197 | .hairline-remove(bottom);
198 | border-radius: 0 0 0.2rem 0.2rem;
199 | }
200 | &:first-child:last-child {
201 | border-radius: 0.2rem;
202 | }
203 | &.disabled {
204 | opacity: 0.95;
205 | color:@gray;
206 | }
207 | }
208 | .actions-modal-button {
209 | cursor: pointer;
210 | line-height: 2.15rem;
211 | font-size:1rem;
212 | color: @color-primary;
213 | &:active, &.active-state {
214 | background: @actionsModalActiveButtonBg;
215 | }
216 | }
217 | .actions-modal-label {
218 | font-size: 0.7rem;
219 | line-height: 1.3;
220 | min-height: 2.2rem;
221 | padding: 0.4rem 0.5rem;
222 | color: @color-text-secondary;
223 | .flexbox();
224 | .justify-content(center);
225 | .align-items(center);
226 | }
227 | // Prompt
228 | input.modal-text-input {
229 | box-sizing: border-box;
230 | height: 1.5rem;
231 | background: #fff;
232 | margin: 0;
233 | margin-top: 0.75rem;
234 | padding: 0 0.25rem;
235 | border: 1px solid #a0a0a0;
236 | border-radius: 0.25rem;
237 | width: 100%;
238 | font-size: 0.7rem;
239 | font-family: inherit;
240 | display: block;
241 | box-shadow: 0 0 0 rgba(0,0,0,0);
242 | appearance: none;
243 | + input.modal-text-input {
244 | margin-top: 0.25rem;
245 | }
246 | &.modal-text-input-double {
247 | border-radius: 0.25rem 0.25rem 0 0;
248 | + input.modal-text-input {
249 | margin-top: 0;
250 | border-top: 0;
251 | border-radius: 0 0 0.25rem 0.25rem;
252 | }
253 | }
254 | }
255 | // Popover
256 | .popover {
257 | width: 16rem;
258 | background:@popoverBg;
259 | z-index: 11000;
260 | margin: 0;
261 | top: 0;
262 | opacity: 0;
263 | left: 0;
264 | border-radius: 0.35rem;
265 | position: absolute;
266 | display: none;
267 | transform: none;
268 | transition-property: opacity;
269 | &.modal-in {
270 | transition-duration: @actionsModalDuration;
271 | opacity: 1;
272 | }
273 | .list-block {
274 | margin: 0;
275 | ul {
276 | background: none;
277 | }
278 | &:first-child {
279 | ul {
280 | .hairline-remove(top);
281 | border-radius: 0.35rem 0.35rem 0 0;
282 | }
283 | li:first-child a{
284 | border-radius: 0.35rem 0.35rem 0 0;
285 | }
286 | }
287 | &:last-child {
288 | ul {
289 | .hairline-remove(bottom);
290 | border-radius: 0 0 0.35rem 0.35rem;
291 | }
292 | li:last-child a{
293 | border-radius: 0 0 0.35rem 0.35rem;
294 | }
295 | }
296 | &:first-child:last-child {
297 | li:first-child:last-child a, ul:first-child:last-child {
298 | border-radius: 0.35rem;
299 | }
300 | }
301 | + .list-block {
302 | margin-top: 1.75rem;
303 | }
304 | }
305 | }
306 | .popover-angle {
307 | width: 1.3rem;
308 | height: 1.3rem;
309 | position: absolute;
310 | left: -1.3rem;
311 | top: 0;
312 | z-index: 100;
313 | overflow: hidden;
314 | &:after {
315 | content:' ';
316 | background: @popoverBg;
317 | width: 1.3rem;
318 | height: 1.3rem;
319 | position: absolute;
320 | left: 0;
321 | top: 0;
322 | border-radius: 1.5rem;
323 | transform: rotate(45deg);
324 | }
325 | &.on-left {
326 | left: -1.3rem;
327 | &:after {
328 | left: 0.95rem;
329 | top: 0;
330 | }
331 | }
332 | &.on-right {
333 | left: 100%;
334 | &:after {
335 | left: -0.95rem;
336 | top: 0;
337 | }
338 | }
339 | &.on-top {
340 | left: 0;
341 | top: -1.3rem;
342 | &:after {
343 | left: 0;
344 | top: 0.95rem;
345 | }
346 | }
347 | &.on-bottom {
348 | left: 0;
349 | top: 100%;
350 | &:after {
351 | left: 0;
352 | top: -0.95rem;
353 | }
354 | }
355 | }
356 | .popover-inner {
357 | .scrollable();
358 | }
359 | .actions-popover {
360 | .list-block + .list-block {
361 | margin-top: 1rem;
362 | }
363 | .list-block ul {
364 | background: #fff;
365 | }
366 | }
367 | .actions-popover-label {
368 | padding: 0.4rem 0.5rem;
369 | color: @color-text-secondary;
370 | font-size: 0.65rem;
371 | line-height: 1.3;
372 | text-align: center;
373 | position: relative;
374 | .hairline(bottom, #d2d2d6);
375 | &:last-child {
376 | .hairline-remove(bottom);
377 | }
378 | }
379 | // Popup
380 | .popup, .login-screen {
381 | position: absolute;
382 | left: 0;
383 | top: 0;
384 | width: 100%;
385 | height: 100%;
386 | z-index: 10400;
387 | background: #fff;
388 | box-sizing: border-box;
389 | display: none;
390 | .scrollable();
391 | transition-property: transform;
392 | transform: translate3d(0,100%,0);
393 | &.modal-in, &.modal-out {
394 | transition-duration: @popupDuration;
395 | }
396 | &.modal-in {
397 | transform: translate3d( 0,0,0);
398 | }
399 | &.modal-out {
400 | transform: translate3d( 0,100%,0);
401 | }
402 | }
403 | .login-screen.modal-in, .login-screen.modal-out {
404 | display: block;
405 | }
406 |
407 | html.with-statusbar-overlay {
408 | // iPhone with statusbar overlay
409 | .popup {
410 | height: ~"-webkit-calc(100% -1rem)";
411 | height: ~"calc(100% - 1rem)";
412 | top: 1rem;
413 | }
414 | .popup-overlay {
415 | z-index: 9800;
416 | }
417 | @media all and (max-width:629px), (max-height:629px) {
418 | .popup {
419 | height: ~"-webkit-calc(100% - 1rem)";
420 | height: ~"calc(100% - 1rem)";
421 | top: 1rem;
422 | }
423 | .popup-overlay {
424 | z-index: 9800;
425 | }
426 | }
427 | .login-screen, .popup.tablet-fullscreen {
428 | height: ~"-webkit-calc(100% - 1rem)";
429 | height: ~"calc(100% - 1rem)";
430 | top: 1rem;
431 | }
432 | }
433 |
434 | //Preloaders modals
435 | .modal .preloader {
436 | width: 1.7rem;
437 | height: 1.7rem;
438 | }
439 | .preloader-indicator-overlay {
440 | visibility: visible;
441 | opacity: 0;
442 | background: none;
443 | }
444 | .preloader-indicator-modal {
445 | position: absolute;
446 | left: 50%;
447 | top: 50%;
448 | padding: 0.4rem;
449 | margin-left: -1.25rem;
450 | margin-top: -1.25rem;
451 | background: rgba(0,0,0,0.8);
452 | z-index: 11000;
453 | border-radius: 0.25rem;
454 | .preloader {
455 | display: block;
456 | width: 1.7rem;
457 | height: 1.7rem;
458 | }
459 | }
460 |
461 | // Picker Modal
462 | .picker-modal {
463 | position: absolute;
464 | left: 0;
465 | bottom: 0;
466 | width: 100%;
467 | height: 13rem;
468 | z-index: 11500;
469 | display: none;
470 | transition-property: transform;
471 | background: #cfd5da;
472 | transform: translate3d( 0,100%,0);
473 | &.modal-in, &.modal-out {
474 | transition-duration: 400ms;
475 | }
476 | &.modal-in {
477 | transform: translate3d(0,0,0);
478 | }
479 | &.modal-out {
480 | transform: translate3d(0,100%,0);
481 | }
482 | .picker-modal-inner {
483 | height: 100%;
484 | position: relative;
485 | }
486 | .toolbar {
487 | .hairline(top, @color-text-gray);
488 | position: relative;
489 | width: 100%;
490 | + .picker-modal-inner {
491 | height: ~"-webkit-calc(100% - 2.2rem)";
492 | height: ~"-moz-calc(100% - 2.2rem)";
493 | height: ~"calc(100% - 2.2rem)";
494 | }
495 | }
496 | &.picker-modal-inline, .popover & {
497 | display: block;
498 | position: relative;
499 | background: none;
500 | z-index: inherit;
501 | transform: translate3d(0,0,0);
502 | .toolbar {
503 | .hairline-remove(top);
504 | .hairline(bottom, @color-text-gray);
505 | }
506 | }
507 | .popover & {
508 | width: auto;
509 | .toolbar {
510 | background: none;
511 | }
512 | }
513 | }
514 |
515 | //toast
516 |
517 | .toast {
518 | background: rgba(0, 0, 0, .8);
519 | border-radius: 1rem;
520 | color: white;
521 | padding: 0 .8rem;
522 | height: 2rem;
523 | line-height: 2rem;
524 | font-size: 0.8rem;
525 | width: auto;
526 | }
527 |
--------------------------------------------------------------------------------
/less/sui/normalize.less:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
2 |
3 | //
4 | // 1. Set default font family to sans-serif.
5 | // 2. Prevent iOS and IE text size adjust after device orientation change,
6 | // without disabling user zoom.
7 | //
8 |
9 | html {
10 | font-family: sans-serif; // 1
11 | -ms-text-size-adjust: 100%; // 2
12 | -webkit-text-size-adjust: 100%; // 2
13 | }
14 |
15 | //
16 | // Remove default margin.
17 | //
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | // HTML5 display definitions
24 | // ==========================================================================
25 |
26 | //
27 | // Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | // Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | // and Firefox.
30 | // Correct `block` display not defined for `main` in IE 11.
31 | //
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | //
50 | // 1. Correct `inline-block` display not defined in IE 8/9.
51 | // 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | //
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; // 1
59 | vertical-align: baseline; // 2
60 | }
61 |
62 | //
63 | // Prevent modern browsers from displaying `audio` without controls.
64 | // Remove excess height in iOS 5 devices.
65 | //
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | //
73 | // Address `[hidden]` styling not present in IE 8/9/10.
74 | // Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
75 | //
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | // Links
83 | // ==========================================================================
84 |
85 | //
86 | // Remove the gray background color from active links in IE 10.
87 | //
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | //
94 | // Improve readability of focused elements when they are also in an
95 | // active/hover state.
96 | //
97 |
98 | a:active,
99 | a:hover {
100 | outline: 0;
101 | }
102 |
103 | // Text-level semantics
104 | // ==========================================================================
105 |
106 | //
107 | // Address styling not present in IE 8/9/10/11, Safari, and Chrome.
108 | //
109 |
110 | abbr[title] {
111 | border-bottom: 1px dotted;
112 | }
113 |
114 | //
115 | // Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
116 | //
117 |
118 | b,
119 | strong {
120 | font-weight: bold;
121 | }
122 |
123 | //
124 | // Address styling not present in Safari and Chrome.
125 | //
126 |
127 | dfn {
128 | font-style: italic;
129 | }
130 |
131 | //
132 | // Address variable `h1` font-size and margin within `section` and `article`
133 | // contexts in Firefox 4+, Safari, and Chrome.
134 | //
135 |
136 | h1 {
137 | font-size: 2em;
138 | margin: 0.67em 0;
139 | }
140 |
141 | //
142 | // Address styling not present in IE 8/9.
143 | //
144 |
145 | mark {
146 | background: #ff0;
147 | color: #000;
148 | }
149 |
150 | //
151 | // Address inconsistent and variable font size in all browsers.
152 | //
153 |
154 | small {
155 | font-size: 80%;
156 | }
157 |
158 | //
159 | // Prevent `sub` and `sup` affecting `line-height` in all browsers.
160 | //
161 |
162 | sub,
163 | sup {
164 | font-size: 75%;
165 | line-height: 0;
166 | position: relative;
167 | vertical-align: baseline;
168 | }
169 |
170 | sup {
171 | top: -0.5em;
172 | }
173 |
174 | sub {
175 | bottom: -0.25em;
176 | }
177 |
178 | // Embedded content
179 | // ==========================================================================
180 |
181 | //
182 | // Remove border when inside `a` element in IE 8/9/10.
183 | //
184 |
185 | img {
186 | border: 0;
187 | }
188 |
189 | //
190 | // Correct overflow not hidden in IE 9/10/11.
191 | //
192 |
193 | svg:not(:root) {
194 | overflow: hidden;
195 | }
196 |
197 | // Grouping content
198 | // ==========================================================================
199 |
200 | //
201 | // Address margin not present in IE 8/9 and Safari.
202 | //
203 |
204 | figure {
205 | margin: 1em 40px;
206 | }
207 |
208 | //
209 | // Address differences between Firefox and other browsers.
210 | //
211 |
212 | hr {
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | //
218 | // Contain overflow in all browsers.
219 | //
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | //
226 | // Address odd `em`-unit font size rendering in all browsers.
227 | //
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | // Forms
238 | // ==========================================================================
239 |
240 | //
241 | // Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | // styling of `select`, unless a `border` property is set.
243 | //
244 |
245 | //
246 | // 1. Correct color not being inherited.
247 | // Known issue: affects color of disabled elements.
248 | // 2. Correct font properties not being inherited.
249 | // 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | //
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; // 1
258 | font: inherit; // 2
259 | margin: 0; // 3
260 | }
261 |
262 | //
263 | // Address `overflow` set to `hidden` in IE 8/9/10/11.
264 | //
265 |
266 | button {
267 | overflow: visible;
268 | }
269 |
270 | //
271 | // Address inconsistent `text-transform` inheritance for `button` and `select`.
272 | // All other form control elements do not inherit `text-transform` values.
273 | // Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274 | // Correct `select` style inheritance in Firefox.
275 | //
276 |
277 | button,
278 | select {
279 | text-transform: none;
280 | }
281 |
282 | //
283 | // 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284 | // and `video` controls.
285 | // 2. Correct inability to style clickable `input` types in iOS.
286 | // 3. Improve usability and consistency of cursor style between image-type
287 | // `input` and others.
288 | //
289 |
290 | button,
291 | html input[type="button"], // 1
292 | input[type="reset"],
293 | input[type="submit"] {
294 | -webkit-appearance: button; // 2
295 | cursor: pointer; // 3
296 | }
297 |
298 | //
299 | // Re-set default cursor for disabled elements.
300 | //
301 |
302 | button[disabled],
303 | html input[disabled] {
304 | cursor: default;
305 | }
306 |
307 | //
308 | // Remove inner padding and border in Firefox 4+.
309 | //
310 |
311 | button::-moz-focus-inner,
312 | input::-moz-focus-inner {
313 | border: 0;
314 | padding: 0;
315 | }
316 |
317 | //
318 | // Address Firefox 4+ setting `line-height` on `input` using `!important` in
319 | // the UA stylesheet.
320 | //
321 |
322 | input {
323 | line-height: normal;
324 | }
325 |
326 | //
327 | // It's recommended that you don't attempt to style these elements.
328 | // Firefox's implementation doesn't respect box-sizing, padding, or width.
329 | //
330 | // 1. Address box sizing set to `content-box` in IE 8/9/10.
331 | // 2. Remove excess padding in IE 8/9/10.
332 | //
333 |
334 | input[type="checkbox"],
335 | input[type="radio"] {
336 | box-sizing: border-box; // 1
337 | padding: 0; // 2
338 | }
339 |
340 | //
341 | // Fix the cursor style for Chrome's increment/decrement buttons. For certain
342 | // `font-size` values of the `input`, it causes the cursor style of the
343 | // decrement button to change from `default` to `text`.
344 | //
345 |
346 | input[type="number"]::-webkit-inner-spin-button,
347 | input[type="number"]::-webkit-outer-spin-button {
348 | height: auto;
349 | }
350 |
351 | //
352 | // 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353 | // 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
354 | //
355 |
356 | input[type="search"] {
357 | -webkit-appearance: textfield; // 1
358 | box-sizing: content-box; // 2
359 | }
360 |
361 | //
362 | // Remove inner padding and search cancel button in Safari and Chrome on OS X.
363 | // Safari (but not Chrome) clips the cancel button when the search input has
364 | // padding (and `textfield` appearance).
365 | //
366 |
367 | input[type="search"]::-webkit-search-cancel-button,
368 | input[type="search"]::-webkit-search-decoration {
369 | -webkit-appearance: none;
370 | }
371 |
372 | //
373 | // Define consistent border, margin, and padding.
374 | //
375 |
376 | fieldset {
377 | border: 1px solid #c0c0c0;
378 | margin: 0 2px;
379 | padding: 0.35em 0.625em 0.75em;
380 | }
381 |
382 | //
383 | // 1. Correct `color` not being inherited in IE 8/9/10/11.
384 | // 2. Remove padding so people aren't caught out if they zero out fieldsets.
385 | //
386 |
387 | legend {
388 | border: 0; // 1
389 | padding: 0; // 2
390 | }
391 |
392 | //
393 | // Remove default vertical scrollbar in IE 8/9/10/11.
394 | //
395 |
396 | textarea {
397 | overflow: auto;
398 | }
399 |
400 | //
401 | // Don't inherit the `font-weight` (applied by a rule above).
402 | // NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
403 | //
404 |
405 | optgroup {
406 | font-weight: bold;
407 | }
408 |
409 | // Tables
410 | // ==========================================================================
411 |
412 | //
413 | // Remove most spacing between table cells.
414 | //
415 |
416 | table {
417 | border-collapse: collapse;
418 | border-spacing: 0;
419 | }
420 |
421 | td,
422 | th {
423 | padding: 0;
424 | }
425 |
--------------------------------------------------------------------------------
/less/sui/pages.less:
--------------------------------------------------------------------------------
1 | /* === Pages === */
2 |
3 | // Pages animations
4 | @pageDuration: 400ms;
5 |
6 | .page {
7 | box-sizing: border-box;
8 | position: absolute;
9 | left: 0;
10 | top: 0;
11 | width: 100%;
12 | height: 100%;
13 | background: #efeff4;
14 | display: none;
15 |
16 | &.page-current,
17 | &.page-from-center-to-left,
18 | &.page-from-center-to-right,
19 | &.page-from-right-to-center,
20 | &.page-from-left-to-center {
21 | display: block;
22 | }
23 | }
24 | .page-left {
25 | opacity: 0.5;
26 | transform: translate3d(-20%);
27 | }
28 | .page-right {
29 | transform: translate3d(100%);
30 | }
31 |
32 | //Class that will trigger transition during page custom transitions (like swipe-back)
33 | .page-transitioning {
34 | &, .swipeback-page-shadow {
35 | transition: @pageDuration;
36 | }
37 | }
38 | // From/to Right To/from Center animations
39 | .page-from-right-to-center {
40 | animation: pageFromRightToCenter @pageDuration forwards;
41 | z-index: 2002;
42 | }
43 | .page-from-center-to-right {
44 | animation: pageFromCenterToRight @pageDuration forwards;
45 | z-index: 2002;
46 | }
47 |
48 | @keyframes pageFromRightToCenter {
49 | from {
50 | transform: translate3d(100%,0,0);
51 | opacity: .9;
52 | }
53 | to {
54 | transform: translate3d(0,0,0);
55 | opacity: 1;
56 | }
57 | }
58 |
59 | @keyframes pageFromCenterToRight {
60 | from {
61 | transform: translate3d(0,0,0);
62 | opacity: 1;
63 | }
64 | to {
65 | transform: translate3d(100%,0,0);
66 | opacity: .9;
67 | }
68 | }
69 |
70 |
71 | // From/to Center To/from Left animations
72 | .page-from-center-to-left {
73 | animation: pageFromCenterToLeft @pageDuration forwards;
74 | }
75 | .page-from-left-to-center {
76 | animation: pageFromLeftToCenter @pageDuration forwards;
77 | }
78 |
79 | @keyframes pageFromCenterToLeft {
80 | from {
81 | opacity: 1;
82 | transform: translate3d(0,0,0);
83 | }
84 | to {
85 | opacity: 0.5;
86 | transform: translate3d(-20%,0,0);
87 | }
88 | }
89 |
90 | @keyframes pageFromLeftToCenter {
91 | from {
92 | opacity: .5;
93 | transform: translate3d(-20%,0,0);
94 | }
95 | to {
96 | opacity: 1;
97 | transform: translate3d(0,0,0);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/less/sui/panels.less:
--------------------------------------------------------------------------------
1 | /* === Panels === */
2 | @panelWidth: 12rem;
3 | @panelsDuration: 400ms;
4 | .panel-overlay {
5 | position: absolute;
6 | left: 0;
7 | top: 0;
8 | width: 100%;
9 | height: 100%;
10 | background: rgba(0,0,0,0);
11 | opacity: 0;
12 | z-index: 5999;
13 | display: none;
14 | }
15 | .panel {
16 | z-index: 1000;
17 | display: none;
18 | background: #111;
19 | color: white;
20 | box-sizing: border-box;
21 | .scrollable();
22 | position: absolute;
23 | width: @panelWidth;
24 | top: 0;
25 | height: 100%;
26 | transform: translate3d(0, 0, 0);
27 | transition: transform @panelsDuration;
28 |
29 | &.panel-left {
30 | &.panel-cover {
31 | z-index: 6000;
32 | left: -@panelWidth;
33 | }
34 | &.panel-reveal {
35 | left: 0;
36 | }
37 | }
38 | &.panel-right {
39 | &.panel-cover {
40 | z-index: 6000;
41 | right: -@panelWidth;
42 | }
43 | &.panel-reveal {
44 | right: 0;
45 | }
46 | }
47 | }
48 | body.with-panel-left-cover, body.with-panel-right-cover {
49 | .page {
50 | transform: translate3d(0, 0, 0);
51 | transition: transform @panelsDuration;
52 | }
53 | .panel-overlay {
54 | display: block;
55 | }
56 | }
57 | body.with-panel-left-reveal, body.with-panel-right-reveal {
58 | .page {
59 | transition: @panelsDuration;
60 | -webkit-transition-property: -webkit-transform;
61 | -moz-transition-property: -moz-transform;
62 | transition-property: transform;
63 | }
64 | .panel-overlay {
65 | display: block;
66 | }
67 | }
68 | body.with-panel-left-reveal {
69 | .page {
70 | transform: translate3d(@panelWidth, 0, 0);
71 | }
72 | .panel-overlay {
73 | margin-left: @panelWidth;
74 | }
75 | }
76 | body.with-panel-left-cover {
77 | .panel-left {
78 | transform: translate3d(@panelWidth, 0, 0);
79 | }
80 | }
81 | body.with-panel-right-reveal {
82 | .page {
83 | transform: translate3d(-@panelWidth, 0, 0);
84 | }
85 | .panel-overlay {
86 | margin-left: -@panelWidth;
87 | }
88 | }
89 | body.with-panel-right-cover {
90 | .panel-right {
91 | transform: translate3d(-@panelWidth, 0, 0);
92 | }
93 | }
94 | body.panel-closing {
95 | .page {
96 | transition: @panelsDuration;
97 | -webkit-transition-property: -webkit-transform;
98 | -moz-transition-property: -moz-transform;
99 | transition-property: transform;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/less/sui/photo-browser.less:
--------------------------------------------------------------------------------
1 | /* === Photo Browser === */
2 |
3 | .photo-browser {
4 | position: absolute;
5 | left: 0;
6 | top: 0;
7 | width: 100%;
8 | height: 100%;
9 | z-index: 10500;
10 | // opacity: 0;
11 | // display: none;
12 | // transform: translate3d(0, 0, 0);
13 | .bar-tab .tab-item .icon {
14 | width: 14px;
15 | height: 14px;
16 | margin-top: -5px;
17 | }
18 | .bar-tab~.photo-browser-captions {
19 | bottom: 52px;
20 | -webkit-transform: translate3d(0,0,0);
21 | transform: translate3d(0,0,0);
22 | }
23 | &.photo-browser-in {
24 | display: block;
25 | animation: photoBrowserIn 400ms forwards;
26 | }
27 | &.photo-browser-out {
28 | display: block;
29 | animation: photoBrowserOut 400ms forwards;
30 | }
31 | html.with-statusbar-overlay & {
32 | height: ~"-webkit-calc(100% - 1rem)";
33 | height: ~"calc(100% - 1rem)";
34 | top: 1rem;
35 | }
36 | .popup > &,
37 | body > & {
38 | .navbar, .toolbar {
39 | transform: translate3d(0, 0, 0);
40 | }
41 | }
42 | .page[data-page="photo-browser-slides"] {
43 | background: none;
44 | }
45 | //add
46 | .page {
47 | box-sizing: border-box;
48 | position: absolute;
49 | left: 0;
50 | top: 0;
51 | width: 100%;
52 | height: 100%;
53 | background: #efeff4;
54 | }
55 | .view {
56 | overflow: hidden;
57 | -webkit-box-sizing: border-box;
58 | -moz-box-sizing: border-box;
59 | box-sizing: border-box;
60 | position: relative;
61 | width: 100%;
62 | height: 100%;
63 | z-index: 5000;
64 | }
65 | }
66 |
67 | .page[data-page="photo-browser-slides"] {
68 | .toolbar a {
69 | color: @color-success;
70 | }
71 | }
72 |
73 | .photo-browser-popup {
74 | background: none;
75 | }
76 |
77 | .photo-browser,
78 | .view[data-page="photo-browser-slides"] {
79 | .navbar, .toolbar {
80 | background: rgba(247, 247, 247, 0.95);
81 | transition: 400ms;
82 | }
83 | }
84 |
85 | .view[data-page="photo-browser-slides"] .page[data-page="photo-browser-slides"] {
86 | .navbar, .toolbar {
87 | transform: translate3d(0, 0, 0);
88 | }
89 | }
90 |
91 | .photo-browser-exposed {
92 | .navbar, .toolbar {
93 | opacity: 0;
94 | visibility: hidden;
95 | pointer-events: none;
96 | }
97 | .photo-browser-swiper-container {
98 | background: #000;
99 | }
100 | }
101 |
102 | .photo-browser-of {
103 | margin: 0 0.25rem;
104 | }
105 |
106 | .photo-browser-captions {
107 | pointer-events: none;
108 | position: absolute;
109 | left: 0;
110 | width: 100%;
111 | bottom: 0;
112 | z-index: 10;
113 | opacity: 1;
114 | transition: 400ms;
115 | &.photo-browser-captions-exposed {
116 | opacity: 0;
117 | }
118 | }
119 |
120 | .toolbar ~ .photo-browser-captions {
121 | bottom: 2.2rem;
122 | transform: translate3d(0, 0rem, 0);
123 | .photo-browser-exposed & {
124 | transform: translate3d(0, 2.2rem, 0);
125 | }
126 | &.photo-browser-captions-exposed {
127 | transformt: ranslate3d(0, 0rem, 0);
128 | }
129 | }
130 |
131 | .photo-browser-caption {
132 | box-sizing: border-box;
133 | transition: 300ms;
134 | position: absolute;
135 | bottom: 0;
136 | left: 0;
137 | opacity: 0;
138 | padding: 0.2rem 0.25px;
139 | width: 100%;
140 | text-align: center;
141 | color: #fff;
142 | background: rgba(0, 0, 0, 0.8);
143 | &:empty {
144 | display: none;
145 | }
146 | &.photo-browser-caption-active {
147 | opacity: 1;
148 | }
149 | .photo-browser-captions-light & {
150 | background: rgba(255, 255, 255, 0.8);
151 | color: @color-text;
152 | }
153 | .photo-browser-exposed & {
154 | color: #fff;
155 | background: rgba(0, 0, 0, 0.8);
156 | }
157 | }
158 |
159 | .photo-browser-swiper-container {
160 | position: absolute;
161 | left: 0;
162 | top: 0;
163 | width: 100%;
164 | height: 100%;
165 | overflow: hidden;
166 | background: #fff;
167 | transition: 400ms;
168 | }
169 |
170 | .photo-browser-swiper-wrapper {
171 | position: absolute;
172 | left: 0;
173 | top: 0;
174 | width: 100%;
175 | height: 100%;
176 | padding: 0;
177 | display: flex;
178 | }
179 |
180 | .photo-browser-link-inactive {
181 | opacity: 0.3;
182 | }
183 |
184 | .photo-browser-slide {
185 | width: 100%;
186 | height: 100%;
187 | position: relative;
188 | overflow: hidden;
189 | display: flex;
190 | justify-content: center;
191 | align-items: center;
192 | flex-shrink: 0;
193 | box-sizing: border-box;
194 | &.transitioning {
195 | transition: 400ms;
196 | }
197 | span.photo-browser-zoom-container {
198 | width: 100%;
199 | text-align: center;
200 | display: none;
201 | }
202 | img {
203 | width: auto;
204 | height: auto;
205 | max-width: 100%;
206 | max-height: 100%;
207 | display: none;
208 | }
209 | &.swiper-slide-active,
210 | &.swiper-slide-next,
211 | &.swiper-slide-prev {
212 | span.photo-browser-zoom-container {
213 | display: block;
214 | }
215 | img {
216 | display: inline;
217 | }
218 | &.photo-browser-slide-lazy {
219 | .preloader {
220 | display: block;
221 | }
222 | }
223 | }
224 | iframe {
225 | width: 100%;
226 | height: 100%;
227 | }
228 | .preloader {
229 | display: none;
230 | position: absolute;
231 | width: 2.1rem;
232 | height: 2.1rem;
233 | margin-left: -2.1rem;
234 | margin-top: -2.1rem;
235 | left: 50%;
236 | top: 50%;
237 | }
238 | }
239 |
240 | .photo-browser-dark {
241 | .navbar, .toolbar {
242 | background: rgba(30, 30, 30, 0.8);
243 | // .hairline-remove(top);
244 | // .hairline-remove(bottom);
245 | &:before {
246 | display: none;
247 | }
248 | &:after {
249 | display: none;
250 | }
251 | color:#fff;
252 | a {
253 | color: #fff;
254 | }
255 | }
256 | .photo-browser-swiper-container {
257 | background: #000;
258 | }
259 | }
260 |
261 | @keyframes photoBrowserIn {
262 | 0% {
263 | transform: translate3d(0, 0, 0) scale(0.5);
264 | opacity: 0;
265 | }
266 | 100% {
267 | transform: translate3d(0, 0, 0) scale(1);
268 | opacity: 1;
269 | }
270 | }
271 |
272 | @keyframes photoBrowserOut {
273 | 0% {
274 | transform: translate3d(0, 0, 0) scale(1);
275 | opacity: 1;
276 | }
277 | 100% {
278 | transform: translate3d(0, 0, 0) scale(0.5);
279 | opacity: 0;
280 | }
281 | }
282 |
--------------------------------------------------------------------------------
/less/sui/picker.less:
--------------------------------------------------------------------------------
1 | /* === Columns Picker === */
2 | .picker-columns {
3 | width: 100%;
4 | height: 13rem;
5 | z-index: 11500;
6 | &.picker-modal-inline, .popover & {
7 | height: 10rem;
8 | }
9 | @media (orientation: landscape) and (max-height: 415px) {
10 | &:not(.picker-modal-inline) {
11 | height: 10rem;
12 | }
13 | }
14 | }
15 | .popover.popover-picker-columns {
16 | width: 14rem;
17 | }
18 | .picker-items {
19 | .flexbox();
20 | .justify-content(center);
21 | padding: 0;
22 | text-align: right;
23 | font-size: 1.2rem;
24 | -webkit-mask-box-image: -webkit-linear-gradient(bottom, transparent, transparent 5%, white 20%, white 80%, transparent 95%, transparent);
25 | -webkit-mask-box-image: linear-gradient(to top, transparent, transparent 5%, white 20%, white 80%, transparent 95%, transparent);
26 | }
27 | .bar + .picker-items {
28 | height: (13rem - 2.2rem);
29 | }
30 | .picker-items-col {
31 | overflow: hidden;
32 | position: relative;
33 | max-height: 100%;
34 |
35 | &.picker-items-col-left {
36 | text-align: left;
37 | }
38 | &.picker-items-col-center {
39 | text-align: center;
40 | }
41 | &.picker-items-col-right {
42 | text-align: right;
43 | }
44 | &.picker-items-col-divider {
45 | color: @color-text;
46 | .flexbox();
47 | .align-items(center);
48 | }
49 | }
50 | .picker-items-col-wrapper {
51 | transition: 300ms;
52 |
53 | -webkit-transition-timing-function: ease-out;
54 | transition-timing-function: ease-out;
55 | }
56 | .picker-item {
57 | height: 36px;
58 | line-height: 36px;
59 | padding: 0 10px;
60 | white-space: nowrap;
61 | position: relative;
62 | overflow: hidden;
63 | text-overflow: ellipsis;
64 | color: @color-text-gray;
65 | left: 0;
66 | top: 0;
67 | width: 100%;
68 | box-sizing: border-box;
69 | transition: 300ms;
70 | .picker-items-col-absolute &{
71 | position: absolute;
72 | }
73 | &.picker-item-far {
74 | pointer-events: none;
75 | }
76 | &.picker-selected {
77 | color: @color-text;
78 | transform: translate3d(0,0,0);
79 | transform: rotateX(0deg);
80 | }
81 | &.picker-before-selected {
82 | }
83 | &.picker-after-selected {
84 | }
85 | }
86 | .picker-center-highlight {
87 | height: 36px;
88 | box-sizing: border-box;
89 | position: absolute;
90 | left: 0;
91 | width: 100%;
92 | top: 50%;
93 | margin-top: -18px;
94 | .hairline(top, #a8abb0);
95 | .hairline(bottom, #a8abb0);
96 | pointer-events: none;
97 | }
98 | // 3D Picker
99 | .picker-3d {
100 | .picker-items {
101 | overflow: hidden;
102 | -webkit-perspective: 1200px;
103 | perspective: 1200px;
104 | }
105 | .picker-items-col, .picker-items-col-wrapper, .picker-item {
106 | -webkit-transform-style: preserve-3d;
107 | transform-style: preserve-3d;
108 | }
109 | .picker-items-col {
110 | overflow: visible;
111 | }
112 | .picker-item {
113 | -webkit-transform-origin: center center -110px;
114 | transform-origin: center center -110px;
115 | -webkit-backface-visibility: hidden;
116 | backface-visibility: hidden;
117 | -webkit-transition-timing-function: ease-out;
118 | transition-timing-function: ease-out;
119 | }
120 | }
121 |
122 | .picker-modal .bar {
123 | position: relative;
124 | top: 0;
125 | .hairline(top, #a8abb0);
126 | .hairline(bottom, #a8abb0);
127 | }
128 | .picker-modal .bar .title {
129 | color: @color-text-secondary;
130 | font-weight: normal;
131 | }
132 |
133 | .city-picker {
134 | .col-province {
135 | width: 5rem;
136 | }
137 | .col-city {
138 | width: 6rem;
139 | }
140 | .col-district {
141 | width: 5rem;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/less/sui/preloader.less:
--------------------------------------------------------------------------------
1 | /* === Preloader === */
2 | .preloader {
3 | display: inline-block;
4 | width: 1rem;
5 | height: 1rem;
6 | -webkit-transform-origin: 50%;
7 | transform-origin: 50%;
8 | -webkit-animation: preloader-spin 1s steps(12, end) infinite;
9 | animation: preloader-spin 1s steps(12, end) infinite;
10 | }
11 | .preloader:after {
12 | display: block;
13 | content: "";
14 | width: 100%;
15 | height: 100%;
16 | .encoded-svg-background(" ");
17 | background-position: 50%;
18 | background-size: 100%;
19 | background-repeat: no-repeat;
20 |
21 | }
22 | .preloader-white:after {
23 | .encoded-svg-background(" ");
24 | }
25 | @-webkit-keyframes preloader-spin {
26 | 100% {
27 | -webkit-transform: rotate(360deg);
28 | }
29 | }
30 | @keyframes preloader-spin {
31 | 100% {
32 | transform: rotate(360deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/less/sui/pull-to-refresh.less:
--------------------------------------------------------------------------------
1 | /* === Pull To Refresh === */
2 | @layerHeight: 2.2rem;
3 | .pull-to-refresh-layer {
4 | position: relative;
5 | // margin-top: -44px;
6 | left:0;
7 | top:0;
8 | width:100%;
9 | height:@layerHeight;
10 |
11 | .preloader {
12 | position: absolute;
13 | left: 50%;
14 | top: 50%;
15 | margin-left: -0.5rem;
16 | margin-top: -0.5rem;
17 | visibility: hidden;
18 | }
19 | .pull-to-refresh-arrow {
20 | width: 0.65rem;
21 | height: 1rem;
22 | position: absolute;
23 | left: 50%;
24 | top: 50%;
25 | margin-left: -0.15rem;
26 | margin-top: -0.5rem;
27 | background: no-repeat center;
28 | .encoded-svg-background(" ");
29 | background-size: 0.65rem 1rem;
30 | z-index: 10;
31 | transform: rotate(0deg) translate3d(0,0,0);
32 | transition-duration: 300ms;
33 | }
34 |
35 | }
36 | .pull-to-refresh-content {
37 | transform: translate3d(0, 0, 0);
38 | &.transitioning, &.refreshing {
39 | transition: transform 400ms;
40 | }
41 | &:not(.refreshing) {
42 | .pull-to-refresh-layer .preloader {
43 | animation:none;
44 | }
45 | }
46 | &.refreshing {
47 | .pull-to-refresh-arrow {
48 | visibility: hidden;
49 | transition-duration: 0ms;
50 | }
51 | .preloader {
52 | visibility: visible;
53 | }
54 | }
55 | &.pull-up {
56 | .pull-to-refresh-arrow {
57 | transform: rotate(180deg) translate3d(0,0,0);
58 | }
59 | }
60 |
61 | }
62 | .pull-to-refresh-content {
63 | top: -@layerHeight;
64 | &.refreshing {
65 | transform: translate3d(0, @layerHeight, 0);
66 | }
67 | }
68 | .bar-nav ~ .pull-to-refresh-content,
69 | .bar-footer ~ .pull-to-refresh-content,
70 | .bar-tab ~ .pull-to-refresh-content {
71 | top: 0;
72 | &.refreshing {
73 | transform: translate3d(0, @layerHeight, 0);
74 | }
75 | }
76 | .bar-header-secondary ~ .pull-to-refresh-content,
77 | .bar-footer-secondary ~ .pull-to-refresh-content {
78 | top: 2.2rem;
79 | }
80 |
--------------------------------------------------------------------------------
/less/sui/push.less:
--------------------------------------------------------------------------------
1 | //
2 | // Push styles (to be used with push.js)
3 | // --------------------------------------------------
4 |
5 | .content {
6 | // Fade animation
7 | &.fade {
8 | left: 0;
9 | opacity: 0;
10 | transition: opacity .4s;
11 |
12 | &.in {
13 | opacity: 1;
14 | }
15 | }
16 |
17 | // Slide animation
18 | &.sliding {
19 | z-index: 2;
20 | transition: transform .4s;
21 | transform: translate3d(0, 0, 0);
22 |
23 | &.left {
24 | z-index: 1;
25 | transform: translate3d(-100%, 0, 0);
26 | }
27 |
28 | &.right {
29 | z-index: 3;
30 | transform: translate3d(100%, 0, 0);
31 | }
32 | }
33 | }
34 |
35 | // Add chevrons to elements
36 | .navigate-left,
37 | .navigate-right,
38 | .push-left,
39 | .push-right {
40 | &:after {
41 | position: absolute;
42 | top: 50%;
43 | display: inline-block;
44 | font-family: Ratchicons;
45 | font-size: inherit;
46 | line-height: 1;
47 | color: #bbb;
48 | text-decoration: none;
49 | -webkit-font-smoothing: antialiased;
50 | transform: translateY(-50%);
51 | }
52 | }
53 | .navigate-left:after,
54 | .push-left:after {
55 | left: 0.75rem;
56 | content: '\e822';
57 | }
58 | .navigate-right:after,
59 | .push-right:after{
60 | right: 0.75rem;
61 | content: '\e826';
62 | }
63 |
--------------------------------------------------------------------------------
/less/sui/rem.less:
--------------------------------------------------------------------------------
1 | //
2 | // Rem
3 | // --------------------------------------------------
4 |
5 | // Vertical screen
6 |
7 | //375屏幕为 20px,以此为基础计算出每一种宽度的字体大小
8 | //375以下不变,375以上等比放大
9 |
10 | @baseWidth: 375px;
11 | @baseFont: 20px;
12 |
13 | html {
14 | font-size: @baseFont; //默认当做320px宽度的屏幕来处理
15 | }
16 |
17 | @bps: 400px, 414px, 480px;
18 |
19 | .loop(@i: 1) when (@i <= length(@bps)) { //注意less数组是从1开始的
20 | @bp: extract(@bps, @i);
21 | @font: @bp/@baseWidth*@baseFont;
22 | @media only screen and (min-width: @bp){
23 | html {
24 | font-size: @font !important;
25 | }
26 | }
27 | .loop((@i + 1));
28 | };
29 | .loop;
30 |
--------------------------------------------------------------------------------
/less/sui/scroller.less:
--------------------------------------------------------------------------------
1 | .content-inner {
2 | box-sizing: border-box;
3 | //防止margin合并
4 | border-top: 1px solid transparent;
5 | margin-top: -1px;
6 | padding-bottom: 0.5rem;
7 | }
8 | .javascript-scroll{
9 | overflow: hidden;
10 | }
11 |
--------------------------------------------------------------------------------
/less/sui/searchbar.less:
--------------------------------------------------------------------------------
1 | /* === Search Bar === */
2 | @searchbarBorderColor: #b4b4b4;
3 | @searchbarSize: 2.2rem;
4 | .searchbar {
5 | padding: 8px 0;
6 | overflow: hidden;
7 | height: @searchbarSize;
8 | .align-items(center);
9 |
10 | .searchbar-cancel {
11 | margin-right: -3rem;
12 | width: 2.2rem; //注意,这里比 2.5rem 要小,因为如果位置刚好一样,可能在动画的过程中出现抖动
13 | float: right;
14 | height: 1.4rem;
15 | line-height: 1.4rem;
16 | text-align: center;
17 | transition: all .3s;
18 | opacity: 0;
19 | transform: translate3d(0,0,0);
20 | }
21 |
22 | .search-input {
23 | transform: translate3d(0,0,0);
24 | margin-right: 0;
25 | transition: all .3s;
26 |
27 | input {
28 | margin: 0;
29 | height: 1.4rem;
30 | }
31 | }
32 |
33 | &.searchbar-active {
34 | .searchbar-cancel {
35 | margin-right: 0;
36 | opacity: 1;
37 |
38 | + .search-input {
39 | margin-right: 2.5rem;
40 | }
41 | }
42 | }
43 | }
44 |
45 | .search-input {
46 | position: relative;
47 | input {
48 | box-sizing: border-box;
49 | width: 100%;
50 | height: 1.4rem;
51 | display: block;
52 | border: none;
53 | appearance: none;
54 | border-radius: 0.25rem;
55 | font-family: inherit;
56 | color: @color-text;
57 | font-size: 0.7rem;
58 | font-weight: normal;
59 | padding: 0 0.5rem;
60 | background-color: #fff;
61 | border: 1px solid @searchbarBorderColor;
62 | &::-webkit-input-placeholder {
63 | color: @color-text-gray-light;
64 | opacity: 1;
65 | }
66 | }
67 | .icon {
68 | position: absolute;
69 | font-size: 0.9rem;
70 | color: @searchbarBorderColor;
71 | top: 50%;
72 | left: 0.3rem;
73 | transform: translate3D(0,-50%,0);
74 | }
75 |
76 | label + input {
77 | padding-left: 1.4rem;
78 | }
79 |
80 | }
81 |
82 | .bar .searchbar {
83 | margin: 0 -0.5rem;
84 | padding: 0.4rem 0.5rem;
85 | background: rgba(0, 0, 0, .1);
86 |
87 | .search-input input {
88 | border: 0;
89 | }
90 | .searchbar-cancel {
91 | color: @color-text-secondary;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/less/sui/sm-extend.less:
--------------------------------------------------------------------------------
1 | // Variables
2 | @import "variables.less";
3 |
4 | // Mixins
5 | @import "mixins.less";
6 |
7 | //幻灯片和图片浏览器
8 | @import "photo-browser.less";
9 | @import "swiper.less";
10 |
--------------------------------------------------------------------------------
/less/sui/sm.less:
--------------------------------------------------------------------------------
1 |
2 | // Variables
3 | @import "variables.less";
4 |
5 | // Mixins
6 | @import "mixins.less";
7 |
8 | // Normalize & Base CSS
9 | @import "rem.less";
10 | @import "normalize.less";
11 | @import "base.less";
12 | @import "content-block.less";
13 |
14 | @import "grid.less";
15 | @import "icons.less";
16 |
17 | // Components
18 | @import "text.less";
19 | @import "bars.less";
20 | @import "badges.less";
21 | @import "lists.less";
22 | @import "forms.less";
23 | @import "searchbar.less";
24 | @import "buttons.less";
25 | @import "tabs.less";
26 |
27 | @import "pages.less";
28 | @import "scroller.less";
29 | @import "pull-to-refresh.less";
30 | @import "infinite.less";
31 | @import "modal.less";
32 | @import "preloader.less";
33 | @import "lists.less";
34 | @import "cards.less";
35 | @import "panels.less";
36 | @import "calendar.less";
37 | @import "picker.less";
38 |
39 | @import "fonts.less";
40 |
41 | @import "themes.less";
42 | @import "colors.less";
43 |
--------------------------------------------------------------------------------
/less/sui/swiper.less:
--------------------------------------------------------------------------------
1 | /* === Swiper === */
2 | .swiper-container {
3 | margin:0 auto;
4 | position:relative;
5 | overflow:hidden;
6 | padding-bottom: 30px; //for pagination
7 | /* Fix of Webkit flickering */
8 | z-index:1;
9 | }
10 | .swiper-container-no-flexbox {
11 | .swiper-slide {
12 | float: left;
13 | }
14 | }
15 | .swiper-container-vertical > .swiper-wrapper{
16 | -webkit-box-orient: vertical;
17 | -moz-box-orient: vertical;
18 | -ms-flex-direction: column;
19 | -webkit-flex-direction: column;
20 | flex-direction: column;
21 | }
22 | .swiper-wrapper {
23 | position:relative;
24 | width: 100%;
25 | height: 100%;
26 | z-index: 1;
27 | display: -webkit-box;
28 | display: -moz-box;
29 | display: -ms-flexbox;
30 | display: -webkit-flex;
31 | display: flex;
32 | .preserve3d();
33 |
34 | -webkit-transition-property:-webkit-transform;
35 | -moz-transition-property:-moz-transform;
36 | -o-transition-property:-o-transform;
37 | -ms-transition-property:-ms-transform;
38 | transition-property:transform;
39 |
40 | -webkit-box-sizing: content-box;
41 | -moz-box-sizing: content-box;
42 | box-sizing: content-box;
43 | }
44 | .swiper-container-android .swiper-slide, .swiper-wrapper {
45 | -webkit-transform:translate3d(0px,0,0);
46 | -moz-transform:translate3d(0px,0,0);
47 | -o-transform:translate(0px,0px);
48 | -ms-transform:translate3d(0px,0,0);
49 | transform:translate3d(0px,0,0);
50 | }
51 | .swiper-container-multirow > .swiper-wrapper {
52 | -webkit-box-lines: multiple;
53 | -moz-box-lines: multiple;
54 | -ms-fles-wrap: wrap;
55 | -webkit-flex-wrap: wrap;
56 | flex-wrap: wrap;
57 | }
58 | .swiper-container-free-mode > .swiper-wrapper {
59 | -webkit-transition-timing-function: ease-out;
60 | -moz-transition-timing-function: ease-out;
61 | -ms-transition-timing-function: ease-out;
62 | -o-transition-timing-function: ease-out;
63 | transition-timing-function: ease-out;
64 | margin: 0 auto;
65 | }
66 | .swiper-slide {
67 | .preserve3d();
68 | -webkit-flex-shrink: 0;
69 | -ms-flex: 0 0 auto;
70 | flex-shrink: 0;
71 | width: 100%;
72 | height: 100%;
73 | position: relative;
74 | }
75 |
76 | /* a11y */
77 | .swiper-container .swiper-notification {
78 | position: absolute;
79 | left: 0;
80 | top: 0;
81 | pointer-events: none;
82 | opacity: 0;
83 | z-index: -1000;
84 | }
85 |
86 | /* IE10 Windows Phone 8 Fixes */
87 | .swiper-wp8-horizontal {
88 | -ms-touch-action: pan-y;
89 | touch-action: pan-y;
90 | }
91 | .swiper-wp8-vertical {
92 | -ms-touch-action: pan-x;
93 | touch-action: pan-x;
94 | }
95 | /* Arrows */
96 | .swiper-button-prev, .swiper-button-next {
97 | position: absolute;
98 | top: 50%;
99 | width: 27px;
100 | height: 44px;
101 | margin-top: -22px;
102 | z-index: 10;
103 | cursor: pointer;
104 | -moz-background-size: 27px 44px;
105 | -webkit-background-size: 27px 44px;
106 | background-size: 27px 44px;
107 | background-position: center;
108 | background-repeat: no-repeat;
109 | &.swiper-button-disabled {
110 | opacity: 0.35;
111 | cursor: auto;
112 | pointer-events: none;
113 | }
114 | }
115 | .swiper-button-prev, .swiper-container-rtl .swiper-button-next {
116 | .encoded-svg-background(" ");
117 | left: 10px;
118 | right: auto;
119 | }
120 | .swiper-button-next, .swiper-container-rtl .swiper-button-prev {
121 | .encoded-svg-background(" ");
122 | right: 10px;
123 | left: auto;
124 | }
125 | /* Pagination Styles */
126 | .swiper-pagination {
127 | position: absolute;
128 | text-align: center;
129 | -webkit-transition: 300ms;
130 | -moz-transition: 300ms;
131 | -o-transition: 300ms;
132 | transition: 300ms;
133 | -webkit-transform: translate3d(0,0,0);
134 | -ms-transform: translate3d(0,0,0);
135 | -o-transform: translate3d(0,0,0);
136 | transform: translate3d(0,0,0);
137 | z-index: 10;
138 | &.swiper-pagination-hidden {
139 | opacity: 0;
140 | }
141 | }
142 | .swiper-pagination-bullet {
143 | width: 8px;
144 | height: 8px;
145 | display: inline-block;
146 | border-radius: 100%;
147 | background: #000;
148 | opacity: 0.2;
149 | }
150 | .swiper-pagination-bullet-active {
151 | opacity: 1;
152 | background: #007aff;
153 | }
154 | .swiper-container-vertical {
155 | > .swiper-pagination {
156 | right: 10px;
157 | top: 50%;
158 | -webkit-transform:translate3d(0px,-50%,0);
159 | -moz-transform:translate3d(0px,-50%,0);
160 | -o-transform:translate(0px,-50%);
161 | -ms-transform:translate3d(0px,-50%,0);
162 | transform:translate3d(0px,-50%,0);
163 | .swiper-pagination-bullet {
164 | margin: 5px 0;
165 | display: block;
166 | }
167 | }
168 | }
169 | .swiper-container-horizontal {
170 | > .swiper-pagination {
171 | bottom: 10px;
172 | left: 0;
173 | width: 100%;
174 | .swiper-pagination-bullet {
175 | margin: 0 5px;
176 | }
177 | }
178 | }
179 | /* 3D Container */
180 | .swiper-container-3d {
181 | -webkit-perspective: 1200px;
182 | -moz-perspective: 1200px;
183 | -o-perspective: 1200px;
184 | perspective: 1200px;
185 | .swiper-wrapper, .swiper-slide, .swiper-slide-shadow-left, .swiper-slide-shadow-right, .swiper-slide-shadow-top, .swiper-slide-shadow-bottom, .swiper-cube-shadow {
186 | .preserve3d();
187 | }
188 | .swiper-slide-shadow-left, .swiper-slide-shadow-right, .swiper-slide-shadow-top, .swiper-slide-shadow-bottom {
189 | position:absolute;
190 | left:0;
191 | top:0;
192 | width:100%;
193 | height:100%;
194 | pointer-events:none;
195 | z-index: 10;
196 | }
197 | .swiper-slide-shadow-left {
198 | background-image: -webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */
199 | background-image: -webkit-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */
200 | background-image: -moz-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */
201 | background-image: -o-linear-gradient(right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */
202 | background-image: linear-gradient(to left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */
203 | }
204 | .swiper-slide-shadow-right {
205 | background-image: -webkit-gradient(linear, right top, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */
206 | background-image: -webkit-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */
207 | background-image: -moz-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */
208 | background-image: -o-linear-gradient(left, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */
209 | background-image: linear-gradient(to right, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */
210 | }
211 | .swiper-slide-shadow-top {
212 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */
213 | background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */
214 | background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */
215 | background-image: -o-linear-gradient(bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */
216 | background-image: linear-gradient(to top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */
217 | }
218 | .swiper-slide-shadow-bottom {
219 | background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0))); /* Safari 4+, Chrome */
220 | background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Chrome 10+, Safari 5.1+, iOS 5+ */
221 | background-image: -moz-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 3.6-15 */
222 | background-image: -o-linear-gradient(top, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Opera 11.10-12.00 */
223 | background-image: linear-gradient(to bottom, rgba(0,0,0,0.5), rgba(0,0,0,0)); /* Firefox 16+, IE10, Opera 12.50+ */
224 | }
225 | }
226 | /* Coverflow */
227 | .swiper-container-coverflow {
228 | .swiper-wrapper {
229 | /* Windows 8 IE 10 fix */
230 | -ms-perspective:1200px;
231 | }
232 |
233 | }
234 | /* Fade */
235 | .swiper-container-fade {
236 | &.swiper-container-free-mode {
237 | .swiper-slide {
238 | -webkit-transition-timing-function: ease-out;
239 | -moz-transition-timing-function: ease-out;
240 | -ms-transition-timing-function: ease-out;
241 | -o-transition-timing-function: ease-out;
242 | transition-timing-function: ease-out;
243 | }
244 | }
245 | .swiper-slide {
246 | pointer-events: none;
247 | }
248 | .swiper-slide-active {
249 | pointer-events: auto;
250 | }
251 | }
252 | /* Cube */
253 | .swiper-container-cube {
254 | overflow: visible;
255 | .swiper-slide {
256 | pointer-events: none;
257 | visibility: hidden;
258 | -webkit-transform-origin: 0 0;
259 | -moz-transform-origin: 0 0;
260 | -ms-transform-origin: 0 0;
261 | transform-origin: 0 0;
262 | -webkit-backface-visibility: hidden;
263 | -moz-backface-visibility: hidden;
264 | -ms-backface-visibility: hidden;
265 | backface-visibility: hidden;
266 | width: 100%;
267 | height: 100%;
268 | }
269 | &.swiper-container-rtl .swiper-slide{
270 | -webkit-transform-origin: 100% 0;
271 | -moz-transform-origin: 100% 0;
272 | -ms-transform-origin: 100% 0;
273 | transform-origin: 100% 0;
274 | }
275 | .swiper-slide-active, .swiper-slide-next, .swiper-slide-prev, .swiper-slide-next + .swiper-slide {
276 | pointer-events: auto;
277 | visibility: visible;
278 | }
279 | .swiper-cube-shadow {
280 | position: absolute;
281 | left: 0;
282 | bottom: 0px;
283 | width: 100%;
284 | height: 100%;
285 | background: #000;
286 | opacity: 0.6;
287 | -webkit-filter: blur(50px);
288 | filter: blur(50px);
289 | }
290 | &.swiper-container-vertical .swiper-cube-shadow {
291 | z-index: 0;
292 | }
293 | }
294 | /* Scrollbar */
295 | .swiper-scrollbar {
296 | border-radius: 10px;
297 | position: relative;
298 | -ms-touch-action: none;
299 | background: rgba(0,0,0,0.1);
300 | .swiper-container-horizontal > & {
301 | position: absolute;
302 | left: 1%;
303 | bottom: 3px;
304 | z-index: 50;
305 | height: 5px;
306 | width: 98%;
307 | }
308 | .swiper-container-vertical > & {
309 | position: absolute;
310 | right: 3px;
311 | top: 1%;
312 | z-index: 50;
313 | width: 5px;
314 | height: 98%;
315 | }
316 | }
317 | .swiper-scrollbar-drag {
318 | height: 100%;
319 | width: 100%;
320 | position: relative;
321 | background: rgba(0,0,0,0.5);
322 | border-radius: 10px;
323 | left: 0;
324 | top: 0;
325 | }
326 | .swiper-scrollbar-cursor-drag {
327 | cursor: move;
328 | }
329 | /* Preloader */
330 | .swiper-slide .preloader {
331 | width: 42px;
332 | height: 42px;
333 | position: absolute;
334 | left: 50%;
335 | top: 50%;
336 | margin-left: -21px;
337 | margin-top: -21px;
338 | z-index: 10;
339 | }
340 |
341 |
342 | .swiper-slide img {
343 | display: block;
344 | }
345 |
--------------------------------------------------------------------------------
/less/sui/tabs.less:
--------------------------------------------------------------------------------
1 | /* === Tabs === */
2 | .tabs {
3 | .tab {
4 | display: none;
5 | }
6 | .tab.active {
7 | display: block;
8 | }
9 | }
10 | .tabs-animated-wrap {
11 | position: relative;
12 | width: 100%;
13 | overflow: hidden;
14 | height: 100%;
15 | >.tabs {
16 | .flexbox();
17 | height: 100%;
18 | transition: 300ms;
19 | >.tab {
20 | width: 100%;
21 | display: block;
22 | .flex-shrink(0);
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/less/sui/text.less:
--------------------------------------------------------------------------------
1 | .color-default {
2 | color: @color-text;
3 | }
4 |
5 | .color-gray {
6 | color: #999;
7 | }
8 |
9 | .color-primary {
10 | color: @color-primary;
11 | }
12 |
13 | .color-success {
14 | color: @color-success;
15 | }
16 | .color-danger {
17 | color: @color-danger;
18 | }
19 | .color-warning {
20 | color: @color-warning;
21 | }
22 |
23 | .text-center {
24 | text-align: center;
25 | }
26 |
--------------------------------------------------------------------------------
/less/sui/themes.less:
--------------------------------------------------------------------------------
1 | /*==========================
2 | Framework7 Layouts Themes
3 | ==========================*/
4 | @import url('mixins.less');
5 | /* === Dark layout === */
6 | .theme-dark {
7 | @pageBg: #222426;
8 | @barsBg: #131313;
9 | @barsBorder: #333;
10 | @barsText: #fff;
11 | @tabBarText: #fff;
12 | @text: #ddd;
13 | @lightText: #bbb;
14 | @strongText: #fff;
15 | @activeLink: #29292f;
16 | @blockBg: #1c1d1f;
17 | @blockBorder: #393939;
18 | @blockStrongBg: #1c1d1f;
19 | @dividerBg: #1a1a1a;
20 | @itemAfterText: @lightText;
21 | @searchbarBg: #333;
22 | @searchbarBorder: #333;
23 | @swipeoutButton: #444;
24 | @checkboxBorder: @blockBorder;
25 | background-color: @pageBg;
26 | .bar, .bar& {
27 | .hairline-color(bottom, @barsBorder);
28 | background-color: @barsBg;
29 | color:@barsText;
30 |
31 | }
32 | .title {
33 | color: @barsText;
34 | }
35 | .bar-nav, .bar-tab,
36 | .bar-nav&, .bar-tab& {
37 | .hairline-color(top, @barsBorder);
38 | background-color: @barsBg;
39 | color: @tabBarText;
40 | }
41 | .tab-item {
42 | color: @tabBarText;
43 | &.active {
44 | color: @color-primary;
45 | }
46 | }
47 | // Picker
48 | .picker-calendar-week-days {
49 | color:#fff;
50 | background-color: @barsBg;
51 | }
52 | .popover .picker-modal, .picker-modal.picker-modal-inline {
53 | .picker-center-highlight {
54 | .hairline-color(top, @barsBorder);
55 | .hairline-color(bottom, @barsBorder);
56 | }
57 | .picker-item.picker-selected {
58 | color:#fff;
59 | }
60 | .picker-calendar-week-days {
61 | color: #fff;
62 | }
63 | .picker-calendar-day {
64 | color:#fff;
65 | &.picker-calendar-day-prev, &.picker-calendar-day-next {
66 | color: #777;
67 | }
68 | &.picker-calendar-day-disabled {
69 | color: #555;
70 | }
71 | &.picker-calendar-day-today span {
72 | background: #444;
73 | }
74 | }
75 | .picker-calendar-week-days, .picker-calendar-row {
76 | .hairline-color(bottom, @barsBorder);
77 | }
78 | .toolbar ~ .picker-modal-inner .picker-calendar-months, .picker-calendar-week-days ~ .picker-calendar-months {
79 | .hairline-color(top, @barsBorder);
80 | }
81 |
82 | }
83 | .popover .picker-modal {
84 | .toolbar {
85 | .hairline-color(bottom, @barsBorder);
86 | }
87 | }
88 | // Photo Browser
89 | .photo-browser, .photo-browser&, .view[data-page="photo-browser-slides"], .view[data-page="photo-browser-slides"]& {
90 | .navbar, .toolbar {
91 | background: rgba(red(@barsBg), green(@barsBg), blue(@barsBg), 0.95);
92 | }
93 | }
94 | .tabbar a:not(.active) {
95 | color:@tabBarText;
96 | }
97 | .page, .login-screen-content, .page&, .panel, .panel&, .content {
98 | background-color: @pageBg;
99 | color:@text;
100 | }
101 | .content-block-title {
102 | color:@strongText;
103 | }
104 | .content-block, .content-block& {
105 | color:@lightText;
106 | }
107 | .content-block-inner {
108 | background: @blockStrongBg;
109 | color:@text;
110 | .hairline-color(top, @blockBorder);
111 | .hairline-color(bottom, @blockBorder);
112 | }
113 | .list-block, .list-block& {
114 | ul {
115 | background: @blockBg;
116 | .hairline-color(top, @blockBorder);
117 | .hairline-color(bottom, @blockBorder);
118 | }
119 | &.inset ul{
120 | background: @blockStrongBg;
121 | }
122 | &.notifications > ul {
123 | background: none;
124 | }
125 | .item-title, .item-subtitle {
126 | color: @lightText;
127 | }
128 | }
129 | .card {
130 | background: @blockBg;
131 | }
132 | .card-header{
133 | .hairline-color(bottom, @blockBorder);
134 | }
135 | .card-footer {
136 | .hairline-color(top, @blockBorder);
137 | color:@lightText;
138 | }
139 | .popover, .popover& {
140 | background: rgba(0,0,0,0.8);
141 | .popover-angle:after {
142 | background: rgba(0,0,0,0.8);
143 | }
144 | .list-block ul {
145 | background: none;
146 | }
147 |
148 | }
149 | .actions-popover .list-block ul {
150 | .hairline-color(top, @blockBorder);
151 | .hairline-color(bottom, @blockBorder);
152 | }
153 | .actions-popover .actions-popover-label {
154 | .hairline-color(bottom, @blockBorder);
155 | }
156 | li.sorting {
157 | background-color: @activeLink;
158 | }
159 | .swipeout-actions-left a, .swipeout-actions-right a {
160 | background-color: @swipeoutButton;
161 | }
162 | .item-inner, .list-block ul ul li:last-child .item-inner {
163 | .hairline-color(bottom, @blockBorder);
164 | }
165 | .item-after {
166 | color:@itemAfterText;
167 | }
168 | .item-link, label.label-checkbox, label.label-radio {
169 | html:not(.watch-active-state) &:active, &.active-state {
170 | background-color: @activeLink;
171 | }
172 | }
173 | .item-link.list-button {
174 | .hairline-color(bottom, @blockBorder);
175 | }
176 | .list-block-label {
177 | color:@lightText;
178 | }
179 | .item-divider, .list-group-title {
180 | background: @dividerBg;
181 | color:@lightText;
182 | .hairline-color(top, @blockBorder);
183 | }
184 |
185 | // Searchbar
186 | .searchbar {
187 | background: @searchbarBg;
188 | .hairline-color(bottom, @searchbarBorder);
189 | }
190 |
191 | // Forms
192 | .list-block, .list-block& {
193 | input[type="text"], input[type="password"], input[type="email"], input[type="tel"], input[type="url"], input[type="date"], input[type="datetime-local"], input[type="number"], select, textarea {
194 | color:@strongText;
195 | }
196 | }
197 | .label-switch .checkbox {
198 | background-color: @checkboxBorder;
199 | &:before {
200 | background-color: @blockBg;
201 | }
202 | }
203 | .range-slider input[type="range"]:after {
204 | background: @blockBg;
205 | }
206 |
207 | .buttons-tab {
208 | background: @barsBg;
209 |
210 | .tab-link:not(.active) {
211 | color: @text;
212 | }
213 | }
214 |
215 | }
216 |
217 | /* === White layout === */
218 | .theme-white {
219 | @pageBg: #fff;
220 | @barsBg: #fff;
221 | @barsBorder: #ddd;
222 | @barsText: #000;
223 | @tabBarText: #777;
224 | @text: #000;
225 | @lightText: #777;
226 | @strongText: #777;
227 | @activeLink: #eee;
228 | @blockBg: @pageBg;
229 | @blockBorder: #ddd;
230 | @blockStrongBg: #fafafa;
231 | @dividerBg: #f7f7f7;
232 | @itemAfterText: #8e8e93;
233 | @searchbarBg: #c9c9ce;
234 | @searchbarBorder: #b4b4b4;
235 | @swipeoutButton: #c7c7cc;
236 | @checkboxBorder: #e5e5e5;
237 | .navbar, .navbar&, .subnavbar, .subnavbar& {
238 | .hairline-color(bottom, @barsBorder);
239 | background-color: @barsBg;
240 | color:@barsText;
241 | }
242 | .toolbar, .toolbar& {
243 | .hairline-color(top, @barsBorder);
244 | background-color: @barsBg;
245 | color:@barsText;
246 | }
247 | // Picker
248 | .popover .picker-modal, .picker-modal.picker-modal-inline {
249 | .picker-center-highlight {
250 | .hairline-color(top, @barsBorder);
251 | .hairline-color(bottom, @barsBorder);
252 | }
253 | .picker-calendar-week-days, .picker-calendar-row {
254 | .hairline-color(bottom, @barsBorder);
255 | }
256 | .toolbar ~ .picker-modal-inner .picker-calendar-months, .picker-calendar-week-days ~ .picker-calendar-months {
257 | .hairline-color(top, @barsBorder);
258 | }
259 | }
260 | .popover .picker-modal {
261 | .toolbar {
262 | .hairline-color(bottom, @barsBorder);
263 | }
264 | }
265 | // Photo Browser
266 | .photo-browser, .photo-browser&, .view[data-page="photo-browser-slides"], .view[data-page="photo-browser-slides"]& {
267 | .navbar, .toolbar {
268 | background: rgba(red(@barsBg), green(@barsBg), blue(@barsBg), 0.95);
269 | }
270 | }
271 | .tabbar a:not(.active) {
272 | color:@tabBarText;
273 | }
274 | .page, .login-screen-content, .page&, .panel, .panel& {
275 | background-color: @pageBg;
276 | color: @text;
277 | }
278 | .content-block-title {
279 | color:@strongText;
280 | }
281 | .content-block, .content-block& {
282 | color:@lightText;
283 | }
284 | .content-block-inner {
285 | background: @blockStrongBg;
286 | color:@text;
287 | .hairline-color(bottom, @blockBorder);
288 | .hairline-color(top, @blockBorder);
289 | }
290 | .list-block, .list-block& {
291 | ul {
292 | background: @blockBg;
293 | .hairline-color(bottom, @blockBorder);
294 | .hairline-color(top, @blockBorder);
295 | }
296 | &.inset ul{
297 | background: @blockStrongBg;
298 | }
299 | &.notifications > ul {
300 | background: none;
301 | }
302 | }
303 | .popover-inner > .list-block ul {
304 | background: none;
305 | }
306 | li.sorting {
307 | background-color: @activeLink;
308 | }
309 | .swipeout-actions-left a, .swipeout-actions-right a {
310 | background-color: @swipeoutButton;
311 | }
312 | .item-inner, .list-block ul ul li:last-child .item-inner {
313 | border-color: @blockBorder;
314 | .hairline-color(bottom, @blockBorder);
315 | }
316 | .item-after {
317 | color:@itemAfterText;
318 | }
319 | .item-link, label.label-checkbox, label.label-radio {
320 | html:not(.watch-active-state) &:active, &.active-state {
321 | background-color: @activeLink;
322 | }
323 | }
324 | .item-link.list-button {
325 | .hairline-color(bottom, @blockBorder);
326 | }
327 | .list-block-label {
328 | color:@lightText;
329 | }
330 | .item-divider, .list-group-title {
331 | background: @dividerBg;
332 | color:@lightText;
333 | .hairline-color(top, @blockBorder);
334 | }
335 |
336 | // Searchbar
337 | .searchbar {
338 | background: @searchbarBg;
339 | .hairline-color(bottom, @searchbarBorder);
340 | }
341 |
342 | // Forms
343 | .list-block, .list-block& {
344 | input[type="text"], input[type="password"], input[type="email"], input[type="tel"], input[type="url"], input[type="date"], input[type="datetime-local"], input[type="number"], select, textarea {
345 | color:@strongText;
346 | }
347 | }
348 | .label-switch .checkbox {
349 | background-color: @checkboxBorder;
350 | &:before {
351 | background-color: @blockBg;
352 | }
353 | }
354 | .range-slider input[type="range"]:after {
355 | background: @blockBg;
356 | }
357 | }
358 |
--------------------------------------------------------------------------------
/less/sui/variables.less:
--------------------------------------------------------------------------------
1 | //
2 | // Variables
3 | // --------------------------------------------------
4 |
5 | // Type
6 | // --------------------------------------------------
7 | @font-family-default: "Helvetica Neue", Helvetica, sans-serif;
8 | @font-size-default: 0.85rem;
9 | @font-weight: 500;
10 | @font-weight-light: 400;
11 | @line-height-default: 1.05rem;
12 |
13 |
14 | //img
15 | @imgBaseUrl: "../img";
16 |
17 | // Colors
18 | // --------------------------------------------------
19 |
20 |
21 | // 主色
22 | @color-primary: #0894ec;
23 | @color-danger: #f6383a;
24 | @color-warning: #f60;
25 | @color-success: #4cd964;
26 |
27 | @color-primary-active: #0a8ddf;
28 | @color-danger-active: darken(@color-danger, 10%);
29 | @color-warning-active: darken(@color-warning, 10%);
30 | @color-success-active: darken(@color-success, 10%);
31 |
32 | @color-split: #e7e7e7; //分割线的颜色
33 | @color-bg: #eee;
34 | @color-text: #3d4145; //文案色
35 | @color-text-secondary: #5f646e; //次级文案
36 | @color-text-gray: #999; //灰色文案
37 | @color-text-gray-light: #ccc; //更灰色文案
38 |
39 | //链接色
40 | @color-link: @color-primary; //链接色有可能不同于主色
41 | @color-link-active: @color-primary-active; //链接色有可能不同于主色
42 |
43 | // Bars
44 | // --------------------------------------------------
45 |
46 | @bar-base-height: 2.2rem;
47 | @bar-tab-height: 2.5rem;
48 | @bar-side-spacing: 0.5rem;
49 |
50 |
51 | // Cards
52 | // --------------------------------------------------
53 |
54 | @card-bg: #fff;
55 |
56 |
57 | // Buttons
58 | // --------------------------------------------------
59 |
60 | @button-font-size: 0.6rem;
61 |
62 |
63 | // Transitions
64 | // --------------------------------------------------
65 |
66 | @timing-fuction: cubic-bezier(.1,.5,.1,1); // Inspired by @c2prods
67 |
68 |
69 | // Borders
70 | // --------------------------------------------------
71 |
72 | @border-default-width: 1px;
73 | @border-default-color: @color-split;
74 | @border-default: @border-default-width solid @border-default-color;
75 | @border-radius: 0.3rem;
76 |
--------------------------------------------------------------------------------
/less/webui/index.less:
--------------------------------------------------------------------------------
1 | html, body {
2 | position: relative;
3 | height: 100%;
4 | width: 100%;
5 | overflow-x: hidden;
6 | -webkit-tap-highlight-color: transparent;
7 | }
8 | div{
9 | cursor:pointer;
10 | }
11 | .tabs .tab {
12 | display: none;
13 | }
14 | .tabs .tab.active {
15 | display: block;
16 | }
17 |
18 | .buttons-tab .button.disabled{
19 | color: #c8c9cb
20 | }
21 |
22 | .buttons-tab .button.disabled:active{
23 | border-bottom:transparent;
24 | }
25 |
26 | .view, .views {
27 | position: relative;
28 | width: 100%;
29 | height: 100%;
30 | z-index: 5000;
31 | }
32 | .views {
33 | overflow: auto;
34 | -webkit-overflow-scrolling: touch;
35 | }
36 | .view {
37 | overflow: hidden;
38 | box-sizing: border-box;
39 | }
40 | .pages {
41 | position: relative;
42 | width: 100%;
43 | height: 100%;
44 | overflow: hidden;
45 |
46 | }
47 | .page {
48 | box-sizing: border-box;
49 | position: absolute;
50 | left: 0;
51 | top: 0;
52 | bottom:0;
53 | width: 100%;
54 | height: 100%;
55 | background: #efeff4;
56 | -webkit-transform: translate3d(0,0,0);
57 | transform: translate3d(0,0,0);
58 | display:block;
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-webui",
3 | "version": "0.0.1",
4 | "title": "Ant Design",
5 | "description": "基于framework7的react的移动端组件库",
6 | "homepage": "https://github.com/liugenpeng/react-mui",
7 | "main": "lib/index",
8 | "author": "Liugenpeng",
9 | "contributors": [
10 | "react-mui"
11 | ],
12 | "keywords": [
13 | "react",
14 | "framework7",
15 | "react-component",
16 | "javascript",
17 | "ui"
18 | ],
19 | "scripts": {
20 | "babel": "babel src --out-dir lib",
21 | "start": "webpack-dev-server --config webpack.dev.config.js --progress --colors",
22 | "test": "karma start"
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "git+https://github.com/liugenpeng/react-mui.git"
27 | },
28 | "bugs": {
29 | "url": "https://github.com/liugenpeng/react-mui/issues"
30 | },
31 | "license": "MIT",
32 | "peerDependencies": {
33 | "react": ">=0.14.3",
34 | "react-dom": ">=0.14.3"
35 | },
36 | "devDependencies": {
37 | "autoprefixer-loader": "~2.0.0",
38 | "babel": "^5.8.23",
39 | "babel-core": "^5.8.25",
40 | "babel-eslint": "^4.1.3",
41 | "babel-loader": "^5.3.2",
42 | "babel-plugin-dev-expression": "^0.1.0",
43 | "babel-runtime": "^5.8.29",
44 | "chai": "^3.3.0",
45 | "classnames": "^2.2.0",
46 | "colors": "^1.1.2",
47 | "css-loader": "^0.21.0",
48 | "es5-shim": "^4.3.1",
49 | "file-loader": "^0.8.4",
50 | "json-loader": "^0.5.3",
51 | "karma": "~0.13.10",
52 | "karma-chrome-launcher": "~0.2.1",
53 | "karma-cli": "0.1.1",
54 | "karma-coverage": "^0.5.2",
55 | "karma-coveralls": "^1.1.2",
56 | "karma-firefox-launcher": "~0.1.6",
57 | "karma-mocha": "~0.2.0",
58 | "karma-mocha-reporter": "^1.1.1",
59 | "karma-sinon-chai": "^1.1.0",
60 | "karma-sourcemap-loader": "^0.3.5",
61 | "karma-webpack": "^1.7.0",
62 | "less": "^2.5.3",
63 | "less-loader": "^2.2.1",
64 | "lodash": "^3.10.1",
65 | "react-addons-test-utils": "^0.14.3",
66 | "react-router": "^1.0.0-rc3",
67 | "sinon": "^1.17.1",
68 | "sinon-chai": "^2.8.0",
69 | "style-loader": "^0.13.0",
70 | "url-loader": "^0.5.6",
71 | "webpack": "^1.12.2",
72 | "webpack-dev-middleware": "^1.2.0",
73 | "webpack-dev-server": "^1.12.0"
74 | },
75 | "dependencies": {
76 | "react-fastclick": "^1.0.3",
77 | "react-gestures": "^0.1.8",
78 | "react-hammerjs": "^0.4.2",
79 | "react-swipe": "^3.0.0",
80 | "react-swipeable": "^3.0.2",
81 | "swipe-js-iso": ">=2.0.0"
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/Button.js:
--------------------------------------------------------------------------------
1 | import React , { Component , PropTypes } from 'react';
2 | import { css,pureRender } from './enhance/index';
3 | import createEnhance from './core/createEnhance';
4 |
5 | @createEnhance(css)
6 | export default class Button extends Component{
7 | static displayName = "Button";
8 | static propTypes = {
9 | color:PropTypes.string,
10 | disabled:PropTypes.bool,
11 | fill:PropTypes.bool,
12 | big:PropTypes.bool,
13 | round:PropTypes.bool,
14 | active:PropTypes.bool,
15 | wrap:PropTypes.bool
16 | };
17 | static get defaultProps(){
18 | return {
19 | disabled:false,
20 | fill:false,
21 | big:false,
22 | round:false,
23 | active:false,
24 | href:"javascript:;",
25 | wrap:true
26 | }
27 | }
28 | _getColorClassName=(color)=>{
29 | return !color ? "":`button-${color}`;
30 | }
31 | render=()=>{
32 | const { color , disabled , fill ,
33 | big , round , active , inline , href ,
34 | className, children ,wrap, ...other
35 | } = this.props;
36 |
37 | let classesSet = {
38 | disabled,
39 | "button-fill":fill,
40 | "button-big":big,
41 | "button-round":round,
42 | active
43 | };
44 | let colorCls = this._getColorClassName(color);
45 |
46 | let buttonEl = (
47 |
48 | { children }
49 |
50 | );
51 | let resultElement ;
52 | resultElement = wrap ? ({buttonEl}
):(buttonEl);
53 | return resultElement
54 |
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/ButtonRow.js:
--------------------------------------------------------------------------------
1 | import React , { Component , PropTypes } from 'react';
2 | import { css,pureRender } from './enhance/index';
3 | import createEnhance from './core/createEnhance'
4 |
5 | @createEnhance(css)
6 | export default class ButtonRow extends Component{
7 | static displayName = "ButtonRow";
8 | render=()=>{
9 | const {
10 | className ,
11 | children ,
12 | round ,
13 | color ,
14 | big ,
15 | ...other
16 | } = this.props;
17 |
18 | let cloneProps = {
19 | fill:false,
20 | wrap:false,
21 | big,
22 | color,
23 | round
24 | };
25 | let buttons = React.Children.map(children,(button)=>{
26 | return React.cloneElement(button,cloneProps);
27 | });
28 | return (
29 |
30 | {buttons}
31 |
32 | );
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/Col.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import { css , pureRender } from './enhance/index';
3 | import createEnhance from './core/createEnhance';
4 | import constant from './constant';
5 | @createEnhance(css,pureRender)
6 | export default class Col extends Component{
7 | static propTypes= {
8 | ComponentClass:React.PropTypes.string,
9 | width:React.PropTypes.string
10 | };
11 | static defaultProps = {
12 | width:"100",
13 | ComponentClass: 'div'
14 | };
15 |
16 | render=()=>{
17 |
18 | const {
19 | ComponentClass,
20 | className ,
21 | children ,
22 | width ,
23 | ...other
24 | } = this.props;
25 |
26 | let classes = {};
27 | let widthClassName = constant.COLS[width] ? constant.COLS[width] : constant["100"];
28 |
29 | return (
30 |
33 | {children}
34 |
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Icon.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import { css,pureRender } from './enhance/index';
3 | import createEnhance from './core/createEnhance'
4 | /**
5 | * 图标组件
6 | */
7 | @createEnhance(css,pureRender)
8 | export default class Icon extends Component{
9 | static propTypes = {
10 | fontSize:React.PropTypes.string,
11 | color:React.PropTypes.string
12 | };
13 |
14 | render=()=>{
15 | const { fontSize , color , icon , ...other } = this.props;
16 | const iconClassName = "icon-"+icon;
17 | const iconStyle = {
18 | fontSize,
19 | color
20 | };
21 | return (
22 |
23 | );
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/Image.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import { css,pureRender } from './enhance/index';
3 | import createEnhance from './core/createEnhance'
4 |
5 | /**
6 | * Image 组件
7 | * author:LGP
8 | */
9 | @createEnhance(css,pureRender)
10 | export default class Image extends Component{
11 | static propTypes= {
12 | src:React.PropTypes.string,
13 | responsive: React.PropTypes.bool,
14 | rounded: React.PropTypes.bool,
15 | circle: React.PropTypes.bool,
16 | thumbnail: React.PropTypes.bool
17 | };
18 | static defaultProps = {
19 | responsive: false, // 是否自适应
20 | rounded: false, // 方形
21 | circle: false, // 原型
22 | thumbnail: false // 缩略图
23 | };
24 |
25 | render=()=>{
26 | const {
27 | responsive , rounded , circle ,
28 | thumbnail , className ,
29 | ...other
30 | } = this.props;
31 | const classes = {
32 | 'img-responsive': responsive,
33 | 'img-rounded': rounded,
34 | 'img-circle':circle,
35 | 'img-thumbnail': thumbnail
36 | };
37 | return (
38 |
39 | );
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/src/Row.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import { css , pureRender } from './enhance/index';
3 | import createEnhance from './core/createEnhance';
4 |
5 | @createEnhance(css,pureRender)
6 | export default class Row extends Component{
7 | static propTypes= {
8 | ComponentClass:React.PropTypes.string
9 | };
10 | static defaultProps = {
11 | ComponentClass: 'div'
12 | };
13 |
14 | render=()=>{
15 |
16 | const {
17 | ComponentClass,
18 | className ,
19 | children ,
20 | ...other
21 | } = this.props;
22 |
23 | return (
24 |
27 | {children}
28 |
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/constant.js:
--------------------------------------------------------------------------------
1 | const constant = {
2 | COLS: {
3 | '5': 'col-5',
4 | '10': 'col-10',
5 | '15': 'col-15',
6 | '20': 'col-20',
7 | '25': 'col-25',
8 | '33': 'col-33',
9 | '40': 'col-30',
10 | '50': 'col-50',
11 | '60': 'col-60',
12 | '66': 'col-66',
13 | '75': 'col-75',
14 | '80': 'col-80',
15 | '85': 'col-85',
16 | '90': 'col-90',
17 | '95': 'col-95',
18 | '100': 'col-100'
19 | }
20 | }
21 | export default constant;
22 |
--------------------------------------------------------------------------------
/src/core/createEnhance.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import classNames from 'classnames';
3 | /**
4 | * 组件增强器,动态添加功能
5 | */
6 | export default function createEnhance(...utilsList){
7 | let utis = Array.from(utilsList);
8 | return function wrapWithEnhance(WrappedComponent){
9 | utis.forEach((util)=>{
10 | for(var k in util){
11 | if(k == "__esModule") continue;
12 | if(util.hasOwnProperty(k)){
13 | WrappedComponent.prototype[k] = util[k];
14 | }
15 | }
16 | });
17 | return WrappedComponent;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/enhance/css.js:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames';
2 |
3 | export function mergeClass(...classList){
4 | return classNames(...classList);
5 | }
6 |
--------------------------------------------------------------------------------
/src/enhance/dom.js:
--------------------------------------------------------------------------------
1 | export function getDom(){
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/src/enhance/index.js:
--------------------------------------------------------------------------------
1 | import * as css from './css';
2 | import * as dom from './dom';
3 | import * as pureRender from './pureRender';
4 | export {
5 | css,
6 | dom,
7 | pureRender
8 | };
9 |
--------------------------------------------------------------------------------
/src/enhance/pureRender.js:
--------------------------------------------------------------------------------
1 | import shallowCompare from '../utils/shallowEqual';
2 | export function shouldComponentUpdate(nextProps,nextState){
3 | return shallowCompare(this, nextProps, nextState)
4 | }
5 |
--------------------------------------------------------------------------------
/src/footer/Footer.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import { css , pureRender } from '../enhance/index';
3 | import createEnhance from '../core/createEnhance';
4 | /**
5 | * Foote导航
6 | */
7 | @createEnhance(css)
8 | export default class Footer extends Component{
9 |
10 | render=()=>{
11 | const {
12 | className ,
13 | children ,
14 |
15 | ...other
16 | } = this.props;
17 |
18 | return (
19 |
20 | { children }
21 |
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/footer/FooterItem.js:
--------------------------------------------------------------------------------
1 | import React , { Component , PropTypes } from 'react';
2 | import { css , pureRender } from '../enhance/index';
3 | import Icon from '../Icon';
4 | import createEnhance from '../core/createEnhance';
5 | /**
6 | * FooterItem 组件(底部导航栏子组件)
7 | * author:LGP
8 | */
9 | @createEnhance(css,pureRender)
10 | export default class FooterItem extends Component{
11 | static propTypes = {
12 | active:PropTypes.bool,
13 | disabled:PropTypes.bool
14 | };
15 | static defaultProps = {
16 | active:false,
17 | disabled:false
18 | };
19 |
20 | render=()=>{
21 | let {
22 | className ,
23 | icon ,
24 | active,
25 | text ,
26 | disabled ,
27 | ...other
28 | } = this.props;
29 |
30 |
31 | const classSet = {
32 | disabled,
33 | active
34 | }
35 | //图标组件
36 | const iconComponent = !icon ? null : (
37 |
38 | );
39 | //文本
40 | const textComponent = iconComponent ? (
41 |
42 | {text}
43 |
44 | ) : text;
45 | //拼装整体组件
46 | let contentComponent ;
47 |
48 | return (
49 |
50 | {iconComponent}
51 | {textComponent}
52 |
53 | );
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/src/header/Header.js:
--------------------------------------------------------------------------------
1 | import React , { Component } from 'react';
2 | import { css , pureRender } from '../enhance/index';
3 | import createEnhance from '../core/createEnhance';
4 |
5 | /**
6 | * Header组件(导航栏)
7 | * author:LGP
8 | */
9 | @createEnhance(css)
10 | export default class Header extends Component{
11 | static propTypes = {
12 | title:React.PropTypes.string
13 | };
14 | render=()=>{
15 | const {
16 | className ,
17 | children ,
18 | title ,
19 | ...other
20 | } = this.props;
21 | //title组件
22 | const titleComponent = !title ? null : (
23 | {title}
24 | );
25 | return (
26 |
27 | { children }
28 | { titleComponent }
29 |
30 | );
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/src/header/HeaderItem.js:
--------------------------------------------------------------------------------
1 | import React , { Component , PropTypes } from 'react';
2 | import { css , pureRender } from '../enhance/index';
3 | import Icon from '../Icon';
4 | import createEnhance from '../core/createEnhance';
5 | /**
6 | * NavItem 组件(导航栏子组件)
7 | * author:LGP
8 | */
9 | @createEnhance(css,pureRender)
10 | export default class HeaderItem extends Component{
11 | static propTypes = {
12 | link:PropTypes.bool,
13 | disabled:PropTypes.bool,
14 | position:PropTypes.string,
15 | ComponentClass:React.PropTypes.string
16 | };
17 | static defaultProps = {
18 | link:false,
19 | disabled:false,
20 | ComponentClass:"button"
21 | };
22 |
23 | render=()=>{
24 | let {
25 | className ,
26 | icon ,
27 | text ,
28 | position ,
29 | link ,
30 | disabled ,
31 | ComponentClass ,
32 | ...other
33 | } = this.props;
34 |
35 | const isLeft = position == "left" ;
36 |
37 | const classSet = {
38 | disabled,
39 | "button-link":link,
40 | "pull-left":isLeft,
41 | "pull-right":!isLeft
42 | }
43 |
44 | //图标组件
45 | const iconComponent = !icon ? null : (
46 |
47 | );
48 |
49 | //拼装整体组件
50 | let contentComponent ;
51 | ComponentClass = !ComponentClass ? "a":ComponentClass;
52 |
53 | return (
54 |
55 | {iconComponent}
56 | {text}
57 |
58 | );
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/src/tabs/Tab.js:
--------------------------------------------------------------------------------
1 | import React , { Component , PropTypes } from 'react';
2 | import { css , pureRender } from '../enhance/index';
3 | import createEnhance from '../core/createEnhance';
4 | import Swipeable from 'react-swipeable';
5 | @createEnhance(css)
6 | export default class Tab extends Component{
7 | static displayName = "Tab";
8 | static propTypes = {
9 | onDestroy: PropTypes.func,
10 | };
11 | componentWillUnmount=()=>{
12 | const { onDestroy } = this.props;
13 | onDestroy && onDestroy();
14 | }
15 | render=()=>{
16 | const {
17 | title ,
18 | disabled ,
19 | active ,
20 | className,
21 | children ,
22 | ...other
23 | } = this.props;
24 | /*let childs = React.Children.map(children,(item)=>{
25 |
26 | return (
27 |
28 | { {item}
}
29 |
30 | );
31 | }) */
32 |
33 | return (
34 |
35 |
36 |
37 |
41 |
42 | { children }
43 |
44 |
45 |
46 |
47 |
48 | );
49 | }
50 | handlerSwipedRight=(e,dis)=>{
51 | const { onSwipedRight } = this.props;
52 | if(dis<=-50){
53 | onSwipedRight && onSwipedRight();
54 | }
55 | }
56 | handlerSwipedLeft=(e,dis)=>{
57 | const { onSwipedLeft } = this.props;
58 | if(dis>=50){
59 | onSwipedLeft && onSwipedLeft();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/tabs/TabNav.js:
--------------------------------------------------------------------------------
1 | import React , { Component , PropTypes } from 'react';
2 | import { css , pureRender } from '../enhance/index';
3 | import createEnhance from '../core/createEnhance';
4 | import Button from '../Button';
5 | @createEnhance(css)
6 | export default class TabNav extends Component{
7 | static displayName = "TabNav";
8 | static propTypes = {
9 | onTabClick: PropTypes.func
10 | };
11 | onTabClick=(key)=>{
12 | const { onTabClick ,disabled } = this.props;
13 |
14 | onTabClick && onTabClick(key);
15 | }
16 | getNavs=(children)=>{
17 | const { panels, activeKey } = this.props;
18 | const rst = [];
19 | React.Children.forEach(panels, (child,index)=> {
20 | const { key , props } = child;
21 | const { disabled , title } = props;
22 |
23 | let events = {} , conf = {} ;
24 | if(!disabled){
25 | events = {
26 | onClick: this.onTabClick.bind(this, key),
27 | };
28 | }
29 |
30 |
31 | if (activeKey == key) {
32 | conf = {
33 | ref:'activeTab',
34 | cls:'active'
35 | };
36 | }
37 |
38 | let cls = activeKey == key ? "active" : "";
39 | rst.push(
40 |
43 | {child.props.title}
44 |
45 | );
46 | });
47 |
48 | return rst;
49 | }
50 | render=()=>{
51 | const {
52 | className,
53 | children ,
54 | ...other
55 | } = this.props;
56 |
57 | let tabNavs = this.getNavs(children);
58 |
59 | return (
60 |
61 | { tabNavs }
62 |
63 | );
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/tabs/Tabs.js:
--------------------------------------------------------------------------------
1 | import React , { Component , PropTypes } from 'react';
2 | import { css } from '../enhance/index';
3 | import createEnhance from '../core/createEnhance';
4 | import TabNav from './TabNav';
5 |
6 | //获取默认的activeKey
7 | function getDefaultActiveKey(props){
8 | let activeKey;
9 |
10 | React.Children.forEach(props.children, (child) => {
11 | if (!activeKey && !child.props.disabled) {
12 | activeKey = child.key;
13 | }
14 | });
15 |
16 | return activeKey;
17 | }
18 |
19 | @createEnhance(css)
20 | export default class Tabs extends Component{
21 | constructor(props,context){
22 | super(props,context);
23 | let _activeKey ;
24 | let { activeKey , defaultActiveKey } = props;
25 | if(activeKey){
26 | _activeKey = activeKey
27 | }else if(defaultActiveKey){
28 | _activeKey = defaultActiveKey;
29 | }else{
30 | _activeKey = getDefaultActiveKey(props);
31 | }
32 |
33 | this.renderPanels = {};
34 | this.state ={
35 | activeKey:_activeKey
36 | };
37 | }
38 |
39 | componentWillReceiveProps=(nextProps)=>{
40 | let { activeKey:newActiveKey } = this.state;
41 | if ('activeKey' in nextProps) {
42 | newActiveKey = nextProps.activeKey;
43 | }
44 | let found;
45 | React.Children.forEach(nextProps.children, (child) => {
46 | if (child.key == newActiveKey) {
47 | found = true;
48 | }
49 | });
50 | if (found) {
51 | this.setActiveTab(newActiveKey);
52 | } else {
53 | this.setActiveTab(getDefaultActiveKey(nextProps));
54 | }
55 | }
56 | render=()=>{
57 | const {
58 | children
59 | } = this.props;
60 | const { activeKey } = this.state;
61 |
62 | let { tab } = this._getTabs(children);
63 |
64 | return (
65 |
66 |
71 |
72 |
73 |
74 | {tab}
75 |
76 |
77 |
78 | );
79 |
80 | }
81 | hanlderSwipedLeft=()=>{
82 | const { activeKey } = this.state ;
83 | const tabCount = React.Children.count(this.props.children);
84 | let newActiveKey = Number.parseInt(activeKey,10)+1;
85 | if(newActiveKey<=tabCount){
86 | this.setActiveTab(newActiveKey);
87 | }
88 |
89 | }
90 | hanlderSwipedRight=()=>{
91 | const { activeKey } = this.state ;
92 |
93 | let newActiveKey = Number.parseInt(activeKey,10)-1;
94 | if(newActiveKey>=1){
95 | this.setActiveTab(newActiveKey);
96 | }
97 | }
98 | onTabDestroy=()=>{
99 | this.renderPanels[key] = void 0;
100 | }
101 | onTabClick=(key)=>{
102 | const { onTabClick, onTabChange } = this.props;
103 | const { activeKey } = this.state;
104 | onTabClick && onTabClick(key);
105 | if (activeKey !== key) {
106 | this.setActiveTab(key,onTabChange);
107 | }
108 | }
109 | //设置活动的tab
110 | setActiveTab=(newActiveKey,cb)=>{
111 |
112 | this.setState({
113 | activeKey:newActiveKey
114 | },()=>{
115 | setTimeout(()=>{
116 | cb && cb();
117 | },0)
118 | });
119 | }
120 | _getTabs=(children)=>{
121 | const { props , state, renderPanels } = this;
122 | const { activeKey }= state;
123 | const tab = [] , tabNav = [];
124 | let active ;
125 |
126 | //遍历子节点
127 | React.Children.forEach(children, (child,index) => {
128 |
129 | const { key , props} = child;
130 | const { title } = props;
131 |
132 | active = ( activeKey == key );
133 |
134 |
135 | if (active || renderPanels[key]) {
136 | child = active ? child : renderPanels[key];
137 | renderPanels[key] = React.cloneElement(child, {
138 | active,
139 | onDestroy: this.onTabDestroy.bind(this, key),
140 | onSwipedLeft:this.hanlderSwipedLeft.bind(this,key),
141 | onSwipedRight:this.hanlderSwipedRight.bind(this,key)
142 | });
143 | tab.push(renderPanels[key]);
144 | } else {
145 | //懒加载
146 | tab.push(React.cloneElement(child, {
147 | active: false,
148 | onSwipedLeft:this.hanlderSwipedLeft.bind(this,key),
149 | onSwipedRight:this.hanlderSwipedRight.bind(this,key)
150 | }, [])
151 | );
152 | }
153 | });
154 | return {
155 | tab
156 | };
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/utils/shallowCompare.js:
--------------------------------------------------------------------------------
1 | var shallowEqual = require("./shallowEqual");
2 | export function shallowCompare(instance, nextProps, nextState) {
3 | return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState);
4 | }
5 |
--------------------------------------------------------------------------------
/src/utils/shallowEqual.js:
--------------------------------------------------------------------------------
1 | export default function shallowEqual(objA, objB) {
2 | debugger;
3 | if (objA === objB) {
4 | return true;
5 | }
6 |
7 | if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
8 | return false;
9 | }
10 |
11 | var keysA = Object.keys(objA);
12 | var keysB = Object.keys(objB);
13 |
14 | if (keysA.length !== keysB.length) {
15 | return false;
16 | }
17 |
18 | // Test for A's keys different from B.
19 | var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
20 | for (var i = 0; i < keysA.length; i++) {
21 | if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
22 | return false;
23 | }
24 | }
25 |
26 | return true;
27 | }
28 |
--------------------------------------------------------------------------------
/test/ButtonSpec.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactTestUtils from 'react-addons-test-utils';
3 | import ReactDOM from 'react-dom';
4 | import Button from '../src/Button';
5 | describe('Button',()=>{
6 | it('should output an a',()=>{
7 | let instance = ReactTestUtils.renderIntoDocument(
8 |
9 | 我是个按钮
10 |
11 | );
12 | assert.equal(ReactDOM.findDOMNode(instance).nodeName, 'A');
13 | });
14 | it('should output className button',()=>{
15 | let instance = ReactTestUtils.renderIntoDocument(
16 |
17 | 我是个按钮
18 |
19 | );
20 | assert.equal(ReactDOM.findDOMNode(instance).className, 'button');
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | import 'es5-shim';
2 |
3 | beforeEach(() => {
4 | sinon.stub(console, 'error');
5 | });
6 |
7 | afterEach(function checkNoUnexpectedWarnings() {
8 |
9 | if (typeof console.error.restore === 'function') {
10 | assert(!console.error.called, () => {
11 | return `${console.error.getCall(0).args[0]} \nIn '${this.currentTest.fullTitle()}'`;
12 | });
13 | console.error.restore();
14 | }
15 | });
16 |
17 | var context = require.context('.', true,/Spec$/);
18 | context.keys().forEach(context);
19 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by liubo on 15/3/11.
3 | */
4 | var fs = require('fs');
5 | var path = require('path');
6 | var webpack = require('webpack');
7 |
8 |
9 |
10 |
11 |
12 | module.exports = function(options) {
13 |
14 | var entry = {
15 | app:'./app/entry.js'
16 | ,common:[
17 | "react"
18 | ,"react-dom"
19 | ,"react-router"
20 | ]
21 | }
22 |
23 |
24 | // 凡是遇到jsx结尾的,都用jsx-loader这个插件来加载,
25 | // 且启用harmony模式
26 | var loaders = [
27 | {
28 | test: /\.js?$/
29 | ,exclude: /(node_modules|bower_components)/
30 | ,loader: 'babel'
31 | ,query: {
32 | optional: ['runtime'],
33 | stage: 0
34 | }
35 | }
36 | ,{ test: /\.css$/, loader: 'style-loader!css-loader' }
37 | ,{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }
38 | ,{ test: /\.(ttf|eot|svg)?$/, loader: "file-loader" }
39 | ,{ test: /\.png$/, loader: "file-loader" }
40 | ,{test: /\.woff$/, loader: "url?limit=10000&minetype=application/font-woff"}
41 | ]
42 |
43 |
44 |
45 | var publicPath = "http:// 10.129.10.45:8080/" ;
46 |
47 |
48 | var output = {
49 | path: path.join(__dirname, "./app/extras/", "build")
50 | ,publicPath: publicPath
51 | ,filename: '[name].js'
52 | ,sourceMapFilename: "[file].map"
53 | ,chunkFilename: "[id].js"
54 | ,hotUpdateMainFilename: "update.json"
55 | ,hotUpdateChunkFilename: "[id].update.js"
56 | };
57 |
58 |
59 |
60 | //deps.forEach(function (dep) {
61 | // var depPath = path.resolve(nodeRoot, dep);
62 | // alias[dep.split(path.sep)[0]] = depPath;
63 | // noParse.push(depPath);
64 | //});
65 |
66 | //console.log(alias);
67 |
68 | //加载插件
69 | var plugins = [
70 | new webpack.ProvidePlugin({
71 | React: "react"
72 | ,ReactDom: "react-dom"
73 | ,ReactRouter: "react-router"
74 |
75 | //,_: "lodash"
76 | })
77 |
78 | ,new webpack.DefinePlugin({
79 | __DEV__: JSON.stringify(JSON.parse(options.devServer || 'false'))
80 | })
81 | //,new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 20 })
82 | ,new webpack.optimize.CommonsChunkPlugin("common", "common.js" + (options.longTermCaching && !options.prerender ? "?[chunkhash]" : ""))
83 | ];
84 |
85 |
86 | var devServer = {
87 | contentBase: "./app"
88 | //,host: (options.hotComponents)? IPv4 :
89 | ,host:"10.129.10.45"
90 | ,port: "8080"
91 | ,inline: true
92 | ,hot: options.hotComponents
93 | ,colors: true
94 | }
95 |
96 | return {
97 | entry: entry
98 | ,output: output
99 | ,devtool: options.devtool
100 | ,resolve: {
101 | extensions: ['', '.js', '.jsx', '.css']
102 | }
103 | ,devServer: devServer
104 | ,plugins:plugins
105 | ,module: {
106 | loaders: loaders
107 | }
108 | ,debug: true
109 | };
110 | }
111 |
--------------------------------------------------------------------------------
/webpack.dev.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require("./webpack.config")({
2 | devServer: true,
3 | minimize: false,
4 | devtool: "eval",
5 | hotComponents: false,
6 | debug: true
7 | });
8 |
--------------------------------------------------------------------------------