Skip to content

Commit d411ea8

Browse files
author
AMJones
committed
Adds theme functions, variables and mixins.
1 parent 705d7b1 commit d411ea8

File tree

6 files changed

+392
-0
lines changed

6 files changed

+392
-0
lines changed

composer.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "strapless/theme",
3+
"description": "CSS Classes, Mixins and Functions to control the look and feel of the StrapLess CSS Framework. Also usable for other CSS projects.",
4+
"keywords": [
5+
"sass",
6+
"scss",
7+
"strapless",
8+
"css",
9+
"theme"
10+
],
11+
"homepage": "https://www.github.com/strapless/theme",
12+
"version": "1.0",
13+
"authors": [
14+
{
15+
"name": "Aaron M Jones",
16+
"homepage": "http://www.jonesiscoding.com"
17+
}
18+
],
19+
"license": "MIT",
20+
"require": {
21+
"strapless/colors": "^1.0",
22+
"strapless/base": "^1.1"
23+
}
24+
}

scss/_theme-functions.scss

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
@import "strapless/base/scss/base";
2+
@import "icons/svg-icons";
3+
4+
@function icon-feature($f) {
5+
@return component-feature("icons", $f);
6+
}
7+
8+
@function has-font-awesome() {
9+
@if(variable-exists(fa-font-path)) {
10+
@if(variable-exists(fa-font-size-base)) {
11+
@if(variable_exists(fa-line-height-base)) {
12+
@return true;
13+
}
14+
}
15+
}
16+
17+
@return false;
18+
}
19+
20+
// Encode symbols
21+
@function _url-encode($string) {
22+
$map: (
23+
"%": "%25",
24+
"<": "%3C",
25+
">": "%3E",
26+
" ": "%20",
27+
"!": "%21",
28+
"*": "%2A",
29+
"'": "%27",
30+
'"': "%22",
31+
"(": "%28",
32+
")": "%29",
33+
";": "%3B",
34+
":": "%3A",
35+
"@": "%40",
36+
"&": "%26",
37+
"=": "%3D",
38+
"+": "%2B",
39+
"$": "%24",
40+
",": "%2C",
41+
"/": "%2F",
42+
"?": "%3F",
43+
"#": "%23",
44+
"[": "%5B",
45+
"]": "%5D"
46+
);
47+
48+
$new: $string;
49+
50+
@each $search, $replace in $map {
51+
$new: str-replace($new, $search, $replace);
52+
}
53+
54+
@return $new;
55+
}
56+
57+
// Format the SVG as a URL
58+
@function inline-svg($string) {
59+
@return url('data:image/svg+xml,#{_url-encode($string)}');
60+
}
61+
62+
@function get-svg-icon($icon-name) {
63+
// Make sure we aren't already an SVG
64+
@if quote(str-slice($icon-name, 1, 4)) == "<svg" {
65+
@return $icon-name;
66+
}
67+
68+
@if map-has-key($svg-icons, $icon-name) {
69+
@return map-get($svg-icons,$icon-name);
70+
} @else {
71+
@error "Invalid SVG Icon name `#{$icon-name}` provided.";
72+
}
73+
}
74+

