Skip to content

Releases: zaydek/duomo

v0.7.12

05 Jan 17:31
Compare
Choose a tag to compare

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.

v0.7.11

29 Dec 13:56
Compare
Choose a tag to compare

Theme transitioning

Added CDN support for theme transitioning. --theme-transition is now a CSS variable that targets the following properties:

  • background-color
  • border-color
  • box-shadow
  • color
  • fill
  • opacity
  • stroke

To customize the theme transition — i.e. smooth dark mode — you can set theme-duration and theme-timing respectively.

Example usage:

:root {
  --theme-duration: 600ms;
  --theme-timing: var(--ease-out);
}

*Note that 600ms and var(--ease-out) are the default --theme-transition values.

In other words, anywhere in your app you use transition: var(--theme-transition), all of these properties will be transitioned smoothly.

Sass theme transitioning

To make things even easier, there is now an exported Sass mixin to help with coordinating light and dark modes. Instead of doing the following:

:root {
  --ui-app-bg: var(--white);
}

[data-theme="dark"] {
  --ui-app-bg: var(--black);
}

.ui-app {
  background-color: var(--ui-app-bg);
  transition: var(--theme-transition);
}

You can now use the themes mixin instead:

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

$light: (
  ui-app-bg: color(white),
);

$dark: (
  ui-app-bg: color(black),
);

@at-root {
  @include themes($light, $dark);
}

This generates:

:root {
  --ui-app-bg: hsl(0deg, 0%, 100%);
}

[data-theme="dark"] {
  --ui-app-bg: hsl(0deg, 0%, 0%);
}

.ui-app {
  background-color: var(--ui-app-bg);
  transition: var(--theme-transition);
}

Getters

Duomo now exports the following getters for use with the Sass API:

weight(...)
font(...)
color(...)
decoration(...)
shadow(...)
timing(...)

weight-var(...)
font-var(...)
color-var(...)
decoration-var(...)
shadow-var(...)
timing-var(...)

These can be used to conveniently access design tokens provided by Duomo. The var counterparts populate as CSS variables, such as var(--font) instead of ui-sans-serif, ..., which may be desirable in some cases.

Finally, there are also plural versions of these getters that return Sass lists.

weights(...)
fonts(...)
colors(...)
decorations(...)
shadows(...)
timings(...)

weight-vars(...)
font-vars(...)
color-vars(...)
decoration-vars(...)
shadow-vars(...)
timing-vars(...)

Colors

To make the library internally consistent, colors are now named:

transparent
current
black
white
cool-gray // Was `gray`
red
amber // Was `green`
emerald // Was `green`
blue
indigo
violet // Was `purple`
pink

Furthermore, all of these colors are provided by Duomo as CSS variables:

transparent
current
black
white
rose
pink
fuchsia
purple
violet
indigo
blue
light-blue
cyan
teal
emerald
green
lime
yellow
amber
orange
red
warm-gray
true-gray
gray
cool-gray
blue-gray

That means you can now use hsl(var(--blue-gray-500)) or color(blue-gray-500) with the Sass API.

Note that all colors are provided as CSS variables with all CDN versions, including the skeleton CDN link.


Other notes:

  • Deprecated [data-debug-space]
  • Deprecated #duomo-root
  • Added justify-self-* and justify-* utilities for use with ZStacks
  • Added bg-placeholder; can be used in conjunction with bg-opacity-* classes

Known regressions:

  • Negative classes (such as -mx-16) are currently missing

v0.7.10

25 Dec 12:51
Compare
Choose a tag to compare
  • Adds theme-transition mixin for composing dark mode.

Example usage:

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

:root {
  --theme-transition: #{theme-transition(700ms, timing(ease-out, $raw: true))};
}
// -> :root {
// ->   --theme-transition: background-color 700ms cubic-bezier(0, 0, 0.2, 1), border-color 700ms cubic-bezier(0, 0, 0.2, 1),
// ->     box-shadow 700ms cubic-bezier(0, 0, 0.2, 1), color 700ms cubic-bezier(0, 0, 0.2, 1),
// ->     fill 700ms cubic-bezier(0, 0, 0.2, 1), opacity 700ms cubic-bezier(0, 0, 0.2, 1),
// ->     stroke 700ms cubic-bezier(0, 0, 0.2, 1), transform 700ms cubic-bezier(0, 0, 0.2, 1);
// -> }
  • Upgraded the runtime.

TypeScript definitions:

type Env = "development" | "production"

interface RuntimeOptions {
  quiet: boolean
}

interface Runtime {
  getDarkMode(): boolean
  setDarkMode(mode: boolean): void
  toggleDarkMode(): void

  getDebugMode(): boolean
  setDebugMode(mode: boolean): void
  toggleDebugMode(): void

