@teacss/directives
v0.10.11
Published
Build-time CSS directive transformer for TeaCSS — @apply, theme(), icon(), and @screen.
Readme
@teacss/directives
Shared transforms for TeaCSS CSS authoring helpers.
.button {
@apply p-x:4 p-y:2 rd:2 content:["hello world"];
color: theme("colors.red.500");
background-image: icon("lucide-sun");
}
@screen md {
.button {
@apply p-x:6;
}
}The package handles @apply, @screen, theme(...), and icon(...).
@screen at-* selects the next greater comparable breakpoint as its upper
bound, including same-unit logical viewport (svi, dvb, etc.) and root-font
(rex, rch, rcap, ric) lengths. Different relative units remain incomparable.
icon() receives <collection>-<icon-name> without the icon: utility
prefix. Group syntax and attached [] values follow the same parsing rules as
class lists.
The @teacss/vite-ts and @teacss/cli pipelines use these transforms
automatically.
With Standard's preflight: "on-demand", applied utilities carry their required
theme variables in the consuming stylesheet, including non-entry CSS modules.
This does not generate additional utility selectors or repeat static resets
and full-theme preflights. Replacing or removing the module removes its
dependencies too.
A rule that two applied utilities both write is written once. An @apply
inside a nested rule writes the @property registrations it needs at the end
of the stylesheet, because browsers drop @property inside a style rule. In
the descriptors of @property, @font-face, @font-palette-values, and
@counter-style, and in an icon() color, theme() writes a color as its
literal value. A role step there is the light value of the palette step it
names, so it does not follow modes or runtime role switching.
The directives also work in SCSS, Less and Stylus source written with braces,
including a Vue <style lang="scss"> block, and leave the rest of the source
as written. A Sass @mixin body or @include content block, a Less detached
ruleset, mixin, guard or :extend() rule hosts @apply as &. A .sass file
that uses a directive fails the transform; write it as .scss. A keyframe block
takes only tokens without a selector or condition.
When a host selector ends with a pseudo-element, a condition goes before it, also
for an @apply in a nested @media, @supports, @container, @layer,
@starting-style, @screen or & rule: .a::before { @media (x) { @apply
p:4@hover; } } writes @media (x) { .a:hover::before { … } } after the rule.
Integration authors can reuse adapter-neutral semantics from the Core subpath:
import {
generateApplyPreflights,
prepareApplyUtilities,
resolveApplyTokens,
resolveCssFunction,
resolveScreenQuery,
} from "@teacss/directives/core";Core helpers do not mutate a stylesheet. The adapter supplies its AST and source
operations. When an integration splices an entry, native @charset and hoisted
@import rules stay before generated content.
Call prepareApplyUtilities(tokens, generator.parentOrders, generator.config.layers, (utilities) => generator.sheetOrder(utilities)).
The optional third argument retains configured layer ordering (the default is
Core's standard order). The optional fourth keeps the utilities of one layer and
parent in the order the stylesheet writes them, a flattened shortcut staying
whole (the default is index order, which ignores that).
Within a layer, parent conditions use Core's generator comparator. Applied
declarations occupy their caller's CSS layer; separate @apply directives retain
source order.
After resolving all applies, pass their flattened utility payloads to
generateApplyPreflights(generator, generated, filename) and append its CSS at the
stylesheet's top level. It preserves configured CSS layers and keeps dependency
state local to that stylesheet. Pass the filename so conventional .module.css
stylesheets keep generated theme selectors global. Also pass it to
renderStandaloneApplyUtility: fixed dependency selectors, html mode selectors and configured
aliases stay global while the application host remains local.
Pre-1.0. Applications should normally use a build adapter.
