@teacss/preset-icons 0.5.1 → 0.6.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/README.md CHANGED
@@ -5,20 +5,21 @@ Pure-CSS icon utilities with no client-side runtime.
5
5
  ## Usage
6
6
 
7
7
  ```css
8
- @preset "standard";
9
- @preset "icons";
8
+ @presets "standard,icons";
10
9
  @teacss;
11
10
  ```
12
11
 
13
12
  ```html
14
13
  <span class="icon:lucide-sun"></span>
14
+ <span class="icon:brands-github"></span>
15
15
  <span class="icon:carbon-sun"></span>
16
16
  <span class="icon:flagpack-nl"></span>
17
17
  <span class="icon:crypto-btc"></span>
18
18
  ```
19
19
 
20
- The grammar is `icon:<collection>-<icon-name>`. The preset bundles Lucide,
21
- Carbon, Flagpack, and Cryptocurrency Color (named `crypto`) and works offline.
20
+ The grammar is `icon:<collection>-<icon-name>`. The preset bundles Boxicons
21
+ Brands (named `brands`), Lucide, Carbon, Flagpack, and Cryptocurrency Color
22
+ (named `crypto`) and works offline.
22
23
  Datasets load only when a matching icon is used.
23
24
 
24
25
  Names are case-insensitive and accept each collection's canonical kebab-case or
@@ -51,17 +52,20 @@ Programmatic integrations can call `preset.api.resolveIcon(name)`.
51
52
 
52
53
  ## Runtime merging
53
54
 
54
- The `/merge` entry exports an icon-only `cn` and `pluginIcon`:
55
+ Import the fixed Standard + Icons merger from `@teacss/classes`:
55
56
 
56
57
  ```ts
57
- import { createMerger } from "@teacss/classes";
58
- import { cn as iconCn, pluginIcon } from "@teacss/preset-icons/merge";
58
+ import { cn } from "@teacss/classes";
59
59
 
60
- const cn = createMerger({ plugins: [pluginIcon] });
60
+ cn("icon:lucide-check", "icon:lucide-x"); // "icon:lucide-x"
61
+ cn("icon:bad icon:other icon:bad"); // "icon:bad"
61
62
  ```
62
63
 
63
- The application `cn` from `teacss` already combines icon and Standard merge
64
- metadata. Merging validates only the canonical token shape, not whether the icon
65
- exists.
64
+ All `icon:value` declarations share one conflict identity, without validating
65
+ the value or checking whether the icon exists. With identical ordered conditions
66
+ and importance, the last declaration wins. An important icon wins over ordinary
67
+ icons under the same conditions. Bare `icon` has a separate keyword identity.
68
+ CSS generation still requires a supported icon name; an invalid merge winner
69
+ emits no icon CSS.
66
70
 
67
71
  Pre-1.0. Output follows the bundled Iconify datasets.
package/dist/browser.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { a as ParsedIcon, i as IconsOptions, n as icons, o as BUNDLED_COLLECTIONS, r as presetIcons, t as IconsAPI } from "./core-DY_Ipkg0.js";
1
+ import { a as ParsedIcon, i as IconsOptions, n as icons, o as BUNDLED_COLLECTIONS, r as presetIcons, t as IconsAPI } from "./core-CWgrTiKr.js";
2
2
  import "./index.js";
3
3
  export { BUNDLED_COLLECTIONS, IconsAPI, type IconsOptions, type ParsedIcon, presetIcons as default, presetIcons, icons };