scss/_theme-mixins.scss

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
@import "theme-variables";
2+
3+
// region //////////////////////////////////////////////// Font Icon Mixins
4+
5+
@mixin icon-font {
6+
@if icon-feature("font-awesome") and mixin_exists(fa-icon) {
7+
//noinspection SassScssUnresolvedMixin
8+
@include fa-icon();
9+
} @else {
10+
display: inline-block;
11+
font: normal normal normal #{$icon-font-size}/#{$icon-line-height} #{$icon-font-name}; // shortening font declaration
12+
text-rendering: auto; // optimizelegibility throws things off
13+
-webkit-font-smoothing: antialiased;
14+
-moz-osx-font-smoothing: grayscale;
15+
}
16+
}
17+
18+
@mixin _font-psuedo($location, $icon-content: null, $opacity: 0, $color) {
19+
&::#{$location} {
20+
@include icon-font;
21+
@if $icon-content != null {
22+
content: $icon-content;
23+
}
24+
@if $color != null and $opacity != null and $opacity < 1 {
25+
color: rgba($color,$opacity);
26+
} @else if $color != null {
27+
color: $color;
28+
@if $opacity == 1 {
29+
opacity: 1;
30+
}
31+
} @else if $opacity > 0 {
32+
opacity: $opacity;
33+
}
34+
@content;
35+
}
36+
}
37+
38+
@mixin font-before($icon-name, $opacity: null, $color: null) {
39+
@include _font-psuedo(before, $opacity, $color) {
40+
@content;
41+
}
42+
}
43+
44+
@mixin font-after($icon-name, $opacity: null, $color: null) {
45+
@include _font-psuedo(after, $icon-name, $opacity, $color) {
46+
@content;
47+
}
48+
}
49+
50+
// endregion ///////////////////////////////////////////// End Font Icon Mixins
51+
52+
// region //////////////////////////////////////////////// SVG Icon Mixins
53+
54+
@mixin _svg-background($svg, $size: $icon-width) {
55+
$content: unquote($svg);
56+
background-image: inline-svg($svg) center center / $size $size no-repeat;
57+
}
58+
59+
@mixin _svg-psuedo($location, $size: $icon-width, $svg: null, $opacity: null, $fill: null) {
60+
&::#{$location} {
61+
display: block;
62+
width: $size;
63+
height: $size;
64+
content: " ";
65+
// Set SVG as Background Image
66+
@if $svg != null {
67+
@include _svg-background($svg, $size);
68+
}
69+
// Add Fill & Opacity if Needed
70+
@if $fill != null and $opacity > 0 and $opacity < 1 {
71+
fill: rgba($fill,$opacity);
72+
} @else if $fill != null {
73+
fill: $fill;
74+
@if $opacity == 1 {
75+
opacity: 1;
76+
}
77+
} @else if $opacity > 0 {
78+
opacity: $opacity;
79+
}
80+
// Any Pass Through Content
81+
@content;
82+
}
83+
}
84+
85+
@mixin svg-before($size: $icon-width, $svg-or-name: null, $opacity: null, $fill: null) {
86+
@include _svg-psuedo(before, $size, get-svg-icon($svg-or-name), $opacity, $fill);
87+
}
88+
89+
@mixin svg-after($size: $icon-width, $svg-or-name: null, $opacity: null, $fill: null) {
90+
@include _svg-psuedo(after, $size, get-svg-icon($svg-or-name), $opacity, $fill);
91+
}
92+
93+
// endregion ///////////////////////////////////////////// End SVG Icon Mixins
94+
95+
// region //////////////////////////////////////////////// Component Icon Mixins
96+
97+
@mixin button-icons($padding) {
98+
& + span {
99+
margin-left: $padding;
100+
}
101+
}
102+
103+
@mixin card-panel-icons($padding) {
104+
> .#{$icon-css-prefix} {
105+
order: -1;
106+
flex: 0 0 auto;
107+
margin: 0 $padding 0 0;
108+
}
109+
}
110+
111+
@mixin card-accordion-indicator($indicator, $size, $right-spacing) {
112+
.card-accordion > .card .card-title {
113+
a[data-toggle="collapse"] {
114+
@include svg-before($indicator, $size, .3) {
115+
transform-origin: center center;
116+
transition-duration: 0.35s;
117+
right: $right-spacing;
118+
position: absolute;
119+
}
120+
}
121+
a.collapsed::before {
122+
transform: rotate(180deg);
123+
}
124+
}
125+
}
126+
127+
// endregion ///////////////////////////////////////////// End Component Icon Mixins
128+
129+
// region //////////////////////////////////////////////// Theme Mixins
130+
131+
@mixin elevation($level, $penumbra: $shadow-key-penumbra-opacity, $umbra: $shadow-key-umbra-opacity, $ambient: $shadow-ambient-shadow-opacity) {
132+
@if theme("shadows") {
133+
@if $level == 0 {
134+
box-shadow: none;
135+
}
136+
@if $level == 1 {
137+
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, $penumbra),
138+
0 2px 1px -1px rgba(0, 0, 0, $umbra),
139+
0 1px 3px 0 rgba(0, 0, 0, $ambient);
140+
}
141+
@if $level == 2 {
142+
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, $penumbra),
143+
0 3px 1px -2px rgba(0, 0, 0, $umbra),
144+
0 1px 5px 0 rgba(0, 0, 0, $ambient);
145+
}
146+
@else if $level == 3 {
147+
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, $penumbra),
148+
0 3px 3px -2px rgba(0, 0, 0, $umbra),
149+
0 1px 8px 0 rgba(0, 0, 0, $ambient);
150+
}
151+
@else if $level == 4 {
152+
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, $penumbra),
153+
0 1px 10px 0 rgba(0, 0, 0, $umbra),
154+
0 2px 4px -1px rgba(0, 0, 0, $ambient);
155+
}
156+
@else if $level == 6 {
157+
box-shadow: 0 6px 10px 0 rgba(0, 0, 0, $penumbra),
158+
0 1px 18px 0 rgba(0, 0, 0, $umbra),
159+
0 3px 5px -1px rgba(0, 0, 0, $ambient);
160+
}
161+
@else if $level == 8 {
162+
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, $penumbra),
163+
0 3px 14px 2px rgba(0, 0, 0, $umbra),
164+
0 5px 5px -3px rgba(0, 0, 0, $ambient);
165+
}
166+
@else if $level == 16 {
167+
box-shadow: 0 16px 24px 2px rgba(0, 0, 0, $penumbra),
168+
0 6px 30px 5px rgba(0, 0, 0, $umbra),
169+
0 8px 10px -5px rgba(0, 0, 0, $ambient);
170+
}
171+
@else if $level == 24 {
172+
box-shadow: 0 9px 46px 8px rgba(0, 0, 0, $penumbra),
173+
0 11px 15px -7px rgba(0, 0, 0, $umbra),
174+
0 24px 38px 3px rgba(0, 0, 0, $ambient);
175+
}
176+
}
177+
}
178+
179+
// endregion ///////////////////////////////////////////// End Theme Mixins
180+
181+
// region //////////////////////////////////////////////// Rounding Mixins
182+
183+
@mixin border-radius($radius: $border-radius) {
184+
@if theme("rounded") {
185+
border-radius: $radius;
186+
}
187+
}
188+
189+
@mixin border-top-radius($radius: $border-radius) {
190+
@if theme("rounded") {
191+
border-top-right-radius: $radius;
192+
border-top-left-radius: $radius;
193+
}
194+
}
195+
196+
@mixin border-right-radius($radius: $border-radius) {
197+
@if theme("rounded") {
198+
border-bottom-right-radius: $radius;
199+
border-top-right-radius: $radius;
200+
}
201+
}
202+
203+
@mixin border-bottom-radius($radius: $border-radius) {
204+
@if theme("rounded") {
205+
border-bottom-right-radius: $radius;
206+
border-bottom-left-radius: $radius;
207+
}
208+
}
209+
210+
@mixin border-left-radius($radius: $border-radius) {
211+
@if theme("rounded") {
212+
border-bottom-left-radius: $radius;
213+
border-top-left-radius: $radius;
214+
}
215+
}
216+
217+
// endregion ///////////////////////////////////////////// End Rounding Mixins
218+
219+

