mirror of
https://github.com/tabler/tabler.git
synced 2026-08-29 21:31:28 +04:00
246 lines
6.1 KiB
SCSS
246 lines
6.1 KiB
SCSS
// Output tests for the `generate-utility` mixin from
|
|
// scss/mixins/bootstrap/_utilities.scss — the engine behind Tabler's utility
|
|
// classes. `@use "../mixins/bootstrap/utilities"` pulls in the real
|
|
// settings/variables chain, so `$enable-important-utilities` = true (hence the
|
|
// `!important` in the output). Custom properties are expected unprefixed: the
|
|
// `--tblr-` prefix is added later, by the css pipeline (.build/css-var-prefix.ts).
|
|
//
|
|
// Each `it` feeds the mixin a hand-built utility map and asserts the generated
|
|
// classes, covering the branches that shape the output: map vs list values,
|
|
// single vs multiple properties, custom class, css-var mode, pseudo-class
|
|
// states and the responsive infix.
|
|
|
|
@use 'sass:map';
|
|
@use '../mixins/bootstrap/utilities' as *;
|
|
@use '../mixins/bootstrap/breakpoints' as *;
|
|
|
|
@include describe('generate-utility') {
|
|
@include it('generates a class per key from a values map') {
|
|
@include assert() {
|
|
@include output() {
|
|
@include generate-utility(
|
|
(
|
|
property: opacity,
|
|
values: (
|
|
0: 0,
|
|
50: 0.5,
|
|
),
|
|
)
|
|
);
|
|
}
|
|
@include expect() {
|
|
.opacity-0 {
|
|
opacity: 0 !important;
|
|
}
|
|
.opacity-50 {
|
|
opacity: 0.5 !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@include it('zips a plain list of values into key/value pairs') {
|
|
@include assert() {
|
|
@include output() {
|
|
@include generate-utility(
|
|
(
|
|
property: float,
|
|
class: float,
|
|
values: (
|
|
left,
|
|
right,
|
|
),
|
|
)
|
|
);
|
|
}
|
|
@include expect() {
|
|
.float-left {
|
|
float: left !important;
|
|
}
|
|
.float-right {
|
|
float: right !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@include it('emits every property when several are given') {
|
|
@include assert() {
|
|
@include output() {
|
|
@include generate-utility(
|
|
(
|
|
property: margin-inline-end margin-inline-start,
|
|
class: mx,
|
|
values: (
|
|
0: 0,
|
|
auto: auto,
|
|
),
|
|
)
|
|
);
|
|
}
|
|
@include expect() {
|
|
.mx-0 {
|
|
margin-inline-end: 0 !important;
|
|
margin-inline-start: 0 !important;
|
|
}
|
|
.mx-auto {
|
|
margin-inline-end: auto !important;
|
|
margin-inline-start: auto !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@include it('sets a custom property instead of a declaration in css-var mode') {
|
|
@include assert() {
|
|
@include output() {
|
|
@include generate-utility(
|
|
(
|
|
property: opacity,
|
|
class: opacity,
|
|
css-var: true,
|
|
values: (
|
|
50: 0.5,
|
|
),
|
|
)
|
|
);
|
|
}
|
|
@include expect() {
|
|
.opacity-50 {
|
|
--opacity: 0.5;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@include it('adds a pseudo-class variant for each declared state') {
|
|
@include assert() {
|
|
@include output() {
|
|
@include generate-utility(
|
|
(
|
|
property: text-decoration,
|
|
class: text-decoration,
|
|
state: hover,
|
|
values: (underline),
|
|
)
|
|
);
|
|
}
|
|
@include expect() {
|
|
.text-decoration-underline {
|
|
text-decoration: underline !important;
|
|
}
|
|
.text-decoration-underline-hover:hover {
|
|
text-decoration: underline !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@include it('injects the responsive infix into the class name') {
|
|
@include assert() {
|
|
@include output() {
|
|
@include generate-utility(
|
|
(
|
|
property: display,
|
|
class: d,
|
|
values: (none),
|
|
),
|
|
'-md'
|
|
);
|
|
}
|
|
@include expect() {
|
|
.d-md-none {
|
|
display: none !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// `generate-utility` itself does not read the `responsive` key — that gate lives
|
|
// in bootstrap/utilities/_api.scss, which loops the breakpoints and only calls
|
|
// the mixin for a given infix when `map.get($utility, responsive)` is truthy (or
|
|
// it's the base, infix-less breakpoint). This reproduces that gate against a local
|
|
// breakpoint map with two utilities: one `responsive: true`, one without.
|
|
@include describe('generate-utility (responsive property)') {
|
|
$g: (
|
|
xs: 0,
|
|
sm: 576px,
|
|
md: 768px,
|
|
);
|
|
$utils: (
|
|
'display': (
|
|
property: display,
|
|
class: d,
|
|
responsive: true,
|
|
values: (
|
|
none,
|
|
flex,
|
|
),
|
|
),
|
|
'float': (
|
|
property: float,
|
|
class: float,
|
|
values: (
|
|
start: inline-start,
|
|
end: inline-end,
|
|
none: none,
|
|
),
|
|
),
|
|
);
|
|
|
|
@include it('only a `responsive: true` utility gets breakpoint-infixed variants') {
|
|
@include assert() {
|
|
@include output() {
|
|
@each $bp in map.keys($g) {
|
|
@include media-breakpoint-up($bp, $g) {
|
|
$infix: breakpoint-infix($bp, $g);
|
|
@each $key, $utility in $utils {
|
|
@if map.get($utility, responsive) or $infix == '' {
|
|
@include generate-utility($utility, $infix);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@include expect() {
|
|
// base breakpoint: both utilities emit bare classes
|
|
.d-none {
|
|
display: none !important;
|
|
}
|
|
.d-flex {
|
|
display: flex !important;
|
|
}
|
|
.float-start {
|
|
float: inline-start !important;
|
|
}
|
|
.float-end {
|
|
float: inline-end !important;
|
|
}
|
|
.float-none {
|
|
float: none !important;
|
|
}
|
|
|
|
// responsive breakpoints: only `d` (responsive: true) is repeated; `float` is not
|
|
@media (min-width: 576px) {
|
|
.d-sm-none {
|
|
display: none !important;
|
|
}
|
|
.d-sm-flex {
|
|
display: flex !important;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
.d-md-none {
|
|
display: none !important;
|
|
}
|
|
.d-md-flex {
|
|
display: flex !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|