@atlassian/aui
Version:
Atlassian User Interface library
110 lines (98 loc) • 4.55 kB
text/less
#aui {
/**
* Create an internal variable whose value is based on the @token value in light/dark themes,
* switching based on the perceptual lightness of @switch-on.
*
* Can only be used on tokens defined in tokenNamesToExtract in extractColorChannels (called
* at build step).
*/
.lf-define-switched-color(
@switch-on: --atl-theme-header-bg-color;
@token;
) {
/*
The following expression switches between two colors, whose oklch channels (l c h, and a
for alpha) are in separate variables built on base name, based on the perceptual lightness
of the input color.
l (perceptual lightness) ranges from 0 to 1; rounding gives 0 or 1; interpolation works
like a switch. We add 0.1 because I found it gives better contrast for some in-between
colors (though it might be only applicable to the current values of --ds-text and might
need adjustment in an unprobable case those values are changed):
round(l + 0.1) * (var(--l2) - var(--l1)) + var(--l1)
^.. when 0 ..^ ^ this doesn't count ^ ^ and we get l1
^.. when 1 ..^ ^ we get l2, cause -l1+l1=0
Safari has a limitation: it doesn't allow round() in this particular expression. So we
mimic it with the min/max trick. `min(l-0.6,1)` transforms the lower part of the range into
a zero; the multiply by 100 preserves zeroes, but makes any positive number (to a
resolution of 0.01 which is good enough) into a 1 or more, which min(x,1) clamps to 1. (The
browser logic would do the last `min` here, but we include it for clarity.)
Use ~'<text>' syntax to bypass Less resolving the functions `min` and `max`.
*/
@base: ~'--auix@{token}';
@switched-color: ~'@{base}@{switch-on}-s';
// Using relative colors triggers the error: `postcss-calc:: Lexical error on line 1:
// Unrecognized text.` It's an open issue in postcss-calc, see
// https://github.com/postcss/postcss-calc/issues/216
@supports (color: rgb(from white r g b)) {
@{switched-color}: ~'oklch(
from var(@{switch-on})
calc(min(max(0, l - 0.6) * 100, 1) * (var(@{base}-l1) - var(@{base}-l2)) + var(@{base}-l2))
calc(min(max(0, l - 0.6) * 100, 1) * (var(@{base}-c1) - var(@{base}-c2)) + var(@{base}-c2))
calc(min(max(0, l - 0.6) * 100, 1) * (var(@{base}-h1) - var(@{base}-h2)) + var(@{base}-h2))
/
calc(min(max(0, l - 0.6) * 100, 1) * (var(@{base}-a1) - var(@{base}-a2)) + var(@{base}-a2))
)';
}
}
/**
* Define a variable @name that'll take its value from a lf-switched variable (must be defined
* earlier via lf-define-switched-color), or @fallback when the lf input variable is not
* defined.
*/
.define-lf-variable(
@name;
@switch-on;
@token;
@fallback;
) {
@base: ~'--auix@{token}';
@switched-color: ~'@{base}@{switch-on}-s';
@{name}: var(@switched-color, var(@fallback));
}
/**
* Define a variable named `${@input-color}-tinted-${tinting-mode}` that'll take its value from
* @input-color: lightened when the input color is perceptually dark; darkened when the input
* color is perceptually light.
*
* When tinting-mode is `contrasting`, the output color is suitable to use for a text color on
* a given background color. When `slight`, it's suitable for defining an active text color out
* of a given text color.
*/
.lf-define-tinted-color(
@input-color;
@tinting-mode: contrasting;
) {
.set-tinting-values(@mode) when (@mode = contrasting) {
@darken-by: 0.6;
@lighten-by: 0.7;
}
.set-tinting-values(@mode) when (@mode = slight) {
@darken-by: 0.2;
@lighten-by: 0.2;
}
.set-tinting-values(@mode) when (default()) {
@darken-by: 0;
@lighten-by: 0;
}
.set-tinting-values(@tinting-mode);
@switched-color: ~'@{input-color}-tinted-@{tinting-mode}';
@supports (color: rgb(from white r g b)) {
@{switched-color}: ~'oklch(
from var(@{input-color})
calc(min(max(0, l - 0.6) * 100, 1) * ((l - @{darken-by}) - (l + @{lighten-by})) + (l + @{lighten-by}))
c
h
)';
}
}
}