package/dist/browser.js CHANGED
@@ -1 +1 @@
1
- import{n as e,r as t,t as n}from"./core-BTaY9Bti.js";import r from"./index.js";export{t as BUNDLED_COLLECTIONS,r as default,n as icons,e as presetIcons};
1
+ import{n as e,r as t,t as n}from"./core-Bam0Bjvx.js";import r from"./index.js";export{t as BUNDLED_COLLECTIONS,r as default,n as icons,e as presetIcons};
@@ -0,0 +1 @@
1
+ import{loadIcon as e}from"@iconify/utils";import{encodeSvgForCss as t}from"@iconify/utils/lib/svg/encode-svg-for-css";import{definePreset as n,getEnvFlags as r,warnOnce as i}from"@teacss/core";import{searchForIcon as a}from"@iconify/utils/lib/loader/modern";const o=new Map([[`brands`,()=>import(`@iconify-json/bxl`).then(e=>e.icons)],[`carbon`,()=>import(`@iconify-json/carbon`).then(e=>e.icons)],[`crypto`,()=>import(`@iconify-json/cryptocurrency-color`).then(e=>e.icons)],[`flagpack`,()=>import(`@iconify-json/flagpack`).then(e=>e.icons)],[`lucide`,()=>import(`@iconify-json/lucide`).then(e=>e.icons)]]),s=[...o.keys()];function c(e){return e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase())}const l=new WeakMap;function u(e){let t=0;for(let n of e)n===`-`&&t++;return t}function d(e,t,n){let r=u(e)-u(t);if(r!==0)return r<0;let i=Number(n(t))-Number(n(e));return i===0?e<t:i<0}function f(e){let t=l.get(e);if(t)return t;let n=new Map,r=t=>Object.hasOwn(e.icons,t);for(let t of[...Object.keys(e.icons),...Object.keys(e.aliases??{})]){let e=c(t).toLowerCase(),i=n.get(e);(i===void 0||d(t,i,r))&&n.set(e,t)}return l.set(e,n),n}async function p(e,t,n){let r=o.get(e);if(!r)return;let i=await r(),s=t.toLowerCase(),c=f(i).get(s),l=[...new Set([t,s,...c==null?[]:[c]])];return await a(i,e,l,n)}const m=String.raw`[\w]+(?:-[\w]+)+`,h=RegExp(`^icon:(${m})(?:\\?(mask|bg|auto))?$`),g=s;async function _(t,n,r){return await p(t,n,r)??await e(t,n,r)}function v(e,t){return`${e}\0${t}`}function y(e,t,n){let r=(t,r)=>{n.set(v(e,t),r instanceof Error?r.message:String(r))};return typeof t==`function`?(async e=>{try{return await t(e)}catch(t){r(e,t);return}}):t&&Object.fromEntries(Object.entries(t).map(([e,t])=>[e,typeof t==`function`?async()=>{try{return await t()}catch(t){r(e,t);return}}:t]))}const b=n((e={})=>{let{scale:n=1,mode:a=`auto`,warn:o=!1,collections:s,extraProperties:c={},customizations:l={},layer:u=`icons`,unit:d,processor:f}=e,p=r(),m=new Map,b={addXmlNs:!0,scale:n,customCollections:s?Object.fromEntries(Object.entries(s).map(([e,t])=>[e,y(e,t,m)])):void 0,warn:void 0,customizations:{...l,additionalProps:{...c},trimCustomSvg:!0,async iconCustomizer(e,t,r){await l.iconCustomizer?.(e,t,r),d&&(r.width||=`${n}${d}`,r.height||=`${n}${d}`)}}},S=new Set([...g,...Object.keys(s||{})]),C=async(e,t)=>{let n=x(e,S);if(!n)return;let r=await _(n.collection,n.name,t?{...b,usedProps:t}:b);if(r)return{...n,svg:r};let i=v(n.collection,n.name),a=m.get(i);if(a!==void 0)throw m.delete(i),Error(a)};return{name:`@teacss/preset-icons`,enforce:`pre`,options:e,layers:{[u]:-30},api:{encodeSvgForCss:t,resolveIcon:e=>C(e)},rules:[[h,async e=>{let[n,r,s=a]=e,c={},l;try{l=await C(r,c)}catch(e){o&&!p.isESLint&&i(`failed to load icon "${n}": ${e instanceof Error?e.message:String(e)}`);return}if(!l){o&&!p.isESLint&&i(`failed to load icon "${n}"`);return}let u,d=`url("data:image/svg+xml;utf8,${t(l.svg)}")`;return s===`auto`&&(s=/currentcolor/i.test(l.svg)?`mask`:`bg`),u=s===`mask`?{"--tea-icon":d,display:`inline-block`,"-webkit-mask":`var(--tea-icon) no-repeat`,mask:`var(--tea-icon) no-repeat`,"-webkit-mask-size":`100% 100%`,"mask-size":`100% 100%`,"background-color":`currentColor`,"background-image":`none`,color:`inherit`,...c}:{display:`inline-block`,"-webkit-mask":`none`,mask:`none`,background:`${d} no-repeat`,"background-size":`100% 100%`,"background-color":`transparent`,...c},await f?.(u,{...l,icon:l.name,mode:s}),u},{layer:u}]]}});function x(e,t){let n=e.split(`-`);if(!(n.length<2||n.some(e=>e.length===0)))for(let e=n.length-1;e>=1;e--){let r=n.slice(0,e).join(`-`);if(t.has(r))return{collection:r,name:n.slice(e).join(`-`)}}}export{b as n,s as r,g as t};
@@ -52,11 +52,10 @@ interface IconsOptions {
52
52
  /**
53
53
  * Extra collections resolved from data the caller supplies.
54
54
  *
55
- * The preset bundles the `lucide` dataset and loads nothing else on its own —
56
- * no filesystem lookup, no registry install, no CDN — so this is the way to
57
- * add another collection. Supply the data inline or through a loader that
58
- * reads it locally, for example `FileSystemIconLoader` from
59
- * `@iconify/utils/lib/loader/fs`.
55
+ * The preset bundles `brands`, `carbon`, `crypto`, `flagpack`, and `lucide`.
56
+ * There is no filesystem lookup, registry install, or CDN fetch. Supply
57
+ * other data inline or through a local loader such as `FileSystemIconLoader`
58
+ * from `@iconify/utils/lib/loader/fs`.
60
59
  */
61
60
  collections?: Record<string, (() => Awaitable<IconifyJSON>) | undefined | CustomIconLoader | InlineCollection>;
62
61
  /**
package/dist/core.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ParsedIcon, i as IconsOptions, n as icons, o as BUNDLED_COLLECTIONS, r as presetIcons, t as IconsAPI } from "./core-DY_Ipkg0.js";
1
+ import { a as ParsedIcon, i as IconsOptions, n as icons, o as BUNDLED_COLLECTIONS, r as presetIcons, t as IconsAPI } from "./core-CWgrTiKr.js";
2
2
  export { BUNDLED_COLLECTIONS, IconsAPI, type IconsOptions, type ParsedIcon, icons, presetIcons };
package/dist/core.js CHANGED
@@ -1 +1 @@
1
- import{n as e,r as t,t as n}from"./core-BTaY9Bti.js";export{t as BUNDLED_COLLECTIONS,n as icons,e as presetIcons};
1
+ import{n as e,r as t,t as n}from"./core-Bam0Bjvx.js";export{t as BUNDLED_COLLECTIONS,n as icons,e as presetIcons};
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ParsedIcon, i as IconsOptions, n as icons, o as BUNDLED_COLLECTIONS, r as presetIcons, t as IconsAPI } from "./core-DY_Ipkg0.js";
1
+ import { a as ParsedIcon, i as IconsOptions, n as icons, o as BUNDLED_COLLECTIONS, r as presetIcons, t as IconsAPI } from "./core-CWgrTiKr.js";
2
2
  export { BUNDLED_COLLECTIONS, IconsAPI, type IconsOptions, type ParsedIcon, presetIcons as default, presetIcons, icons };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{n as e,r as t,t as n}from"./core-BTaY9Bti.js";var r=e;export{t as BUNDLED_COLLECTIONS,r as default,n as icons,e as presetIcons};
1
+ import{n as e,r as t,t as n}from"./core-Bam0Bjvx.js";var r=e;export{t as BUNDLED_COLLECTIONS,r as default,n as icons,e as presetIcons};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teacss/preset-icons",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Pure-CSS Iconify icon utilities for TeaCSS — one class per icon, no runtime.",
5
5
  "homepage": "https://css.teasim.com",
6
6
  "funding": "https://github.com/sponsors/billgo",
@@ -15,7 +15,6 @@
15
15
  },
16
16
  "./browser": "./dist/browser.js",
17
17
  "./core": "./dist/core.js",
18
- "./merge": "./dist/merge.js",
19
18
  "./package.json": "./package.json"
20
19
  },
21
20
  "types": "./dist/index.d.ts",
@@ -28,14 +27,17 @@
28
27
  "dev": "tsdown --config-loader unrun --watch"
29
28
  },
30
29
  "dependencies": {
30
+ "@iconify-json/bxl": "^1.2.4",
31
31
  "@iconify-json/carbon": "^1.2.26",
32
32
  "@iconify-json/cryptocurrency-color": "^1.2.4",
33
33
  "@iconify-json/flagpack": "^1.2.8",
34
34
  "@iconify-json/lucide": "^1.2.129",
35
35
  "@iconify/types": "^2.0.0",
36
36
  "@iconify/utils": "^3.1.5",
37
- "@teacss/classes": "0.5.1",
38
- "@teacss/core": "0.5.1"
37
+ "@teacss/core": "0.6.0"
38
+ },
39
+ "devDependencies": {
40
+ "@teacss/classes": "0.6.0"
39
41
  },
40
42
  "engines": {
41
43
  "node": ">=22.12.0"
@@ -1 +0,0 @@
1
- import{t as e}from"./syntax-DmIPw0tH.js";import{loadIcon as t}from"@iconify/utils";import{encodeSvgForCss as n}from"@iconify/utils/lib/svg/encode-svg-for-css";import{definePreset as r,getEnvFlags as i,warnOnce as a}from"@teacss/core";import{searchForIcon as o}from"@iconify/utils/lib/loader/modern";const s=new Map([[`carbon`,()=>import(`@iconify-json/carbon`).then(e=>e.icons)],[`crypto`,()=>import(`@iconify-json/cryptocurrency-color`).then(e=>e.icons)],[`flagpack`,()=>import(`@iconify-json/flagpack`).then(e=>e.icons)],[`lucide`,()=>import(`@iconify-json/lucide`).then(e=>e.icons)]]),c=[...s.keys()];function l(e){return e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase())}const u=new WeakMap;function d(e){let t=0;for(let n of e)n===`-`&&t++;return t}function f(e,t,n){let r=d(e)-d(t);if(r!==0)return r<0;let i=Number(n(t))-Number(n(e));return i===0?e<t:i<0}function p(e){let t=u.get(e);if(t)return t;let n=new Map,r=t=>Object.hasOwn(e.icons,t);for(let t of[...Object.keys(e.icons),...Object.keys(e.aliases??{})]){let e=l(t).toLowerCase(),i=n.get(e);(i===void 0||f(t,i,r))&&n.set(e,t)}return u.set(e,n),n}async function m(e,t,n){let r=s.get(e);if(!r)return;let i=await r(),a=t.toLowerCase(),c=p(i).get(a),l=[...new Set([t,a,...c==null?[]:[c]])];return await o(i,e,l,n)}const h=c;async function g(e,n,r){return await m(e,n,r)??await t(e,n,r)}function _(e,t){return`${e}\0${t}`}function v(e,t,n){let r=(t,r)=>{n.set(_(e,t),r instanceof Error?r.message:String(r))};return typeof t==`function`?(async e=>{try{return await t(e)}catch(t){r(e,t);return}}):t&&Object.fromEntries(Object.entries(t).map(([e,t])=>[e,typeof t==`function`?async()=>{try{return await t()}catch(t){r(e,t);return}}:t]))}const y=r((t={})=>{let{scale:r=1,mode:o=`auto`,warn:s=!1,collections:c,extraProperties:l={},customizations:u={},layer:d=`icons`,unit:f,processor:p}=t,m=i(),y=new Map,x={addXmlNs:!0,scale:r,customCollections:c?Object.fromEntries(Object.entries(c).map(([e,t])=>[e,v(e,t,y)])):void 0,warn:void 0,customizations:{...u,additionalProps:{...l},trimCustomSvg:!0,async iconCustomizer(e,t,n){await u.iconCustomizer?.(e,t,n),f&&(n.width||=`${r}${f}`,n.height||=`${r}${f}`)}}},S=new Set([...h,...Object.keys(c||{})]),C=async(e,t)=>{let n=b(e,S);if(!n)return;let r=await g(n.collection,n.name,t?{...x,usedProps:t}:x);if(r)return{...n,svg:r};let i=_(n.collection,n.name),a=y.get(i);if(a!==void 0)throw y.delete(i),Error(a)};return{name:`@teacss/preset-icons`,enforce:`pre`,options:t,layers:{[d]:-30},api:{encodeSvgForCss:n,resolveIcon:e=>C(e)},rules:[[e,async e=>{let[t,r,i=o]=e,c={},l;try{l=await C(r,c)}catch(e){s&&!m.isESLint&&a(`failed to load icon "${t}": ${e instanceof Error?e.message:String(e)}`);return}if(!l){s&&!m.isESLint&&a(`failed to load icon "${t}"`);return}let u,d=`url("data:image/svg+xml;utf8,${n(l.svg)}")`;return i===`auto`&&(i=/currentcolor/i.test(l.svg)?`mask`:`bg`),u=i===`mask`?{"--tea-icon":d,display:`inline-block`,"-webkit-mask":`var(--tea-icon) no-repeat`,mask:`var(--tea-icon) no-repeat`,"-webkit-mask-size":`100% 100%`,"mask-size":`100% 100%`,"background-color":`currentColor`,"background-image":`none`,color:`inherit`,...c}:{display:`inline-block`,"-webkit-mask":`none`,mask:`none`,background:`${d} no-repeat`,"background-size":`100% 100%`,"background-color":`transparent`,...c},await p?.(u,{...l,icon:l.name,mode:i}),u},{layer:d}]]}});function b(e,t){let n=e.split(`-`);if(!(n.length<2||n.some(e=>e.length===0)))for(let e=n.length-1;e>=1;e--){let r=n.slice(0,e).join(`-`);if(t.has(r))return{collection:r,name:n.slice(e).join(`-`)}}}export{y as n,c as r,h as t};
package/dist/merge.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import { Merger, MergerPlugin } from "@teacss/classes";
2
- //#region src/merge.d.ts
3
- /** Merger metadata for the canonical `icon:<collection>-<name>` vocabulary. */
4
- export declare const pluginIcon: MergerPlugin;
5
- /** Lazily initialized merger bound only to the canonical icon vocabulary. */
6
- export declare const cn: Merger;
7
- //#endregion
package/dist/merge.js DELETED
@@ -1 +0,0 @@
1
- import{n as e}from"./syntax-DmIPw0tH.js";import{MERGE_OPAQUE as t,createMerger as n}from"@teacss/classes";const r={name:`@teacss/preset-icons/merge`,conflicts:{keywords:{},overlaps:{icon:`@teacss/preset-icons:icon`}},group(n){return n.prefix===`icon`?!n.keyword&&e(n.value)?null:t:null}};let i;const a=((...e)=>(i??=n({plugins:[r]}))(...e));export{a as cn,r as pluginIcon};
@@ -1 +0,0 @@
1
- const e=String.raw`[\w]+(?:-[\w]+)+`,t=RegExp(`^icon:(${e})(?:\\?(mask|bg|auto))?$`),n=RegExp(`^${e}(?:\\?(?:mask|bg|auto))?$`);function r(e){return e!=null&&n.test(e)}export{r as n,t};