scss/_theme-variables.scss

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@import "theme-functions";
2+
@import "icons/svg-icons";
3+
4+
$enable-framework: false !default;
5+
6+
// region //////////////////////////////////////////////// Icon Variables
7+
8+
//noinspection SassScssUnresolvedVariable
9+
@if icon-feature("font-awesome") and has-font-awesome() {
10+
$icon-css-prefix: $fa-css-prefix !default;
11+
$icon-font-name: FontAwesome !default;
12+
$icon-font-size: $fa-font-size-base !default;
13+
$icon-line-height: $fa-line-height-base !default;
14+
}
15+
16+
$icon-css-prefix: ico !default;
17+
$icon-width: 16px !default;
18+
$icon-height: 16px !default;
19+
20+
$icon-font-size: $icon-width !default;
21+
$icon-line-height: 1 !default;
22+
23+
// endregion ///////////////////////////////////////////// End Icon Variables
24+
25+
// region //////////////////////////////////////////////// Theme Variables
26+
27+
$border-radius: 4px;
28+
29+
// endregion ///////////////////////////////////////////// End Theme Variables
30+

scss/_theme.scss

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@import "theme-variables";
2+
3+
// region //////////////////////////////////////////////// Icon Classes
4+
5+
@if component("icons") {
6+
@if icon-feature("font") and not(icon-feature("font-awesome")) {
7+
@include icon-font();
8+
.#{$icon-css-prefix}-2x { font-size: 2em; }
9+
.#{$icon-css-prefix}-3x { font-size: 3em; }
10+
.#{$icon-css-prefix}-4x { font-size: 4em; }
11+
.#{$icon-css-prefix}-5x { font-size: 5em; }
12+
}
13+
14+
@if icon-feature("svg") {
15+
svg.#{$icon-css-prefix} {
16+
width: $icon-width;
17+
height: $icon-height;
18+
max-height: 100%;
19+
fill: currentColor;
20+
@if component-feature("icons","font") {
21+
&::before {
22+
content: '' !important;
23+
}
24+
}
25+
&.#{$icon-css-prefix}-2x { width: 2 * $icon-width; height: 2 * $icon-height; }
26+
&.#{$icon-css-prefix}-3x { width: 3 * $icon-width; height: 3 * $icon-height; }
27+
&.#{$icon-css-prefix}-4x { width: 4 * $icon-width; height: 4 * $icon-height; }
28+
&.#{$icon-css-prefix}-5x { width: 5 * $icon-width; height: 5 * $icon-height; }
29+
}
30+
}
31+
}
32+
33+
// endregion ///////////////////////////////////////////// End Icon Classes

scss/icons/_svg-icons.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// region //////////////////////////////////////////////// SVG Icon Map
2+
3+
$svg-icons: (
4+
'chevron-bottom': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M1.5 0l-1.5 1.5 4 4 4-4-1.5-1.5-2.5 2.5-2.5-2.5z" transform="translate(0 1)" /></svg>',
5+
'chevron-left': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z" transform="translate(1)" /></svg>',
6+
'chevron-right': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z" transform="translate(1)" /></svg>',
7+
'chevron-top': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M4 0l-4 4 1.5 1.5 2.5-2.5 2.5 2.5 1.5-1.5-4-4z" transform="translate(0 1)" /></svg>',
8+
'caret-bottom': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M0 0l4 4 4-4h-8z" transform="translate(0 2)" /></svg>',
9+
'caret-left': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M4 0l-4 4 4 4v-8z" transform="translate(2)" /></svg>',
10+
'caret-right': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M0 0v8l4-4-4-4z" transform="translate(2)" /></svg>',
11+
'caret-top': '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="8" height="8" viewBox="0 0 8 8"><path d="M4 0l-4 4h8l-4-4z" transform="translate(0 2)" /></svg>'
12+
) !default;

0 commit comments

Comments
 (0)