  getDebugSpaceMode(): boolean
  setDebugSpaceMode(mode: boolean): void
  toggleDebugSpaceMode(): void

  init(env?: Env, options?: RuntimeOptions): () => void
}

v0.7.9

23 Dec 07:58
Compare
Choose a tag to compare
  • Deprecated gap-x-* and gap-y-* classes for now. These will likely be added back later.
  • Leading classes now use the -100 convention: leading-100 means line-height: 1, leading-110 means line-height: 1.1.
  • Non-minified files now use two spaces for formatting so tab-size never appears as 8 spaces.
  • Added skeleton CDN links: The skeleton bundle is meant to provide Duomo classes without colors (only grays) and variants (only core and responsive).
  • Added wrap classes for stacks; wrap, wrap-reverse, wrap-none.
  • Reverted shorthands for t-0, tr-0, r-0 back to top-0, top-right-0, right-0, etc.
  • Added transform-origin classes: origin-top, origin-top-right, origin-right, etc.
  • Added min-content and max-content classes throughout: min-w-min, w-min, max-w-min and max-w-min, w-max, max-w-max.
  • dist/stats.txt is now generated with every build; stats.txt tracks text, gzip, and brotli compression stats for every distribution CSS file.
  • Deprecated the place API for ZStack (see below).

ZStack usage:

<div class="zstack">
  <div><!-- ... --></div>
  <div class="top-0 right-0"><!-- ... --></div>
</div>

CDN links:

  • duomo-full.css
  • duomo-full.min.css* (default)
  • duomo.css
  • duomo.min.css
  • skeleton.css
  • skeleton.min.css

You can always explore the CDN links via this unpkg link: http://unpkg.com/@zaydek/duomo/. Note that the trailing forward slash is important to differentiate the default build from the inspectable directory.

dist/stats.txt for this release:

dist/duomo-full.css
+-----------------+
| text   | 1029kB |
| gzip   |   93kB |
| brotli |   35kB |
+-----------------+

dist/duomo-full.min.css
+-----------------+
| text   |  695kB |
| gzip   |   85kB |
| brotli |   29kB |
+-----------------+

dist/duomo.css
+-----------------+
| text   |  697kB |
| gzip   |   65kB |
| brotli |   24kB |
+-----------------+

dist/duomo.min.css
+-----------------+
| text   |  469kB |
| gzip   |   59kB |
| brotli |   21kB |
+-----------------+

dist/skeleton.css
+-----------------+
| text   |  416kB |
| gzip   |   48kB |
| brotli |   17kB |
+-----------------+

dist/skeleton.min.css
+-----------------+
| text   |  314kB |
| gzip   |   47kB |
| brotli |   16kB |
+-----------------+

v0.7.8

21 Dec 13:40
Compare
Choose a tag to compare

Added support for toggling dark mode instantly: window.Duomo.toggleDarkMode(true).

v0.7.7

21 Dec 13:12
Compare
Choose a tag to compare
  • All width and height classes now implement --dm-align-self so stack auto-alignment works as expected
  • Dark mode side effects (from the runtime) now target <html> instead of <body>
  • Runtime debugger can now toggle [data-debug-space] for you
    • d: Toggles [data-debug]
    • opt-d: Toggles [data-debug-space]
    • ctrl-d: Toggles [data-theme="dark"]
  • Default CDN link now points to prod-full
  • Staggerers have now been changed to [data-stagger="1"] syntax instead of data-stagger-1

v0.7.6

20 Dec 10:17
Compare
Choose a tag to compare
  • Patches an implementation bug with the align-self-* classes
  • Reversed the runtime shortcuts: d is now debug and ctrl-d is now dark mode

v0.7.5

20 Dec 09:08
Compare
Choose a tag to compare

Patches the browser runtime; Duomo now attaches to the window via window.Duomo.

v0.7.4

20 Dec 08:45
Compare
Choose a tag to compare
  • Adds experimental support for React components (<HStack>, <VStack>, <ZStack>, and <Spacer>)
  • Patched stack logic (user-facing API is unchanged)
  • The JavaScript runtime should now be accessible as a browser dependency: <script src=".../dist/browser">
  • The following classes have been renamed:
    • a-0inset-0
    • x-0inset-x-0
    • y-0inset-y-0
    • t-0top-0
    • tr-0top-right-0*
    • r-0right-0*
    • b-0bottom-0*
    • br-0bottom-right-0*
    • l-0left-0*
    • t-0top-0*
    • tl-0top-left-0*
    • translate-x-0x-0
    • translate-y-0y-0

*Note that place-* directions have now been updated to follow this pattern.

v0.7.3

19 Dec 10:00
Compare
Choose a tag to compare

Improves debugger aesthetic for empty spacers .spacer:empty.