@teacss/directives 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2021-PRESENT Anthony Fu <https://github.com/antfu>
4
+ Copyright (c) 2026-PRESENT Billgo <hi@billgo.me>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # @teacss/directives
2
+
3
+ **CSS directive transforms for TeaCSS.**
4
+
5
+ ## Purpose
6
+
7
+ This package expands authoring helpers such as `@apply`, `@screen`,
8
+ `theme(...)`, and `icon(...)` before CSS is emitted by integrations.
9
+
10
+ It is a shared implementation for TeaCSS build-integration authors. The main
11
+ entry provides the source-transformer and CSS-entry helpers used by official
12
+ pipelines, while `@teacss/directives/core` exposes adapter-neutral primitives
13
+ for other CSS ASTs. It does not own source scanning, watching, or bundler
14
+ lifecycle; applications should normally select a build integration instead.
15
+
16
+ ## Usage
17
+
18
+ ```css
19
+ .button {
20
+ @apply p-x:4 p-y:2 radius:2 content:["hello world"];
21
+ color: theme("colors.red.500");
22
+ background-image: icon("carbon-sun");
23
+ }
24
+
25
+ @screen md {
26
+ .button {
27
+ @apply p-x:6;
28
+ }
29
+ }
30
+ ```
31
+
32
+ `icon()` receives `<collection>-<icon-name>` without the class utility's
33
+ `icon:` property prefix.
34
+
35
+ `@apply` splits only whitespace outside attached `[]` literal regions, so
36
+ spaces in arbitrary values remain part of one TeaCSS utility.
37
+
38
+ Used automatically by the Vite, PostCSS, Rsbuild, Bun, and CLI pipelines.
39
+ When an integration splices a CSS entry, a BOM and native `@charset` remain
40
+ before hoisted `@import` rules.
41
+
42
+ ## Integration-author API
43
+
44
+ CSS adapters can reuse the same directive semantics through the public core
45
+ subpath:
46
+
47
+ ```ts
48
+ import {
49
+ prepareApplyUtilities,
50
+ resolveApplyTokens,
51
+ resolveCssFunction,
52
+ resolveScreenQuery,
53
+ } from "@teacss/directives/core";
54
+ ```
55
+
56
+ The subpath also exports the apply rendering helpers and their public types.
57
+ It does not parse or mutate an adapter's stylesheet; callers provide the host
58
+ AST and source-range operations needed by their CSS implementation.
59
+
60
+ ## Status
61
+
62
+ Pre-1.0 public API for integration authors. Most applications should use a
63
+ TeaCSS build integration instead.
package/dist/core.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { TeacssGenerator } from "@teacss/core";
2
+ import { FunctionNode, SelectorList } from "css-tree";
3
+ //#region src/apply-core.d.ts
4
+ type ResolvedApplyToken = readonly [name: string, utilities: Awaited<ReturnType<TeacssGenerator["parseToken"]>>];
5
+ type PreparedApplyUtility = {
6
+ readonly kind: "inline";
7
+ readonly body: string;
8
+ } | {
9
+ readonly kind: "standalone";
10
+ readonly selector: string | undefined;
11
+ readonly body: string;
12
+ readonly parent: string | undefined;
13
+ readonly noMerge: boolean;
14
+ };
15
+ type StandaloneApplyUtility = Extract<PreparedApplyUtility, {
16
+ kind: "standalone";
17
+ }>;
18
+ interface ApplyHost {
19
+ readonly prelude: SelectorList;
20
+ readonly selector: string;
21
+ readonly replacementSelector: string;
22
+ }
23
+ declare function resolveApplyTokens(classNames: readonly string[], generator: TeacssGenerator): Promise<ResolvedApplyToken[]>;
24
+ declare function missingApplyTokens(tokens: readonly ResolvedApplyToken[]): string[];
25
+ declare function formatMissingApplyTokens(missing: readonly string[]): string;
26
+ declare function prepareApplyUtilities(tokens: readonly ResolvedApplyToken[], parentOrders: ReadonlyMap<string, number>): PreparedApplyUtility[];
27
+ declare function renderStandaloneApplyUtility(host: ApplyHost, utility: StandaloneApplyUtility): string;
28
+ //#endregion
29
+ //#region src/function-core.d.ts
30
+ type ReadSourceRange = (start: number, end: number) => string;
31
+ /** Resolve a TeaCSS declaration-value function without mutating an adapter's source. */
32
+ declare function resolveCssFunction(generator: TeacssGenerator, node: FunctionNode, readSourceRange: ReadSourceRange, throwOnMissing?: boolean): Promise<string | undefined>;
33
+ //#endregion
34
+ //#region src/screen-core.d.ts
35
+ /** Resolve an `@screen` value to the media-query condition shared by CSS adapters. */
36
+ declare function resolveScreenQuery(rawBreakpoint: string, theme: object): string | undefined;
37
+ //#endregion
38
+ export { type ApplyHost, type PreparedApplyUtility, type ResolvedApplyToken, type StandaloneApplyUtility, formatMissingApplyTokens, missingApplyTokens, prepareApplyUtilities, renderStandaloneApplyUtility, resolveApplyTokens, resolveCssFunction, resolveScreenQuery };
package/dist/core.js ADDED
@@ -0,0 +1 @@
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./screen-core-DIkTMaQQ.js";export{i as formatMissingApplyTokens,t as missingApplyTokens,e as prepareApplyUtilities,r as renderStandaloneApplyUtility,a as resolveApplyTokens,n as resolveCssFunction,o as resolveScreenQuery};
@@ -0,0 +1,98 @@
1
+ import { MagicStringLike, SourceCodeTransformer, TeacssGenerator } from "@teacss/core";
2
+ import { customToTheme, diagnoseCustom, parseEntry, resolvePresets } from "@teacss/config";
3
+ //#region src/types.d.ts
4
+ interface TransformerDirectivesOptions {
5
+ enforce?: SourceCodeTransformer["enforce"];
6
+ /**
7
+ * Throw an error if utils or themes are not found.
8
+ *
9
+ * @default true
10
+ */
11
+ throwOnMissing?: boolean;
12
+ /**
13
+ * Treat CSS custom properties as @apply directives for CSS syntax compatibility.
14
+ *
15
+ * Pass `false` to disable.
16
+ *
17
+ * @default ['--at-apply']
18
+ */
19
+ applyVariable?: false | string | string[];
20
+ /**
21
+ * Treat CSS custom properties as directives for CSS syntax compatibility.
22
+ *
23
+ * Pass `false` to disable, or a string to use as a prefix.
24
+ *
25
+ * @deprecated use `applyVariable` to specify the full var name instead.
26
+ * @default '--at-'
27
+ */
28
+ varStyle?: false | string;
29
+ }
30
+ interface TransformerDirectivesContext {
31
+ code: MagicStringLike;
32
+ generator: TeacssGenerator;
33
+ options: TransformerDirectivesOptions;
34
+ applyVariable: string[];
35
+ offset?: number;
36
+ filename?: string;
37
+ }
38
+ //#endregion
39
+ //#region src/generateEntry.d.ts
40
+ interface GenerateEntryOptions {
41
+ /** Entry file directory — base for `@preset` relative specifiers and `@source` globs. */
42
+ base: string;
43
+ /** Read scanned content for the given include/exclude globs. Omit when `contents` is given. */
44
+ readSources?: (includes: string[], excludes: string[]) => Promise<{
45
+ files: string[];
46
+ sources: string[];
47
+ }>;
48
+ /** Inline content to extract utilities from — skips `readSources` (tests / programmatic use). */
49
+ contents?: string[];
50
+ }
51
+ interface GenerateEntryResult {
52
+ /** Generated stylesheet (preflight `:root`/mode theme vars + utilities) to splice at `@teacss`. */
53
+ layers: string;
54
+ /** Absolute paths scanned (for watch registration). */
55
+ files: string[];
56
+ /** `@custom` var names that matched no namespace / illegal step (decision 11 — for LSP diagnostics). */
57
+ unknown: string[];
58
+ /** Number of utilities matched. */
59
+ matched: number;
60
+ /** Whether the entry has a `@teacss;` placeholder. */
61
+ hasTeacss: boolean;
62
+ /** Whether the entry declared at least one `@preset` (false → nothing to generate; caller warns). */
63
+ hasPreset: boolean;
64
+ }
65
+ /**
66
+ * Drive generation from a CSS entry: parse its directives, resolve `@preset`,
67
+ * register `@custom` into the theme, scan `@source` content, and generate.
68
+ * There's no implicit default preset — an entry with no `@preset` yields no
69
+ * utilities and reports `hasPreset: false` for the caller to warn. Returns the
70
+ * generated layers (the theme preflight emits `:root`/mode vars from the
71
+ * registered `@custom`) plus the scanned files and `@custom` diagnostics.
72
+ * Splicing the layers into the entry file (replacing `@teacss`, stripping the
73
+ * consumed directives) is the caller's job. The core engine is untouched — this
74
+ * is integration-layer orchestration.
75
+ */
76
+ declare function generateEntry(entryCss: string, options: GenerateEntryOptions): Promise<GenerateEntryResult>;
77
+ //#endregion
78
+ //#region src/spliceEntry.d.ts
79
+ /**
80
+ * Produce the final stylesheet from an entry CSS file and the generated layers:
81
+ *
82
+ * - `@teacss;` → replaced by `layers`
83
+ * - `@preset` / `@source` / `@custom {}` → stripped (consumed)
84
+ * - native `@charset` / `@import` → hoisted in CSS-required order
85
+ * - everything else (plain rules, comments, `@media`, …) → kept in place
86
+ *
87
+ * Pure, css-tree-free: exact top-level at-rule ranges are scanned structurally
88
+ * and spliced out of the original.
89
+ */
90
+ declare function spliceEntry(entryCss: string, layers: string): string;
91
+ //#endregion
92
+ //#region src/transform.d.ts
93
+ declare function transformDirectives(code: MagicStringLike, generator: TeacssGenerator, options: TransformerDirectivesOptions, filename?: string, originalCode?: string, offset?: number): Promise<void>;
94
+ //#endregion
95
+ //#region src/index.d.ts
96
+ declare function transformerDirectives(options?: TransformerDirectivesOptions): SourceCodeTransformer;
97
+ //#endregion
98
+ export { GenerateEntryOptions, GenerateEntryResult, TransformerDirectivesContext, TransformerDirectivesOptions, customToTheme, transformerDirectives as default, diagnoseCustom, generateEntry, parseEntry, resolvePresets, spliceEntry, transformDirectives };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{a as e,i as t,n,o as r,r as i,s as a,t as o}from"./screen-core-DIkTMaQQ.js";import{createGenerator as s,expandVariantGroup as c,isCssId as l,splitClassTokens as u,toArray as d}from"@teacss/core";import{generate as f,parse as p,walk as m}from"css-tree";import{hasIconFn as h,hasThemeFn as g}from"@teacss/rule-helpers";import{customToTheme as _,diagnoseCustom as v,parseEntry as y,resolveEntryConfig as b,resolvePresets as x,scanTopLevelAtRules as S}from"@teacss/config";import{generateSources as C}from"@teacss/runtime/source-generation";async function w(e,t,n){let r=[],i=[],a=!1;for(let o of t.block.children)if(o.type===`Raw`)await n(o.value,o.loc.start.offset);else{let n=await T(e,t,o);if(!n)continue;r.push(n.consumedRange),i.push(...n.standaloneCss),a||=n.hasInlineUtility}let o=e.code.original,s=t.block.loc.start.offset+1,c=!1;for(let[e,t]of r){if(o.slice(s,e).trim()){c=!0;break}s=t}c||=!!o.slice(s,t.block.loc.end.offset-1).trim(),!a&&!c&&r.length>0&&e.code.remove(t.loc.start.offset,t.loc.end.offset);for(let n of i)e.code.appendLeft(t.loc.end.offset,n)}async function T({code:n,generator:o,applyVariable:s,options:l,filename:d},p,m){let h=n.original,g;if(m.type===`Atrule`&&m.name===`apply`&&m.prelude&&m.prelude.type===`Raw`)g=E(m.prelude.value.trim());else if(m.type===`Declaration`&&s.includes(m.property)&&(m.value.type===`Value`||m.value.type===`Raw`)){let e=h.slice(m.value.loc.start.offset,m.value.loc.end.offset).trim();e=E(e),g=u(e).map(e=>E(e)).join(` `)}if(!g)return;g=D(g);let _=await a(u(c(g)),o),v=t(_);if(v.length&&(l.throwOnMissing??!0))throw Error(`${i(v)}${d?` in ${d}`:``}`);let y=e(_,o.parentOrders),b=+(h[m.loc.end.offset]===`;`),x=[m.loc.start.offset,m.loc.end.offset+b];if(!y.length)return n.remove(...x),{consumedRange:x,hasInlineUtility:!1,standaloneCss:[]};let S,C=!1,w=[];for(let e of y)if(e.kind===`standalone`){if(!S){let e=p.prelude;S={prelude:e,selector:f(e),replacementSelector:n.slice(p.prelude.loc.start.offset,p.prelude.loc.end.offset)}}let t=r(S,e);w.push(t)}else C=!0,e.body.includes(`@`)?n.appendRight(h.length,e.body):n.appendLeft(m.loc.start.offset,e.body);return x[1]=m.loc.end.offset+b,n.remove(...x),{consumedRange:x,hasInlineUtility:C,standaloneCss:w}}function E(e){return e.replace(/^(['"])(.*)\1$/,`$2`)}function D(e){return e.replace(/\/\*[\s\S]*?\*\//g,``)}async function O({code:e,generator:t,options:r},i){let a=await n(t,i,(t,n)=>e.slice(t,n),r.throwOnMissing??!0);a!==void 0&&e.overwrite(i.loc.start.offset,i.loc.end.offset,a)}const k=/(@screen [^{]+).+/g;function A({code:e,generator:t},n){if(n.prelude?.type!==`Raw`)return;let r=o(n.prelude.value,t.config.theme);if(!r)return;let i=n.loc.start.offset,a=e.original.slice(i,n.loc.end.offset);for(let t of a.matchAll(k))e.overwrite(i+t.index,i+t.index+t[1].length,`@media ${r}`)}async function j(e,t,n,r,i,a){let{applyVariable:o}=n,s=n.varStyle;o===void 0&&(o=s===void 0?[`--at-apply`]:s?[`${s}apply`]:[]),o=d(o||[]);let c=e=>e.includes(`@apply`)||o.some(t=>e.includes(t)),l=i||e.original,u=c(l),f=l.includes(`@screen`),_=g(l)||h(l);if(!u&&!_&&!f)return;let v=p(l,{parseCustomProperty:!0,parseAtrulePrelude:!1,positions:!0,filename:r,offset:a});if(v.type!==`StyleSheet`)return;let y=[],b=new WeakSet,x=new WeakSet,S={options:n,applyVariable:o,generator:t,code:e,filename:r,offset:a},C=(i,a)=>j(e,t,n,r,i,a),T=async e=>{for(let t of e.block.children)t.type===`Raw`&&await C(t.value,t.loc.start.offset)};m(v,function(t){if(f&&t.type===`Atrule`&&t.name===`screen`)A(S,t);else if(_&&t.type===`Function`&&(t.name===`theme`||t.name===`icon`))return y.push(O(S,t)),this.skip;else u&&t.type===`Rule`&&c(e.original.slice(t.loc.start.offset,t.loc.end.offset))?(b.add(t),y.push(w(S,t,C))):t.type===`Raw`&&this.rule&&!b.has(this.rule)&&!x.has(this.rule)&&(x.add(this.rule),y.push(T(this.rule)))}),await Promise.all(y)}async function M(e,t){let{base:n,readSources:r,contents:i}=t,a=await b(e,n),o=await s(a.config),c=[],l=[];for(let e of a.config.content?.filesystem??[])e.startsWith(`!`)?l.push(e.slice(1)):c.push(e);let{files:u,sources:d}=i?{files:[],sources:i}:r?await r(c,l):{files:[],sources:[]},f=await C(o,u,d);return{layers:f.getLayers()||``,files:u,unknown:a.unknown,matched:f.matched.size,hasTeacss:a.hasTeacss,hasPreset:!!a.config.presets?.length}}function N(e,t){let n=[],r=[],i=[];for(let a of S(e))a.name===`charset`&&a.terminator===`;`?(n.push(e.slice(a.start,a.end)),i.push({start:a.start,end:a.end,replacement:``})):a.name===`import`&&a.terminator===`;`?(r.push(e.slice(a.start,a.end)),i.push({start:a.start,end:a.end,replacement:``})):(a.name===`preset`||a.name===`source`)&&a.terminator===`;`||a.name===`custom`&&a.terminator===`block`?i.push({start:a.start,end:a.end,replacement:``}):a.name===`teacss`&&a.prelude===``&&a.terminator!==`block`&&i.push({start:a.start,end:a.end,replacement:t});i.sort((e,t)=>e.start-t.start);let a=``,o=0;for(let t of i)a+=e.slice(o,t.start)+t.replacement,o=t.end;a+=e.slice(o);let s=a.startsWith(``)?``:``;s&&(a=a.slice(1));let c=[...n,...r];return s+(c.length?`${c.join(`
2
+ `)}\n`:``)+a}function P(e={}){return{name:`@teacss/directives`,enforce:e.enforce,idFilter:l,transform:(t,n,r)=>j(t,r.generator,e,n)}}export{_ as customToTheme,P as default,v as diagnoseCustom,M as generateEntry,y as parseEntry,x as resolvePresets,N as spliceEntry,j as transformDirectives};
@@ -0,0 +1 @@
1
+ import{notNull as e}from"@teacss/core";import{clone as t,generate as n,parse as r,walk as i}from"css-tree";import{calcMaxWidthBySize as a,hasIconFn as o,hasThemeFn as s,transformThemeFn as c,transformThemeString as l}from"@teacss/rule-helpers";async function u(e,t){return await Promise.all(e.map(async e=>[e,await t.parseToken(e,`-`)]))}function d(e){return e.filter(([,e])=>e==null).map(([e])=>e)}function f(e){return`[@teacss] @apply: no rule matched ${e.map(e=>`"${e}"`).join(`, `)}`}function p(e){let t=!1,n=0,r,i=``;for(let a=0;a<e.length;a++){let o=e[a];if(t){o===`*`&&e[a+1]===`/`&&(t=!1,a++);continue}if(r){o===`\\`?a++:o===r&&(r=void 0);continue}if(o===`/`&&e[a+1]===`*`){t=!0,a++;continue}if(o===`\\`){a++;continue}if(o===`"`||o===`'`){r=o;continue}if(!/\s/.test(o)||e[a+1]!==`$`||e[a+2]!==`$`||!/\s/.test(e[a+3]??``))continue;let s=a+4;for(;s<e.length&&/\s/.test(e[s]);)s++;i+=`${e.slice(n,a)} `,n=s,a=s-1}return n?i+e.slice(n):e}function m(e){let t=[],n=0,r=!1,i=0,a,o=0;for(let s=0;s<e.length;s++){let c=e[s];r?c===`*`&&e[s+1]===`/`&&(r=!1,s++):a?c===`\\`?s++:c===a&&(a=void 0):c===`/`&&e[s+1]===`*`?(r=!0,s++):c===`"`||c===`'`?a=c:c===`(`?i++:c===`)`?i>0&&i--:c===`[`?n++:c===`]`?n>0&&n--:n===0&&i===0&&e.startsWith(` $$ `,s)&&(t.push(e.slice(o,s)),s+=3,o=s+1)}return t.push(e.slice(o)),t}function h(t,n){let r=t.flatMap(([,e])=>e??[]).filter(e).sort((e,t)=>(e[3]?n.get(e[3])??0:0)-(t[3]?n.get(t[3])??0:0)||e[0]-t[0]);if(!r.length)return[];let i=[],a;for(let e of r){if(!a&&i.length===64){a=new Map;for(let e of i)g(a,e)}let t=e[1],n=e[3],r=a?a.get(n)?.get(t):i.find(e=>e[1]===t&&e[3]===n);if(r){r[2]+=e[2];continue}let o=[...e];i.push(o),a&&g(a,o)}return i.map(([,e,t,n,r])=>{let i=e&&p(e),a=!!(i&&r?.noMerge);return n||i&&i!==`.\\-`||a?{kind:`standalone`,selector:i,body:t,parent:n,noMerge:a}:{kind:`inline`,body:t}})}function g(e,t){let n=t[3],r=e.get(n);r||(r=new Map,e.set(n,r)),r.set(t[1],t)}function _(e,t){let n=e.selector;t.selector&&t.selector!==`.\\-`&&(n=v(e.prelude,t.selector));let r=`${n}{${t.body}}`;if(t.parent){let n=m(t.parent);r=n.length>1?`${n.join(`{`)}{${r}${`}`.repeat(n.length)}`:t.parent===`.\\-`?`${e.replacementSelector}{${r}}`:`${t.parent}{${r}}`}return r}function v(e,a){let o=r(`${a}{}`,{context:`rule`}).prelude;if(!a.includes(`.\\-`))return n(o);let s=t(o);return s.children.clear(),e.children.forEach(e=>{o.children.forEach(n=>{let r=t(n);i(r,{visit:`ClassSelector`,enter(n,r,i){n.name===`\\-`&&i.replace(r,t(e).children)}}),s.children.appendData(r)})}),n(s)}async function y(e,t,n,r=!0){switch(t.name){case`theme`:{if(!t.children.size)throw Error(`theme() expect exact one argument`);if(t.children.first.type!==`String`)throw Error(`theme() expect a string argument`);let i;if(t.children.size>1){let e=t.children.toArray().slice(1);if(e[0].type!==`Operator`||e[0].value!==`,`)throw Error(`theme() expect a comma between expression string and default value`);e.length>1&&(i=[e[1].loc.start.offset,t.children.last.loc.end.offset])}let a=l(t.children.first.value,e.config.theme,!i&&r);return a===void 0&&i&&(a=await b(e,n(i[0],i[1]),r)),a}case`icon`:{let n=t.children.toArray().filter(e=>e.type===`String`).map(e=>e.value);if(n.length===0)throw Error(`icon() expects at least one argument`);let[i,a]=n;return a&&=encodeURIComponent(c(a,e.config.theme,r)),x(e,i,a)}}}async function b(e,t,n){if(!s(t)&&!o(t))return t;let a=[],c=[];i(r(t,{context:`value`,parseCustomProperty:!0,positions:!0}),function(r){if(!(r.type!==`Function`||r.name!==`theme`&&r.name!==`icon`||!r.loc))return c.push(y(e,r,(e,n)=>t.slice(e,n),n).then(e=>{e!==void 0&&a.push({start:r.loc.start.offset,end:r.loc.end.offset,value:e})})),this.skip}),await Promise.all(c);let l=t;for(let e of a.sort((e,t)=>t.start-e.start))l=`${l.slice(0,e.start)}${e.value}${l.slice(e.end)}`;return l}async function x(e,t,n){let r=e.config.presets?.flat()?.find(e=>e.name===`@teacss/preset-icons`);if(!r){console.warn(`@teacss/preset-icons not found, icon() directive will be kept as-is`);return}let i=r.api,a=await i.resolveIcon(t);if(!a)return;let o=i.encodeSvgForCss(a.svg);return`url("data:image/svg+xml;utf8,${n?o.replace(/currentcolor/gi,n):o}")`}function S(e,t){let n=e.trim();if(!n)return;let r=``,i=n.match(/^(?:(lt|at)-)?([\w-]+)$/);i&&(r=i[1],n=i[2]);let{breakpoint:o,breakpoints:s}=t,c=o??s??{};if(r!==`at`){if(!Object.hasOwn(c,n))throw Error(`breakpoint ${n} not found`);let e=c[n];return r===`lt`?`(max-width: ${a(e)})`:`(min-width: ${e})`}let l=Object.entries(c).sort((e,t)=>Number.parseFloat(e[1])-Number.parseFloat(t[1])),u=l.findIndex(([e])=>e===n);if(u<0)throw Error(`breakpoint ${n} not found`);return`(min-width: ${l[u][1]})${l[u+1]?` and (max-width: ${a(l[u+1][1])})`:``}`}export{h as a,d as i,y as n,_ as o,f as r,u as s,S as t};
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@teacss/directives",
3
+ "version": "0.3.0",
4
+ "description": "Build-time CSS directive transformer for TeaCSS — @apply, theme(), icon(), and @screen.",
5
+ "homepage": "https://css.teasim.com",
6
+ "funding": "https://github.com/sponsors/billgo",
7
+ "license": "MIT",
8
+ "author": "Billgo <hi@billgo.me>",
9
+ "sideEffects": false,
10
+ "type": "module",
11
+ "exports": {
12
+ ".": "./dist/index.js",
13
+ "./core": "./dist/core.js",
14
+ "./package.json": "./package.json"
15
+ },
16
+ "types": "./dist/index.d.ts",
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "bunx rimraf dist && bunx tsdown --config tsdown.config.mts",
23
+ "dev": "tsdown --watch"
24
+ },
25
+ "dependencies": {
26
+ "@teacss/config": "0.3.0",
27
+ "@teacss/core": "0.3.0",
28
+ "@teacss/rule-helpers": "0.3.0",
29
+ "@teacss/runtime": "0.3.0",
30
+ "@types/css-tree": "^2.3.11",
31
+ "css-tree": "^3.2.1"
32
+ },
33
+ "devDependencies": {
34
+ "@teacss/preset-icons": "0.3.0",
35
+ "@teacss/preset-standard": "0.3.0",
36
+ "magic-string": "^1.1.0"
37
+ },
38
+ "engines": {
39
+ "node": ">=22.12.0"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ }
44
+ }