unocss-merge 0.0.1 → 0.2.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
@@ -16,13 +16,23 @@ $ pnpm add unocss-merge
16
16
 
17
17
  ## API
18
18
 
19
- ```js
20
- const unocssMerge = require('unocss-merge');
19
+ ```ts
20
+ import { unoMerge } from 'unocss-merge'
21
+
22
+ expect(unoMerge('hidden', 'block')).toBe('block')
23
+ expect(unoMerge('hidden', 'block', 'flex')).toBe('flex')
24
+
25
+ expect(unoMerge('mr-1', 'mr-2')).toBe('mr-2')
26
+ expect(unoMerge('mr-1', 'mr-4px')).toBe('mr-4px')
27
+ expect(unoMerge('mr-1', 'mr-[-4px]')).toBe('mr-[-4px]')
28
+ expect(unoMerge('mr-1', 'mr--4px')).toBe('mr--4px')
29
+
30
+ expect(unoMerge('cursor-pointer', 'cursor-not-allowed')).toBe('cursor-not-allowed')
21
31
  ```
22
32
 
23
33
  ## Changelog
24
34
 
25
- [CHANGELOG.md](CHANGELOG.md)
35
+ See https://github.com/magicdawn/unocss-merge/releases
26
36
 
27
37
  ## License
28
38
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,12 @@
1
- declare function getClassList(className?: string): string[];
2
- declare function unoMerge(...classNames: Array<string | undefined>): string;
1
+ //#region src/index.d.ts
2
+ declare function getClassList(className: string | null | undefined): string[];
3
+ /**
4
+ * Match steps
5
+ * 1. `getMergeMapKeyValue`: exact-string + regex match
6
+ * 2. `findInKnownPrefixHasDashValue`: prefix match; may replace alias via `PREFIX_ALIAS`
7
+ * 3. `lastIndexOf('-')` based split; may replace alias via `PREFIX_ALIAS`
8
+ */
9
+ declare function unoMerge(...classNames: Array<string | undefined | null>): string;
3
10
 
4
- export { getClassList, unoMerge };
11
+ //#endregion
12
+ export { getClassList, unoMerge };
package/dist/index.js CHANGED
@@ -1,8 +1 @@
1
- import {
2
- getClassList,
3
- unoMerge
4
- } from "./chunk-XPETEQCQ.js";
5
- export {
6
- getClassList,
7
- unoMerge
8
- };
1
+ import{getClassList as e,unoMerge as t}from"./src-DkzuEjkD.js";export{e as getClassList,t as unoMerge};
package/dist/react.d.ts CHANGED
@@ -1,6 +1,8 @@
1
+ //#region src/react.d.ts
1
2
  /**
2
- * @note `useMemo` `deps array`.length should not change in runtime
3
- */
3
+ * @note `useMemo` `deps array`.length should not change in runtime
4
+ */
4
5
  declare function useUnoMerge(...classNames: Array<string | undefined>): string;
5
6
 
6
- export { useUnoMerge };
7
+ //#endregion
8
+ export { useUnoMerge };
package/dist/react.js CHANGED
@@ -1,12 +1 @@
1
- import {
2
- unoMerge
3
- } from "./chunk-XPETEQCQ.js";
4
-
5
- // src/react.ts
6
- import { useMemo } from "react";
7
- function useUnoMerge(...classNames) {
8
- return useMemo(() => unoMerge(...classNames), [...classNames]);
9
- }
10
- export {
11
- useUnoMerge
12
- };
1
+ import{unoMerge as e}from"./src-DkzuEjkD.js";import{useMemo as t}from"react";function n(...n){return t(()=>e(...n),[...n])}export{n as useUnoMerge};
@@ -0,0 +1,6 @@
1
+ function e(e){return Array.from(new Set(e))}function t(e,t){if(!e)throw Error(t)}const n=[[u(`
2
+ block,inline-block,inline,flex,inline-flex,flow-root,grid,inline-grid,contents,list-item,hidden
3
+ table,inline-table,table-caption,table-cell,table-column,table-row,
4
+ table-column-group,table-footer-group,table-header-group,table-row-group
5
+ `),`display`],[[`isolate`,`isolation-auto`],`isolation`],[[`static`,`fixed`,`absolute`,`relative`,`sticky`],`position`],[[`visible`,`invisible`,`collapse`],`visibility`],[[`flex-row`,`flex-row-reverse`,`flex-col`,`flex-col-reverse`],`flex-direction`],[[`flex-wrap`,`flex-wrap-reverse`,`flex-nowrap`],`flex-wrap`],[d(`object-`,[`contain`,`cover`,`fill`,`none`,`scale-down`]),`object-fit`],[d(`object-`,[`bottom`,`center`,`left`,`left-bottom`,`left-top`,`right`,`right-bottom`,`right-top`,`top`]),`object-position`],[[`antialiased`,`subpixel-antialiased`],`font-smoothing`],[[`italic`,`not-italic`],`font-style`],[d(`font-`,[`thin`,`extralight`,`light`,`normal`,`medium`,`semibold`,`bold`,`extrabold`,`black`]),`font-weight`],[[`normal-nums`,`ordinal`,`slashed-zero`,`lining-nums`,`oldstyle-nums`,`proportional-nums`,`tabular-nums`,`diagonal-fractions`,`stacked-fractions`],`font-variant-numeric`],[[`text-xs`,`text-sm`,`text-base`,`text-lg`,`text-xl`,/^text-(size-)?\d+xl/,/^text-(size-)?\d+/,/^font-size-\d+/],`font-size`],[[`list-inside`,`list-outside`],`list-style-position`],[[`list-none`,`list-disc`,`list-decimal`],`list-style-type`],[d(`text-`,[`left`,`center`,`right`,`justify`,`start`,`end`]),`text-align`],[[`underline`,`overline`,`line-through`,`no-underline`],`text-decoration-line`],[d(`decoration-`,[`solid`,`double`,`dotted`,`dashed`,`wavy`]),`text-decoration-style`],[[`decoration-auto`,`decoration-from-font`,/^decoration-\d+/],`text-decoration-thickness`],[[`truncate`,`text-ellipsis`,`text-clip`],`text-overflow`],[[`text-wrap`,`text-nowrap`,`text-balance`,`text-pretty`],`text-wrap`],[d(`bg-`,[`bottom`,`center`,`left`,`left-bottom`,`left-top`,`right`,`right-bottom`,`right-top`,`top`]),`background-position`],[[`bg-repeat`,`bg-no-repeat`,/^bg-repeat-/],`background-repeat`],[[`bg-auto`,`bg-cover`,`bg-contain`],`background-size`],[[`bg-none`,/^bg-gradient-to-/],`background-image`],[[/^(?:border-|b-)?(?:rounded|rd)()(?:-(.+))?$/],`rounded`],[/^b(?:order)?-(solid|dashed|dotted|double|hidden|none)$/,`border-style`],[/^b(?:order)?($|-\d+)/,`border-width`],[/^b(?:order)?-(t|b|l|r|x|y|s|e)($|-\d+)/,(e,t)=>`border-${t?.[1]}-width`],[/^outline-\d+/,`outline-width`],[[`outline`,/^outline-(solid|dashed|dotted|double|none)$/],`outline-style`],[/^divide-(solid|dashed|dotted|double|none)$/,`divide-style`],[/^divide-(x|y)($|-\d+)/,(e,t)=>`divide-${t?.[1]}-width`],[[`ring`,/^ring-\d+/],`ring-width`],[[/^ring-offset-\d+/],`ring-offset-width`],[[`shadow`,...d(`shadow-`,[`sm`,`md`,`lg`,`xl`,`2xl`,`inner`,`none`])],`box-shadow`],[[`border-collapse`,`border-separate`],`border-collapse`],[[`table-auto`,`table-fixed`],`table-layout`],[[`caption-top`,`caption-bottom`],`caption-side`],[[`scroll-auto`,`scroll-smooth`],`scroll-behavior`],[[`snap-start`,`snap-end`,`snap-center`,`snap-align-none`],`scroll-snap-align`],[[`snap-normal`,`snap-always`],`scroll-snap-stop`],[[`snap-none`,`snap-x`,`snap-y`,`snap-both`,`snap-mandatory`,`snap-proximity`],`scroll-snap-type`],[/^stroke-\d+/,`stroke-width`],[[`sr-only`,`not-sr-only`],`Screen-Readers`],[/^(flex-)?grow($|-\d+$)/,`flex-grow`],[/^(flex-)?shrink($|-\d+$)/,`flex-shrink`],...[`ring-inset`,`divide-x-reverse`,`divide-y-reverse`].map(e=>[e,e]),...[`resize`,`blur`,`drop-shadow`,`grayscale`,`invert`,`sepia`,`backdrop-blur`,`backdrop-grayscale`,`backdrop-invert`,`backdrop-sepia`].map(e=>[e,e])],r=new Map,i=new Map;for(let[e,t]of n){let n=[e].flat(),a=n.filter(e=>typeof e==`string`),o=n.filter(e=>typeof e==`object`&&e instanceof RegExp);a.forEach(e=>{let n=typeof t==`string`?t:t(e);r.set(e,n)}),o.forEach(e=>{i.set(e,t)})}function a(e){if(r.has(e))return r.get(e);for(let[t,n]of i.entries())if(t.test(e)){let r=t.exec(e),i=typeof n==`string`?n:n(e,r);return i}}function o(e){return s.map(e=>typeof e==`string`?[e,e]:e).find(([t,n])=>e.startsWith(t+`-`))}const s=[`break-after`,`break-before`,`break-inside`,`grid-flow`,`align`,`whitespace`,`mix-blend`,`bg-blend`,`ease`,`origin`,`cursor`,`touch`,[`text`,`color`],`color`,[`bg`,`background-color`],[`b`,`border-color`],[`border`,`border-color`],[`decoration`,`text-decoration-color`],[`from`,`gradient-color-stops`],[`divide`,`divide-color`],[`outline`,`outline-color`],[`ring`,`ring-color`],[`ring-offset`,`ring-offset-color`],[`shadow`,`box-shadow-color`],[`accent`,`accent-color`],[`caret`,`caret-color`],`fill`,`stroke`];function c(e){return l.has(e)?l.get(e):e}const l=new Map(Object.entries({leading:`line-height`,col:`grid-column`,"col-span":`grid-column`,"col-start":`grid-column-start`,"col-end":`grid-column-end`,row:`grid-row`,"row-span":`grid-row`,"row-start":`grid-row-start`,"row-end":`grid-row-end`}));function u(e){return e.split(`
6
+ `).map(e=>e.trim()).filter(Boolean).map(e=>e.split(`,`).map(e=>e.trim()).filter(Boolean)).flat()}function d(e,n){return t(e.endsWith(`-`),"prefix must end with `-`"),n.map(t=>e+t)}function f(t){return e((t||``).split(` `).map(e=>e.trim()).filter(Boolean))}function p(...e){let t=e.map(f).flat().filter(Boolean),n=new Map;for(let e of t){{let t=a(e);if(t){n.set(t,e);continue}}let t=o(e);if(t){let[r,i]=t,a=c(i);n.set(a,e);continue}let r=e,i=/(\[[\w_,-]+\])$/;i.test(e)&&(r=e.replace(i,function(e,t){return`*`.repeat(t.length)})),r.includes(`--`)&&(r=r.replace(/--/g,`-*`));let s=r.lastIndexOf(`-`);if(s===-1){n.set(c(e),e);continue}let l=c(e.slice(0,s));n.set(l,e)}return Array.from(n.values()).join(` `)}export{f as getClassList,p as unoMerge};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unocss-merge",
3
- "version": "0.0.1",
3
+ "version": "0.2.0",
4
4
  "description": "simple utility to merge unocss class names",
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,30 +19,29 @@
19
19
  ],
20
20
  "scripts": {
21
21
  "prepare": "husky",
22
- "dev": "tsup --watch",
23
- "build": "tsup",
22
+ "dev": "tsdown --watch",
23
+ "build": "tsdown",
24
24
  "typecheck": "tsc --noEmit",
25
25
  "test": "vitest run",
26
26
  "test:dev": "vitest",
27
27
  "test-cover": "vitest run --coverage",
28
28
  "prepublishOnly": "pnpm typecheck && pnpm test-cover && pnpm build"
29
29
  },
30
- "dependencies": {
31
- "es-toolkit": "^1.36.0"
32
- },
33
30
  "devDependencies": {
34
31
  "@magicdawn/prettier-config": "^0.0.4",
35
32
  "@swc/core": "^1.11.22",
36
- "@types/node": "^22.15.0",
33
+ "@types/node": "^22.15.2",
34
+ "@types/react": "^19.1.2",
37
35
  "@typescript-eslint/eslint-plugin": "^8.31.0",
38
36
  "@typescript-eslint/parser": "^8.31.0",
39
37
  "@vitest/coverage-v8": "^3.1.2",
38
+ "es-toolkit": "^1.36.0",
40
39
  "eslint": "^9.25.1",
41
40
  "eslint-config-prettier": "^10.1.2",
42
41
  "husky": "^9.1.7",
43
42
  "lint-staged": "^15.5.1",
44
43
  "prettier": "^3.5.3",
45
- "tsup": "^8.4.0",
44
+ "tsdown": "^0.9.8",
46
45
  "typescript": "^5.8.3",
47
46
  "vitest": "^3.1.2"
48
47
  },
@@ -1,180 +0,0 @@
1
- // src/index.ts
2
- import { uniq } from "es-toolkit";
3
-
4
- // src/config.ts
5
- var singleValues = {
6
- "display": toValues(`
7
- block,inline-block,inline,flex,inline-flex,
8
- table,inline-table,table-caption,table-cell,table-column,table-row,
9
- table-column-group,table-footer-group,table-header-group,table-row-group,
10
- flow-root,grid,inline-grid,contents,list-item,hidden
11
- `),
12
- "isolation": ["isolate", "isolation-auto"],
13
- "position": ["static", "fixed", "absolute", "relative", "stick"],
14
- "visibility": ["visible", "invisible", "collapse"],
15
- "flex-direction": ["flex-row", "flex-row-reverse", "flex-col", "flex-col-reverse"],
16
- "flex-wrap": ["flex-wrap", "flex-wrap-reverse", "flex-nowrap"],
17
- "object-fit": [
18
- "object-contain",
19
- "object-cover",
20
- "object-fill",
21
- "object-none",
22
- "object-scale-down"
23
- ],
24
- "object-position": [
25
- "object-bottom",
26
- "object-center",
27
- "object-left",
28
- "object-left-bottom",
29
- "object-left-top",
30
- "object-right",
31
- "object-right-bottom",
32
- "object-right-top",
33
- "object-top"
34
- ],
35
- "font-smoothing": ["antialiased", "subpixel-antialiased"],
36
- "font-style": ["italic", "not-italic"],
37
- "font-weight": [
38
- "font-thin",
39
- "font-extralight",
40
- "font-light",
41
- "font-normal",
42
- "font-medium",
43
- "font-semibold",
44
- "font-bold",
45
- "font-extrabold",
46
- "font-black"
47
- ],
48
- "font-variant-numeric": [
49
- "normal-nums",
50
- "ordinal",
51
- "slashed-zero",
52
- "lining-nums",
53
- "oldstyle-nums",
54
- "proportional-nums",
55
- "tabular-nums",
56
- "diagonal-fractions",
57
- "stacked-fractions"
58
- ],
59
- // TODO:
60
- "font-size": [
61
- "text-xs",
62
- "text-sm",
63
- "text-base",
64
- "text-lg",
65
- "text-xl",
66
- "text-2xl",
67
- "text-3xl",
68
- "text-4xl",
69
- "text-5xl",
70
- "text-6xl",
71
- "text-7xl",
72
- "text-8xl",
73
- "text-9xl"
74
- ],
75
- "list-style-position": ["list-inside", "list-outside"],
76
- "list-style-type": ["list-none", "list-disc", "list-decimal"],
77
- "text-align": [
78
- "text-left",
79
- "text-center",
80
- "text-right",
81
- "text-justify",
82
- "text-start",
83
- "text-end"
84
- ]
85
- };
86
- var specialValues = {
87
- "grow": { key: "flex-grow", value: "1" },
88
- "shrink": { key: "flex-shrink", value: "1" },
89
- "flex-grow": { key: "flex-grow", value: "1" },
90
- "flex-shrink": { key: "flex-shrink", value: "1" }
91
- };
92
- var classNameMap = /* @__PURE__ */ new Map();
93
- for (const [prop, values] of Object.entries(singleValues)) {
94
- for (const cls of values) {
95
- classNameMap.set(cls, { key: prop, value: cls });
96
- }
97
- }
98
- for (const [cls, config] of Object.entries(specialValues)) {
99
- classNameMap.set(cls, config);
100
- }
101
- var knownPrefixHasDashValue = [
102
- "break-after",
103
- // break-after-avoid-page
104
- "break-before",
105
- "break-inside",
106
- // grid
107
- "grid-flow"
108
- // grid-flow-row-dense
109
- ];
110
- var ShortcutMap = new Map(
111
- Object.entries({
112
- "grow": "flex-grow",
113
- "shrink": "flex-shrink",
114
- "col": "grid-column",
115
- // `col-auto` => `grid-column: auto;`
116
- "col-span": "grid-column",
117
- "col-start": "grid-column-start",
118
- "col-end": "grid-column-end",
119
- "row": "grid-row",
120
- // `row-auto` => `grid-row: auto;`
121
- "row-span": "grid-row",
122
- "row-start": "grid-row-start",
123
- "row-end": "grid-row-end",
124
- "leading": "line-height"
125
- })
126
- );
127
- function toValues(str) {
128
- return str.split("\n").map((line) => line.trim()).filter(Boolean).map(
129
- (line) => line.split(",").map((x) => x.trim()).filter(Boolean)
130
- ).flat();
131
- }
132
-
133
- // src/index.ts
134
- function getClassList(className) {
135
- return uniq(
136
- (className || "").split(" ").map((x) => x.trim()).filter(Boolean)
137
- );
138
- }
139
- function unoMerge(...classNames) {
140
- const classList = classNames.map(getClassList).flat().filter(Boolean);
141
- const map = /* @__PURE__ */ new Map();
142
- for (const cls of classList) {
143
- if (classNameMap.has(cls)) {
144
- const { key: key2, value } = classNameMap.get(cls);
145
- map.set(key2, value);
146
- continue;
147
- }
148
- const prefix = knownPrefixHasDashValue.find((prefix2) => cls.startsWith(prefix2 + "-"));
149
- if (prefix) {
150
- map.set(prefix, cls);
151
- continue;
152
- }
153
- let clsForSearing = cls;
154
- const reg = /(\[[\w_,-]+\])$/;
155
- if (reg.test(cls)) {
156
- clsForSearing = cls.replace(reg, function(match, p1) {
157
- return "*".repeat(p1.length);
158
- });
159
- }
160
- if (clsForSearing.includes("--")) {
161
- clsForSearing = clsForSearing.replace(/--/g, "-*");
162
- }
163
- const lastHyphenIndex = clsForSearing.lastIndexOf("-");
164
- if (lastHyphenIndex === -1) {
165
- map.set(cls, cls);
166
- continue;
167
- }
168
- let key = cls.slice(0, lastHyphenIndex);
169
- if (ShortcutMap.has(key)) {
170
- key = ShortcutMap.get(key);
171
- }
172
- map.set(key, cls);
173
- }
174
- return Array.from(map.values()).join(" ");
175
- }
176
-
177
- export {
178
- getClassList,
179
- unoMerge
180
- };