├── tests ├── tests-syntax │ ├── tests.css │ ├── color │ │ ├── _core.scss │ │ ├── _color.scss │ │ ├── _complementary.scss │ │ ├── _analogous.scss │ │ ├── _triad.scss │ │ ├── _adjacent.scss │ │ ├── _split-complementary.scss │ │ ├── _square.scss │ │ ├── _rectangle.scss │ │ └── _contrast.scss │ ├── layout │ │ ├── _container.scss │ │ ├── _layout.scss │ │ └── _grid.scss │ ├── utilities │ │ ├── _list-get-max.scss │ │ ├── _list-remove.scss │ │ ├── _em.scss │ │ ├── _rem.scss │ │ ├── _strip-unit.scss │ │ ├── _list-decrease.scss │ │ ├── _list-increase.scss │ │ ├── _list-remove-duplicates.scss │ │ ├── _map-update-breakpoints.scss │ │ ├── _to-number.scss │ │ ├── _pxto.scss │ │ ├── _to-length.scss │ │ ├── _get-TRBL.scss │ │ ├── _string-slice-from.scss │ │ ├── _is-simple-map.scss │ │ ├── _trigonometric.scss │ │ ├── _is-nested-list.scss │ │ ├── _check-zero-value.scss │ │ ├── _opposite.scss │ │ ├── _is-number-list.scss │ │ ├── _args-get.scss │ │ ├── _to-string.scss │ │ ├── _utilities.scss │ │ ├── _is-number-map-list.scss │ │ ├── _args-get-prev.scss │ │ ├── _args-get-global-breakpoints.scss │ │ ├── _args-get-next.scss │ │ └── _args-get-type.scss │ └── tests.scss ├── images │ ├── logo.png │ ├── radio.png │ ├── triad.png │ ├── adjacent.png │ ├── checkbox.png │ ├── graphic.png │ ├── square.png │ ├── arrow-down.png │ ├── arrow-r-w.png │ ├── diamond │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 12.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── rectangle.png │ ├── title-next.png │ ├── title-prev.png │ ├── angled-edge │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ └── 3.jpg │ ├── arrow-right.png │ ├── complementary.png │ ├── radio-active.png │ ├── checkbox-active.png │ └── split-complementary.png ├── scss │ ├── off-canvas-reveal.scss │ ├── off-canvas-scale-up.scss │ ├── off-canvas-open-door.scss │ ├── off-canvas-rotate-in.scss │ ├── off-canvas-rotate-out.scss │ ├── off-canvas-scale-down.scss │ ├── off-canvas-slide-out.scss │ ├── off-canvas-slide-along.scss │ ├── off-canvas-slide-in.scss │ ├── off-canvas-rotate-in-reverse.scss │ ├── off-canvas.scss │ ├── off-canvas-drawer.scss │ ├── flex-media.scss │ ├── off-canvas-push.scss │ ├── hide-text.scss │ ├── scrollTo.scss │ ├── center.scss │ ├── scale-type.scss │ ├── fluid-type.scss │ ├── parallelogram.scss │ ├── justify.scss │ ├── input-file.scss │ ├── chart.scss │ ├── tooltip.scss │ ├── checkbox.scss │ ├── breakpoint.scss │ ├── index.scss │ ├── switch.scss │ ├── gallery.scss │ ├── reset.scss │ ├── container.scss │ ├── push-toggle.scss │ ├── dropdown.scss │ ├── _off-canvas-base.scss │ ├── angled-edge.scss │ ├── diamond.scss │ ├── metro.scss │ ├── drop-shadow.scss │ ├── accordion.scss │ ├── quantity-query.scss │ ├── responsive-table.scss │ └── masonry.scss ├── templates │ ├── code │ │ ├── off-canvas-reveal-code.njk │ │ ├── off-canvas-scale-up-code.njk │ │ ├── off-canvas-open-door-code.njk │ │ ├── off-canvas-rotate-in-code.njk │ │ ├── off-canvas-rotate-out-code.njk │ │ ├── off-canvas-scale-down-code.njk │ │ ├── off-canvas-slide-along-code.njk │ │ ├── off-canvas-slide-out-code.njk │ │ ├── off-canvas-slide-in-code.njk │ │ ├── off-canvas-rotate-in-reverse-code.njk │ │ ├── off-canvas-code.njk │ │ ├── off-canvas-drawer-code.njk │ │ ├── flex-media-code.njk │ │ ├── off-canvas-push-code.njk │ │ ├── hide-text-code.njk │ │ ├── center-code.njk │ │ ├── scale-type-code.njk │ │ ├── fluid-type-code.njk │ │ ├── parallelogram-code.njk │ │ ├── justify-code.njk │ │ ├── input-file-code.njk │ │ ├── chart-code.njk │ │ ├── tooltip-code.njk │ │ ├── checkbox-code.njk │ │ ├── breakpoint-code.njk │ │ ├── switch-code.njk │ │ ├── index-code.njk │ │ ├── gallery-code.njk │ │ ├── container-code.njk │ │ ├── reset-code.njk │ │ ├── push-toggle-code.njk │ │ ├── angled-edge-code.njk │ │ ├── dropdown-code.njk │ │ ├── diamond-code.njk │ │ ├── metro-code.njk │ │ ├── drop-shadow-code.njk │ │ ├── accordion-code.njk │ │ ├── quantity-query-code.njk │ │ ├── responsive-table-code.njk │ │ ├── masonry-code.njk │ │ └── button-code.njk │ ├── off-canvas-push.njk │ ├── off-canvas-drawer.njk │ ├── off-canvas-reveal.njk │ ├── off-canvas-scale-up.njk │ ├── off-canvas-slide-in.njk │ ├── off-canvas-open-door.njk │ ├── off-canvas-rotate-in.njk │ ├── off-canvas-rotate-out.njk │ ├── off-canvas-scale-down.njk │ ├── off-canvas-slide-out.njk │ ├── off-canvas-slide-along.njk │ ├── off-canvas-rotate-in-reverse.njk │ ├── hide-text.njk │ ├── flex-media.njk │ ├── parallelogram.njk │ ├── breakpoint.njk │ ├── drop-shadow.njk │ ├── justify.njk │ ├── container.njk │ ├── tooltip.njk │ ├── masonry.njk │ ├── center.njk │ ├── off-canvas.njk │ ├── fluid-type.njk │ ├── validation.njk │ ├── diamond.njk │ ├── push-toggle.njk │ ├── tree.json │ ├── metro.njk │ ├── gallery.njk │ ├── scale-type.njk │ ├── checkbox.njk │ ├── grid.njk │ ├── liquid.njk │ ├── input-file.njk │ ├── holy-grail.njk │ ├── button.njk │ ├── dropdown.njk │ ├── parts │ │ ├── layout.njk │ │ └── form-validation.njk │ └── tab.njk ├── js │ ├── ie.js │ ├── modernizr-config.json │ └── ie │ │ └── matchmedia.polyfill.js ├── css │ ├── index.css │ └── reset.css └── flex-media.html ├── .env ├── src ├── scss │ ├── color │ │ ├── _color.scss │ │ ├── _analogous.scss │ │ └── _contrast.scss │ ├── utilities │ │ ├── _strip-unit.scss │ │ ├── _box-sizing.scss │ │ ├── _em.scss │ │ ├── _get-calc.scss │ │ ├── _rem.scss │ │ ├── _check-arg-type.scss │ │ ├── _power.scss │ │ ├── _to-string.scss │ │ ├── _args-get-prev.scss │ │ ├── _check-zero-value.scss │ │ ├── _args-get-next.scss │ │ ├── _get-TRBL.scss │ │ ├── _opposite.scss │ │ ├── _is-liquid-list.scss │ │ ├── _list-remove-duplicates.scss │ │ ├── _list-get-max.scss │ │ ├── _to-length.scss │ │ ├── _is-nested-list.scss │ │ ├── _list-remove.scss │ │ ├── _pxto.scss │ │ ├── _is-simple-map.scss │ │ ├── _args-get-liquid-data.scss │ │ ├── _args-get.scss │ │ ├── _number-odd-even.scss │ │ ├── _map-update-breakpoints.scss │ │ ├── _is-number-list.scss │ │ ├── _list-decrease.scss │ │ ├── _is-number-map-list.scss │ │ ├── _list-increase.scss │ │ ├── _args-get-type.scss │ │ ├── _get-position-from-order.scss │ │ ├── _args-get-global-breakpoints.scss │ │ ├── _get-max-breakpoint.scss │ │ ├── _string-slice-from.scss │ │ ├── _gutter-fallback.scss │ │ ├── _to-number.scss │ │ ├── _utilities.scss │ │ └── _trigonometric.scss │ ├── vendors │ │ ├── _clearfix.scss │ │ ├── _vendors.scss │ │ ├── _perspective.scss │ │ ├── _transform.scss │ │ ├── _prefixer.scss │ │ ├── _keyframes.scss │ │ └── _animation.scss │ ├── addons │ │ ├── _hide-text.scss │ │ ├── _addons.scss │ │ ├── _equal-to.scss │ │ ├── _at-least.scss │ │ ├── _at-most.scss │ │ ├── _scale-type.scss │ │ ├── _between.scss │ │ ├── _breakpoint.scss │ │ └── _fluid-type.scss │ ├── layout │ │ ├── _layout.scss │ │ ├── _justify.scss │ │ ├── _center.scss │ │ └── _container.scss │ ├── components │ │ ├── _checkbox.scss │ │ ├── _components.scss │ │ ├── _push-toggle.scss │ │ ├── _input-file.scss │ │ ├── _parallelogram.scss │ │ ├── _flex-media.scss │ │ └── _accordion.scss │ ├── _rocket.scss │ └── setting │ │ └── _variables.scss └── js │ └── components │ ├── ie-placeholder.js │ ├── input-file.js │ └── responsive-table.js ├── .gitignore ├── .npmignore ├── docker-compose.yml ├── package.json ├── bower.json └── README.md /tests/tests-syntax/tests.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/tests-syntax/color/_core.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | #.env 2 | COMPOSE_HTTP_TIMEOUT=36000 -------------------------------------------------------------------------------- /tests/tests-syntax/layout/_container.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_list-get-max.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_list-remove.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/scss/color/_color.scss: -------------------------------------------------------------------------------- 1 | @import "contrast"; 2 | @import "analogous"; 3 | @import "palette"; -------------------------------------------------------------------------------- /tests/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/logo.png -------------------------------------------------------------------------------- /tests/images/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/radio.png -------------------------------------------------------------------------------- /tests/images/triad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/triad.png -------------------------------------------------------------------------------- /tests/images/adjacent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/adjacent.png -------------------------------------------------------------------------------- /tests/images/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/checkbox.png -------------------------------------------------------------------------------- /tests/images/graphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/graphic.png -------------------------------------------------------------------------------- /tests/images/square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/square.png -------------------------------------------------------------------------------- /tests/images/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/arrow-down.png -------------------------------------------------------------------------------- /tests/images/arrow-r-w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/arrow-r-w.png -------------------------------------------------------------------------------- /tests/images/diamond/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/1.jpg -------------------------------------------------------------------------------- /tests/images/diamond/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/10.jpg -------------------------------------------------------------------------------- /tests/images/diamond/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/11.jpg -------------------------------------------------------------------------------- /tests/images/diamond/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/12.jpg -------------------------------------------------------------------------------- /tests/images/diamond/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/2.jpg -------------------------------------------------------------------------------- /tests/images/diamond/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/3.jpg -------------------------------------------------------------------------------- /tests/images/diamond/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/4.jpg -------------------------------------------------------------------------------- /tests/images/diamond/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/5.jpg -------------------------------------------------------------------------------- /tests/images/diamond/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/6.jpg -------------------------------------------------------------------------------- /tests/images/diamond/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/7.jpg -------------------------------------------------------------------------------- /tests/images/diamond/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/8.jpg -------------------------------------------------------------------------------- /tests/images/diamond/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/diamond/9.jpg -------------------------------------------------------------------------------- /tests/images/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/rectangle.png -------------------------------------------------------------------------------- /tests/images/title-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/title-next.png -------------------------------------------------------------------------------- /tests/images/title-prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/title-prev.png -------------------------------------------------------------------------------- /tests/scss/off-canvas-reveal.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('reveal' 'submenu'); -------------------------------------------------------------------------------- /tests/scss/off-canvas-scale-up.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('scale-up' 'submenu'); -------------------------------------------------------------------------------- /tests/images/angled-edge/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/angled-edge/1.jpg -------------------------------------------------------------------------------- /tests/images/angled-edge/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/angled-edge/2.jpg -------------------------------------------------------------------------------- /tests/images/angled-edge/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/angled-edge/3.jpg -------------------------------------------------------------------------------- /tests/images/arrow-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/arrow-right.png -------------------------------------------------------------------------------- /tests/images/complementary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/complementary.png -------------------------------------------------------------------------------- /tests/images/radio-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/radio-active.png -------------------------------------------------------------------------------- /tests/scss/off-canvas-open-door.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('open-door' 'submenu'); -------------------------------------------------------------------------------- /tests/scss/off-canvas-rotate-in.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('rotate-in' 'submenu'); -------------------------------------------------------------------------------- /tests/scss/off-canvas-rotate-out.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('rotate-out' 'submenu'); -------------------------------------------------------------------------------- /tests/scss/off-canvas-scale-down.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('scale-down' 'submenu'); -------------------------------------------------------------------------------- /tests/scss/off-canvas-slide-out.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('slide-out' 'submenu'); -------------------------------------------------------------------------------- /tests/images/checkbox-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/checkbox-active.png -------------------------------------------------------------------------------- /tests/scss/off-canvas-slide-along.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('slide-along' 'submenu'); -------------------------------------------------------------------------------- /tests/scss/off-canvas-slide-in.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('slide-in' 'inside' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-reveal-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('reveal' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-scale-up-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('scale-up' 'submenu'); -------------------------------------------------------------------------------- /tests/images/split-complementary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ganlanyuan/rocket/HEAD/tests/images/split-complementary.png -------------------------------------------------------------------------------- /tests/scss/off-canvas-rotate-in-reverse.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('rotate-in-reverse' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-open-door-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('open-door' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-rotate-in-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('rotate-in' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-rotate-out-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('rotate-out' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-scale-down-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('scale-down' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-slide-along-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('slide-along' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-slide-out-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('slide-out' 'submenu'); -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-slide-in-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('slide-in' 'inside' 'submenu'); -------------------------------------------------------------------------------- /src/scss/utilities/_strip-unit.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:math'; 2 | 3 | @function strip-unit($val) { 4 | @return math.div($val, ($val * 0 + 1)); 5 | } -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-rotate-in-reverse-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('rotate-in-reverse' 'submenu'); -------------------------------------------------------------------------------- /src/scss/utilities/_box-sizing.scss: -------------------------------------------------------------------------------- 1 | @mixin box-sizing ($key) { 2 | -webkit-box-sizing: $key; 3 | -moz-box-sizing: $key; 4 | box-sizing: $key; 5 | } -------------------------------------------------------------------------------- /tests/templates/off-canvas-push.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'push' %} 2 | {% set page = 'off-canvas-push' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-drawer.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'drawer' %} 2 | {% set page = 'off-canvas-drawer' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-reveal.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'reveal' %} 2 | {% set page = 'off-canvas-reveal' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-scale-up.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'scale-up' %} 2 | {% set page = 'off-canvas-scale-up' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-slide-in.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'slide-in' %} 2 | {% set page = 'off-canvas-slide-in' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-open-door.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'open-door' %} 2 | {% set page = 'off-canvas-open-door' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-rotate-in.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'rotate-in' %} 2 | {% set page = 'off-canvas-rotate-in' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-rotate-out.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'rotate-out' %} 2 | {% set page = 'off-canvas-rotate-out' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-scale-down.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'scale-down' %} 2 | {% set page = 'off-canvas-scale-down' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /tests/templates/off-canvas-slide-out.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'slide-out' %} 2 | {% set page = 'off-canvas-slide-out' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /src/scss/utilities/_em.scss: -------------------------------------------------------------------------------- 1 | @import '../setting/variables'; 2 | @import 'pxto'; 3 | 4 | @function em($pxval, $base: $ro-em-base) { 5 | @return pxto(1em, $pxval, $base); 6 | } -------------------------------------------------------------------------------- /src/scss/utilities/_get-calc.scss: -------------------------------------------------------------------------------- 1 | @mixin get-calc($prop, $val) { 2 | #{$prop}: -webkit-calc(#{$val}); 3 | #{$prop}: -moz-calc(#{$val}); 4 | #{$prop}: calc(#{$val}); 5 | } -------------------------------------------------------------------------------- /tests/templates/off-canvas-slide-along.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'slide-along' %} 2 | {% set page = 'off-canvas-slide-along' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /src/scss/utilities/_rem.scss: -------------------------------------------------------------------------------- 1 | @import '../setting/variables'; 2 | @import 'pxto'; 3 | 4 | @function rem($pxval, $base: $ro-em-base) { 5 | @return pxto(1rem, $pxval, $base); 6 | } -------------------------------------------------------------------------------- /src/scss/vendors/_clearfix.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | clear: both; 4 | content: ""; 5 | display: table; 6 | } 7 | } 8 | 9 | %clearfix { @include clearfix; } -------------------------------------------------------------------------------- /tests/templates/off-canvas-rotate-in-reverse.njk: -------------------------------------------------------------------------------- 1 | {% set offcanvasMode = 'rotate-in-reverse' %} 2 | {% set page = 'off-canvas-rotate-in-reverse' %} 3 | {% extends 'parts/off-canvas-layout.njk' %} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.css.map 2 | *.DS_Store 3 | *.scssc 4 | *.swp 5 | *.jar 6 | *.log 7 | *.xml 8 | 9 | .sass-cache/ 10 | bower_components/ 11 | node_modules/ 12 | tests/nightwatch/screenshots/ 13 | LICENSE -------------------------------------------------------------------------------- /src/scss/addons/_hide-text.scss: -------------------------------------------------------------------------------- 1 | @mixin hide-text(){ 2 | text-indent: 110%; 3 | white-space: nowrap; 4 | overflow: hidden; 5 | } 6 | 7 | %hide-text { 8 | @include hide-text(); 9 | } 10 | -------------------------------------------------------------------------------- /src/scss/utilities/_check-arg-type.scss: -------------------------------------------------------------------------------- 1 | @mixin check-arg-type($arg, $type) { 2 | @if type-of($arg) != $type { 3 | @error 'The parameter must be a map, you passed a ' + type-of($arg) + ': ' + $arg + '.'; 4 | } 5 | } -------------------------------------------------------------------------------- /src/scss/addons/_addons.scss: -------------------------------------------------------------------------------- 1 | @import "breakpoint"; 2 | @import "hide-text"; 3 | @import "at-least"; 4 | @import "at-most"; 5 | @import "equal-to"; 6 | @import "between"; 7 | @import "fluid-type"; 8 | @import "scale-type"; -------------------------------------------------------------------------------- /src/scss/utilities/_power.scss: -------------------------------------------------------------------------------- 1 | @function power($num, $power) { 2 | $return: 1; 3 | @if $power > 0 { 4 | @for $i from 1 through $power { 5 | $return: $return * $num; 6 | } 7 | } 8 | @return $return; 9 | } -------------------------------------------------------------------------------- /tests/scss/off-canvas.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | 3 | .container { max-width: 800px; } 4 | h3 { 5 | margin-bottom: 10px; 6 | } 7 | iframe { 8 | width: 100%; 9 | min-height: 300px; 10 | overflow: hidden; 11 | } -------------------------------------------------------------------------------- /src/scss/utilities/_to-string.scss: -------------------------------------------------------------------------------- 1 | @function to-string($value) { 2 | @if type-of($value) == string { 3 | @return $value; 4 | } @else if $value == null { 5 | @return "null"; 6 | } @else { 7 | @return "" + $value; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | 3 | .container { max-width: 800px; } 4 | h3 { 5 | margin-bottom: 10px; 6 | } 7 | iframe { 8 | width: 100%; 9 | min-height: 300px; 10 | overflow: hidden; 11 | } -------------------------------------------------------------------------------- /src/scss/vendors/_vendors.scss: -------------------------------------------------------------------------------- 1 | @import "clearfix"; 2 | @import "prefixer"; 3 | @import "keyframes"; 4 | @import "animation"; 5 | @import "transform"; 6 | @import "perspective"; 7 | @import "transition"; 8 | @import "triangle"; 9 | @import "flexbox"; -------------------------------------------------------------------------------- /tests/tests-syntax/color/_color.scss: -------------------------------------------------------------------------------- 1 | @import 'contrast'; 2 | @import 'analogous'; 3 | 4 | @import 'core'; 5 | @import 'adjacent'; 6 | @import 'complementary'; 7 | @import 'split-complementary'; 8 | @import 'triad'; 9 | @import 'rectangle'; 10 | @import 'square'; -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | **/.* 2 | .gitignore 3 | .sublime-project 4 | .codekit 5 | sftp-config.json 6 | bower.json 7 | README.md 8 | changelog.md 9 | /node_modules 10 | /bower_components 11 | /docs 12 | /demos 13 | /test 14 | /tests 15 | .env 16 | docker-compose.yml 17 | gulpfile.js -------------------------------------------------------------------------------- /src/scss/layout/_layout.scss: -------------------------------------------------------------------------------- 1 | @import "container"; 2 | @import "grid"; 3 | @import "liquid"; 4 | @import "holy-grail"; 5 | @import "gallery"; 6 | @import "masonry"; 7 | @import "metro"; 8 | @import "diamond"; 9 | @import "justify"; 10 | @import "center"; 11 | @import "angled-edge"; -------------------------------------------------------------------------------- /src/scss/utilities/_args-get-prev.scss: -------------------------------------------------------------------------------- 1 | @function args-get-prev($list, $val, $default:false) { 2 | $index: index($list, $val); 3 | 4 | @if type-of($list) == 'list' and $index and $index >= 2 { 5 | @return nth($list, ($index - 1)); 6 | } @else { 7 | @return $default; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/scss/off-canvas-drawer.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | $bp: ( 3 | small: 600px, 4 | medium: 900px, 5 | ); 6 | $map: ( 7 | 500px: 20px, 8 | small: 30px, 9 | medium: 40px, 10 | null: 70px 11 | ); 12 | @include off-canvas('drawer' $map 'breakpoint' $bp 'submenu'); -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_em.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | // Testing Functions 4 | @include test('em [function]') { 5 | $test-1: em(16px); 6 | $expect-1: 1em; 7 | @include assert-equal($test-1, $expect-1, 'return em length'); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_rem.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | // Testing Functions 4 | @include test('rem [function]') { 5 | $test-1: rem(16px); 6 | $expect-1: 1rem; 7 | @include assert-equal($test-1, $expect-1, 'return rem length'); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_strip-unit.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | // Testing Functions 4 | @include test('strip-unit [function]') { 5 | $test-1: strip-unit(20px); 6 | $expect-1: 20; 7 | @include assert-equal($test-1, $expect-1, 'return em length'); 8 | } 9 | } -------------------------------------------------------------------------------- /src/scss/utilities/_check-zero-value.scss: -------------------------------------------------------------------------------- 1 | @import 'strip-unit'; 2 | 3 | @function check-zero-value($val){ 4 | @if not $val or 5 | type-of($val) != 'number' or 6 | $val and strip-unit($val) == 0 { 7 | @return 0; 8 | } @else { 9 | @return $val; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-drawer-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | $bp: ( 3 | small: 600px, 4 | medium: 900px, 5 | ); 6 | $map: ( 7 | 500px: 20px, 8 | small: 30px, 9 | medium: 40px, 10 | null: 70px 11 | ); 12 | @include off-canvas('drawer' $map 'breakpoint' $bp 'submenu'); -------------------------------------------------------------------------------- /src/scss/components/_checkbox.scss: -------------------------------------------------------------------------------- 1 | @mixin checkbox(){ 2 | > input { 3 | position: absolute; 4 | left: -9999px; 5 | } 6 | > label { 7 | display: inline-block; 8 | @content; 9 | } 10 | } 11 | 12 | @mixin checkbox-active(){ 13 | > input:checked + label { 14 | @content; 15 | } 16 | } -------------------------------------------------------------------------------- /tests/tests-syntax/color/_complementary.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('complementary [function]') { 5 | $original: #d92626; 6 | 7 | @include assert-equal(quote(complementary($original -1)), quote(#26d926), 'Returns the complementary color'); 8 | } 9 | } -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_list-decrease.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | @include test('list-decrease [function]') { 4 | $test: list-decrease( (1px 5px 20px 3px) ); 5 | $expect: (20px 5px 3px 1px); 6 | @include assert-equal($test, $expect, 'reorder number list: decrease'); 7 | }; 8 | }; -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_list-increase.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | @include test('list-increase [function]') { 4 | $test: list-increase( (1px 5px 20px 3px) ); 5 | $expect: (1px 3px 5px 20px); 6 | @include assert-equal($test, $expect, 'reorder number list: increase'); 7 | }; 8 | }; -------------------------------------------------------------------------------- /src/scss/utilities/_args-get-next.scss: -------------------------------------------------------------------------------- 1 | @function args-get-next($list, $val, $default:false) { 2 | $index: index($list, $val); 3 | 4 | @if type-of($list) == 'list' and $index and length($list) >= ($index + 1) { 5 | @return nth($list, ($index + 1)); 6 | } @else { 7 | @return $default; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/js/ie.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * NWMatcher 1.2.5 (for selectivizr) 4 | * selectivizr 5 | * Respond.js 6 | * 7 | * no html5.js 8 | */ 9 | 10 | // @codekit-prepend "ie/nwmatcher.js" 11 | // @codekit-prepend "ie/selectivizr.js" 12 | // @codekit-prepend "ie/matchmedia.polyfill.js" 13 | // @codekit-prepend "ie/respond.js" 14 | -------------------------------------------------------------------------------- /src/scss/utilities/_get-TRBL.scss: -------------------------------------------------------------------------------- 1 | @import 'args-get-next'; 2 | 3 | @function get-TRBL($key) { 4 | $top: args-get-next($key, top, 0); 5 | $right: args-get-next($key, right, 0); 6 | $bottom: args-get-next($key, bottom, 0); 7 | $left: args-get-next($key, left, 0); 8 | 9 | @return ($top $right $bottom $left); 10 | } 11 | -------------------------------------------------------------------------------- /tests/templates/code/flex-media-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/flex-media"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "video" %} 8 | .video { @include flex-media('iframe' (315/560)); } 9 | 10 | {% endif %} 11 | {% endmacro %} -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | web: 5 | image: cmcdev/web:2.7.1 6 | ports: 7 | - 3000:3000 8 | - 3001:3001 9 | volumes: 10 | - .:/www/web/ 11 | working_dir: /www/web 12 | container_name: rocket 13 | entrypoint: sh /www/start.sh 14 | stdin_open: true 15 | tty: true -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_list-remove-duplicates.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | @include test('list-remove-duplicates [function]') { 4 | 5 | $list: (2 4 0 4 5 3 5); 6 | $expect: (2 4 0 5 3); 7 | @include assert-equal(list-remove-duplicates($list), $expect, 'remove duplicate list items.'); 8 | }; 9 | }; -------------------------------------------------------------------------------- /src/scss/vendors/_perspective.scss: -------------------------------------------------------------------------------- 1 | @import 'prefixer'; 2 | 3 | @mixin ro-perspective($depth: none) { 4 | // none | 5 | @include ro-prefixer(perspective, $depth, webkit moz spec); 6 | } 7 | 8 | @mixin ro-perspective-origin($value: 50% 50%) { 9 | @include ro-prefixer(perspective-origin, $value, webkit moz spec); 10 | } 11 | -------------------------------------------------------------------------------- /tests/scss/flex-media.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/flex-media"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "video" %} 8 | .video { @include flex-media('iframe' (315/560)); } 9 | 10 | //=> {% endif %} 11 | //=> {% endmacro %} -------------------------------------------------------------------------------- /src/scss/layout/_justify.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | 3 | @mixin justify($key: '*'){ 4 | $selector: args-get-type($key, 'string', ('selector'), '*'); 5 | 6 | text-align: justify; 7 | &:after { 8 | content: ''; 9 | display: inline-block; 10 | width: 100%; 11 | } 12 | > #{$selector} { 13 | display: inline-block; 14 | } 15 | } -------------------------------------------------------------------------------- /src/scss/utilities/_opposite.scss: -------------------------------------------------------------------------------- 1 | @function opposite($direction){ 2 | @if $direction == left { 3 | @return right; 4 | } @else if $direction == right { 5 | @return left; 6 | } @else if $direction == top { 7 | @return bottom; 8 | } @else if $direction == bottom { 9 | @return top; 10 | } @else { 11 | @return false; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/tests-syntax/color/_analogous.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('analogous [function]') { 5 | 6 | @include assert-equal(quote(analogous(#5173a3 10%)), quote(#6f8db8), 'Returns the analogous color'); 7 | @include assert-equal(quote(analogous(#bbf8e6 10%)), quote(#8df3d5), 'Returns the analogous color'); 8 | } 9 | } -------------------------------------------------------------------------------- /src/scss/utilities/_is-liquid-list.scss: -------------------------------------------------------------------------------- 1 | @function is-liquid-list($key) { 2 | @if type-of($key) != 'list' { @return false; } 3 | 4 | $is-liquid-list: true; 5 | @each $item in $key { 6 | @if $is_liquid-list and type-of($item) != 'number' and not index((null 'auto'), $item) { 7 | $is-liquid-list: false; 8 | } 9 | } 10 | 11 | @return $is-liquid-list; 12 | } -------------------------------------------------------------------------------- /src/scss/utilities/_list-remove-duplicates.scss: -------------------------------------------------------------------------------- 1 | @function list-remove-duplicates($list) { 2 | @if type-of($list) != 'list' { 3 | @warn '"#{$list}" is not a list.' 4 | } 5 | 6 | $result: (); 7 | 8 | @each $item in $list { 9 | @if not index($result, $item) { 10 | $result: append($result, $item); 11 | } 12 | } 13 | 14 | @return $result; 15 | } 16 | -------------------------------------------------------------------------------- /src/scss/addons/_equal-to.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | 3 | @mixin equal-to($key) { 4 | $selector: args-get-type($key, 'string', null, '*'); 5 | $count: args-get-type($key, 'number'); 6 | 7 | 8 | #{$selector}:first-child:nth-last-of-type(#{$count}), 9 | #{$selector}:first-child:nth-last-of-type(#{$count}) ~ #{$selector} { 10 | @content; 11 | } 12 | } -------------------------------------------------------------------------------- /tests/scss/off-canvas-push.scss: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('push' 'top' 50px 'submenu'); 3 | 4 | li { 5 | display: inline-block; 6 | vertical-align: top; 7 | white-space: nowrap; 8 | // > ul { 9 | // white-space: normal; 10 | // } 11 | } 12 | [data-has-submenu] > a { margin-right: 30px; } 13 | .nav a, .nav [data-back] { border-bottom-width: 0; } -------------------------------------------------------------------------------- /src/scss/addons/_at-least.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | 3 | @mixin at-least($key) { 4 | $selector: args-get-type($key, 'string', null, '*'); 5 | $count: args-get-type($key, 'number'); 6 | 7 | 8 | #{$selector}:first-child:nth-last-of-type(n + #{$count}), 9 | #{$selector}:first-child:nth-last-of-type(n + #{$count}) ~ #{$selector} { 10 | @content; 11 | } 12 | } -------------------------------------------------------------------------------- /src/scss/addons/_at-most.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | 3 | @mixin at-most($key) { 4 | $selector: args-get-type($key, 'string', null, '*'); 5 | $count: args-get-type($key, 'number'); 6 | 7 | 8 | #{$selector}:first-child:nth-last-of-type(-n + #{$count}), 9 | #{$selector}:first-child:nth-last-of-type(-n + #{$count}) ~ #{$selector} { 10 | @content; 11 | } 12 | } -------------------------------------------------------------------------------- /tests/templates/code/off-canvas-push-code.njk: -------------------------------------------------------------------------------- 1 | @import 'off-canvas-base'; 2 | @include off-canvas('push' 'top' 50px 'submenu'); 3 | 4 | li { 5 | display: inline-block; 6 | vertical-align: top; 7 | white-space: nowrap; 8 | // > ul { 9 | // white-space: normal; 10 | // } 11 | } 12 | [data-has-submenu] > a { margin-right: 30px; } 13 | .nav a, .nav [data-back] { border-bottom-width: 0; } -------------------------------------------------------------------------------- /tests/tests-syntax/color/_triad.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('triad [function]') { 5 | $original: #d92626; 6 | 7 | @include assert-equal(quote(triad($original 1 saturation 10%)), quote(#e6e619), 'Returns the triad color'); 8 | @include assert-equal(quote(triad($original 2)), quote(#265cd9), 'Returns the triad color'); 9 | } 10 | } -------------------------------------------------------------------------------- /tests/templates/hide-text.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'hide-text' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 |

