├── .travis.yml
├── less
├── forms.less
├── msgs.less
├── icons.less
├── scharts.less
├── component-animations.less
├── utilities.less
├── grid.less
├── hero-unit.less
├── scaffolding.less
├── wells.less
├── breadcrumbs.less
├── close.less
├── accordion.less
├── layouts.less
├── checkbox.less
├── label.less
├── loading.less
├── tag.less
├── code.less
├── responsive-utilities.less
├── responsive.less
├── sui.less
├── tests
│ ├── forms-responsive.html
│ └── forms.html
├── icon-pc.less
├── modals.less
├── carousel.less
├── popovers.less
├── progress-bars.less
└── timepicker.less
├── fonts
├── icon-pc.eot
├── icon-pc.ttf
├── icon-pc.woff
├── icon-moon.eot
├── icon-moon.ttf
├── icon-moon.woff
├── icon-touch.eot
├── icon-touch.ttf
└── icon-touch.woff
├── docs
├── pictures
│ ├── logo.png
│ ├── docs
│ │ ├── btn.png
│ │ ├── forms.png
│ │ ├── input.png
│ │ ├── msgs.png
│ │ ├── steps.png
│ │ ├── tab.png
│ │ ├── table.png
│ │ ├── text.png
│ │ ├── loading.png
│ │ ├── popover.png
│ │ ├── popover.psb
│ │ ├── search.png
│ │ ├── tooltip.png
│ │ ├── breadcrumb.png
│ │ ├── checkbox.png
│ │ ├── datepicker.png
│ │ ├── dropdown.png
│ │ ├── pagination.png
│ │ ├── progress.png
│ │ └── timepicker.png
│ ├── example-form.png
│ ├── title-arrow.png
│ ├── bootstrap-logo.png
│ ├── example-table.png
│ ├── index-demo-browsers.png
│ └── index-demo-components.png
├── assets
│ ├── imgs
│ │ └── pagination1.png
│ ├── zeroclipboard
│ │ └── ZeroClipboard.swf
│ ├── js
│ │ ├── index.js
│ │ ├── google-code-prettify
│ │ │ └── prettify.css
│ │ ├── application.js
│ │ ├── html5shiv.js
│ │ └── README.md
│ ├── css
│ │ ├── my-animate.css
│ │ └── index.css
│ └── less
│ │ ├── my-animate.less
│ │ └── index.less
├── templates
│ ├── foot.jade
│ ├── ga.jade
│ ├── base_index.jade
│ ├── head.jade
│ ├── base.jade
│ ├── discuss.jade
│ ├── about.jade
│ ├── text.jade
│ ├── header.jade
│ ├── examples.jade
│ ├── download.jade
│ ├── progress.jade
│ ├── layout.jade
│ ├── global.jade
│ ├── label.jade
│ ├── button-groups.jade
│ ├── index.jade
│ ├── breadcrumb.jade
│ ├── loading.jade
│ ├── tag.jade
│ ├── dropdown-js.jade
│ ├── pagination.jade
│ ├── sidenav.jade
│ ├── grid.jade
│ ├── buttons.jade
│ ├── pagination-js.jade
│ ├── msgs.jade
│ ├── tab-js.jade
│ ├── tab.jade
│ ├── checkbox.jade
│ └── tree-js.jade
├── demos
│ ├── templates
│ │ └── icons.jade
│ └── icons.html
└── examples
│ └── todo-create.html
├── js
├── .jshintrc
├── tests
│ ├── unit
│ │ ├── transition.js
│ │ ├── affix.js
│ │ ├── scrollspy.js
│ │ ├── alert.js
│ │ ├── phantom.js
│ │ ├── tab.js
│ │ ├── collapse.js
│ │ └── button.js
│ └── index.html
├── sui.js
├── transition.js
├── alert.js
├── button.js
├── checkbox.js
├── popover.js
├── affix.js
├── tab.js
└── validate-rules.js
├── .gitignore
├── index.html
├── package.json
├── scripts
└── mod_his.sh
├── developer.md
├── README.md
├── gulpfile.js
├── CONTRIBUTING.md
└── Gruntfile.js
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 0.6
--------------------------------------------------------------------------------
/less/forms.less:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/less/forms.less
--------------------------------------------------------------------------------
/less/msgs.less:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/less/msgs.less
--------------------------------------------------------------------------------
/fonts/icon-pc.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-pc.eot
--------------------------------------------------------------------------------
/fonts/icon-pc.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-pc.ttf
--------------------------------------------------------------------------------
/fonts/icon-pc.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-pc.woff
--------------------------------------------------------------------------------
/fonts/icon-moon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-moon.eot
--------------------------------------------------------------------------------
/fonts/icon-moon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-moon.ttf
--------------------------------------------------------------------------------
/fonts/icon-moon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-moon.woff
--------------------------------------------------------------------------------
/fonts/icon-touch.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-touch.eot
--------------------------------------------------------------------------------
/fonts/icon-touch.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-touch.ttf
--------------------------------------------------------------------------------
/docs/pictures/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/logo.png
--------------------------------------------------------------------------------
/fonts/icon-touch.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/fonts/icon-touch.woff
--------------------------------------------------------------------------------
/docs/pictures/docs/btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/btn.png
--------------------------------------------------------------------------------
/docs/pictures/docs/forms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/forms.png
--------------------------------------------------------------------------------
/docs/pictures/docs/input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/input.png
--------------------------------------------------------------------------------
/docs/pictures/docs/msgs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/msgs.png
--------------------------------------------------------------------------------
/docs/pictures/docs/steps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/steps.png
--------------------------------------------------------------------------------
/docs/pictures/docs/tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/tab.png
--------------------------------------------------------------------------------
/docs/pictures/docs/table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/table.png
--------------------------------------------------------------------------------
/docs/pictures/docs/text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/text.png
--------------------------------------------------------------------------------
/less/icons.less:
--------------------------------------------------------------------------------
1 | @import 'icon-pc.less';
2 | @import 'icon-touch.less';
3 | @import 'icon-moon.less';
4 |
--------------------------------------------------------------------------------
/docs/pictures/docs/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/loading.png
--------------------------------------------------------------------------------
/docs/pictures/docs/popover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/popover.png
--------------------------------------------------------------------------------
/docs/pictures/docs/popover.psb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/popover.psb
--------------------------------------------------------------------------------
/docs/pictures/docs/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/search.png
--------------------------------------------------------------------------------
/docs/pictures/docs/tooltip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/tooltip.png
--------------------------------------------------------------------------------
/docs/pictures/example-form.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/example-form.png
--------------------------------------------------------------------------------
/docs/pictures/title-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/title-arrow.png
--------------------------------------------------------------------------------
/docs/assets/imgs/pagination1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/assets/imgs/pagination1.png
--------------------------------------------------------------------------------
/docs/pictures/bootstrap-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/bootstrap-logo.png
--------------------------------------------------------------------------------
/docs/pictures/docs/breadcrumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/breadcrumb.png
--------------------------------------------------------------------------------
/docs/pictures/docs/checkbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/checkbox.png
--------------------------------------------------------------------------------
/docs/pictures/docs/datepicker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/datepicker.png
--------------------------------------------------------------------------------
/docs/pictures/docs/dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/dropdown.png
--------------------------------------------------------------------------------
/docs/pictures/docs/pagination.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/pagination.png
--------------------------------------------------------------------------------
/docs/pictures/docs/progress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/progress.png
--------------------------------------------------------------------------------
/docs/pictures/docs/timepicker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/docs/timepicker.png
--------------------------------------------------------------------------------
/docs/pictures/example-table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/example-table.png
--------------------------------------------------------------------------------
/docs/pictures/index-demo-browsers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/index-demo-browsers.png
--------------------------------------------------------------------------------
/docs/pictures/index-demo-components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/pictures/index-demo-components.png
--------------------------------------------------------------------------------
/docs/assets/zeroclipboard/ZeroClipboard.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sdc-alibaba/wqui/HEAD/docs/assets/zeroclipboard/ZeroClipboard.swf
--------------------------------------------------------------------------------
/docs/templates/foot.jade:
--------------------------------------------------------------------------------
1 | script(src="assets/js/google-code-prettify/prettify.js")
2 | script(src='assets/zeroclipboard/ZeroClipboard.js')
3 | script(src="assets/js/application.js")
4 | script(src="http://localhost:3456/livereload.js")
5 |
--------------------------------------------------------------------------------
/js/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "validthis": true,
3 | "laxcomma" : true,
4 | "laxbreak" : true,
5 | "browser" : true,
6 | "eqnull" : true,
7 | "debug" : true,
8 | "devel" : true,
9 | "boss" : true,
10 | "expr" : true,
11 | "asi" : true
12 | }
13 |
--------------------------------------------------------------------------------
/less/scharts.less:
--------------------------------------------------------------------------------
1 | .chart-tooltip {
2 | position: absolute;
3 | z-index:10000000;
4 | color: #fff;
5 | padding: 6px;
6 | box-shadow: 2px 2px 0 0 rgba(0, 0, 0, 0.1);
7 | border-radius: 3px;
8 | h4 {
9 | margin: 0 0 6px 0;
10 | font-size: 16px;
11 | }
12 | p {
13 | margin: 0;
14 | }
15 | }
16 |
17 |
18 |
--------------------------------------------------------------------------------
/less/component-animations.less:
--------------------------------------------------------------------------------
1 | //
2 | // Component animations
3 | // --------------------------------------------------
4 |
5 |
6 | .fade {
7 | opacity: 0;
8 | .transition(opacity .15s linear);
9 | &.in {
10 | opacity: 1;
11 | }
12 | }
13 |
14 | .collapse {
15 | position: relative;
16 | height: 0;
17 | overflow: hidden;
18 | .transition(height .35s ease);
19 | &.in {
20 | height: auto;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/docs/templates/ga.jade:
--------------------------------------------------------------------------------
1 | script.
2 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
3 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
4 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
5 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
6 |
7 | ga('create', 'UA-50817062-1', 'taobao.org');
8 | ga('send', 'pageview');
9 |
--------------------------------------------------------------------------------
/js/tests/unit/transition.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 |
3 | module("transition")
4 |
5 | test("should be defined on jquery support object", function () {
6 | ok($.support.transition !== undefined, 'transition object is defined')
7 | })
8 |
9 | test("should provide an end object", function () {
10 | ok($.support.transition ? $.support.transition.end : true, 'end string is defined')
11 | })
12 |
13 | })
14 |
--------------------------------------------------------------------------------
/docs/templates/base_index.jade:
--------------------------------------------------------------------------------
1 | html(lang="en")
2 | head
3 | include head
4 |
5 | block head
6 |
7 | body
8 | include header
9 | block header
10 | +header('demos')
11 | mixin sidebar(highlight)
12 | include sidenav
13 | block content_wrap
14 | block footer
15 | .footer
16 | ul.unstyled
17 | li @time 2014.03.07
18 | li @author 商家业务事业部-电商服务支撑平台-UED团队
19 |
20 | include foot
21 | block js_block
22 |
--------------------------------------------------------------------------------
/less/utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // Quick floats
7 | .pull-right {
8 | float: right;
9 | }
10 | .pull-left {
11 | float: left;
12 | }
13 |
14 | // Toggling content
15 | .hide {
16 | display: none;
17 | }
18 | .show {
19 | display: block;
20 | }
21 |
22 | // Visibility
23 | .invisible {
24 | visibility: hidden;
25 | }
26 |
27 | // For Affix plugin
28 | .affix {
29 | position: fixed;
30 | }
31 |
--------------------------------------------------------------------------------
/js/sui.js:
--------------------------------------------------------------------------------
1 | //核心组件
2 | require('./transition')
3 | require('./alert')
4 | require('./button')
5 | require('./carousel')
6 | require('./collapse')
7 | require('./dropdown')
8 | require('./modal')
9 | require('./tooltip')
10 | require('./popover')
11 | require('./scrollspy')
12 | require('./tab')
13 | require('./affix')
14 | require('./pagination')
15 | require('./validate')
16 | require('./validate-rules')
17 | require('./tree')
18 | require('./datepicker')
19 | require('./timepicker')
20 | require('./checkbox')
21 |
--------------------------------------------------------------------------------
/less/grid.less:
--------------------------------------------------------------------------------
1 | //
2 | // Grid system
3 | // --------------------------------------------------
4 |
5 |
6 | // Fixed default
7 | #grid > .core(@gridColumnWidth, @gridGutterWidth);
8 |
9 | // Fluid default
10 | #grid > .fluid(@fluidGridColumnWidth, @fluidGridGutterWidth);
11 |
12 | // Reset utility classes due to specificity
13 | [class*="span"].hide,
14 | .sui-row-fluid [class*="span"].hide {
15 | display: none;
16 | }
17 |
18 | [class*="span"].pull-right,
19 | .sui-row-fluid [class*="span"].pull-right {
20 | float: right;
21 | }
22 |
--------------------------------------------------------------------------------
/docs/assets/js/index.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | 'use strict';
3 | var windowHeight = $(window).height()
4 |
5 | var onScroll = function() {
6 | $('.jumbotron').each(function() {
7 | var scrollTop = $(document).scrollTop()
8 | var $this = $(this)
9 | var offsetBottom = windowHeight - ($this.offset()['top'] - scrollTop)
10 | if(offsetBottom > Math.min(windowHeight / 2, 300)) {
11 | $this.addClass('inview')
12 | }
13 | })
14 | }
15 | $(document).scroll(onScroll)
16 | setTimeout(onScroll, 1000)
17 | })
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Numerous always-ignore extensions
2 | *.diff
3 | *.err
4 | *.orig
5 | *.log
6 | *.rej
7 | *.swo
8 | *.swp
9 | *.zip
10 | *.vi
11 | *~
12 | *.sass-cache
13 |
14 | # OS or Editor folders
15 | .DS_Store
16 | ._*
17 | Thumbs.db
18 | .cache
19 | .project
20 | .settings
21 | .tmproj
22 | *.esproj
23 | nbproject
24 | *.sublime-project
25 | *.sublime-workspace
26 |
27 | # Komodo
28 | *.komodoproject
29 | .komodotools
30 |
31 | # Folders to ignore
32 | .hg
33 | .svn
34 | .CVS
35 | .idea
36 | node_modules
37 | #bootstrap
38 | docs/assets/fonts
39 |
40 | pid.txt
41 |
42 | #build files
43 | build/
44 | docs/*.html
45 | .package/
46 |
--------------------------------------------------------------------------------
/less/hero-unit.less:
--------------------------------------------------------------------------------
1 | //
2 | // Hero unit
3 | // --------------------------------------------------
4 |
5 |
6 | .sui-hero-unit {
7 | padding: 60px;
8 | margin-bottom: 30px;
9 | font-size: 18px;
10 | font-weight: 200;
11 | line-height: @baseLineHeight * 1.5;
12 | color: @heroUnitLeadColor;
13 | background-color: @heroUnitBackground;
14 | .border-radius(6px);
15 | h1 {
16 | margin-bottom: 0;
17 | font-size: 60px;
18 | line-height: 1;
19 | color: @heroUnitHeadingColor;
20 | letter-spacing: -1px;
21 | }
22 | li {
23 | line-height: @baseLineHeight * 1.5; // Reset since we specify in type.less
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/docs/templates/head.jade:
--------------------------------------------------------------------------------
1 | meta(charset="utf-8")
2 | block title
3 | meta(http-equiv="X-UA-Compatible",content="IE=edge")
4 | meta(name="viewport",content="width=device-width, initial-scale=1")
5 | link(href="assets/css/animate.css",rel="stylesheet")
6 | link(href="../.package/css/sui.css",rel="stylesheet")
7 | link(href="assets/css/docs.css" rel="stylesheet")
8 | link(href="assets/js/google-code-prettify/prettify.css" rel="stylesheet")
9 | link(rel="shortcut icon" href="pictures/logo.png")
10 | script(src="../js/lib/jquery.js")
11 | script(src="../.package/js/sui.js")
12 | include ga
13 |
14 | //[if lt IE 9]>
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
16 |
17 |
18 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/less/breadcrumbs.less:
--------------------------------------------------------------------------------
1 | //
2 | // Breadcrumbs
3 | // --------------------------------------------------
4 |
5 | .sui-breadcrumb {
6 | padding: 0;
7 | margin: 0 0 @baseMargin;
8 | list-style: none;
9 | font-size: @baseFontSize;
10 | font-weight: normal;
11 | .border-radius(@borderRadiusSmall);
12 | > li {
13 | display: inline-block;
14 | .ie7-inline-block();
15 | // text-shadow: 0 1px 0 @white;
16 | + li:before {
17 | content: ">";
18 | padding: 0 5px;
19 | color: #ccc;
20 | }
21 | }
22 | > .active {
23 | color: @grayLight;
24 | }
25 | &.breadcrumb-large {
26 | font-size: @fontSizeLarge;
27 | }
28 |
29 | &.breadcrumb-bold {
30 | font-weight: bold;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/docs/templates/discuss.jade:
--------------------------------------------------------------------------------
1 | div#disqus_thread
2 |
3 | script(type="text/javascript").
4 | /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
5 | var disqus_shortname = 'sui-alibaba'; // required: replace example with your forum shortname
6 |
7 | /* * * DON'T EDIT BELOW THIS LINE * * */
8 | (function() {
9 | var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
10 | dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
11 | (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
12 | })();
13 | a(href="http://disqus.com" class="dsq-brlink") comments powered by
14 | span.logo-disqus Disqus
15 |
--------------------------------------------------------------------------------
/less/close.less:
--------------------------------------------------------------------------------
1 | //
2 | // Close icons
3 | // --------------------------------------------------
4 |
5 |
6 | .sui-close {
7 | float: right;
8 | font-size: 24px;
9 | line-height: @baseLineHeight;
10 | color: #666;
11 | text-shadow: 0 1px 0 rgba(255,255,255,1);
12 | outline: none;
13 | &:hover,
14 | &:focus {
15 | color: #ff5050;
16 | text-decoration: none;
17 | cursor: pointer;
18 | }
19 | &:focus {
20 | color: #dd5050;
21 | }
22 | }
23 |
24 | // Additional properties for button version
25 | // iOS requires the button element instead of an anchor tag.
26 | // If you want the anchor version, it requires `href="#"`.
27 | button.sui-close {
28 | padding: 0;
29 | cursor: pointer;
30 | background: transparent;
31 | border: 0;
32 | -webkit-appearance: none;
33 | }
34 |
--------------------------------------------------------------------------------
/less/accordion.less:
--------------------------------------------------------------------------------
1 | //
2 | // Accordion
3 | // --------------------------------------------------
4 |
5 |
6 | // Parent container
7 | .sui-accordion {
8 | margin-bottom: @baseLineHeight;
9 |
10 | // Group == heading + body
11 | .accordion-group {
12 | margin-bottom: 2px;
13 | border: 1px solid #e5e5e5;
14 | .border-radius(@baseBorderRadius);
15 | }
16 | .accordion-heading {
17 | border-bottom: 0;
18 | }
19 | .accordion-heading .accordion-toggle {
20 | display: block;
21 | padding: 8px 15px;
22 | }
23 |
24 | // General toggle styles
25 | .accordion-toggle {
26 | cursor: pointer;
27 | }
28 |
29 | // Inner needs the styles because you can't animate properly with any styles on the element
30 | .accordion-inner {
31 | padding: 9px 15px;
32 | border-top: 1px solid #e5e5e5;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/docs/assets/css/my-animate.css:
--------------------------------------------------------------------------------
1 | .animated {
2 | -webkit-animation-duration: 1s;
3 | animation-duration: 1s;
4 | -webkit-animation-fill-mode: both;
5 | animation-fill-mode: both;
6 | }
7 | @-webkit-keyframes myBounceInUp {
8 | 0% {
9 | opacity: 0;
10 | -webkit-transform: translateY(200px);
11 | transform: translateY(200px);
12 | }
13 | 100% {
14 | opacity: 1;
15 | -webkit-transform: translateY(0);
16 | transform: translateY(0);
17 | }
18 | }
19 | @keyframes myBounceInUp {
20 | 0% {
21 | opacity: 0;
22 | -webkit-transform: translateY(200px);
23 | transform: translateY(200px);
24 | }
25 | 100% {
26 | opacity: 1;
27 | -webkit-transform: translateY(0);
28 | transform: translateY(0);
29 | }
30 | }
31 | .myBounceInUp {
32 | -webkit-animation-name: myBounceInUp;
33 | animation-name: myBounceInUp;
34 | }
35 |
--------------------------------------------------------------------------------
/docs/assets/less/my-animate.less:
--------------------------------------------------------------------------------
1 | .animated {
2 | -webkit-animation-duration: 1s;
3 | animation-duration: 1s;
4 | -webkit-animation-fill-mode: both;
5 | animation-fill-mode: both;
6 | }
7 | @-webkit-keyframes myBounceInUp {
8 | 0% {
9 | opacity: 0;
10 | -webkit-transform: translateY(200px);
11 | transform: translateY(200px);
12 | }
13 |
14 | 100% {
15 | opacity: 1;
16 | -webkit-transform: translateY(0);
17 | transform: translateY(0);
18 | }
19 | }
20 |
21 | @keyframes myBounceInUp {
22 | 0% {
23 | opacity: 0;
24 | -webkit-transform: translateY(200px);
25 | transform: translateY(200px);
26 | }
27 |
28 | 100% {
29 | opacity: 1;
30 | -webkit-transform: translateY(0);
31 | transform: translateY(0);
32 | }
33 | }
34 |
35 | .myBounceInUp {
36 | -webkit-animation-name: myBounceInUp;
37 | animation-name: myBounceInUp;
38 | }
39 |
--------------------------------------------------------------------------------
/js/tests/unit/affix.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 |
3 | module("affix")
4 |
5 | test("should provide no conflict", function () {
6 | var affix = $.fn.affix.noConflict()
7 | ok(!$.fn.affix, 'affix was set back to undefined (org value)')
8 | $.fn.affix = affix
9 | })
10 |
11 | test("should be defined on jquery object", function () {
12 | ok($(document.body).affix, 'affix method is defined')
13 | })
14 |
15 | test("should return element", function () {
16 | ok($(document.body).affix()[0] == document.body, 'document.body returned')
17 | })
18 |
19 | test("should exit early if element is not visible", function () {
20 | var $affix = $('').affix()
21 | $affix.data('affix').checkPosition()
22 | ok(!$affix.hasClass('affix'), 'affix class was not added')
23 | })
24 |
25 | })
26 |
--------------------------------------------------------------------------------
/less/layouts.less:
--------------------------------------------------------------------------------
1 | //
2 | // Layouts
3 | // --------------------------------------------------
4 |
5 |
6 | // Container (centered, fixed-width layouts)
7 | .sui-container {
8 | .container-fixed();
9 | }
10 |
11 | // Fluid layouts (left aligned, with sidebar, min- & max-width content)
12 | .sui-container-fluid {
13 | padding-right: @gridGutterWidth;
14 | padding-left: @gridGutterWidth;
15 | .clearfix();
16 | }
17 |
18 | // 2 & 3 column layout
19 |
20 | .sui-layout > {
21 | position: relative;
22 | .sidebar {
23 | width: @layoutSidebarWidth;
24 | float: left;
25 | }
26 | .sidebar + .sidebar {
27 | float: right;
28 | }
29 | .content + .sidebar {
30 | position: absolute;
31 | right: 0;
32 | top: 0;
33 | }
34 | .content {
35 | margin-left: @layoutSidebarWidth;
36 | }
37 |
38 | &.layout3 {
39 | > .content {
40 | margin-right: @layoutSidebarWidth;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sui",
3 | "description": "sui.",
4 | "version": "1.0.0",
5 | "keywords": [
6 | "sui",
7 | "css"
8 | ],
9 | "homepage": "",
10 | "author": "",
11 | "scripts": {
12 | "test": "grunt test"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "http://gitlab.alibaba-inc.com/sj/dpl"
17 | },
18 | "licenses": [
19 | {
20 | "type": "Apache-2.0",
21 | "url": "http://www.apache.org/licenses/LICENSE-2.0"
22 | }
23 | ],
24 | "dependencies": {
25 | "grunt": "~0.4.4",
26 | "grunt-contrib-connect": "~0.7.1",
27 | "grunt-contrib-copy": "~0.5.0",
28 | "grunt-contrib-jade": "~0.11.0",
29 | "grunt-contrib-jshint": "~0.9.2",
30 | "grunt-contrib-watch": "~0.6.1",
31 | "grunt-browserify": "~2.0.1",
32 | "grunt-contrib-less": "~0.11.0",
33 | "grunt-contrib-uglify": "~0.4.0",
34 | "grunt-newer": "~0.7.0"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/assets/js/google-code-prettify/prettify.css:
--------------------------------------------------------------------------------
1 | .com { color: #93a1a1; }
2 | .lit { color: #195f91; }
3 | .pun, .opn, .clo { color: #93a1a1; }
4 | .fun { color: #dc322f; }
5 | .str, .atv { color: #D14; }
6 | .kwd, .prettyprint .tag { color: #1e347b; }
7 | .typ, .atn, .dec, .var { color: teal; }
8 | .pln { color: #48484c; }
9 |
10 | .prettyprint {
11 | padding: 8px;
12 | background-color: #f7f7f9;
13 | border: 1px solid #e1e1e8;
14 | }
15 | .prettyprint.linenums {
16 | -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
17 | -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
18 | box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
19 | }
20 |
21 | /* Specify class=linenums on a pre to get line numbering */
22 | ol.linenums {
23 | margin: 0 0 0 33px; /* IE indents via margin-left */
24 | }
25 | ol.linenums li {
26 | padding-left: 12px;
27 | color: #bebec5;
28 | line-height: 20px;
29 | text-shadow: 0 1px 0 #fff;
30 | }
--------------------------------------------------------------------------------
/docs/templates/about.jade:
--------------------------------------------------------------------------------
1 | extends base_index
2 |
3 | block title
4 | title 关于
5 |
6 | block header
7 | +header('about')
8 |
9 | block content_wrap
10 | .sui-container
11 | h1.sui-page-header 关于
12 |
13 | p.sui-lead
14 | | SUI 是商家后台系统的设计规范和前端组件库。
15 |
16 | h3 设计师
17 |
18 | p.sui-lead
19 | a(href='#') 致轩
20 | |,
21 | a(href='#') 裴芸
22 | |,
23 | a(href='#') 泉源
24 | | 以及
25 | strong 商家业务事业部设计师团队。
26 |
27 | h3 前端
28 |
29 | p.sui-lead
30 | a(href='#') 银鹏
31 | |,
32 | a(href='#') 半边
33 | |,
34 | a(href='#') 酥心
35 | |,
36 | a(href='#') 阿凯
37 | |,
38 | a(href='#') 墨焰
39 | |,
40 | a(href='#') 任行
41 | | 以及
42 | strong 商家业务事业部前端团队。
43 |
44 | h3 联系我们
45 | p.sui-lead
46 | |如果有任何问题和建议可以直接联系我们。
47 | |设计和交互请联系
48 | a(href='mailto:yun.peiy@alibaba-inc.com') 裴芸
49 | a(href='mailto:jingzhu.caijzh@taobao.com') 泉源
50 | |。
51 | br
52 | |技术以及其他任何问题都可以联系
53 | a(href='mailto:hongxun.lhx@alibaba-inc.com') 任行
54 | |。
55 |
--------------------------------------------------------------------------------
/scripts/mod_his.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | git filter-branch -f --env-filter '
4 |
5 | an="$GIT_AUTHOR_NAME"
6 | am="$GIT_AUTHOR_EMAIL"
7 | cn="$GIT_COMMITTER_NAME"
8 | cm="$GIT_COMMITTER_EMAIL"
9 |
10 | if [ "$GIT_COMMITTER_EMAIL" = "lihongxun945@163.com" ]
11 | then
12 | cn="hongxun.lhx"
13 | cm="hongxun.lhx@alibaba-inc.com"
14 | fi
15 | if [ "$GIT_AUTHOR_EMAIL" = "lihongxun945@163.com" ]
16 | then
17 | an="hongxun.lhx"
18 | am="hongxun.lhx@alibaba-inc.com"
19 | fi
20 |
21 | if [ "$GIT_COMMITTER_EMAIL" = "itaofe@gmail.com" ]
22 | then
23 | cn="半边"
24 | cm="zangtao.zt@alibaba-inc.com"
25 | fi
26 | if [ "$GIT_AUTHOR_EMAIL" = "itaofe@gmail.com" ]
27 | then
28 | an="半边"
29 | am="zangtao.zt@alibaba-inc.com"
30 | fi
31 | if [ "$GIT_COMMITTER_EMAIL" = "yiye.js@gmail.com" ]
32 | then
33 | cn="何道"
34 | cm="shuangling.ysl@alibaba-inc.com"
35 | fi
36 | if [ "$GIT_AUTHOR_EMAIL" = "yiye.js@gmail.com" ]
37 | then
38 | an="何道"
39 | am="shuangling.ysl@alibaba-inc.com"
40 | fi
41 |
42 | export GIT_AUTHOR_NAME="$an"
43 | export GIT_AUTHOR_EMAIL="$am"
44 | export GIT_COMMITTER_NAME="$cn"
45 | export GIT_COMMITTER_EMAIL="$cm"
46 | '
47 |
--------------------------------------------------------------------------------
/docs/demos/templates/icons.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 图标
5 |
6 | block content
7 | div.container
8 | - var ROLES = [{ roles: ["arrow-down", "arrow-left", "arrow-right", "arrow-up", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "circle-arrow-down", "circle-arrow-left", "circle-arrow-right", "circle-arrow-up"], name: "方向图标" }]
9 | - ROLES.push({ roles: ["ban-circle", "bell", "exclamation-sign", "ok", "ok-circle", "ok-sign", "remove", "remove-circle", "remove-sign", "warning-sign"], name: "提示反馈"})
10 | - ROLES.push({ roles: ["calendar", "pencil", "search"], name: "表单"})
11 | - ROLES.push({ roles: ["backward"," forward"," fast-backward","fast-forward","play","play-circle","step-backward","step-forward","stop"], name: "多媒体"})
12 | - ROLES.push({ roles: ["book","bookmark","comment","download","file","flag","fullscreen","lock","move","plus","plus-sign","star","star-empty","user","zoom-in","zoom-out", "cog"], name: "其他"})
13 | each v in ROLES
14 | h2 #{v.name}
15 | each r in v.roles
16 | - var classname = 'glyphicon glyphicon-'
17 | - classname += r
18 | i(class='#{classname}')
19 | |
20 |
--------------------------------------------------------------------------------
/less/checkbox.less:
--------------------------------------------------------------------------------
1 | .checkbox-pretty,
2 | .radio-pretty
3 | {
4 | display: block;
5 | input {
6 | //这里不能用display:none,或者visibility:hidden;否则在ie下input会直接被忽略
7 | opacity: 0;
8 | position: absolute;
9 | left: -9999px;
10 | }
11 | span {
12 | .sui-icon;
13 | font-family: 'icon-pc';
14 | }
15 | span:before {
16 | content: "\e605";
17 | margin-right: 2px;
18 | vertical-align: middle;
19 | font-size: 150%;
20 | color: @checkboxColor;
21 | margin-left: -3px;
22 | }
23 |
24 |
25 | &.checked > span:before {
26 | content: "\e607";
27 | color: @checkboxCheckedColor;
28 | }
29 | &.halfchecked > span:before {
30 | content: "\e606";
31 | color: @checkboxCheckedColor;
32 | }
33 | &:hover {
34 | span:before {
35 | color: @checkboxHighlightColor;
36 | }
37 | }
38 | &.inline {
39 | display: inline;
40 | }
41 | &.inline + &.inline {
42 | margin-left: 6px;
43 | }
44 |
45 | &.disabled {
46 | color: lighten(@checkboxDisableColor, 10%);
47 | span:before {
48 | color: @checkboxDisableColor;
49 | }
50 | }
51 | }
52 |
53 | .radio-pretty {
54 | span:before {
55 | content: "\e603";
56 | }
57 | &.checked > span:before {
58 | content: "\e604";
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/docs/templates/text.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 文本
5 |
6 | block sidebar
7 | +sidebar('text')
8 |
9 | block content
10 | div.sui-page-header
11 | h1 文本
12 | p.sui-lead
13 | | 不同功能和颜色的文本
14 |
15 | h2 不同类型
16 | ul.sui-nav.nav-tabs.nav-large
17 | li.active
18 | a(href='#demo1', data-toggle='tab') 示例
19 | li
20 | a(href='#code1', data-toggle='tab') 代码
21 |
22 | style.
23 | .bs-docs-example ul {
24 | margin-bottom: 20px;
25 | }
26 | .bs-docs-example li {
27 | display: inline-block;
28 | margin: 0 10px 10px 0;
29 | }
30 | div.tab-content
31 | div.tab-pane.active#demo1
32 | div.bs-docs-example
33 | - var cls = ['nav', 'description', 'less-important', 'disabled', 'help', 'success', 'warning', 'error']
34 | - var txt = ['导航文本', '辅助说明', '次级文本', '禁用文本', '说明提示', '强调', '警告', '错误', '公告']
35 | ul
36 | li
37 | span 默认文本
38 | each clsi, i in cls
39 | li
40 | span(class='sui-text-#{clsi}') #{txt[i]}
41 | div.tab-pane#code1
42 | pre.prettyprint.linenums(data-target='#demo1>div')
43 | ul.demo-operations.clearfix
44 | li
45 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
46 |
--------------------------------------------------------------------------------
/less/label.less:
--------------------------------------------------------------------------------
1 | //
2 | // Labels and badges
3 | // --------------------------------------------------
4 |
5 |
6 | // Base classes
7 | .sui-label {
8 | display: inline-block;
9 | padding: 2px 10px;
10 | font-size: @baseFontSize * .846;
11 | line-height: @fontSizeLarge; // ensure proper line-height if floated
12 | color: @white;
13 | vertical-align: baseline;
14 | white-space: nowrap;
15 | text-shadow: 0 -1px 0 rgba(0,0,0,.25);
16 | background-color: @grayLight;
17 | .border-radius(1px);
18 | cursor: default;
19 | }
20 |
21 | // Empty labels/badges collapse
22 | .sui-label:empty {
23 | display: none;
24 | }
25 |
26 |
27 | // Colors
28 | .sui-label {
29 | // danger (red)
30 | &.label-danger { background-color: @errorText; }
31 | // Warnings (orange)
32 | &.label-warning { background-color: @orange; }
33 | // Success (green)
34 | &.label-success { background-color: @successText; }
35 | // Info (turquoise)
36 | &.label-info { background-color: @infoText; }
37 | // Inverse (black)
38 | &.label-inverse { background-color: @grayDark; }
39 | }
40 |
41 | // Quick fix for labels in buttons
42 | .sui-btn {
43 | .sui-label {
44 | position: relative;
45 | top: -1px;
46 | }
47 | }
48 | .btn-mini {
49 | .sui-label {
50 | top: 0;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/docs/templates/header.jade:
--------------------------------------------------------------------------------
1 | mixin header(highlight)
2 | - var classIndex = ''
3 | - var classDemos = ''
4 | - var classExamples = ''
5 | - var classTutorial = ''
6 | - var classDownload = ''
7 | - var classAbout = ''
8 |
9 | if highlight == 'demos'
10 | - classDemos = 'active'
11 | else if highlight == 'examples'
12 | - classExamples = 'active'
13 | else if highlight == 'tutorial'
14 | - classTutorial = 'active'
15 | else if highlight == 'download'
16 | - classDownload = 'active'
17 | else if highlight == 'about'
18 | - classAbout = 'active'
19 | else
20 | - classIndex = 'active'
21 | div.sui-navbar.navbar-inverse.navbar-fixed-top
22 | div.navbar-inner
23 | .sui-container
24 | a.sui-brand(href="./index.html")
25 | i.sui-icon.icon-github-alt
26 | | WQUI
27 | ul.sui-nav
28 | li(class=classIndex)
29 | a(href="./index.html") 首页
30 | li(class=classDemos)
31 | a(href="./global.html") 组件库
32 | li(class=classExamples)
33 | a(href="./examples.html") 案例
34 | li(class=classTutorial)
35 | a(href="./tutorial.html") 教程
36 | li(class=classDownload)
37 | a(href="./download.html") 下载
38 | li(class=classAbout)
39 | a(href="./about.html") 关于
40 |
--------------------------------------------------------------------------------
/docs/templates/examples.jade:
--------------------------------------------------------------------------------
1 | extends base_index
2 |
3 | block title
4 | title 案例
5 |
6 | block head
7 | style(type='text/css').
8 | .jumbotron {
9 | background-color: #6f5499;
10 | color: #fff;
11 | padding: 40px 0;
12 | }
13 |
14 | .sui-row {
15 | margin-top: 20px;
16 | border-radius: 6px;
17 | background: #DEE8F3;
18 | }
19 |
20 | .sui-row [class^='span'] {
21 | padding: 20px;
22 | box-sizing: border-box;
23 | }
24 |
25 | block header
26 | +header('examples')
27 |
28 | block content_wrap
29 | .jumbotron
30 | .sui-container
31 | h1 经典案例
32 | p.sui-lead
33 | | 使用SUI可以轻松搭建一个漂亮的页面,她有丰富的组件库可以像搭积木一样轻松搭建一个页面。
34 | p.sui-lead
35 | | 你现在正在浏览的官网就是用SUI组件搭建的,想要更多的案例,看看下面这些精美的页面吧。
36 |
37 |
38 | .sui-container
39 | .sui-row
40 | .span8
41 | a.picture(href='examples/serving-custom.html', target='_blank')
42 | img(src='pictures/example-form.png')
43 | .span4
44 | h2 订购服务
45 | p.lead
46 | 经典的表单应用页面。包括输入框,按钮,图片,提示等。
47 | .sui-row
48 | .span4
49 | h2 我的采购单
50 | p.lead
51 | 典型的搜索页面,由一个多条件的搜索框和一个由复杂table组成的搜索结果。
52 | .span8
53 | a.picture(href='examples/my-purchase.html', target="_blank")
54 | img(src='pictures/example-table.png')
55 |
56 |
--------------------------------------------------------------------------------
/docs/templates/download.jade:
--------------------------------------------------------------------------------
1 | extends base_index
2 |
3 | block title
4 | title 下载
5 |
6 | block head
7 | style(type='text/css').
8 | .btn-huge {
9 | padding: 15px 40px;
10 | font-size: 20px;
11 | }
12 | block header
13 | +header('download')
14 |
15 | block content_wrap
16 | .sui-container
17 | h1.sui-page-header 下载 WQUI
18 |
19 | h2 直接引用CDN文件
20 | p
21 | | 最简单使用方式是直接引用我们的CDN,不需要下载任何文件:
22 | ul.unstyled
23 | li
24 | a(href='http://g.tbcdn.cn/sj/wqui/1.0.0/css/sui.min.css', target='_blank') g.tbcdn.cn/sj/wqui/1.0.0/css/sui.min.css
25 | li
26 | a(href='http://g.tbcdn.cn/sj/wqui/1.0.0/js/sui.min.js', target='_blank') g.tbcdn.cn/sj/wqui/1.0.0/js/sui.min.js
27 |
28 | p
29 | | 注意在引用sui.min.js之前必须先引用 jquery。
30 |
31 | h2 下载zip文件
32 |
33 | p.sui-lead
34 | | 包括所有的源代码和文档。
35 |
36 | p
37 | a.sui-btn.btn-primary.btn-xlarge.btn-huge(href='https://github.com/sdc-alibaba/wqui/archive/build.zip', target="_blank")
38 | i.sui-icon.icon-download
39 | | download WQUI-1.0.source.zip
40 |
41 | h2 获取最新源码
42 |
43 | p.sui-lead
44 | |可以从 github 上直接获取最新的代码,项目地址:
45 | a.sui-btn.btn-success.btn-huge(href='https://github.com/sdc-alibaba/wqui', target="_blank")
46 | i.sui-icon.icon-github-alt
47 | | view WQUI on github
48 |
--------------------------------------------------------------------------------
/docs/templates/progress.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 进度条
5 |
6 | block head
7 | style(type='text/css').
8 | .sui-progress {
9 | max-width: 400px;
10 | }
11 |
12 | block sidebar
13 | +sidebar('progress')
14 |
15 | block content
16 |
17 | h1 进度条
18 |
19 | h2.sui-page-header 设计规范
20 |
21 | div.docs-description
22 | img(src='pictures/docs/progress.png')
23 |
24 | ul.demo-operations.clearfix
25 | li
26 | a(href='#') 下载psd文件
27 |
28 | h2.sui-page-header 开发者文档
29 | p.sui-lead
30 | | 不同功能和样式的进度条。
31 |
32 | ul.sui-nav.nav-tabs.nav-large
33 | li.active
34 | a(href='#demo1', data-toggle='tab') 示例
35 | li
36 | a(href='#code1', data-toggle='tab') 代码
37 | div.tab-content
38 | div.tab-pane.active#demo1
39 | div.bs-docs-example
40 | div.sui-progress
41 | div.bar(style="width: 20%;")
42 | .bar-text 20%
43 |
44 | div.sui-progress.progress-small
45 | div.bar(style="width: 30%;")
46 | .bar-text 30%
47 |
48 | div.sui-progress.progress-small
49 | div.bar(style="width: 40%;")
50 |
51 | div.tab-pane#code12
52 | pre.prettyprint.linenums(data-target='#demo12>div')
53 |
54 | ul.demo-operations.clearfix
55 | li
56 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
57 |
--------------------------------------------------------------------------------
/js/tests/unit/scrollspy.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 |
3 | module("scrollspy")
4 |
5 | test("should provide no conflict", function () {
6 | var scrollspy = $.fn.scrollspy.noConflict()
7 | ok(!$.fn.scrollspy, 'scrollspy was set back to undefined (org value)')
8 | $.fn.scrollspy = scrollspy
9 | })
10 |
11 | test("should be defined on jquery object", function () {
12 | ok($(document.body).scrollspy, 'scrollspy method is defined')
13 | })
14 |
15 | test("should return element", function () {
16 | ok($(document.body).scrollspy()[0] == document.body, 'document.body returned')
17 | })
18 |
19 | test("should switch active class on scroll", function () {
20 | var sectionHTML = ''
21 | , $section = $(sectionHTML).append('#qunit-fixture')
22 | , topbarHTML =''
23 | + '
'
24 | + '
'
25 | + '
'
26 | + '
'
29 | + '
'
30 | + '
'
31 | + '
'
32 | , $topbar = $(topbarHTML).scrollspy()
33 |
34 | ok($topbar.find('.active', true))
35 | })
36 |
37 | })
38 |
--------------------------------------------------------------------------------
/docs/templates/layout.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 左右定宽三栏布局
5 |
6 | block head
7 | style(type='text/css').
8 | .bs-docs-example .sui-layout div { background-color: #f5faff; min-height: 100px; }
9 | .bs-docs-example .sui-layout .sidebar { background: #3096de; }
10 |
11 | block sidebar
12 | +sidebar('layout')
13 |
14 | block content
15 | h1 左右定宽三栏布局
16 |
17 | h2.sui-page-header 开发者文档
18 |
19 | p.sui-lead
20 | | 不同与栅格系统的响应式布局,layout 是一个简单的两边固定宽度中间自适应的布局。
21 |
22 | ul.sui-nav.nav-tabs.nav-large
23 | li.active
24 | a(href='#demo1', data-toggle='tab') 示例
25 | li
26 | a(href='#code1', data-toggle='tab') 代码
27 | li
28 | a(href='#doc1', data-toggle='tab') 文档
29 | div.tab-content
30 | div.tab-pane.active#demo1
31 | div.bs-docs-example
32 | h2 2 col layout
33 | div.sui-layout
34 | div.sidebar sidebar
35 | div.content content
36 | h2 3 col layout
37 | div.sui-layout.layout3
38 | div.sidebar sidebar
39 | div.content content
40 | div.sidebar sidebar
41 | div.tab-pane#code1
42 | pre.prettyprint.linenums(data-target='#demo1>div')
43 | div.tab-pane#doc1
44 | |左右宽度固定中间自适应的布局,默认宽度会铺满整个屏幕。非常适合用在有侧边栏的全屏页面布局。默认的两边宽度是150px,可以根据需要自己重载。
45 | ul.demo-operations.clearfix
46 | li
47 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
48 |
--------------------------------------------------------------------------------
/less/loading.less:
--------------------------------------------------------------------------------
1 | .icon-pc-loading {
2 | .sui-loading.loading-large & {
3 | font-size: 60px;
4 | }
5 | .sui-loading.loading-xlarge & {
6 | font-size: 80px;
7 | }
8 | .sui-loading.loading-xxlarge & {
9 | font-size: 100px;
10 | }
11 | .sui-loading.loading-small & {
12 | font-size: 40px;
13 | }
14 | .sui-loading.loading-xsmall & {
15 | font-size: 30px;
16 | }
17 | .sui-loading.loading-xxsmall & {
18 | font-size: 20px;
19 | }
20 | .sui-loading.loading-dark & {
21 | color: @black;
22 | opacity: 0.9;
23 | }
24 | .sui-loading.loading-light & {
25 | color: @gray;
26 | opacity: 0.2;
27 | }
28 | }
29 |
30 | .sui-loading {
31 | text-align: center;
32 | display: block;
33 | &.loading-inline {
34 | display: inline-block;
35 | }
36 | .icon-pc-loading {
37 | -webkit-animation: rotation 2s infinite linear;
38 | -moz-animation: rotation 2s infinite linear;
39 | animation: rotation 2s infinite linear;
40 | display: inline-block;
41 | font-size: 50px;
42 | color: @btnPrimaryBackground;
43 | }
44 |
45 | @-webkit-keyframes rotation {
46 | from {-webkit-transform: rotate(0deg);}
47 | to {-webkit-transform: rotate(359deg);}
48 | }
49 | @-moz-keyframes rotation {
50 | from {-moz-transform: rotate(0deg);}
51 | to {-moz-transform: rotate(359deg);}
52 | }
53 | @keyframes rotation {
54 | from {transform: rotate(0deg);}
55 | to {transform: rotate(359deg);}
56 | }
57 | }
58 |
59 |
60 |
--------------------------------------------------------------------------------
/docs/assets/less/index.less:
--------------------------------------------------------------------------------
1 | @import 'my-animate.less';
2 |
3 | .intro {
4 | background-color: #6f5499;
5 | color: #fff;
6 | padding: 80px 0;
7 | }
8 |
9 | .jumbotron {
10 | padding: 60px 0;
11 | color: #fff;
12 | }
13 | .beautify(@bg) {
14 | background-color: lighten(@bg, 20%);
15 | -webkit-transition: background .5s, background ease-in-out .5s;
16 | transition: background .5s, background .5s;
17 | -webkit-transition: color 1s .5s, color ease-in-out 1s .5s;
18 | transition: color 1s .5s, color 1s .5s;
19 | img {
20 | opacity: 0;
21 | }
22 | color: #555;
23 | &.inview {
24 | background-color: @bg;
25 | color: #fff;
26 |
27 | img {
28 | .myBounceInUp;
29 | .animated;
30 | }
31 | }
32 | }
33 | .components {
34 | .beautify(#45b7ed);
35 | }
36 | .features {
37 | .beautify(#ac8);
38 | }
39 | .bootstrap {
40 | .beautify(#0b9);
41 | }
42 | .intro> .sui-container {
43 | text-align: center;
44 | }
45 |
46 | h1 {
47 | font-size: 64px;
48 | line-height: 1.5;
49 | }
50 | h2 {
51 | font-size: 48px;
52 | line-height: 1.5;
53 | }
54 | .center {
55 | text-align: center;
56 | }
57 | .brand-intro .sui-lead {
58 | font-size: 24px;
59 | line-height: 2;
60 | }
61 |
62 | .btn-lead {
63 | padding: 20px 80px;
64 | font-size: 24px;
65 | }
66 |
67 | .btn-wrap {
68 | margin-top: 50px;
69 | }
70 |
71 | .details ul {
72 | margin-top: 50px;
73 | }
74 |
75 | .details li {
76 | font-size: 18px;
77 | line-height: 2;
78 | }
79 |
80 | .bootstrap-logo {
81 | height: 300px;
82 | }
83 |
--------------------------------------------------------------------------------
/docs/templates/global.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 全局样式
5 |
6 | block sidebar
7 | +sidebar('global')
8 |
9 | block content
10 | - var SIZES = ['xlarge', 'large', '', 'small']
11 | - var ROLES = ["", "primary", "success", "info", "warning", "danger", "inverse"]
12 |
13 | h1 全局样式
14 |
15 | h2.sui-page-header 设计规范
16 |
17 | div.docs-description
18 | img(src='pictures/docs/text.png')
19 |
20 | ul.demo-operations.clearfix
21 | li
22 | a(href='#') 下载psd文件
23 |
24 | h2.sui-page-header 开发者文档
25 |
26 | h2 1. 基础字体和颜色
27 | ul.sui-nav.nav-tabs.nav-large
28 | li.active
29 | a(href='#demo1', data-toggle='tab') 示例
30 | li
31 | a(href='#code1', data-toggle='tab') 代码
32 | li
33 | a(href='#doc1', data-toggle='tab') 文档
34 |
35 | div.tab-content
36 | div.tab-pane.active#demo1
37 | div.bs-docs-example
38 | p
39 | | 段落
40 | | 基础字体:12px, #333, 微软雅黑
41 | | 基础行高: 18px
42 |
43 | h1 粗体标题一
44 | h2 粗体标题二
45 | h3 粗体标题三
46 | h4 粗体标题四
47 | h5 粗体标题五
48 |
49 | h1.sui-normal 标题一
50 | h2.sui-normal 标题二
51 | h3.sui-normal 标题三
52 | h4.sui-normal 标题四
53 | h5.sui-normal 标题五
54 |
55 | p
56 | a(href='#') 链接颜色
57 | div.tab-pane#code1
58 | pre.prettyprint.linenums(data-target='#demo1>div')
59 | div.tab-pane#doc1
60 |
61 | ul.demo-operations.clearfix
62 | li
63 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
64 |
--------------------------------------------------------------------------------
/docs/templates/label.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title Label
5 |
6 | block sidebar
7 | +sidebar('Label')
8 |
9 | block content
10 |
11 | h1 Label
12 |
13 | h2.sui-page-header 开发者文档
14 |
15 | ul.sui-nav.nav-tabs.nav-large
16 | li.active
17 | a(href='#demo1', data-toggle='tab') 示例
18 | li
19 | a(href='#code1', data-toggle='tab') 代码
20 | li
21 | a(href='#doc1', data-toggle='tab') 文档
22 |
23 | div.tab-content
24 | div.tab-pane.active#demo1
25 | style.
26 | .bs-docs-example ul {
27 | margin-bottom: 20px;
28 | }
29 | .bs-docs-example li {
30 | display: inline-block;
31 | margin: 0 10px 10px 0;
32 | }
33 | div.bs-docs-example
34 | - var cls = ['', 'success', 'warning', 'danger', 'info']
35 | - var txt = ['默认', '上升', '持平', '下降', '公告']
36 | ul
37 | each clsi, i in cls
38 | li
39 | span.sui-label(class='label-#{clsi}') #{txt[i]}
40 | ul
41 | li
42 | span 默认文本
43 | each clsi, i in cls
44 | li
45 | span(class='sui-text-#{clsi}') #{txt[i]}
46 |
47 | div.tab-pane#code1
48 | pre.prettyprint.linenums(data-target='#demo1>div')
49 | div.tab-pane#doc1
50 | p 删掉原bootstrap里的badget,商家业务场合用的不多,且可以很方便的由label扩展去。
51 | p sui-label类名确定一个元素以label样式显示,再加之label-***可以区分不同状态的标识label
52 | ul.demo-operations.clearfix
53 | li
54 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
55 |
56 |
--------------------------------------------------------------------------------
/less/tag.less:
--------------------------------------------------------------------------------
1 | .sui-tag {
2 | list-style: none;
3 | font-size: 0;
4 | line-height: 0;
5 | padding: 5px 5px 0 5px;
6 | &>li, &>a {
7 | font-size: @baseFontSize;
8 | margin: 0 5px 5px 0;
9 | display: inline-block;
10 | overflow: hidden;
11 | color: @black;
12 | background: @btnBackgroundHighlight;
13 | padding: 0 7px;
14 | height: 20px;
15 | line-height: 20px;
16 | border: 1px solid #d1d1d1;
17 | white-space: nowrap;
18 | cursor: pointer;
19 | &:hover {
20 | color: @stepsCurrentColor;
21 | }
22 | &.tag-selected {
23 | color: @white;
24 | background: @stepsCurrentColor;
25 | border-color: #1c91d3;
26 | }
27 | .transition(color 0.2s ease-out);
28 | &.with-x {
29 | cursor: default;
30 | i {
31 | margin-left: 10px;
32 | cursor: pointer;
33 | font: normal 14px tahoma;
34 | display: inline-block;
35 | height: 100%;
36 | vertical-align: middle;
37 | }
38 | }
39 |
40 | }
41 | /*
42 | &.tag-hole {
43 | &>li, &>span {
44 | padding: 0 10px 0 15px;
45 | height: 28px;
46 | line-height: 28px;
47 | position: relative;
48 | &:before {
49 | content: '';
50 | position: absolute;
51 | width: 12px;
52 | height: 12px;
53 | left: -7px;
54 | top: 50%;
55 | margin-top: -7px;
56 | background: @white;
57 | border: 1px solid #d1d1d1;
58 | //border-width: 1px 1px 0 0;
59 | .border-radius(6px);
60 | }
61 | }
62 | }
63 | */
64 | }
65 |
--------------------------------------------------------------------------------
/less/code.less:
--------------------------------------------------------------------------------
1 | //
2 | // Code (inline and blocK)
3 | // --------------------------------------------------
4 |
5 |
6 | // Inline and block code styles
7 | code,
8 | .sui-code,
9 | pre,
10 | .sui-pre
11 | {
12 | padding: 0 3px 2px;
13 | #font > #family > .monospace;
14 | font-size: @baseFontSize - 2;
15 | color: @grayDark;
16 | .border-radius(3px);
17 | }
18 |
19 | // Inline code
20 | code,
21 | .sui-code
22 | {
23 | padding: 2px 4px;
24 | color: #d14;
25 | background-color: #f7f7f9;
26 | white-space: nowrap;
27 | }
28 |
29 | // Blocks of code
30 | pre,
31 | sui-pre
32 | {
33 | display: block;
34 | padding: (@baseLineHeight - 1) / 2;
35 | margin: 0 0 @baseLineHeight / 2;
36 | font-size: @baseFontSize - 1; // 14px to 13px
37 | line-height: @baseLineHeight;
38 | word-break: break-all;
39 | word-wrap: break-word;
40 | white-space: pre;
41 | white-space: pre-wrap;
42 | background-color: #f5f5f5;
43 | border: 1px solid #ccc; // fallback for IE7-8
44 | border: 1px solid rgba(0,0,0,.15);
45 | .border-radius(@baseBorderRadius);
46 |
47 | // Make prettyprint styles more spaced out for readability
48 | &.prettyprint {
49 | margin-bottom: @baseLineHeight;
50 | }
51 |
52 | // Account for some code outputs that place code tags in pre tags
53 | code, .sui-code {
54 | padding: 0;
55 | color: inherit;
56 | white-space: pre;
57 | white-space: pre-wrap;
58 | background-color: transparent;
59 | border: 0;
60 | }
61 | }
62 |
63 | // Enable scrollable blocks of code
64 | .pre-scrollable {
65 | max-height: 340px;
66 | overflow-y: scroll;
67 | }
68 |
--------------------------------------------------------------------------------
/docs/assets/js/application.js:
--------------------------------------------------------------------------------
1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
2 | // IT'S ALL JUST JUNK FOR OUR DOCS!
3 | // ++++++++++++++++++++++++++++++++++++++++++
4 |
5 | (function($) {
6 | "use strict";
7 | var parseCode = function(code) {
8 | //格式化代码,删除多余缩进空格,删除多余空行
9 | if(!code) return;
10 | code = code.replace(/^ *\n/g, '').replace(/\s+$/g, '')
11 | var indentNum = (/^\s+/.exec(code) || ["", ""])[0] .length
12 | return code.replace(new RegExp(' {'+indentNum+'}', 'g'), '')
13 | }
14 | // 侧边栏
15 | var $sidenav = $(".docs-sidenav").on("click", '> li', function(e) {
16 | var $li = $(e.currentTarget)
17 | if($li.hasClass(".active")) {
18 | return
19 | }
20 | $sidenav.find(".active").removeClass("active")
21 | $li.addClass("active")
22 | })
23 |
24 | //代码高亮
25 | $('.prettyprint').each(function() {
26 | var $this = $(this)
27 | var $target = $($this.data("target"))
28 | if(!$target[0]) return;
29 | $this.text(parseCode($target.html()))
30 | })
31 | $(function() {
32 | // make code pretty
33 | window.prettyPrint && prettyPrint()
34 | })
35 |
36 | //复制代码
37 | $(".copy-btn").each(function() {
38 | var $btn = $(this)
39 | var $target = $($btn.data("target"))
40 | var $li = $btn.parents("li")
41 | var $msg = $li.find(".sui-msg")
42 | if (!$msg[0]) {
43 | $msg = $('').appendTo($li)
44 | }
45 | $btn.attr('data-clipboard-text', parseCode($target.html()))
46 | var cp = new ZeroClipboard(this, {
47 | moviePath: "assets/zeroclipboard/ZeroClipboard.swf"
48 | })
49 | cp.on('load', function(cp) {
50 | cp.on( "complete", function(cp, args) {
51 | $msg.show().delay(2000).fadeOut()
52 | })
53 | })
54 | })
55 | })(window.jQuery)
56 |
--------------------------------------------------------------------------------
/less/responsive-utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Responsive: Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // IE10 Metro responsive
7 | // Required for Windows 8 Metro split-screen snapping with IE10
8 | // Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/
9 | @-ms-viewport{
10 | width: device-width;
11 | }
12 |
13 | // Hide from screenreaders and browsers
14 | // Credit: HTML5 Boilerplate
15 | .hidden {
16 | display: none;
17 | visibility: hidden;
18 | }
19 |
20 | // Visibility utilities
21 |
22 | // For desktops
23 | .visible-phone { display: none !important; }
24 | .visible-tablet { display: none !important; }
25 | .hidden-phone { }
26 | .hidden-tablet { }
27 | .hidden-desktop { display: none !important; }
28 | .visible-desktop { display: inherit !important; }
29 |
30 | // Tablets & small desktops only
31 | @media (min-width: 768px) and (max-width: 979px) {
32 | // Hide everything else
33 | .hidden-desktop { display: inherit !important; }
34 | .visible-desktop { display: none !important ; }
35 | // Show
36 | .visible-tablet { display: inherit !important; }
37 | // Hide
38 | .hidden-tablet { display: none !important; }
39 | }
40 |
41 | // Phones only
42 | @media (max-width: 767px) {
43 | // Hide everything else
44 | .hidden-desktop { display: inherit !important; }
45 | .visible-desktop { display: none !important; }
46 | // Show
47 | .visible-phone { display: inherit !important; } // Use inherit to restore previous behavior
48 | // Hide
49 | .hidden-phone { display: none !important; }
50 | }
51 |
52 | // Print utilities
53 | .visible-print { display: none !important; }
54 | .hidden-print { }
55 |
56 | @media print {
57 | .visible-print { display: inherit !important; }
58 | .hidden-print { display: none !important; }
59 | }
60 |
--------------------------------------------------------------------------------
/less/responsive.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Responsive v2.3.2
3 | *
4 | * Copyright 2013 Twitter, Inc
5 | * Licensed under the Apache License v2.0
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Designed and built with all the love in the world by @mdo and @fat.
9 | */
10 |
11 |
12 | // Responsive.less
13 | // For phone and tablet devices
14 | // -------------------------------------------------------------
15 |
16 |
17 | // REPEAT VARIABLES & MIXINS
18 | // -------------------------
19 | // Required since we compile the responsive stuff separately
20 |
21 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc
22 | @import "mixins.less";
23 |
24 |
25 | // RESPONSIVE CLASSES
26 | // ------------------
27 |
28 | @import "responsive-utilities.less";
29 |
30 |
31 | // MEDIA QUERIES
32 | // ------------------
33 | @media (min-width: 1440px) {
34 |
35 | // Fixed grid
36 | #grid > .core(@gridColumnWidthXLarge, @gridGutterWidthXLarge);
37 |
38 | // Fluid grid
39 | #grid > .fluid(@fluidGridColumnWidthXLarge, @fluidGridGutterWidthXLarge);
40 |
41 | // Input grid
42 | #grid > .input(@gridColumnWidthXLarge, @gridGutterWidthXLarge);
43 |
44 | // Thumbnails
45 | .thumbnails {
46 | margin-left: -@gridGutterWidthXLarge;
47 | }
48 | .thumbnails > li {
49 | margin-left: @gridGutterWidthXLarge;
50 | }
51 | .row-fluid .thumbnails {
52 | margin-left: 0;
53 | }
54 |
55 | }
56 | // Large desktops
57 | @media (min-width: 1280px) and (max-width: 1439px) {
58 |
59 | // Fixed grid
60 | #grid > .core(@gridColumnWidthLarge, @gridGutterWidthLarge);
61 |
62 | // Fluid grid
63 | #grid > .fluid(@fluidGridColumnWidthLarge, @fluidGridGutterWidthLarge);
64 |
65 | // Input grid
66 | #grid > .input(@gridColumnWidthLarge, @gridGutterWidthLarge);
67 |
68 | // No need to reset .thumbnails here since it's the same @gridGutterWidth
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/docs/templates/button-groups.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 按钮组
5 |
6 | block head
7 | style(type="text/css").
8 | .btn-group-vertical .sui-btn {
9 | min-width: 100px;
10 | }
11 |
12 | block sidebar
13 | +sidebar('btn-group')
14 |
15 | block content
16 | h1 按钮组
17 | h2.sui-page-header 开发者文档
18 |
19 | p.sui-lead
20 | | 垂直和水平方向按钮组
21 |
22 | ul.sui-nav.nav-tabs.nav-large
23 | li.active
24 | a(href='#demo1', data-toggle='tab') 示例
25 | li
26 | a(href='#code1', data-toggle='tab') 代码
27 | li
28 | a(href='#doc1', data-toggle='tab') 文档
29 |
30 | div.tab-content
31 | div.tab-pane.active#demo1
32 | div.bs-docs-example
33 | div.sui-btn-group
34 | button.sui-btn 左边
35 | button.sui-btn 中间
36 | button.sui-btn 右边
37 | div.sui-btn-group
38 | button.sui-btn 按钮
39 | button.sui-btn.btn-primray 按钮
40 | button.sui-btn.btn-warning 按钮
41 | button.sui-btn.btn-success 按钮
42 | button.sui-btn.btn-danger 按钮
43 |
44 | h2 垂直方向
45 | div.sui-btn-group.btn-group-vertical
46 | button.sui-btn 左边
47 | button.sui-btn 中间
48 | button.sui-btn 右边
49 |
50 | h2 工具栏
51 | div.sui-btn-toolbar(style="margin: 0;")
52 | div.sui-btn-group
53 | button.sui-btn 复制
54 | button.sui-btn 粘贴
55 | button.sui-btn 缩进
56 |
57 | div.sui-btn-group
58 | button.sui-btn.btn-danger 删除
59 | button.sui-btn.btn-primary 插入
60 | div.tab-pane#code1
61 | pre.prettyprint.linenums(data-target='#demo1>div')
62 | div.tab-pane#doc1
63 | | 按钮组,默认是水平排列,通过class btn-group-vertical 控制按钮组垂直排列。
64 |
65 | ul.demo-operations.clearfix
66 | li
67 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
68 |
69 |
70 |
--------------------------------------------------------------------------------
/docs/templates/index.jade:
--------------------------------------------------------------------------------
1 | extends base_index
2 |
3 | block title
4 | title WQUI
5 |
6 | block head
7 | link(rel="stylesheet",href="assets/css/index.css")
8 | script(src='assets/js/index.js')
9 |
10 | block header
11 | +header('index')
12 |
13 | block content_wrap
14 | .jumbotron.intro
15 | .sui-container.brand-intro
16 | h1 WQUI
17 | p.sui-lead
18 | | WQUI 是一套基于bootstrap开发的前端组件库,同时她也是一套设计规范。
19 | br
20 | | 通过WQUI,可以非常方便的设计和实现精美的页面。
21 |
22 | p.btn-wrap.bounceInDown.animated
23 | a.sui-btn.btn-success.btn-lead(href='download.html') 立即下载 WQUI V1.0
24 |
25 | .jumbotron.components
26 | .sui-container
27 | .sui-row
28 | .span4
29 | .details.center
30 | h2 丰富的组件库
31 | ul.unstyled
32 | li 响应式栅格
33 | li icon font 字体图标
34 | li 按钮,表单,表格,提示
35 | li 标签页,步骤条,面包屑
36 | li 对话框,Tooltip,分页器
37 | li 更多组件敬请期待...
38 | .span8.center
39 | a(href='global.html')
40 | img(src='pictures/index-demo-components.png')
41 |
42 | .jumbotron.features
43 | .sui-container
44 | .sui-row
45 | .span4
46 | .details.center
47 | h2 为现代浏览器设计
48 | ul.unstyled
49 | li 扁平化设计
50 | li 响应式布局
51 | li icon font
52 | li CSS 特效
53 | li 兼容chrome,firfox,safari,ie8+等主流浏览器
54 | .span8.center
55 | img(src='pictures/index-demo-browsers.png')
56 |
57 | .jumbotron.bootstrap
58 | .sui-container
59 | .sui-row
60 | .span4
61 | .details.center
62 | h2 基于 bootstrap 2.3
63 |
64 | ul.unstyled
65 | li 基于 boostrap 2.3 ,有良好的代码结构和丰富的文档及示例
66 | li 引入了 icon font, grunt, jade 等新技术
67 |
68 | .span8.center
69 | img.bootstrap-logo(src='pictures/bootstrap-logo.png')
70 |
--------------------------------------------------------------------------------
/less/sui.less:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | /*!
4 | * Bootstrap v2.3.2
5 | *
6 | * Copyright 2013 Twitter, Inc
7 | * Licensed under the Apache License v2.0
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Designed and built with all the love in the world by @mdo and @fat.
11 | */
12 |
13 | // Core variables and mixins
14 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc
15 | @import "mixins.less";
16 |
17 | // CSS Reset
18 | @import "reset.less";
19 |
20 | // Grid system and page structure
21 | @import "scaffolding.less";
22 | @import "grid.less";
23 | @import "layouts.less";
24 |
25 | // Base CSS
26 | @import "type.less";
27 | @import "icons.less";
28 | @import "code.less";
29 | @import "forms.less";
30 | @import "checkbox.less";
31 | @import "msgs.less"; // 添加消息提示模块 @by kai 2014-01-20
32 | @import "tables.less";
33 |
34 | // Components: common
35 | @import "dropdowns.less";
36 | @import "wells.less";
37 | @import "component-animations.less";
38 | @import "close.less";
39 |
40 | // Components: Buttons & Alerts
41 | @import "buttons.less";
42 | @import "button-groups.less";
43 |
44 | // Components: Nav
45 | @import "navs.less";
46 | @import "navbar.less";
47 | @import "breadcrumbs.less";
48 | @import "pagination.less";
49 |
50 | // Components: Popovers
51 | @import "modals.less";
52 | @import "tooltip.less";
53 | @import "popovers.less";
54 | @import "datepicker.less";
55 | @import "timepicker.less";
56 |
57 | // Components: label,tag
58 | @import "label.less";
59 | @import "tag.less";
60 |
61 | // Components: Misc
62 | @import "progress-bars.less";
63 | @import "accordion.less";
64 | @import "carousel.less";
65 | @import "hero-unit.less";
66 | @import "loading.less";
67 |
68 | // steps
69 | @import "steps.less";
70 |
71 | //scharts
72 | @import "scharts.less";
73 |
74 | // Utility classes
75 | @import "utilities.less"; // Has to be last to override when necessary
76 |
77 | // responsive
78 | @import "responsive.less";
79 |
--------------------------------------------------------------------------------
/js/transition.js:
--------------------------------------------------------------------------------
1 | /* ===================================================
2 | * bootstrap-transition.js v2.3.2
3 | * http://getbootstrap.com/2.3.2/javascript.html#transitions
4 | * ===================================================
5 | * Copyright 2013 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict";
24 |
25 |
26 | /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
27 | * ======================================================= */
28 |
29 | $(function () {
30 |
31 | $.support.transition = (function () {
32 |
33 | var transitionEnd = (function () {
34 |
35 | var el = document.createElement('bootstrap')
36 | , transEndEventNames = {
37 | 'WebkitTransition' : 'webkitTransitionEnd'
38 | , 'MozTransition' : 'transitionend'
39 | , 'OTransition' : 'oTransitionEnd otransitionend'
40 | , 'transition' : 'transitionend'
41 | }
42 | , name
43 |
44 | for (name in transEndEventNames){
45 | if (el.style[name] !== undefined) {
46 | return transEndEventNames[name]
47 | }
48 | }
49 |
50 | }())
51 |
52 | return transitionEnd && {
53 | end: transitionEnd
54 | }
55 |
56 | })()
57 |
58 | })
59 |
60 | }(window.jQuery);
61 |
--------------------------------------------------------------------------------
/js/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bootstrap Plugin Test Suite
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/developer.md:
--------------------------------------------------------------------------------
1 | # 一,仓库和分支
2 |
3 | ## 仓库和分支说明
4 |
5 | 三个仓库分别是 **sui,wqui,qnui**。其中 **wqui** 和 **qnui** 都是从 **sui** 复制来的,可以理解为 **fork** ,因为在github上无法在同一个organization中fork,所以我们用复制。
6 |
7 | 每个仓库中的主分支都是dev。
8 | build分支包含所有编译出来的代码,用来在官网服务器上部署。
9 |
10 | ## 设置remote
11 | 假设把三个仓库都clone到本地之后分别是**~/sui**,**~/qnui**,和**~/wqui**。
12 | 下一步就是要设置remote,每个仓库中现在都有一个默认的remote叫 **origin** ,指向github上的同名仓库,这个不要修改。
13 |
14 | ### 设置sui的remote
15 |
16 | 进入sui仓库,执行 `git remote -v` 会发现已经存在一个 **origin**,那么我们还需要添加一个 **gitlab** 来发布代码。
17 | 执行命令 **git remote add gitlab git@gitlab.alibaba-inc.com:sj/sui.git** 即可
18 |
19 | ### 设置qnui的remote
20 |
21 | 进入qnui仓库,执行 `git remote -v` 会发现也已经存在一个origin,然后和sui中的一样 我们也需要添加gitlab用来发布代码。
22 |
23 | * 执行命令 `git remote add gitlab git@gitlab.alibaba-inc.com:sj/qnui.git`。
24 | * 为了能同步sui上的更新,我们还需要把sui也加入自己的remote:
25 | * 执行命令 `git remote add sui git@github.com:sdc-alibaba/sui.git`。
26 |
27 | 这样如果我们 `git fetch sui` 就可以把sui仓库的分支全部更新到qnui中。
28 |
29 | **全部的remote关系如下图所示**
30 |
31 | 
32 |
33 | # 二,开发流程
34 |
35 | 假设A开发一个组件ac。
36 |
37 | 1. A从dev新建一个分支ac,并开发代码, `git checkout -b ac`。
38 | 2. A提交代码并push到github,然后在github上向dev发pull request,指定给另一个人B。
39 | 3. B review之后同意merge,此时ac分支上的代码就进入了sui的dev分支。
40 |
41 | 下一步是要把ac组件同步到qnui和wqui。
42 |
43 | 1. 切换到本地的qnui仓库,切换到dev分支,然后`git fetch sui`,此时会看到一个sui/dev的更新
44 | 2. 然后git merge sui/dev,如果有冲突可能要手动解决下
45 | 3. 解决完冲突并提交之后,执行 git push origin dev就可以了。
46 |
47 | wqui的操作和上面一样。
48 |
49 | 经过上面的操作,三个仓库中的dev分支中都包含了ac组件。
50 |
51 | # 三,发布流程
52 | 发布包含两部分,一是把代码发布到CDN上,二是更新官网。
53 |
54 | ## 发布代码到CDN
55 | 1. 以sui为例,切换到分支daily/1.0.0,如果没有就从dev上新建一个。
56 | 2. 然后merge dev分支
57 | 3. 删除上次发布的tag,`git push gitlab :publish/1.0.0`
58 | 4. `git push gitlab daily/1.0.0`,发布到daily环境
59 | 5. 本地重新打一个tag,并push
60 | - `git tag -d publish/1/0.0`
61 | - `git tag -d publish/1/0.0`
62 | - `git push gitlab publish/1.0.0`
63 |
64 | ## 更新官网
65 |
66 | 因为官网服务器没有安装node,所以需要我们本地构建好代码
67 |
68 | 1. 切换到build分支,`git checkout dev`
69 | 2. `git merge dev`
70 | 3. 执行 `grunt`
71 | 4. 提交并push。
72 | * `git commit -a`
73 | * `git push origin build`
74 |
75 | 最后在官网服务器上对应仓库执行git pull 即可。
76 |
--------------------------------------------------------------------------------
/docs/templates/breadcrumb.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title Breadcrumb 面包屑
5 |
6 | block sidebar
7 | +sidebar('breadcrumb')
8 |
9 | block content
10 |
11 | h1 面包屑
12 |
13 | h2.sui-page-header 设计规范
14 |
15 | div.docs-description
16 | img(src='pictures/docs/breadcrumb.png')
17 |
18 | ul.demo-operations.clearfix
19 | li
20 | a(href='#') 下载psd文件
21 |
22 | h2.sui-page-header 开发者文档
23 |
24 | ul.sui-nav.nav-tabs.nav-large
25 | li.active
26 | a(href='#demo1', data-toggle='tab') 示例
27 | li
28 | a(href='#code1', data-toggle='tab') 代码
29 | li
30 | a(href='#doc1', data-toggle='tab') 文档
31 | div.tab-content
32 | div.tab-pane.active#demo1
33 | div.bs-docs-example
34 | h1 默认尺寸
35 | ul.sui-breadcrumb
36 | li
37 | a(href='#') 首页
38 | li
39 | a(href='#') 手机数码、电脑办公
40 | li.active 智能手机
41 | ul.sui-breadcrumb.breadcrumb-bold
42 | li
43 | a(href='#') 首页
44 | li
45 | a(href='#') 手机数码、电脑办公
46 | li.active 智能手机
47 |
48 | h1 大尺寸
49 | ul.sui-breadcrumb.breadcrumb-large
50 | li
51 | a(href='#') 首页
52 | li
53 | a(href='#') 手机数码、电脑办公
54 | li.active 智能手机
55 | ul.sui-breadcrumb.breadcrumb-large.breadcrumb-bold
56 | li
57 | a(href='#') 首页
58 | li
59 | a(href='#') 手机数码、电脑办公
60 | li.active 智能手机
61 |
62 | div.tab-pane#code1
63 | pre.prettyprint.linenums(data-target='#demo1>div')
64 | div.tab-pane#doc1
65 | | 由于从IE8+开始兼容,故无需加分割符,利用:before自动添加,面包屑有默认18px(一个行高)的下边距,宽度100%。
66 | ul.demo-operations.clearfix
67 | li
68 | a(href='#') 下载psd文件
69 | li
70 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
71 |
--------------------------------------------------------------------------------
/js/tests/unit/alert.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 |
3 | module("alerts")
4 |
5 | test("should provide no conflict", function () {
6 | var alert = $.fn.alert.noConflict()
7 | ok(!$.fn.alert, 'alert was set back to undefined (org value)')
8 | $.fn.alert = alert
9 | })
10 |
11 | test("should be defined on jquery object", function () {
12 | ok($(document.body).alert, 'alert method is defined')
13 | })
14 |
15 | test("should return element", function () {
16 | ok($(document.body).alert()[0] == document.body, 'document.body returned')
17 | })
18 |
19 | test("should fade element out on clicking .close", function () {
20 | var alertHTML = ''
21 | + '
×'
22 | + '
Holy guacamole! Best check yo self, you\'re not looking too good.
'
23 | + '
'
24 | , alert = $(alertHTML).alert()
25 |
26 | alert.find('.close').click()
27 |
28 | ok(!alert.hasClass('in'), 'remove .in class on .close click')
29 | })
30 |
31 | test("should remove element when clicking .close", function () {
32 | $.support.transition = false
33 |
34 | var alertHTML = ''
35 | + '
×'
36 | + '
Holy guacamole! Best check yo self, you\'re not looking too good.
'
37 | + '
'
38 | , alert = $(alertHTML).appendTo('#qunit-fixture').alert()
39 |
40 | ok($('#qunit-fixture').find('.alert-message').length, 'element added to dom')
41 |
42 | alert.find('.close').click()
43 |
44 | ok(!$('#qunit-fixture').find('.alert-message').length, 'element removed from dom')
45 | })
46 |
47 | test("should not fire closed when close is prevented", function () {
48 | $.support.transition = false
49 | stop();
50 | $('')
51 | .bind('close', function (e) {
52 | e.preventDefault();
53 | ok(true);
54 | start();
55 | })
56 | .bind('closed', function () {
57 | ok(false);
58 | })
59 | .alert('close')
60 | })
61 |
62 | })
63 |
--------------------------------------------------------------------------------
/docs/assets/js/html5shiv.js:
--------------------------------------------------------------------------------
1 | /*
2 | HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
3 | */
4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x";
6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
8 | if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;ddiv')
66 | div.tab-pane#doc1
67 | p 很简单,可以自己定制尺寸
68 | p 为方便使用,默认有几种推荐的尺寸,分别对应class: loading-small,loading-xsmall,loading-xxsmall, loading-l, loading-ll, loading-lll
69 | p 默认作为块级盒子显示,.sui-loading.loading-inline 则会以内联盒子形式显示 (inline-block)
70 | p 颜色方面有默认色、黑色、灰色三种, .sui-loading.loading-dark .loading-light
71 | ul.demo-operations.clearfix
72 | li
73 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
74 |
75 |
--------------------------------------------------------------------------------
/js/tests/unit/phantom.js:
--------------------------------------------------------------------------------
1 | /*
2 | * grunt-contrib-qunit
3 | * http://gruntjs.com/
4 | *
5 | * Copyright (c) 2013 "Cowboy" Ben Alman, contributors
6 | * Licensed under the MIT license.
7 | */
8 |
9 | /*global QUnit:true, alert:true*/
10 | (function () {
11 | 'use strict';
12 |
13 | // Don't re-order tests.
14 | QUnit.config.reorder = false
15 | // Run tests serially, not in parallel.
16 | QUnit.config.autorun = false
17 |
18 | // Send messages to the parent PhantomJS process via alert! Good times!!
19 | function sendMessage() {
20 | var args = [].slice.call(arguments)
21 | alert(JSON.stringify(args))
22 | }
23 |
24 | // These methods connect QUnit to PhantomJS.
25 | QUnit.log = function(obj) {
26 | // What is this I don’t even
27 | if (obj.message === '[object Object], undefined:undefined') { return }
28 | // Parse some stuff before sending it.
29 | var actual = QUnit.jsDump.parse(obj.actual)
30 | var expected = QUnit.jsDump.parse(obj.expected)
31 | // Send it.
32 | sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source)
33 | }
34 |
35 | QUnit.testStart = function(obj) {
36 | sendMessage('qunit.testStart', obj.name)
37 | }
38 |
39 | QUnit.testDone = function(obj) {
40 | sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total)
41 | }
42 |
43 | QUnit.moduleStart = function(obj) {
44 | sendMessage('qunit.moduleStart', obj.name)
45 | }
46 |
47 | QUnit.begin = function () {
48 | sendMessage('qunit.begin')
49 | console.log("Starting test suite")
50 | console.log("================================================\n")
51 | }
52 |
53 | QUnit.moduleDone = function (opts) {
54 | if (opts.failed === 0) {
55 | console.log("\r\u2714 All tests passed in '" + opts.name + "' module")
56 | } else {
57 | console.log("\u2716 " + opts.failed + " tests failed in '" + opts.name + "' module")
58 | }
59 | sendMessage('qunit.moduleDone', opts.name, opts.failed, opts.passed, opts.total)
60 | }
61 |
62 | QUnit.done = function (opts) {
63 | console.log("\n================================================")
64 | console.log("Tests completed in " + opts.runtime + " milliseconds")
65 | console.log(opts.passed + " tests of " + opts.total + " passed, " + opts.failed + " failed.")
66 | sendMessage('qunit.done', opts.failed, opts.passed, opts.total, opts.runtime)
67 | }
68 |
69 | }())
70 |
--------------------------------------------------------------------------------
/docs/templates/tag.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title Tag
5 |
6 | block sidebar
7 | +sidebar('Tag')
8 |
9 | block content
10 | h1 TAG
11 |
12 | h2.sui-page-header 开发者文档
13 |
14 | p.sui-lead 入口class:.sui-tag。近亲label在
15 | a(href='./label.html') 这里
16 |
17 | h2 普通与选中的tag
18 | ul.sui-nav.nav-tabs.nav-large
19 | li.active
20 | a(href='#demo1', data-toggle='tab') 示例
21 | li
22 | a(href='#code1', data-toggle='tab') 代码
23 | li
24 | a(href='#doc1', data-toggle='tab') 文档
25 |
26 | div.tab-content
27 | div.tab-pane.active#demo1
28 | div.bs-docs-example
29 | - var txt = ['Normal', 'logo设计', '店铺装修达人', '艺术', '公sdf告', '注意afs']
30 | h3 默认
31 | ul.sui-tag
32 | each text, i in txt
33 | li #{text}
34 | h3 选中的tag的状态:li.tag-selected
35 | ul.sui-tag.tag-selected
36 | each text, i in txt
37 | if i % 2 == 0
38 | li #{text}
39 | else
40 | li.tag-selected #{text}
41 |
42 | div.tab-pane#code1
43 | pre.prettyprint.linenums(data-target='#demo1>div')
44 | div.tab-pane#doc1
45 | p 使用方法很简单了,最好是用ul>li的结构,或者内部是a标签也可以。
46 | ul.demo-operations.clearfix
47 | li
48 | a(href='#') 下载psd文件
49 | li
50 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
51 |
52 |
53 | h2 右侧带叉(用以删除)
54 | ul.sui-nav.nav-tabs.nav-large
55 | li.active
56 | a(href='#demo2', data-toggle='tab') 示例
57 | li
58 | a(href='#code2', data-toggle='tab') 代码
59 | li
60 | a(href='#doc2', data-toggle='tab') 文档
61 |
62 | div.tab-content
63 | div.tab-pane.active#demo2
64 | div.bs-docs-example
65 | - var txt = ['Normal', 'logo设计', '店铺装修达人', '艺术', '公sdf告', '注意afs', '店铺装修达人', '艺术', '公sdf告']
66 | h3 默认 .sui-tag
67 | ul.sui-tag(style="width:300px;border: 1px solid #999")
68 | each text, i in txt
69 | if i % 2 == 0
70 | li #{text}
71 | else
72 | li.tag-selected.with-x #{text}
73 | i ×
74 |
75 | div.tab-pane#code2
76 | pre.prettyprint.linenums(data-target='#demo2>div')
77 | div.tab-pane#doc2
78 | p 带叉的tag则在每个tag元素附加class="with-x",同时内部添加html:
79 | code <i>×</i>
80 | p 因为是CSS组件,相关事件需要根据业务逻辑自己添加
81 | ul.demo-operations.clearfix
82 | li
83 | a(href='#') 下载psd文件
84 | li
85 | a.copy-btn(href='javascript:void(0)', data-target='#demo2>div') 复制代码
86 |
87 |
--------------------------------------------------------------------------------
/less/tests/forms-responsive.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | sui, from Twitter
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/less/icon-pc.less:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'icon-pc';
3 | src:url('@{iconFontPath}/icon-pc.eot?59lb71');
4 | src:url('@{iconFontPath}/icon-pc.eot?#iefix59lb71') format('embedded-opentype'),
5 | url('@{iconFontPath}/icon-pc.woff?59lb71') format('woff'),
6 | url('@{iconFontPath}/icon-pc.ttf?59lb71') format('truetype'),
7 | url('@{iconFontPath}/icon-pc.svg?59lb71#icon-pc') format('svg');
8 | font-weight: normal;
9 | font-style: normal;
10 | }
11 |
12 | .sui-icon {
13 | &[class^="icon-pc-"],
14 | &[class*=" icon-pc-"] {
15 | font-family: 'icon-pc';
16 | speak: none;
17 | font-style: normal;
18 | font-weight: normal;
19 | font-variant: normal;
20 | text-transform: none;
21 | line-height: 1;
22 |
23 | /* Better Font Rendering =========== */
24 | -webkit-font-smoothing: antialiased;
25 | -moz-osx-font-smoothing: grayscale;
26 | }
27 | }
28 | .icon-pc-loading:before {
29 | content: "\e600";
30 | }
31 | .icon-pc-enter:before {
32 | content: "\e602";
33 | }
34 | .icon-pc-ww:before {
35 | content: "\c600";
36 | }
37 | .icon-pc-sound:before {
38 | content: "\c601";
39 | }
40 | .icon-pc-settings:before {
41 | content: "\c602";
42 | }
43 | .icon-pc-right:before {
44 | content: "\c603";
45 | }
46 | .icon-pc-right-circle:before {
47 | content: "\e601";
48 | }
49 | .icon-pc-refresh:before {
50 | content: "\c604";
51 | }
52 | .icon-pc-question-circle:before {
53 | content: "\c605";
54 | }
55 | .icon-pc-prev:before {
56 | content: "\c606";
57 | }
58 | .icon-pc-next:before {
59 | content: "\c607";
60 | }
61 | .icon-pc-list:before {
62 | content: "\c608";
63 | }
64 | .icon-pc-light:before {
65 | content: "\c609";
66 | }
67 | .icon-pc-info-circle:before {
68 | content: "\c60a";
69 | }
70 | .icon-pc-forbidden:before {
71 | content: "\c60b";
72 | }
73 | .icon-pc-error:before {
74 | content: "\c60c";
75 | }
76 | .icon-pc-error-circle:before {
77 | content: "\c60d";
78 | }
79 | .icon-pc-chevron-top:before {
80 | content: "\c60e";
81 | }
82 | .icon-pc-chevron-right:before {
83 | content: "\c60f";
84 | }
85 | .icon-pc-chevron-left:before {
86 | content: "\c610";
87 | }
88 | .icon-pc-chevron-bottom:before {
89 | content: "\c611";
90 | }
91 | .icon-pc-bell:before {
92 | content: "\c612";
93 | }
94 | .icon-pc-checkbox-checked:before {
95 | content: "\e607";
96 | }
97 | .icon-pc-checkbox-unchecked:before {
98 | content: "\e605";
99 | }
100 | .icon-pc-checkbox-halfchecked:before {
101 | content: "\e606";
102 | }
103 | .icon-pc-radio-checked:before {
104 | content: "\e604";
105 | }
106 | .icon-pc-radio-unchecked:before {
107 | content: "\e603";
108 | }
109 |
--------------------------------------------------------------------------------
/docs/templates/dropdown-js.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 下拉菜单
5 |
6 | block sidebar
7 | +sidebar('dropdown-js')
8 |
9 | block content
10 | h1 对话框
11 |
12 | h2.sui-page-header 开发者文档
13 |
14 | p.sui-lead
15 | | JS 下拉菜单,比原生的select有更精美的样式并且有更好的可拓展性。
16 |
17 | h2 通过标记使用
18 | ul.sui-nav.nav-tabs.nav-large
19 | li.active
20 | a(href='#demo1', data-toggle='tab') 示例
21 | li
22 | a(href='#code1', data-toggle='tab') 代码
23 | li
24 | a(href='#doc1', data-toggle='tab') 文档
25 |
26 | div.tab-content
27 | div.tab-pane.active#demo1
28 | div.bs-docs-example(style='height: 140px;')
29 | span.sui-dropdown
30 | a.dropdown-toggle#drop1(role="button" data-toggle="dropdown" href="#") 杭州
31 | ul#menu1.sui-dropdown-menu(role="menu" aria-labelledby="drop1")
32 | li(role="presentation")
33 | a(role="menuitem" tabindex="-1" href="#") 北京
34 | li(role="presentation")
35 | a(role="menuitem" tabindex="-1" href="#") 圣彼得堡
36 | li(role="presentation")
37 | a(role="menuitem" tabindex="-1" href="#") 莫斯科
38 |
39 | div.tab-pane#code1
40 | pre.prettyprint.linenums(data-target='#demo1>div')
41 | div.tab-pane#doc1
42 | | 通过添加 data-toggle="dropdown" 可以启用下拉功能。
43 | ul.demo-operations.clearfix
44 | li
45 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
46 |
47 |
48 | h2 通过JS调用
49 | ul.sui-nav.nav-tabs.nav-large
50 | li.active
51 | a(href='#demo2', data-toggle='tab') 示例
52 | li
53 | a(href='#code2', data-toggle='tab') 代码
54 | li
55 | a(href='#doc2', data-toggle='tab') 文档
56 |
57 | div.tab-content
58 | div.tab-pane.active#demo2
59 | div.bs-docs-example(style='height: 140px;')
60 | span.sui-dropdown#dropdown-demo2
61 | a.dropdown-toggle#drop2(role='button' href="#") 杭州
62 | ul#menu2.sui-dropdown-menu(role='menu' aria-labelledby="drop2")
63 | li(role="presentation")
64 | a(role="menuitem" tabindex="-1" href="#") 北京
65 | li(role="presentation")
66 | a(role="menuitem" tabindex="-1" href="#") 上海
67 | li(role="presentation")
68 | a(role="menuitem" tabindex="-1" href="#") 深圳
69 | script.
70 | $('#dropdown-demo2 .dropdown-toggle').dropdown()
71 | div.tab-pane#code2
72 | pre.prettyprint.linenums(data-target='#demo2>div')
73 | div.tab-pane#doc2
74 | p
75 | js直接调用 $().dropdown()
76 | p
77 | | 还提供一个 $().dropdown('toggle') 方法可以控制菜单的显示。
78 | ul.demo-operations.clearfix
79 | li
80 | a.copy-btn(href='javascript:void(0)', data-target='#demo2>div') 复制代码
81 |
--------------------------------------------------------------------------------
/docs/templates/pagination.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 分页器
5 |
6 | block sidebar
7 | +sidebar('pagination')
8 |
9 | block content
10 | h1 分页器
11 |
12 | h2.sui-page-header 设计规范
13 |
14 | div.docs-description
15 | img(src='pictures/docs/pagination.png')
16 |
17 | ul.demo-operations.clearfix
18 | li
19 | a(href='#') 下载psd文件
20 |
21 | h2.sui-page-header 开发者文档
22 |
23 | p.sui-lead
24 | div
25 | a(href='pagination-js.html') 点击访问:pagination-JS组件
26 |
27 | ul.sui-nav.nav-tabs.nav-large
28 | li.active
29 | a(href='#demo1', data-toggle='tab') 示例
30 | li
31 | a(href='#code1', data-toggle='tab') 代码
32 | li
33 | a(href='#doc1', data-toggle='tab') 文档
34 |
35 | div.tab-content
36 | div.tab-pane.active#demo1
37 | div.bs-docs-example
38 | h2 小型分页器
39 | p.sui-lead
40 | | 当只有一页内容,且不超过5条时,可以只显示数字,把“上一页”和“下一页”拿掉。
41 | div.sui-pagination
42 | ul
43 | li.prev.disabled
44 | a(href='#') «
45 | li.active
46 | a(href='#') 1
47 | li
48 | a(href='#') 2
49 | li
50 | a(href='#') 3
51 | li
52 | a(href='#') 4
53 | li
54 | a(href='#') 5
55 | li.next
56 | a(href='#') »
57 | h2 常态分页器
58 | div.sui-pagination
59 | ul
60 | li.prev.disabled
61 | a(href='#') «上一页
62 | li.active
63 | a(href='#') 1
64 | li
65 | a(href='#') 2
66 | li
67 | a(href='#') 3
68 | li
69 | a(href='#') 4
70 | li
71 | a(href='#') 5
72 | li.dotted
73 | span ...
74 | li.next
75 | a(href='#') 下一页»
76 | div
77 | span 共10页
78 | span
79 | |到
80 | |
81 | |页
82 | h2 无页码分页器
83 | div.sui-pagination
84 | ul
85 | li.prev
86 | a(href='#') «上一页
87 | li.next
88 | a(href='#') 下一页»
89 | div.tab-pane#code1
90 | pre.prettyprint.linenums(data-target='#demo1>div')
91 | div.tab-pane#doc1
92 | | 所有形式的分页器都提供三种尺寸,除此之外,还有pagination-centered,,pagination-right 控制分页器的水平位置
93 | ul.demo-operations.clearfix
94 | li
95 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
96 |
97 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DPL
2 |
3 | ## 一,开发环境:
4 |
5 | ### Grunt
6 |
7 | 之前的make脚本已经被改成grunt,除了常规的[grunt安装](http://gruntjs.com/),还需要安装[hogan](http://twitter.github.io/hogan.js/)用来编译文档模板。grunt 中已经配置了如下几个任务:
8 |
9 | * dist:编辑css和js,包含两个任务dist-js和dist-css
10 | * docs:编译文档, 因为依赖关系,所以编译文档实际上也会执行dist
11 | * test:代码检查和单元测试
12 | * default:默认任务,等价于 test + dist
13 | * watch:监控文件改动实时编译
14 |
15 | ** 因为我们的代码构建放在了服务器端,而服务器端使用的npm源是 [http://registry.npm.taobao.net](http://registry.npm.taobao.net),所以建议把在自己的电脑上也设置这个源。**
16 |
17 | ### Gulp
18 |
19 | **gulp 暂时无人维护,不要用**
20 |
21 | ### iconfont
22 | 图标全部用iconfont实现。
23 |
24 | ### git协作:
25 |
26 | 分支说明
27 | * master分支用来发布代码,不要在master上做任何改动。
28 | * dev分支用来预发布,所有测试通过准备发布的代码都先merge进dev。
29 | * build分支包含了所有打包编译出的代码,用在不方便安装node的环境。
30 |
31 | 每个人新建一个自己的分支,比如开发btn的分支就叫btn,开发完成后向dev发送一个merge request,另一个同学review完代码之后点击merge即可提交到dev。
32 |
33 | 开发时候只需要执行 **grunt watch** 就可以,会自动编译代码并刷新页面。最后提交的时候要执行 **grunt test** 保证没有错误再提交。
34 |
35 |
36 | ## 二,文件结构:
37 | - .package: 编译后的js和css文件,这个被gitignore,执行grunt会自动生成。
38 | - docs:文档,文档是用mustache模板写的,mustache是一个无逻辑模板语言(官网:[mustache](http://mustache.github.io/)),用twitter自己写的一个编译器hogan来编译([hogan](http://twitter.github.io/hogan.js/))。 每个组件都有自己的demo,开发一个组件就在这里新建一个demo,这里用的是jade模板生成的,执行grunt docs会自动把docs/template下的jade模板编译到docs目录下的同名文件。其中base.jade是公用模板,其他模板都应该继承base。如果模板名字以com-开头或者以-com.jade结尾,则不会被编译为html,适合中间组件.
39 | docs中注意如下几个文件:
40 | - assets:只在docs中使用的静态文件放这里,和bootstrap代码相关的比如bootstrap.css和fonts是从外面cp进来的。
41 | - example:示例,这个是没有用模板来写的,后面如果有必要我会用mustache改造一下。每完成一个组件都应该在这里面写一个详细的例子(或者在less下面建一个demo文件夹更好点?)。
42 | - template:官网页面,这个是用mustache来写的,里面有一个base和若干pages。
43 |
44 | - fonts: 字体描述文件,icon font字体是支持包括ie6在内的所有主流浏览器,只是每个浏览器支持的字体描述文件格式不同,这里提供了全部四种格式。但是因为icon用了:before和content来实现,所以ie8以下的浏览器还是不支持的。
45 | - less:css源码(注意这里面的test没有测试框架的支持,人肉检查组件而已)
46 | 模块结构可以在bootstrap.less中看的非常清楚,直接看bootstrap.less的代码。
47 |
48 | - js:重点注意单元测试,需要先学习qunit的用法。每一个js模块都对应一个单元测试。js代码的提交一定要通过单元测试。grunt test或者直接访问index.html都可以。(目前grunt qunit会有一个超时bug,暂时去掉了)
49 |
50 |
51 | ## css组件规范:
52 |
53 | 1. 尺寸规范:
54 | 元素的尺寸由line-height,padding,border,margin组成,还有不影响元素本身大小的是font-size
55 | 所以广义的元素尺寸包括了上述五个因素。
56 | 我们把组件都分成四种大小:mini,small,default,large。这四种大小分别对应四种不同的font-size,line-height,padding,border和margin,这些是在variables中已经定义好的。
57 | 一些基础css组件可能包含全部的四种尺寸,比如btn和input,大部分组件都是其中一种尺寸。
58 | 当然很多时候一个组件无法对应这四种尺寸之一,那就直接写死常量。
59 | 这方面bootstrap做的不好,大部分都是写死在代码中的常量。
60 |
61 | 2. 颜色规范:
62 | 常用的颜色可能就十几种,定义在variables中,其他颜色最好能根据常用颜色算出来。这样换皮肤的话只需要把颜色配置换掉就好了。
63 | 比如btn-primary的颜色是这么定义的:
64 | @btnPrimaryBackground: @linkColor;
65 | @btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 20%);
66 |
67 | 3. 浏览器分级
68 | 对浏览器分ABC级:
69 | A: 最优体验,视觉和功能完全保证
70 | B: 功能保证,无法保证视觉美观
71 | C: 不兼容
72 |
73 |
74 | 4. 命名规范:
75 |
76 | - css中除了变量用驼峰法,其他都是’-‘分割(3.0全部改成减号分割)
77 | - 一个组件有不同的样式,应该把每一种样式都作为一个追加的classname,而不是修改原有的class。即 .btn.btn-primary,而不是直接用.btn-primary替换.btn
78 | 最重要的是语义化命名,参见后文。
79 |
80 | ## js 插件开发规范:
81 |
82 | ## js:单元测试规范:
83 | TODO
84 |
--------------------------------------------------------------------------------
/docs/demos/icons.html:
--------------------------------------------------------------------------------
1 | 图标方向图标
提示反馈
表单
多媒体
其他
--------------------------------------------------------------------------------
/js/alert.js:
--------------------------------------------------------------------------------
1 | /* ==========================================================
2 | * bootstrap-alert.js v2.3.2
3 | * http://getbootstrap.com/2.3.2/javascript.html#alerts
4 | * ==========================================================
5 | * Copyright 2013 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict";
24 |
25 |
26 | /* ALERT CLASS DEFINITION
27 | * ====================== */
28 |
29 | var dismiss = '[data-dismiss="alert"]'
30 | , Alert = function (el) {
31 | $(el).on('click', dismiss, this.close)
32 | }
33 |
34 | Alert.prototype.close = function (e) {
35 | var $this = $(this)
36 | , selector = $this.attr('data-target')
37 | , $parent
38 |
39 | if (!selector) {
40 | selector = $this.attr('href')
41 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
42 | }
43 |
44 | $parent = $(selector)
45 |
46 | e && e.preventDefault()
47 |
48 | $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
49 |
50 | $parent.trigger(e = $.Event('close'))
51 |
52 | if (e.isDefaultPrevented()) return
53 |
54 | $parent.removeClass('in')
55 |
56 | function removeElement() {
57 | $parent
58 | .trigger('closed')
59 | .remove()
60 | }
61 |
62 | $.support.transition && $parent.hasClass('fade') ?
63 | $parent.on($.support.transition.end, removeElement) :
64 | removeElement()
65 | }
66 |
67 |
68 | /* ALERT PLUGIN DEFINITION
69 | * ======================= */
70 |
71 | var old = $.fn.alert
72 |
73 | $.fn.alert = function (option) {
74 | return this.each(function () {
75 | var $this = $(this)
76 | , data = $this.data('alert')
77 | if (!data) $this.data('alert', (data = new Alert(this)))
78 | if (typeof option == 'string') data[option].call($this)
79 | })
80 | }
81 |
82 | $.fn.alert.Constructor = Alert
83 |
84 |
85 | /* ALERT NO CONFLICT
86 | * ================= */
87 |
88 | $.fn.alert.noConflict = function () {
89 | $.fn.alert = old
90 | return this
91 | }
92 |
93 |
94 | /* ALERT DATA-API
95 | * ============== */
96 |
97 | $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
98 |
99 | }(window.jQuery);
100 |
--------------------------------------------------------------------------------
/less/modals.less:
--------------------------------------------------------------------------------
1 | //
2 | // Modals
3 | // --------------------------------------------------
4 | .popdiv-footer {
5 | padding: 7px 10px 5px;
6 | margin-bottom: 0;
7 | text-align: right; // right align buttons
8 | .border-radius(0 0 3px 3px);
9 | .clearfix(); // clear it in case folks use .pull-* classes on buttons
10 |
11 | // Properly space out buttons
12 | .sui-btn + .sui-btn {
13 | margin-left: 7px;
14 | margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
15 | }
16 | // but override that for button groups
17 | .sui-btn-group .sui-btn + .sui-btn {
18 | margin-left: -1px;
19 | }
20 | // and override it for block buttons as well
21 | .btn-block + .btn-block {
22 | margin-left: 0;
23 | }
24 | }
25 |
26 | .overspread {
27 | top: 0;
28 | right: 0;
29 | bottom: 0;
30 | left: 0;
31 | }
32 | // Background
33 | .sui-modal-backdrop {
34 | position: fixed;
35 | .overspread;
36 | z-index: @zindexModalBackdrop;
37 | // Fade for backdrop
38 | &.fade { opacity: 0; }
39 | }
40 |
41 | .sui-modal-backdrop,
42 | .sui-modal-backdrop.fade.in {
43 | .opacity(40);
44 | }
45 | // modal shade
46 | .sui-modal .shade {
47 | position: absolute;
48 | .overspread;
49 | &.in {.opacity(40);}
50 | }
51 |
52 | // Base modal
53 | .sui-modal {
54 | position: fixed;
55 | top: 50%;
56 | left: 50%;
57 | margin-left: -220px;
58 | z-index: @zindexModal;
59 | width: 440px;
60 | background-color: @white;
61 | .border-radius(3px);
62 | .box-shadow(0 0 8px 2px #999);
63 | .background-clip(padding-box);
64 | // Remove focus outline from opened modal
65 | outline: none;
66 |
67 | &.fade {
68 | .transition(e('opacity .3s linear, top .3s ease-out'));
69 | top: -25%;
70 | }
71 | &.fade.in {
72 | top: 50%;
73 | }
74 |
75 | .modal-header {
76 | padding: 0 10px;
77 | background: #4a4a4a;
78 | color: #fff;
79 | .border-radius(3px 3px 0 0);
80 | // Heading
81 | h4 {
82 | margin: 0;
83 | line-height: 30px;
84 | font-weight: normal;
85 | }
86 | .modal-title{
87 | margin: 0;
88 | }
89 | .sui-close {
90 | color: #bebebe;
91 | text-shadow: none;
92 | font-size: 20px;
93 | line-height: 30px;
94 | &:hover {
95 | color: #ff5050;
96 | }
97 | }
98 | }
99 |
100 | // Body (where all modal content resides)
101 | .modal-body {
102 | position: relative;
103 | overflow-y: auto;
104 | min-height: 100px;
105 | max-height: 500px;
106 | margin: 0;
107 | padding: 10px 20px;
108 | &.no-foot{
109 | min-height: 190px;
110 | }
111 | }
112 | // Remove bottom margin if need be
113 | .modal-form {
114 | margin-bottom: 0;
115 | }
116 |
117 | // Footer (for actions)
118 | .modal-footer {
119 | .popdiv-footer()
120 | }
121 |
122 | }
123 | .tooltip-footer {
124 | .popdiv-footer()
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/docs/templates/sidenav.jade:
--------------------------------------------------------------------------------
1 | ul.sui-nav.nav-tabs.nav-stacked.nav-xlarge.docs-sidenav
2 | - var items = []
3 | - items.push({name: 'global', title:'全局样式', url: 'global.html', icon: 'sui-icon icon-globe'})
4 | - items.push({name: 'base-css', title: '基础css', children:[], icon: 'sui-icon icon-magic' })
5 | - items.push({name: 'css-components', title: 'css组件', children:[], icon: 'sui-icon icon-picture'})
6 | - items.push({name: 'js-components', title: 'js组件', children:[], icon: 'sui-icon icon-shopping-cart'})
7 |
8 | - items[1].children.push({name: 'btn', title:'按钮', url:'buttons.html'})
9 | - items[1].children.push({name: 'form', title:'表单', url:'forms.html'})
10 | - items[1].children.push({name: 'icons', title:'图标', url:'icons.html'})
11 | - items[1].children.push({name: 'table', title:'表格', url:'tables.html'})
12 |
13 |
14 | - items[2].children.push({name: 'msg', title:'提示消息', url:'msgs.html'})
15 | - items[2].children.push({name: 'step', title:'步骤条', url:'steps.html'})
16 | - items[2].children.push({name: 'tab', title:'标签页', url:'tab.html'})
17 | - items[2].children.push({name: 'breadcrumb', title:'面包屑', url:'breadcrumb.html'})
18 | - items[2].children.push({name: 'pagination', title:'分页器', url:'pagination.html'})
19 | - items[2].children.push({name: 'dropdown', title:'下拉菜单', url:'dropdown.html'})
20 | - items[2].children.push({name: 'checkbox', title:'选框', url:'checkbox.html'})
21 | - items[2].children.push({name: 'progress', title:'进度条', url:'progress.html'})
22 | - items[2].children.push({name: 'Loading', title:'Loading', url:'loading.html'})
23 |
24 | - items[3].children.push({name: 'dialog', title:'对话框', url:'dialog.html'})
25 | - items[3].children.push({name: 'tooltip', title:'tooltip', url:'tooltip.html'})
26 | - items[3].children.push({name: 'tab-js', title:'标签页', url:'tab-js.html'})
27 | - items[3].children.push({name: 'pagination-js', title:'分页器', url:'pagination-js.html'})
28 | - items[3].children.push({name: 'dropdown-js', title:'下拉菜单', url:'dropdown-js.html'})
29 | - items[3].children.push({name: 'tree-js', title:'级联选择', url:'tree-js.html'})
30 | - items[3].children.push({name: 'datetimepicker', title:'datetimepicker', url:'datetimepicker.html'})
31 |
32 | for cat, i in items
33 | - var classname = ''
34 | if highlight == cat.name
35 | - classname = "active"
36 | if cat.children
37 | for item,j in cat.children
38 | if highlight == item.name
39 | - classname = 'active'
40 | li(class=classname)
41 | if !cat.children
42 | a(href=cat.url)
43 | i(class='#{cat.icon}')
44 | |#{cat.title}
45 | else
46 | a(href=cat.url)
47 | i(class='#{cat.icon}')
48 | |#{cat.title}
49 | i.sui-icon.icon-angle-down.pull-right
50 | ul.sui-nav.nav-tabs.nav-stacked
51 |
52 | for item,j in cat.children
53 | - var classname = ''
54 | if highlight == item.name
55 | - classname = "active"
56 | li(class=classname)
57 | a(href=item.url) #{item.title}
58 |
59 | script(type="text/javascript").
60 | var disqus_identifier = 'disqus-id-!{highlight}';
61 |
--------------------------------------------------------------------------------
/js/tests/unit/tab.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 |
3 | module("tabs")
4 |
5 | test("should provide no conflict", function () {
6 | var tab = $.fn.tab.noConflict()
7 | ok(!$.fn.tab, 'tab was set back to undefined (org value)')
8 | $.fn.tab = tab
9 | })
10 |
11 | test("should be defined on jquery object", function () {
12 | ok($(document.body).tab, 'tabs method is defined')
13 | })
14 |
15 | test("should return element", function () {
16 | ok($(document.body).tab()[0] == document.body, 'document.body returned')
17 | })
18 |
19 | test("should activate element by tab id", function () {
20 | var tabsHTML =
21 | ''
25 |
26 | $('').appendTo("#qunit-fixture")
27 |
28 | $(tabsHTML).find('li:last a').tab('show')
29 | equal($("#qunit-fixture").find('.active').attr('id'), "profile")
30 |
31 | $(tabsHTML).find('li:first a').tab('show')
32 | equal($("#qunit-fixture").find('.active').attr('id'), "home")
33 | })
34 |
35 | test("should activate element by tab id", function () {
36 | var pillsHTML =
37 | ''
41 |
42 | $('').appendTo("#qunit-fixture")
43 |
44 | $(pillsHTML).find('li:last a').tab('show')
45 | equal($("#qunit-fixture").find('.active').attr('id'), "profile")
46 |
47 | $(pillsHTML).find('li:first a').tab('show')
48 | equal($("#qunit-fixture").find('.active').attr('id'), "home")
49 | })
50 |
51 |
52 | test("should not fire closed when close is prevented", function () {
53 | $.support.transition = false
54 | stop();
55 | $('')
56 | .bind('show', function (e) {
57 | e.preventDefault();
58 | ok(true);
59 | start();
60 | })
61 | .bind('shown', function () {
62 | ok(false);
63 | })
64 | .tab('show')
65 | })
66 |
67 | test("show and shown events should reference correct relatedTarget", function () {
68 | var dropHTML =
69 | ''
70 | + '- 1'
71 | + ''
75 | + '
'
76 | + '
'
77 |
78 | $(dropHTML).find('ul>li:first a').tab('show').end()
79 | .find('ul>li:last a').on('show', function(event){
80 | equal(event.relatedTarget.hash, "#1-1")
81 | }).on('shown', function(event){
82 | equal(event.relatedTarget.hash, "#1-1")
83 | }).tab('show')
84 | })
85 |
86 | })
87 |
--------------------------------------------------------------------------------
/docs/templates/grid.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 12 栏栅格
5 |
6 | block head
7 | style(type="text/css").
8 | .grid-demo .sui-row div,
9 | .grid-demo .sui-row-fluid div {
10 | background: #dfedfc;
11 | min-height: 50px;
12 | }
13 | .grid-demo .sui-row + .sui-row,
14 | .grid-demo .sui-row-fluid + .sui-row-fluid {
15 | margin-top: 10px;
16 | }
17 | block sidebar
18 | +sidebar('grid')
19 |
20 | block content
21 | h1 响应式栅格系统
22 |
23 | h2.sui-page-header 开发者文档
24 |
25 | p.sui-lead
26 | | 响应式的12栏栅格系统,兼容三种主流屏幕尺寸 1024,1280/1366以及1440。实际上用户屏幕宽度在1024px以上的情况下会自动选择一个最佳的栅格宽度。
27 | | 如果想关闭响应式布局,只需要删除 sui-responsive.less文件即可。
28 |
29 | h2 1. 默认栅格系统
30 | ul.sui-nav.nav-tabs.nav-large
31 | li.active
32 | a(href='#demo1', data-toggle='tab') 示例
33 | li
34 | a(href='#code1', data-toggle='tab') 代码
35 | li
36 | a(href='#doc1', data-toggle='tab') 文档
37 |
38 | div.tab-content
39 | div.tab-pane.active#demo1
40 | div.bs-docs-example
41 | div.grid-demo
42 | div.sui-row
43 | - for (var x = 1; x <= 8; x++)
44 | div(class="span#{1}")=1
45 | div.sui-row
46 | - each x in [1, 2, 2, 3, ]
47 | div(class="span#{x}")=x
48 | div.sui-row
49 | - each x in [4, 4]
50 | div(class="span#{x}")=x
51 | div.sui-row
52 | - each x in [2, 6]
53 | div(class="span#{x}")=x
54 | div.tab-pane#code1
55 | pre.prettyprint.linenums(data-target='#demo1>div')
56 | div.tab-pane#doc1
57 | p
58 | | 默认栅格系统每一栏是定宽的,并且宽度可以根据屏幕宽度在几个固定值之间变化,区别于流式栅格系统的百分比宽度。
59 |
60 | ul.demo-operations.clearfix
61 | li
62 | a(href='#') 下载psd文件
63 | li
64 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
65 |
66 |
67 | h2 2. 流式栅格系统
68 | ul.sui-nav.nav-tabs.nav-large
69 | li.active
70 | a(href='#demo2', data-toggle='tab') 示例
71 | li
72 | a(href='#code2', data-toggle='tab') 代码
73 | li
74 | a(href='#doc2', data-toggle='tab') 文档
75 |
76 | div.tab-content
77 | div.tab-pane.active#demo2
78 | div.bs-docs-example
79 | div.grid-demo
80 | div.sui-row-fluid
81 | - for (var x = 1; x <= 8; x++)
82 | div(class="span#{1}")=1
83 | div.sui-row-fluid
84 | - each x in [1, 2, 2, 3, ]
85 | div(class="span#{x}")=x
86 | div.sui-row-fluid
87 | - each x in [4, 4]
88 | div(class="span#{x}")=x
89 | div.sui-row-fluid
90 | - each x in [2, 6]
91 | div(class="span#{x}")=x
92 | div.tab-pane#code2
93 | pre.prettyprint.linenums(data-target='#demo2>div')
94 | div.tab-pane#doc2
95 | p
96 | | 流式栅格系统每一栏的宽度都是其容器的百分比,因此会随着屏幕宽度的变化而不断变化,没有一个固定的宽度像素值。
97 |
98 | ul.demo-operations.clearfix
99 | li
100 | a(href='#') 下载psd文件
101 | li
102 | a.copy-btn(href='javascript:void(0)', data-target='#demo2>div') 复制代码
103 |
--------------------------------------------------------------------------------
/docs/templates/buttons.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 按钮
5 |
6 | block sidebar
7 | +sidebar('btn')
8 |
9 | block content
10 | - var SIZES = ['xlarge', 'large', '', 'small']
11 | - var ROLES = [["", "默认"], ["primary", "首要"], ["success", "成功"], ["info", "信息"], ["warning", "警告"], ["danger", "危险"], ["link", "链接"]]
12 |
13 | h1 按钮
14 |
15 | h2.sui-page-header 设计规范
16 |
17 | div.docs-description
18 | img(src='pictures/docs/btn.png')
19 |
20 | ul.demo-operations.clearfix
21 | li
22 | a(href='#') 下载psd文件
23 |
24 | h2.sui-page-header 开发者文档
25 |
26 | p.sui-lead
27 | ul.unstyled
28 | li 按钮统一使用下面提供的高度和样式,最好不要自己添加新的尺寸和样式(但是可以把其中某些样式进行重载)。
29 | li 一般情况下推荐使用灰白色按钮,根据具体的页面和使用环境来选择。
30 | li 比较重要的操作或者需要用户明显注意到的地方使用蓝色按钮。
31 | li 黄色按钮请谨慎使用,在非常重要和特殊的情况下需要用户迅速发现并立即处理的时候使用,一个页面不能超过一个黄色按钮。
32 |
33 | ul.demo-operations.clearfix
34 | li
35 | a(href='#') 下载psd文件
36 |
37 | h2 1. 不同大小和功能的按钮
38 | ul.sui-nav.nav-tabs.nav-large
39 | li.active
40 | a(href='#demo1', data-toggle='tab') 示例
41 | li
42 | a(href='#code1', data-toggle='tab') 代码
43 |
44 | div.tab-content
45 | div.tab-pane.active#demo1
46 | div.bs-docs-example
47 |
48 | each s in SIZES
49 | - var classname = 'sui-btn'
50 | - var size = ''
51 | if s
52 | - size = 'btn-' + s
53 | each r in ROLES
54 | - var role = ''
55 | if r[0]
56 | - role = 'btn-' + r[0]
57 | | #{r[1]}
58 | |
59 | a(disabled class='sui-btn #{size}' href='javascript:void(0);') 禁用
60 | a(disabled class='sui-btn btn-text #{size}' href='javascript:void(0);') 禁用
61 | a(disabled class='sui-btn btn-link #{size}' href='javascript:void(0);') 禁用
62 | br
63 | br
64 | div.tab-pane#code1
65 | pre.prettyprint.linenums(data-target='#demo1>div')
66 |
67 | ul.demo-operations.clearfix
68 | li
69 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
70 |
71 |
72 | h2 2.带图标的按钮
73 | ul.sui-nav.nav-tabs.nav-large
74 | li.active
75 | a(href='#demo2', data-toggle='tab') 示例
76 | li
77 | a(href='#code2', data-toggle='tab') 代码
78 |
79 | div.tab-content
80 | div.tab-pane.active#demo2
81 | div.bs-docs-example
82 | each v in ROLES
83 | - var classname = 'sui-btn'
84 | if v[0]
85 | - classname += ' btn-' + v[0]
86 | if v[0] != 'link'
87 | |#{v[1]}
88 | |
89 |
90 | a.sui-btn.btn-text(href='javascript:void(0);')
91 | i.sui-icon.icon-pc-refresh
92 | a.sui-btn.btn-text.btn-default(href='javascript:void(0);')
93 | i.sui-icon.icon-pc-refresh
94 | | 刷新
95 | div.tab-pane#code2
96 | pre.prettyprint.linenums(data-target='#demo2>div')
97 |
98 | ul.demo-operations.clearfix
99 | li
100 | a.copy-btn(href='javascript:void(0)', data-target='#demo2>div') 复制代码
101 |
--------------------------------------------------------------------------------
/docs/examples/todo-create.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 新建待办事项
5 |
6 |
7 |
8 |
9 | ;
10 | ;
11 |
12 |
13 |
14 |
15 | - 待办事项
16 | - 添加待办事项
17 |
18 |
19 |
20 | 新的待办事项”晚上9点拿夜宵”创建成功!
21 |
22 |
23 |
24 |
80 |
81 |
82 | ').collapse('show')
21 | ok(el.hasClass('in'), 'has class in')
22 | ok(/height/.test(el.attr('style')), 'has height set')
23 | })
24 |
25 | test("should hide a collapsed element", function () {
26 | var el = $('').collapse('hide')
27 | ok(!el.hasClass('in'), 'does not have class in')
28 | ok(/height/.test(el.attr('style')), 'has height set')
29 | })
30 |
31 | test("should not fire shown when show is prevented", function () {
32 | $.support.transition = false
33 | stop()
34 | stop() //这里有一个bug, 下面的start方法会触发两次
35 | $('')
36 | .bind('show', function (e) {
37 | e.preventDefault();
38 | ok(true);
39 | start();
40 | })
41 | .bind('shown', function () {
42 | ok(false);
43 | })
44 | .collapse('show')
45 | })
46 |
47 | test("should reset style to auto after finishing opening collapse", function () {
48 | $.support.transition = false
49 | stop()
50 | $('')
51 | .bind('show', function () {
52 | ok(this.style.height == '0px')
53 | })
54 | .bind('shown', function () {
55 | ok(this.style.height == 'auto')
56 | start()
57 | })
58 | .collapse('show')
59 | })
60 |
61 | test("should add active class to target when collapse shown", function () {
62 | $.support.transition = false
63 | stop()
64 |
65 | var target = $('')
66 | .appendTo($('#qunit-fixture'))
67 |
68 | var collapsible = $('')
69 | .appendTo($('#qunit-fixture'))
70 | .on('show', function () {
71 | ok(!target.hasClass('collapsed'))
72 | start()
73 | })
74 |
75 | target.click()
76 | })
77 |
78 | test("should remove active class to target when collapse hidden", function () {
79 | $.support.transition = false
80 | stop()
81 |
82 | var target = $('')
83 | .appendTo($('#qunit-fixture'))
84 |
85 | var collapsible = $('')
86 | .appendTo($('#qunit-fixture'))
87 | .on('hide', function () {
88 | ok(target.hasClass('collapsed'))
89 | start()
90 | })
91 |
92 | target.click()
93 | })
94 |
95 | })
96 |
--------------------------------------------------------------------------------
/js/button.js:
--------------------------------------------------------------------------------
1 | /* ============================================================
2 | * bootstrap-button.js v2.3.2
3 | * http://getbootstrap.com/2.3.2/javascript.html#buttons
4 | * ============================================================
5 | * Copyright 2013 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ============================================================ */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict";
24 |
25 |
26 | /* BUTTON PUBLIC CLASS DEFINITION
27 | * ============================== */
28 |
29 | var Button = function (element, options) {
30 | this.$element = $(element)
31 | this.options = $.extend({}, $.fn.button.defaults, options)
32 | }
33 |
34 | Button.prototype.setState = function (state) {
35 | var d = 'disabled'
36 | , $el = this.$element
37 | , data = $el.data()
38 | , val = $el.is('input') ? 'val' : 'html'
39 |
40 | state = state + 'Text'
41 | data.resetText || $el.data('resetText', $el[val]())
42 |
43 | $el[val](data[state] || this.options[state])
44 |
45 | // push to event loop to allow forms to submit
46 | setTimeout(function () {
47 | state == 'loadingText' ?
48 | $el.addClass(d).attr(d, d) :
49 | $el.removeClass(d).removeAttr(d)
50 | }, 0)
51 | }
52 |
53 | Button.prototype.toggle = function () {
54 | var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
55 |
56 | $parent && $parent
57 | .find('.active')
58 | .removeClass('active')
59 |
60 | this.$element.toggleClass('active')
61 | }
62 |
63 |
64 | /* BUTTON PLUGIN DEFINITION
65 | * ======================== */
66 |
67 | var old = $.fn.button
68 |
69 | $.fn.button = function (option) {
70 | return this.each(function () {
71 | var $this = $(this)
72 | , data = $this.data('button')
73 | , options = typeof option == 'object' && option
74 | if (!data) $this.data('button', (data = new Button(this, options)))
75 | if (option == 'toggle') data.toggle()
76 | else if (option) data.setState(option)
77 | })
78 | }
79 |
80 | $.fn.button.defaults = {
81 | loadingText: 'loading...'
82 | }
83 |
84 | $.fn.button.Constructor = Button
85 |
86 |
87 | /* BUTTON NO CONFLICT
88 | * ================== */
89 |
90 | $.fn.button.noConflict = function () {
91 | $.fn.button = old
92 | return this
93 | }
94 |
95 |
96 | /* BUTTON DATA-API
97 | * =============== */
98 |
99 | $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
100 | var $btn = $(e.target)
101 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
102 | $btn.button('toggle')
103 | })
104 |
105 | }(window.jQuery);
106 |
--------------------------------------------------------------------------------
/js/checkbox.js:
--------------------------------------------------------------------------------
1 | !function ($) {
2 |
3 | "use strict";
4 |
5 | var CHECKED_CLASS = 'checked';
6 | var HALF_CHECKED_CLASS = 'halfchecked';
7 | var DISABLED_CLASS= 'disabled';
8 |
9 | var Checkbox = function (element, options) {
10 | this.$element = $(element)
11 | //this.options = $.extend({}, $.fn.checkbox.defaults, options)
12 | this.$checkbox = this.$element.find("input").change($.proxy(this.update, this))
13 | //同步状态
14 | this.update()
15 | var name = this.$checkbox.prop("name")
16 | var self = this;
17 | if (name && this.$checkbox.attr("type").toUpperCase() == 'RADIO') {
18 | //radio 会因为其他相同name 的radio的改变而受到影响
19 | $("input[name='"+name+"']").each(function(){
20 | $(this).change($.proxy(self.update, self))
21 | })
22 | }
23 | }
24 |
25 | var old = $.fn.checkbox
26 |
27 | $.fn.checkbox = function (option) {
28 | return this.each(function () {
29 | var $this = $(this)
30 | , data = $this.data('checkbox')
31 | , options = typeof option == 'object' && option
32 | if (!data) $this.data('checkbox', (data = new Checkbox(this, options)))
33 | else if (option) data[option]()
34 | })
35 | }
36 | //同步状态
37 | Checkbox.prototype.update = function () {
38 | if(this.$checkbox.prop("checked")) this.$element.removeClass(HALF_CHECKED_CLASS).addClass(CHECKED_CLASS)
39 | else this.$element.removeClass(CHECKED_CLASS)
40 | if(this.$checkbox.prop('disabled')) this.$element.addClass(DISABLED_CLASS)
41 | else this.$element.removeClass(DISABLED_CLASS)
42 | }
43 | Checkbox.prototype.toggle = function () {
44 | if(this.$checkbox.prop("checked")) this.uncheck()
45 | else this.check()
46 | }
47 |
48 | Checkbox.prototype.check = function () {
49 | if(this.$checkbox.prop("disabled")) return
50 | this.$element.removeClass(HALF_CHECKED_CLASS).addClass(CHECKED_CLASS)
51 | this.$checkbox.prop('checked', 'checked')
52 | }
53 | Checkbox.prototype.uncheck = function () {
54 | if(this.$checkbox.prop("disabled")) return
55 | this.$element.removeClass(HALF_CHECKED_CLASS).removeClass(CHECKED_CLASS)
56 | this.$checkbox.removeAttr('checked')
57 | }
58 | Checkbox.prototype.halfcheck = function () {
59 | if(this.$checkbox.prop("disabled")) return
60 | this.$element.removeClass(CHECKED_CLASS).addClass(HALF_CHECKED_CLASS)
61 | this.$checkbox.removeAttr('checked')
62 | }
63 |
64 | Checkbox.prototype.disable = function () {
65 | this.$element.addClass(DISABLED_CLASS)
66 | this.$checkbox.prop('disabled', 'disabled')
67 | }
68 | Checkbox.prototype.enable = function () {
69 | this.$element.removeClass(DISABLED_CLASS)
70 | this.$checkbox.removeAttr('disabled')
71 | }
72 |
73 | $.fn.checkbox.defaults = {
74 | loadingText: 'loading...'
75 | }
76 |
77 | $.fn.checkbox.Constructor = Checkbox
78 |
79 |
80 | /* NO CONFLICT
81 | * ================== */
82 |
83 | $.fn.checkbox.noConflict = function () {
84 | $.fn.checkbox = old
85 | return this
86 | }
87 |
88 | $.fn.radio = $.fn.checkbox;
89 |
90 |
91 | /* DATA-API
92 | * =============== */
93 |
94 | //必须一开始就初始化,不然对于radio,由于其他相同name的radio改动的时候由于没有初始化就无法更新状态
95 | $(function() {
96 | $('[data-toggle^=checkbox],[data-toggle^=radio] ').each(function () {
97 | $(this).checkbox()
98 | })
99 | })
100 |
101 | }(window.jQuery);
102 |
--------------------------------------------------------------------------------
/less/carousel.less:
--------------------------------------------------------------------------------
1 | //
2 | // Carousel
3 | // --------------------------------------------------
4 |
5 |
6 | .sui-carousel {
7 | position: relative;
8 | margin-bottom: @baseLineHeight;
9 | line-height: 1;
10 |
11 | .carousel-inner {
12 | overflow: hidden;
13 | width: 100%;
14 | position: relative;
15 | }
16 |
17 | .carousel-inner {
18 |
19 | > .item {
20 | display: none;
21 | position: relative;
22 | .transition(.6s ease-in-out left);
23 |
24 | // Account for jankitude on images
25 | > img,
26 | > a > img {
27 | display: block;
28 | line-height: 1;
29 | }
30 | }
31 |
32 | > .active,
33 | > .next,
34 | > .prev { display: block; }
35 |
36 | > .active {
37 | left: 0;
38 | }
39 |
40 | > .next,
41 | > .prev {
42 | position: absolute;
43 | top: 0;
44 | width: 100%;
45 | }
46 |
47 | > .next {
48 | left: 100%;
49 | }
50 | > .prev {
51 | left: -100%;
52 | }
53 | > .next.left,
54 | > .prev.right {
55 | left: 0;
56 | }
57 |
58 | > .active.left {
59 | left: -100%;
60 | }
61 | > .active.right {
62 | left: 100%;
63 | }
64 |
65 | }
66 |
67 | // Left/right controls for nav
68 | // ---------------------------
69 |
70 | .carousel-control {
71 | position: absolute;
72 | top: 40%;
73 | left: 15px;
74 | width: 40px;
75 | height: 40px;
76 | margin-top: -20px;
77 | font-size: 60px;
78 | font-weight: 100;
79 | line-height: 30px;
80 | color: @white;
81 | text-align: center;
82 | background: @grayDarker;
83 | border: 3px solid @white;
84 | .border-radius(23px);
85 | .opacity(50);
86 |
87 | // we can't have this transition here
88 | // because webkit cancels the carousel
89 | // animation if you trip this while
90 | // in the middle of another animation
91 | // ;_;
92 | // .transition(opacity .2s linear);
93 |
94 | // Reposition the right one
95 | &.right {
96 | left: auto;
97 | right: 15px;
98 | }
99 |
100 | // Hover/focus state
101 | &:hover,
102 | &:focus {
103 | color: @white;
104 | text-decoration: none;
105 | .opacity(90);
106 | }
107 | }
108 |
109 | // Carousel indicator pips
110 | // -----------------------------
111 | .carousel-indicators {
112 | position: absolute;
113 | top: 15px;
114 | right: 15px;
115 | z-index: 5;
116 | margin: 0;
117 | list-style: none;
118 |
119 | li {
120 | display: block;
121 | float: left;
122 | width: 10px;
123 | height: 10px;
124 | margin-left: 5px;
125 | text-indent: -999px;
126 | background-color: #ccc;
127 | background-color: rgba(255,255,255,.25);
128 | border-radius: 5px;
129 | }
130 | .active {
131 | background-color: #fff;
132 | }
133 | }
134 |
135 | // Caption for text below images
136 | // -----------------------------
137 |
138 | .carousel-caption {
139 | position: absolute;
140 | left: 0;
141 | right: 0;
142 | bottom: 0;
143 | padding: 15px;
144 | background: @grayDark;
145 | background: rgba(0,0,0,.75);
146 | }
147 | .carousel-caption h4,
148 | .carousel-caption p {
149 | color: @white;
150 | line-height: @baseLineHeight;
151 | }
152 | .carousel-caption h4 {
153 | margin: 0 0 5px;
154 | }
155 | .carousel-caption p {
156 | margin-bottom: 0;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/js/popover.js:
--------------------------------------------------------------------------------
1 | /* ===========================================================
2 | * bootstrap-popover.js v2.3.2
3 | * http://getbootstrap.com/2.3.2/javascript.html#popovers
4 | * ===========================================================
5 | * Copyright 2013 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * =========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict";
24 |
25 |
26 | /* POPOVER PUBLIC CLASS DEFINITION
27 | * =============================== */
28 |
29 | var Popover = function (element, options) {
30 | this.init('popover', element, options)
31 | }
32 |
33 |
34 | /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
35 | ========================================== */
36 |
37 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
38 |
39 | constructor: Popover
40 |
41 | , setContent: function () {
42 | var $tip = this.tip()
43 | , title = this.getTitle()
44 | , content = this.getContent()
45 |
46 | $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
47 | $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
48 |
49 | $tip.removeClass('fade top bottom left right in')
50 | }
51 |
52 | , hasContent: function () {
53 | return this.getTitle() || this.getContent()
54 | }
55 |
56 | , getContent: function () {
57 | var content
58 | , $e = this.$element
59 | , o = this.options
60 |
61 | content = (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
62 | || $e.attr('data-content')
63 |
64 | return content
65 | }
66 |
67 | , tip: function () {
68 | if (!this.$tip) {
69 | this.$tip = $(this.options.template)
70 | }
71 | return this.$tip
72 | }
73 |
74 | , destroy: function () {
75 | this.hide().$element.off('.' + this.type).removeData(this.type)
76 | }
77 |
78 | })
79 |
80 |
81 | /* POPOVER PLUGIN DEFINITION
82 | * ======================= */
83 |
84 | var old = $.fn.popover
85 |
86 | $.fn.popover = function (option) {
87 | return this.each(function () {
88 | var $this = $(this)
89 | , data = $this.data('popover')
90 | , options = typeof option == 'object' && option
91 | if (!data) $this.data('popover', (data = new Popover(this, options)))
92 | if (typeof option == 'string') data[option]()
93 | })
94 | }
95 |
96 | $.fn.popover.Constructor = Popover
97 |
98 | $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
99 | placement: 'right'
100 | , trigger: 'click'
101 | , content: ''
102 | , template: ''
103 | })
104 |
105 |
106 | /* POPOVER NO CONFLICT
107 | * =================== */
108 |
109 | $.fn.popover.noConflict = function () {
110 | $.fn.popover = old
111 | return this
112 | }
113 |
114 | }(window.jQuery);
115 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | var join = require("path").join
4 |
5 | var gulp = require('gulp'),
6 | gutil = require('gulp-util'),
7 | requirejs = require('gulp-requirejs'),
8 | uglify = require('gulp-uglify'),
9 | rename = require("gulp-rename"),
10 | jshint = require('gulp-jshint'),
11 | less = require('gulp-less'),
12 | jade = require('gulp-jade'),
13 | qunit = require('gulp-qunit'),
14 | watch = require('gulp-watch'),
15 | livereload = require('gulp-livereload'),
16 | tinnylr = require('tiny-lr')
17 |
18 | var server = tinnylr()
19 |
20 | var exec = require("child_process").exec
21 |
22 | var paths = {
23 | distRoot: './build',
24 | docsRoot: './docs',
25 | demosRoot: './docs/demos'
26 | }
27 |
28 | var pkg = {
29 | name: "bootstrap"
30 | }
31 |
32 | gulp.task('requirejs', function() {
33 | //目前requirejs还不支持gulp.src
34 | var jsDist = join(paths.distRoot, 'js')
35 | var requirejsConfig= {
36 | baseUrl: "js",
37 | name: "almond",
38 | optimize: "none",
39 | include: pkg.name,
40 | insertRequire: [pkg.name],
41 | mainConfigFile: "js/requirejs-config.js",
42 | out: pkg.name + '.js',
43 | wrap: true
44 | }
45 | requirejs(requirejsConfig)
46 | //uncompressed
47 | .pipe(gulp.dest(jsDist))
48 | //uglify
49 | .pipe(uglify({preserveComments: 'some'}))
50 | .pipe(rename(pkg.name + '.min.js'))
51 | .pipe(gulp.dest(jsDist))
52 | .pipe(livereload(server))
53 | })
54 |
55 | gulp.task('less', function() {
56 | var cssDist = join(paths.distRoot, 'css')
57 |
58 | var recess = function(input, output) {
59 | output = output || input
60 | gulp.src(join('less', input + '.less'))
61 | .pipe(less())
62 | .pipe(rename(output + '.css'))
63 | .pipe(gulp.dest(cssDist))
64 | .pipe(less({compress: true}))
65 | .pipe(rename(output + '.min.css'))
66 | .pipe(gulp.dest(cssDist))
67 | .pipe(livereload(server))
68 | }
69 |
70 | recess('bootstrap')
71 | recess('responsive', pkg.name + '-responsive')
72 | })
73 |
74 | // compile jade template
75 | gulp.task('jade', function() {
76 | gulp.src(['**/*.jade', '!base.jade', '!com-*', '!*-com.jade'], {cwd: join(paths.demosRoot, 'templates')})
77 | .pipe(jade({pretty: true}))
78 | .pipe(gulp.dest(paths.demosRoot))
79 | .pipe(livereload(server))
80 | })
81 |
82 | //compile mastache template
83 | gulp.task('hogan', function(callback) {
84 | var child = exec('node docs/build', function(e) {
85 | callback()
86 | })
87 | })
88 |
89 | gulp.task('jshint', function() {
90 | var jsfiles = [
91 | 'gulpfile.js',
92 | 'js/*.js',
93 | 'js/tests/unit/*.js'
94 | ]
95 | gulp.src(jsfiles)
96 | .pipe(jshint('js/.jshintrc'))
97 | .pipe(jshint.reporter('default'))
98 | })
99 |
100 | gulp.task('qunit', function(callback) {
101 | gulp.src('js/tests/*.html')
102 | .pipe(qunit());
103 | })
104 |
105 | // copy fonts to build
106 | gulp.task('fonts', function() {
107 | gulp.src('./fonts/*')
108 | .pipe(gulp.dest(join(paths.distRoot, 'fonts')))
109 | })
110 |
111 | gulp.task('watch', function() {
112 | server.listen(3456)
113 | gulp.watch('js/**/*.js', ['requirejs'])
114 | gulp.watch('less/**/*.less', ['less'])
115 | gulp.watch(join(paths.docsRoot, 'templates/**/*.mustache'), ['hogan'])
116 | gulp.watch(join(paths.demosRoot, 'templates/**/*.jade'), ['jade'])
117 | gulp.watch('./fonts/*', ['jade'])
118 | })
119 |
120 | gulp.task('test', ['jshint', 'qunit'])
121 |
122 | gulp.task('docs', ['fonts', 'jade', 'hogan'])
123 |
124 | gulp.task('default', ['less', 'test', 'requirejs', 'docs'])
125 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Bootstrap
2 |
3 | Looking to contribute something to Bootstrap? **Here's how you can help.**
4 |
5 |
6 |
7 | ## Reporting issues
8 |
9 | We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems that we can fix within the Bootstrap core. Please read the following guidelines before opening any issue.
10 |
11 | 1. **Search for existing issues.** We get a lot of duplicate issues, and you'd help us out a lot by first checking if someone else has reported the same issue. Moreover, the issue may have already been resolved with a fix available.
12 | 2. **Create an isolated and reproducible test case.** Be sure the problem exists in Bootstrap's code with a [reduced test case](http://css-tricks.com/reduced-test-cases/) that should be included in each bug report.
13 | 3. **Include a live example.** Make use of jsFiddle or jsBin to share your isolated test cases.
14 | 4. **Share as much information as possible.** Include operating system and version, browser and version, version of Bootstrap, customized or vanilla build, etc. where appropriate. Also include steps to reproduce the bug.
15 |
16 |
17 |
18 | ## Key branches
19 |
20 | - `master` is the latest, deployed version.
21 | - `gh-pages` is the hosted docs (not to be used for pull requests).
22 | - `*-wip` is the official work in progress branch for the next release.
23 |
24 |
25 |
26 | ## Notes on the repo
27 |
28 | As of v2.0.0, Bootstrap's documentation is powered by Mustache templates and built via `make` before each commit and release. This was done to enable internationalization (translation) in a future release by uploading our strings to the [Twitter Translation Center](http://translate.twttr.com/). Any edits to the docs should be first done in the Mustache files and then recompiled into the HTML.
29 |
30 |
31 |
32 | ## Pull requests
33 |
34 | - Try to submit pull requests against the latest `*-wip` branch for easier merging
35 | - Any changes to the docs must be made to the Mustache templates, not just the compiled HTML pages
36 | - CSS changes must be done in .less files first, never just the compiled files
37 | - If modifying the .less files, always recompile and commit the compiled files bootstrap.css and bootstrap.min.css
38 | - Try not to pollute your pull request with unintended changes--keep them simple and small
39 | - Try to share which browsers your code has been tested in before submitting a pull request
40 |
41 |
42 |
43 | ## Coding standards: HTML
44 |
45 | - Two spaces for indentation, never tabs
46 | - Double quotes only, never single quotes
47 | - Always use proper indentation
48 | - Use tags and elements appropriate for an HTML5 doctype (e.g., self-closing tags)
49 |
50 |
51 |
52 | ## Coding standards: CSS
53 |
54 | - Adhere to the [Recess CSS property order](http://markdotto.com/2011/11/29/css-property-order/)
55 | - Multiple-line approach (one property and value per line)
56 | - Always a space after a property's colon (.e.g, `display: block;` and not `display:block;`)
57 | - End all lines with a semi-colon
58 | - For multiple, comma-separated selectors, place each selector on it's own line
59 | - Attribute selectors, like `input[type="text"]` should always wrap the attribute's value in double quotes, for consistency and safety (see this [blog post on unquoted attribute values](http://mathiasbynens.be/notes/unquoted-attribute-values) that can lead to XSS attacks).
60 |
61 |
62 |
63 | ## Coding standards: JS
64 |
65 | - No semicolons
66 | - Comma first
67 | - 2 spaces (no tabs)
68 | - strict mode
69 | - "Attractive"
70 |
71 |
72 |
73 | ## License
74 |
75 | By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/twbs/bootstrap/blob/master/LICENSE
76 |
--------------------------------------------------------------------------------
/docs/assets/js/README.md:
--------------------------------------------------------------------------------
1 | ## 2.0 BOOTSTRAP JS PHILOSOPHY
2 | These are the high-level design rules which guide the development of Bootstrap's plugin apis.
3 |
4 | ---
5 |
6 | ### DATA-ATTRIBUTE API
7 |
8 | We believe you should be able to use all plugins provided by Bootstrap purely through the markup API without writing a single line of javascript.
9 |
10 | We acknowledge that this isn't always the most performant and sometimes it may be desirable to turn this functionality off altogether. Therefore, as of 2.0 we provide the ability to disable the data attribute API by unbinding all events on the body namespaced with `'data-api'`. This looks like this:
11 |
12 | $('body').off('.data-api')
13 |
14 | To target a specific plugin, just include the plugins name as a namespace along with the data-api namespace like this:
15 |
16 | $('body').off('.alert.data-api')
17 |
18 | ---
19 |
20 | ### PROGRAMMATIC API
21 |
22 | We also believe you should be able to use all plugins provided by Bootstrap purely through the JS API.
23 |
24 | All public APIs should be single, chainable methods, and return the collection acted upon.
25 |
26 | $(".btn.danger").button("toggle").addClass("fat")
27 |
28 | All methods should accept an optional options object, a string which targets a particular method, or null which initiates the default behavior:
29 |
30 | $("#myModal").modal() // initialized with defaults
31 | $("#myModal").modal({ keyboard: false }) // initialized with now keyboard
32 | $("#myModal").modal('show') // initializes and invokes show immediately afterqwe2
33 |
34 | ---
35 |
36 | ### OPTIONS
37 |
38 | Options should be sparse and add universal value. We should pick the right defaults.
39 |
40 | All plugins should have a default object which can be modified to effect all instance's default options. The defaults object should be available via `$.fn.plugin.defaults`.
41 |
42 | $.fn.modal.defaults = { … }
43 |
44 | An options definition should take the following form:
45 |
46 | *noun*: *adjective* - describes or modifies a quality of an instance
47 |
48 | examples:
49 |
50 | backdrop: true
51 | keyboard: false
52 | placement: 'top'
53 |
54 | ---
55 |
56 | ### EVENTS
57 |
58 | All events should have an infinitive and past participle form. The infinitive is fired just before an action takes place, the past participle on completion of the action.
59 |
60 | show | shown
61 | hide | hidden
62 |
63 | ---
64 |
65 | ### CONSTRUCTORS
66 |
67 | Each plugin should expose it's raw constructor on a `Constructor` property -- accessed in the following way:
68 |
69 |
70 | $.fn.popover.Constructor
71 |
72 | ---
73 |
74 | ### DATA ACCESSOR
75 |
76 | Each plugin stores a copy of the invoked class on an object. This class instance can be accessed directly through jQuery's data API like this:
77 |
78 | $('[rel=popover]').data('popover') instanceof $.fn.popover.Constructor
79 |
80 | ---
81 |
82 | ### DATA ATTRIBUTES
83 |
84 | Data attributes should take the following form:
85 |
86 | - data-{{verb}}={{plugin}} - defines main interaction
87 | - data-target || href^=# - defined on "control" element (if element controls an element other than self)
88 | - data-{{noun}} - defines class instance options
89 |
90 | examples:
91 |
92 | // control other targets
93 | data-toggle="modal" data-target="#foo"
94 | data-toggle="collapse" data-target="#foo" data-parent="#bar"
95 |
96 | // defined on element they control
97 | data-spy="scroll"
98 |
99 | data-dismiss="modal"
100 | data-dismiss="alert"
101 |
102 | data-toggle="dropdown"
103 |
104 | data-toggle="button"
105 | data-toggle="buttons-checkbox"
106 | data-toggle="buttons-radio"
--------------------------------------------------------------------------------
/less/popovers.less:
--------------------------------------------------------------------------------
1 | //
2 | // Popovers
3 | // --------------------------------------------------
4 |
5 |
6 | .sui-popover {
7 | position: absolute;
8 | top: 0;
9 | left: 0;
10 | z-index: @zindexPopover;
11 | display: none;
12 | max-width: 276px;
13 | padding: 1px;
14 | text-align: left; // Reset given new insertion method
15 | background-color: @popoverBackground;
16 | -webkit-background-clip: padding-box;
17 | -moz-background-clip: padding;
18 | background-clip: padding-box;
19 | border: 1px solid #ccc;
20 | border: 1px solid rgba(0,0,0,.2);
21 | .border-radius(6px);
22 | .box-shadow(0 5px 10px rgba(0,0,0,.2));
23 |
24 | // Overrides for proper insertion
25 | white-space: normal;
26 |
27 | // Offset the popover to account for the popover arrow
28 | &.top { margin-top: -10px; }
29 | &.right { margin-left: 10px; }
30 | &.bottom { margin-top: 10px; }
31 | &.left { margin-left: -10px; }
32 | }
33 |
34 | .popover-title {
35 | margin: 0; // reset heading margin
36 | padding: 8px 14px;
37 | font-size: 14px;
38 | font-weight: normal;
39 | line-height: 18px;
40 | background-color: @popoverTitleBackground;
41 | border-bottom: 1px solid darken(@popoverTitleBackground, 5%);
42 | .border-radius(5px 5px 0 0);
43 |
44 | &:empty {
45 | display: none;
46 | }
47 | }
48 |
49 | .popover-content {
50 | padding: 9px 14px;
51 | }
52 |
53 | // Arrows
54 | //
55 | // .arrow is outer, .arrow:after is inner
56 |
57 | .sui-popover .arrow {
58 | &, &:after {
59 | position: absolute;
60 | display: block;
61 | width: 0;
62 | height: 0;
63 | border-color: transparent;
64 | border-style: solid;
65 | }
66 | .arrow {
67 | border-width: @popoverArrowOuterWidth;
68 | }
69 | .arrow:after {
70 | border-width: @popoverArrowWidth;
71 | content: "";
72 | }
73 | }
74 |
75 | .sui-popover {
76 | &.top .arrow {
77 | left: 50%;
78 | margin-left: -@popoverArrowOuterWidth;
79 | border-bottom-width: 0;
80 | border-top-color: #999; // IE8 fallback
81 | border-top-color: @popoverArrowOuterColor;
82 | bottom: -@popoverArrowOuterWidth;
83 | &:after {
84 | bottom: 1px;
85 | margin-left: -@popoverArrowWidth;
86 | border-bottom-width: 0;
87 | border-top-color: @popoverArrowColor;
88 | }
89 | }
90 | &.right .arrow {
91 | top: 50%;
92 | left: -@popoverArrowOuterWidth;
93 | margin-top: -@popoverArrowOuterWidth;
94 | border-left-width: 0;
95 | border-right-color: #999; // IE8 fallback
96 | border-right-color: @popoverArrowOuterColor;
97 | &:after {
98 | left: 1px;
99 | bottom: -@popoverArrowWidth;
100 | border-left-width: 0;
101 | border-right-color: @popoverArrowColor;
102 | }
103 | }
104 | &.bottom .arrow {
105 | left: 50%;
106 | margin-left: -@popoverArrowOuterWidth;
107 | border-top-width: 0;
108 | border-bottom-color: #999; // IE8 fallback
109 | border-bottom-color: @popoverArrowOuterColor;
110 | top: -@popoverArrowOuterWidth;
111 | &:after {
112 | top: 1px;
113 | margin-left: -@popoverArrowWidth;
114 | border-top-width: 0;
115 | border-bottom-color: @popoverArrowColor;
116 | }
117 | }
118 |
119 | &.left .arrow {
120 | top: 50%;
121 | right: -@popoverArrowOuterWidth;
122 | margin-top: -@popoverArrowOuterWidth;
123 | border-right-width: 0;
124 | border-left-color: #999; // IE8 fallback
125 | border-left-color: @popoverArrowOuterColor;
126 | &:after {
127 | right: 1px;
128 | border-right-width: 0;
129 | border-left-color: @popoverArrowColor;
130 | bottom: -@popoverArrowWidth;
131 | }
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/docs/templates/pagination-js.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 分页器
5 |
6 | block sidebar
7 | +sidebar('pagination-js')
8 |
9 | block content
10 | h1 分页器-JS
11 |
12 | h2.sui-page-header 开发者文档
13 |
14 | p.sui-lead
15 | | pagination-JS组件用于前端分页,无刷新等应用场景
16 | div
17 | a(href="pagination.html") 点击访问pagination-CSS组件
18 |
19 | ul.sui-nav.nav-tabs.nav-large
20 | li.active
21 | a(href='#demo1', data-toggle='tab') 示例
22 | li
23 | a(href='#doc1', data-toggle='tab') 文档
24 |
25 | div.tab-content
26 | div.tab-pane.active#demo1
27 | div.bs-docs-example
28 | h3 示例
29 | p.test
30 | pre.prettyprint.linenums.
31 | $('.test').pagination({
32 | pages: 50,
33 | styleClass: ['pagination-large'],
34 | showCtrl: true,
35 | displayPage: 6,
36 | onSelect: function (num) {
37 | console.log(num) //打开控制台观察
38 | }
39 | })
40 | h3 最小配置项
41 | p.test1
42 | pre.prettyprint.linenums.
43 | $('.test').pagination({
44 | pages: 6
45 | })
46 |
47 | div.tab-pane#doc1
48 | h3 配置项
49 | h4 pagination组件一共有8个配置项,较于其他分页插件,配置更为灵活简单,提供2种分页计算方式,且可控页码显示的数量。
50 | dl
51 | dt styleClass
52 | dd styleClass接收一个数组,包括结合SUI CSS部分的pagination-small,pagiantion-large和默认的pagination样式,以后提供皮肤样式和自定义样式的时候也可以在这里引入
53 | dd eg: styleClass: ['pagination-large', 'custom-red', 'custom-size']
54 | dl
55 | dt displayPage
56 | dd displayPage指的是要显示多少个页码,如下图所示,展示了6个,默认显示5个
57 | dd
58 | img(src="assets/imgs/pagination1.png")
59 | dd 指定了displayPage以后,pagination组件会根据该配置项自动分页,出于用户体验的考虑,displayPage最小为5个,低于5个会自动被改写为5个
60 | dd 需要指出一种情况是,如果displayPage为n,但是总的页码为n+1时,pagination组件会展示全部的页码(也就是n+1),不出现省略号
61 | dl
62 | dt currentPage
63 | dd 当前页,默认为第1页,不解释
64 | dl
65 | dt itemsCount,pageSize和pages
66 | dd pagination组件提供两种计算分页的方式,一种是直接给出pages,另一种是给出数据的总条数和每页显示的条数,pagination会自动计算出页数。
67 | dd 当给出pages时,会忽略itemsCount和pageSize参数
68 | dd P.S:一般情况来讲,通过pages来配置分页,适用于分页数固定的情况。
69 | dl
70 | dt showCtrl
71 | dd 是否展示总页数和跳转控制器,默认为false,设置为true时会在pagination节点上注册一些事件,对跳转页码做合法性校验,并支持键盘操作。
72 | dl
73 | dt onSelect
74 | dd 点击页码时的回调函数,提供一个当前点击的页码的参数,可以在回调函数中使用自定义事件。
75 | dt remote
76 | dd 远程控制开关,如果设置为true的话,分页器不会自动跳转,需要人工调用goToPage方法,主要用于一些特殊条件下,比如点击了页码之后,需要等页面加载完之后再跳转
77 | h3 函数
78 | h4 pagination组件对外暴露2个函数
79 | dl
80 | dt $('selector').pagination('updateItemsCount',itemsCount[, pageToGo])
81 | dd 当数据条目总数发生变化时,调用此方法,参数为新的数据条目总数
82 | dd pageToGo是要跳转到的某页
83 | dl
84 | dt $('selector').pagination('updatePages',pages[, pageToGo])
85 | dd 当分页直接采用pages配置项时,pageSize不存在,因此只能通过该方法直接更新分页数
86 | dd P.S:一般情况来讲,通过pages来配置分页,适用于分页数固定的情况,不推荐使用此方法。
87 | dd pageToGo是要跳转到的某页
88 | dl
89 | dt $('selector').pagination('goToPage', pageNum)
90 | dd 跳转到指定页面
91 |
92 | block js_block
93 | script.
94 | $('.test').pagination({
95 | pages: 50,
96 | styleClass: ['pagination-large'],
97 | showCtrl: true,
98 | displayPage: 6,
99 | onSelect: function (num) {
100 | console.log(num)
101 | }
102 | })
103 |
104 | $('.test1').pagination({
105 | pages: 6
106 | })
107 |
108 |
--------------------------------------------------------------------------------
/docs/assets/css/index.css:
--------------------------------------------------------------------------------
1 | .animated {
2 | -webkit-animation-duration: 1s;
3 | animation-duration: 1s;
4 | -webkit-animation-fill-mode: both;
5 | animation-fill-mode: both;
6 | }
7 | @-webkit-keyframes myBounceInUp {
8 | 0% {
9 | opacity: 0;
10 | -webkit-transform: translateY(200px);
11 | transform: translateY(200px);
12 | }
13 | 100% {
14 | opacity: 1;
15 | -webkit-transform: translateY(0);
16 | transform: translateY(0);
17 | }
18 | }
19 | @keyframes myBounceInUp {
20 | 0% {
21 | opacity: 0;
22 | -webkit-transform: translateY(200px);
23 | transform: translateY(200px);
24 | }
25 | 100% {
26 | opacity: 1;
27 | -webkit-transform: translateY(0);
28 | transform: translateY(0);
29 | }
30 | }
31 | .myBounceInUp {
32 | -webkit-animation-name: myBounceInUp;
33 | animation-name: myBounceInUp;
34 | }
35 | .intro {
36 | background-color: #6f5499;
37 | color: #fff;
38 | padding: 80px 0;
39 | }
40 | .jumbotron {
41 | padding: 60px 0;
42 | color: #fff;
43 | }
44 | .components {
45 | background-color: #a2dbf6;
46 | -webkit-transition: background 0.5s, background ease-in-out 0.5s;
47 | transition: background .5s, background .5s;
48 | -webkit-transition: color 1s 0.5s, color ease-in-out 1s 0.5s;
49 | transition: color 1s .5s, color 1s .5s;
50 | color: #555;
51 | }
52 | .components img {
53 | opacity: 0;
54 | }
55 | .components.inview {
56 | background-color: #45b7ed;
57 | color: #fff;
58 | }
59 | .components.inview img {
60 | -webkit-animation-name: myBounceInUp;
61 | animation-name: myBounceInUp;
62 | -webkit-animation-duration: 1s;
63 | animation-duration: 1s;
64 | -webkit-animation-fill-mode: both;
65 | animation-fill-mode: both;
66 | }
67 | .features {
68 | background-color: #ddebcf;
69 | -webkit-transition: background 0.5s, background ease-in-out 0.5s;
70 | transition: background .5s, background .5s;
71 | -webkit-transition: color 1s 0.5s, color ease-in-out 1s 0.5s;
72 | transition: color 1s .5s, color 1s .5s;
73 | color: #555;
74 | }
75 | .features img {
76 | opacity: 0;
77 | }
78 | .features.inview {
79 | background-color: #aacc88;
80 | color: #fff;
81 | }
82 | .features.inview img {
83 | -webkit-animation-name: myBounceInUp;
84 | animation-name: myBounceInUp;
85 | -webkit-animation-duration: 1s;
86 | animation-duration: 1s;
87 | -webkit-animation-fill-mode: both;
88 | animation-fill-mode: both;
89 | }
90 | .bootstrap {
91 | background-color: #22ffd7;
92 | -webkit-transition: background 0.5s, background ease-in-out 0.5s;
93 | transition: background .5s, background .5s;
94 | -webkit-transition: color 1s 0.5s, color ease-in-out 1s 0.5s;
95 | transition: color 1s .5s, color 1s .5s;
96 | color: #555;
97 | }
98 | .bootstrap img {
99 | opacity: 0;
100 | }
101 | .bootstrap.inview {
102 | background-color: #00bb99;
103 | color: #fff;
104 | }
105 | .bootstrap.inview img {
106 | -webkit-animation-name: myBounceInUp;
107 | animation-name: myBounceInUp;
108 | -webkit-animation-duration: 1s;
109 | animation-duration: 1s;
110 | -webkit-animation-fill-mode: both;
111 | animation-fill-mode: both;
112 | }
113 | .intro > .sui-container {
114 | text-align: center;
115 | }
116 | h1 {
117 | font-size: 64px;
118 | line-height: 1.5;
119 | }
120 | h2 {
121 | font-size: 48px;
122 | line-height: 1.5;
123 | }
124 | .center {
125 | text-align: center;
126 | }
127 | .brand-intro .sui-lead {
128 | font-size: 24px;
129 | line-height: 2;
130 | }
131 | .btn-lead {
132 | padding: 20px 80px;
133 | font-size: 24px;
134 | }
135 | .btn-wrap {
136 | margin-top: 50px;
137 | }
138 | .details ul {
139 | margin-top: 50px;
140 | }
141 | .details li {
142 | font-size: 18px;
143 | line-height: 2;
144 | }
145 | .bootstrap-logo {
146 | height: 300px;
147 | }
148 |
--------------------------------------------------------------------------------
/js/affix.js:
--------------------------------------------------------------------------------
1 | /* ==========================================================
2 | * bootstrap-affix.js v2.3.2
3 | * http://getbootstrap.com/2.3.2/javascript.html#affix
4 | * ==========================================================
5 | * Copyright 2013 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict";
24 |
25 |
26 | /* AFFIX CLASS DEFINITION
27 | * ====================== */
28 |
29 | var Affix = function (element, options) {
30 | this.options = $.extend({}, $.fn.affix.defaults, options)
31 | this.$window = $(window)
32 | .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
33 | .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
34 | this.$element = $(element)
35 | this.checkPosition()
36 | }
37 |
38 | Affix.prototype.checkPosition = function () {
39 | if (!this.$element.is(':visible')) return
40 |
41 | var scrollHeight = $(document).height()
42 | , scrollTop = this.$window.scrollTop()
43 | , position = this.$element.offset()
44 | , offset = this.options.offset
45 | , offsetBottom = offset.bottom
46 | , offsetTop = offset.top
47 | , reset = 'affix affix-top affix-bottom'
48 | , affix
49 |
50 | if (typeof offset != 'object') offsetBottom = offsetTop = offset
51 | if (typeof offsetTop == 'function') offsetTop = offset.top()
52 | if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
53 |
54 | affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
55 | false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
56 | 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
57 | 'top' : false
58 |
59 | if (this.affixed === affix) return
60 |
61 | this.affixed = affix
62 | this.unpin = affix == 'bottom' ? position.top - scrollTop : null
63 |
64 | this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
65 | }
66 |
67 |
68 | /* AFFIX PLUGIN DEFINITION
69 | * ======================= */
70 |
71 | var old = $.fn.affix
72 |
73 | $.fn.affix = function (option) {
74 | return this.each(function () {
75 | var $this = $(this)
76 | , data = $this.data('affix')
77 | , options = typeof option == 'object' && option
78 | if (!data) $this.data('affix', (data = new Affix(this, options)))
79 | if (typeof option == 'string') data[option]()
80 | })
81 | }
82 |
83 | $.fn.affix.Constructor = Affix
84 |
85 | $.fn.affix.defaults = {
86 | offset: 0
87 | }
88 |
89 |
90 | /* AFFIX NO CONFLICT
91 | * ================= */
92 |
93 | $.fn.affix.noConflict = function () {
94 | $.fn.affix = old
95 | return this
96 | }
97 |
98 |
99 | /* AFFIX DATA-API
100 | * ============== */
101 |
102 | $(window).on('load', function () {
103 | $('[data-spy="affix"]').each(function () {
104 | var $spy = $(this)
105 | , data = $spy.data()
106 |
107 | data.offset = data.offset || {}
108 |
109 | data.offsetBottom && (data.offset.bottom = data.offsetBottom)
110 | data.offsetTop && (data.offset.top = data.offsetTop)
111 |
112 | $spy.affix(data)
113 | })
114 | })
115 |
116 |
117 | }(window.jQuery);
118 |
--------------------------------------------------------------------------------
/docs/templates/msgs.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 提示消息
5 |
6 | block head
7 | style(type="text/css").
8 | code {
9 | display: inline-block;
10 | *display: inline;
11 | *zoom: 1;
12 | padding: 2px 4px;
13 | border: 1px solid #e1e1e8;
14 | font-size: 12px;
15 | }
16 |
17 | block sidebar
18 | +sidebar('msg')
19 | block content
20 |
21 | h1 提示消息
22 |
23 | h2.sui-page-header 设计规范
24 |
25 | div.docs-description
26 | img(src='pictures/docs/msgs.png')
27 |
28 | ul.demo-operations.clearfix
29 | li
30 | a(href='#') 下载psd文件
31 |
32 | h2.sui-page-header 开发者文档
33 |
34 | h2 不同种类
35 |
36 | ul.sui-nav.nav-tabs.nav-large
37 | li.active
38 | a(href='#demo1', data-toggle='tab') 示例
39 | li
40 | a(href='#code1', data-toggle='tab') 代码
41 |
42 | div.tab-content
43 | div.tab-pane.active#demo1
44 | div.bs-docs-example
45 | div.sui-msg.msg-error
46 | div.msg-con
47 | strong 错误
48 | | 辅助信息说明
49 | s.msg-icon
50 |
51 |
52 |
53 | div.sui-msg.msg-stop
54 | div.msg-con
55 | strong 禁止
56 | | 辅助信息说明
57 | s.msg-icon
58 |
59 |
60 |
61 | div.sui-msg.msg-success
62 | div.msg-con
63 | strong 成功
64 | | 辅助信息说明
65 | s.msg-icon
66 |
67 |
68 |
69 | div.sui-msg.msg-warning
70 | div.msg-con
71 | strong 警告
72 | | 辅助信息说明
73 | s.msg-icon
74 |
75 |
76 |
77 | div.sui-msg.msg-notice
78 | div.msg-con
79 | strong 系统
80 | | 辅助信息说明
81 | s.msg-icon
82 |
83 |
84 |
85 | div.sui-msg.msg-tips
86 | div.msg-con
87 | strong 提示
88 | | 辅助信息说明
89 | s.msg-icon
90 |
91 |
92 |
93 | div.sui-msg.msg-info
94 | div.msg-con
95 | strong 提醒
96 | | 辅助信息说明
97 | s.msg-icon
98 |
99 |
100 |
101 | div.sui-msg.msg-question
102 | div.msg-con
103 | strong 疑问
104 | | 辅助信息说明
105 | s.msg-icon
106 |
107 |
108 |
109 | div.tab-pane#code1
110 | pre.prettyprint.linenums(data-target='#demo1>div')
111 |
112 | ul.demo-operations.clearfix
113 | li
114 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
115 |
116 | h2 去边框和底色
117 |
118 | ul.sui-nav.nav-tabs.nav-large
119 | li.active
120 | a(href='#demo6', data-toggle='tab') 示例
121 | li
122 | a(href='#code6', data-toggle='tab') 代码
123 |
124 | div.tab-content
125 | div.tab-pane.active#demo6
126 | div.bs-docs-example
127 | div.sui-msg.msg-naked.msg-error
128 | div.msg-con
129 | strong 错误
130 | | 辅助说明
131 | s.msg-icon
132 |
133 | div.tab-pane#code6
134 | pre.prettyprint.linenums(data-target='#demo6>div')
135 |
136 | ul.demo-operations.clearfix
137 | li
138 | a.copy-btn(href='javascript:void(0)', data-target='#demo6>div') 复制代码
139 |
140 |
141 | h2 带删除按钮
142 |
143 | ul.sui-nav.nav-tabs.nav-large
144 | li.active
145 | a(href='#demo7', data-toggle='tab') 示例
146 | li
147 | a(href='#code7', data-toggle='tab') 代码
148 |
149 | div.tab-content
150 | div.tab-pane.active#demo7
151 | div.bs-docs-example
152 | div.sui-msg.msg-error.msg-block
153 | div.msg-con
154 | strong 错误
155 | | 辅助说明
156 | a.remove
157 | i.msg-icon
158 |
159 | div.tab-pane#code7
160 | pre.prettyprint.linenums(data-target='#demo7>div')
161 |
162 | ul.demo-operations.clearfix
163 | li
164 | a.copy-btn(href='javascript:void(0)', data-target='#demo7>div') 复制代码
165 |
--------------------------------------------------------------------------------
/docs/templates/tab-js.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 标签页
5 |
6 | block sidebar
7 | +sidebar('tab-js')
8 | block content
9 | h1 标签页
10 |
11 | h2.sui-page-header 开发者文档
12 | p.sui-lead
13 | 通过此组件轻松添加动态的标签页切换功能。此文档的标签页切换效果正是通过这个组件实现的。
14 |
15 | h2 1. 通过标记使用
16 |
17 | ul.sui-nav.nav-tabs.nav-large
18 | li.active
19 | a(href='#demo1', data-toggle='tab') 示例
20 | li
21 | a(href='#code1', data-toggle='tab') 代码
22 | li
23 | a(href='#doc1', data-toggle='tab') 文档
24 |
25 | div.tab-content
26 | div.tab-pane.active#demo1
27 | div.bs-docs-example
28 | ul.sui-nav.nav-tabs
29 | li.active
30 | a(href='#index', data-toggle='tab') 首页
31 | li
32 | a(href='#profile', data-toggle='tab') 教程
33 | li
34 | a(href='#about', data-toggle='tab') 关于
35 | div.tab-content
36 | div.tab-pane.active#index
37 | p qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.
38 | div.tab-pane#profile
39 | p Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park
40 | div.tab-pane#about
41 | p Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.
42 | div.tab-pane#code1
43 | pre.prettyprint.linenums(data-target='#demo1>div')
44 | div.tab-pane#doc1
45 | | 通过在tab元素上添加 data-toggle="tab" 或者 data-toggle="pill" 来开启标签切换功能.
46 | | 每一个tab对应的内容区域由tab的 href 或者 data-target 属性来指定。
47 |
48 | ul.demo-operations.clearfix
49 | li
50 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
51 |
52 |
53 | h2 2. 通过js调用
54 |
55 | ul.sui-nav.nav-tabs.nav-large
56 | li.active
57 | a(href='#demo2', data-toggle='tab') 示例
58 | li
59 | a(href='#code2', data-toggle='tab') 代码
60 | li
61 | a(href='#doc2', data-toggle='tab') 文档
62 | li
63 | a(href='#event2', data-toggle='tab') 事件
64 |
65 | div.tab-content
66 |
67 | div.tab-pane.active#demo2
68 | div.bs-docs-example
69 | ul.sui-nav.nav-tabs#tab-demo2
70 | li.active
71 | a(href='#index2') 首页
72 | li
73 | a(href='#profile2') 教程
74 | li
75 | a(href='#about2') 关于
76 | div.tab-content
77 | div.tab-pane.active#index2
78 | p qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.
79 | div.tab-pane#profile2
80 | p Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park
81 | div.tab-pane#about2
82 | p Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.
83 |
84 | script.
85 | $('#tab-demo2 a').click(function (e) {
86 | e.preventDefault();
87 | $(this).tab('show');
88 | })
89 |
90 | div.tab-pane#code2
91 | pre.prettyprint.linenums(data-target='#demo2>div')
92 | div.tab-pane#doc2
93 | | 通过在tab中的a标签上调用 tab("show") 方法来显示此tab对应的内容区域。
94 | | 每一个tab对应的内容区域由tab的 href 或者 data-target 属性来指定。
95 |
96 | div.tab-pane#event2
97 | table.sui-table.table-bordered
98 | tr
99 | th 事件
100 | th 说明
101 |
102 | tr
103 | td show
104 | td 在标签页显示之前触发,在shown事件之前。event.target 和 event.relatedTarget 分别是当前标签和上一个标签。
105 | tr
106 | td shown
107 | td 在标签页显示之后触发,在show事件之后。event.target 和 event.relatedTarget 分别是当前标签和上一个标签。
108 |
109 | ul.demo-operations.clearfix
110 | li
111 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
112 |
--------------------------------------------------------------------------------
/js/tab.js:
--------------------------------------------------------------------------------
1 | /* ========================================================
2 | * bootstrap-tab.js v2.3.2
3 | * http://getbootstrap.com/2.3.2/javascript.html#tabs
4 | * ========================================================
5 | * Copyright 2013 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ======================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict";
24 |
25 |
26 | /* TAB CLASS DEFINITION
27 | * ==================== */
28 |
29 | var Tab = function (element) {
30 | this.element = $(element)
31 | }
32 |
33 | Tab.prototype = {
34 |
35 | constructor: Tab
36 |
37 | , show: function () {
38 | var $this = this.element
39 | , $ul = $this.closest('ul:not(.dropdown-menu)')
40 | , selector = $this.attr('data-target')
41 | , previous
42 | , $target
43 | , e
44 |
45 | if (!selector) {
46 | selector = $this.attr('href')
47 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
48 | }
49 |
50 | if ( $this.parent('li').hasClass('active') ) return
51 |
52 | previous = $ul.find('.active:last a')[0]
53 |
54 | e = $.Event('show', {
55 | relatedTarget: previous
56 | })
57 |
58 | $this.trigger(e)
59 |
60 | if (e.isDefaultPrevented()) return
61 |
62 | $target = $(selector)
63 |
64 | this.activate($this.parent('li'), $ul)
65 | this.activate($target, $target.parent(), function () {
66 | $this.trigger({
67 | type: 'shown'
68 | , relatedTarget: previous
69 | })
70 | })
71 | }
72 |
73 | , activate: function ( element, container, callback) {
74 | var $active = container.find('> .active')
75 | , transition = callback
76 | && $.support.transition
77 | && $active.hasClass('fade')
78 |
79 | function next() {
80 | $active
81 | .removeClass('active')
82 | .find('> .dropdown-menu > .active')
83 | .removeClass('active')
84 |
85 | element.addClass('active')
86 |
87 | if (transition) {
88 | element[0].offsetWidth // reflow for transition
89 | element.addClass('in')
90 | } else {
91 | element.removeClass('fade')
92 | }
93 |
94 | if ( element.parent('.dropdown-menu') ) {
95 | element.closest('li.dropdown').addClass('active')
96 | }
97 |
98 | callback && callback()
99 | }
100 |
101 | transition ?
102 | $active.one($.support.transition.end, next) :
103 | next()
104 |
105 | $active.removeClass('in')
106 | }
107 | }
108 |
109 |
110 | /* TAB PLUGIN DEFINITION
111 | * ===================== */
112 |
113 | var old = $.fn.tab
114 |
115 | $.fn.tab = function ( option ) {
116 | return this.each(function () {
117 | var $this = $(this)
118 | , data = $this.data('tab')
119 | if (!data) $this.data('tab', (data = new Tab(this)))
120 | if (typeof option == 'string') data[option]()
121 | })
122 | }
123 |
124 | $.fn.tab.Constructor = Tab
125 |
126 |
127 | /* TAB NO CONFLICT
128 | * =============== */
129 |
130 | $.fn.tab.noConflict = function () {
131 | $.fn.tab = old
132 | return this
133 | }
134 |
135 |
136 | /* TAB DATA-API
137 | * ============ */
138 |
139 | $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
140 | e.preventDefault()
141 | $(this).tab('show')
142 | })
143 |
144 | }(window.jQuery);
145 |
--------------------------------------------------------------------------------
/js/tests/unit/button.js:
--------------------------------------------------------------------------------
1 | $(function () {
2 |
3 | module("buttons")
4 |
5 | test("should provide no conflict", function () {
6 | var button = $.fn.button.noConflict()
7 | ok(!$.fn.button, 'button was set back to undefined (org value)')
8 | $.fn.button = button
9 | })
10 |
11 | test("should be defined on jquery object", function () {
12 | ok($(document.body).button, 'button method is defined')
13 | })
14 |
15 | test("should return element", function () {
16 | ok($(document.body).button()[0] == document.body, 'document.body returned')
17 | })
18 |
19 | test("should return set state to loading", function () {
20 | var btn = $('')
21 | equal(btn.html(), 'mdo', 'btn text equal mdo')
22 | btn.button('loading')
23 | equal(btn.html(), 'fat', 'btn text equal fat')
24 | stop()
25 | setTimeout(function () {
26 | ok(btn.attr('disabled'), 'btn is disabled')
27 | ok(btn.hasClass('disabled'), 'btn has disabled class')
28 | start()
29 | }, 0)
30 | })
31 |
32 | test("should return reset state", function () {
33 | var btn = $('')
34 | equal(btn.html(), 'mdo', 'btn text equal mdo')
35 | btn.button('loading')
36 | equal(btn.html(), 'fat', 'btn text equal fat')
37 | stop()
38 | setTimeout(function () {
39 | ok(btn.attr('disabled'), 'btn is disabled')
40 | ok(btn.hasClass('disabled'), 'btn has disabled class')
41 | start()
42 | stop()
43 | }, 0)
44 | btn.button('reset')
45 | equal(btn.html(), 'mdo', 'btn text equal mdo')
46 | setTimeout(function () {
47 | ok(!btn.attr('disabled'), 'btn is not disabled')
48 | ok(!btn.hasClass('disabled'), 'btn does not have disabled class')
49 | start()
50 | }, 100)
51 | })
52 |
53 | test("should toggle active", function () {
54 | var btn = $('')
55 | ok(!btn.hasClass('active'), 'btn does not have active class')
56 | btn.button('toggle')
57 | ok(btn.hasClass('active'), 'btn has class active')
58 | })
59 |
60 | test("should toggle active when btn children are clicked", function () {
61 | var btn = $('')
62 | , inner = $('')
63 | btn
64 | .append(inner)
65 | .appendTo($('#qunit-fixture'))
66 | ok(!btn.hasClass('active'), 'btn does not have active class')
67 | inner.click()
68 | ok(btn.hasClass('active'), 'btn has class active')
69 | })
70 |
71 | test("should toggle active when btn children are clicked within btn-group", function () {
72 | var btngroup = $('')
73 | , btn = $('')
74 | , inner = $('')
75 | btngroup
76 | .append(btn.append(inner))
77 | .appendTo($('#qunit-fixture'))
78 | ok(!btn.hasClass('active'), 'btn does not have active class')
79 | inner.click()
80 | ok(btn.hasClass('active'), 'btn has class active')
81 | })
82 |
83 | test("should check for closest matching toggle", function () {
84 | var group = $("")
85 | , btn1 = $("")
86 | , btn2 = $("")
87 | , wrap = $("")
88 |
89 | wrap.append(btn1, btn2)
90 |
91 | group
92 | .append(wrap)
93 | .appendTo($('#qunit-fixture'))
94 |
95 | ok(btn1.hasClass('active'), 'btn1 has active class')
96 | ok(!btn2.hasClass('active'), 'btn2 does not have active class')
97 | btn2.click()
98 | ok(!btn1.hasClass('active'), 'btn1 does not have active class')
99 | ok(btn2.hasClass('active'), 'btn2 has active class')
100 | })
101 |
102 | })
103 |
--------------------------------------------------------------------------------
/js/validate-rules.js:
--------------------------------------------------------------------------------
1 | // add rules
2 | !function($) {
3 | Validate = $.validate;
4 | trim = function(v) {
5 | if (!v) return v;
6 | return v.replace(/^\s+/g, '').replace(/\s+$/g, '')
7 | };
8 | var required = function(value, element, param) {
9 | var $input = $(element)
10 | return !!trim(value);
11 | };
12 | var requiredMsg = function ($input, param) {
13 | var getWord = function($input) {
14 | var tagName = $input[0].tagName.toUpperCase();
15 | var type = $input[0].type.toUpperCase();
16 | if ( type == 'CHECKBOX' || type == 'RADIO' || tagName == 'SELECT') {
17 | return '选择'
18 | }
19 | return '填写'
20 | }
21 | return "请" + getWord($input)
22 | }
23 | Validate.setRule("required", required, requiredMsg);
24 |
25 | var prefill = function(value, element, param) {
26 | var $input = $(element)
27 | if (param && typeof param === typeof 'a') {
28 | var $form = $input.parents("form")
29 | var $required = $form.find("[name='"+param+"']")
30 | return !!$required.val()
31 | }
32 | return true
33 | }
34 | Validate.setRule("prefill", prefill, function($input, param) {
35 | var getWord = function($input) {
36 | var tagName = $input[0].tagName.toUpperCase();
37 | var type = $input[0].type.toUpperCase();
38 | if ( type == 'CHECKBOX' || type == 'RADIO' || tagName == 'SELECT') {
39 | return '选择'
40 | }
41 | return '填写'
42 | }
43 | if (param && typeof param === typeof 'a') {
44 | var $form = $input.parents("form")
45 | var $required = $form.find("[name='"+param+"']")
46 | if (!$required.val()) {
47 | return "请先" + getWord($required) + ($required.attr("title") || $required.attr("name"))
48 | }
49 | }
50 | return '错误'
51 | });
52 | var match = function(value, element, param) {
53 | value = trim(value);
54 | return value == $(element).parents('form').find("[name='"+param+"']").val()
55 | };
56 | Validate.setRule("match", match, '必须与$0相同');
57 | var number = function(value, element, param) {
58 | value = trim(value);
59 | return (/^\d+(.\d*)?$/).test(value)
60 | };
61 | Validate.setRule("number", number, '请输入数字');
62 | var digits = function(value, element, param) {
63 | value = trim(value);
64 | return (/^\d+$/).test(value)
65 | };
66 | Validate.setRule("digits", digits, '请输入整数');
67 | var mobile = function(value, element, param) {
68 | return (/^0?1[3|4|5|7|8][0-9]\d{8,9}$/).test(trim(value));
69 | };
70 | Validate.setRule("mobile", mobile, '请填写正确的手机号码');
71 | var tel = function(value, element, param) {
72 | return (/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,11})+$/).test(trim(value));
73 | };
74 | Validate.setRule("tel", tel, '请填写正确的电话号码');
75 | var email = function(value, element, param) {
76 | return (/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/).test(trim(value)); //"
77 | };
78 | Validate.setRule("email", email, '请填写正确的email地址');
79 | var zip = function(value, element, param) {
80 | return (/^[1-9][0-9]{5}$/).test(trim(value));
81 | };
82 | Validate.setRule("zip", zip, '请填写正确的邮编');
83 | var date = function(value, element, param) {
84 | return (/^[1|2]\d{3}-[0-2][0-9]-[0-3][0-9]$/).test(trim(value));
85 | };
86 | Validate.setRule("date", date, '请填写正确的日期');
87 | var url = function(value, element, param) {
88 | var urlPattern;
89 | value = trim(value);
90 | urlPattern = /(http|ftp|https):\/\/([\w-]+\.)?[\w-]+\.(com|net|cn|org|me|io|info)/;
91 | if (!/^http/.test(value)) {
92 | value = 'http://' + value;
93 | }
94 | return urlPattern.test(value);
95 | };
96 | Validate.setRule("url", url, '请填写正确的网址');
97 | var minlength = function(value, element, param) {
98 | return trim(value).length >= param;
99 | };
100 | Validate.setRule("minlength", minlength, '长度不能少于$0');
101 | var maxlength = function(value, element, param) {
102 | return trim(value).length <= param;
103 | };
104 | Validate.setRule("maxlength", maxlength, '长度不能超过$0');
105 | }(window.jQuery)
106 |
--------------------------------------------------------------------------------
/less/progress-bars.less:
--------------------------------------------------------------------------------
1 | //
2 | // Progress bars
3 | // --------------------------------------------------
4 |
5 |
6 | // ANIMATIONS
7 | // ----------
8 |
9 | // Webkit
10 | @-webkit-keyframes progress-bar-stripes {
11 | from { background-position: 40px 0; }
12 | to { background-position: 0 0; }
13 | }
14 |
15 | // Firefox
16 | @-moz-keyframes progress-bar-stripes {
17 | from { background-position: 40px 0; }
18 | to { background-position: 0 0; }
19 | }
20 |
21 | // IE9
22 | @-ms-keyframes progress-bar-stripes {
23 | from { background-position: 40px 0; }
24 | to { background-position: 0 0; }
25 | }
26 |
27 | // Opera
28 | @-o-keyframes progress-bar-stripes {
29 | from { background-position: 0 0; }
30 | to { background-position: 40px 0; }
31 | }
32 |
33 | // Spec
34 | @keyframes progress-bar-stripes {
35 | from { background-position: 40px 0; }
36 | to { background-position: 0 0; }
37 | }
38 |
39 |
40 |
41 | // THE BARS
42 | // --------
43 |
44 | // Outer container
45 | .sui-progress {
46 | overflow: hidden;
47 | height: @baseLineHeight + 12px;
48 | margin-bottom: @baseMargin;
49 | background-color: #eee;
50 | .border-radius(@baseBorderRadius);
51 | border: none;
52 | position: relative;
53 |
54 | // Bar of progress
55 | .bar {
56 | width: 0%;
57 | height: 100%;
58 | padding: 6px 0;
59 | padding-left: 0;
60 | padding-right: 0;
61 | color: @white;
62 | float: left;
63 | font-size: 12px;
64 | text-align: center;
65 | text-shadow: 0 -1px 0 rgba(0,0,0,.25);
66 | background-color: @progressColor;
67 | .box-sizing(border-box);
68 | .transition(width .6s ease);
69 | }
70 |
71 | .bar-text {
72 | position: absolute;
73 | color: @textColor;
74 | text-align: center;
75 | width: 100%;
76 | padding: 2px 0;
77 | }
78 |
79 | //不同大小
80 | &.progress-small {
81 | height: @baseLineHeight;
82 | line-height: @baseLineHeight;
83 | font-size: @fontSizeSmall;
84 |
85 | .bar,
86 | .bar-text
87 | {
88 | padding: 0;
89 | }
90 | }
91 | &.progress-large {
92 | height: @lineHeightLarge + 14px;
93 | line-height: @lineHeightLarge;
94 | font-size: @fontSizeLarge;
95 | .bar {
96 | padding: 8px 0;
97 | }
98 | }
99 | &.progress-xlarge {
100 | height: @lineHeightXLarge + 14px;
101 | line-height: @lineHeightXLarge;
102 | font-size: @fontSizeXLarge;
103 | .bar {
104 | padding: 8px 0;
105 | }
106 | }
107 | }
108 |
109 | // Striped bars
110 | .progress-striped .bar {
111 | #gradient > .striped(@progressColor);
112 | .background-size(40px 40px);
113 | }
114 |
115 | // Call animation for the active one
116 | .sui-progress.active .bar {
117 | -webkit-animation: progress-bar-stripes 2s linear infinite;
118 | -moz-animation: progress-bar-stripes 2s linear infinite;
119 | -ms-animation: progress-bar-stripes 2s linear infinite;
120 | -o-animation: progress-bar-stripes 2s linear infinite;
121 | animation: progress-bar-stripes 2s linear infinite;
122 | }
123 |
124 |
125 |
126 | // COLORS
127 | // ------
128 |
129 | // Danger (red)
130 | .progress-danger .bar, .sui-progress .bar-danger {
131 | background-color: @progressDangerColor;
132 | }
133 | .progress-danger.progress-striped .bar, .progress-striped .bar-danger {
134 | #gradient > .striped(@progressDangerColor);
135 | }
136 |
137 | // Success (green)
138 | .progress-success .bar, .sui-progress .bar-success {
139 | background-color: @progressSuccessColor;
140 | }
141 | .progress-success.progress-striped .bar, .progress-striped .bar-success {
142 | #gradient > .striped(@progressSuccessColor);
143 | }
144 |
145 | // Info (teal)
146 | .progress-info .bar, .sui-progress .bar-info {
147 | background-color: @progressInfoColor;
148 | }
149 | .progress-info.progress-striped .bar, .progress-striped .bar-info {
150 | #gradient > .striped(@progressInfoColor);
151 | }
152 |
153 | // Warning (orange)
154 | .progress-warning .bar, .sui-progress .bar-warning {
155 | background-color: @progressWarningColor;
156 | }
157 | .progress-warning.progress-striped .bar, .progress-striped .bar-warning {
158 | #gradient > .striped(@progressWarningColor);
159 | }
160 |
--------------------------------------------------------------------------------
/docs/templates/tab.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 标签页
5 |
6 | block sidebar
7 | +sidebar('tab')
8 |
9 | block content
10 |
11 | h1 标签页
12 |
13 | h2.sui-page-header 设计规范
14 |
15 | div.docs-description
16 | img(src='pictures/docs/tab.png')
17 |
18 | ul.demo-operations.clearfix
19 | li
20 | a(href='#') 下载psd文件
21 |
22 | h2.sui-page-header 开发者文档
23 |
24 | p.sui-lead
25 | | 三种不同大小的标签页,可以当做静态组件使用,引入js之后可以做动态的切换。
26 |
27 | h2 默认标签页
28 | ul.sui-nav.nav-tabs.nav-large
29 | li.active
30 | a(href='#demo1', data-toggle='tab') 示例
31 | li
32 | a(href='#code1', data-toggle='tab') 代码
33 | li
34 | a(href='#doc1', data-toggle='tab') 文档
35 | div.tab-content
36 | div.tab-pane.active#demo1
37 | div.bs-docs-example
38 | ul.sui-nav.nav-tabs
39 | li.active
40 | a 标签一
41 | li
42 | a(href='#') 标签二
43 | li
44 | a(href='#') 标签二
45 |
46 |
47 | h3 垂直
48 | ul.sui-nav.nav-tabs.nav-large.tab-vertical
49 | li
50 | a 语文
51 | li.active
52 | a(href='#') 数学
53 | li
54 | a(href='#') 英语
55 |
56 | div.tab-pane#code1
57 | pre.prettyprint.linenums(data-target='#demo1>div')
58 | div.tab-pane#doc1
59 | | 有三种尺寸: default, .nav-large, .nav-tabs-xlarge。通过在 li 标签上添加 .active 可以指定当前高亮的tab。
60 | | 默认标签页是静态的,如果需要动态的标签页可以参考这里 js 标签页
61 |
62 | ul.demo-operations.clearfix
63 | li
64 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>div') 复制代码
65 |
66 |
67 |
68 | h2 首要标签页
69 | ul.sui-nav.nav-tabs.nav-large
70 | li.active
71 | a(href='#demo2', data-toggle='tab') 示例
72 | li
73 | a(href='#code2', data-toggle='tab') 代码
74 | li
75 | a(href='#doc2', data-toggle='tab') 文档
76 | div.tab-content
77 | div.tab-pane.active#demo2
78 | div.bs-docs-example
79 | ul.sui-nav.nav-tabs.nav-primary
80 | li.active
81 | a 标签一
82 | li
83 | a(href='#') 标签二
84 | li
85 | a(href='#') 标签二
86 |
87 | h3 垂直
88 | ul.sui-nav.nav-tabs.nav-primary.nav-large.tab-vertical
89 | li
90 | a 标签一
91 | li.active
92 | a(href='#') 标签二
93 | li
94 | a(href='#') 标签二
95 | div.tab-pane#code2
96 | pre.prettyprint.linenums(data-target='#demo2>div')
97 | div.tab-pane#doc2
98 | | 首要标签页,添加 nav-primary
99 |
100 | ul.demo-operations.clearfix
101 | li
102 | a.copy-btn(href='javascript:void(0)', data-target='#demo2>div') 复制代码
103 |
104 | h2 纯文字
105 | ul.sui-nav.nav-tabs.nav-large
106 | li.active
107 | a(href='#demo3', data-toggle='tab') 示例
108 | li
109 | a(href='#code3', data-toggle='tab') 代码
110 | div.tab-content
111 | div.tab-pane.active#demo3
112 | div.bs-docs-example
113 | ul.sui-nav.nav-tabs.tab-light
114 | li.active
115 | a 标签一
116 | li
117 | a(href='#') 标签二
118 | li
119 | a(href='#') 标签二
120 |
121 | h3 垂直
122 | ul.sui-nav.nav-tabs.tab-light.tab-vertical
123 | li
124 | a 前端
125 | li.active
126 | a(href='#') 后端
127 | li
128 | a(href='#') 运维
129 |
130 | div.tab-pane#code3
131 | pre.prettyprint.linenums(data-target='#demo3>div')
132 |
133 | ul.demo-operations.clearfix
134 | li
135 | a.copy-btn(href='javascript:void(0)', data-target='#demo3>div') 复制代码
136 |
137 | h2 带背景
138 | ul.sui-nav.nav-tabs.nav-large
139 | li.active
140 | a(href='#demo4', data-toggle='tab') 示例
141 | li
142 | a(href='#code4', data-toggle='tab') 代码
143 | div.tab-content
144 | div.tab-pane.active#demo4
145 | div.bs-docs-example
146 | ul.sui-nav.nav-tabs.tab-dark
147 | li.active
148 | a 标签一
149 | i.sui-icon
150 | li
151 | a(href='#') 标签二
152 | li
153 | a(href='#') 标签二
154 |
155 | h3 垂直
156 | ul.sui-nav.nav-tabs.tab-dark.tab-vertical
157 | li
158 | a 前端
159 | li
160 | a(href='#') 后端
161 | li.active
162 | a(href='#') 运维
163 | div.tab-pane#code4
164 | pre.prettyprint.linenums(data-target='#demo4>div')
165 |
166 | ul.demo-operations.clearfix
167 | li
168 | a.copy-btn(href='javascript:void(0)', data-target='#demo4>div') 复制代码
169 |
--------------------------------------------------------------------------------
/docs/templates/checkbox.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title 选框
5 |
6 | block sidebar
7 | +sidebar('checkbox')
8 |
9 | block content
10 |
11 | h1 单选框和复选框
12 |
13 | h2.sui-page-header 开发者文档
14 |
15 | p.sui-lead
16 | | 这是js重写的选框组件,兼容ie8+。但是使用此组件必须引入sui.js。此组件内部依然通过原生的checkbox和radio来实现,所以不会影响原生的表单操作。
17 | br
18 | | 注意,在使用此组件的时候不要通过直接修改input的方式来操作,而是通过checkbox api来调用。
19 |
20 | h2 通过data-api使用
21 |
22 | ul.sui-nav.nav-tabs.nav-large
23 | li.active
24 | a(href='#demo1', data-toggle='tab') 示例
25 | li
26 | a(href='#code1', data-toggle='tab') 代码
27 | li
28 | a(href='#doc1', data-toggle='tab') 文档
29 |
30 |
31 | div.tab-content
32 | div.tab-pane.active#demo1
33 | form.sui-form
34 | h3 复选框
35 | label.checkbox-pretty.inline.checked(data-toggle='checkbox')
36 | input(type='checkbox' checked='checked')
37 | span 鸣人
38 |
39 | label.checkbox-pretty.inline(data-toggle='checkbox')
40 | input(type='checkbox')
41 | span 佐助
42 |
43 | h3 单选框
44 | label.radio-pretty.inline.checked(data-toggle='radio')
45 | input(type='radio' checked='checked' name='radio')
46 | span 服装
47 |
48 | label.radio-pretty.inline(data-toggle='radio')
49 | input(type='radio' name='radio')
50 | span 电器
51 | label.radio-pretty.inline(data-toggle='radio')
52 | input(type='radio' name='radio')
53 | span 美食
54 |
55 | h3 半选
56 | label.checkbox-pretty.inline.halfchecked(data-toggle='radio')
57 | input(type='checkbox')
58 | span 半选
59 |
60 | h3 禁用
61 | label.checkbox-pretty.inline.checked.disabled(data-toggle='radio')
62 | input(type='checkbox' checked='checked' disabled)
63 | span 不可选
64 |
65 |
66 | div.tab-pane#code1
67 | pre.prettyprint.linenums(data-target='#demo1')
68 | div.tab-pane#doc1
69 | p
70 | | 通过添加 data-toggle='checobox' 或者 data-toggle='radio' 来启用。
71 | p
72 | | 在初始化的时候同时设置好input的属性和label的class,否则在js加载之后可能会闪一下或者会出现状态不一致。
73 |
74 |
75 | ul.demo-operations.clearfix
76 | li
77 | a.copy-btn(href='javascript:void(0)', data-target='#demo1>form') 复制代码
78 |
79 | h2 通过JS调用
80 |
81 | ul.sui-nav.nav-tabs.nav-large
82 | li.active
83 | a(href='#demo2', data-toggle='tab') 示例
84 | li
85 | a(href='#code2', data-toggle='tab') 代码
86 | li
87 | a(href='#doc2', data-toggle='tab') 文档
88 | li
89 | a(href='#api2', data-toggle='tab') API
90 |
91 |
92 | div.tab-content
93 | div.tab-pane.active#demo2
94 | form.sui-form
95 | h3 复选框
96 | label.checkbox-pretty.inline.checked#checkbox2(data-toggle='checkbox')
97 | input(type='checkbox' checked='checked')
98 | span 选项一
99 | div.op.sui-btn-group(style='display:block;margin-top: 15px;')
100 | a.sui-btn.btn-primary(name='check' href='javascript:void(0);') 选中
101 | a.sui-btn.btn-primary(name='uncheck' href='javascript:void(0);') 取消
102 | a.sui-btn.btn-primary(name='halfcheck' href='javascript:void(0);') 半选
103 | a.sui-btn.btn-primary(name='toggle' href='javascript:void(0);') toggle
104 | a.sui-btn.btn-primary(name='disable' href='javascript:void(0);') disable
105 | a.sui-btn.btn-primary(name='enable' href='javascript:void(0);') enable
106 | script.
107 | var $checkbox = $("#checkbox2").checkbox()
108 | $(".op").on("click", "a", function(e){
109 | var $a = $(e.currentTarget);
110 | $checkbox.checkbox($a.attr("name"))
111 | })
112 |
113 | div.tab-pane#code2
114 | pre.prettyprint.linenums(data-target='#demo2')
115 | div.tab-pane#doc2
116 | ul.unstyled
117 | li 要把checkbox当做一个组件来用,不要通过js直接修改input的属性,要通过checkbox api来调用。
118 | li 禁用状态会禁止用户的操作,但是不会禁止通过api来修改状态。
119 | li 半选状态其实就是未选中,所以不会向后台提交。
120 | div.tab-pane#api2
121 | table.sui-table
122 | thead
123 | tr
124 | th 方法
125 | th 说明
126 | tbody
127 | tr
128 | td check
129 | td 选中
130 | tr
131 | td uncheck
132 | td 取消选中
133 | tr
134 | td halfcheck
135 | td 半选
136 | tr
137 | td disable
138 | td 禁用
139 | tr
140 | td enable
141 | td 启用
142 |
143 | ul.demo-operations.clearfix
144 | li
145 | a.copy-btn(href='javascript:void(0)', data-target='#demo2>form') 复制代码
146 |
147 |
--------------------------------------------------------------------------------
/less/timepicker.less:
--------------------------------------------------------------------------------
1 | .timepicker {
2 | width: 100px;
3 | height: 228px;
4 | //border: 1px solid #ddd;
5 | position: relative;
6 | padding: 12px 20px;
7 | background: #fff;
8 | .clearfix();
9 | .picker-wrap {
10 | width: 40px;
11 | overflow: hidden;
12 | float: left;
13 | position: relative;
14 | z-index: 1
15 | }
16 | .picker-wrap:first-child {
17 | margin-right: 20px
18 | }
19 | .picker-btn {
20 | display: block;
21 | width: 50%;
22 | height: 27px;
23 | line-height: 25px;
24 | margin: 0 auto;
25 | text-align: center;
26 | position: relative;
27 | @top: 0px;
28 | .arrow,.arrow-bg{
29 | width: 0;
30 | height: 0;
31 | display: inline-block;
32 | position: absolute;
33 | left: 3px;
34 | }
35 | .arrow{
36 | border: 7px solid #bbb;
37 | }
38 | .arrow-bg{
39 | border: 7px solid #fff;
40 | }
41 | &.up{
42 | @top:0px;
43 | .arrow,.arrow-bg{
44 | border-left-color: transparent;
45 | border-top-color: transparent;
46 | border-right-color: transparent;
47 | }
48 | .arrow{
49 | top: @top;
50 | }
51 | .arrow-bg{
52 | top: @top + 1;
53 | }
54 | }
55 | &.down{
56 | @bottom: 0px;
57 | .arrow,.arrow-bg{
58 | border-left-color: transparent;
59 | border-right-color: transparent;
60 | border-bottom-color: transparent;
61 | }
62 | .arrow{
63 | bottom: @bottom;
64 | }
65 | .arrow-bg{
66 | bottom: @bottom + 1;
67 | }
68 | }
69 | }
70 | .picker-con {
71 | width: 100%;
72 | height: 174px;
73 | overflow: hidden;
74 | position: relative;
75 | // border: 1px solid red;
76 | .picker-innercon {
77 | position: absolute;
78 | top: 0;
79 | left: 0;
80 | width: 100%;
81 | -webkit-transition: .5s;
82 | transition: .5s;
83 | -webkit-touch-callout: none;
84 | -webkit-user-select: none;
85 | -khtml-user-select: none;
86 | -moz-user-select: none;
87 | -ms-user-select: none;
88 | user-select: none;
89 | }
90 | span {
91 | display: block;
92 | height: 35px;
93 | width: 100%;
94 | text-align: center;
95 | line-height: 35px;
96 | cursor: pointer;
97 | color: #bbb;
98 | &.current {
99 | color: #000;
100 | font-size: 16px
101 | }
102 | }
103 | }
104 | .timePicker-split {
105 | position: absolute;
106 | left: 20px;
107 | top: 50%;
108 | margin-top: -15px;
109 | height: 30px;
110 | width: 100px;
111 | z-index: 0;
112 | .hour-input,
113 | .minute-input{
114 | width: 38px;
115 | height: 28px;
116 | border: 1px solid #ececec;
117 | float: left;
118 | background: #f9f9f9;
119 | }
120 | .split-icon {
121 | width: 20px;
122 | height: 30px;
123 | line-height: 30px;
124 | float: left;
125 | text-align: center;
126 | color: #000;
127 | }
128 | }
129 | &.dropdown-menu{
130 | position: absolute;
131 | top: 0;
132 | left: 0;
133 | z-index: @zindexDropdown;
134 | float: left;
135 | display: none; // none by default, but block on "open" of the menu
136 | list-style: none;
137 | /* padding: 0;*/
138 | background-color: @dropdownBackground;
139 | border: 1px solid #ccc;
140 | border: 1px solid rgba(0,0,0,.2);
141 | .border-radius(0px);
142 | .box-shadow(0 5px 10px rgba(0,0,0,.2));
143 | -webkit-background-clip: padding-box;
144 | -moz-background-clip: padding;
145 | background-clip: padding-box;
146 | *border-right-width: 2px;
147 | *border-bottom-width: 2px;
148 |
149 | // Normally inherited from bootstrap's `body`
150 | color: #333333;
151 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
152 | font-size:13px;
153 | line-height: @baseLineHeight;
154 | }
155 | }
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | var exec = require("child_process").exec;
4 |
5 | module.exports = function(grunt) {
6 | 'use strict';
7 | grunt.initConfig({
8 | pkg: grunt.file.readJSON('package.json'),
9 | banner: '/*dpl started*/',
10 | distRoot: grunt.option('target') || '.package',
11 | docsRoot: 'docs',
12 |
13 | jshint: {
14 | options: {
15 | jshintrc: 'js/.jshintrc'
16 | },
17 | gruntfile: {
18 | src: 'Gruntfile.js'
19 | },
20 | src: {
21 | src: ['js/*.js']
22 | },
23 | test: {
24 | src: ['js/tests/unit/*.js']
25 | }
26 | },
27 | browserify: {
28 | build: {
29 | files: {
30 | '<%= distRoot %>/js/<%= pkg.name %>.js': ['js/<%= pkg.name %>.js'],
31 | }
32 | }
33 | },
34 |
35 | uglify: {
36 | build: {
37 | options: {
38 | sourceMap: true
39 | },
40 | files: [{
41 | expand: true,
42 | cwd: '<%= distRoot %>/js/',
43 | src: ['**/*.js', '!*.min.js'],
44 | dest: '<%= distRoot %>/js/',
45 | ext: '.min.js'
46 | }]
47 | }
48 | },
49 |
50 | less: {
51 | options: {
52 | compile: true
53 | },
54 | sui: {
55 | src: ['less/<%= pkg.name %>.less'],
56 | dest: '<%= distRoot %>/css/<%= pkg.name %>.css'
57 | },
58 | suiMin: {
59 | options: {
60 | compress: true
61 | },
62 | src: ['less/<%= pkg.name %>.less'],
63 | dest: '<%= distRoot %>/css/<%= pkg.name %>.min.css'
64 | },
65 |
66 | docs: {
67 | files: [{
68 | expand: true,
69 | cwd: '<%= docsRoot %>/assets/less/',
70 | src: ['**/*.less'],
71 | dest: '<%= docsRoot %>/assets/css/',
72 | ext: '.css'
73 | }]
74 | }
75 | },
76 | jade: {
77 | docs: {
78 | options: {
79 | pretty: true
80 | },
81 | files: [
82 | {
83 | expand: true,
84 | cwd: '<%= docsRoot %>/templates',
85 | src: ['**/*.jade', '!base.jade', '!sidenav.jade', '!header.jade', '!com-*', '!*-com.jade', '!discuss.jade', '!foot.jade', '!head.jade'],
86 | dest: '<%= docsRoot %>',
87 | ext: '.html'
88 | },
89 | ],
90 | }
91 | },
92 | copy: {
93 | fonts: {
94 | files: [
95 | { expand: true, src: ['./fonts/*'], dest: '<%= distRoot %>/' },
96 | ]
97 | }
98 | },
99 | /*
100 | qunit: {
101 | options: {
102 | inject: 'js/tests/unit/phantom.js'
103 | },
104 | files: ['js/tests/*.html']
105 | },
106 | */
107 |
108 | connect: {
109 | server: {
110 | options: {
111 | port: 3000,
112 | base: '.'
113 | }
114 | }
115 | },
116 |
117 | watch: {
118 | options: {
119 | livereload: 3456
120 | },
121 | css: {
122 | files: 'less/*.less',
123 | tasks: ['less:sui', 'newer:copy']
124 | },
125 | js: {
126 | files: 'js/*.js',
127 | tasks: ['browserify', 'newer:copy']
128 | },
129 | docs: {
130 | files: '<%= docsRoot %>/templates/**/*.jade',
131 | tasks: ['newer:jade:docs']
132 | },
133 | docsCss: {
134 | files: '<%= docsRoot %>/assets/less/**/*.less',
135 | tasks: ['newer:less:docs']
136 | }
137 | }
138 | });
139 |
140 |
141 | // These plugins provide necessary tasks.
142 | grunt.loadNpmTasks('grunt-contrib-connect');
143 | grunt.loadNpmTasks('grunt-contrib-copy');
144 | grunt.loadNpmTasks('grunt-contrib-jade');
145 | grunt.loadNpmTasks('grunt-contrib-jshint');
146 | grunt.loadNpmTasks('grunt-contrib-watch');
147 | grunt.loadNpmTasks('grunt-browserify');
148 | grunt.loadNpmTasks('grunt-contrib-less');
149 | grunt.loadNpmTasks('grunt-contrib-uglify');
150 | grunt.loadNpmTasks('grunt-newer');
151 | // Test task.
152 | grunt.registerTask('test', ['jshint']);
153 |
154 | // JS distribution task.
155 | grunt.registerTask('dist-js', ['browserify', 'uglify']);
156 |
157 | // CSS distribution task.
158 | grunt.registerTask('dist-css', ['less']);
159 |
160 | // CSS distribution task.
161 | grunt.registerTask('dist-fonts', ['copy:fonts']);
162 |
163 | // Full distribution task.
164 | grunt.registerTask('dist', ['dist-css', 'dist-js', 'dist-fonts']);
165 | grunt.registerTask('docs', ['jade']); //必须先执行dist才能执行此任务
166 |
167 | // Default task.
168 | grunt.registerTask('default', ['test', 'dist', 'docs']);
169 | //local server and watch
170 | grunt.registerTask('local',['connect','watch']);
171 | }
172 |
--------------------------------------------------------------------------------
/less/tests/forms.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | sui, from Twitter
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/docs/templates/tree-js.jade:
--------------------------------------------------------------------------------
1 | extends base
2 |
3 | block title
4 | title TREE 级联选择
5 |
6 | block head
7 | style.
8 | .bs-docs-example{font-size:12px;}
9 | .sui-tree-group > select + select{margin-left:5px;}
10 |
11 | block sidebar
12 | +sidebar('tree-js')
13 |
14 | block content
15 | h1 级联选择
16 |
17 | h2.sui-page-header 开发者文档
18 |
19 | p.docs
20 | | 根据给定的数据生成下拉框,并且能够级联选择,并取到相应的数据。
21 | | 修改日志:由原来的一次性获取所有数据改为只获取第一级数据,后面的数据在选中某个节点后获取,并且移除了source参数
22 |
23 | h1 1. select,通过标记自动初始化
24 |
25 | ul.sui-nav.nav-tabs.nav-large
26 | li.active
27 | a(href='#demo1', data-toggle='tab') 示例
28 | li
29 | a(href='#code1', data-toggle='tab') 代码
30 | li
31 | a(href='#doc1', data-toggle='tab') 文档
32 | li
33 | a(href='#api1', data-toggle='tab') API
34 |
35 | div.tab-content
36 | .tab-pane.active#demo1
37 | .bs-docs-example
38 | form.sui-form
39 | .sui-tree-group(data-toggle='tree', data-src='http://10.68.111.150/php/demo/server/getCity.json', data-jsonp='true')
40 | .tab-pane#code1
41 | pre.prettyprint.linenums(data-target='#demo1>div')
42 | .tab-pane#doc1
43 | | data-toggle='tree'通过在元素上加此属性自动初始化,并生成第一个select,必须在初始化之前指定数据源
44 | | data-src="url" 通过ajax或jsonp方式获取数据的url
45 | | data-jsonp="true" 为true表示src的url为垮域请求,会以jsonp的形式发送
46 | | data-val="[x,y,z]" 初始化的时候的初始值,注意xyz的值必须要能在srouce对象中找到
47 | .tab-pane#api1
48 | | $(element).data('tree').datas,element为data-toggle='tree'的元素,获取当前的值对象,格式为{value : [], option : []},value代表select的value值,option表示显示的option的文字
49 | | $(element).tree('setValue', [x,y,z]) 设置tree的值,参数同初始化的data-val相同
50 | h1 2. select,通过js调用初始化
51 |
52 | ul.sui-nav.nav-tabs.nav-large
53 | li.active
54 | a(href='#demo2', data-toggle='tab') 示例
55 | li
56 | a(href='#code2', data-toggle='tab') 代码
57 | li
58 | a(href='#doc2', data-toggle='tab') 文档
59 | li
60 | a(href='#api2', data-toggle='tab') API
61 |
62 | .tab-content
63 | .tab-pane.active#demo2
64 | .bs-docs-example
65 | .sui-tree-group.sui-form#treeGroup2
66 | script.
67 | $(function() {
68 | $('#treeGroup2').tree({
69 | src : 'http://10.68.111.150/php/demo/server/getCategory.json',
70 | placeholder : '-- 请选择 --',
71 | val : [2, 148, 152],
72 | jsonp : true
73 | });
74 | })
75 | .tab-pane#code2
76 | pre.prettyprint.linenums(data-target='#demo2>div')
77 | .tab-pane#doc2
78 | | 手动调用tree方法,并传入参数
79 | | 返回数据的格式:
80 | pre.prettyprint.
81 | {
82 | "code" : 200, // 代表请求成功
83 | "data" : [
84 | {
85 | "id" : "id", // id值,用于option的value
86 | "value" : "value", // 显示的内容,用于option的text
87 | "parent" : "parent", // 父节点的id,暂无用途
88 | "isleaf" : "false", // 是否是叶结点,如果为false,则选中此项的时候会根据id获取子节点的数据
89 | },
90 | {...},
91 | ...
92 | ]
93 | }
94 | .tab-pane#api2
95 | table.sui-table.table-bordered
96 | thead
97 | tr
98 | th(style="width:100px") 名称
99 | th(style="width:50px") 类型
100 | th(style="width:50px") 默认值
101 | th 描述
102 | tbody
103 | tr
104 | td src
105 | td string
106 | td null
107 | td 通过ajax获取数据的url
108 | tr
109 | td jsonp
110 | td boolean
111 | td false
112 | td 表示src请求是一个jsonp请求
113 | tr
114 | td key
115 | td string
116 | td "id"
117 | td 发送请求时获取数据的参数名,默认为id
118 | tr
119 | td placeholder
120 | td string
121 | td "请选择"
122 | td 默认的第一个option,可以传null或空串,则不会出现默认的option
123 | tr
124 | td val
125 | td Array
126 | td []
127 | td 初始化的值,是一个数组,里面的值是option的value值
128 |
--------------------------------------------------------------------------------