X-Git-Url: https://git.draconx.ca/gitweb/homepage.git/blobdiff_plain/e39d97fade755e9b53e7dc0f7bd4320ade1b7b83..062c731462e3ec513b470308cc2dd475098ce231:/lib/colourmap.scss diff --git a/lib/colourmap.scss b/lib/colourmap.scss new file mode 100644 index 0000000..62468d9 --- /dev/null +++ b/lib/colourmap.scss @@ -0,0 +1,118 @@ +// Nick's web site: SCSS colourmap helpers for automatic light/dark styles. +// +// Copyright © 2022 Nick Bowler +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// database of colour names +$colourmap: (); + +// database of combination CSS properties that should be translated to +// colour-only properties (e.g., border-top -> border-top-color). +$_colourpropmap: + ( border-top: border-top-color + , border-bottom: border-bottom-color + , border-left: border-left-color + , border-right: border-right-color + , border: border-color + ); + +// Define a named set of colours. Pass keyword arguments with each keyword +// being a colour name and the argument is a list of one or two colours. +// +// When two colours are specified, the first should be for "light" backgrounds +// and the second for "dark". +// +// For example: +// +// @include defcolours($bg: white black, $fg: black white); +@mixin defcolours($args...) { + :root { + @each $colour, $list in keywords($args) { + $colourmap: map-merge($colourmap, ($colour: $list)) !global; + @if length($list) > 1 { + #{--colour- + $colour}: nth($list, 1); + } + } + } + @media (prefers-color-scheme: dark) { + :root { + @each $colour, $list in keywords($args) { + @if length($list) > 1 { + #{--colour- + $colour}: nth($list, 2); + } + } + } + } +} + +// For the given previously-defined colour name, returns its value from +// primary (light) colour scheme. +// +// The $pre and $post keyword arguments may be used to supplement the +// result with additional tokens either before or after the colour +// value, respectively, as might be used for combined properties +// such as border, outline, etc. +@function getcolour($colour, $pre: (), $post: ()) { + @return join(append($pre, nth(map-get($colourmap, $colour), 1)), $post); +} + +@mixin usecolour_var_($prop, $colour, $pre: (), $post: ()) { + @if (length(map-get($colourmap, $colour)) > 1) { + $transprop: map-get($_colourpropmap, $prop); + @if $transprop { + #{$transprop}: var(--colour- + $colour) + } @else { + #{$prop}: join(append($pre, var(--colour- + $colour)), $post); + } + } +} + +// Sets the given CSS property to the specified colour name. The $pre +// and $post keyword arguments may be used to supplement the property +// value, as with the getcolour function. +// +// For two-value colours, the property is set using CSS variables to +// adapt the colour based on the user's preference for a light or dark +// background. The rules will fall back to the static (light) colour +// if CSS variables are not supported. +// +// For example: +// +// @include usecolour(border, fg, $pre: solid 1px); +@mixin usecolour($prop, $colour, $pre: (), $post: ()) { + #{$prop}: getcolour($colour, $pre, $post); + @at-root & { @include usecolour_var_($prop, $colour, $pre, $post); } +} + +// Convenience helper to assign multiple colour properties at once, for +// the common case where the $pre and $post arguments to usecolour are +// not required. +// +// Takes any number of keyword arguments with the keyword being the +// property name and the value being the colour name. +// +// For example: +// +// @include usecolours($background-color: bg, $color: fg); +@mixin usecolours($args...) { + @each $prop, $colour in keywords($args) { + #{$prop}: getcolour($colour); + } + @at-root & { + @each $prop, $colour in keywords($args) { + @include usecolour_var_($prop, $colour); + } + } +}