Firefox

8 |
9 |

10 |     {%- filter trim %}{{ fn.get('logo') }}{% endfilter -%}
11 |   
12 | {% endblock %} -------------------------------------------------------------------------------- /tests/tests-syntax/color/_adjacent.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('adjacent [function]') { 5 | $original: #d92626; 6 | 7 | @include assert-equal(quote(adjacent($original -1)), quote(#d9268b), 'Returns the adjacent color'); 8 | @include assert-equal(quote(adjacent($original 1)), quote(#d97726), 'Returns the adjacent color'); 9 | } 10 | } -------------------------------------------------------------------------------- /src/scss/_rocket.scss: -------------------------------------------------------------------------------- 1 | // Rocket v4.0.2 2 | // Created by William Lin (ganlanyuan@gmail.com) 3 | // Licensed under MIT Open Source 4 | // ============================================= 5 | 6 | @import "setting/variables"; 7 | @import "utilities/utilities"; 8 | @import "vendors/vendors"; 9 | 10 | @import "color/color"; 11 | @import "addons/addons"; 12 | @import "layout/layout"; 13 | @import "components/components"; -------------------------------------------------------------------------------- /src/scss/utilities/_list-get-max.scss: -------------------------------------------------------------------------------- 1 | @function list-get-max($list) { 2 | $_list: (); 3 | $max: false; 4 | 5 | @if type-of($list) == 'list' { 6 | @each $item in $list { 7 | @if type-of($item) == 'number' { 8 | $_list: append($_list, $item); 9 | } 10 | } 11 | $max: max($_list...); 12 | @return $max; 13 | } @else { 14 | @warn '"#{$list}" is not a list.' 15 | } 16 | } -------------------------------------------------------------------------------- /src/scss/utilities/_to-length.scss: -------------------------------------------------------------------------------- 1 | @function to-length($value, $unit) { 2 | $units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax); 3 | 4 | @if not index(map-keys($units), $unit) { 5 | $_: log('Invalid unit `#{$unit}`.'); 6 | } 7 | 8 | @return $value * map-get($units, $unit); 9 | } -------------------------------------------------------------------------------- /src/scss/utilities/_is-nested-list.scss: -------------------------------------------------------------------------------- 1 | @function is-nested-list($list) { 2 | @if type-of($list) != 'list' { 3 | @return false; 4 | } 5 | 6 | $is-nested-list: false; 7 | @each $item in $list { 8 | @if not $is-nested-list and 9 | type-of($item) == 'list' or 10 | type-of($item) == 'map' { 11 | $is-nested-list: true; 12 | } 13 | } 14 | 15 | @return $is-nested-list; 16 | } -------------------------------------------------------------------------------- /src/scss/utilities/_list-remove.scss: -------------------------------------------------------------------------------- 1 | @function list-remove($list, $val){ 2 | $result: (); 3 | 4 | @if type-of($list) != 'list' { 5 | $result: $list; 6 | } 7 | 8 | @each $item in $list { 9 | @if $item != $val { 10 | $result: append($result, $item); 11 | } 12 | } 13 | 14 | // return the only item in list 15 | @if length($result) == 1 { $result: nth($result, 1); } 16 | 17 | @return $result; 18 | } -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_map-update-breakpoints.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | @include test('map-update-breakpoints [function]') { 4 | $a: (null: 12px, small: 20px, 900px: 30px); 5 | $b: (small: 700px); 6 | 7 | $test-1: map-update-breakpoints($a, $b); 8 | $expect-1: (null: 12px, 700px: 20px, 900px: 30px); 9 | @include assert-equal($test-1, $expect-1, 'update map'); 10 | } 11 | } -------------------------------------------------------------------------------- /src/scss/components/_components.scss: -------------------------------------------------------------------------------- 1 | @import "chart"; 2 | @import "responsive-table"; 3 | @import "off-canvas"; 4 | @import "validation"; 5 | @import "button"; 6 | @import "parallelogram"; 7 | @import "drop-shadow"; 8 | @import "switch"; 9 | @import "push-toggle"; 10 | @import "checkbox"; 11 | @import "input-file"; 12 | @import "tab"; 13 | @import "accordion"; 14 | @import "dropdown"; 15 | @import "tooltip"; 16 | @import "flex-media"; -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_to-number.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | // Testing Functions 4 | @include test('to-number [function]') { 5 | $test-1: to-number('10px'); 6 | $expect-1: 10px; 7 | @include assert-equal($test-1, $expect-1, 'return number'); 8 | 9 | $test-2: to-number('-10.33'); 10 | $expect-2: -10.33; 11 | @include assert-equal($test-2, $expect-2, 'return number'); 12 | } 13 | } -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_pxto.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | // Testing Functions 4 | @include test('pxto [function]') { 5 | $test-1: pxto(1em, 16px, 16px); 6 | $expect-1: 1em; 7 | @include assert-equal($test-1, $expect-1, 'return em length'); 8 | 9 | $test-2: pxto(1rem, 32px, 16px); 10 | $expect-2: 2rem; 11 | @include assert-equal($test-2, $expect-2, 'return rem length'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_to-length.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | // Testing Functions 4 | @include test('to-length [function]') { 5 | $test-1: to-length(20, 'px'); 6 | $expect-1: 20px; 7 | @include assert-equal($test-1, $expect-1, 'return length'); 8 | 9 | $test-2: to-length(33.3, 'vmin'); 10 | $expect-2: 33.3vmin; 11 | @include assert-equal($test-2, $expect-2, 'return length'); 12 | } 13 | } -------------------------------------------------------------------------------- /src/scss/utilities/_pxto.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:math'; 2 | 3 | @function pxto($unit, $px-val, $base) { 4 | @if unit($px-val) == 'em' or unit($px-val) == 'rem' { 5 | @return strip-unit($px-val) * $unit; 6 | 7 | } @else { 8 | @if unit($px-val) == 'px' or unitless($px-val) { $px-val: strip-unit($px-val); } 9 | @if unit($base) == 'px' or unitless($base) { $base: strip-unit($base); } 10 | @return math.div($px-val, $base) * $unit; 11 | } 12 | } -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_get-TRBL.scss: -------------------------------------------------------------------------------- 1 | @include test-module('trigonometric') { 2 | 3 | @include test('get-TRBL [function]') { 4 | 5 | $test1: get-TRBL(top 30px); 6 | $expect1: 30px 0 0 0; 7 | @include assert-equal($test1, $expect1, 'return a TRBL value.'); 8 | 9 | $test2: get-TRBL(left 300px right 20px); 10 | $expect2: 0 20px 0 300px; 11 | @include assert-equal($test2, $expect2, 'return a TRBL value.'); 12 | }; 13 | }; -------------------------------------------------------------------------------- /tests/tests-syntax/color/_split-complementary.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('split-complementary [function]') { 5 | $original: #d92626; 6 | 7 | @include assert-equal(quote(split-complementary($original 1)), quote(#9dd926), 'Returns the split-complementary color'); 8 | @include assert-equal(quote(split-complementary($original 2)), quote(#26d9d9), 'Returns the split-complementary color'); 9 | } 10 | } -------------------------------------------------------------------------------- /tests/tests-syntax/layout/_layout.scss: -------------------------------------------------------------------------------- 1 | // @import "container"; // @required [mixin] breakpoint 2 | @import "grid"; 3 | // @import "liquid"; 4 | // @import "holy-grail"; 5 | // @import "gallery"; 6 | // @import "masonry"; 7 | // @import "masonry-cluster"; 8 | // @import "metro"; 9 | // @import "diamond"; 10 | // @import "justify"; // @required [mixin] display, justify-content, align-items 11 | // @import "center"; 12 | // @import "sticky-footer"; 13 | // @import "angled-edge"; -------------------------------------------------------------------------------- /src/scss/utilities/_is-simple-map.scss: -------------------------------------------------------------------------------- 1 | @function is-simple-map($map) { 2 | @if type-of($map) != 'map' { 3 | @return false; 4 | } 5 | 6 | $is-simple-map: true; 7 | $values: map-values($map); 8 | 9 | @each $item in $values { 10 | // no need for further check if false 11 | @if $is-simple-map and not index(('string' 'number' 'null' 'bool'), type-of($item)) { 12 | $is-simple-map: false; 13 | } 14 | } 15 | 16 | @return $is-simple-map; 17 | } 18 | -------------------------------------------------------------------------------- /tests/tests-syntax/color/_square.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('square [function]') { 5 | $original: #d92626; 6 | 7 | @include assert-equal(quote(square($original 1)), quote(#d9bb26), 'Returns the square color'); 8 | @include assert-equal(quote(square($original 2)), quote(#26d926), 'Returns the square color'); 9 | @include assert-equal(quote(square($original 3)), quote(#5026d9), 'Returns the square color'); 10 | } 11 | } -------------------------------------------------------------------------------- /src/scss/components/_push-toggle.scss: -------------------------------------------------------------------------------- 1 | @import '../vendors/clearfix'; 2 | 3 | @mixin push-toggle() { 4 | @include clearfix; 5 | 6 | [type="radio"] { 7 | position: absolute; 8 | left: -9999px; 9 | } 10 | label { 11 | float: left; 12 | display: inline-block; 13 | text-align: center; 14 | -webkit-box-sizing: border-box; 15 | -moz-box-sizing: border-box; 16 | box-sizing: border-box; 17 | } 18 | 19 | input:checked + label { 20 | @content; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/templates/flex-media.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'flex-media' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 |
8 |
9 |

10 |     {%- filter trim %}{{ fn.get('video') }}{% endfilter -%}
11 |   
12 | {% endblock %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_string-slice-from.scss: -------------------------------------------------------------------------------- 1 | @include test-module('String') { 2 | 3 | @include test('string-slice-from [function]') { 4 | 5 | $test1: string-slice-from('weight-normal', '-', after); 6 | $expect1: 'normal'; 7 | @include assert-equal($test1, $expect1, 'get string slice after "-".'); 8 | 9 | $test2: string-slice-from('weight.normal', '.', before); 10 | $expect2: 'weight'; 11 | @include assert-equal($test2, $expect2, 'get string slice before ".".'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/tests-syntax/color/_rectangle.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('rectangle [function]') { 5 | $original: #d92626; 6 | 7 | @include assert-equal(quote(rectangle($original 1)), quote(#d97726), 'Returns the rectangle color'); 8 | @include assert-equal(quote(rectangle($original 2)), quote(#26d926), 'Returns the rectangle color'); 9 | @include assert-equal(quote(rectangle($original 3)), quote(#26d9d9), 'Returns the rectangle color'); 10 | } 11 | } -------------------------------------------------------------------------------- /src/scss/utilities/_args-get-liquid-data.scss: -------------------------------------------------------------------------------- 1 | @import 'is-liquid-list'; 2 | 3 | @function args-get-liquid-data($key, $length) { 4 | $data: false; 5 | 6 | @if type-of($key) == map or 7 | type-of($key) == 'list' and length($key) == $length and is-liquid-list($key) { 8 | $data: $key; 9 | } @else if type-of($key) == 'list' { 10 | @each $item in $key { 11 | 12 | @if not $data { 13 | $data: args-get-liquid-data($item, $length); 14 | } 15 | } 16 | } 17 | 18 | @return $data; 19 | } -------------------------------------------------------------------------------- /src/scss/utilities/_args-get.scss: -------------------------------------------------------------------------------- 1 | @function args-get($key, $arg, $def:false){ 2 | $result: $def; 3 | 4 | // string: return true/false when exists 5 | @if type-of($arg) == 'string' { 6 | @if index($key, $arg) { 7 | $result: true; 8 | } 9 | } @else if type-of($arg) == 'list' { 10 | 11 | // list: return item itself when the item exists 12 | @each $item in $arg { 13 | @if index($key, $item) { 14 | $result: $item; 15 | } 16 | } 17 | } 18 | 19 | @return $result; 20 | } 21 | -------------------------------------------------------------------------------- /src/scss/utilities/_number-odd-even.scss: -------------------------------------------------------------------------------- 1 | @import 'strip-unit'; 2 | 3 | @function number-odd-even($num) { 4 | $return: false; 5 | 6 | @if type-of($num) == 'number' { 7 | $num-unitless: abs(strip-unit($num)); 8 | 9 | @if $num-unitless == round($num-unitless) { 10 | $half-num-unitless: ($num-unitless / 2); 11 | @if $half-num-unitless == round($half-num-unitless) { 12 | $return: 'even'; 13 | } @else { 14 | $return: 'odd'; 15 | } 16 | } 17 | } 18 | 19 | @return $return; 20 | } -------------------------------------------------------------------------------- /tests/templates/parallelogram.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'parallelogram' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | 12 |

13 |     {%- filter trim %}{{ fn.get('parallelogram') }}{% endfilter -%}
14 |   
15 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/code/hide-text-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/hide-text"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "logo" %} 8 | .logo > a { 9 | @extend %hide-text; 10 | display: block; 11 | width: 144px; 12 | height: 154px; 13 | margin: 0 auto; 14 | background: url('https://mozorg.cdn.mozilla.net/media/img/styleguide/identity/firefox/usage-logo.54fbc7b6231b.png') 0 0 no-repeat; 15 | } 16 | 17 | {% endif %} 18 | {% endmacro %} -------------------------------------------------------------------------------- /tests/js/modernizr-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "minify": true, 3 | "options": [ 4 | "setClasses" 5 | ], 6 | "feature-detects": [ 7 | "css/boxshadow", 8 | "css/calc", 9 | "css/columns", 10 | "css/flexbox", 11 | "css/flexboxlegacy", 12 | "css/flexboxtweener", 13 | "css/flexwrap", 14 | "css/gradients", 15 | "css/multiplebgs", 16 | "css/transforms", 17 | "css/transforms3d", 18 | "css/transitions", 19 | "svg/asimg", 20 | "svg/inline", 21 | "svg/smil", 22 | "touchevents" 23 | ] 24 | } -------------------------------------------------------------------------------- /tests/scss/hide-text.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/hide-text"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "logo" %} 8 | .logo > a { 9 | @extend %hide-text; 10 | display: block; 11 | width: 144px; 12 | height: 154px; 13 | margin: 0 auto; 14 | background: url('https://mozorg.cdn.mozilla.net/media/img/styleguide/identity/firefox/usage-logo.54fbc7b6231b.png') 0 0 no-repeat; 15 | } 16 | 17 | //=> {% endif %} 18 | //=> {% endmacro %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_is-simple-map.scss: -------------------------------------------------------------------------------- 1 | @include test-module('map') { 2 | 3 | @include test('is-simple-map [function]') { 4 | 5 | $test-1: (null:1, 200px:0); 6 | @include assert-true(is-simple-map($test-1), 'This is a simple map.'); 7 | 8 | $test-2: ('default': 2 2, 800px: (3 7) 2); 9 | @include assert-false(is-simple-map($test-2), 'This map containes lists.'); 10 | 11 | $test-3: ('default': 2 2, 800px: (3:1, 7:0)); 12 | @include assert-false(is-simple-map($test-3), 'This map contains nested map.'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/scss/color/_analogous.scss: -------------------------------------------------------------------------------- 1 | @function analogous($key) { 2 | $color: false; 3 | $lightness: false; 4 | 5 | @each $item in $key { 6 | @if type-of($item) == color and not $color { 7 | $color: $item; 8 | } @else if type-of($item) == number and not $lightness { 9 | $lightness: $item; 10 | } 11 | } 12 | 13 | @if $color { 14 | @if $lightness { 15 | @return if(lightness($color) >= 50%, darken($color, $lightness), lighten($color, $lightness)); 16 | } @else { 17 | @return $color; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_trigonometric.scss: -------------------------------------------------------------------------------- 1 | @include test-module('trigonometric') { 2 | 3 | @include test('sqrt [function]') { 4 | 5 | $test1: sqrt(9); 6 | $expect1: 3; 7 | @include assert-equal($test1, $expect1, 'return a square root of 9.'); 8 | 9 | $test2: sqrt(0); 10 | $expect2: 0; 11 | @include assert-equal($test2, $expect2, 'return a square root of 0.'); 12 | 13 | $test3: sqrt(-2); 14 | $expect3: false; 15 | @include assert-equal($test3, $expect3, 'return false when value is negative.'); 16 | }; 17 | }; -------------------------------------------------------------------------------- /src/scss/utilities/_map-update-breakpoints.scss: -------------------------------------------------------------------------------- 1 | @function map-update-breakpoints($map, $bps) { 2 | @if not $bps { 3 | @warn "breakpoints doesn't exit." 4 | } 5 | 6 | $map-new: (_placeholder: _placeholder); 7 | 8 | @each $key, $value in $map { 9 | @if type-of($key) == 'string' and map-has-key($bps, $key) { 10 | $map-new: map-merge($map-new, ( map-get($bps, $key): $value )); 11 | } @else { 12 | $map-new: map-merge($map-new, ( $key: $value )); 13 | } 14 | } 15 | 16 | $map-new: map-remove($map-new, _placeholder); 17 | @return $map-new; 18 | } 19 | -------------------------------------------------------------------------------- /src/scss/components/_input-file.scss: -------------------------------------------------------------------------------- 1 | @mixin input-file(){ 2 | > input { 3 | .js & { 4 | width: 0.1px; 5 | height: 0.1px; 6 | opacity: 0; 7 | overflow: hidden; 8 | position: absolute; 9 | z-index: -1; 10 | } 11 | + label { 12 | display: inline-block; 13 | cursor: pointer; 14 | @content; 15 | .no-js & { display: none; } 16 | } 17 | &:focus + label { 18 | outline: 1px dotted #000; 19 | outline: -webkit-focus-ring-color auto 5px; 20 | * { pointer-events: none; } 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/scss/components/_parallelogram.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | @import '../vendors/transform'; 3 | 4 | @mixin parallelogram($key) { 5 | $color: args-get-type($key, 'color'); 6 | $angle: args-get-type($key, 'number'); 7 | 8 | position: relative; 9 | &:before { 10 | content: ''; 11 | position: absolute; 12 | top: 0; 13 | right: 0; 14 | bottom: 0; 15 | left: 0; 16 | z-index: -1; 17 | 18 | @if $color { 19 | background-color: $color; 20 | } 21 | @if $angle { 22 | @include ro-transform(skew($angle)); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /tests/scss/scrollTo.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | 3 | .scroll-to { 4 | padding: 40px 0; 5 | text-align: center; 6 | } 7 | .btn { 8 | margin: 0 0 20px; 9 | padding: 0 1.6em; 10 | height: 2.6em; 11 | line-height: 2.6; 12 | font-size: 14px; 13 | border-radius: 5px; 14 | background-color: #333; 15 | } 16 | .box { 17 | max-width: 800px; 18 | margin: 400px auto 0; 19 | padding: 10px; 20 | min-height: 200px; 21 | margin-bottom: 20px; 22 | line-height: 1.5; 23 | color: #fff; 24 | border-radius: 10px; 25 | box-sizing: border-box; 26 | background-color: #F54E86; 27 | } 28 | -------------------------------------------------------------------------------- /src/scss/utilities/_is-number-list.scss: -------------------------------------------------------------------------------- 1 | @function is-number-list($list) { 2 | @if type-of($list) != 'list' { 3 | @warn '"#{$list}" is not a list'; 4 | @return false; 5 | } 6 | 7 | $is-number-list: true; 8 | @each $item in $list { 9 | // if $is-number-list: false, no need to check anymore 10 | @if $is-number-list and type-of($item) != 'number' { 11 | // check sub list 12 | @if type-of($item) == 'list' { 13 | $is-number-list: is-number-list($item); 14 | } @else { 15 | $is-number-list: false; 16 | } 17 | } 18 | } 19 | 20 | @return $is-number-list; 21 | } -------------------------------------------------------------------------------- /tests/templates/breakpoint.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'breakpoint' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'num', 8 | 'num-max', 9 | 'num-2-max', 10 | 'num-print', 11 | 'height', 12 | 'num-9' 13 | ] %} 14 | 15 |
16 |
17 |
18 | 19 | {# code #} 20 |

21 |       {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
22 |     
23 | {% endfor %} 24 | {% endblock %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_is-nested-list.scss: -------------------------------------------------------------------------------- 1 | @include test-module('List') { 2 | 3 | @include test('is-nested-list [function]') { 4 | 5 | // $test-1: 'string'; 6 | // @include assert-false(is-nested-list($test-1), 'This is not a list.'); 7 | 8 | $test-2: (1 3 5); 9 | @include assert-false(is-nested-list($test-2), 'This is a simple list.'); 10 | 11 | $test-3: (1 (3 4) 5); 12 | @include assert-true(is-nested-list($test-3), 'This list contains nested list.'); 13 | 14 | $test-4: (1 (3 : 4) 5); 15 | @include assert-true(is-nested-list($test-4), 'This list contains map.'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/js/components/ie-placeholder.js: -------------------------------------------------------------------------------- 1 | // ie placeholder 2 | function iePlaceholder () { 3 | kit('.lt-ie10 [placeholder]').forEach(function (el) { 4 | var input = kit(el), 5 | text = el.getAttribute('placeholder'); 6 | 7 | if (text) { input.attr('value', text); } 8 | 9 | input.focus(function(){ 10 | if (input[0].value === text) { 11 | input.attr('value', ''); 12 | } 13 | }); 14 | input.blur(function(){ 15 | if (input[0].value === "") { 16 | input.attr('value', text); 17 | } 18 | }); 19 | }); 20 | } 21 | ready(function () { 22 | iePlaceholder(); 23 | }); -------------------------------------------------------------------------------- /src/scss/utilities/_list-decrease.scss: -------------------------------------------------------------------------------- 1 | @import 'list-remove'; 2 | 3 | @function list-decrease($list) { 4 | @if type-of($list) != 'list' { 5 | @warn '"#{$list}" is not a list.' 6 | } 7 | 8 | @each $item in $list { 9 | @if type-of($item) != 'number' { 10 | @warn '"#{$item}" is not a number.' 11 | } 12 | } 13 | 14 | $list: $list; 15 | $return: (); 16 | 17 | @while length($list) > 1 { 18 | $max: max($list...); 19 | 20 | $return: append($return, $max); 21 | $list: list-remove($list, $max); 22 | } 23 | $return: append($return, nth($list, 1)); 24 | 25 | @return $return; 26 | } 27 | -------------------------------------------------------------------------------- /src/scss/utilities/_is-number-map-list.scss: -------------------------------------------------------------------------------- 1 | @function is-number-map-list($list) { 2 | @if type-of($list) != 'list' { 3 | @return false; 4 | } 5 | 6 | $is-number-map-list: true; 7 | @each $item in $list { 8 | // if $is-number-map-list: false, no need for further check 9 | @if $is-number-map-list and 10 | type-of($item) != 'number' and 11 | type-of($item) != 'map' { 12 | @if type-of($item) == 'list' { 13 | $is-number-map-list: is-number-map-list($item); 14 | } @else { 15 | $is-number-map-list: false; 16 | } 17 | } 18 | } 19 | 20 | @return $is-number-map-list; 21 | } -------------------------------------------------------------------------------- /src/scss/vendors/_transform.scss: -------------------------------------------------------------------------------- 1 | @import 'prefixer'; 2 | 3 | @mixin ro-transform($property: none) { 4 | // none | 5 | @include ro-prefixer(transform, $property, webkit moz ms o spec); 6 | } 7 | 8 | @mixin ro-transform-origin($axes: 50%) { 9 | // x-axis - left | center | right | length | % 10 | // y-axis - top | center | bottom | length | % 11 | // z-axis - length 12 | @include ro-prefixer(transform-origin, $axes, webkit moz ms o spec); 13 | } 14 | 15 | @mixin ro-transform-style($style: flat) { 16 | @include ro-prefixer(transform-style, $style, webkit moz ms o spec); 17 | } 18 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_check-zero-value.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | @include test('check-zero-value [function]') { 4 | 5 | $test1: check-zero-value(9px); 6 | $expect1: 9px; 7 | @include assert-equal($test1, $expect1, 'return a non-zero value.'); 8 | 9 | $val: null; 10 | $test2: check-zero-value($val); 11 | $expect2: 0; 12 | @include assert-equal($test2, $expect2, 'return 0 when $val is not exist.'); 13 | 14 | $test3: check-zero-value(0px); 15 | $expect3: 0; 16 | @include assert-equal($test3, $expect3, 'return 0 when $val is 0 with a unit.'); 17 | }; 18 | }; -------------------------------------------------------------------------------- /src/scss/utilities/_list-increase.scss: -------------------------------------------------------------------------------- 1 | @import 'list-remove'; 2 | 3 | @function list-increase($list) { 4 | @if type-of($list) != 'list' { 5 | @warn '"#{$list}" is not a list.' 6 | } 7 | @each $item in $list { 8 | @if type-of($item) != 'number' and type-of($item) != 'list' { 9 | @warn '"#{$item}" is not a number.' 10 | } 11 | } 12 | 13 | $list: $list; 14 | $return: (); 15 | 16 | @while length($list) > 1 { 17 | $min: min($list...); 18 | 19 | $return: append($return, $min); 20 | $list: list-remove($list, $min); 21 | } 22 | $return: append($return, nth($list, 1)); 23 | 24 | @return $return; 25 | } 26 | -------------------------------------------------------------------------------- /tests/templates/drop-shadow.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'drop-shadow' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'lifted', 8 | 'raised', 9 | 'perspective', 10 | 'curve-left', 11 | 'curve-right', 12 | 'curve-horizontal', 13 | 'curve-top', 14 | 'curve-bottom', 15 | 'curve-vertical' 16 | ] %} 17 | 18 |
{{ item | replace('-', ' ') }}
19 |

20 |       {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
21 |     
22 | {% endfor %} 23 | {% endblock %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_opposite.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | @include test('opposite [function]') { 4 | 5 | $direction: (left right top bottom); 6 | $expect: (right left bottom top); 7 | @include assert-equal(opposite(nth($direction, 1)), nth($expect, 1), 'return opposite direction.'); 8 | @include assert-equal(opposite(nth($direction, 2)), nth($expect, 2), 'return opposite direction.'); 9 | @include assert-equal(opposite(nth($direction, 3)), nth($expect, 3), 'return opposite direction.'); 10 | @include assert-equal(opposite(nth($direction, 4)), nth($expect, 4), 'return opposite direction.'); 11 | }; 12 | }; -------------------------------------------------------------------------------- /tests/templates/justify.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'justify' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | 15 | 16 |

17 |     {%- filter trim %}{{ fn.get('justify') }}{% endfilter -%}
18 |   
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /src/scss/utilities/_args-get-type.scss: -------------------------------------------------------------------------------- 1 | @function args-get-type($key, $type, $check:null, $def:false) { 2 | $result: $def; 3 | 4 | @if not $key { @return $result; } 5 | 6 | @if type-of($key) == $type { 7 | @if index($check, $key) == false or 8 | index($check, $key) == null { 9 | $result: $key; 10 | } 11 | } @else if type-of($key) == 'list' { 12 | @each $item in $key { 13 | @if $result == $def and type-of($item) == $type { 14 | @if index($check, $item) == false or 15 | index($check, $item) == null { 16 | $result: $item; 17 | } 18 | } 19 | } 20 | } 21 | 22 | @return $result; 23 | } -------------------------------------------------------------------------------- /tests/templates/code/center-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/center"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "center" %} 8 | .center { 9 | @include center('main'); 10 | 11 | height: 400px; 12 | > main { 13 | background: #fff; 14 | box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); 15 | max-width: 640px; 16 | padding: 20px; 17 | box-sizing: border-box; 18 | img { 19 | float: left; 20 | margin-right: 20px; 21 | margin-bottom: 10px; 22 | } 23 | p { color: #000; } 24 | } 25 | } 26 | 27 | {% endif %} 28 | {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/container.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'container' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'default', 8 | 'px-left', 9 | 'px-right', 10 | 'px-px', 11 | 'px-0px', 12 | 'em', 13 | 'em-px', 14 | 'percentage', 15 | 'percentage-px' 16 | ] %} 17 |
18 |
19 |
20 |

21 |       {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
22 |     
23 | {% endfor %} 24 | {% endblock %} -------------------------------------------------------------------------------- /src/scss/components/_flex-media.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | 3 | %flex-media-container { 4 | position: relative; 5 | height: 0; 6 | overflow: hidden; 7 | } 8 | %flex-media { 9 | position: absolute; 10 | width: 100%; 11 | height: 100%; 12 | } 13 | 14 | @mixin flex-media($key: (9/16)){ 15 | $selector: args-get-type($key, 'string'); 16 | $ratio: args-get-type($key, 'number'); 17 | @if unitless($ratio) { $ratio: percentage($ratio); } 18 | 19 | $selectors: if($selector, "> #{$selector}", "> iframe, > object, > embed"); 20 | 21 | @extend %flex-media-container; 22 | padding-bottom: $ratio; 23 | #{$selectors} { @extend %flex-media; } 24 | } -------------------------------------------------------------------------------- /src/scss/utilities/_get-position-from-order.scss: -------------------------------------------------------------------------------- 1 | @import 'list-increase'; 2 | @import 'list-remove-duplicates'; 3 | @import 'to-number'; 4 | 5 | @function get-position-from-order($order) { 6 | $nums: list-increase(list-remove-duplicates($order)); // reordered values 7 | $temp: (); 8 | $positions: (); 9 | 10 | @each $num in $nums { 11 | @for $i from 1 through length($order) { 12 | @if nth($order, $i) == $num { 13 | $temp: append($temp, #{$i}); // use number as text 14 | } 15 | } 16 | } 17 | 18 | @each $n in $temp { 19 | $positions: append($positions, to-number($n)); // transfer text to number 20 | } 21 | @return $positions; 22 | } -------------------------------------------------------------------------------- /tests/scss/center.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/center"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "center" %} 8 | .center { 9 | @include center('main'); 10 | 11 | height: 400px; 12 | > main { 13 | background: #fff; 14 | box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); 15 | max-width: 640px; 16 | padding: 20px; 17 | box-sizing: border-box; 18 | img { 19 | float: left; 20 | margin-right: 20px; 21 | margin-bottom: 10px; 22 | } 23 | p { color: #000; } 24 | } 25 | } 26 | 27 | //=> {% endif %} 28 | //=> {% endmacro %} -------------------------------------------------------------------------------- /src/scss/utilities/_args-get-global-breakpoints.scss: -------------------------------------------------------------------------------- 1 | @function args-get-global-breakpoints($arg){ 2 | $global-bps: false; 3 | 4 | // map: return map 5 | @if type-of($arg) == 'list' { 6 | @each $item in $arg { 7 | @if type-of($item) == 'map' { 8 | $keys: map-keys($item); 9 | $values: map-values($item); 10 | $bps: true; 11 | 12 | @for $i from 1 through length($keys) { 13 | @if type-of(nth($keys, $i)) != 'string' or 14 | type-of(nth($values, $i)) != 'number' { $bps: false; } 15 | } 16 | 17 | @if $bps { $global-bps: $item; } 18 | } 19 | } 20 | } 21 | 22 | @return $global-bps; 23 | } 24 | -------------------------------------------------------------------------------- /tests/templates/code/scale-type-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/scale-type"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "scale-type1" %} 8 | @include scale-type(1.2); 9 | 10 | {% elif componentName === "scale-type2" %} 11 | @include scale-type(1.4 ('.heading1', '.heading2', '.heading3', '.heading4')); 12 | 13 | {% elif componentName === "scale-type3" %} 14 | @include scale-type('height' 1.4 100px false ('.box1', '.box2', '.box3', '.box4')); 15 | 16 | {% endif %} 17 | {% endmacro %} 18 | 19 | h1, h2, h3, h4, h5, h6, [class*='heading'], .box { margin: 0 0 20px; } 20 | .box { background-color: #008080; } -------------------------------------------------------------------------------- /src/scss/utilities/_get-max-breakpoint.scss: -------------------------------------------------------------------------------- 1 | @function get-max-breakpoint($list, $condition) { 2 | @if type-of($list) == 'list' { 3 | 4 | $list-nums: (); 5 | @each $bp in $list { 6 | @if type-of($bp) == 'number' { 7 | $list-nums: append($list-nums, $bp); 8 | } 9 | } 10 | 11 | @if $condition == 'min' { 12 | @return max($list-nums...); 13 | 14 | } @else { 15 | 16 | @if index($list, null) { 17 | @return null; 18 | 19 | } @else if index($list, 'default') { 20 | @return 'default'; 21 | 22 | } @else { 23 | @return max($list-nums...); 24 | } 25 | } 26 | } @else { 27 | @warn '"#{$list}" is not a list.' 28 | } 29 | } -------------------------------------------------------------------------------- /tests/templates/tooltip.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'tooltip' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'left', 8 | 'right', 9 | 'top', 10 | 'bottom' 11 | ] %} 12 | 13 |
Lorem ipsum dolor sit amet. Quo vitae {{ item }} odit fuga asperiores.
14 |

15 |       {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
16 |     
17 | {% endfor %} 18 | {% endblock %} -------------------------------------------------------------------------------- /tests/scss/scale-type.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/scale-type"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "scale-type1" %} 8 | @include scale-type(1.2); 9 | 10 | //=> {% elif componentName === "scale-type2" %} 11 | @include scale-type(1.4 ('.heading1', '.heading2', '.heading3', '.heading4')); 12 | 13 | //=> {% elif componentName === "scale-type3" %} 14 | @include scale-type('height' 1.4 100px false ('.box1', '.box2', '.box3', '.box4')); 15 | 16 | //=> {% endif %} 17 | //=> {% endmacro %} 18 | 19 | h1, h2, h3, h4, h5, h6, [class*='heading'], .box { margin: 0 0 20px; } 20 | .box { background-color: #008080; } -------------------------------------------------------------------------------- /tests/templates/code/fluid-type-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/fluid-type"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "h2" %} 8 | h2 { @include fluid-type('font-size' 'margin' (320px: 24px, 1024px: 40px)); } 9 | 10 | {% elif componentName === "p" %} 11 | p { @include fluid-type('font-size' (320px: 18px, 1024px: 24px)); } 12 | 13 | {% endif %} 14 | {% endmacro %} 15 | 16 | h2 { 17 | text-align: center; 18 | margin: 1.5em 0; 19 | } 20 | p { 21 | margin-top: 0; 22 | margin-bottom: 0; 23 | line-height: 1.7; 24 | color: #333; 25 | text-align: center; 26 | } 27 | pre[class*="language-"] { margin-bottom: 20px; } -------------------------------------------------------------------------------- /tests/templates/code/parallelogram-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/parallelogram"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "parallelogram" %} 8 | .parallelogram a { @include parallelogram(#1C6493 -20deg); } 9 | 10 | {% endif %} 11 | {% endmacro %}} 12 | 13 | .parallelogram { 14 | text-align: center; 15 | margin-bottom: 50px; 16 | & li { display: inline-block; } 17 | & a { 18 | display: inline-block; 19 | padding: 1em 1.5em; 20 | font-size: 14px; 21 | color: #fff; 22 | text-decoration: none; 23 | &:hover:before { 24 | background: darken(#32A8DE, 10%); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/templates/masonry.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'masonry' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'masonry-number', 8 | 'masonry-child', 9 | 'masonry-0px', 10 | 'masonry-percentage-gutter', 11 | 'masonry-condition', 12 | 'masonry-breakpoints', 13 | 'masonry-global-breakpoints' 14 | ] %} 15 | 16 |
17 |
    {% include './parts/masonry-content.njk' %}
18 | 19 | {# code #} 20 |

21 |         {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
22 |       
23 |
24 | 25 | {% endfor %} 26 | {% endblock %} -------------------------------------------------------------------------------- /src/scss/utilities/_string-slice-from.scss: -------------------------------------------------------------------------------- 1 | @function string-slice-from($string, $separator, $from) { 2 | @if type-of($string) == 'string' { 3 | $position: 1; 4 | $return: ''; 5 | 6 | @if str-index($string, $separator) { 7 | $position: str-index($string, $separator); 8 | @if $from == 'after' { 9 | $position: $position + 1; 10 | $return: str-slice($string, $position, str-length($string)); 11 | } @else if $from == 'before' { 12 | $position: $position - 1; 13 | $return: str-slice($string, 1, $position); 14 | } 15 | } @else { 16 | $return: $string; 17 | } 18 | 19 | @return $return; 20 | } @else { 21 | @warn '"#{$string}" is not a string.'; 22 | } 23 | } -------------------------------------------------------------------------------- /tests/scss/fluid-type.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/fluid-type"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "h2" %} 8 | h2 { @include fluid-type('font-size' 'margin' (320px: 24px, 1024px: 40px)); } 9 | 10 | //=> {% elif componentName === "p" %} 11 | p { @include fluid-type('font-size' (320px: 18px, 1024px: 24px)); } 12 | 13 | //=> {% endif %} 14 | //=> {% endmacro %} 15 | 16 | h2 { 17 | text-align: center; 18 | margin: 1.5em 0; 19 | } 20 | p { 21 | margin-top: 0; 22 | margin-bottom: 0; 23 | line-height: 1.7; 24 | color: #333; 25 | text-align: center; 26 | } 27 | pre[class*="language-"] { margin-bottom: 20px; } -------------------------------------------------------------------------------- /tests/scss/parallelogram.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/parallelogram"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "parallelogram" %} 8 | .parallelogram a { @include parallelogram(#1C6493 -20deg); } 9 | 10 | //=> {% endif %} 11 | //=> {% endmacro %}} 12 | 13 | .parallelogram { 14 | text-align: center; 15 | margin-bottom: 50px; 16 | & li { display: inline-block; } 17 | & a { 18 | display: inline-block; 19 | padding: 1em 1.5em; 20 | font-size: 14px; 21 | color: #fff; 22 | text-decoration: none; 23 | &:hover:before { 24 | background: darken(#32A8DE, 10%); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/templates/code/justify-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/justify"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "justify" %} 8 | .justify { @include justify('li'); } 9 | 10 | {% endif %} 11 | {% endmacro %} 12 | 13 | .justify { 14 | li { 15 | font-size: 13px; 16 | text-transform: uppercase; 17 | } 18 | a { display: block; } 19 | input { 20 | padding: 0 0.8em; 21 | line-height: 2.4; 22 | height: 2.4em; 23 | width: 150px; 24 | font-size: 14px; 25 | border: 1px solid #ddd; 26 | -webkit-transition: width 0.3s; 27 | transition: width 0.3s; 28 | &:focus { width: 250px; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/scss/justify.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/justify"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "justify" %} 8 | .justify { @include justify('li'); } 9 | 10 | //=> {% endif %} 11 | //=> {% endmacro %} 12 | 13 | .justify { 14 | li { 15 | font-size: 13px; 16 | text-transform: uppercase; 17 | } 18 | a { display: block; } 19 | input { 20 | padding: 0 0.8em; 21 | line-height: 2.4; 22 | height: 2.4em; 23 | width: 150px; 24 | font-size: 14px; 25 | border: 1px solid #ddd; 26 | -webkit-transition: width 0.3s; 27 | transition: width 0.3s; 28 | &:focus { width: 250px; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/templates/center.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'center' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 |
8 | 9 |

We Make America Great

10 |

Take a break from politics and visit a community celebration. You’ll see neighbors working together showcasing local bounty. This is the real America—where citizens build strong communities because they care.

11 |
12 |
13 |

14 |     {%- filter trim %}{{ fn.get('center') }}{% endfilter -%}
15 |   
16 | {% endblock %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_is-number-list.scss: -------------------------------------------------------------------------------- 1 | @include test-module('List') { 2 | 3 | @include test('is-number-list [function]') { 4 | 5 | // $test-1: 'Some text here.'; 6 | // @include assert-false(is-number-list($test-1), 'This is not a list.'); 7 | 8 | $test-1: (1 3 5); 9 | @include assert-true(is-number-list($test-1), 'This is a number list.'); 10 | 11 | $test-2: (1 (3 4) 5); 12 | @include assert-true(is-number-list($test-2), 'This list is a number list.'); 13 | 14 | $test-3: (1 (3 : 4) 5); 15 | @include assert-false(is-number-list($test-3), 'This list contains map.'); 16 | 17 | $test-4: (1 (3 'deep' 4) 5); 18 | @include assert-false(is-number-list($test-4), 'This list contains string.'); 19 | } 20 | } -------------------------------------------------------------------------------- /src/scss/layout/_center.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get'; 2 | @import '../utilities/args-get-type'; 3 | 4 | @mixin center($key: '*'){ 5 | $check: (left right center 'selector'); 6 | $selector: args-get-type($key, 'string', $check); 7 | $align: args-get($key, (left right center), left); 8 | 9 | 10 | text-align: center; 11 | white-space: nowrap; 12 | &:before { 13 | content: ''; 14 | display: inline-block; 15 | height: 100%; 16 | vertical-align: middle; 17 | margin-right: -.25em; // adjusts for spacing 18 | } 19 | > #{$selector} { 20 | display: inline-block; 21 | vertical-align: middle; 22 | white-space: normal; 23 | @if $align != center { 24 | text-align: $align; 25 | } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tests/tests-syntax/color/_contrast.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Colors') { 2 | 3 | // Testing Functions 4 | @include test('contrast [function]') { 5 | 6 | $test1: contrast(#5173a3); 7 | $expect1: #fff; 8 | @include assert-equal($test1, $expect1, 'Returns the contrast color'); 9 | 10 | $test2: contrast(#bbf8e6); 11 | $expect2: #000; 12 | @include assert-equal($test2, $expect2, 'Returns the contrast color'); 13 | 14 | $test3: contrast(#333 'light' #f2f2f2); 15 | $expect3: #f2f2f2; 16 | @include assert-equal($test3, $expect3, 'Returns the contrast color'); 17 | 18 | $test4: contrast(#f5f5f5 'light' #f2f2f2 'dark' #333); 19 | $expect4: #333; 20 | @include assert-equal($test4, $expect4, 'Returns the contrast color'); 21 | } 22 | } -------------------------------------------------------------------------------- /tests/templates/code/input-file-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/input-file"; 3 | 4 | .container { text-align: center; } 5 | {% macro get(componentName) %} 6 | {% if componentName === "xxx" %} 7 | 8 | {% elif componentName === "input-file" %} 9 | .input-file { 10 | @include input-file() { 11 | padding: 0.8em; 12 | font-size: 18px; 13 | color: #2E92E3; 14 | figure { 15 | display: table-cell; 16 | width: 120px; 17 | height: 120px; 18 | margin: 0; 19 | border-radius: 50%; 20 | background-color: #2E92E3; 21 | text-align: center; 22 | vertical-align: middle; 23 | path { fill: #fff; } 24 | } 25 | span { display: block; } 26 | } 27 | } 28 | 29 | {% endif %} 30 | {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/off-canvas.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'off-canvas' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% block main %} 5 | {% for item in [ 6 | 'slide-in', 7 | 'slide-along', 8 | 'slide-out', 9 | 'rotate-in', 10 | 'rotate-out', 11 | 'rotate-in-reverse', 12 | 'scale-down', 13 | 'scale-up', 14 | 'open-door', 15 | 'push', 16 | 'reveal', 17 | 'drawer' 18 | ] %} 19 | 20 |

{{ item }}

21 | 22 |

23 |       {%- filter trim %}{% include 'code/off-canvas-' + item + '-code.njk' %}{% endfilter -%}
24 |     
25 | {% endfor %} 26 | {% endblock %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_args-get.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Arguments') { 2 | 3 | @include test('args-get [function]') { 4 | 5 | $args1: (map (1024px: (200px null)) left gutter 20px); 6 | $test1: args-get($args1, left); 7 | @include assert-true($test1, 'get a value from arguments.'); 8 | 9 | $args2: (map (1024px: (200px null)) left gutter 20px); 10 | $test2: args-get($args2, right); 11 | @include assert-false($test2, 'get a value from arguments.'); 12 | 13 | $base: capitalize, uppercase, lowercase, none, full-width, transform-inherit; 14 | $args3: (14px 1.4 uppercase bold); 15 | $test3: args-get($args3, $base); 16 | $expect3: uppercase; 17 | @include assert-equal($test3, $expect3, 'get a value from arguments.'); 18 | }; 19 | }; -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_to-string.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | // Testing Functions 4 | @include test('to-string [function]') { 5 | // number 6 | $test-1: to-string(16px); 7 | $expect-1: '16px'; 8 | @include assert-equal($test-1, $expect-1, 'return a string'); 9 | 10 | // color 11 | $test-2: to-string(#ccc); 12 | $expect-2: '#ccc'; 13 | @include assert-equal($test-2, $expect-2, 'return a string'); 14 | 15 | // bool 16 | $test-3: to-string(true); 17 | $expect-3: 'true'; 18 | @include assert-equal($test-3, $expect-3, 'return a string'); 19 | 20 | // string 21 | $test-4: to-string('20em'); 22 | $expect-4: '20em'; 23 | @include assert-equal($test-4, $expect-4, 'return a string'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/scss/input-file.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/input-file"; 3 | 4 | .container { text-align: center; } 5 | //=> {% macro get(componentName) %} 6 | //=> {% if componentName === "xxx" %} 7 | 8 | //=> {% elif componentName === "input-file" %} 9 | .input-file { 10 | @include input-file() { 11 | padding: 0.8em; 12 | font-size: 18px; 13 | color: #2E92E3; 14 | figure { 15 | display: table-cell; 16 | width: 120px; 17 | height: 120px; 18 | margin: 0; 19 | border-radius: 50%; 20 | background-color: #2E92E3; 21 | text-align: center; 22 | vertical-align: middle; 23 | path { fill: #fff; } 24 | } 25 | span { display: block; } 26 | } 27 | } 28 | 29 | //=> {% endif %} 30 | //=> {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/fluid-type.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'fluid-type' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 |

I, Too, Sing America

8 |

I, too, sing America.

9 |

I am the darker brother.

10 |

They send me to eat in the kitchen

11 |

When company comes,

12 |

But I laugh,

13 |

And eat well,

14 |

And grow strong.

15 |

Tomorrow,

16 |

I'll be at the table

17 |

When company comes.

18 |
19 | 20 | {% for item in [ 21 | 'h2', 22 | 'p' 23 | ] %} 24 |

25 |      {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
26 |     
27 | {% endfor %} 28 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/code/chart-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/chart"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "chart1" %} 8 | .chart1 { @include chart(( 9 | #FF6666: 8.9 10.5 19.3 21.45 10 | ) 'bar' 'steps' (2 22) 'animation' (0.6s)); } 11 | 12 | {% elif componentName === "chart2" %} 13 | .chart2 { @include chart(( 14 | #0080FF: 8.9 10.5 19.3 21.45, 15 | #FF8000: 5 10 16 22, 16 | #666666: 10.7 12 12 18 17 | ) 'column' 'steps' (2 24) 'animation' (0.6s)); } 18 | 19 | {% endif %} 20 | {% endmacro %} 21 | 22 | 23 | .chart { 24 | margin: 50px 0; 25 | li span { font-size: 14px; } 26 | &-wrap { 27 | max-width: 800px; 28 | margin: 0 auto; 29 | padding: 20px 0; 30 | h4 { font-size: 24px; } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/scss/components/_accordion.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | @import '../vendors/transition'; 3 | 4 | @mixin accordion($key: 'div'){ 5 | $selector: args-get-type($key, 'string', null, 'div'); 6 | $max-height: 1000px; 7 | $duration: 0.3s; 8 | 9 | @each $item in $key { 10 | @if type-of($item) == 'number' { 11 | @if unit($item) == 's' { 12 | $duration: $item; 13 | } @else { 14 | @if unitless($item) { $item: $item * 1px; } 15 | $max-height: $item; 16 | } 17 | } 18 | } 19 | 20 | > input { 21 | position: absolute; 22 | left: -9999px; 23 | &:checked ~ #{$selector} { 24 | max-height: $max-height; 25 | } 26 | } 27 | > #{$selector} { 28 | @include ro-transition(max-height $duration); 29 | max-height: 0; 30 | overflow: hidden; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/js/components/input-file.js: -------------------------------------------------------------------------------- 1 | // ========== inputFile ========== 2 | 3 | function inputFile (selector) { 4 | var inputs = document.querySelectorAll(selector); 5 | Array.prototype.forEach.call(inputs, function(input) 6 | { 7 | var label = input.nextElementSibling, 8 | labelVal = label.innerHTML; 9 | 10 | input.addEventListener('change', function(e) { 11 | var fileName = ''; 12 | if(this.files && this.files.length > 1) { 13 | fileName = (this.getAttribute('data-multiple-caption') || '' ).replace('{count}', this.files.length); 14 | } else { 15 | fileName = e.target.value.split('\\').pop(); 16 | } 17 | 18 | if(fileName) { 19 | label.querySelector('span').innerHTML = fileName; 20 | } else { 21 | label.innerHTML = labelVal; 22 | } 23 | }); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scss/chart.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/chart"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "chart1" %} 8 | .chart1 { @include chart(( 9 | #FF6666: 8.9 10.5 19.3 21.45 10 | ) 'bar' 'steps' (2 22) 'animation' (0.6s)); } 11 | 12 | //=> {% elif componentName === "chart2" %} 13 | .chart2 { @include chart(( 14 | #0080FF: 8.9 10.5 19.3 21.45, 15 | #FF8000: 5 10 16 22, 16 | #666666: 10.7 12 12 18 17 | ) 'column' 'steps' (2 24) 'animation' (0.6s)); } 18 | 19 | //=> {% endif %} 20 | //=> {% endmacro %} 21 | 22 | 23 | .chart { 24 | margin: 50px 0; 25 | li span { font-size: 14px; } 26 | &-wrap { 27 | max-width: 800px; 28 | margin: 0 auto; 29 | padding: 20px 0; 30 | h4 { font-size: 24px; } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_utilities.scss: -------------------------------------------------------------------------------- 1 | // *** function *** // 2 | @import "opposite"; 3 | @import "strip-unit"; 4 | @import "trigonometric"; 5 | 6 | @import "to-length"; 7 | @import "to-number"; 8 | @import "to-string"; 9 | 10 | @import "pxto"; 11 | @import "em"; 12 | @import "rem"; 13 | 14 | @import "string-slice-from"; 15 | 16 | @import "list-remove"; 17 | @import "list-remove-duplicates"; 18 | @import "list-increase"; 19 | @import "list-decrease"; 20 | @import "list-get-max"; 21 | @import "is-nested-list"; 22 | @import "is-number-list"; 23 | @import "is-number-map-list"; 24 | 25 | @import "map-update-breakpoints"; 26 | @import "is-simple-map"; 27 | 28 | @import "args-get"; 29 | @import "args-get-type"; 30 | @import "args-get-prev"; 31 | @import "args-get-next"; 32 | @import "args-get-global-breakpoints"; 33 | 34 | @import "get-TRBL"; 35 | @import "check-zero-value"; -------------------------------------------------------------------------------- /tests/templates/validation.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'validation' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | 21 | 22 | 27 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/diamond.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'diamond' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% macro box(number) %} 5 | {% for i in range(1, number + 1) %} 6 |
7 | {% endfor %} 8 | {% endmacro %} 9 | 10 | {% import 'code/' + page + '-code.njk' as fn %} 11 | {% block main %} 12 | {% for item, number in { 13 | 'diamond-count': 5, 14 | 'diamond-count-combined': 7, 15 | 'diamond-size': 8, 16 | 'diamond-breakpoints': 4, 17 | 'octagon-count': 6, 18 | 'octagon-size': 6 19 | } %} 20 | 21 |
22 | {{ box(number) }} 23 |
24 |

25 |       {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
26 |     
27 | {% endfor %} 28 | {% endblock %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_is-number-map-list.scss: -------------------------------------------------------------------------------- 1 | @include test-module('List') { 2 | 3 | @include test('is-number-map-list [function]') { 4 | 5 | // $test-1: 'Some text here.'; 6 | // @include assert-false(is-number-list($test-1), 'This is not a list.'); 7 | 8 | $test-1: (1 3 5); 9 | @include assert-true(is-number-list($test-1), 'This is a number list.'); 10 | 11 | $test-2: (1 (3 4) 5); 12 | @include assert-true(is-number-list($test-2), 'This is a number list.'); 13 | 14 | $test-3: (1 (3 : 4) 5); 15 | @include assert-false(is-number-list($test-3), 'This is a number-map list.'); 16 | 17 | $test-4: (1 (3 'deep' 4) 5); 18 | @include assert-false(is-number-list($test-4), 'This list contains string.'); 19 | 20 | $test-5: (1 ( 3 4 : 5 6) (3 false 4) 5); 21 | @include assert-false(is-number-list($test-5), 'This list contains boolean value.'); 22 | } 23 | } -------------------------------------------------------------------------------- /tests/templates/code/tooltip-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/tooltip"; 3 | 4 | div { margin: 1em 0; } 5 | .tooltip { 6 | display: inline-block; 7 | font-style: italic; 8 | border-bottom: 1px dashed #333; 9 | &:after { font-style: normal; } 10 | } 11 | 12 | {% macro get(componentName) %} 13 | {% if componentName === "xxx" %} 14 | 15 | {% elif componentName === "left" %} 16 | .left { @include tooltip(left #b02df3); } 17 | 18 | {% elif componentName === "right" %} 19 | .right { @include tooltip(0.5em right #66CCFF); } 20 | 21 | {% elif componentName === "top" %} 22 | .top { @include tooltip(top #FF8000 'content' 'The tooltip or infotip or a hint is a common graphical user interface element.'); } 23 | 24 | {% elif componentName === "bottom" %} 25 | .bottom { @include tooltip(bottom #0080FF 'content' attr(data-customize)); } 26 | 27 | {% endif %} 28 | {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/push-toggle.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'push-toggle' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |

21 |     {%- filter trim %}{{ fn.get('push-toggle') }}{% endfilter -%}
22 |   
23 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "tree": { 3 | "layout": [ 4 | "container", 5 | "grid", 6 | "gallery", 7 | "liquid", 8 | "holy-grail", 9 | "masonry", 10 | "metro", 11 | "angled-edge", 12 | "justify", 13 | "center", 14 | "diamond" 15 | ], 16 | "components": [ 17 | "button", 18 | "accordion", 19 | "chart", 20 | "checkbox", 21 | "drop-shadow", 22 | "dropdown", 23 | "flex-media", 24 | "input-file", 25 | "off-canvas", 26 | "parallelogram", 27 | "push-toggle", 28 | "responsive-table", 29 | "switch", 30 | "tab", 31 | "tooltip", 32 | "validation" 33 | ], 34 | "addons": [ 35 | "breakpoint", 36 | "color-functions", 37 | "hide-text", 38 | "quantity-query", 39 | "fluid-type", 40 | "scale-type" 41 | ] 42 | } 43 | } -------------------------------------------------------------------------------- /src/scss/utilities/_gutter-fallback.scss: -------------------------------------------------------------------------------- 1 | @import 'strip-unit'; 2 | @import 'to-length'; 3 | 4 | @function gutter-fallback ($gutter, $unit) { 5 | $width: 0; 6 | $return: $gutter; 7 | 8 | @if $unit != unit($gutter) { 9 | @if index(('px', 'pt'), unit($gutter)) != null { 10 | $width: strip-unit($gutter); 11 | } @else if index(('em', 'rem'), unit($gutter)) != null{ 12 | $width: (strip-unit($gutter) * 16); 13 | } @else if index(('%', 'vw', 'vmax'), unit($gutter)) != null{ 14 | $width: (strip-unit($gutter) * 10); 15 | } 16 | 17 | @if index(('px', 'pt'), $unit) != null { 18 | $return: to-length($width, $unit); 19 | } @else if index(('em', 'rem'), $unit) != null{ 20 | $return: to-length(($width / 16), $unit); 21 | } @else if index(('%', 'vw', 'vmax'), $unit) != null{ 22 | $return: to-length(($width / 1000), $unit); 23 | } 24 | } 25 | 26 | @return $return; 27 | } -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_args-get-prev.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Arguments') { 2 | 3 | @include test('args-get-prev [function]') { 4 | 5 | $args1: (1 of 3 by 4); 6 | $test1: args-get-prev($args1, 'by'); 7 | $expect1: 3; 8 | @include assert-equal($test1, $expect1, 'get prev item of "by".'); 9 | 10 | $args2: (map left gutter 20px); 11 | $test2: args-get-prev($args2, 'child'); 12 | $expect2: false; 13 | @include assert-equal($test2, $expect2, '"child" doesn\'t exists.'); 14 | 15 | $args3: (map left gutter); 16 | $test3: args-get-prev($args3, 'map'); 17 | $expect3: false; 18 | @include assert-equal($test3, $expect3, '"map" is the first item in "$args4".'); 19 | 20 | $args4: 'map left gutter'; 21 | $test4: args-get-prev($args4, 'gutter'); 22 | $expect4: false; 23 | @include assert-equal($test4, $expect4, 'argment is not a list.'); 24 | }; 25 | }; -------------------------------------------------------------------------------- /tests/scss/tooltip.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/tooltip"; 3 | 4 | div { margin: 1em 0; } 5 | .tooltip { 6 | display: inline-block; 7 | font-style: italic; 8 | border-bottom: 1px dashed #333; 9 | &:after { font-style: normal; } 10 | } 11 | 12 | //=> {% macro get(componentName) %} 13 | //=> {% if componentName === "xxx" %} 14 | 15 | //=> {% elif componentName === "left" %} 16 | .left { @include tooltip(left #b02df3); } 17 | 18 | //=> {% elif componentName === "right" %} 19 | .right { @include tooltip(0.5em right #66CCFF); } 20 | 21 | //=> {% elif componentName === "top" %} 22 | .top { @include tooltip(top #FF8000 'content' 'The tooltip or infotip or a hint is a common graphical user interface element.'); } 23 | 24 | //=> {% elif componentName === "bottom" %} 25 | .bottom { @include tooltip(bottom #0080FF 'content' attr(data-customize)); } 26 | 27 | //=> {% endif %} 28 | //=> {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/code/checkbox-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/checkbox"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "radio" %} 8 | .radio { 9 | @include checkbox() { 10 | padding: 4px 0 4px 26px; 11 | margin-bottom: 3px; 12 | font-size: 14px; 13 | background: url('../images/radio.png') 0 50% no-repeat; 14 | } 15 | @include checkbox-active() { 16 | background-image: url('../images/radio-active.png'); 17 | } 18 | } 19 | 20 | {% elif componentName === "checkbox" %} 21 | .checkbox { 22 | @include checkbox() { 23 | padding: 4px 0 4px 26px; 24 | margin-bottom: 3px; 25 | font-size: 14px; 26 | background: url('../images/checkbox.png') 0 50% no-repeat; 27 | } 28 | @include checkbox-active() { 29 | background-image: url('../images/checkbox-active.png'); 30 | } 31 | } 32 | 33 | {% endif %} 34 | {% endmacro %} -------------------------------------------------------------------------------- /tests/scss/checkbox.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/checkbox"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "radio" %} 8 | .radio { 9 | @include checkbox() { 10 | padding: 4px 0 4px 26px; 11 | margin-bottom: 3px; 12 | font-size: 14px; 13 | background: url('../images/radio.png') 0 50% no-repeat; 14 | } 15 | @include checkbox-active() { 16 | background-image: url('../images/radio-active.png'); 17 | } 18 | } 19 | 20 | //=> {% elif componentName === "checkbox" %} 21 | .checkbox { 22 | @include checkbox() { 23 | padding: 4px 0 4px 26px; 24 | margin-bottom: 3px; 25 | font-size: 14px; 26 | background: url('../images/checkbox.png') 0 50% no-repeat; 27 | } 28 | @include checkbox-active() { 29 | background-image: url('../images/checkbox-active.png'); 30 | } 31 | } 32 | 33 | //=> {% endif %} 34 | //=> {% endmacro %} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rocket-sass", 3 | "version": "4.0.2", 4 | "description": "Rocket is a powerful Sass framework with many common used components and utility functions, to help you build websites faster and easier.", 5 | "main": "./src/scss/rocket.scss", 6 | "directories": { 7 | "doc": "docs", 8 | "test": "tests" 9 | }, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/ganlanyuan/rocket.git" 16 | }, 17 | "keywords": [ 18 | "css", 19 | "mixins", 20 | "sass", 21 | "grid", 22 | "framework", 23 | "frontend", 24 | "scss-framework", 25 | "rocket" 26 | ], 27 | "author": "William Lin ", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/ganlanyuan/rocket/issues" 31 | }, 32 | "homepage": "https://ganlanyuan.github.io/rocket/" 33 | } 34 | -------------------------------------------------------------------------------- /tests/templates/code/breakpoint-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/breakpoint"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "num" %} 8 | .num > div { @include bp(600) { background: #FF66FF; } } 9 | 10 | {% elif componentName === "num-max" %} 11 | .num-max > div { @include bp('max' 600) { background: #FF66FF; } } 12 | 13 | {% elif componentName === "num-2-max" %} 14 | .num-2-max > div { @include bp(600 900 'max') { background: #FF66FF; } } 15 | 16 | {% elif componentName === "num-print" %} 17 | .num-print > div { @include bp(600 'print') { background: #FF66FF; } } 18 | 19 | {% elif componentName === "height" %} 20 | .height > div { @include bp(600 'height') { background: #FF66FF; } } 21 | 22 | {% elif componentName === "num-9" %} 23 | .num-9 > div { @include bp(300 400 500 600 700 800 900 1000 1100) { background: #FF66FF; } } 24 | 25 | {% endif %} 26 | {% endmacro %} 27 | 28 | [data-bp-default] { background: #eee; } -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_args-get-global-breakpoints.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Arguments') { 2 | 3 | @include test('args-get-global-breakpoints [function]') { 4 | 5 | // arg is a map 6 | $args1: ('default': 3 4); 7 | $test1: args-get-global-breakpoints($args1); 8 | $expect1: false; 9 | @include assert-equal($test1, $expect1, 'not global breakpoints.'); 10 | 11 | // args contains 2 maps 12 | $args2: ('default': (null 200px), 800px: (300px null)) ('small': 640px, 'medium': 768px); 13 | $test2: args-get-global-breakpoints($args2); 14 | $expect2: ('small': 640px, 'medium': 768px); 15 | @include assert-equal($test2, $expect2, 'get the global breakpoints.'); 16 | 17 | $args3: ('sm': 640px, 'md': 768px) ('lg': 1024px, 'xlg': 1400px); 18 | $test3: args-get-global-breakpoints($args3); 19 | $expect3: ('lg': 1024px, 'xlg': 1400px); 20 | @include assert-equal($test3, $expect3, 'more than one potential global breakpoints, get the last one.'); 21 | }; 22 | }; -------------------------------------------------------------------------------- /tests/scss/breakpoint.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/breakpoint"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "num" %} 8 | .num > div { @include bp(600) { background: #FF66FF; } } 9 | 10 | //=> {% elif componentName === "num-max" %} 11 | .num-max > div { @include bp('max' 600) { background: #FF66FF; } } 12 | 13 | //=> {% elif componentName === "num-2-max" %} 14 | .num-2-max > div { @include bp(600 900 'max') { background: #FF66FF; } } 15 | 16 | //=> {% elif componentName === "num-print" %} 17 | .num-print > div { @include bp(600 'print') { background: #FF66FF; } } 18 | 19 | //=> {% elif componentName === "height" %} 20 | .height > div { @include bp(600 'height') { background: #FF66FF; } } 21 | 22 | //=> {% elif componentName === "num-9" %} 23 | .num-9 > div { @include bp(300 400 500 600 700 800 900 1000 1100) { background: #FF66FF; } } 24 | 25 | //=> {% endif %} 26 | //=> {% endmacro %} 27 | 28 | [data-bp-default] { background: #eee; } -------------------------------------------------------------------------------- /tests/templates/metro.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'metro' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'metro-list', 8 | 'metro-list-0px', 9 | 'metro-child', 10 | 'metro-ratio', 11 | 'metro-breakpoint', 12 | 'metro-breakpoint-condition', 13 | 'metro-global-breakpoints' 14 | ] %} 15 | 16 |
17 |
    18 | {% if item === 'metro-child' %} 19 | {% set number = 4 %} 20 | {% else %} 21 | {% set number = 5 %} 22 | {% endif %} 23 | 24 | {% for i in range(1, number) %} 25 |
  • 26 | {% endfor %} 27 |
28 | 29 | {# code #} 30 |

31 |         {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
32 |       
33 |
34 | {% endfor %} 35 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/code/switch-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/switch"; 3 | 4 | .container { 5 | text-align: center; 6 | max-width: 800px; 7 | } 8 | .switch { 9 | margin: 15px auto; 10 | text-align: center; 11 | 12 | &-group { 13 | margin-top: 50px; 14 | text-align: center; 15 | } 16 | } 17 | 18 | {% macro get(componentName) %} 19 | {% if componentName === "xxx" %} 20 | 21 | {% elif componentName === "one" %} 22 | .one { @include switch('border-radius' 3px); } 23 | 24 | {% elif componentName === "two" %} 25 | .two { @include switch(#333 #C06EE1 50px 'border-radius' 1000px); } 26 | 27 | {% elif componentName === "slider" %} 28 | .slider { @include switch('slider' #ddd #399DE1 24px 'border-radius' 50%); } 29 | 30 | {% elif componentName === "text" %} 31 | .text { @include switch(#ddd #399DE1 36px 'text' ("on" "off") 'border-radius' 10em); } 32 | 33 | {% elif componentName === "switch-g" %} 34 | .switch-g { @include switch(#ddd #CC412F 25px 'border-radius' 3px); } 35 | 36 | {% endif %} 37 | {% endmacro %} -------------------------------------------------------------------------------- /tests/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | text-align: center; 3 | } 4 | 5 | body section { 6 | margin: 10% 0; 7 | } 8 | 9 | #searchbar { 10 | position: sticky; 11 | top: 0; 12 | display: block; 13 | width: 80%; 14 | height: 2.6em; 15 | margin: 20px auto 0; 16 | padding: 0 0.5em; 17 | font-size: 1.2em; 18 | -webkit-box-sizing: border-box; 19 | -moz-box-sizing: border-box; 20 | box-sizing: border-box; 21 | } 22 | 23 | .container { 24 | max-width: 1200px; 25 | margin: 0 auto; 26 | } 27 | 28 | h2 { 29 | font-size: 48px; 30 | } 31 | 32 | h3 { 33 | font-size: 36px; 34 | } 35 | 36 | li { 37 | display: inline-block; 38 | margin: 0 20px 20px 0; 39 | vertical-align: top; 40 | } 41 | 42 | li a { 43 | display: block; 44 | width: 200px; 45 | height: 200px; 46 | display: table-cell; 47 | background-color: #cfe9fc; 48 | font-size: 22px; 49 | text-transform: capitalize; 50 | font-weight: 100; 51 | vertical-align: middle; 52 | transition: background-color 0.25s; 53 | } 54 | 55 | li a:hover { 56 | background-color: #fafafa; 57 | } 58 | -------------------------------------------------------------------------------- /tests/scss/index.scss: -------------------------------------------------------------------------------- 1 | body { 2 | text-align: center; 3 | section { 4 | margin: 10% 0; 5 | } 6 | } 7 | .search-field { 8 | } 9 | #searchbar { 10 | position: sticky; 11 | top: 0; 12 | display: block; 13 | width: 80%; 14 | height: 2.6em; 15 | margin: 20px auto 0; 16 | padding: 0 0.5em; 17 | font-size: 1.2em; 18 | -webkit-box-sizing: border-box; 19 | -moz-box-sizing: border-box; 20 | box-sizing: border-box; 21 | } 22 | .container { 23 | max-width: 1200px; 24 | margin: 0 auto; 25 | } 26 | h2 { font-size: 48px; } 27 | h3 { font-size: 36px; } 28 | li { 29 | display: inline-block; 30 | margin: 0 20px 20px 0; 31 | vertical-align: top; 32 | a { 33 | display: block; 34 | width: 200px; 35 | height: 200px; 36 | display: table-cell; 37 | 38 | background-color: hsl(205, 90%, 90%); 39 | 40 | font-size: 22px; 41 | text-transform: capitalize; 42 | font-weight: 100; 43 | vertical-align: middle; 44 | transition: background-color 0.25s; 45 | &:hover { 46 | background-color: hsl(0, 0%, 98%); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /tests/scss/switch.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/switch"; 3 | 4 | .container { 5 | text-align: center; 6 | max-width: 800px; 7 | } 8 | .switch { 9 | margin: 15px auto; 10 | text-align: center; 11 | 12 | &-group { 13 | margin-top: 50px; 14 | text-align: center; 15 | } 16 | } 17 | 18 | //=> {% macro get(componentName) %} 19 | //=> {% if componentName === "xxx" %} 20 | 21 | //=> {% elif componentName === "one" %} 22 | .one { @include switch('border-radius' 3px); } 23 | 24 | //=> {% elif componentName === "two" %} 25 | .two { @include switch(#333 #C06EE1 50px 'border-radius' 1000px); } 26 | 27 | //=> {% elif componentName === "slider" %} 28 | .slider { @include switch('slider' #ddd #399DE1 24px 'border-radius' 50%); } 29 | 30 | //=> {% elif componentName === "text" %} 31 | .text { @include switch(#ddd #399DE1 36px 'text' ("on" "off") 'border-radius' 10em); } 32 | 33 | //=> {% elif componentName === "switch-g" %} 34 | .switch-g { @include switch(#ddd #CC412F 25px 'border-radius' 3px); } 35 | 36 | //=> {% endif %} 37 | //=> {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/code/index-code.njk: -------------------------------------------------------------------------------- 1 | body { 2 | text-align: center; 3 | section { 4 | margin: 10% 0; 5 | } 6 | } 7 | .search-field { 8 | } 9 | #searchbar { 10 | position: sticky; 11 | top: 0; 12 | display: block; 13 | width: 80%; 14 | height: 2.6em; 15 | margin: 20px auto 0; 16 | padding: 0 0.5em; 17 | font-size: 1.2em; 18 | -webkit-box-sizing: border-box; 19 | -moz-box-sizing: border-box; 20 | box-sizing: border-box; 21 | } 22 | .container { 23 | max-width: 1200px; 24 | margin: 0 auto; 25 | } 26 | h2 { font-size: 48px; } 27 | h3 { font-size: 36px; } 28 | li { 29 | display: inline-block; 30 | margin: 0 20px 20px 0; 31 | vertical-align: top; 32 | a { 33 | display: block; 34 | width: 200px; 35 | height: 200px; 36 | display: table-cell; 37 | 38 | background-color: hsl(205, 90%, 90%); 39 | 40 | font-size: 22px; 41 | text-transform: capitalize; 42 | font-weight: 100; 43 | vertical-align: middle; 44 | transition: background-color 0.25s; 45 | &:hover { 46 | background-color: hsl(0, 0%, 98%); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /tests/templates/code/gallery-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/gallery"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "num" %} 8 | .num > ul { @include gallery(3); } 9 | 10 | {% elif componentName === "num-0px" %} 11 | .num-0px > ul { @include gallery(3 'gutter' 0px); } 12 | 13 | {% elif componentName === "child" %} 14 | .child > div { @include gallery(4 'selector' 'div'); } 15 | 16 | {% elif componentName === "direction" %} 17 | .direction > ul { @include gallery(4 'RTL'); } 18 | 19 | {% elif componentName === "center-align" %} 20 | .center-align > ul { @include gallery(3 'center-align'); } 21 | 22 | {% elif componentName === "percentage-gutter" %} 23 | .percentage-gutter > ul { @include gallery(4 'gutter' 5%); } 24 | 25 | {% elif componentName === "rem-gutter" %} 26 | .rem-gutter > ul { @include gallery(5 'gutter' 2rem); } 27 | 28 | {% elif componentName === "map" %} 29 | .map > ul { @include gallery(( 30 | 'default': 2, 31 | 600px: 3, 32 | 900px: 4 33 | )); } 34 | 35 | {% endif %} 36 | {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/gallery.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'gallery' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import './code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'num', 8 | 'num-0px', 9 | 'child', 10 | 'direction', 11 | 'center-align', 12 | 'percentage-gutter', 13 | 'rem-gutter', 14 | 'map' 15 | ] %} 16 | 17 |
18 | {% if item === 'child' %} 19 |
20 | {% for i in range(1, 9) %} 21 |
22 | {% endfor %} 23 |
24 | {% else %} 25 |
    26 | {% for i in range(1, 9) %} 27 |
  • 28 | {% endfor %} 29 |
30 | {% endif %} 31 | 32 | {# code #} 33 |

34 |         {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
35 |       
36 |
37 | {% endfor %} 38 | 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /src/scss/utilities/_to-number.scss: -------------------------------------------------------------------------------- 1 | @import 'to-length'; 2 | 3 | @function to-number($value) { 4 | @if type-of($value) == 'number' { 5 | @return $value; 6 | } @else if type-of($value) != 'string' { 7 | $_: log('Value for `to-number` should be a number or a string.'); 8 | } 9 | 10 | $result: 0; 11 | $digits: 0; 12 | $minus: str-slice($value, 1, 1) == '-'; 13 | $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9); 14 | 15 | @for $i from if($minus, 2, 1) through str-length($value) { 16 | $character: str-slice($value, $i, $i); 17 | 18 | @if not (index(map-keys($numbers), $character) or $character == '.') { 19 | @return to-length(if($minus, -$result, $result), str-slice($value, $i)) 20 | } 21 | 22 | @if $character == '.' { 23 | $digits: 1; 24 | } @else if $digits == 0 { 25 | $result: $result * 10 + map-get($numbers, $character); 26 | } @else { 27 | $digits: $digits * 10; 28 | $result: $result + map-get($numbers, $character) / $digits; 29 | } 30 | } 31 | 32 | @return if($minus, -$result, $result);; 33 | } -------------------------------------------------------------------------------- /tests/css/reset.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | min-width: 320px; 3 | } 4 | 5 | body, 6 | figure, 7 | dl, 8 | dt, 9 | dd, 10 | ul, 11 | ol, 12 | li { 13 | margin: 0; 14 | } 15 | 16 | dl, 17 | ul, 18 | ol { 19 | padding: 0; 20 | } 21 | 22 | li { 23 | list-style: none; 24 | } 25 | 26 | img, video { 27 | max-width: 100%; 28 | height: auto; 29 | } 30 | 31 | iframe { 32 | max-width: 100%; 33 | } 34 | 35 | figure img, 36 | a > img { 37 | vertical-align: bottom; 38 | } 39 | 40 | @media \0screen { 41 | img { 42 | width: auto; 43 | } 44 | } 45 | 46 | label { 47 | cursor: pointer; 48 | } 49 | 50 | select { 51 | -webkit-appearance: none; 52 | } 53 | 54 | a { 55 | text-decoration: none; 56 | color: inherit; 57 | } 58 | 59 | body { 60 | font-family: 'Roboto', sans-serif; 61 | } 62 | 63 | button, 64 | input, 65 | select { 66 | line-height: normal !important; 67 | } 68 | 69 | button:focus, 70 | input:focus, 71 | select:focus, 72 | textarea:focus { 73 | outline: 0; 74 | } 75 | 76 | button { 77 | border: none; 78 | } 79 | 80 | pre[class*="language-"] { 81 | margin: 0 0 100px; 82 | border-radius: 0; 83 | } 84 | -------------------------------------------------------------------------------- /tests/scss/gallery.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/gallery"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "num" %} 8 | .num > ul { @include gallery(3); } 9 | 10 | //=> {% elif componentName === "num-0px" %} 11 | .num-0px > ul { @include gallery(3 'gutter' 0px); } 12 | 13 | //=> {% elif componentName === "child" %} 14 | .child > div { @include gallery(4 'selector' 'div'); } 15 | 16 | //=> {% elif componentName === "direction" %} 17 | .direction > ul { @include gallery(4 'RTL'); } 18 | 19 | //=> {% elif componentName === "center-align" %} 20 | .center-align > ul { @include gallery(3 'center-align'); } 21 | 22 | //=> {% elif componentName === "percentage-gutter" %} 23 | .percentage-gutter > ul { @include gallery(4 'gutter' 5%); } 24 | 25 | //=> {% elif componentName === "rem-gutter" %} 26 | .rem-gutter > ul { @include gallery(5 'gutter' 2rem); } 27 | 28 | //=> {% elif componentName === "map" %} 29 | .map > ul { @include gallery(( 30 | 'default': 2, 31 | 600px: 3, 32 | 900px: 4 33 | )); } 34 | 35 | //=> {% endif %} 36 | //=> {% endmacro %} -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_args-get-next.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Arguments') { 2 | 3 | @include test('args-get-next [function]') { 4 | 5 | $args1: (map (1024px: (200px null)) left gutter 20px); 6 | $test1: args-get-next($args1, 'map'); 7 | $expect1: (1024px: (200px null)); 8 | @include assert-equal($test1, $expect1, 'get a map.'); 9 | 10 | $args2: (map #ccc left gutter 20px); 11 | $test2: args-get-next($args2, 'gutter'); 12 | $expect2: 20px; 13 | @include assert-equal($test2, $expect2, 'get a gutter.'); 14 | 15 | $args3: (map left gutter 20px); 16 | $test3: args-get-next($args3, 'child'); 17 | $expect3: false; 18 | @include assert-equal($test3, $expect3, '"child" doesn\'t exists.'); 19 | 20 | $args4: (map left gutter); 21 | $test4: args-get-next($args4, 'gutter'); 22 | $expect4: false; 23 | @include assert-equal($test4, $expect4, 'Nothing after "gutter".'); 24 | 25 | $args5: 'map left gutter'; 26 | $test5: args-get-next($args5, 'gutter'); 27 | $expect5: false; 28 | @include assert-equal($test5, $expect5, 'argment is not a list.'); 29 | }; 30 | }; -------------------------------------------------------------------------------- /tests/templates/code/container-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/container"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "default" %} 8 | .default > div { @include container(); } 9 | 10 | {% elif componentName === "px-left" %} 11 | .px-left > div { @include container(900px left); } 12 | 13 | {% elif componentName === "px-right" %} 14 | .px-right > div { @include container(900px right); } 15 | 16 | {% elif componentName === "px-px" %} 17 | .px-px > div { @include container(900px gutter 30px); } 18 | 19 | {% elif componentName === "px-0px" %} 20 | .px-0px > div { @include container(900px gutter 0px); } 21 | 22 | {% elif componentName === "em" %} 23 | .em > div { @include container(56.25em); } 24 | 25 | {% elif componentName === "em-px" %} 26 | .em-px > div { @include container(56.25em gutter 20px); } 27 | 28 | {% elif componentName === "percentage" %} 29 | .percentage > div { @include container(80%); } 30 | 31 | {% elif componentName === "percentage-px" %} 32 | .percentage-px > div { @include container(80% gutter 30px); } 33 | 34 | {% endif %} 35 | {% endmacro %} 36 | -------------------------------------------------------------------------------- /tests/tests-syntax/layout/_grid.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Functions') { 2 | 3 | @include test('grid-get-columns [function]') { 4 | 5 | $test-1: grid-get-columns( 4 ); 6 | $expect-1: 4; 7 | @include assert-equal($test-1, $expect-1, 'return a number'); 8 | 9 | $test-2: grid-get-columns( (4 6 3) ); 10 | $expect-2: (4 6 3); 11 | @include assert-equal($test-2, $expect-2, 'return a list'); 12 | 13 | $test-3: grid-get-columns( (4 6 3 : 1 3 2) ); 14 | $expect-3: (4 6 3); 15 | @include assert-equal($test-3, $expect-3, 'return a list'); 16 | } 17 | 18 | @include test('grid-get-orders [function]') { 19 | 20 | $test-1: grid-get-orders( (4 6 3 : 0 2 1) ); 21 | $expect-1: (1 3 2); // (0 2 1) + (1 1 1) 22 | @include assert-equal($test-1, $expect-1, 'return a list'); 23 | 24 | $test-2: grid-get-orders( (4 6 3 : -5 2 3) ); 25 | $expect-2: (1 8 9); // (-5 2 3) + (6 6 6) 26 | @include assert-equal($test-2, $expect-2, 'return a list'); 27 | 28 | $test-3: grid-get-orders( (4 6 3 : 1 3 2) ); 29 | $expect-3: (1 3 2); 30 | @include assert-equal($test-3, $expect-3, 'return a list'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/scss/addons/_scale-type.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/power'; 2 | 3 | @mixin scale-type($key: (1em 1.15)) { 4 | $base: 1em; 5 | $scale: 1.15; 6 | $property: font-size; 7 | $reverse: true; 8 | $selectors: ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); 9 | 10 | @each $item in $key { 11 | @if type-of($item) == 'list' { 12 | $is-tag-list: true; 13 | @each $i in $item { 14 | @if $is-tag-list and type-of($i) != 'string' { $is-tag-list: false; } 15 | } 16 | 17 | @if $is-tag-list { 18 | $selectors: $item; 19 | } 20 | } @else if type-of($item) == 'string' { 21 | $property: $item; 22 | } @else if type-of($item) == 'bool' { 23 | $reverse: $item; 24 | } @else if type-of($item) == 'number' { 25 | 26 | @if unitless($item) { 27 | $scale: $item; 28 | } @else { 29 | $base: $item; 30 | } 31 | } 32 | } 33 | 34 | $len: length($selectors); 35 | $num: 1; 36 | @if $len > 0 { 37 | @for $i from 1 through length($selectors) { 38 | $num: if($reverse, $len - $i, $i - 1); 39 | #{nth($selectors, $i)} { #{$property}: $base * power($scale, $num); } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/scss/utilities/_utilities.scss: -------------------------------------------------------------------------------- 1 | // *** function *** // 2 | @import "box-sizing"; 3 | @import "opposite"; 4 | @import "strip-unit"; 5 | @import "trigonometric"; 6 | 7 | @import "to-length"; 8 | @import "to-number"; 9 | @import "to-string"; 10 | 11 | @import "pxto"; 12 | @import "em"; 13 | @import "rem"; 14 | @import "power"; 15 | 16 | @import "string-slice-from"; 17 | @import "number-odd-even"; 18 | 19 | @import "list-remove"; 20 | @import "list-remove-duplicates"; 21 | @import "list-increase"; 22 | @import "list-decrease"; 23 | @import "list-get-max"; 24 | @import "is-nested-list"; 25 | @import "is-number-list"; 26 | @import "is-number-map-list"; 27 | @import "is-liquid-list"; 28 | 29 | @import "map-update-breakpoints"; 30 | @import "is-simple-map"; 31 | 32 | @import "args-get"; 33 | @import "args-get-type"; 34 | @import "args-get-prev"; 35 | @import "args-get-next"; 36 | @import "args-get-global-breakpoints"; 37 | @import "args-get-liquid-data"; 38 | 39 | @import "get-max-breakpoint"; 40 | @import "get-TRBL"; 41 | @import "get-position-from-order"; 42 | @import "get-calc"; 43 | 44 | @import "gutter-fallback"; 45 | @import "check-zero-value"; 46 | @import "check-arg-type"; -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rocket", 3 | "version": "4.0.2", 4 | "main": [ 5 | "./src/scss/rocket.scss", 6 | "./src/js/kit.js" 7 | ], 8 | "keywords": [ 9 | "css", 10 | "mixins", 11 | "sass", 12 | "grid", 13 | "framework", 14 | "frontend", 15 | "scss-framework", 16 | "rocket" 17 | ], 18 | "authors": [ 19 | "William Lin " 20 | ], 21 | "description": "Rocket is a powerful Sass framework with many common used components and utility functions, to help you build websites faster and easier.", 22 | "license": "MIT", 23 | "ignore": [ 24 | "**/.*", 25 | ".gitignore", 26 | ".sublime-project", 27 | ".codekit", 28 | "sftp-config.json", 29 | "bower.json", 30 | "README.md", 31 | "changelog.md", 32 | "node_modules", 33 | "bower_components", 34 | "docs", 35 | "demos", 36 | "test", 37 | "tests" 38 | ], 39 | "homepage": "https://ganlanyuan.github.io/rocket/", 40 | "repository": { 41 | "type": "git", 42 | "url": "https://github.com/ganlanyuan/rocket.git" 43 | }, 44 | "dependencies": {}, 45 | "devDependencies": { 46 | "true": "^2.0.3" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/scss/reset.scss: -------------------------------------------------------------------------------- 1 | // reset 2 | // ======== 3 | 4 | // set min-width to 320 5 | html, body { min-width: 320px; } 6 | 7 | // remove margin and padding 8 | body, 9 | figure, 10 | dl, 11 | dt, 12 | dd, 13 | ul, 14 | ol, 15 | li { margin: 0; } 16 | dl, 17 | ul, 18 | ol { padding: 0; } 19 | 20 | // reset list styles 21 | li { list-style: none; } 22 | 23 | // make images & videos flexible 24 | img, video { max-width: 100%; height: auto; } 25 | iframe { max-width: 100%; } 26 | 27 | // remove the white space under images 28 | figure img, 29 | a > img { vertical-align: bottom; } 30 | 31 | // prevent an image issue on IE 8 32 | @media \0screen { img { width: auto; } } 33 | 34 | // reset form styles 35 | label { cursor: pointer; } 36 | select { -webkit-appearance: none; } 37 | 38 | // reset link style 39 | a { text-decoration: none; color: inherit; } 40 | 41 | body { font-family: 'Roboto', sans-serif; } 42 | button, 43 | input, 44 | select { line-height: normal !important; } 45 | button:focus, 46 | input:focus, 47 | select:focus, 48 | textarea:focus {outline: 0; } 49 | button { border: none; } 50 | 51 | // reset prism.css 52 | pre[class*="language-"] { 53 | margin: 0 0 100px; 54 | border-radius: 0; 55 | } -------------------------------------------------------------------------------- /src/scss/addons/_between.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get-type'; 2 | 3 | @mixin between($key) { 4 | $selector: args-get-type($key, 'string', null, '*'); 5 | $count: args-get-type($key, 'number'); 6 | $count-min: false; 7 | $count-max: false; 8 | 9 | $numbers: (); 10 | @if type-of($key) == 'list' { 11 | @each $item in $key { 12 | @if type-of($item) == 'number' { 13 | $numbers: append($numbers, $item); 14 | } @else if type-of($item) == 'list' { 15 | @each $i in $item { 16 | @if type-of($i) == 'number' { $numbers: append($numbers, $i); } 17 | } 18 | } 19 | } 20 | @if length($numbers) > 1 { 21 | $count-min: min($numbers...); 22 | $count-max: max($numbers...); 23 | } 24 | } @else { 25 | @error "A list with at least two numbers is required." 26 | } 27 | 28 | 29 | @if $count-min and 30 | $count-max and 31 | $count-max > $count-min { 32 | #{$selector}:first-child:nth-last-child(n + #{$count-min}):nth-last-child(-n + #{$count-max}), 33 | #{$selector}:first-child:nth-last-child(n + #{$count-min}):nth-last-child(-n + #{$count-max}) ~ #{$selector} { 34 | @content; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/scss/container.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/container"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "default" %} 8 | .default > div { @include container(); } 9 | 10 | //=> {% elif componentName === "px-left" %} 11 | .px-left > div { @include container(900px left); } 12 | 13 | //=> {% elif componentName === "px-right" %} 14 | .px-right > div { @include container(900px right); } 15 | 16 | //=> {% elif componentName === "px-px" %} 17 | .px-px > div { @include container(900px gutter 30px); } 18 | 19 | //=> {% elif componentName === "px-0px" %} 20 | .px-0px > div { @include container(900px gutter 0px); } 21 | 22 | //=> {% elif componentName === "em" %} 23 | .em > div { @include container(56.25em); } 24 | 25 | //=> {% elif componentName === "em-px" %} 26 | .em-px > div { @include container(56.25em gutter 20px); } 27 | 28 | //=> {% elif componentName === "percentage" %} 29 | .percentage > div { @include container(80%); } 30 | 31 | //=> {% elif componentName === "percentage-px" %} 32 | .percentage-px > div { @include container(80% gutter 30px); } 33 | 34 | //=> {% endif %} 35 | //=> {% endmacro %} 36 | -------------------------------------------------------------------------------- /tests/templates/code/reset-code.njk: -------------------------------------------------------------------------------- 1 | // reset 2 | // ======== 3 | 4 | // set min-width to 320 5 | html, body { min-width: 320px; } 6 | 7 | // remove margin and padding 8 | body, 9 | figure, 10 | dl, 11 | dt, 12 | dd, 13 | ul, 14 | ol, 15 | li { margin: 0; } 16 | dl, 17 | ul, 18 | ol { padding: 0; } 19 | 20 | // reset list styles 21 | li { list-style: none; } 22 | 23 | // make images & videos flexible 24 | img, video { max-width: 100%; height: auto; } 25 | iframe { max-width: 100%; } 26 | 27 | // remove the white space under images 28 | figure img, 29 | a > img { vertical-align: bottom; } 30 | 31 | // prevent an image issue on IE 8 32 | @media \0screen { img { width: auto; } } 33 | 34 | // reset form styles 35 | label { cursor: pointer; } 36 | select { -webkit-appearance: none; } 37 | 38 | // reset link style 39 | a { text-decoration: none; color: inherit; } 40 | 41 | body { font-family: 'Roboto', sans-serif; } 42 | button, 43 | input, 44 | select { line-height: normal !important; } 45 | button:focus, 46 | input:focus, 47 | select:focus, 48 | textarea:focus {outline: 0; } 49 | button { border: none; } 50 | 51 | // reset prism.css 52 | pre[class*="language-"] { 53 | margin: 0 0 100px; 54 | border-radius: 0; 55 | } -------------------------------------------------------------------------------- /tests/tests-syntax/utilities/_args-get-type.scss: -------------------------------------------------------------------------------- 1 | @include test-module('Arguments') { 2 | 3 | @include test('args-get-type [function]') { 4 | 5 | $args1: (map (1024px: (200px null)) left gutter 20px); 6 | $test1: args-get-type($args1, 'map'); 7 | $expect1: (1024px: (200px null)); 8 | @include assert-equal($test1, $expect1, 'get a map.'); 9 | 10 | $args2: (map (1024px: (200px null)) #ccc left gutter 20px); 11 | $test2: args-get-type($args2, 'color'); 12 | $expect2: #ccc; 13 | @include assert-equal($test2, $expect2, 'get a color.'); 14 | 15 | $args3: (map (1024px: (200px null)) left gutter 20px); 16 | $test3: args-get-type($args3, 'color'); 17 | $expect3: false; 18 | @include assert-equal($test3, $expect3, 'get a color.'); 19 | 20 | $args4: (map (1024px: (200px null)) left gutter 20px div); 21 | $test4: args-get-type($args4, 'string', (map left gutter)); 22 | $expect4: 'div'; 23 | @include assert-equal($test4, $expect4, 'get a string.'); 24 | 25 | $args5: div; 26 | $test5: args-get-type($args5, 'string'); 27 | $expect5: 'div'; 28 | @include assert-equal($test5, $expect5, 'get the only parameter string.'); 29 | }; 30 | }; -------------------------------------------------------------------------------- /src/scss/vendors/_prefixer.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | $prefix-for-webkit: true; 4 | $prefix-for-mozilla: true; 5 | $prefix-for-microsoft: true; 6 | $prefix-for-opera: true; 7 | $prefix-for-spec: true; 8 | 9 | 10 | @mixin ro-prefixer($property, $value, $prefixes) { 11 | @each $prefix in $prefixes { 12 | @if $prefix == webkit { 13 | @if $prefix-for-webkit { 14 | -webkit-#{$property}: $value; 15 | } 16 | } @else if $prefix == moz { 17 | @if $prefix-for-mozilla { 18 | -moz-#{$property}: $value; 19 | } 20 | } @else if $prefix == ms { 21 | @if $prefix-for-microsoft { 22 | -ms-#{$property}: $value; 23 | } 24 | } @else if $prefix == o { 25 | @if $prefix-for-opera { 26 | -o-#{$property}: $value; 27 | } 28 | } @else if $prefix == spec { 29 | @if $prefix-for-spec { 30 | #{$property}: $value; 31 | } 32 | } @else { 33 | @warn "Unrecognized prefix: #{$prefix}"; 34 | } 35 | } 36 | } 37 | 38 | @mixin ro-disable-prefix-for-all() { 39 | $prefix-for-webkit: false; 40 | $prefix-for-mozilla: false; 41 | $prefix-for-microsoft: false; 42 | $prefix-for-opera: false; 43 | $prefix-for-spec: false; 44 | } 45 | -------------------------------------------------------------------------------- /tests/templates/code/push-toggle-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/push-toggle"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "push-toggle" %} 8 | .push-toggle { 9 | // default push-toggle style 10 | label { 11 | padding: 0.9em 1.2em; 12 | background: #e1e1e1; 13 | background: linear-gradient(to bottom, #fff, #F4F4F4 70%, #e1e1e1); 14 | border: 1px solid #ccc; 15 | border-left-width: 0; 16 | &:first-of-type { 17 | border-top-left-radius: 3px; 18 | border-bottom-left-radius: 3px; 19 | border-left-width: 1px; 20 | } 21 | &:last-of-type { 22 | border-top-right-radius: 5px; 23 | border-bottom-right-radius: 5px; 24 | } 25 | } 26 | 27 | // active push-toggle style 28 | @include push-toggle(){ 29 | background: #f2f2f2; 30 | background: linear-gradient(to bottom, #E8E8E8, #F1F1F1 20%, #fff); 31 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1) inset; 32 | } 33 | 34 | &.two label { width: 50%; } 35 | &.three label { width: 33.3%; } 36 | } 37 | 38 | {% endif %} 39 | {% endmacro %} 40 | 41 | .push-toggle { 42 | max-width: 230px; 43 | margin: 20px auto; 44 | font-size: 14px; 45 | } -------------------------------------------------------------------------------- /tests/js/ie/matchmedia.polyfill.js: -------------------------------------------------------------------------------- 1 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 2 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 3 | 4 | (function(w){ 5 | "use strict"; 6 | w.matchMedia = w.matchMedia || (function( doc, undefined ) { 7 | 8 | var bool, 9 | docElem = doc.documentElement, 10 | refNode = docElem.firstElementChild || docElem.firstChild, 11 | // fakeBody required for 12 | fakeBody = doc.createElement( "body" ), 13 | div = doc.createElement( "div" ); 14 | 15 | div.id = "mq-test-1"; 16 | div.style.cssText = "position:absolute;top:-100em"; 17 | fakeBody.style.background = "none"; 18 | fakeBody.appendChild(div); 19 | 20 | return function(q){ 21 | 22 | div.innerHTML = "­"; 23 | 24 | docElem.insertBefore( fakeBody, refNode ); 25 | bool = div.offsetWidth === 42; 26 | docElem.removeChild( fakeBody ); 27 | 28 | return { 29 | matches: bool, 30 | media: q 31 | }; 32 | 33 | }; 34 | 35 | }( w.document )); 36 | }( this )); 37 | -------------------------------------------------------------------------------- /tests/scss/push-toggle.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/push-toggle"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "push-toggle" %} 8 | .push-toggle { 9 | // default push-toggle style 10 | label { 11 | padding: 0.9em 1.2em; 12 | background: #e1e1e1; 13 | background: linear-gradient(to bottom, #fff, #F4F4F4 70%, #e1e1e1); 14 | border: 1px solid #ccc; 15 | border-left-width: 0; 16 | &:first-of-type { 17 | border-top-left-radius: 3px; 18 | border-bottom-left-radius: 3px; 19 | border-left-width: 1px; 20 | } 21 | &:last-of-type { 22 | border-top-right-radius: 5px; 23 | border-bottom-right-radius: 5px; 24 | } 25 | } 26 | 27 | // active push-toggle style 28 | @include push-toggle(){ 29 | background: #f2f2f2; 30 | background: linear-gradient(to bottom, #E8E8E8, #F1F1F1 20%, #fff); 31 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1) inset; 32 | } 33 | 34 | &.two label { width: 50%; } 35 | &.three label { width: 33.3%; } 36 | } 37 | 38 | //=> {% endif %} 39 | //=> {% endmacro %} 40 | 41 | .push-toggle { 42 | max-width: 230px; 43 | margin: 20px auto; 44 | font-size: 14px; 45 | } -------------------------------------------------------------------------------- /tests/tests-syntax/tests.scss: -------------------------------------------------------------------------------- 1 | @import "../../bower_components/true/sass/true"; 2 | @import "../../src/scss/rocket"; 3 | 4 | @import "utilities/utilities"; 5 | @import "color/color"; 6 | @import "layout/layout"; 7 | 8 | // @include test-module('Utilities') { 9 | 10 | // // Testing Functions 11 | // @include test('Map Add [function]') { 12 | // $base: (one: 1, two: 1, three: 1); 13 | // $add: (one: 1, two: 2, three: -1); 14 | 15 | // $test: map-add($base, $add); 16 | // $expect: (one: 2, two: 3, three: 0); 17 | // @include assert-equal($test, $expect, 18 | // 'Returns the sum of two numeric maps'); 19 | // } 20 | 21 | // // Testing Mixins 22 | // @include test('Font Size [mixin]') { 23 | // @include assert('Outputs a font size and line height based on keyword.') { 24 | // @include input { 25 | // @include font-size(large); 26 | // } 27 | 28 | // @include expect { 29 | // font-size: 2rem; 30 | // line-height: 3rem; 31 | // } 32 | // } 33 | // } 34 | // } 35 | 36 | // Optionally show summary report in CSS and/or the command line: 37 | // - If you use Mocha, reporting to the command line is automatic. 38 | // - if you use true-cli, report(terminal) is required for output. 39 | @include report; -------------------------------------------------------------------------------- /src/scss/vendors/_keyframes.scss: -------------------------------------------------------------------------------- 1 | // Adds keyframes blocks for supported prefixes, removing redundant prefixes in the block's content 2 | @mixin ro-keyframes($name) { 3 | $original-prefix-for-webkit: $prefix-for-webkit; 4 | $original-prefix-for-mozilla: $prefix-for-mozilla; 5 | $original-prefix-for-microsoft: $prefix-for-microsoft; 6 | $original-prefix-for-opera: $prefix-for-opera; 7 | $original-prefix-for-spec: $prefix-for-spec; 8 | 9 | @if $original-prefix-for-webkit { 10 | @include ro-disable-prefix-for-all(); 11 | $prefix-for-webkit: true !global; 12 | @-webkit-keyframes #{$name} { 13 | @content; 14 | } 15 | } 16 | 17 | @if $original-prefix-for-mozilla { 18 | @include ro-disable-prefix-for-all(); 19 | $prefix-for-mozilla: true !global; 20 | @-moz-keyframes #{$name} { 21 | @content; 22 | } 23 | } 24 | 25 | $prefix-for-webkit: $original-prefix-for-webkit !global; 26 | $prefix-for-mozilla: $original-prefix-for-mozilla !global; 27 | $prefix-for-microsoft: $original-prefix-for-microsoft !global; 28 | $prefix-for-opera: $original-prefix-for-opera !global; 29 | $prefix-for-spec: $original-prefix-for-spec !global; 30 | 31 | @if $original-prefix-for-spec { 32 | @keyframes #{$name} { 33 | @content; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/templates/scale-type.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'scale-type' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |

Accusantium aspernatur corrupti velit quaerat, sint dolore.

7 |

Cum a, natus dolore sunt illo exercitationem.

8 |

Ab aliquam voluptates accusamus tempore iste eaque?

9 |

Error culpa, delectus explicabo temporibus veniam pariatur!

10 |
Saepe ratione dicta omnis labore, distinctio esse.
11 |
Numquam nesciunt quasi atque voluptas veniam, facilis.
12 |

13 |   {%- filter trim %}{{ fn.get('scale-type1') }}{% endfilter -%}
14 | 
15 | 16 |
Accusantium aspernatur corrupti velit quaerat, sint dolore.
17 |
Cum a, natus dolore sunt illo exercitationem.
18 |
Ab aliquam voluptates accusamus tempore iste eaque?
19 |
Error culpa, delectus explicabo temporibus veniam pariatur!
20 |

21 |   {%- filter trim %}{{ fn.get('scale-type2') }}{% endfilter -%}
22 | 
23 | 24 |
25 |
26 |
27 |
28 |

29 |   {%- filter trim %}{{ fn.get('scale-type3') }}{% endfilter -%}
30 | 
31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /tests/templates/code/angled-edge-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/angled-edge"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "bottom" %} 8 | .bottom { @include angled-edge('bottom' 5deg #B9E2FF); } 9 | 10 | {% elif componentName === "both" %} 11 | .both { @include angled-edge('both' 5deg 'flip' #B9E2FF #FBDBF6); } 12 | 13 | {% elif componentName === "top" %} 14 | .top { @include angled-edge('top' -5deg #FBDBF6); } 15 | 16 | {% endif %} 17 | {% endmacro %} 18 | 19 | // other styles 20 | .example-angled-edge { 21 | max-width: 950px; 22 | margin-left: auto; 23 | margin-right: auto; 24 | .bottom, .both, .top, .sibling { 25 | padding: 50px; 26 | h1, p { 27 | padding: 0; 28 | color: #fff; 29 | } 30 | h1 { margin: 30px 0; } 31 | p { 32 | max-width: none; 33 | font-size: 17px; 34 | } 35 | } 36 | .sibling { 37 | h1, p { color: #000; } 38 | } 39 | .bottom, .both, .top { 40 | box-sizing: border-box; 41 | background: #52ABFF 0 0 no-repeat; 42 | background-size: cover; 43 | } 44 | .sibling-1 { background-color: #B9E2FF; } 45 | .sibling-2 { background-color: #FBDBF6; } 46 | .bottom { background-image: url('../images/angled-edge/1.jpg'); } 47 | .both { background-image: url('../images/angled-edge/2.jpg'); } 48 | .top { background-image: url('../images/angled-edge/3.jpg'); } 49 | } 50 | -------------------------------------------------------------------------------- /tests/templates/code/dropdown-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/dropdown"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "dropdown-1" %} 8 | .dropdown-1 { 9 | @include dropdown('default' 'rotate' 'click'); 10 | .sub-1 { @include dropdown('default' 'left' 'rotate' 'click'); } 11 | } 12 | 13 | {% elif componentName === "dropdown-2" %} 14 | .dropdown-2 { 15 | @include dropdown('scale' 'default'); 16 | .sub-2 { 17 | @include dropdown('default' 'scale' 'right' 'hover'); 18 | } 19 | } 20 | 21 | {% endif %} 22 | {% endmacro %} 23 | 24 | .container { text-align: center; } 25 | .dropdown-1, 26 | .dropdown-2 { 27 | text-align: left; 28 | padding: 10px 0 0; 29 | margin-right: 30px; 30 | display: inline-block; 31 | vertical-align: top; 32 | > ul { 33 | z-index: 9999; 34 | } 35 | li { white-space: nowrap; } 36 | small { 37 | font-size: 12px; 38 | display: inline-block; 39 | padding: 5px 3px; 40 | } 41 | } 42 | .dropdown-1 { 43 | > label { 44 | display: inline-block; 45 | padding: 10px 0; 46 | } 47 | .sub-1 { 48 | padding-bottom: 0.62em; 49 | label { 50 | padding: 0.31em 1.25em 0.62em 1.25em; 51 | } 52 | > input:checked ~ a { background-color: #dfdfdf; } 53 | } 54 | } 55 | 56 | .dropdown-2 { 57 | > span { 58 | display: inline-block; 59 | padding: 10px 0; 60 | } 61 | } -------------------------------------------------------------------------------- /tests/scss/dropdown.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/dropdown"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "dropdown-1" %} 8 | .dropdown-1 { 9 | @include dropdown('default' 'rotate' 'click'); 10 | .sub-1 { @include dropdown('default' 'left' 'rotate' 'click'); } 11 | } 12 | 13 | //=> {% elif componentName === "dropdown-2" %} 14 | .dropdown-2 { 15 | @include dropdown('scale' 'default'); 16 | .sub-2 { 17 | @include dropdown('default' 'scale' 'right' 'hover'); 18 | } 19 | } 20 | 21 | //=> {% endif %} 22 | //=> {% endmacro %} 23 | 24 | .container { text-align: center; } 25 | .dropdown-1, 26 | .dropdown-2 { 27 | text-align: left; 28 | padding: 10px 0 0; 29 | margin-right: 30px; 30 | display: inline-block; 31 | vertical-align: top; 32 | > ul { 33 | z-index: 9999; 34 | } 35 | li { white-space: nowrap; } 36 | small { 37 | font-size: 12px; 38 | display: inline-block; 39 | padding: 5px 3px; 40 | } 41 | } 42 | .dropdown-1 { 43 | > label { 44 | display: inline-block; 45 | padding: 10px 0; 46 | } 47 | .sub-1 { 48 | padding-bottom: 0.62em; 49 | label { 50 | padding: 0.31em 1.25em 0.62em 1.25em; 51 | } 52 | > input:checked ~ a { background-color: #dfdfdf; } 53 | } 54 | } 55 | 56 | .dropdown-2 { 57 | > span { 58 | display: inline-block; 59 | padding: 10px 0; 60 | } 61 | } -------------------------------------------------------------------------------- /src/scss/setting/_variables.scss: -------------------------------------------------------------------------------- 1 | // variables 2 | //----------------------------- 3 | 4 | // layout 5 | $global-gutter: 20px !default; 6 | 7 | // setting 8 | $breakpoint-fix: true !default; 9 | 10 | // base 11 | $ro-em-base: 16px !default; 12 | $ro-rem-base: 16px !default; 13 | $ro-media-type: all, aural, braille, handheld, print, projection, screen, tty, tv, embossed !default; 14 | $ro-media-features: 'width', 'height' !default; 15 | 16 | // off-canvas 17 | $ro-off-canvas-z-index: ( 18 | 'page': 201, 19 | 'nav': 200, 20 | 'page-overlay': 199, 21 | ) !default; 22 | 23 | // color functions 24 | // get data from http://paletton.com/ 25 | $ro-normal-model: 0, 7, 12, 17, 21, 24, 27, 30, 32, 34, 36, 38, 40, 41, 44, 45, 47, 48, 50, 52, 53, 55, 56, 58, 60, 64, 67, 70, 73, 77, 80, 84, 87, 93, 99, 107, 120, 136, 147, 154, 162, 170, 180, 191, 200, 206, 212, 216, 222, 227, 233, 240, 245, 250, 254, 258, 262, 266, 270, 274, 278, 284, 291, 300, 312, 319, 326, 332, 337, 342, 347, 353, 360; 26 | 27 | $ro-ideal-model: 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300, 305, 310, 315, 320, 325, 330, 335, 340, 345, 350, 355, 360; 28 | 29 | // validation 30 | $validation-background: ( 31 | 'valid': #40B328, 32 | 'required': #272106, 33 | 'error': #FC2625, 34 | ); -------------------------------------------------------------------------------- /tests/scss/_off-canvas-base.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/off-canvas"; 3 | 4 | $off-canvas-options: ('page' '.page' 'nav' '.nav' 'submenu'); 5 | 6 | .container { max-width: 800px; } 7 | .has-bg { background-color: #000; } 8 | .hidden-checkbox { 9 | position: absolute; 10 | left: -99999px; 11 | } 12 | p { 13 | font-size: 14px; 14 | line-height: 1.5; 15 | margin-bottom: 1.5em; 16 | } 17 | .code { 18 | background: #dbdbdb; 19 | padding: 5px 10px; 20 | margin-bottom: 60px; 21 | } 22 | .menu-icon { 23 | display: block; 24 | margin: 20px; 25 | margin-left: 0; 26 | width: 21px; 27 | padding: 12px 10px; 28 | background-color: #dbdbdb; 29 | &:before, &:after { 30 | content: ''; 31 | } 32 | span, &:before, &:after { 33 | display: block; 34 | height: 2px; 35 | background-color: #000; 36 | margin-bottom: 4px; 37 | } 38 | &:after { margin-bottom: 0; } 39 | } 40 | .nav { 41 | background-color: #1975B8; 42 | a, label { 43 | font-size: 14px; 44 | padding: 12px 15px; 45 | } 46 | a, [data-back] { 47 | display: block; 48 | border-bottom: 1px solid rgba(255, 255, 255, 0.4); 49 | } 50 | a { color: #fff; } 51 | li:last-child > a { border-bottom-width: 0; } 52 | [data-submenu] { 53 | background-color: #1975B8; 54 | } 55 | } 56 | .page { 57 | background: #f2f2f2; 58 | margin-bottom: 0 !important; 59 | header { padding-top: 1px; } 60 | } 61 | .main { padding-bottom: 1px; } -------------------------------------------------------------------------------- /tests/scss/angled-edge.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/angled-edge"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "bottom" %} 8 | .bottom { @include angled-edge('bottom' 5deg #B9E2FF); } 9 | 10 | //=> {% elif componentName === "both" %} 11 | .both { @include angled-edge('both' 5deg 'flip' #B9E2FF #FBDBF6); } 12 | 13 | //=> {% elif componentName === "top" %} 14 | .top { @include angled-edge('top' -5deg #FBDBF6); } 15 | 16 | //=> {% endif %} 17 | //=> {% endmacro %} 18 | 19 | // other styles 20 | .example-angled-edge { 21 | max-width: 950px; 22 | margin-left: auto; 23 | margin-right: auto; 24 | .bottom, .both, .top, .sibling { 25 | padding: 50px; 26 | h1, p { 27 | padding: 0; 28 | color: #fff; 29 | } 30 | h1 { margin: 30px 0; } 31 | p { 32 | max-width: none; 33 | font-size: 17px; 34 | } 35 | } 36 | .sibling { 37 | h1, p { color: #000; } 38 | } 39 | .bottom, .both, .top { 40 | box-sizing: border-box; 41 | background: #52ABFF 0 0 no-repeat; 42 | background-size: cover; 43 | } 44 | .sibling-1 { background-color: #B9E2FF; } 45 | .sibling-2 { background-color: #FBDBF6; } 46 | .bottom { background-image: url('../images/angled-edge/1.jpg'); } 47 | .both { background-image: url('../images/angled-edge/2.jpg'); } 48 | .top { background-image: url('../images/angled-edge/3.jpg'); } 49 | } 50 | -------------------------------------------------------------------------------- /tests/templates/checkbox.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'checkbox' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 |
8 | 9 | 10 |
11 | 12 | 13 |
14 | 15 | 16 |
17 |
18 |
19 |

20 |     {%- filter trim %}{{ fn.get('radio') }}{% endfilter -%}
21 |   
22 | 23 |
24 |
25 | 26 | 27 |
28 | 29 | 30 |
31 | 32 | 33 |
34 |
35 |
36 |

37 |     {%- filter trim %}{{ fn.get('checkbox') }}{% endfilter -%}
38 |   
39 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/code/diamond-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/diamond"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "diamond-count" %} 8 | .diamond-count > div { @include diamond(3 'shape' 'diamond'); } 9 | 10 | {% elif componentName === "diamond-count-combined" %} 11 | .diamond-count-combined > div { @include diamond(3 'shape' 'diamond' 'tight'); } 12 | 13 | {% elif componentName === "diamond-size" %} 14 | .diamond-size > div { @include diamond(25%); } 15 | 16 | {% elif componentName === "diamond-breakpoints" %} 17 | .diamond-breakpoints > div { @include diamond(( 18 | 600px:3, 19 | 800px:4 20 | ) 'shape' 'diamond'); } 21 | 22 | {% elif componentName === "octagon-count" %} 23 | .octagon-count > div { @include diamond(4 'shape' 'octagon'); } 24 | 25 | {% elif componentName === "octagon-size" %} 26 | .octagon-size > div { @include diamond(300px 'shape' 'octagon'); } 27 | 28 | {% endif %} 29 | {% endmacro %} 30 | 31 | .container { max-width: 900px; } 32 | .demo:after { 33 | content: ''; 34 | display: table; 35 | clear: both; 36 | } 37 | .order span:after { 38 | display: block; 39 | position: relative; 40 | top: -180px; 41 | top: -16vw; 42 | text-align: center; 43 | color: #fff; 44 | font-weight: 100; 45 | font-size: 60px; 46 | font-family: 'Helvetica Neue',Arial,sans-serif; 47 | } 48 | @for $i from 1 through 8 { 49 | .order:nth-child(#{$i}) span:after { content: '#{$i}'; } 50 | } 51 | -------------------------------------------------------------------------------- /tests/templates/code/metro-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/metro"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "metro-list" %} 8 | .metro-list > ul { @include metro((w1 w3 h2 w4 of 5) 'gutter' 10px); } 9 | 10 | {% elif componentName === "metro-list-0px" %} 11 | .metro-list-0px > ul { @include metro((w1 w3 h2 w4 of 5) 'gutter' 0px); } 12 | 13 | {% elif componentName === "metro-child" %} 14 | .metro-child > ul { @include metro((w2h3 w3h1 w3h2 of 5) 'selector' '.child' 'gutter' 5%); } 15 | 16 | {% elif componentName === "metro-ratio" %} 17 | .metro-ratio > ul { @include metro((w1 w3 w3 w1 of 4) 'ratio' (9/16) 'gutter' 10px); } 18 | 19 | {% elif componentName === "metro-breakpoint" %} 20 | .metro-breakpoint > ul { @include metro(( 21 | 600px: w6h1 w2h2 w4h2 of 6 22 | ) 'gutter' 10px); } 23 | 24 | {% elif componentName === "metro-breakpoint-condition" %} 25 | .metro-breakpoint-condition > ul { @include metro(( 26 | 900px: w2h2 w2 w2 of 4 27 | ) 'gutter' 10px 'max' 'screen'); } 28 | 29 | {% elif componentName === "metro-global-breakpoints" %} 30 | .metro-global-breakpoints > ul { @include metro(( 31 | 'default': w6 w2 w4 of 6, 32 | 'sm': w2h3 w4 w4h2 of 6, 33 | 'md': w3h2 w3 w3 of 6 34 | ) $global-bps 'gutter' 10px); } 35 | 36 | {% endif %} 37 | {% endmacro %} 38 | 39 | .container { max-width: 800px; } 40 | .metro-list li:nth-child(3) { float: right; } 41 | .metro-list-0px li:nth-child(3) { float: right; } -------------------------------------------------------------------------------- /tests/templates/grid.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'grid' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% macro box(number) %} 5 |
6 | {% for i in range(1, number + 1) %} 7 |
8 | {% endfor %} 9 |
10 | {% endmacro %} 11 | 12 | {% import 'code/' + page + '-code.njk' as fn %} 13 | {% block main %} 14 | {% for item, number in { 15 | 'list': 2, 16 | 'child': 2, 17 | 'gutter1': 2, 18 | 'gutter2': 2, 19 | 'list-direction': 2, 20 | 'nested-list': 3, 21 | 'map1': 4, 22 | 'map2': 4, 23 | 'breakpoint': 2, 24 | 'breakpoint-outside': 2, 25 | 'global-breakpoints': 2, 26 | 'breakpoint-max': 2, 27 | 'breakpoint-nested-list': 5, 28 | 'breakpoint-map1': 5, 29 | 'breakpoint-map2': 5, 30 | 'breakpoint-default': 2, 31 | 'breakpoint-complex-list': 5 32 | } %} 33 | 34 |
35 | 36 | {% if item === 'child' %} 37 |
38 |
39 | 40 |
41 | {% else %} 42 | {{ box(number) }} 43 | {% endif %} 44 | 45 |

46 |         {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
47 |       
48 |
49 | 50 | {% endfor %} 51 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/liquid.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'liquid' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 | {% for item in [ 8 | 'liquid-list', 9 | 'liquid-order1', 10 | 'liquid-order2', 11 | 'liquid-RTL', 12 | 'liquid-selector1', 13 | 'liquid-selector2', 14 | 'liquid-gutter-0px', 15 | 'liquid-gutter-sameunit', 16 | 'liquid-gutter-percentage', 17 | 'liquid-gutter-differentunit', 18 | 'liquid-breakpoint1', 19 | 'liquid-breakpoint2', 20 | 'liquid-breakpoint-default1', 21 | 'liquid-breakpoint-default2', 22 | 'liquid-breakpoint-max', 23 | 'liquid-global-breakpoints' 24 | ] %} 25 | 26 |
27 |
28 | {% if item === 'liquid-selector2' %} 29 |
30 | 31 | {% else %} 32 |
33 |
34 | {% endif %} 35 |
36 | 37 | {# code #} 38 |

39 |           {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
40 |         
41 |
42 | {% endfor %} 43 |
44 | {% endblock %} 45 | -------------------------------------------------------------------------------- /tests/scss/diamond.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/diamond"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "diamond-count" %} 8 | .diamond-count > div { @include diamond(3 'shape' 'diamond'); } 9 | 10 | //=> {% elif componentName === "diamond-count-combined" %} 11 | .diamond-count-combined > div { @include diamond(3 'shape' 'diamond' 'tight'); } 12 | 13 | //=> {% elif componentName === "diamond-size" %} 14 | .diamond-size > div { @include diamond(25%); } 15 | 16 | //=> {% elif componentName === "diamond-breakpoints" %} 17 | .diamond-breakpoints > div { @include diamond(( 18 | 600px:3, 19 | 800px:4 20 | ) 'shape' 'diamond'); } 21 | 22 | //=> {% elif componentName === "octagon-count" %} 23 | .octagon-count > div { @include diamond(4 'shape' 'octagon'); } 24 | 25 | //=> {% elif componentName === "octagon-size" %} 26 | .octagon-size > div { @include diamond(300px 'shape' 'octagon'); } 27 | 28 | //=> {% endif %} 29 | //=> {% endmacro %} 30 | 31 | .container { max-width: 900px; } 32 | .demo:after { 33 | content: ''; 34 | display: table; 35 | clear: both; 36 | } 37 | .order span:after { 38 | display: block; 39 | position: relative; 40 | top: -180px; 41 | top: -16vw; 42 | text-align: center; 43 | color: #fff; 44 | font-weight: 100; 45 | font-size: 60px; 46 | font-family: 'Helvetica Neue',Arial,sans-serif; 47 | } 48 | @for $i from 1 through 8 { 49 | .order:nth-child(#{$i}) span:after { content: '#{$i}'; } 50 | } 51 | -------------------------------------------------------------------------------- /src/scss/layout/_container.scss: -------------------------------------------------------------------------------- 1 | @import '../vendors/clearfix'; 2 | @import '../setting/variables'; 3 | @import '../utilities/args-get'; 4 | @import '../utilities/args-get-next'; 5 | @import '../utilities/check-zero-value'; 6 | @import '../utilities/list-remove'; 7 | @import '../utilities/opposite'; 8 | 9 | @mixin container($key: false){ 10 | $container: false; 11 | $gutter: args-get-next($key, 'gutter', $global-gutter); 12 | // strip unit when gutter == 0 13 | $gutter: check-zero-value($gutter); 14 | $align: args-get($key, (left right center), center); 15 | 16 | // get container & gutter 17 | @if type-of($key) == 'number' { 18 | $container: $key; 19 | } @else if type-of($key) == list { 20 | @if index($key, 'gutter') { 21 | $key: list-remove($key, $gutter); 22 | } 23 | @each $item in $key { 24 | @if type-of($item) == 'number'{ 25 | @if not $container { 26 | $container: $item; 27 | } @else { 28 | $gutter: $item; 29 | } 30 | } 31 | } 32 | } 33 | @if not $container { $container: 1060px; } 34 | 35 | 36 | @extend %clearfix; 37 | // pecentage container: 80% 38 | @if unit($container) == '%' { 39 | padding: 0 ((100% - $container) / 2); 40 | 41 | // px or em container: 1000px 42 | } @else { 43 | max-width: $container; 44 | @if $gutter != 0 { padding: 0 $gutter; } 45 | @if $align == center { 46 | margin-left: auto; 47 | margin-right: auto; 48 | } @else { 49 | margin-#{opposite($align)}: auto; 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /tests/scss/metro.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/metro"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "metro-list" %} 8 | .metro-list > ul { @include metro((w1 w3 h2 w4 of 5) 'gutter' 10px); } 9 | 10 | //=> {% elif componentName === "metro-list-0px" %} 11 | .metro-list-0px > ul { @include metro((w1 w3 h2 w4 of 5) 'gutter' 0px); } 12 | 13 | //=> {% elif componentName === "metro-child" %} 14 | .metro-child > ul { @include metro((w2h3 w3h1 w3h2 of 5) 'selector' '.child' 'gutter' 5%); } 15 | 16 | //=> {% elif componentName === "metro-ratio" %} 17 | .metro-ratio > ul { @include metro((w1 w3 w3 w1 of 4) 'ratio' (9/16) 'gutter' 10px); } 18 | 19 | //=> {% elif componentName === "metro-breakpoint" %} 20 | .metro-breakpoint > ul { @include metro(( 21 | 600px: w6h1 w2h2 w4h2 of 6 22 | ) 'gutter' 10px); } 23 | 24 | //=> {% elif componentName === "metro-breakpoint-condition" %} 25 | .metro-breakpoint-condition > ul { @include metro(( 26 | 900px: w2h2 w2 w2 of 4 27 | ) 'gutter' 10px 'max' 'screen'); } 28 | 29 | //=> {% elif componentName === "metro-global-breakpoints" %} 30 | .metro-global-breakpoints > ul { @include metro(( 31 | 'default': w6 w2 w4 of 6, 32 | 'sm': w2h3 w4 w4h2 of 6, 33 | 'md': w3h2 w3 w3 of 6 34 | ) $global-bps 'gutter' 10px); } 35 | 36 | //=> {% endif %} 37 | //=> {% endmacro %} 38 | 39 | .container { max-width: 800px; } 40 | .metro-list li:nth-child(3) { float: right; } 41 | .metro-list-0px li:nth-child(3) { float: right; } -------------------------------------------------------------------------------- /src/scss/color/_contrast.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:math'; 2 | 3 | @import '../utilities/args-get-type'; 4 | @import '../utilities/args-get-next'; 5 | @import '../utilities/list-remove'; 6 | @import '../utilities/trigonometric'; 7 | 8 | @function contrast($key) { 9 | $light: args-get-next($key, 'light', #fff); 10 | $dark: args-get-next($key, 'dark', #000); 11 | 12 | @if type-of($key) == 'list' { 13 | $key: list-remove($key, $light); 14 | $key: list-remove($key, $dark); 15 | } 16 | $color: args-get-type($key, 'color'); 17 | 18 | @if $color { 19 | @if brightness($color) < 65% { 20 | @return $light; 21 | } @else { 22 | @return $dark; 23 | } 24 | } 25 | } 26 | 27 | // From John W. Long jlong 28 | // Brightness math based on: 29 | // http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx 30 | $red-magic-number: 241; 31 | $green-magic-number: 691; 32 | $blue-magic-number: 68; 33 | $brightness-divisor: $red-magic-number + $green-magic-number + $blue-magic-number; 34 | 35 | @function brightness($color) { 36 | // Extract color components 37 | $red-component: red($color); 38 | $green-component: green($color); 39 | $blue-component: blue($color); 40 | 41 | // Calculate a brightness value in 3d color space between 0 and 255 42 | $number: sqrt((($red-component * $red-component * $red-magic-number) + ($green-component * $green-component * $green-magic-number) + ($blue-component * $blue-component * $blue-magic-number)) / $brightness-divisor); 43 | 44 | // Convert to percentage and return 45 | @return math.div(100% * $number, 255); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /tests/templates/input-file.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'input-file' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 |
7 |
8 | 9 | 15 |
16 |
17 |

18 |     {%- filter trim %}{{ fn.get('input-file') }}{% endfilter -%}
19 |   
20 | 21 | 22 | 29 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/code/drop-shadow-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/drop-shadow"; 3 | 4 | body { 5 | background-color: #f2f2f2; 6 | } 7 | .container { 8 | text-align: center; 9 | max-width: 700px; 10 | &:before { 11 | content: ''; 12 | clear: both; 13 | display: table; 14 | } 15 | } 16 | .box { 17 | margin: 20px; 18 | padding: 15% 0; 19 | width: 70%; 20 | margin-left: 15%; 21 | box-sizing: border-box; 22 | box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.2); 23 | } 24 | 25 | {% macro get(componentName) %} 26 | {% if componentName === "xxx" %} 27 | 28 | {% elif componentName === "lifted" %} 29 | .lifted { @include drop-shadow('lifted' 20px); } 30 | 31 | {% elif componentName === "raised" %} 32 | .raised { @include drop-shadow('raised' 20px); } 33 | 34 | {% elif componentName === "perspective" %} 35 | .perspective { @include drop-shadow('perspective' 20px); } 36 | 37 | {% elif componentName === "curve-left" %} 38 | .curve-left { @include drop-shadow('curve' 'left' 20px); } 39 | 40 | {% elif componentName === "curve-right" %} 41 | .curve-right { @include drop-shadow('curve' 'right' 20px); } 42 | 43 | {% elif componentName === "curve-horizontal" %} 44 | .curve-horizontal { @include drop-shadow('curve' 'horizontal' 20px); } 45 | 46 | {% elif componentName === "curve-top" %} 47 | .curve-top { @include drop-shadow('curve' 'top' 20px); } 48 | 49 | {% elif componentName === "curve-bottom" %} 50 | .curve-bottom { @include drop-shadow('curve' 'bottom' 20px); } 51 | 52 | {% elif componentName === "curve-vertical" %} 53 | .curve-vertical { @include drop-shadow('curve' 'vertical' 20px); } 54 | 55 | {% endif %} 56 | {% endmacro %} -------------------------------------------------------------------------------- /tests/scss/drop-shadow.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/drop-shadow"; 3 | 4 | body { 5 | background-color: #f2f2f2; 6 | } 7 | .container { 8 | text-align: center; 9 | max-width: 700px; 10 | &:before { 11 | content: ''; 12 | clear: both; 13 | display: table; 14 | } 15 | } 16 | .box { 17 | margin: 20px; 18 | padding: 15% 0; 19 | width: 70%; 20 | margin-left: 15%; 21 | box-sizing: border-box; 22 | box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.2); 23 | } 24 | 25 | //=> {% macro get(componentName) %} 26 | //=> {% if componentName === "xxx" %} 27 | 28 | //=> {% elif componentName === "lifted" %} 29 | .lifted { @include drop-shadow('lifted' 20px); } 30 | 31 | //=> {% elif componentName === "raised" %} 32 | .raised { @include drop-shadow('raised' 20px); } 33 | 34 | //=> {% elif componentName === "perspective" %} 35 | .perspective { @include drop-shadow('perspective' 20px); } 36 | 37 | //=> {% elif componentName === "curve-left" %} 38 | .curve-left { @include drop-shadow('curve' 'left' 20px); } 39 | 40 | //=> {% elif componentName === "curve-right" %} 41 | .curve-right { @include drop-shadow('curve' 'right' 20px); } 42 | 43 | //=> {% elif componentName === "curve-horizontal" %} 44 | .curve-horizontal { @include drop-shadow('curve' 'horizontal' 20px); } 45 | 46 | //=> {% elif componentName === "curve-top" %} 47 | .curve-top { @include drop-shadow('curve' 'top' 20px); } 48 | 49 | //=> {% elif componentName === "curve-bottom" %} 50 | .curve-bottom { @include drop-shadow('curve' 'bottom' 20px); } 51 | 52 | //=> {% elif componentName === "curve-vertical" %} 53 | .curve-vertical { @include drop-shadow('curve' 'vertical' 20px); } 54 | 55 | //=> {% endif %} 56 | //=> {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/holy-grail.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'holy-grail' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'holy-grail-list1', 8 | 'holy-grail-list2', 9 | 'holy-grail-list3', 10 | 'holy-grail-order1', 11 | 'holy-grail-order2', 12 | 'holy-grail-order3', 13 | 'holy-grail-order4', 14 | 'holy-grail-order5', 15 | 'holy-grail-order6', 16 | 'holy-grail-RTL', 17 | 'holy-grail-selector1', 18 | 'holy-grail-selector2', 19 | 'holy-grail-gutter-0px', 20 | 'holy-grail-gutter-sameunit', 21 | 'holy-grail-gutter-percentage', 22 | 'holy-grail-gutter-differentunit', 23 | 'holy-grail-breakpoint1', 24 | 'holy-grail-breakpoint2', 25 | 'holy-grail-default-breakpoint1', 26 | 'holy-grail-default-breakpoint2', 27 | 'holy-grail-breakpoint-conditions', 28 | 'holy-grail-global-breakpoints' 29 | ] %} 30 | 31 |
32 |
33 | {% if item === 'holy-grail-selector2' %} 34 | 35 |
36 | 37 | {% else %} 38 | {% for i in range(1, 4) %} 39 |
40 | {% endfor %} 41 | {% endif %} 42 |
43 | 44 | {# code #} 45 |

46 |         {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
47 |       
48 |
49 | {% endfor %} 50 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/button.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'button' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'default', 8 | 'color', 9 | 'style-highlight', 10 | 'style-simple', 11 | 'style-slide', 12 | 'style-ripple', 13 | 'style-veil', 14 | 'style-cut', 15 | 'style-push', 16 | 'style-bubble', 17 | 'style-line-drawing', 18 | 'style-shake' 19 | ] %} 20 |
21 | {% set text = item | replace('style-', '') %} 22 | 23 | {% if item === 'default' %} 24 | 25 | {% elif item === 'color' %} 26 | {{ text }} 27 | {% elif item === 'style-push' %} 28 |
29 |
{{ text }}
30 |
31 | {% elif item === 'style-line-drawing' %} 32 |
{{ text }} 33 | 34 | 35 | 36 | 37 |
38 | {% else %} 39 |
{{ text }}
40 | {% endif %} 41 | 42 |

43 |         {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
44 |       
45 |
46 | {% endfor %} 47 | 57 | {% endblock %} -------------------------------------------------------------------------------- /src/scss/vendors/_animation.scss: -------------------------------------------------------------------------------- 1 | @import 'prefixer'; 2 | 3 | // http://www.w3.org/TR/css3-animations/#the-animation-name-property- 4 | // Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties. 5 | 6 | @mixin ro-animation($animations...) { 7 | @include ro-prefixer(animation, $animations, webkit moz spec); 8 | } 9 | 10 | @mixin ro-animation-name($names...) { 11 | @include ro-prefixer(animation-name, $names, webkit moz spec); 12 | } 13 | 14 | @mixin ro-animation-duration($times...) { 15 | @include ro-prefixer(animation-duration, $times, webkit moz spec); 16 | } 17 | 18 | @mixin ro-animation-timing-function($motions...) { 19 | // ease | linear | ease-in | ease-out | ease-in-out 20 | @include ro-prefixer(animation-timing-function, $motions, webkit moz spec); 21 | } 22 | 23 | @mixin ro-animation-iteration-count($values...) { 24 | // infinite | 25 | @include ro-prefixer(animation-iteration-count, $values, webkit moz spec); 26 | } 27 | 28 | @mixin ro-animation-direction($directions...) { 29 | // normal | alternate 30 | @include ro-prefixer(animation-direction, $directions, webkit moz spec); 31 | } 32 | 33 | @mixin ro-animation-play-state($states...) { 34 | // running | paused 35 | @include ro-prefixer(animation-play-state, $states, webkit moz spec); 36 | } 37 | 38 | @mixin ro-animation-delay($times...) { 39 | @include ro-prefixer(animation-delay, $times, webkit moz spec); 40 | } 41 | 42 | @mixin ro-animation-fill-mode($modes...) { 43 | // none | forwards | backwards | both 44 | @include ro-prefixer(animation-fill-mode, $modes, webkit moz spec); 45 | } 46 | -------------------------------------------------------------------------------- /tests/templates/code/accordion-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/accordion"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "string" %} 8 | .string > div { @include accordion('div'); } 9 | 10 | {% elif componentName === "string-height" %} 11 | .string-height > div { @include accordion('div' 200px); } 12 | 13 | {% elif componentName === "string-duration" %} 14 | .string-duration > div { @include accordion('div' 0.4s); } 15 | 16 | {% elif componentName === "string-height-duration" %} 17 | .string-height-duration > div { @include accordion('.nav' 200px 0.4s); } 18 | 19 | {% endif %} 20 | {% endmacro %} 21 | 22 | label { 23 | display: block; 24 | border: 1px solid #BABABA; 25 | strong { 26 | display: block; 27 | font-size: 13px; 28 | margin: 0; 29 | padding: 10px; 30 | } 31 | } 32 | .container { max-width: 800px; } 33 | .acc { 34 | &-1 label { 35 | background-color: #F8F0E2; 36 | border-color: #E3D19D; 37 | } 38 | &-2 label { 39 | background-color: #D7F2F8; 40 | border-color: #AACED7; 41 | } 42 | &-3 label { 43 | background-color: #EDE2F8; 44 | border-color: #D6C7E6; 45 | } 46 | } 47 | .header { 48 | padding: 15px; 49 | color: #fff; 50 | background-color: #E7435C; 51 | .menu-icon { 52 | display: block; 53 | width: 21px; 54 | border-width: 0; 55 | &:before, &:after { 56 | content: ''; 57 | } 58 | span, &:before, &:after { 59 | display: block; 60 | height: 2px; 61 | background-color: #fff; 62 | margin-bottom: 4px; 63 | } 64 | &:after { margin-bottom: 0; } 65 | } 66 | .nav { 67 | ul { padding: 10px 0; } 68 | li { 69 | font-size: 14px; 70 | padding: 10px 0; 71 | } 72 | } 73 | a { color: #fff; } 74 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rocket v4 2 | 3 | ![Version](https://img.shields.io/badge/Version-4.0.2-blue.svg) 4 | Rocket is a powerful Sass framework with many common used components and utility functions, to help you build websites faster and easier. 5 | 6 | ## What's new in version 4 7 | - Add `scale-type`. 8 | - Simplify layout mixins (remove flex-box, IE8 classes). 9 | - Rename `liquid-2` to `liquid`, `liquid-3` to `holy-grail`, `angled-edges` to `angled-edge`, `tabs` to `tab`, `drop-shadows` to `drop-shadow`, `charts` to `chart`. 10 | - Remove `slider-carousel`, `slider-gallery`, `sticky-footer`, `priority-nav`, `type`, `responsive-type`, `rems`, `opacity`, `ie-rgba`, `media-list`. 11 | - Remove kit.js. 12 | - Drop IE8 support. 13 | - More improves and fixes [see here](https://github.com/ganlanyuan/rocket/releases/tag/v4.0.2). 14 | 15 | 16 | [version 2](https://github.com/ganlanyuan/rocket/tree/v2) 17 | [version 3](https://github.com/ganlanyuan/rocket/tree/v3) 18 | 19 | ## Requests 20 | + Please replace `` with the markup below for better IE support. 21 | ``` html 22 | 23 | 24 | 25 | ``` 26 | 27 | ## Install 28 | 29 | ```` bash 30 | $ bower install rocket --save 31 | ```` 32 | 33 | ## Docs 34 | [Guide](https://ganlanyuan.github.io/rocket.site/v3/guide.html) 35 | [Docs](https://ganlanyuan.github.io/rocket.site/v4/docs.html) 36 | 37 | 38 | ## Supports 39 | [BrowserStack BrowserStack](http://www.browserstack.com/) 40 | 41 | ## License 42 | This project is available under the MIT license. 43 | -------------------------------------------------------------------------------- /tests/scss/accordion.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/accordion"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "string" %} 8 | .string > div { @include accordion('div'); } 9 | 10 | //=> {% elif componentName === "string-height" %} 11 | .string-height > div { @include accordion('div' 200px); } 12 | 13 | //=> {% elif componentName === "string-duration" %} 14 | .string-duration > div { @include accordion('div' 0.4s); } 15 | 16 | //=> {% elif componentName === "string-height-duration" %} 17 | .string-height-duration > div { @include accordion('.nav' 200px 0.4s); } 18 | 19 | //=> {% endif %} 20 | //=> {% endmacro %} 21 | 22 | label { 23 | display: block; 24 | border: 1px solid #BABABA; 25 | strong { 26 | display: block; 27 | font-size: 13px; 28 | margin: 0; 29 | padding: 10px; 30 | } 31 | } 32 | .container { max-width: 800px; } 33 | .acc { 34 | &-1 label { 35 | background-color: #F8F0E2; 36 | border-color: #E3D19D; 37 | } 38 | &-2 label { 39 | background-color: #D7F2F8; 40 | border-color: #AACED7; 41 | } 42 | &-3 label { 43 | background-color: #EDE2F8; 44 | border-color: #D6C7E6; 45 | } 46 | } 47 | .header { 48 | padding: 15px; 49 | color: #fff; 50 | background-color: #E7435C; 51 | .menu-icon { 52 | display: block; 53 | width: 21px; 54 | border-width: 0; 55 | &:before, &:after { 56 | content: ''; 57 | } 58 | span, &:before, &:after { 59 | display: block; 60 | height: 2px; 61 | background-color: #fff; 62 | margin-bottom: 4px; 63 | } 64 | &:after { margin-bottom: 0; } 65 | } 66 | .nav { 67 | ul { padding: 10px 0; } 68 | li { 69 | font-size: 14px; 70 | padding: 10px 0; 71 | } 72 | } 73 | a { color: #fff; } 74 | } -------------------------------------------------------------------------------- /tests/templates/code/quantity-query-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/at-least"; 3 | @import "../../src/scss/addons/at-most"; 4 | @import "../../src/scss/addons/equal-to"; 5 | @import "../../src/scss/addons/between"; 6 | 7 | {% macro get(componentName) %} 8 | {% if componentName === "xxx" %} 9 | 10 | {% elif componentName === "at-least" %} 11 | .at-least { 12 | @include at-least('.box' 4) { background-color: #FF49A6; } 13 | } 14 | 15 | {% elif componentName === "at-most" %} 16 | .at-most { 17 | @include at-most('.box' 4) { background-color: #FF49A6; } 18 | } 19 | 20 | {% elif componentName === "equal-to" %} 21 | .equal-to { 22 | @include equal-to('.box' 4) { background-color: #FF49A6; } 23 | } 24 | 25 | {% elif componentName === "between" %} 26 | .between { 27 | @include between('.box' 3 6) { background-color: #FF49A6; } 28 | } 29 | 30 | {% endif %} 31 | {% endmacro %} 32 | 33 | .quantity-query { text-align: center; } 34 | .control { 35 | margin-bottom: 20px; 36 | input { 37 | font-size: 14px; 38 | padding: 0.6em 1.1em; 39 | border-width: 0; 40 | border-radius: 3px; 41 | background: #cbcbcb; 42 | cursor: pointer; 43 | } 44 | .active { 45 | color: #fff; 46 | background-color: #333; 47 | &:hover { 48 | background-color: #222; 49 | } 50 | } 51 | .action { 52 | background: #f2f2f2; 53 | } 54 | } 55 | .show { 56 | margin-bottom: 40px; 57 | &:after { 58 | content: ''; 59 | display: table; 60 | clear: both; 61 | } 62 | > .box { 63 | display: inline-block; 64 | width: 150px; 65 | height: 150px; 66 | margin: 0 5px 10px; 67 | background-color: #56AFEE; 68 | } 69 | } 70 | .info { 71 | color: #666; 72 | font-size: 13px; 73 | margin-left: 10px; 74 | span { color: #ff49a6; } 75 | } 76 | pre[class*="language-"] { margin-bottom: 20px; } -------------------------------------------------------------------------------- /tests/scss/quantity-query.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/addons/at-least"; 3 | @import "../../src/scss/addons/at-most"; 4 | @import "../../src/scss/addons/equal-to"; 5 | @import "../../src/scss/addons/between"; 6 | 7 | //=> {% macro get(componentName) %} 8 | //=> {% if componentName === "xxx" %} 9 | 10 | //=> {% elif componentName === "at-least" %} 11 | .at-least { 12 | @include at-least('.box' 4) { background-color: #FF49A6; } 13 | } 14 | 15 | //=> {% elif componentName === "at-most" %} 16 | .at-most { 17 | @include at-most('.box' 4) { background-color: #FF49A6; } 18 | } 19 | 20 | //=> {% elif componentName === "equal-to" %} 21 | .equal-to { 22 | @include equal-to('.box' 4) { background-color: #FF49A6; } 23 | } 24 | 25 | //=> {% elif componentName === "between" %} 26 | .between { 27 | @include between('.box' 3 6) { background-color: #FF49A6; } 28 | } 29 | 30 | //=> {% endif %} 31 | //=> {% endmacro %} 32 | 33 | .quantity-query { text-align: center; } 34 | .control { 35 | margin-bottom: 20px; 36 | input { 37 | font-size: 14px; 38 | padding: 0.6em 1.1em; 39 | border-width: 0; 40 | border-radius: 3px; 41 | background: #cbcbcb; 42 | cursor: pointer; 43 | } 44 | .active { 45 | color: #fff; 46 | background-color: #333; 47 | &:hover { 48 | background-color: #222; 49 | } 50 | } 51 | .action { 52 | background: #f2f2f2; 53 | } 54 | } 55 | .show { 56 | margin-bottom: 40px; 57 | &:after { 58 | content: ''; 59 | display: table; 60 | clear: both; 61 | } 62 | > .box { 63 | display: inline-block; 64 | width: 150px; 65 | height: 150px; 66 | margin: 0 5px 10px; 67 | background-color: #56AFEE; 68 | } 69 | } 70 | .info { 71 | color: #666; 72 | font-size: 13px; 73 | margin-left: 10px; 74 | span { color: #ff49a6; } 75 | } 76 | pre[class*="language-"] { margin-bottom: 20px; } -------------------------------------------------------------------------------- /tests/templates/code/responsive-table-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/responsive-table"; 3 | 4 | table { 5 | text-align: left; 6 | width: 100%; 7 | font-size: 13px; 8 | border: 1px solid #dbdbdb; 9 | border-width: 1px 0 0 1px; 10 | } 11 | th, td { 12 | padding: 10px 6px; 13 | border: 1px solid #dbdbdb; 14 | border-width: 0 1px 1px 0; 15 | } 16 | th { 17 | background-color: #f5f5f5; 18 | } 19 | 20 | {% macro get(componentName) %} 21 | {% if componentName === "xxx" %} 22 | 23 | {% elif componentName === "flip-scroll" %} 24 | .flip-scroll { 25 | @include rp-table('breakpoint' 900) { 26 | border-right-width: 1px; 27 | > tbody > tr:last-child > td { border-right-width: 0; } 28 | .lt-ie10 & { 29 | border-right-width: 0; 30 | > tbody > tr:last-child > td { border-right-width: 1px; } 31 | } 32 | } 33 | } 34 | 35 | {% elif componentName === "scroll" %} 36 | .scroll { 37 | @include rp-table('scroll' 'breakpoint' 900) { 38 | .scrollable { 39 | border-right-width: 1px; 40 | th:last-child, td:last-child { border-right-width: 0; } 41 | .lt-ie10 & { 42 | border-right-width: 0; 43 | th:last-child, td:last-child { border-right-width: 1px; } 44 | } 45 | } 46 | } 47 | } 48 | 49 | {% elif componentName === "toggle" %} 50 | .toggle { 51 | @include rp-table('toggle' 'breakpoint' 900 'count' 10); 52 | } 53 | 54 | {% elif componentName === "stack" %} 55 | .stack { 56 | @include rp-table('stack' 'breakpoint' 900 #dbdbdb 'data' ("First Name", "Last Name", "Job Title", "Favorite Color", "Wars or Trek?", "Porn Name", "Date of Birth", "Dream Vacation City", "GPA", "Arbitrary Data")) { 57 | tr:nth-of-type(2n) { 58 | background-color: #f5f5f5; 59 | .lt-ie10 & { background-color: transparent; } 60 | } 61 | td:before { margin-right: 7px; } 62 | } 63 | } 64 | 65 | {% endif %} 66 | {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/dropdown.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'dropdown' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | 23 |

24 |     {%- filter trim %}{{ fn.get('dropdown-1') }}{% endfilter -%}
25 |   
26 | 27 | 47 |

48 |     {%- filter trim %}{{ fn.get('dropdown-2') }}{% endfilter -%}
49 |   
50 | {% endblock %} -------------------------------------------------------------------------------- /tests/scss/responsive-table.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/responsive-table"; 3 | 4 | table { 5 | text-align: left; 6 | width: 100%; 7 | font-size: 13px; 8 | border: 1px solid #dbdbdb; 9 | border-width: 1px 0 0 1px; 10 | } 11 | th, td { 12 | padding: 10px 6px; 13 | border: 1px solid #dbdbdb; 14 | border-width: 0 1px 1px 0; 15 | } 16 | th { 17 | background-color: #f5f5f5; 18 | } 19 | 20 | //=> {% macro get(componentName) %} 21 | //=> {% if componentName === "xxx" %} 22 | 23 | //=> {% elif componentName === "flip-scroll" %} 24 | .flip-scroll { 25 | @include rp-table('breakpoint' 900) { 26 | border-right-width: 1px; 27 | > tbody > tr:last-child > td { border-right-width: 0; } 28 | .lt-ie10 & { 29 | border-right-width: 0; 30 | > tbody > tr:last-child > td { border-right-width: 1px; } 31 | } 32 | } 33 | } 34 | 35 | //=> {% elif componentName === "scroll" %} 36 | .scroll { 37 | @include rp-table('scroll' 'breakpoint' 900) { 38 | .scrollable { 39 | border-right-width: 1px; 40 | th:last-child, td:last-child { border-right-width: 0; } 41 | .lt-ie10 & { 42 | border-right-width: 0; 43 | th:last-child, td:last-child { border-right-width: 1px; } 44 | } 45 | } 46 | } 47 | } 48 | 49 | //=> {% elif componentName === "toggle" %} 50 | .toggle { 51 | @include rp-table('toggle' 'breakpoint' 900 'count' 10); 52 | } 53 | 54 | //=> {% elif componentName === "stack" %} 55 | .stack { 56 | @include rp-table('stack' 'breakpoint' 900 #dbdbdb 'data' ("First Name", "Last Name", "Job Title", "Favorite Color", "Wars or Trek?", "Porn Name", "Date of Birth", "Dream Vacation City", "GPA", "Arbitrary Data")) { 57 | tr:nth-of-type(2n) { 58 | background-color: #f5f5f5; 59 | .lt-ie10 & { background-color: transparent; } 60 | } 61 | td:before { margin-right: 7px; } 62 | } 63 | } 64 | 65 | //=> {% endif %} 66 | //=> {% endmacro %} -------------------------------------------------------------------------------- /tests/templates/code/masonry-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/masonry"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "masonry-number" %} 8 | .masonry-number > ul { @include masonry(3); } 9 | 10 | {% elif componentName === "masonry-child" %} 11 | .masonry-child > ul { @include masonry(4 'selector' '.masonry-item'); } 12 | 13 | {% elif componentName === "masonry-0px" %} 14 | .masonry-0px > ul { @include masonry(4 'gutter' 0px); } 15 | 16 | {% elif componentName === "masonry-percentage-gutter" %} 17 | .masonry-percentage-gutter > ul { @include masonry(4 'gutter' 3%); } 18 | 19 | {% elif componentName === "masonry-condition" %} 20 | .masonry-condition > ul { @include masonry((900px: 3) 'max'); } 21 | 22 | {% elif componentName === "masonry-breakpoints" %} 23 | .masonry-breakpoints > ul { @include masonry(( 24 | 600px: 2, 25 | 900px: 3 26 | )); } 27 | 28 | {% elif componentName === "masonry-global-breakpoints" %} 29 | .masonry-global-breakpoints > ul { @include masonry(( 30 | 'sm': 2, 31 | 'md': 3 32 | ) $global-bps); } 33 | 34 | 35 | {% endif %} 36 | {% endmacro %} 37 | 38 | // other styles 39 | [class*= "masonry-"] img { 40 | display: block; 41 | width: 100%; 42 | } 43 | .masonry-content { 44 | padding: 15px; 45 | overflow: hidden; 46 | background: #f2f2f2; 47 | -webkit-box-sizing: border-box; 48 | -moz-box-sizing: border-box; 49 | box-sizing: border-box; 50 | h3 { 51 | font-size: 18px; 52 | margin-bottom: 10px; 53 | } 54 | p { 55 | margin: 0; 56 | line-height: 1.5; 57 | font-size: 13px; 58 | color: #666; 59 | } 60 | } 61 | 62 | // fallback 63 | .lt-ie10 { 64 | [class*= "masonry-"] { 65 | text-align: center; 66 | > li { 67 | display: inline-block; 68 | vertical-align: top; 69 | width: 250px; 70 | margin: 0 20px 20px 0; 71 | text-align: left; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /tests/templates/parts/layout.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{ page }} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 33 | 34 | 35 |
36 | {% if page !== 'index' %} 37 |

{{ page | title }}

38 | {% endif %} 39 | 40 | {% block main %} 41 | {% endblock %} 42 | 43 | {% if page !== 'index' %} 44 | 45 | {% endif %} 46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /tests/scss/masonry.scss: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/layout/masonry"; 3 | 4 | //=> {% macro get(componentName) %} 5 | //=> {% if componentName === "xxx" %} 6 | 7 | //=> {% elif componentName === "masonry-number" %} 8 | .masonry-number > ul { @include masonry(3); } 9 | 10 | //=> {% elif componentName === "masonry-child" %} 11 | .masonry-child > ul { @include masonry(4 'selector' '.masonry-item'); } 12 | 13 | //=> {% elif componentName === "masonry-0px" %} 14 | .masonry-0px > ul { @include masonry(4 'gutter' 0px); } 15 | 16 | //=> {% elif componentName === "masonry-percentage-gutter" %} 17 | .masonry-percentage-gutter > ul { @include masonry(4 'gutter' 3%); } 18 | 19 | //=> {% elif componentName === "masonry-condition" %} 20 | .masonry-condition > ul { @include masonry((900px: 3) 'max'); } 21 | 22 | //=> {% elif componentName === "masonry-breakpoints" %} 23 | .masonry-breakpoints > ul { @include masonry(( 24 | 600px: 2, 25 | 900px: 3 26 | )); } 27 | 28 | //=> {% elif componentName === "masonry-global-breakpoints" %} 29 | .masonry-global-breakpoints > ul { @include masonry(( 30 | 'sm': 2, 31 | 'md': 3 32 | ) $global-bps); } 33 | 34 | 35 | //=> {% endif %} 36 | //=> {% endmacro %} 37 | 38 | // other styles 39 | [class*= "masonry-"] img { 40 | display: block; 41 | width: 100%; 42 | } 43 | .masonry-content { 44 | padding: 15px; 45 | overflow: hidden; 46 | background: #f2f2f2; 47 | -webkit-box-sizing: border-box; 48 | -moz-box-sizing: border-box; 49 | box-sizing: border-box; 50 | h3 { 51 | font-size: 18px; 52 | margin-bottom: 10px; 53 | } 54 | p { 55 | margin: 0; 56 | line-height: 1.5; 57 | font-size: 13px; 58 | color: #666; 59 | } 60 | } 61 | 62 | // fallback 63 | .lt-ie10 { 64 | [class*= "masonry-"] { 65 | text-align: center; 66 | > li { 67 | display: inline-block; 68 | vertical-align: top; 69 | width: 250px; 70 | margin: 0 20px 20px 0; 71 | text-align: left; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /tests/templates/parts/form-validation.njk: -------------------------------------------------------------------------------- 1 |
    2 |
  1. 3 | 4 | 5 |
    User name is valid.
    6 |
    Valid user name required.
    7 |
    User name must be at least 6 characters.
    8 |
  2. 9 |
  3. 10 | 11 | 12 |
    Email address is valid.
    13 |
    Valid email address required.
    14 |
    Please enter a valid email.
    15 |
  4. 16 |
  5. 17 | 18 | 19 |
    Password is valid.
    20 |
    Valid password required.
    21 |
    Password must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters
    22 |
  6. 23 | 29 |
  7. 30 | 31 | 32 |
    Phone number required.
    33 |
    Phone number format must be xxx-xxx-xxxx.
    34 |
  8. 35 |
  9. 36 | 37 | 38 | 39 |
  10. 40 |
-------------------------------------------------------------------------------- /src/scss/addons/_breakpoint.scss: -------------------------------------------------------------------------------- 1 | @import '../utilities/args-get'; 2 | @import '../utilities/em'; 3 | @import '../utilities/list-increase'; 4 | @import '../utilities/number-odd-even'; 5 | 6 | @mixin ro-breakpoint($key){ 7 | $condition: args-get($key, ('min' 'max'), 'min'); 8 | $media: args-get($key, ('all' 'aural' 'braille' 'handheld' 'print' 'projection' 'screen' 'tty' 'tv' 'embossed')); 9 | $feature: args-get($key, ('width' 'height'), 'width'); 10 | 11 | // get breakpoints 12 | $breakpoint-em: (); 13 | @each $item in $key { 14 | @if type-of($item) == 'number' { 15 | $breakpoint-em: append($breakpoint-em, em($item)); 16 | } @else if type-of($item) == 'list' { 17 | @each $i in $item { 18 | @if type-of($item) == 'number' { $breakpoint-em: append($breakpoint-em, em($item)); } 19 | } 20 | } 21 | } 22 | $breakpoint-em: list-increase($breakpoint-em); 23 | 24 | $media-string: if($media, '#{$media} and ', ''); 25 | $selector: ''; 26 | 27 | $length: length($breakpoint-em); 28 | @if $length == 1 { 29 | $bp: if($breakpoint-fix and $condition == 'max', (nth($breakpoint-em, 1) - em(1)), nth($breakpoint-em, 1)); 30 | $selector: $media-string + '(#{$condition}-#{$feature}: #{$bp})'; 31 | } @else if $length >= 2 { 32 | @for $i from 1 through $length { 33 | @if number-odd-even($i) == 'odd' { 34 | $selector: $selector + ', ' + $media-string + ' (min-#{$feature}: #{nth($breakpoint-em, $i)})'; 35 | } @else if number-odd-even($i) == 'even' { 36 | $bp-max: if($breakpoint-fix, (nth($breakpoint-em, $i) - em(1)), nth($breakpoint-em, $i)); 37 | $selector: $selector + 'and (max-#{$feature}: #{$bp-max})'; 38 | } 39 | } 40 | // remove the first ', ' 41 | @if str-index($selector, ', ') == 1 { $selector: str-slice($selector, 3); } 42 | } @else if $length == 0 { 43 | @error "No breakpoint found."; 44 | } 45 | 46 | @media #{unquote($selector)} { @content; } 47 | } 48 | 49 | @mixin bp($key) { 50 | @include ro-breakpoint($key) { 51 | @content; 52 | }; 53 | } -------------------------------------------------------------------------------- /src/js/components/responsive-table.js: -------------------------------------------------------------------------------- 1 | // responsiveTable(obj); 2 | function windowWidth () { 3 | var d = document, w = window, 4 | winW = w.innerWidth || d.documentElement.clientWidth || d.body.clientWidth; 5 | return winW; 6 | } 7 | 8 | function windowResize (fn) { 9 | if (typeof addEventListener !== "undefined") { 10 | window.addEventListener('resize', fn, false); 11 | } else if (typeof attachEvent !== "undefined") { 12 | window.attachEvent('onresize', fn); 13 | } 14 | } 15 | 16 | var updated = false; 17 | function responsiveTable (el, breakpoint) { 18 | var ww = windowWidth(); 19 | 20 | windowResize(function () { 21 | ww = windowWidth(); 22 | 23 | if (ww <= breakpoint) { 24 | if (!updated) { 25 | responsiveTableRun(el); 26 | } 27 | } else { 28 | if (updated) { 29 | responsiveTableRemove(el); 30 | }; 31 | } 32 | }); 33 | 34 | if (ww <= breakpoint) { 35 | if (!updated) { 36 | responsiveTableRun(el); 37 | } 38 | } 39 | } 40 | 41 | function responsiveTableRun (el) { 42 | if (el.length === undefined) { 43 | el = [el]; 44 | } 45 | 46 | for (var i = 0; i < el.length; i++) { 47 | var container = el[i]; 48 | var table = container.querySelector('table'); 49 | 50 | if (table.className.indexOf('pinned') === -1) { 51 | table.className += ' pinned'; 52 | } 53 | 54 | var clonedTable = table.cloneNode(true); 55 | clonedTable.className = clonedTable.className.replace('pinned', 'scrollable').trim(); 56 | container.appendChild(clonedTable); 57 | }; 58 | 59 | updated = true; 60 | } 61 | 62 | function responsiveTableRemove (el) { 63 | if (el.length === undefined) { 64 | el = [el]; 65 | } 66 | 67 | for (var i = 0; i < el.length; i++) { 68 | var container = el[i]; 69 | var pinnedTable = container.querySelector('.pinned'); 70 | var scrollableTable = container.querySelector('.scrollable'); 71 | 72 | container.removeChild(scrollableTable); 73 | pinnedTable.className = pinnedTable.className.replace('pinned', '').trim(); 74 | }; 75 | 76 | updated = false; 77 | } 78 | -------------------------------------------------------------------------------- /src/scss/addons/_fluid-type.scss: -------------------------------------------------------------------------------- 1 | // stolen from http://www.sassmeister.com/gist/7f22e44ace49b5124eec 2 | // https://blog.codepen.io/2016/10/31/fluid-type-blogs/ 3 | @import '../setting/variables'; 4 | @import '../utilities/rem'; 5 | @import '../utilities/strip-unit'; 6 | @import 'breakpoint'; 7 | 8 | @mixin fluid-type($key) { 9 | $property: false; 10 | $breakpoint: false; 11 | @if type-of($key) == 'list' { 12 | @each $item in $key { 13 | @if type-of($item) == 'map' { 14 | $breakpoint: $item; 15 | } @else if type-of($item) == 'string' { 16 | @if $property { 17 | $property: append($property, $item); 18 | } @else { 19 | $property:($item); 20 | } 21 | } @else if type-of($item) == 'list' { 22 | $property: $item; 23 | } 24 | } 25 | } @else if type-of($key) == 'map' { 26 | $breakpoint: $key; 27 | $property: 'font-size'; 28 | } 29 | 30 | @if $property and $breakpoint { 31 | $keys: map-keys($breakpoint); 32 | $values: map-values($breakpoint); 33 | 34 | $vw-sm: nth($keys, 1); 35 | $vw-bg: nth($keys, 2); 36 | $value-sm: nth($values, 1); 37 | $value-bg: nth($values, 2); 38 | 39 | @each $item in $property { 40 | #{$item}: $value-sm; 41 | @if $item == 'font-size' and unit($value-sm) == 'px' { 42 | #{$item}: rem($value-sm); 43 | } 44 | } 45 | 46 | @include bp($vw-sm) { 47 | @each $item in $property { 48 | @if $item == 'font-size' and unit($value-sm) == 'px' { 49 | #{$item}: calc(#{rem($value-sm)} + #{strip-unit($value-bg - $value-sm)} * (100vw - #{rem($vw-sm)}) / #{strip-unit($vw-bg - $vw-sm)}); 50 | } @else { 51 | #{$item}: calc(#{$value-sm} + #{strip-unit($value-bg - $value-sm)} * (100vw - #{$vw-sm}) / #{strip-unit($vw-bg - $vw-sm)}); 52 | } 53 | } 54 | } 55 | 56 | @include bp($vw-bg) { 57 | @each $item in $property { 58 | #{$item}: $value-bg; 59 | @if $item == 'font-size' and unit($value-bg) == 'px' { 60 | #{$item}: rem($value-bg); 61 | } 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/scss/utilities/_trigonometric.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:math'; 2 | 3 | // http://thesassway.com/advanced/inverse-trigonometric-functions-with-sass 4 | // pow 5 | @function pow($number, $exp) { 6 | $value: 1; 7 | @if $exp > 0 { 8 | @for $i from 1 through $exp { 9 | $value: $value * $number; 10 | } 11 | } 12 | @else if $exp < 0 { 13 | @for $i from 1 through -$exp { 14 | $value: math.div($value, $number); 15 | } 16 | } 17 | @return $value; 18 | } 19 | 20 | // fact 21 | @function fact($number) { 22 | $value: 1; 23 | @if $number > 0 { 24 | @for $i from 1 through $number { 25 | $value: $value * $i; 26 | } 27 | } 28 | @return $value; 29 | } 30 | 31 | // pi 32 | @function pi() { 33 | @return 3.14159265359; 34 | } 35 | 36 | // rad 37 | @function rad($angle) { 38 | $unit: unit($angle); 39 | $unitless: math.div($angle, ($angle * 0 + 1)); 40 | // If the angle has 'deg' as unit, convert to radians. 41 | @if $unit == deg { 42 | $unitless: math.div($unitless, 180) * pi(); 43 | } 44 | @return $unitless; 45 | } 46 | 47 | // sin 48 | @function sin($angle) { 49 | $sin: 0; 50 | $angle: rad($angle); 51 | // Iterate a bunch of times. 52 | @for $i from 0 through 10 { 53 | $sin: $sin + math.div(pow(-1, $i) * pow($angle, (2 * $i + 1)), fact(2 * $i + 1)); 54 | } 55 | @return $sin; 56 | } 57 | 58 | // cos 59 | @function cos($angle) { 60 | $cos: 0; 61 | $angle: rad($angle); 62 | // Iterate a bunch of times. 63 | @for $i from 0 through 10 { 64 | $cos: $cos + math.div(pow(-1, $i) * pow($angle, 2 * $i), fact(2 * $i)); 65 | } 66 | @return $cos; 67 | } 68 | 69 | // tan 70 | @function tan($angle) { 71 | @return math.div(sin($angle), cos($angle)); 72 | } 73 | 74 | // sqrt 75 | // http://www.antimath.info/css/sass-sqrt-function/ 76 | @function sqrt($r) { 77 | @if $r < 0 { 78 | @return false; 79 | } @else if $r == 0 { 80 | @return 0; 81 | } @else { 82 | $x0: 1; 83 | $x1: $x0; 84 | 85 | @for $i from 1 through 10 { 86 | $x1: $x0 - math.div(($x0 * $x0 - $r), (2 * $x0)); 87 | $x0: $x1; 88 | } 89 | 90 | @return $x1; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/flex-media.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | flex-media 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 30 | 31 | 32 |
33 |

34 | Flex-media 35 |

36 |
37 |
38 | 39 |
40 |
41 |
.video { @include flex-media('iframe' (315/560)); }
42 |
43 | ← Back to home 44 |
45 |
46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tests/templates/tab.njk: -------------------------------------------------------------------------------- 1 | {% set page = 'tab' %} 2 | {% extends 'parts/layout.njk' %} 3 | 4 | {% import 'code/' + page + '-code.njk' as fn %} 5 | {% block main %} 6 | {% for item in [ 7 | 'tab-normal', 8 | 'tab-carousel', 9 | 'tab-customize' 10 | ] %} 11 | 12 |
13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 |
21 |
22 |
23 |

Lorem ipsum dolor sit amet, consectetur adipisicing.

24 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore vitae ut dolore itaque ducimus facilis aliquid est minima consequuntur quisquam!

25 |

Est, dicta vitae earum distinctio? Iure harum facilis, at. Nisi rerum, ratione a libero voluptatibus odio incidunt! Tempora, maxime, quo.

26 |
27 |
28 |

Voluptatem laborum facilis architecto, amet aperiam ipsum?

29 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Unde sunt perspiciatis maxime, vero odit et velit recusandae accusantium neque atque.

30 |

Voluptate qui quas, natus, fugit saepe dignissimos inventore, ipsa quam illo sunt animi, dicta fuga voluptatum assumenda perspiciatis veniam tenetur?

31 |
32 |
33 |

Odio harum nostrum vero minima, provident quo!

34 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci nisi est, maxime magnam perspiciatis? Eveniet blanditiis ut porro accusantium itaque.

35 |

Minima incidunt quod quaerat alias, mollitia exercitationem reiciendis dolores. Nihil facilis praesentium doloribus deserunt delectus magni quam quae ab? Quos.

36 |
37 |
38 |
39 | 40 | {# code #} 41 |

42 |       {%- filter trim %}{{ fn.get(item) }}{% endfilter -%}
43 |     
44 | {% endfor %} 45 | {% endblock %} -------------------------------------------------------------------------------- /tests/templates/code/button-code.njk: -------------------------------------------------------------------------------- 1 | @import 'demo-base'; 2 | @import "../../src/scss/components/button"; 3 | 4 | {% macro get(componentName) %} 5 | {% if componentName === "xxx" %} 6 | 7 | {% elif componentName === "default" %} 8 | .default > .btn { 9 | @include button(); 10 | } 11 | 12 | {% elif componentName === "color" %} 13 | .color > .btn { 14 | @include button(#46A736); 15 | } 16 | 17 | {% elif componentName === "style-highlight" %} 18 | .style-highlight > .btn { 19 | @include button(#2B8ACF #52cfdb 'highlight'); 20 | } 21 | 22 | {% elif componentName === "style-simple" %} 23 | .style-simple > .btn { 24 | @include button(#2B8ACF 'simple'); 25 | } 26 | 27 | {% elif componentName === "style-slide" %} 28 | .style-slide > .btn { 29 | @include button(#2B8ACF #52cfdb 'slide'); 30 | } 31 | 32 | {% elif componentName === "style-ripple" %} 33 | .style-ripple > .btn { 34 | @include button(#2B8ACF #52cfdb ':hover' 'ripple'); 35 | } 36 | 37 | {% elif componentName === "style-veil" %} 38 | .style-veil > .btn { 39 | @include button(#2B8ACF 'veil'); 40 | } 41 | 42 | {% elif componentName === "style-cut" %} 43 | .style-cut > .btn { 44 | @include button(#2B8ACF #52cfdb 'cut'); 45 | } 46 | 47 | {% elif componentName === "style-push" %} 48 | .style-push > .btn { 49 | @include button(#2B8ACF 'push'); 50 | } 51 | 52 | {% elif componentName === "style-bubble" %} 53 | .style-bubble > .btn { 54 | @include button(#2B8ACF 'bubble'); 55 | &:before { 56 | border-radius: 0.7em; 57 | } 58 | } 59 | 60 | {% elif componentName === "style-line-drawing" %} 61 | .style-line-drawing > .btn { 62 | @include button(#2B8ACF 'line-drawing'); 63 | } 64 | 65 | {% elif componentName === "style-shake" %} 66 | .style-shake > .btn { 67 | @include button(#2B8ACF 'shake'); 68 | } 69 | 70 | {% endif %} 71 | {% endmacro %} 72 | 73 | .container { text-align: center; } 74 | .demo { 75 | display: inline-block; 76 | width: 500px; 77 | margin: 0 50px 50px 0; 78 | vertical-align: top; 79 | &:before { 80 | font-size: 13px; 81 | opacity: 0.66; 82 | margin-bottom: 7px; 83 | } 84 | &.style-bubble { overflow: visible; } 85 | } 86 | .btn { 87 | display: inline-block; 88 | min-width: 10em; 89 | height: 3.2em; 90 | line-height: 3.2em; 91 | border-radius: 0.5em; 92 | font-size: 20px; 93 | margin-bottom: 1em; 94 | } --------------------------------------------------------------------------------