Skip to content

v0.7.12

Latest
Compare
Choose a tag to compare
@zaydek zaydek released this 05 Jan 17:31
· 69 commits to main since this release

This release focuses on two goals:

  • Making Duomo structurally more sound and future-proof
  • Implementing MVP dark mode Sass APIs

Structurally sound

What does structurally more sound mean? One of the end-goals of Duomo is that you don’t need to using purging technologies in order to leverage Duomo via CDN or the Sass API.

How is this possible? Optimizations! There are many optimizations that can be taken to decrease the generated CSS file. Besides the basics -- like constraining ranges and colors -- grouping selectors is one of the most effective methods.

What does grouping selectors mean in practice? Essentially the following:

// duomo.scss (optimized for development)
.class { ... }
.hover\:class { ... }
.focus\:class { ... }
// duomo.min.scss (optimized for production)
.class,
.hover\:class,
.focus\:class { ... }

This means that classes that implement variants do not generate their own bodies in production mode. This optimization makes it possible for selectors to be effectively grouped. For Duomo, this cuts the generated CDN footprint by as much as 22%!

The cleancss CLI tool was also added to the build process, which shaves off another ~3%. These two techniques combined make up for a 25% file size reduction for the standard Duomo CDN link, which now weighs 421kB uncompressed and 19kB with Brotli compression. Note that if you are using the Sass APIs, you can expect significantly smaller file sizes, as you can configure the library to your liking. Omitting colors, for example, helps dramatically.

Dark mode APIs (Sass)

The previous dark mode Sass API has been deprecated in favor of a simpler, less magical API. The new themes API simply interpolates maps associated with light and dark mode schemes but does not generate classes automatically.

Here’s a rough idea of the new direction for the Sass dark mode API:

@use "@zaydek/duomo" as * with ($headless: true);

$light: (
  app-color: color(black),
  app-bg: color(white),
  hoverable-bg: color(black, 0.05),
);

$dark: (
  app-color: color(white),
  app-bg: color(black),
  hoverable-bg: color(white, 0.05),
);

@at-root {
  @include themes((light: $light, dark: $dark), 700ms, timing(ease-out));
}

.x-app {
  @include theme-transition {
    color: var(--app-color);
    background-color: var(--app-bg);
  }
}

The light and dark maps are interpolated as simple CSS variables using the :root and :root[data-theme="dark"] selectors. The final arguments, 700ms and timing(ease-out) simply set --default-theme-transition-duration and --default-theme-transition-timing so you don’t have to.

Finally, you are meant to compose your own classes, name them to your liking, and simply reference the CSS variables that were generated for you in either the $light and or $dark maps.

The reason maps are used is because it removes a lot of unnecessary syntax: no need to delimit CSS variables with -- or wrap values with #{...} because expressions are eagerly (rather than lazily) processed.

The idea with this API is to enable support for more than light and dark modes in the future, by simply providing more maps than $light and $dark.

Finally, there are two mixins that are provided to make your life easier when coordinating theme-aware classes.

  • theme-transition
  • theme-variants

theme-transition

theme-transition simply adds transition: var(--theme-transition) at the end of a class body. This enables classes to transition gracefully between light and dark modes as their properties are theme-aware.

For example:

.x-app {
  @include theme-transition {
    color: var(--app-color);
    background-color: var(--app-bg);
  }
}

// -> .x-app {
// ->   color: var(--app-color);
// ->   background-color: var(--app-bg);
// ->   transition: var(--theme-transition);
// -> }

theme-variants

theme-variants is designed to make authoring variant-based classes easier (such as hover or focus) and are theme-aware by default.

Here’s the basic idea:

.x-hoverable {
  @include theme-variants((hover), 250ms, timing(ease-out)) {
    background-color: var(--hoverable-bg);
  }
}

// -> .x-hoverable {
// ->   transition: var(--theme-transition);
// -> }
// ->
// -> :root:not([data-theme-effect]) .x-hoverable {
// ->   transition: 250ms background-color cubic-bezier(0, 0, 0.2, 1), ...
// -> }
// ->
// -> .x-hoverable:hover {
// ->   background-color: var(--hoverable-bg);
// -> }

Both of these APIs are experimental and may be deprecated in the future.

Note: theme-variants does not yet support group-*-based variants.

New getters

Range-based getters have been added to make iterating over range-based values easier. These are used throughout the library extensively.

nspaces()       // Negative spaces, from -1 up to -128
spaces()        // Non-negative spaces, from 0 up to 128
sizes()         // From 0 up to 640
font-sizes()    // From 8 up to 64
border-widths() // From 0 up to 8
border-radii()  // From 0 up to 32

Revised aspect ratio API

The aspect ratio API has been upgraded to use utility classes as opposed to the style selector that was previously used. This is because style selectors cannot reasonably support responsive variants.

If you know Tailwind CSS-based aspect ratios, the API is the same:

<!-- Non-responsive -->
<div class="aspect aspect-w-16 aspect-h-9">...</div>

<!-- Responsive -->
<div class="aspect aspect-w-16 md:aspect-w-9 aspect-h-9 md:aspect-h-16">
  ...
</div>

Other improvements:

  • HStack, VStack, and ZStack have been internally simplified.
  • cursor-default, cursor-pointer, and cursor-none classes have been added (thanks to @joyact!).
  • justify and justify-self classes have been added (thanks to @joyact!).
  • Skeleton has been renamed to Layout; the Layout CDN / API does not generate color-based classes at all now.
  • Plural getters (like colors) now return a key-value map instead of list of values.
  • The standard range has simplified (see src/configuration/configuration.scss for more information).
  • color(transparent) and color(current) or color(currentColor) no longer return an erroneous value.
  • Added (back) the placement API
  • Stacks are designed to be simpler and more internally consistent (auto-centering fixed-size elements has been deprecated)

Deprecations:

  • The hidden, unhidden API has been renamed to hide, show. Don’t @ me.
  • duomo.full.css and duomo.full.min.css have been deprecated in favor of duomo.css and duomo.min.scss (https://unpkg.com now points to duomo.css by default).
  • The -var getters have been deprecated.
  • Colors are intentionally no longer exported as CSS variables. In order to leverage colors and other design tokens provided by Duomo, you should opt for the Sass APIs, which provide more power for less code.

Known regressions:

  • The bg-placeholder class has been temporarily disabled.
  • The transition classes have been temporarily disabled.