aboutsummaryrefslogtreecommitdiffstats
path: root/src/styles/abstracts
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2021-12-13 00:51:39 +0100
committerArmand Philippot <git@armandphilippot.com>2021-12-13 00:51:39 +0100
commitab29d725320ff8e883394aee536ea37b74018009 (patch)
tree3f4cdb605abc4ded03d8f3399eacf6d7f9b69851 /src/styles/abstracts
parent5299774837aa2be2c0f26e766ead20e9dd17e18a (diff)
chore: define Sass functions, mixins, placeholders and variables
Diffstat (limited to 'src/styles/abstracts')
-rw-r--r--src/styles/abstracts/_functions.scss3
-rw-r--r--src/styles/abstracts/_mixins.scss1
-rw-r--r--src/styles/abstracts/_placeholders.scss2
-rw-r--r--src/styles/abstracts/_variables.scss159
-rw-r--r--src/styles/abstracts/functions/_convert.scss16
-rw-r--r--src/styles/abstracts/functions/_encode.scss14
-rw-r--r--src/styles/abstracts/functions/_str-replace.scss22
-rw-r--r--src/styles/abstracts/mixins/_media-queries.scss82
-rw-r--r--src/styles/abstracts/placeholders/_clearfix.scss14
-rw-r--r--src/styles/abstracts/placeholders/_list.scss32
10 files changed, 345 insertions, 0 deletions
diff --git a/src/styles/abstracts/_functions.scss b/src/styles/abstracts/_functions.scss
new file mode 100644
index 0000000..406cc7a
--- /dev/null
+++ b/src/styles/abstracts/_functions.scss
@@ -0,0 +1,3 @@
+@forward "./functions/convert";
+@forward "./functions/encode";
+@forward "./functions/str-replace";
diff --git a/src/styles/abstracts/_mixins.scss b/src/styles/abstracts/_mixins.scss
new file mode 100644
index 0000000..a49c848
--- /dev/null
+++ b/src/styles/abstracts/_mixins.scss
@@ -0,0 +1 @@
+@forward "./mixins/media-queries";
diff --git a/src/styles/abstracts/_placeholders.scss b/src/styles/abstracts/_placeholders.scss
new file mode 100644
index 0000000..5ee6cea
--- /dev/null
+++ b/src/styles/abstracts/_placeholders.scss
@@ -0,0 +1,2 @@
+@forward "./placeholders/clearfix";
+@forward "./placeholders/list";
diff --git a/src/styles/abstracts/_variables.scss b/src/styles/abstracts/_variables.scss
new file mode 100644
index 0000000..e7816f3
--- /dev/null
+++ b/src/styles/abstracts/_variables.scss
@@ -0,0 +1,159 @@
+@use "sass:map";
+@use "sass:math";
+@use "@styles/abstracts/functions" as fun;
+
+//===========================================================================
+// Ratios
+//===========================================================================
+
+/// Ratios map
+/// @prop {String} keys - Keys are identifiers mapped to a given ratio
+/// @prop {Map} value - Value is actual ratio
+$ratios: (
+ "minor-second": 1.067,
+ "major-second": 1.125,
+ "minor-third": 1.2,
+ "major-third": 1.25,
+ "perfect-fourth": 1.333,
+ "augmented-fourth": 1.414,
+ "perfect-fifth": 1.5,
+ "golden-number": 1.618,
+);
+
+// I cannot declare the following function with others functions due to module
+// loop. But, it will only be used in this file so it is not really a problem.
+
+/// Get ratio
+/// @param {String} $name - Ratio name.
+/// @return {Integer} The ratio value.
+@function get-ratio($name) {
+ @return map.get($ratios, $name);
+}
+
+//===========================================================================
+// Layout
+//===========================================================================
+
+/// Breakpoints map
+/// @prop {String} keys - Keys are identifiers mapped to a given length
+/// @prop {Map} values - Values are actual breakpoints expressed in pixels
+$breakpoints: (
+ "xs": fun.convert-px(600, "em"),
+ "sm": fun.convert-px(800, "em"),
+ "md": fun.convert-px(1280, "em"),
+ "lg": fun.convert-px(1600, "em"),
+);
+
+//===========================================================================
+// Fonts
+//===========================================================================
+
+/* stylelint-disable -- Fonts name are not keywords, lowercase is not needed. */
+/// Regular font family
+/// @type List
+$font-family_primary: ("Inter", "Liberation Sans", Arial, sans-serif);
+
+/// Alternative regular font family
+/// @type List
+$font-family_secondary: ("Kanit", "Liberation Sans", Arial, sans-serif);
+
+/// Monospace font family
+/// @type List
+$font-family_mono: (
+ "Cousine",
+ "Liberation Mono",
+ "DejaVu Sans Mono",
+ "Courier New",
+ monospace
+);
+/* stylelint-enable */
+
+$line-height: get-ratio("golden-number");
+
+$font-size_base: 16px;
+$font-size_base-rem: fun.convert-px(16); // font-size_base without unit
+$font-size_ratio: get-ratio("minor-third");
+$font-size_levels: "sm", "md", "lg", "xl", "2xl", "3xl", "4xl";
+
+// We start with small font-size, so it needs to be less than $font-size_base.
+$font-size_current: math.div($font-size_base-rem, $font-size_ratio);
+
+/// Font-sizes map ('sm', 'md', 'lg'...)
+/// @prop {String} keys - Size as key is mapped to a given font-size
+/// @prop {Map} value - Value is actual font-size
+$font-sizes: ();
+
+// We fill our font-sizes map.
+/// Inspired by Stephanie Eckles.
+/// @link https://moderncss.dev/generating-font-size-css-rules-and-creating-a-fluid-type-scale/
+@each $level in $font-size_levels {
+ $font-size_current: $font-size_current * $font-size_ratio;
+ $font-sizes: map.merge(
+ $font-sizes,
+ (
+ $level: $font-size_current,
+ )
+ );
+}
+
+// We cannot declare this function with others functions due to module loop.
+
+/// Get font-size
+/// @param {String} $name - Font-size ('sm', 'md', 'lg'...).
+/// @return {Integer} The font-size value.
+@function font-size($key) {
+ @return map.get($font-sizes, $key);
+}
+
+//============================================================================
+// Spacings
+//============================================================================
+
+$spacing_ratio: get-ratio("golden-number");
+$spacing_base: $spacing_ratio * 1rem;
+
+$spacing_levels: "2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl", "4xl";
+
+// We start with 2xs spacing, so it needs to be less than the base.
+$spacing_current: math.div($spacing_base, $spacing_ratio * 3);
+
+/// Spacings map ('sm', 'md', 'lg'...)
+/// @prop {String} keys - Size as key is mapped to a given spacing
+/// @prop {Map} value - Value is actual spacing
+$spacings: ();
+
+/// We fill our spacings map.
+@each $level in $spacing_levels {
+ $spacing_current: $spacing_current * $spacing_ratio;
+ $spacings: map.merge(
+ $spacings,
+ (
+ $level: $spacing_current,
+ )
+ );
+}
+
+// We cannot declare this function with others functions due to module loop.
+
+/// Get spacing.
+/// @param {String} $name - Spacing size ('sm', 'md', 'lg'...).
+/// @return {Integer} The spacing value.
+@function spacing($key) {
+ @return map.get($spacings, $key);
+}
+
+//============================================================================
+// Colors
+//============================================================================
+
+$color_black: hsl(207, 47%, 11%);
+$color_blue: hsl(206, 75%, 31%);
+$color_blue-bright: hsl(206, 77%, 36%);
+$color_blue-brighter: hsl(200, 75%, 45%);
+$color_blue-dark: hsl(206, 76%, 25%);
+$color_grey: hsl(206, 15%, 80%);
+$color_grey-dark: hsla(206, 10%, 25%);
+$color_grey-dark-o70: hsla(206, 10%, 25%, 0.7);
+$color_orange: hsl(32, 100%, 55%);
+$color_white: hsl(206, 15%, 97%);
+$color_white-o90: hsl(206, 15%, 97%, 0.9);
diff --git a/src/styles/abstracts/functions/_convert.scss b/src/styles/abstracts/functions/_convert.scss
new file mode 100644
index 0000000..9f51dc7
--- /dev/null
+++ b/src/styles/abstracts/functions/_convert.scss
@@ -0,0 +1,16 @@
+@use "sass:math";
+
+/// Convert px to rem or em.
+/// @param {Number} $px Value in px
+/// @param {String} $to Unit. Either "rem" or "em"
+/// @param {Number} $standard 1rem (or 1em) = 16px
+/// @return {Number} Value in rem or em
+@function convert-px($px, $to: "rem", $standard: 16) {
+ @if $to == "rem" {
+ @return math.div($px, $standard) + 0rem; // stylelint-disable-line
+ } @else if $to == "em" {
+ @return math.div($px, $standard) + 0em; // stylelint-disable-line
+ } @else {
+ @error "`$to` must be either `rem` or `em`.";
+ }
+}
diff --git a/src/styles/abstracts/functions/_encode.scss b/src/styles/abstracts/functions/_encode.scss
new file mode 100644
index 0000000..4350185
--- /dev/null
+++ b/src/styles/abstracts/functions/_encode.scss
@@ -0,0 +1,14 @@
+@use "str-replace" as fun;
+
+/// Encode a SVG.
+/// @param {String} $svg A complete svg (`<svg>...</svg>`).
+/// @return The encoded svg, ready to use for background-image.
+@function encode-svg($svg) {
+ $svg-encoding: (("<", "%3C"), (">", "%3E"), ("#", "%23"));
+
+ @each $char, $encoded in $svg-encoding {
+ $svg: fun.str-replace($svg, $char, $encoded);
+ }
+
+ @return "data:image/svg+xml;utf8," + $svg;
+}
diff --git a/src/styles/abstracts/functions/_str-replace.scss b/src/styles/abstracts/functions/_str-replace.scss
new file mode 100644
index 0000000..98cc4b0
--- /dev/null
+++ b/src/styles/abstracts/functions/_str-replace.scss
@@ -0,0 +1,22 @@
+@use "sass:string";
+
+/// Replace `$search` with `$replace` in `$string`
+/// @author Hugo Giraudel
+/// @param {String} $string - Initial string
+/// @param {String} $search - Substring to replace
+/// @param {String} $replace ('') - New value
+/// @return {String} - Updated string
+@function str-replace($string, $search, $replace: "") {
+ $index: string.index($string, $search);
+
+ @if $index {
+ @return string.slice($string, 1, $index - 1) + $replace +
+ str-replace(
+ string.slice($string, $index + string.length($search)),
+ $search,
+ $replace
+ );
+ }
+
+ @return $string;
+}
diff --git a/src/styles/abstracts/mixins/_media-queries.scss b/src/styles/abstracts/mixins/_media-queries.scss
new file mode 100644
index 0000000..db0b568
--- /dev/null
+++ b/src/styles/abstracts/mixins/_media-queries.scss
@@ -0,0 +1,82 @@
+@use "../variables" as var;
+@use "sass:map";
+
+/// Media query: media type
+/// @param {String} $type - Media type: all, screen, print, retina.
+/// @example scss - `@media only screen` equivalent is:
+/// @include media("screen");
+@mixin media($type) {
+ @if $type == "retina" {
+ $type: "(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)";
+ } @else if $type == "screen" or $type == "print" {
+ $type: "only #{$type}";
+ }
+
+ @media #{$type} {
+ @content;
+ }
+}
+
+/// Media query: min-width / max-width
+/// @param {String} $from - min-width breakpoint.
+/// @param {String} $until - max-width breakpoint.
+/// @example scss - `@media (min-width: "md")` equivalent is:
+/// @include dimensions("md");
+@mixin dimensions($from: null, $until: null) {
+ $query: "";
+
+ @if $from {
+ @if type-of($from) == "string" {
+ $size: map.get(var.$breakpoints, $from);
+ $query: "(min-width: #{$size})";
+ } @else {
+ @error "`$from` must be a string.";
+ }
+ }
+
+ @if $from and $until {
+ $query: $query + " and ";
+ }
+
+ @if $until {
+ @if type-of($until) == "string" {
+ $size: map.get(var.$breakpoints, $until);
+ $size: calc(#{$size} - 1px);
+ $query: $query + "(max-width: #{$size})";
+ } @else {
+ @error "`$until` must be a string.";
+ }
+ }
+
+ @media #{$query} {
+ @content;
+ }
+}
+
+/// Media query: prefers-reduced-motion
+/// @param {String} $value - Media query value: `no-preference` or `reduce`.
+/// @example scss - @media (prefers-reduced-motion: "reduce") equivalent is:
+/// @include motion("reduce");
+@mixin motion($value) {
+ @if $value == "no-preference" or $value == "reduce" {
+ @media (prefers-reduced-motion: #{$value}) {
+ @content;
+ }
+ } @else {
+ @error "Allowed values are `no-preference` and `reduce`.";
+ }
+}
+
+/// Media query: any-pointer
+/// @param {String} $value - Media query value: `fine`, `coarse` or `none`.
+/// @example scss - @media (any-pointer: "fine") equivalent is:
+/// @include pointer("fine");
+@mixin pointer($value) {
+ @if $value == "fine" or $value == "coarse" or $value == "none" {
+ @media (any-pointer: #{$value}) {
+ @content;
+ }
+ } @else {
+ @error "Allowed values are `fine`, `coarse` and `none`.";
+ }
+}
diff --git a/src/styles/abstracts/placeholders/_clearfix.scss b/src/styles/abstracts/placeholders/_clearfix.scss
new file mode 100644
index 0000000..2a4f262
--- /dev/null
+++ b/src/styles/abstracts/placeholders/_clearfix.scss
@@ -0,0 +1,14 @@
+/// Set up clearfix
+%clearfix {
+ *zoom: 1;
+
+ &::before,
+ &::after {
+ content: " ";
+ display: table;
+ }
+
+ &::after {
+ clear: both;
+ }
+}
diff --git a/src/styles/abstracts/placeholders/_list.scss b/src/styles/abstracts/placeholders/_list.scss
new file mode 100644
index 0000000..85e8386
--- /dev/null
+++ b/src/styles/abstracts/placeholders/_list.scss
@@ -0,0 +1,32 @@
+/// List Reset
+%reset-list {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+
+ li {
+ margin-bottom: 0;
+ }
+}
+
+/// Ordered List Reset
+%reset-ordered-list {
+ @extend %reset-list;
+
+ li {
+ display: list-item;
+ counter-increment: none;
+
+ &::before {
+ display: none;
+ }
+ }
+}
+
+/// Display an inline list with flexbox
+%flex-list {
+ @extend %reset-list;
+
+ display: flex;
+ flex-flow: row wrap;
+}