@slimr/css 1.0.40 → 2.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slimr/css",
3
- "version": "1.0.40",
3
+ "version": "2.0.2",
4
4
  "author": "Brian Dombrowski",
5
5
  "license": "ISC",
6
6
  "private": false,
package/src/core.cjs ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";var g=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var c=(r,n)=>{for(var t in n)g(r,t,{get:n[t],enumerable:!0})},y=(r,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of f(n))!b.call(r,e)&&e!==t&&g(r,e,{get:()=>n[e],enumerable:!(o=l(n,e))||o.enumerable});return r};var h=r=>y(g({},"__esModule",{value:!0}),r);var k={};c(k,{addCss:()=>m,breakPoints:()=>a,classJoin:()=>x,createClass:()=>u,shorthandProps:()=>w,shorthandPropsMap:()=>p,t2s:()=>d});module.exports=h(k);var a=["30em","48em","62em","80em","96em"];function x(...r){return r.filter(n=>n&&typeof n=="string").join(" ")}function $(r){return r.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm,"")}function j(r){return r.includes("[")?r.split(`
2
+ `).map(n=>{var e;let[,t,o]=(e=[...n.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)][0])!=null?e:[];return o?o.split(",").map((i,s)=>(i=i.trim(),!i||i==="null"||i==="undefined"?"":s===0?`${t}: ${i};`:`@media (min-width: ${a[s-1]}) { ${t}: ${i}; }`)).join(`
3
+ `):n}).join(`
4
+ `):r}var p={ai:"align-items",b:"border",br:"border-radius",bg:"background",c:"color",d:"display",f:"flex",fd:"flex-direction",i:"inset",h:"height",jc:"justify-content",m:"margin",ml:"margin-left",mr:"margin-right",mt:"margin-top",mb:"margin-bottom",maxW:"max-width",minW:"min-width",p:"padding",pl:"padding-left",pr:"padding-right",pt:"padding-top",pb:"padding-bottom",pos:"position",ta:"text-align",w:"width",z:"z-index"},w=[...Object.keys(p),"mx","my","px","py"];function P(r){return r=`
5
+ `+r,r=r.replace(/([mp])x:([^;]*)/g,`$1l:$2;
6
+ $1r:$2`).replace(/([mp])y:([^;]*);/g,`$1t:$2;
7
+ $1b:$2`),Object.entries(p).forEach(([n,t])=>{r=r.replace(new RegExp(`([
8
+ ;])${n}:`,"g"),`$1${t}:`)}),r.trim()}function S(r){let n=[];for(let t of r.matchAll(/[@&]/gm)){let o="",e=0,i=0;for(let s=t.index;s<r.length;s++)if(r[s]==="{")i===0&&(o=r.slice(t.index,s).trim(),e=s+1),i++;else if(r[s]==="}"&&(i--,i===0)){n.push({start:t.index,end:s+1,query:o,outerBody:r.slice(t.index,s+1),innerBody:r.slice(e,s)});break}i!==0&&console.error(`${o} not closed: "${r}"`)}return n}function A(r){return r.split(`
9
+ `).map(n=>n.trim()).filter(n=>n).join(`
10
+ `)}function d(...r){let[n,...t]=r;return typeof n=="string"?n:n.map((o,e)=>{var i;return o+((i=t==null?void 0:t[e])!=null?i:"")}).join("")}function m(r){m.que.add(r),setTimeout(()=>{let n=[...m.que].join(`
11
+ `);if(n){m.que.clear();let t=document.createElement("style");t.id=`u${m.count++}`,t.innerHTML=n,document.head.appendChild(t)}},0)}m.que=new Set;m.count=0;function u(...r){let n=d(...r);if(!n)return"";let t=u.history.get(n);if(!t){t="s"+u.count++,u.history.set(n,t),n=$(n),n=P(n),n=j(n);let o=S(n);for(let e of o.reverse())n=n.slice(0,e.start)+n.slice(e.end);n=`.${t}{
12
+ ${n}
13
+ }
14
+ `,n+=o.map(e=>e.query.startsWith("&")?`.${t}${e.query.slice(1)}{
15
+ ${e.innerBody}
16
+ }`:e.query.startsWith("@keyframes")?e.outerBody:`${e.query}{
17
+ .${t}{${e.innerBody}
18
+ }
19
+ }`).join(`
20
+ `),n=A(n)+`
21
+
22
+ `,m(n)}return t}u.count=0;u.history=new Map;0&&(module.exports={addCss,breakPoints,classJoin,createClass,shorthandProps,shorthandPropsMap,t2s});
23
+ //# sourceMappingURL=core.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["core.ts"],"sourcesContent":["/** Breakpoints like chakra */\nexport const breakPoints = ['30em', '48em', '62em', '80em', '96em']\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype allowableAny = any\n\n/** Joins class names and filters out blanks */\nexport function classJoin(...classes: allowableAny[]) {\n return classes.filter(c => c && typeof c === 'string').join(' ')\n}\n\n/** delete css comments **/\nfunction deleteComments(css: string) {\n return css.replace(/{\\/\\*[\\s\\S]*?(?=\\*\\/})\\*\\/}/gm, '')\n}\n\n/**\n * Expands array values into media queries\n *\n * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles\n */\nfunction expandArrayValues(css: string) {\n if (!css.includes('[')) return css\n return css\n .split('\\n')\n .map(l => {\n // eslint-disable-next-line no-useless-escape\n const [, prop, vals] = [...l.matchAll(/([A-Za-z\\-]*):[ ]*\\[([^\\]]+)\\]/g)]?.[0] ?? []\n if (vals) {\n return vals\n .split(',')\n .map((val, i) => {\n val = val.trim()\n if (!val || val === 'null' || val === 'undefined') return ''\n if (i === 0) {\n return `${prop}: ${val};`\n }\n return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`\n })\n .join('\\n')\n }\n return l\n })\n .join('\\n')\n}\n\nexport interface ShorthandProps {\n /** shorthand for css:align-items */\n ai?: string\n /** shorthand for css:border */\n b?: string | number\n /** shorthand for css:border-radius */\n br?: string | number\n /** shorthand for css:background */\n bg?: string\n /** shorthand for css:color */\n c?: string\n /** shorthand for css:display */\n d?: string\n /** shorthand for css:flex */\n f?: string\n /** shorthand for css:flex-direction */\n fd?: string\n /** shorthand for css:height */\n h?: number | string\n /** shorthand for css:inset */\n i?: number | string\n /** shorthand for css:justify-content */\n jc?: string\n /** shorthand for css:margin */\n m?: number | string\n /** shorthand for css:margin-left */\n ml?: number | string\n /** shorthand for css:margin-right */\n mr?: number | string\n /** shorthand for css:margin-top */\n mt?: number | string\n /** shorthand for css:margin-bottom */\n mb?: number | string\n /** shorthand for css:margin-top & margin-bottom */\n my?: number | string\n /** shorthand for css:margin-left & margin-right */\n mx?: number | string\n /** shorthand for css:max-width */\n maxW?: number | string\n /** shorthand for css:min-width */\n minW?: number | string\n /** shorthand for css:padding */\n p?: number | string\n /** shorthand for css:padding-left */\n pl?: number | string\n /** shorthand for css:padding-right */\n pr?: number | string\n /** shorthand for css:padding-top */\n pt?: number | string\n /** shorthand for css:padding-bottom */\n pb?: number | string\n /** shorthand for css:padding-top & padding-bottom */\n py?: number | string\n /** shorthand for css:padding-left & padding-right */\n px?: number | string\n /** shorthand for css:position */\n pos?: number | string\n /** shorthand for css:text-align */\n ta?: string\n /** shorthand for css:width */\n w?: number | string\n /** shorthand for css:z-index */\n z?: number | string\n}\nexport const shorthandPropsMap: Record<\n keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>,\n string\n> = {\n ai: 'align-items',\n b: 'border',\n br: 'border-radius',\n bg: 'background',\n c: 'color',\n d: 'display',\n f: 'flex',\n fd: 'flex-direction',\n i: 'inset',\n h: 'height',\n jc: 'justify-content',\n m: 'margin',\n ml: 'margin-left',\n mr: 'margin-right',\n mt: 'margin-top',\n mb: 'margin-bottom',\n maxW: 'max-width',\n minW: 'min-width',\n p: 'padding',\n pl: 'padding-left',\n pr: 'padding-right',\n pt: 'padding-top',\n pb: 'padding-bottom',\n pos: 'position',\n ta: 'text-align',\n w: 'width',\n z: 'z-index',\n}\nexport const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']\n\n/** Expand short-hand css props to full */\nfunction expandProps(css: string) {\n css = '\\n' + css // inject a newline to make the regex easier\n // Handle 'mx', 'my', 'px', 'py'\n css = css\n .replace(/([mp])x:([^;]*)/g, '$1l:$2;\\n$1r:$2')\n .replace(/([mp])y:([^;]*);/g, '$1t:$2;\\n$1b:$2')\n Object.entries(shorthandPropsMap).forEach(([k, v]) => {\n css = css.replace(new RegExp(`([ \\n\\t;])${k}:`, 'g'), `$1${v}:`)\n })\n return css.trim()\n}\n\n/** Find @keyframes, @media, @container queries in css **/\nfunction findQueries(css: string) {\n const queries = []\n for (const m of css.matchAll(/[@&]/gm)) {\n let query = ''\n let bodyStart = 0\n let openCount = 0\n for (let i = m.index!; i < css.length; i++) {\n if (css[i] === '{') {\n if (openCount === 0) {\n query = css.slice(m.index, i).trim()\n bodyStart = i + 1\n }\n openCount++\n } else if (css[i] === '}') {\n openCount--\n if (openCount === 0) {\n queries.push({\n start: m.index,\n end: i + 1,\n query,\n outerBody: css.slice(m.index, i + 1),\n innerBody: css.slice(bodyStart, i),\n })\n break\n }\n }\n }\n if (openCount !== 0) console.error(`${query} not closed: \"${css}\"`)\n }\n return queries\n}\n\n/** Trims whitespace for every line */\nfunction trim(css: string) {\n return css\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l)\n .join('\\n')\n}\n\n/**\n * Assemble a string from a template string array and a list of placeholders.\n *\n * - If the first argument is a string, it is returned as is.\n *\n * i.e.\n * myFoo(...props: TemplateStringProps) => {\n * const inputStr = t2s(...props);\n * }\n * myFoo`hello ${name}` => 'hello world'\n * myFoo(`hello ${name}`) => 'hello world'\n */\nexport function t2s(...tsp: TemplateStringProps) {\n const [s, ...p] = tsp\n return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')\n}\nexport type TemplateStringProps = [\n strings: TemplateStringsArray | string,\n ...placeHolders: string[]\n]\n\n/**\n * Injects css to the page\n *\n * - Batches adds for performance\n *\n * @param css - css to be injected\n * @returns void\n */\nexport function addCss(css: string) {\n addCss.que.add(css)\n setTimeout(() => {\n const css = [...addCss.que].join('\\n')\n if (css) {\n addCss.que.clear()\n const s = document.createElement('style')\n s.id = `u${addCss.count++}`\n s.innerHTML = css\n document.head.appendChild(s)\n }\n }, 0)\n}\naddCss.que = new Set<string>()\naddCss.count = 0\n\n/**\n * Injects css and creates unique class names\n *\n * - Skips if already added\n *\n * @param css - string or template string, to be injected\n * @returns a unique class name\n */\nexport function createClass(...p: TemplateStringProps) {\n let css = t2s(...p)\n if (!css) return ''\n let className = createClass.history.get(css)\n if (!className) {\n className = 's' + createClass.count++\n createClass.history.set(css, className)\n\n css = deleteComments(css)\n css = expandProps(css)\n css = expandArrayValues(css)\n const qs = findQueries(css)\n\n for (const q of qs.reverse()) {\n css = css.slice(0, q.start) + css.slice(q.end)\n }\n\n css = `.${className}{\\n${css}\\n}\\n`\n css += qs\n .map(q => {\n if (q.query.startsWith('&')) {\n return `.${className}${q.query.slice(1)}{\\n${q.innerBody}\\n}`\n }\n if (q.query.startsWith('@keyframes')) {\n return q.outerBody\n }\n return `${q.query}{\\n.${className}{${q.innerBody}\\n}\\n}`\n })\n .join('\\n')\n\n css = trim(css) + '\\n\\n'\n\n addCss(css)\n }\n return className\n}\ncreateClass.count = 0\ncreateClass.history = new Map<string, string>()\n"],"mappings":"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","names":["core_exports","__export","addCss","breakPoints","classJoin","createClass","shorthandProps","shorthandPropsMap","t2s","__toCommonJS","classes","c","deleteComments","css","expandArrayValues","l","_a","prop","vals","val","i","expandProps","k","v","findQueries","queries","m","query","bodyStart","openCount","trim","tsp","s","p","className","qs","q"]}
package/src/core.d.ts ADDED
@@ -0,0 +1,116 @@
1
+ /** Breakpoints like chakra */
2
+ declare const breakPoints: string[];
3
+ type allowableAny = any;
4
+ /** Joins class names and filters out blanks */
5
+ declare function classJoin(...classes: allowableAny[]): string;
6
+ interface ShorthandProps {
7
+ /** shorthand for css:align-items */
8
+ ai?: string;
9
+ /** shorthand for css:border */
10
+ b?: string | number;
11
+ /** shorthand for css:border-radius */
12
+ br?: string | number;
13
+ /** shorthand for css:background */
14
+ bg?: string;
15
+ /** shorthand for css:color */
16
+ c?: string;
17
+ /** shorthand for css:display */
18
+ d?: string;
19
+ /** shorthand for css:flex */
20
+ f?: string;
21
+ /** shorthand for css:flex-direction */
22
+ fd?: string;
23
+ /** shorthand for css:height */
24
+ h?: number | string;
25
+ /** shorthand for css:inset */
26
+ i?: number | string;
27
+ /** shorthand for css:justify-content */
28
+ jc?: string;
29
+ /** shorthand for css:margin */
30
+ m?: number | string;
31
+ /** shorthand for css:margin-left */
32
+ ml?: number | string;
33
+ /** shorthand for css:margin-right */
34
+ mr?: number | string;
35
+ /** shorthand for css:margin-top */
36
+ mt?: number | string;
37
+ /** shorthand for css:margin-bottom */
38
+ mb?: number | string;
39
+ /** shorthand for css:margin-top & margin-bottom */
40
+ my?: number | string;
41
+ /** shorthand for css:margin-left & margin-right */
42
+ mx?: number | string;
43
+ /** shorthand for css:max-width */
44
+ maxW?: number | string;
45
+ /** shorthand for css:min-width */
46
+ minW?: number | string;
47
+ /** shorthand for css:padding */
48
+ p?: number | string;
49
+ /** shorthand for css:padding-left */
50
+ pl?: number | string;
51
+ /** shorthand for css:padding-right */
52
+ pr?: number | string;
53
+ /** shorthand for css:padding-top */
54
+ pt?: number | string;
55
+ /** shorthand for css:padding-bottom */
56
+ pb?: number | string;
57
+ /** shorthand for css:padding-top & padding-bottom */
58
+ py?: number | string;
59
+ /** shorthand for css:padding-left & padding-right */
60
+ px?: number | string;
61
+ /** shorthand for css:position */
62
+ pos?: number | string;
63
+ /** shorthand for css:text-align */
64
+ ta?: string;
65
+ /** shorthand for css:width */
66
+ w?: number | string;
67
+ /** shorthand for css:z-index */
68
+ z?: number | string;
69
+ }
70
+ declare const shorthandPropsMap: Record<keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>, string>;
71
+ declare const shorthandProps: string[];
72
+ /**
73
+ * Assemble a string from a template string array and a list of placeholders.
74
+ *
75
+ * - If the first argument is a string, it is returned as is.
76
+ *
77
+ * i.e.
78
+ * myFoo(...props: TemplateStringProps) => {
79
+ * const inputStr = t2s(...props);
80
+ * }
81
+ * myFoo`hello ${name}` => 'hello world'
82
+ * myFoo(`hello ${name}`) => 'hello world'
83
+ */
84
+ declare function t2s(...tsp: TemplateStringProps): string;
85
+ type TemplateStringProps = [
86
+ strings: TemplateStringsArray | string,
87
+ ...placeHolders: string[]
88
+ ];
89
+ /**
90
+ * Injects css to the page
91
+ *
92
+ * - Batches adds for performance
93
+ *
94
+ * @param css - css to be injected
95
+ * @returns void
96
+ */
97
+ declare function addCss(css: string): void;
98
+ declare namespace addCss {
99
+ var que: Set<string>;
100
+ var count: number;
101
+ }
102
+ /**
103
+ * Injects css and creates unique class names
104
+ *
105
+ * - Skips if already added
106
+ *
107
+ * @param css - string or template string, to be injected
108
+ * @returns a unique class name
109
+ */
110
+ declare function createClass(...p: TemplateStringProps): string;
111
+ declare namespace createClass {
112
+ var count: number;
113
+ var history: Map<string, string>;
114
+ }
115
+
116
+ export { ShorthandProps, TemplateStringProps, addCss, breakPoints, classJoin, createClass, shorthandProps, shorthandPropsMap, t2s };
package/src/core.js ADDED
@@ -0,0 +1,23 @@
1
+ var p=["30em","48em","62em","80em","96em"];function y(...r){return r.filter(n=>n&&typeof n=="string").join(" ")}function a(r){return r.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm,"")}function d(r){return r.includes("[")?r.split(`
2
+ `).map(n=>{var e;let[,t,s]=(e=[...n.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)][0])!=null?e:[];return s?s.split(",").map((i,o)=>(i=i.trim(),!i||i==="null"||i==="undefined"?"":o===0?`${t}: ${i};`:`@media (min-width: ${p[o-1]}) { ${t}: ${i}; }`)).join(`
3
+ `):n}).join(`
4
+ `):r}var g={ai:"align-items",b:"border",br:"border-radius",bg:"background",c:"color",d:"display",f:"flex",fd:"flex-direction",i:"inset",h:"height",jc:"justify-content",m:"margin",ml:"margin-left",mr:"margin-right",mt:"margin-top",mb:"margin-bottom",maxW:"max-width",minW:"min-width",p:"padding",pl:"padding-left",pr:"padding-right",pt:"padding-top",pb:"padding-bottom",pos:"position",ta:"text-align",w:"width",z:"z-index"},h=[...Object.keys(g),"mx","my","px","py"];function l(r){return r=`
5
+ `+r,r=r.replace(/([mp])x:([^;]*)/g,`$1l:$2;
6
+ $1r:$2`).replace(/([mp])y:([^;]*);/g,`$1t:$2;
7
+ $1b:$2`),Object.entries(g).forEach(([n,t])=>{r=r.replace(new RegExp(`([
8
+ ;])${n}:`,"g"),`$1${t}:`)}),r.trim()}function f(r){let n=[];for(let t of r.matchAll(/[@&]/gm)){let s="",e=0,i=0;for(let o=t.index;o<r.length;o++)if(r[o]==="{")i===0&&(s=r.slice(t.index,o).trim(),e=o+1),i++;else if(r[o]==="}"&&(i--,i===0)){n.push({start:t.index,end:o+1,query:s,outerBody:r.slice(t.index,o+1),innerBody:r.slice(e,o)});break}i!==0&&console.error(`${s} not closed: "${r}"`)}return n}function b(r){return r.split(`
9
+ `).map(n=>n.trim()).filter(n=>n).join(`
10
+ `)}function c(...r){let[n,...t]=r;return typeof n=="string"?n:n.map((s,e)=>{var i;return s+((i=t==null?void 0:t[e])!=null?i:"")}).join("")}function m(r){m.que.add(r),setTimeout(()=>{let n=[...m.que].join(`
11
+ `);if(n){m.que.clear();let t=document.createElement("style");t.id=`u${m.count++}`,t.innerHTML=n,document.head.appendChild(t)}},0)}m.que=new Set;m.count=0;function u(...r){let n=c(...r);if(!n)return"";let t=u.history.get(n);if(!t){t="s"+u.count++,u.history.set(n,t),n=a(n),n=l(n),n=d(n);let s=f(n);for(let e of s.reverse())n=n.slice(0,e.start)+n.slice(e.end);n=`.${t}{
12
+ ${n}
13
+ }
14
+ `,n+=s.map(e=>e.query.startsWith("&")?`.${t}${e.query.slice(1)}{
15
+ ${e.innerBody}
16
+ }`:e.query.startsWith("@keyframes")?e.outerBody:`${e.query}{
17
+ .${t}{${e.innerBody}
18
+ }
19
+ }`).join(`
20
+ `),n=b(n)+`
21
+
22
+ `,m(n)}return t}u.count=0;u.history=new Map;export{m as addCss,p as breakPoints,y as classJoin,u as createClass,h as shorthandProps,g as shorthandPropsMap,c as t2s};
23
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["core.ts"],"sourcesContent":["/** Breakpoints like chakra */\nexport const breakPoints = ['30em', '48em', '62em', '80em', '96em']\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype allowableAny = any\n\n/** Joins class names and filters out blanks */\nexport function classJoin(...classes: allowableAny[]) {\n return classes.filter(c => c && typeof c === 'string').join(' ')\n}\n\n/** delete css comments **/\nfunction deleteComments(css: string) {\n return css.replace(/{\\/\\*[\\s\\S]*?(?=\\*\\/})\\*\\/}/gm, '')\n}\n\n/**\n * Expands array values into media queries\n *\n * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles\n */\nfunction expandArrayValues(css: string) {\n if (!css.includes('[')) return css\n return css\n .split('\\n')\n .map(l => {\n // eslint-disable-next-line no-useless-escape\n const [, prop, vals] = [...l.matchAll(/([A-Za-z\\-]*):[ ]*\\[([^\\]]+)\\]/g)]?.[0] ?? []\n if (vals) {\n return vals\n .split(',')\n .map((val, i) => {\n val = val.trim()\n if (!val || val === 'null' || val === 'undefined') return ''\n if (i === 0) {\n return `${prop}: ${val};`\n }\n return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`\n })\n .join('\\n')\n }\n return l\n })\n .join('\\n')\n}\n\nexport interface ShorthandProps {\n /** shorthand for css:align-items */\n ai?: string\n /** shorthand for css:border */\n b?: string | number\n /** shorthand for css:border-radius */\n br?: string | number\n /** shorthand for css:background */\n bg?: string\n /** shorthand for css:color */\n c?: string\n /** shorthand for css:display */\n d?: string\n /** shorthand for css:flex */\n f?: string\n /** shorthand for css:flex-direction */\n fd?: string\n /** shorthand for css:height */\n h?: number | string\n /** shorthand for css:inset */\n i?: number | string\n /** shorthand for css:justify-content */\n jc?: string\n /** shorthand for css:margin */\n m?: number | string\n /** shorthand for css:margin-left */\n ml?: number | string\n /** shorthand for css:margin-right */\n mr?: number | string\n /** shorthand for css:margin-top */\n mt?: number | string\n /** shorthand for css:margin-bottom */\n mb?: number | string\n /** shorthand for css:margin-top & margin-bottom */\n my?: number | string\n /** shorthand for css:margin-left & margin-right */\n mx?: number | string\n /** shorthand for css:max-width */\n maxW?: number | string\n /** shorthand for css:min-width */\n minW?: number | string\n /** shorthand for css:padding */\n p?: number | string\n /** shorthand for css:padding-left */\n pl?: number | string\n /** shorthand for css:padding-right */\n pr?: number | string\n /** shorthand for css:padding-top */\n pt?: number | string\n /** shorthand for css:padding-bottom */\n pb?: number | string\n /** shorthand for css:padding-top & padding-bottom */\n py?: number | string\n /** shorthand for css:padding-left & padding-right */\n px?: number | string\n /** shorthand for css:position */\n pos?: number | string\n /** shorthand for css:text-align */\n ta?: string\n /** shorthand for css:width */\n w?: number | string\n /** shorthand for css:z-index */\n z?: number | string\n}\nexport const shorthandPropsMap: Record<\n keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>,\n string\n> = {\n ai: 'align-items',\n b: 'border',\n br: 'border-radius',\n bg: 'background',\n c: 'color',\n d: 'display',\n f: 'flex',\n fd: 'flex-direction',\n i: 'inset',\n h: 'height',\n jc: 'justify-content',\n m: 'margin',\n ml: 'margin-left',\n mr: 'margin-right',\n mt: 'margin-top',\n mb: 'margin-bottom',\n maxW: 'max-width',\n minW: 'min-width',\n p: 'padding',\n pl: 'padding-left',\n pr: 'padding-right',\n pt: 'padding-top',\n pb: 'padding-bottom',\n pos: 'position',\n ta: 'text-align',\n w: 'width',\n z: 'z-index',\n}\nexport const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']\n\n/** Expand short-hand css props to full */\nfunction expandProps(css: string) {\n css = '\\n' + css // inject a newline to make the regex easier\n // Handle 'mx', 'my', 'px', 'py'\n css = css\n .replace(/([mp])x:([^;]*)/g, '$1l:$2;\\n$1r:$2')\n .replace(/([mp])y:([^;]*);/g, '$1t:$2;\\n$1b:$2')\n Object.entries(shorthandPropsMap).forEach(([k, v]) => {\n css = css.replace(new RegExp(`([ \\n\\t;])${k}:`, 'g'), `$1${v}:`)\n })\n return css.trim()\n}\n\n/** Find @keyframes, @media, @container queries in css **/\nfunction findQueries(css: string) {\n const queries = []\n for (const m of css.matchAll(/[@&]/gm)) {\n let query = ''\n let bodyStart = 0\n let openCount = 0\n for (let i = m.index!; i < css.length; i++) {\n if (css[i] === '{') {\n if (openCount === 0) {\n query = css.slice(m.index, i).trim()\n bodyStart = i + 1\n }\n openCount++\n } else if (css[i] === '}') {\n openCount--\n if (openCount === 0) {\n queries.push({\n start: m.index,\n end: i + 1,\n query,\n outerBody: css.slice(m.index, i + 1),\n innerBody: css.slice(bodyStart, i),\n })\n break\n }\n }\n }\n if (openCount !== 0) console.error(`${query} not closed: \"${css}\"`)\n }\n return queries\n}\n\n/** Trims whitespace for every line */\nfunction trim(css: string) {\n return css\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l)\n .join('\\n')\n}\n\n/**\n * Assemble a string from a template string array and a list of placeholders.\n *\n * - If the first argument is a string, it is returned as is.\n *\n * i.e.\n * myFoo(...props: TemplateStringProps) => {\n * const inputStr = t2s(...props);\n * }\n * myFoo`hello ${name}` => 'hello world'\n * myFoo(`hello ${name}`) => 'hello world'\n */\nexport function t2s(...tsp: TemplateStringProps) {\n const [s, ...p] = tsp\n return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')\n}\nexport type TemplateStringProps = [\n strings: TemplateStringsArray | string,\n ...placeHolders: string[]\n]\n\n/**\n * Injects css to the page\n *\n * - Batches adds for performance\n *\n * @param css - css to be injected\n * @returns void\n */\nexport function addCss(css: string) {\n addCss.que.add(css)\n setTimeout(() => {\n const css = [...addCss.que].join('\\n')\n if (css) {\n addCss.que.clear()\n const s = document.createElement('style')\n s.id = `u${addCss.count++}`\n s.innerHTML = css\n document.head.appendChild(s)\n }\n }, 0)\n}\naddCss.que = new Set<string>()\naddCss.count = 0\n\n/**\n * Injects css and creates unique class names\n *\n * - Skips if already added\n *\n * @param css - string or template string, to be injected\n * @returns a unique class name\n */\nexport function createClass(...p: TemplateStringProps) {\n let css = t2s(...p)\n if (!css) return ''\n let className = createClass.history.get(css)\n if (!className) {\n className = 's' + createClass.count++\n createClass.history.set(css, className)\n\n css = deleteComments(css)\n css = expandProps(css)\n css = expandArrayValues(css)\n const qs = findQueries(css)\n\n for (const q of qs.reverse()) {\n css = css.slice(0, q.start) + css.slice(q.end)\n }\n\n css = `.${className}{\\n${css}\\n}\\n`\n css += qs\n .map(q => {\n if (q.query.startsWith('&')) {\n return `.${className}${q.query.slice(1)}{\\n${q.innerBody}\\n}`\n }\n if (q.query.startsWith('@keyframes')) {\n return q.outerBody\n }\n return `${q.query}{\\n.${className}{${q.innerBody}\\n}\\n}`\n })\n .join('\\n')\n\n css = trim(css) + '\\n\\n'\n\n addCss(css)\n }\n return className\n}\ncreateClass.count = 0\ncreateClass.history = new Map<string, string>()\n"],"mappings":"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","names":["breakPoints","classJoin","classes","c","deleteComments","css","expandArrayValues","l","_a","prop","vals","val","i","shorthandPropsMap","shorthandProps","expandProps","k","v","findQueries","queries","m","query","bodyStart","openCount","trim","t2s","tsp","s","p","addCss","createClass","className","qs","q"]}
package/src/core.ts ADDED
@@ -0,0 +1,290 @@
1
+ /** Breakpoints like chakra */
2
+ export const breakPoints = ['30em', '48em', '62em', '80em', '96em']
3
+
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ type allowableAny = any
6
+
7
+ /** Joins class names and filters out blanks */
8
+ export function classJoin(...classes: allowableAny[]) {
9
+ return classes.filter(c => c && typeof c === 'string').join(' ')
10
+ }
11
+
12
+ /** delete css comments **/
13
+ function deleteComments(css: string) {
14
+ return css.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm, '')
15
+ }
16
+
17
+ /**
18
+ * Expands array values into media queries
19
+ *
20
+ * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles
21
+ */
22
+ function expandArrayValues(css: string) {
23
+ if (!css.includes('[')) return css
24
+ return css
25
+ .split('\n')
26
+ .map(l => {
27
+ // eslint-disable-next-line no-useless-escape
28
+ const [, prop, vals] = [...l.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)]?.[0] ?? []
29
+ if (vals) {
30
+ return vals
31
+ .split(',')
32
+ .map((val, i) => {
33
+ val = val.trim()
34
+ if (!val || val === 'null' || val === 'undefined') return ''
35
+ if (i === 0) {
36
+ return `${prop}: ${val};`
37
+ }
38
+ return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`
39
+ })
40
+ .join('\n')
41
+ }
42
+ return l
43
+ })
44
+ .join('\n')
45
+ }
46
+
47
+ export interface ShorthandProps {
48
+ /** shorthand for css:align-items */
49
+ ai?: string
50
+ /** shorthand for css:border */
51
+ b?: string | number
52
+ /** shorthand for css:border-radius */
53
+ br?: string | number
54
+ /** shorthand for css:background */
55
+ bg?: string
56
+ /** shorthand for css:color */
57
+ c?: string
58
+ /** shorthand for css:display */
59
+ d?: string
60
+ /** shorthand for css:flex */
61
+ f?: string
62
+ /** shorthand for css:flex-direction */
63
+ fd?: string
64
+ /** shorthand for css:height */
65
+ h?: number | string
66
+ /** shorthand for css:inset */
67
+ i?: number | string
68
+ /** shorthand for css:justify-content */
69
+ jc?: string
70
+ /** shorthand for css:margin */
71
+ m?: number | string
72
+ /** shorthand for css:margin-left */
73
+ ml?: number | string
74
+ /** shorthand for css:margin-right */
75
+ mr?: number | string
76
+ /** shorthand for css:margin-top */
77
+ mt?: number | string
78
+ /** shorthand for css:margin-bottom */
79
+ mb?: number | string
80
+ /** shorthand for css:margin-top & margin-bottom */
81
+ my?: number | string
82
+ /** shorthand for css:margin-left & margin-right */
83
+ mx?: number | string
84
+ /** shorthand for css:max-width */
85
+ maxW?: number | string
86
+ /** shorthand for css:min-width */
87
+ minW?: number | string
88
+ /** shorthand for css:padding */
89
+ p?: number | string
90
+ /** shorthand for css:padding-left */
91
+ pl?: number | string
92
+ /** shorthand for css:padding-right */
93
+ pr?: number | string
94
+ /** shorthand for css:padding-top */
95
+ pt?: number | string
96
+ /** shorthand for css:padding-bottom */
97
+ pb?: number | string
98
+ /** shorthand for css:padding-top & padding-bottom */
99
+ py?: number | string
100
+ /** shorthand for css:padding-left & padding-right */
101
+ px?: number | string
102
+ /** shorthand for css:position */
103
+ pos?: number | string
104
+ /** shorthand for css:text-align */
105
+ ta?: string
106
+ /** shorthand for css:width */
107
+ w?: number | string
108
+ /** shorthand for css:z-index */
109
+ z?: number | string
110
+ }
111
+ export const shorthandPropsMap: Record<
112
+ keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>,
113
+ string
114
+ > = {
115
+ ai: 'align-items',
116
+ b: 'border',
117
+ br: 'border-radius',
118
+ bg: 'background',
119
+ c: 'color',
120
+ d: 'display',
121
+ f: 'flex',
122
+ fd: 'flex-direction',
123
+ i: 'inset',
124
+ h: 'height',
125
+ jc: 'justify-content',
126
+ m: 'margin',
127
+ ml: 'margin-left',
128
+ mr: 'margin-right',
129
+ mt: 'margin-top',
130
+ mb: 'margin-bottom',
131
+ maxW: 'max-width',
132
+ minW: 'min-width',
133
+ p: 'padding',
134
+ pl: 'padding-left',
135
+ pr: 'padding-right',
136
+ pt: 'padding-top',
137
+ pb: 'padding-bottom',
138
+ pos: 'position',
139
+ ta: 'text-align',
140
+ w: 'width',
141
+ z: 'z-index',
142
+ }
143
+ export const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']
144
+
145
+ /** Expand short-hand css props to full */
146
+ function expandProps(css: string) {
147
+ css = '\n' + css // inject a newline to make the regex easier
148
+ // Handle 'mx', 'my', 'px', 'py'
149
+ css = css
150
+ .replace(/([mp])x:([^;]*)/g, '$1l:$2;\n$1r:$2')
151
+ .replace(/([mp])y:([^;]*);/g, '$1t:$2;\n$1b:$2')
152
+ Object.entries(shorthandPropsMap).forEach(([k, v]) => {
153
+ css = css.replace(new RegExp(`([ \n\t;])${k}:`, 'g'), `$1${v}:`)
154
+ })
155
+ return css.trim()
156
+ }
157
+
158
+ /** Find @keyframes, @media, @container queries in css **/
159
+ function findQueries(css: string) {
160
+ const queries = []
161
+ for (const m of css.matchAll(/[@&]/gm)) {
162
+ let query = ''
163
+ let bodyStart = 0
164
+ let openCount = 0
165
+ for (let i = m.index!; i < css.length; i++) {
166
+ if (css[i] === '{') {
167
+ if (openCount === 0) {
168
+ query = css.slice(m.index, i).trim()
169
+ bodyStart = i + 1
170
+ }
171
+ openCount++
172
+ } else if (css[i] === '}') {
173
+ openCount--
174
+ if (openCount === 0) {
175
+ queries.push({
176
+ start: m.index,
177
+ end: i + 1,
178
+ query,
179
+ outerBody: css.slice(m.index, i + 1),
180
+ innerBody: css.slice(bodyStart, i),
181
+ })
182
+ break
183
+ }
184
+ }
185
+ }
186
+ if (openCount !== 0) console.error(`${query} not closed: "${css}"`)
187
+ }
188
+ return queries
189
+ }
190
+
191
+ /** Trims whitespace for every line */
192
+ function trim(css: string) {
193
+ return css
194
+ .split('\n')
195
+ .map(l => l.trim())
196
+ .filter(l => l)
197
+ .join('\n')
198
+ }
199
+
200
+ /**
201
+ * Assemble a string from a template string array and a list of placeholders.
202
+ *
203
+ * - If the first argument is a string, it is returned as is.
204
+ *
205
+ * i.e.
206
+ * myFoo(...props: TemplateStringProps) => {
207
+ * const inputStr = t2s(...props);
208
+ * }
209
+ * myFoo`hello ${name}` => 'hello world'
210
+ * myFoo(`hello ${name}`) => 'hello world'
211
+ */
212
+ export function t2s(...tsp: TemplateStringProps) {
213
+ const [s, ...p] = tsp
214
+ return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')
215
+ }
216
+ export type TemplateStringProps = [
217
+ strings: TemplateStringsArray | string,
218
+ ...placeHolders: string[]
219
+ ]
220
+
221
+ /**
222
+ * Injects css to the page
223
+ *
224
+ * - Batches adds for performance
225
+ *
226
+ * @param css - css to be injected
227
+ * @returns void
228
+ */
229
+ export function addCss(css: string) {
230
+ addCss.que.add(css)
231
+ setTimeout(() => {
232
+ const css = [...addCss.que].join('\n')
233
+ if (css) {
234
+ addCss.que.clear()
235
+ const s = document.createElement('style')
236
+ s.id = `u${addCss.count++}`
237
+ s.innerHTML = css
238
+ document.head.appendChild(s)
239
+ }
240
+ }, 0)
241
+ }
242
+ addCss.que = new Set<string>()
243
+ addCss.count = 0
244
+
245
+ /**
246
+ * Injects css and creates unique class names
247
+ *
248
+ * - Skips if already added
249
+ *
250
+ * @param css - string or template string, to be injected
251
+ * @returns a unique class name
252
+ */
253
+ export function createClass(...p: TemplateStringProps) {
254
+ let css = t2s(...p)
255
+ if (!css) return ''
256
+ let className = createClass.history.get(css)
257
+ if (!className) {
258
+ className = 's' + createClass.count++
259
+ createClass.history.set(css, className)
260
+
261
+ css = deleteComments(css)
262
+ css = expandProps(css)
263
+ css = expandArrayValues(css)
264
+ const qs = findQueries(css)
265
+
266
+ for (const q of qs.reverse()) {
267
+ css = css.slice(0, q.start) + css.slice(q.end)
268
+ }
269
+
270
+ css = `.${className}{\n${css}\n}\n`
271
+ css += qs
272
+ .map(q => {
273
+ if (q.query.startsWith('&')) {
274
+ return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`
275
+ }
276
+ if (q.query.startsWith('@keyframes')) {
277
+ return q.outerBody
278
+ }
279
+ return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`
280
+ })
281
+ .join('\n')
282
+
283
+ css = trim(css) + '\n\n'
284
+
285
+ addCss(css)
286
+ }
287
+ return className
288
+ }
289
+ createClass.count = 0
290
+ createClass.history = new Map<string, string>()
package/src/index.cjs CHANGED
@@ -1,14 +1,14 @@
1
- "use strict";var g=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var c=(r,n)=>{for(var t in n)g(r,t,{get:n[t],enumerable:!0})},y=(r,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of f(n))!b.call(r,e)&&e!==t&&g(r,e,{get:()=>n[e],enumerable:!(o=l(n,e))||o.enumerable});return r};var h=r=>y(g({},"__esModule",{value:!0}),r);var T={};c(T,{addCss:()=>m,classJoin:()=>$,default:()=>u,shorthandProps:()=>P,shorthandPropsMap:()=>p,t2s:()=>d});module.exports=h(T);var x=["30em","48em","62em","80em","96em"];function $(...r){return r.filter(n=>n&&typeof n=="string").join(" ")}function j(r){return r.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm,"")}function w(r){return r.includes("[")?r.split(`
2
- `).map(n=>{var s;let[t,o,e]=(s=[...n.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)][0])!=null?s:[];return e?e.split(",").map((i,a)=>(i=i.trim(),!i||i==="null"||i==="undefined"?"":a===0?`${o}: ${i};`:`@media (min-width: ${x[a-1]}) { ${o}: ${i}; }`)).join(`
1
+ "use strict";var p=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var b=(r,n)=>{for(var t in n)p(r,t,{get:n[t],enumerable:!0})},y=(r,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of f(n))!c.call(r,e)&&e!==t&&p(r,e,{get:()=>n[e],enumerable:!(o=l(n,e))||o.enumerable});return r};var x=r=>y(p({},"__esModule",{value:!0}),r);var k={};b(k,{addCss:()=>m,breakPoints:()=>a,classJoin:()=>h,createClass:()=>u,css:()=>u,shorthandProps:()=>w,shorthandPropsMap:()=>g,t2s:()=>d});module.exports=x(k);var a=["30em","48em","62em","80em","96em"];function h(...r){return r.filter(n=>n&&typeof n=="string").join(" ")}function $(r){return r.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm,"")}function j(r){return r.includes("[")?r.split(`
2
+ `).map(n=>{var e;let[,t,o]=(e=[...n.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)][0])!=null?e:[];return o?o.split(",").map((i,s)=>(i=i.trim(),!i||i==="null"||i==="undefined"?"":s===0?`${t}: ${i};`:`@media (min-width: ${a[s-1]}) { ${t}: ${i}; }`)).join(`
3
3
  `):n}).join(`
4
- `):r}var p={ai:"align-items",b:"border",br:"border-radius",bg:"background",c:"color",d:"display",f:"flex",fd:"flex-direction",i:"inset",h:"height",jc:"justify-content",m:"margin",ml:"margin-left",mr:"margin-right",mt:"margin-top",mb:"margin-bottom",maxW:"max-width",minW:"min-width",p:"padding",pl:"padding-left",pr:"padding-right",pt:"padding-top",pb:"padding-bottom",pos:"position",ta:"text-align",w:"width",z:"z-index"},P=[...Object.keys(p),"mx","my","px","py"];function S(r){return r=`
4
+ `):r}var g={ai:"align-items",b:"border",br:"border-radius",bg:"background",c:"color",d:"display",f:"flex",fd:"flex-direction",i:"inset",h:"height",jc:"justify-content",m:"margin",ml:"margin-left",mr:"margin-right",mt:"margin-top",mb:"margin-bottom",maxW:"max-width",minW:"min-width",p:"padding",pl:"padding-left",pr:"padding-right",pt:"padding-top",pb:"padding-bottom",pos:"position",ta:"text-align",w:"width",z:"z-index"},w=[...Object.keys(g),"mx","my","px","py"];function P(r){return r=`
5
5
  `+r,r=r.replace(/([mp])x:([^;]*)/g,`$1l:$2;
6
6
  $1r:$2`).replace(/([mp])y:([^;]*);/g,`$1t:$2;
7
- $1b:$2`),Object.entries(p).forEach(([n,t])=>{r=r.replace(new RegExp(`([
8
- ;])${n}:`,"g"),`$1${t}:`)}),r.trim()}function k(r){let n=[];for(let t of r.matchAll(/[@&]/gm)){let o="",e=0,s=0;for(let i=t.index;i<r.length;i++)if(r[i]==="{")s===0&&(o=r.slice(t.index,i).trim(),e=i+1),s++;else if(r[i]==="}"&&(s--,s===0)){n.push({start:t.index,end:i+1,query:o,outerBody:r.slice(t.index,i+1),innerBody:r.slice(e,i)});break}s!==0&&console.error(`${o} not closed: "${r}"`)}return n}function q(r){return r.split(`
7
+ $1b:$2`),Object.entries(g).forEach(([n,t])=>{r=r.replace(new RegExp(`([
8
+ ;])${n}:`,"g"),`$1${t}:`)}),r.trim()}function S(r){let n=[];for(let t of r.matchAll(/[@&]/gm)){let o="",e=0,i=0;for(let s=t.index;s<r.length;s++)if(r[s]==="{")i===0&&(o=r.slice(t.index,s).trim(),e=s+1),i++;else if(r[s]==="}"&&(i--,i===0)){n.push({start:t.index,end:s+1,query:o,outerBody:r.slice(t.index,s+1),innerBody:r.slice(e,s)});break}i!==0&&console.error(`${o} not closed: "${r}"`)}return n}function A(r){return r.split(`
9
9
  `).map(n=>n.trim()).filter(n=>n).join(`
10
- `)}function d(...r){let[n,...t]=r;return typeof n=="string"?n:n.map((o,e)=>{var s;return o+((s=t==null?void 0:t[e])!=null?s:"")}).join("")}function m(r){m.que.add(r),setTimeout(()=>{let n=[...m.que].join(`
11
- `);if(n){m.que.clear();let t=document.createElement("style");t.id=`u${m.count++}`,t.innerHTML=n,document.head.appendChild(t)}},0)}m.que=new Set;m.count=0;function u(...r){let n=d(...r);if(!n)return"";let t=u.history.get(n);if(!t){t="s"+u.count++,u.history.set(n,t),n=j(n),n=S(n),n=w(n);let o=k(n);for(let e of o.reverse())n=n.slice(0,e.start)+n.slice(e.end);n=`.${t}{
10
+ `)}function d(...r){let[n,...t]=r;return typeof n=="string"?n:n.map((o,e)=>{var i;return o+((i=t==null?void 0:t[e])!=null?i:"")}).join("")}function m(r){m.que.add(r),setTimeout(()=>{let n=[...m.que].join(`
11
+ `);if(n){m.que.clear();let t=document.createElement("style");t.id=`u${m.count++}`,t.innerHTML=n,document.head.appendChild(t)}},0)}m.que=new Set;m.count=0;function u(...r){let n=d(...r);if(!n)return"";let t=u.history.get(n);if(!t){t="s"+u.count++,u.history.set(n,t),n=$(n),n=P(n),n=j(n);let o=S(n);for(let e of o.reverse())n=n.slice(0,e.start)+n.slice(e.end);n=`.${t}{
12
12
  ${n}
13
13
  }
14
14
  `,n+=o.map(e=>e.query.startsWith("&")?`.${t}${e.query.slice(1)}{
@@ -17,7 +17,7 @@ ${e.innerBody}
17
17
  .${t}{${e.innerBody}
18
18
  }
19
19
  }`).join(`
20
- `),n=q(n)+`
20
+ `),n=A(n)+`
21
21
 
22
- `,m(n)}return t}u.count=0;u.history=new Map;0&&(module.exports={addCss,classJoin,shorthandProps,shorthandPropsMap,t2s});
22
+ `,m(n)}return t}u.count=0;u.history=new Map;0&&(module.exports={addCss,breakPoints,classJoin,createClass,css,shorthandProps,shorthandPropsMap,t2s});
23
23
  //# sourceMappingURL=index.cjs.map
package/src/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["/** Breakpoints like chakra */\nconst breakPoints = ['30em', '48em', '62em', '80em', '96em']\n\n/** Joins class names and filters out blanks */\nexport function classJoin(...classes: any[]) {\n return classes.filter((c) => c && typeof c === 'string').join(' ')\n}\n\n// delete css comments i.e. {/* blah */}\nfunction deleteComments(css: string) {\n return css.replace(/{\\/\\*[\\s\\S]*?(?=\\*\\/})\\*\\/}/gm, '')\n}\n\n/**\n * Expands array values into media queries\n *\n * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles\n */\nfunction expandArrayValues(css: string) {\n if (!css.includes('[')) return css\n return css\n .split('\\n')\n .map((l) => {\n const [_, prop, vals] = [...l.matchAll(/([A-Za-z\\-]*):[ ]*\\[([^\\]]+)\\]/g)]?.[0] ?? []\n if (vals) {\n return vals\n .split(',')\n .map((val, i) => {\n val = val.trim()\n if (!val || val === 'null' || val === 'undefined') return ''\n if (i === 0) {\n return `${prop}: ${val};`\n }\n return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`\n })\n .join('\\n')\n }\n return l\n })\n .join('\\n')\n}\n\nexport interface ShorthandProps {\n /** shorthand for css:align-items */\n ai?: string\n /** shorthand for css:border */\n b?: string | number\n /** shorthand for css:border-radius */\n br?: string | number\n /** shorthand for css:background */\n bg?: string\n /** shorthand for css:color */\n c?: string\n /** shorthand for css:display */\n d?: string\n /** shorthand for css:flex */\n f?: string\n /** shorthand for css:flex-direction */\n fd?: string\n /** shorthand for css:height */\n h?: number | string\n /** shorthand for css:inset */\n i?: number | string\n /** shorthand for css:justify-content */\n jc?: string\n /** shorthand for css:margin */\n m?: number | string\n /** shorthand for css:margin-left */\n ml?: number | string\n /** shorthand for css:margin-right */\n mr?: number | string\n /** shorthand for css:margin-top */\n mt?: number | string\n /** shorthand for css:margin-bottom */\n mb?: number | string\n /** shorthand for css:margin-top & margin-bottom */\n my?: number | string\n /** shorthand for css:margin-left & margin-right */\n mx?: number | string\n /** shorthand for css:max-width */\n maxW?: number | string\n /** shorthand for css:min-width */\n minW?: number | string\n /** shorthand for css:padding */\n p?: number | string\n /** shorthand for css:padding-left */\n pl?: number | string\n /** shorthand for css:padding-right */\n pr?: number | string\n /** shorthand for css:padding-top */\n pt?: number | string\n /** shorthand for css:padding-bottom */\n pb?: number | string\n /** shorthand for css:padding-top & padding-bottom */\n py?: number | string\n /** shorthand for css:padding-left & padding-right */\n px?: number | string\n /** shorthand for css:position */\n pos?: number | string\n /** shorthand for css:text-align */\n ta?: string\n /** shorthand for css:width */\n w?: number | string\n /** shorthand for css:z-index */\n z?: number | string\n}\nexport const shorthandPropsMap: Record<keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>, string> = {\n ai: 'align-items',\n b: 'border',\n br: 'border-radius',\n bg: 'background',\n c: 'color',\n d: 'display',\n f: 'flex',\n fd: 'flex-direction',\n i: 'inset',\n h: 'height',\n jc: 'justify-content',\n m: 'margin',\n ml: 'margin-left',\n mr: 'margin-right',\n mt: 'margin-top',\n mb: 'margin-bottom',\n maxW: 'max-width',\n minW: 'min-width',\n p: 'padding',\n pl: 'padding-left',\n pr: 'padding-right',\n pt: 'padding-top',\n pb: 'padding-bottom',\n pos: 'position',\n ta: 'text-align',\n w: 'width',\n z: 'z-index',\n}\nexport const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']\n\n/** Expand short-hand css props to full */\nfunction expandProps(css: string) {\n css = '\\n' + css // inject a newline to make the regex easier\n // Handle 'mx', 'my', 'px', 'py'\n css = css.replace(/([mp])x:([^;]*)/g, '$1l:$2;\\n$1r:$2').replace(/([mp])y:([^;]*);/g, '$1t:$2;\\n$1b:$2')\n Object.entries(shorthandPropsMap).forEach(([k, v]) => {\n css = css.replace(new RegExp(`([ \\n\\t;])${k}:`, 'g'), `$1${v}:`)\n })\n return css.trim()\n}\n\n/** Find @keyframes, @media, @container queries in css **/\nfunction findQueries(css: string) {\n const queries = []\n for (let m of css.matchAll(/[@&]/gm)) {\n let query = ''\n let bodyStart = 0\n let openCount = 0\n for (let i = m.index!; i < css.length; i++) {\n if (css[i] === '{') {\n if (openCount === 0) {\n query = css.slice(m.index, i).trim()\n bodyStart = i + 1\n }\n openCount++\n } else if (css[i] === '}') {\n openCount--\n if (openCount === 0) {\n queries.push({\n start: m.index,\n end: i + 1,\n query,\n outerBody: css.slice(m.index, i + 1),\n innerBody: css.slice(bodyStart, i),\n })\n break\n }\n }\n }\n if (openCount !== 0) console.error(`${query} not closed: \"${css}\"`)\n }\n return queries\n}\n\n/** Trims whitespace for every line */\nfunction trim(css: string) {\n return css\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l)\n .join('\\n')\n}\n\n/**\n * Assemble a string from a template string array and a list of placeholders.\n *\n * - If the first argument is a string, it is returned as is.\n *\n * i.e.\n * myFoo(...props: TemplateStringProps) => {\n * const inputStr = t2s(...props);\n * }\n * myFoo`hello ${name}` => 'hello world'\n * myFoo(`hello ${name}`) => 'hello world'\n */\nexport function t2s(...tsp: TemplateStringProps) {\n const [s, ...p] = tsp\n return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')\n}\nexport type TemplateStringProps = [strings: TemplateStringsArray | string, ...placeHolders: string[]]\n\n/**\n * Injects css to the page\n *\n * - Batches adds for performance\n *\n * @param css - css to be injected\n * @returns void\n */\nexport function addCss(css: string) {\n addCss.que.add(css)\n setTimeout(() => {\n const css = [...addCss.que].join('\\n')\n if (css) {\n addCss.que.clear()\n const s = document.createElement('style')\n s.id = `u${addCss.count++}`\n s.innerHTML = css\n document.head.appendChild(s)\n }\n }, 0)\n}\naddCss.que = new Set<string>()\naddCss.count = 0\n\n/**\n * Injects css and creates unique class names\n *\n * - Skips if already added\n *\n * @param css - string or template string, to be injected\n * @returns a unique class name\n */\nexport default function createClass(...p: TemplateStringProps) {\n let css = t2s(...p)\n if (!css) return ''\n let className = createClass.history.get(css)\n if (!className) {\n className = 's' + createClass.count++\n createClass.history.set(css, className)\n\n css = deleteComments(css)\n css = expandProps(css)\n css = expandArrayValues(css)\n const qs = findQueries(css)\n\n for (let q of qs.reverse()) {\n css = css.slice(0, q.start) + css.slice(q.end)\n }\n\n css = `.${className}{\\n${css}\\n}\\n`\n css += qs\n .map((q) => {\n if (q.query.startsWith('&')) {\n return `.${className}${q.query.slice(1)}{\\n${q.innerBody}\\n}`\n }\n if (q.query.startsWith('@keyframes')) {\n return q.outerBody\n }\n return `${q.query}{\\n.${className}{${q.innerBody}\\n}\\n}`\n })\n .join('\\n')\n\n css = trim(css) + '\\n\\n'\n\n addCss(css)\n }\n return className\n}\ncreateClass.count = 0\ncreateClass.history = new Map<string, string>()\n"],"mappings":"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","names":["src_exports","__export","addCss","classJoin","createClass","shorthandProps","shorthandPropsMap","t2s","__toCommonJS","breakPoints","classes","c","deleteComments","css","expandArrayValues","l","_a","_","prop","vals","val","i","expandProps","k","v","findQueries","queries","m","query","bodyStart","openCount","trim","tsp","s","p","className","qs","q"]}
1
+ {"version":3,"sources":["index.ts","core.ts"],"sourcesContent":["export * from './core.js'\nexport {createClass as css} from './core.js'\n","/** Breakpoints like chakra */\nexport const breakPoints = ['30em', '48em', '62em', '80em', '96em']\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype allowableAny = any\n\n/** Joins class names and filters out blanks */\nexport function classJoin(...classes: allowableAny[]) {\n return classes.filter(c => c && typeof c === 'string').join(' ')\n}\n\n/** delete css comments **/\nfunction deleteComments(css: string) {\n return css.replace(/{\\/\\*[\\s\\S]*?(?=\\*\\/})\\*\\/}/gm, '')\n}\n\n/**\n * Expands array values into media queries\n *\n * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles\n */\nfunction expandArrayValues(css: string) {\n if (!css.includes('[')) return css\n return css\n .split('\\n')\n .map(l => {\n // eslint-disable-next-line no-useless-escape\n const [, prop, vals] = [...l.matchAll(/([A-Za-z\\-]*):[ ]*\\[([^\\]]+)\\]/g)]?.[0] ?? []\n if (vals) {\n return vals\n .split(',')\n .map((val, i) => {\n val = val.trim()\n if (!val || val === 'null' || val === 'undefined') return ''\n if (i === 0) {\n return `${prop}: ${val};`\n }\n return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`\n })\n .join('\\n')\n }\n return l\n })\n .join('\\n')\n}\n\nexport interface ShorthandProps {\n /** shorthand for css:align-items */\n ai?: string\n /** shorthand for css:border */\n b?: string | number\n /** shorthand for css:border-radius */\n br?: string | number\n /** shorthand for css:background */\n bg?: string\n /** shorthand for css:color */\n c?: string\n /** shorthand for css:display */\n d?: string\n /** shorthand for css:flex */\n f?: string\n /** shorthand for css:flex-direction */\n fd?: string\n /** shorthand for css:height */\n h?: number | string\n /** shorthand for css:inset */\n i?: number | string\n /** shorthand for css:justify-content */\n jc?: string\n /** shorthand for css:margin */\n m?: number | string\n /** shorthand for css:margin-left */\n ml?: number | string\n /** shorthand for css:margin-right */\n mr?: number | string\n /** shorthand for css:margin-top */\n mt?: number | string\n /** shorthand for css:margin-bottom */\n mb?: number | string\n /** shorthand for css:margin-top & margin-bottom */\n my?: number | string\n /** shorthand for css:margin-left & margin-right */\n mx?: number | string\n /** shorthand for css:max-width */\n maxW?: number | string\n /** shorthand for css:min-width */\n minW?: number | string\n /** shorthand for css:padding */\n p?: number | string\n /** shorthand for css:padding-left */\n pl?: number | string\n /** shorthand for css:padding-right */\n pr?: number | string\n /** shorthand for css:padding-top */\n pt?: number | string\n /** shorthand for css:padding-bottom */\n pb?: number | string\n /** shorthand for css:padding-top & padding-bottom */\n py?: number | string\n /** shorthand for css:padding-left & padding-right */\n px?: number | string\n /** shorthand for css:position */\n pos?: number | string\n /** shorthand for css:text-align */\n ta?: string\n /** shorthand for css:width */\n w?: number | string\n /** shorthand for css:z-index */\n z?: number | string\n}\nexport const shorthandPropsMap: Record<\n keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>,\n string\n> = {\n ai: 'align-items',\n b: 'border',\n br: 'border-radius',\n bg: 'background',\n c: 'color',\n d: 'display',\n f: 'flex',\n fd: 'flex-direction',\n i: 'inset',\n h: 'height',\n jc: 'justify-content',\n m: 'margin',\n ml: 'margin-left',\n mr: 'margin-right',\n mt: 'margin-top',\n mb: 'margin-bottom',\n maxW: 'max-width',\n minW: 'min-width',\n p: 'padding',\n pl: 'padding-left',\n pr: 'padding-right',\n pt: 'padding-top',\n pb: 'padding-bottom',\n pos: 'position',\n ta: 'text-align',\n w: 'width',\n z: 'z-index',\n}\nexport const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']\n\n/** Expand short-hand css props to full */\nfunction expandProps(css: string) {\n css = '\\n' + css // inject a newline to make the regex easier\n // Handle 'mx', 'my', 'px', 'py'\n css = css\n .replace(/([mp])x:([^;]*)/g, '$1l:$2;\\n$1r:$2')\n .replace(/([mp])y:([^;]*);/g, '$1t:$2;\\n$1b:$2')\n Object.entries(shorthandPropsMap).forEach(([k, v]) => {\n css = css.replace(new RegExp(`([ \\n\\t;])${k}:`, 'g'), `$1${v}:`)\n })\n return css.trim()\n}\n\n/** Find @keyframes, @media, @container queries in css **/\nfunction findQueries(css: string) {\n const queries = []\n for (const m of css.matchAll(/[@&]/gm)) {\n let query = ''\n let bodyStart = 0\n let openCount = 0\n for (let i = m.index!; i < css.length; i++) {\n if (css[i] === '{') {\n if (openCount === 0) {\n query = css.slice(m.index, i).trim()\n bodyStart = i + 1\n }\n openCount++\n } else if (css[i] === '}') {\n openCount--\n if (openCount === 0) {\n queries.push({\n start: m.index,\n end: i + 1,\n query,\n outerBody: css.slice(m.index, i + 1),\n innerBody: css.slice(bodyStart, i),\n })\n break\n }\n }\n }\n if (openCount !== 0) console.error(`${query} not closed: \"${css}\"`)\n }\n return queries\n}\n\n/** Trims whitespace for every line */\nfunction trim(css: string) {\n return css\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l)\n .join('\\n')\n}\n\n/**\n * Assemble a string from a template string array and a list of placeholders.\n *\n * - If the first argument is a string, it is returned as is.\n *\n * i.e.\n * myFoo(...props: TemplateStringProps) => {\n * const inputStr = t2s(...props);\n * }\n * myFoo`hello ${name}` => 'hello world'\n * myFoo(`hello ${name}`) => 'hello world'\n */\nexport function t2s(...tsp: TemplateStringProps) {\n const [s, ...p] = tsp\n return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')\n}\nexport type TemplateStringProps = [\n strings: TemplateStringsArray | string,\n ...placeHolders: string[]\n]\n\n/**\n * Injects css to the page\n *\n * - Batches adds for performance\n *\n * @param css - css to be injected\n * @returns void\n */\nexport function addCss(css: string) {\n addCss.que.add(css)\n setTimeout(() => {\n const css = [...addCss.que].join('\\n')\n if (css) {\n addCss.que.clear()\n const s = document.createElement('style')\n s.id = `u${addCss.count++}`\n s.innerHTML = css\n document.head.appendChild(s)\n }\n }, 0)\n}\naddCss.que = new Set<string>()\naddCss.count = 0\n\n/**\n * Injects css and creates unique class names\n *\n * - Skips if already added\n *\n * @param css - string or template string, to be injected\n * @returns a unique class name\n */\nexport function createClass(...p: TemplateStringProps) {\n let css = t2s(...p)\n if (!css) return ''\n let className = createClass.history.get(css)\n if (!className) {\n className = 's' + createClass.count++\n createClass.history.set(css, className)\n\n css = deleteComments(css)\n css = expandProps(css)\n css = expandArrayValues(css)\n const qs = findQueries(css)\n\n for (const q of qs.reverse()) {\n css = css.slice(0, q.start) + css.slice(q.end)\n }\n\n css = `.${className}{\\n${css}\\n}\\n`\n css += qs\n .map(q => {\n if (q.query.startsWith('&')) {\n return `.${className}${q.query.slice(1)}{\\n${q.innerBody}\\n}`\n }\n if (q.query.startsWith('@keyframes')) {\n return q.outerBody\n }\n return `${q.query}{\\n.${className}{${q.innerBody}\\n}\\n}`\n })\n .join('\\n')\n\n css = trim(css) + '\\n\\n'\n\n addCss(css)\n }\n return className\n}\ncreateClass.count = 0\ncreateClass.history = new Map<string, string>()\n"],"mappings":"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","names":["src_exports","__export","addCss","breakPoints","classJoin","createClass","shorthandProps","shorthandPropsMap","t2s","__toCommonJS","breakPoints","classJoin","classes","c","deleteComments","css","expandArrayValues","l","_a","prop","vals","val","i","shorthandPropsMap","shorthandProps","expandProps","k","v","findQueries","queries","m","query","bodyStart","openCount","trim","t2s","tsp","s","p","addCss","createClass","className","qs","q"]}
package/src/index.d.ts CHANGED
@@ -1,110 +1 @@
1
- /** Joins class names and filters out blanks */
2
- declare function classJoin(...classes: any[]): string;
3
- interface ShorthandProps {
4
- /** shorthand for css:align-items */
5
- ai?: string;
6
- /** shorthand for css:border */
7
- b?: string | number;
8
- /** shorthand for css:border-radius */
9
- br?: string | number;
10
- /** shorthand for css:background */
11
- bg?: string;
12
- /** shorthand for css:color */
13
- c?: string;
14
- /** shorthand for css:display */
15
- d?: string;
16
- /** shorthand for css:flex */
17
- f?: string;
18
- /** shorthand for css:flex-direction */
19
- fd?: string;
20
- /** shorthand for css:height */
21
- h?: number | string;
22
- /** shorthand for css:inset */
23
- i?: number | string;
24
- /** shorthand for css:justify-content */
25
- jc?: string;
26
- /** shorthand for css:margin */
27
- m?: number | string;
28
- /** shorthand for css:margin-left */
29
- ml?: number | string;
30
- /** shorthand for css:margin-right */
31
- mr?: number | string;
32
- /** shorthand for css:margin-top */
33
- mt?: number | string;
34
- /** shorthand for css:margin-bottom */
35
- mb?: number | string;
36
- /** shorthand for css:margin-top & margin-bottom */
37
- my?: number | string;
38
- /** shorthand for css:margin-left & margin-right */
39
- mx?: number | string;
40
- /** shorthand for css:max-width */
41
- maxW?: number | string;
42
- /** shorthand for css:min-width */
43
- minW?: number | string;
44
- /** shorthand for css:padding */
45
- p?: number | string;
46
- /** shorthand for css:padding-left */
47
- pl?: number | string;
48
- /** shorthand for css:padding-right */
49
- pr?: number | string;
50
- /** shorthand for css:padding-top */
51
- pt?: number | string;
52
- /** shorthand for css:padding-bottom */
53
- pb?: number | string;
54
- /** shorthand for css:padding-top & padding-bottom */
55
- py?: number | string;
56
- /** shorthand for css:padding-left & padding-right */
57
- px?: number | string;
58
- /** shorthand for css:position */
59
- pos?: number | string;
60
- /** shorthand for css:text-align */
61
- ta?: string;
62
- /** shorthand for css:width */
63
- w?: number | string;
64
- /** shorthand for css:z-index */
65
- z?: number | string;
66
- }
67
- declare const shorthandPropsMap: Record<keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>, string>;
68
- declare const shorthandProps: string[];
69
- /**
70
- * Assemble a string from a template string array and a list of placeholders.
71
- *
72
- * - If the first argument is a string, it is returned as is.
73
- *
74
- * i.e.
75
- * myFoo(...props: TemplateStringProps) => {
76
- * const inputStr = t2s(...props);
77
- * }
78
- * myFoo`hello ${name}` => 'hello world'
79
- * myFoo(`hello ${name}`) => 'hello world'
80
- */
81
- declare function t2s(...tsp: TemplateStringProps): string;
82
- type TemplateStringProps = [strings: TemplateStringsArray | string, ...placeHolders: string[]];
83
- /**
84
- * Injects css to the page
85
- *
86
- * - Batches adds for performance
87
- *
88
- * @param css - css to be injected
89
- * @returns void
90
- */
91
- declare function addCss(css: string): void;
92
- declare namespace addCss {
93
- var que: Set<string>;
94
- var count: number;
95
- }
96
- /**
97
- * Injects css and creates unique class names
98
- *
99
- * - Skips if already added
100
- *
101
- * @param css - string or template string, to be injected
102
- * @returns a unique class name
103
- */
104
- declare function createClass(...p: TemplateStringProps): string;
105
- declare namespace createClass {
106
- var count: number;
107
- var history: Map<string, string>;
108
- }
109
-
110
- export { ShorthandProps, TemplateStringProps, addCss, classJoin, createClass as default, shorthandProps, shorthandPropsMap, t2s };
1
+ export { ShorthandProps, TemplateStringProps, addCss, breakPoints, classJoin, createClass, createClass as css, shorthandProps, shorthandPropsMap, t2s } from './core.js';
package/src/index.js CHANGED
@@ -1,17 +1,17 @@
1
- var a=["30em","48em","62em","80em","96em"];function h(...r){return r.filter(n=>n&&typeof n=="string").join(" ")}function d(r){return r.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm,"")}function l(r){return r.includes("[")?r.split(`
2
- `).map(n=>{var s;let[t,o,e]=(s=[...n.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)][0])!=null?s:[];return e?e.split(",").map((i,g)=>(i=i.trim(),!i||i==="null"||i==="undefined"?"":g===0?`${o}: ${i};`:`@media (min-width: ${a[g-1]}) { ${o}: ${i}; }`)).join(`
1
+ var g=["30em","48em","62em","80em","96em"];function y(...r){return r.filter(n=>n&&typeof n=="string").join(" ")}function a(r){return r.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm,"")}function d(r){return r.includes("[")?r.split(`
2
+ `).map(n=>{var e;let[,t,s]=(e=[...n.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)][0])!=null?e:[];return s?s.split(",").map((i,o)=>(i=i.trim(),!i||i==="null"||i==="undefined"?"":o===0?`${t}: ${i};`:`@media (min-width: ${g[o-1]}) { ${t}: ${i}; }`)).join(`
3
3
  `):n}).join(`
4
- `):r}var p={ai:"align-items",b:"border",br:"border-radius",bg:"background",c:"color",d:"display",f:"flex",fd:"flex-direction",i:"inset",h:"height",jc:"justify-content",m:"margin",ml:"margin-left",mr:"margin-right",mt:"margin-top",mb:"margin-bottom",maxW:"max-width",minW:"min-width",p:"padding",pl:"padding-left",pr:"padding-right",pt:"padding-top",pb:"padding-bottom",pos:"position",ta:"text-align",w:"width",z:"z-index"},x=[...Object.keys(p),"mx","my","px","py"];function f(r){return r=`
4
+ `):r}var p={ai:"align-items",b:"border",br:"border-radius",bg:"background",c:"color",d:"display",f:"flex",fd:"flex-direction",i:"inset",h:"height",jc:"justify-content",m:"margin",ml:"margin-left",mr:"margin-right",mt:"margin-top",mb:"margin-bottom",maxW:"max-width",minW:"min-width",p:"padding",pl:"padding-left",pr:"padding-right",pt:"padding-top",pb:"padding-bottom",pos:"position",ta:"text-align",w:"width",z:"z-index"},x=[...Object.keys(p),"mx","my","px","py"];function l(r){return r=`
5
5
  `+r,r=r.replace(/([mp])x:([^;]*)/g,`$1l:$2;
6
6
  $1r:$2`).replace(/([mp])y:([^;]*);/g,`$1t:$2;
7
7
  $1b:$2`),Object.entries(p).forEach(([n,t])=>{r=r.replace(new RegExp(`([
8
- ;])${n}:`,"g"),`$1${t}:`)}),r.trim()}function b(r){let n=[];for(let t of r.matchAll(/[@&]/gm)){let o="",e=0,s=0;for(let i=t.index;i<r.length;i++)if(r[i]==="{")s===0&&(o=r.slice(t.index,i).trim(),e=i+1),s++;else if(r[i]==="}"&&(s--,s===0)){n.push({start:t.index,end:i+1,query:o,outerBody:r.slice(t.index,i+1),innerBody:r.slice(e,i)});break}s!==0&&console.error(`${o} not closed: "${r}"`)}return n}function c(r){return r.split(`
8
+ ;])${n}:`,"g"),`$1${t}:`)}),r.trim()}function f(r){let n=[];for(let t of r.matchAll(/[@&]/gm)){let s="",e=0,i=0;for(let o=t.index;o<r.length;o++)if(r[o]==="{")i===0&&(s=r.slice(t.index,o).trim(),e=o+1),i++;else if(r[o]==="}"&&(i--,i===0)){n.push({start:t.index,end:o+1,query:s,outerBody:r.slice(t.index,o+1),innerBody:r.slice(e,o)});break}i!==0&&console.error(`${s} not closed: "${r}"`)}return n}function c(r){return r.split(`
9
9
  `).map(n=>n.trim()).filter(n=>n).join(`
10
- `)}function y(...r){let[n,...t]=r;return typeof n=="string"?n:n.map((o,e)=>{var s;return o+((s=t==null?void 0:t[e])!=null?s:"")}).join("")}function m(r){m.que.add(r),setTimeout(()=>{let n=[...m.que].join(`
11
- `);if(n){m.que.clear();let t=document.createElement("style");t.id=`u${m.count++}`,t.innerHTML=n,document.head.appendChild(t)}},0)}m.que=new Set;m.count=0;function u(...r){let n=y(...r);if(!n)return"";let t=u.history.get(n);if(!t){t="s"+u.count++,u.history.set(n,t),n=d(n),n=f(n),n=l(n);let o=b(n);for(let e of o.reverse())n=n.slice(0,e.start)+n.slice(e.end);n=`.${t}{
10
+ `)}function b(...r){let[n,...t]=r;return typeof n=="string"?n:n.map((s,e)=>{var i;return s+((i=t==null?void 0:t[e])!=null?i:"")}).join("")}function m(r){m.que.add(r),setTimeout(()=>{let n=[...m.que].join(`
11
+ `);if(n){m.que.clear();let t=document.createElement("style");t.id=`u${m.count++}`,t.innerHTML=n,document.head.appendChild(t)}},0)}m.que=new Set;m.count=0;function u(...r){let n=b(...r);if(!n)return"";let t=u.history.get(n);if(!t){t="s"+u.count++,u.history.set(n,t),n=a(n),n=l(n),n=d(n);let s=f(n);for(let e of s.reverse())n=n.slice(0,e.start)+n.slice(e.end);n=`.${t}{
12
12
  ${n}
13
13
  }
14
- `,n+=o.map(e=>e.query.startsWith("&")?`.${t}${e.query.slice(1)}{
14
+ `,n+=s.map(e=>e.query.startsWith("&")?`.${t}${e.query.slice(1)}{
15
15
  ${e.innerBody}
16
16
  }`:e.query.startsWith("@keyframes")?e.outerBody:`${e.query}{
17
17
  .${t}{${e.innerBody}
@@ -19,5 +19,5 @@ ${e.innerBody}
19
19
  }`).join(`
20
20
  `),n=c(n)+`
21
21
 
22
- `,m(n)}return t}u.count=0;u.history=new Map;export{m as addCss,h as classJoin,u as default,x as shorthandProps,p as shorthandPropsMap,y as t2s};
22
+ `,m(n)}return t}u.count=0;u.history=new Map;export{m as addCss,g as breakPoints,y as classJoin,u as createClass,u as css,x as shorthandProps,p as shorthandPropsMap,b as t2s};
23
23
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["/** Breakpoints like chakra */\nconst breakPoints = ['30em', '48em', '62em', '80em', '96em']\n\n/** Joins class names and filters out blanks */\nexport function classJoin(...classes: any[]) {\n return classes.filter((c) => c && typeof c === 'string').join(' ')\n}\n\n// delete css comments i.e. {/* blah */}\nfunction deleteComments(css: string) {\n return css.replace(/{\\/\\*[\\s\\S]*?(?=\\*\\/})\\*\\/}/gm, '')\n}\n\n/**\n * Expands array values into media queries\n *\n * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles\n */\nfunction expandArrayValues(css: string) {\n if (!css.includes('[')) return css\n return css\n .split('\\n')\n .map((l) => {\n const [_, prop, vals] = [...l.matchAll(/([A-Za-z\\-]*):[ ]*\\[([^\\]]+)\\]/g)]?.[0] ?? []\n if (vals) {\n return vals\n .split(',')\n .map((val, i) => {\n val = val.trim()\n if (!val || val === 'null' || val === 'undefined') return ''\n if (i === 0) {\n return `${prop}: ${val};`\n }\n return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`\n })\n .join('\\n')\n }\n return l\n })\n .join('\\n')\n}\n\nexport interface ShorthandProps {\n /** shorthand for css:align-items */\n ai?: string\n /** shorthand for css:border */\n b?: string | number\n /** shorthand for css:border-radius */\n br?: string | number\n /** shorthand for css:background */\n bg?: string\n /** shorthand for css:color */\n c?: string\n /** shorthand for css:display */\n d?: string\n /** shorthand for css:flex */\n f?: string\n /** shorthand for css:flex-direction */\n fd?: string\n /** shorthand for css:height */\n h?: number | string\n /** shorthand for css:inset */\n i?: number | string\n /** shorthand for css:justify-content */\n jc?: string\n /** shorthand for css:margin */\n m?: number | string\n /** shorthand for css:margin-left */\n ml?: number | string\n /** shorthand for css:margin-right */\n mr?: number | string\n /** shorthand for css:margin-top */\n mt?: number | string\n /** shorthand for css:margin-bottom */\n mb?: number | string\n /** shorthand for css:margin-top & margin-bottom */\n my?: number | string\n /** shorthand for css:margin-left & margin-right */\n mx?: number | string\n /** shorthand for css:max-width */\n maxW?: number | string\n /** shorthand for css:min-width */\n minW?: number | string\n /** shorthand for css:padding */\n p?: number | string\n /** shorthand for css:padding-left */\n pl?: number | string\n /** shorthand for css:padding-right */\n pr?: number | string\n /** shorthand for css:padding-top */\n pt?: number | string\n /** shorthand for css:padding-bottom */\n pb?: number | string\n /** shorthand for css:padding-top & padding-bottom */\n py?: number | string\n /** shorthand for css:padding-left & padding-right */\n px?: number | string\n /** shorthand for css:position */\n pos?: number | string\n /** shorthand for css:text-align */\n ta?: string\n /** shorthand for css:width */\n w?: number | string\n /** shorthand for css:z-index */\n z?: number | string\n}\nexport const shorthandPropsMap: Record<keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>, string> = {\n ai: 'align-items',\n b: 'border',\n br: 'border-radius',\n bg: 'background',\n c: 'color',\n d: 'display',\n f: 'flex',\n fd: 'flex-direction',\n i: 'inset',\n h: 'height',\n jc: 'justify-content',\n m: 'margin',\n ml: 'margin-left',\n mr: 'margin-right',\n mt: 'margin-top',\n mb: 'margin-bottom',\n maxW: 'max-width',\n minW: 'min-width',\n p: 'padding',\n pl: 'padding-left',\n pr: 'padding-right',\n pt: 'padding-top',\n pb: 'padding-bottom',\n pos: 'position',\n ta: 'text-align',\n w: 'width',\n z: 'z-index',\n}\nexport const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']\n\n/** Expand short-hand css props to full */\nfunction expandProps(css: string) {\n css = '\\n' + css // inject a newline to make the regex easier\n // Handle 'mx', 'my', 'px', 'py'\n css = css.replace(/([mp])x:([^;]*)/g, '$1l:$2;\\n$1r:$2').replace(/([mp])y:([^;]*);/g, '$1t:$2;\\n$1b:$2')\n Object.entries(shorthandPropsMap).forEach(([k, v]) => {\n css = css.replace(new RegExp(`([ \\n\\t;])${k}:`, 'g'), `$1${v}:`)\n })\n return css.trim()\n}\n\n/** Find @keyframes, @media, @container queries in css **/\nfunction findQueries(css: string) {\n const queries = []\n for (let m of css.matchAll(/[@&]/gm)) {\n let query = ''\n let bodyStart = 0\n let openCount = 0\n for (let i = m.index!; i < css.length; i++) {\n if (css[i] === '{') {\n if (openCount === 0) {\n query = css.slice(m.index, i).trim()\n bodyStart = i + 1\n }\n openCount++\n } else if (css[i] === '}') {\n openCount--\n if (openCount === 0) {\n queries.push({\n start: m.index,\n end: i + 1,\n query,\n outerBody: css.slice(m.index, i + 1),\n innerBody: css.slice(bodyStart, i),\n })\n break\n }\n }\n }\n if (openCount !== 0) console.error(`${query} not closed: \"${css}\"`)\n }\n return queries\n}\n\n/** Trims whitespace for every line */\nfunction trim(css: string) {\n return css\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l)\n .join('\\n')\n}\n\n/**\n * Assemble a string from a template string array and a list of placeholders.\n *\n * - If the first argument is a string, it is returned as is.\n *\n * i.e.\n * myFoo(...props: TemplateStringProps) => {\n * const inputStr = t2s(...props);\n * }\n * myFoo`hello ${name}` => 'hello world'\n * myFoo(`hello ${name}`) => 'hello world'\n */\nexport function t2s(...tsp: TemplateStringProps) {\n const [s, ...p] = tsp\n return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')\n}\nexport type TemplateStringProps = [strings: TemplateStringsArray | string, ...placeHolders: string[]]\n\n/**\n * Injects css to the page\n *\n * - Batches adds for performance\n *\n * @param css - css to be injected\n * @returns void\n */\nexport function addCss(css: string) {\n addCss.que.add(css)\n setTimeout(() => {\n const css = [...addCss.que].join('\\n')\n if (css) {\n addCss.que.clear()\n const s = document.createElement('style')\n s.id = `u${addCss.count++}`\n s.innerHTML = css\n document.head.appendChild(s)\n }\n }, 0)\n}\naddCss.que = new Set<string>()\naddCss.count = 0\n\n/**\n * Injects css and creates unique class names\n *\n * - Skips if already added\n *\n * @param css - string or template string, to be injected\n * @returns a unique class name\n */\nexport default function createClass(...p: TemplateStringProps) {\n let css = t2s(...p)\n if (!css) return ''\n let className = createClass.history.get(css)\n if (!className) {\n className = 's' + createClass.count++\n createClass.history.set(css, className)\n\n css = deleteComments(css)\n css = expandProps(css)\n css = expandArrayValues(css)\n const qs = findQueries(css)\n\n for (let q of qs.reverse()) {\n css = css.slice(0, q.start) + css.slice(q.end)\n }\n\n css = `.${className}{\\n${css}\\n}\\n`\n css += qs\n .map((q) => {\n if (q.query.startsWith('&')) {\n return `.${className}${q.query.slice(1)}{\\n${q.innerBody}\\n}`\n }\n if (q.query.startsWith('@keyframes')) {\n return q.outerBody\n }\n return `${q.query}{\\n.${className}{${q.innerBody}\\n}\\n}`\n })\n .join('\\n')\n\n css = trim(css) + '\\n\\n'\n\n addCss(css)\n }\n return className\n}\ncreateClass.count = 0\ncreateClass.history = new Map<string, string>()\n"],"mappings":"AACA,IAAMA,EAAc,CAAC,OAAQ,OAAQ,OAAQ,OAAQ,MAAM,EAGpD,SAASC,KAAaC,EAAgB,CAC3C,OAAOA,EAAQ,OAAQC,GAAMA,GAAK,OAAOA,GAAM,QAAQ,EAAE,KAAK,GAAG,CACnE,CAGA,SAASC,EAAeC,EAAa,CACnC,OAAOA,EAAI,QAAQ,gCAAiC,EAAE,CACxD,CAOA,SAASC,EAAkBD,EAAa,CACtC,OAAKA,EAAI,SAAS,GAAG,EACdA,EACJ,MAAM;AAAA,CAAI,EACV,IAAKE,GAAM,CAtBhB,IAAAC,EAuBM,GAAM,CAACC,EAAGC,EAAMC,CAAI,GAAIH,EAAA,CAAC,GAAGD,EAAE,SAAS,iCAAiC,CAAC,EAAI,KAArD,KAAAC,EAA2D,CAAC,EACpF,OAAIG,EACKA,EACJ,MAAM,GAAG,EACT,IAAI,CAACC,EAAKC,KACTD,EAAMA,EAAI,KAAK,EACX,CAACA,GAAOA,IAAQ,QAAUA,IAAQ,YAAoB,GACtDC,IAAM,EACD,GAAGH,MAASE,KAEd,sBAAsBZ,EAAYa,EAAI,SAASH,MAASE,OAChE,EACA,KAAK;AAAA,CAAI,EAEPL,CACT,CAAC,EACA,KAAK;AAAA,CAAI,EApBmBF,CAqBjC,CAkEO,IAAMS,EAA2F,CACtG,GAAI,cACJ,EAAG,SACH,GAAI,gBACJ,GAAI,aACJ,EAAG,QACH,EAAG,UACH,EAAG,OACH,GAAI,iBACJ,EAAG,QACH,EAAG,SACH,GAAI,kBACJ,EAAG,SACH,GAAI,cACJ,GAAI,eACJ,GAAI,aACJ,GAAI,gBACJ,KAAM,YACN,KAAM,YACN,EAAG,UACH,GAAI,eACJ,GAAI,gBACJ,GAAI,cACJ,GAAI,iBACJ,IAAK,WACL,GAAI,aACJ,EAAG,QACH,EAAG,SACL,EACaC,EAAiB,CAAC,GAAG,OAAO,KAAKD,CAAiB,EAAG,KAAM,KAAM,KAAM,IAAI,EAGxF,SAASE,EAAYX,EAAa,CAChC,OAAAA,EAAM;AAAA,EAAOA,EAEbA,EAAMA,EAAI,QAAQ,mBAAoB;AAAA,OAAiB,EAAE,QAAQ,oBAAqB;AAAA,OAAiB,EACvG,OAAO,QAAQS,CAAiB,EAAE,QAAQ,CAAC,CAACG,EAAGC,CAAC,IAAM,CACpDb,EAAMA,EAAI,QAAQ,IAAI,OAAO;AAAA,MAAaY,KAAM,GAAG,EAAG,KAAKC,IAAI,CACjE,CAAC,EACMb,EAAI,KAAK,CAClB,CAGA,SAASc,EAAYd,EAAa,CAChC,IAAMe,EAAU,CAAC,EACjB,QAASC,KAAKhB,EAAI,SAAS,QAAQ,EAAG,CACpC,IAAIiB,EAAQ,GACRC,EAAY,EACZC,EAAY,EAChB,QAAS,EAAIH,EAAE,MAAQ,EAAIhB,EAAI,OAAQ,IACrC,GAAIA,EAAI,KAAO,IACTmB,IAAc,IAChBF,EAAQjB,EAAI,MAAMgB,EAAE,MAAO,CAAC,EAAE,KAAK,EACnCE,EAAY,EAAI,GAElBC,YACSnB,EAAI,KAAO,MACpBmB,IACIA,IAAc,GAAG,CACnBJ,EAAQ,KAAK,CACX,MAAOC,EAAE,MACT,IAAK,EAAI,EACT,MAAAC,EACA,UAAWjB,EAAI,MAAMgB,EAAE,MAAO,EAAI,CAAC,EACnC,UAAWhB,EAAI,MAAMkB,EAAW,CAAC,CACnC,CAAC,EACD,KACF,CAGAC,IAAc,GAAG,QAAQ,MAAM,GAAGF,kBAAsBjB,IAAM,CACpE,CACA,OAAOe,CACT,CAGA,SAASK,EAAKpB,EAAa,CACzB,OAAOA,EACJ,MAAM;AAAA,CAAI,EACV,IAAKE,GAAMA,EAAE,KAAK,CAAC,EACnB,OAAQA,GAAMA,CAAC,EACf,KAAK;AAAA,CAAI,CACd,CAcO,SAASmB,KAAOC,EAA0B,CAC/C,GAAM,CAACC,KAAMC,CAAC,EAAIF,EAClB,OAAO,OAAOC,GAAM,SAAWA,EAAIA,EAAE,IAAI,CAACA,EAAGf,IAAG,CA5MlD,IAAAL,EA4MqD,OAAAoB,IAAKpB,EAAAqB,GAAA,YAAAA,EAAIhB,KAAJ,KAAAL,EAAU,IAAG,EAAE,KAAK,EAAE,CAChF,CAWO,SAASsB,EAAOzB,EAAa,CAClCyB,EAAO,IAAI,IAAIzB,CAAG,EAClB,WAAW,IAAM,CACf,IAAMA,EAAM,CAAC,GAAGyB,EAAO,GAAG,EAAE,KAAK;AAAA,CAAI,EACrC,GAAIzB,EAAK,CACPyB,EAAO,IAAI,MAAM,EACjB,IAAMF,EAAI,SAAS,cAAc,OAAO,EACxCA,EAAE,GAAK,IAAIE,EAAO,UAClBF,EAAE,UAAYvB,EACd,SAAS,KAAK,YAAYuB,CAAC,CAC7B,CACF,EAAG,CAAC,CACN,CACAE,EAAO,IAAM,IAAI,IACjBA,EAAO,MAAQ,EAUA,SAARC,KAAgCF,EAAwB,CAC7D,IAAIxB,EAAMqB,EAAI,GAAGG,CAAC,EAClB,GAAI,CAACxB,EAAK,MAAO,GACjB,IAAI2B,EAAYD,EAAY,QAAQ,IAAI1B,CAAG,EAC3C,GAAI,CAAC2B,EAAW,CACdA,EAAY,IAAMD,EAAY,QAC9BA,EAAY,QAAQ,IAAI1B,EAAK2B,CAAS,EAEtC3B,EAAMD,EAAeC,CAAG,EACxBA,EAAMW,EAAYX,CAAG,EACrBA,EAAMC,EAAkBD,CAAG,EAC3B,IAAM4B,EAAKd,EAAYd,CAAG,EAE1B,QAAS6B,KAAKD,EAAG,QAAQ,EACvB5B,EAAMA,EAAI,MAAM,EAAG6B,EAAE,KAAK,EAAI7B,EAAI,MAAM6B,EAAE,GAAG,EAG/C7B,EAAM,IAAI2B;AAAA,EAAe3B;AAAA;AAAA,EACzBA,GAAO4B,EACJ,IAAKC,GACAA,EAAE,MAAM,WAAW,GAAG,EACjB,IAAIF,IAAYE,EAAE,MAAM,MAAM,CAAC;AAAA,EAAOA,EAAE;AAAA,GAE7CA,EAAE,MAAM,WAAW,YAAY,EAC1BA,EAAE,UAEJ,GAAGA,EAAE;AAAA,GAAYF,KAAaE,EAAE;AAAA;AAAA,EACxC,EACA,KAAK;AAAA,CAAI,EAEZ7B,EAAMoB,EAAKpB,CAAG,EAAI;AAAA;AAAA,EAElByB,EAAOzB,CAAG,CACZ,CACA,OAAO2B,CACT,CACAD,EAAY,MAAQ,EACpBA,EAAY,QAAU,IAAI","names":["breakPoints","classJoin","classes","c","deleteComments","css","expandArrayValues","l","_a","_","prop","vals","val","i","shorthandPropsMap","shorthandProps","expandProps","k","v","findQueries","queries","m","query","bodyStart","openCount","trim","t2s","tsp","s","p","addCss","createClass","className","qs","q"]}
1
+ {"version":3,"sources":["core.ts"],"sourcesContent":["/** Breakpoints like chakra */\nexport const breakPoints = ['30em', '48em', '62em', '80em', '96em']\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype allowableAny = any\n\n/** Joins class names and filters out blanks */\nexport function classJoin(...classes: allowableAny[]) {\n return classes.filter(c => c && typeof c === 'string').join(' ')\n}\n\n/** delete css comments **/\nfunction deleteComments(css: string) {\n return css.replace(/{\\/\\*[\\s\\S]*?(?=\\*\\/})\\*\\/}/gm, '')\n}\n\n/**\n * Expands array values into media queries\n *\n * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles\n */\nfunction expandArrayValues(css: string) {\n if (!css.includes('[')) return css\n return css\n .split('\\n')\n .map(l => {\n // eslint-disable-next-line no-useless-escape\n const [, prop, vals] = [...l.matchAll(/([A-Za-z\\-]*):[ ]*\\[([^\\]]+)\\]/g)]?.[0] ?? []\n if (vals) {\n return vals\n .split(',')\n .map((val, i) => {\n val = val.trim()\n if (!val || val === 'null' || val === 'undefined') return ''\n if (i === 0) {\n return `${prop}: ${val};`\n }\n return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`\n })\n .join('\\n')\n }\n return l\n })\n .join('\\n')\n}\n\nexport interface ShorthandProps {\n /** shorthand for css:align-items */\n ai?: string\n /** shorthand for css:border */\n b?: string | number\n /** shorthand for css:border-radius */\n br?: string | number\n /** shorthand for css:background */\n bg?: string\n /** shorthand for css:color */\n c?: string\n /** shorthand for css:display */\n d?: string\n /** shorthand for css:flex */\n f?: string\n /** shorthand for css:flex-direction */\n fd?: string\n /** shorthand for css:height */\n h?: number | string\n /** shorthand for css:inset */\n i?: number | string\n /** shorthand for css:justify-content */\n jc?: string\n /** shorthand for css:margin */\n m?: number | string\n /** shorthand for css:margin-left */\n ml?: number | string\n /** shorthand for css:margin-right */\n mr?: number | string\n /** shorthand for css:margin-top */\n mt?: number | string\n /** shorthand for css:margin-bottom */\n mb?: number | string\n /** shorthand for css:margin-top & margin-bottom */\n my?: number | string\n /** shorthand for css:margin-left & margin-right */\n mx?: number | string\n /** shorthand for css:max-width */\n maxW?: number | string\n /** shorthand for css:min-width */\n minW?: number | string\n /** shorthand for css:padding */\n p?: number | string\n /** shorthand for css:padding-left */\n pl?: number | string\n /** shorthand for css:padding-right */\n pr?: number | string\n /** shorthand for css:padding-top */\n pt?: number | string\n /** shorthand for css:padding-bottom */\n pb?: number | string\n /** shorthand for css:padding-top & padding-bottom */\n py?: number | string\n /** shorthand for css:padding-left & padding-right */\n px?: number | string\n /** shorthand for css:position */\n pos?: number | string\n /** shorthand for css:text-align */\n ta?: string\n /** shorthand for css:width */\n w?: number | string\n /** shorthand for css:z-index */\n z?: number | string\n}\nexport const shorthandPropsMap: Record<\n keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>,\n string\n> = {\n ai: 'align-items',\n b: 'border',\n br: 'border-radius',\n bg: 'background',\n c: 'color',\n d: 'display',\n f: 'flex',\n fd: 'flex-direction',\n i: 'inset',\n h: 'height',\n jc: 'justify-content',\n m: 'margin',\n ml: 'margin-left',\n mr: 'margin-right',\n mt: 'margin-top',\n mb: 'margin-bottom',\n maxW: 'max-width',\n minW: 'min-width',\n p: 'padding',\n pl: 'padding-left',\n pr: 'padding-right',\n pt: 'padding-top',\n pb: 'padding-bottom',\n pos: 'position',\n ta: 'text-align',\n w: 'width',\n z: 'z-index',\n}\nexport const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']\n\n/** Expand short-hand css props to full */\nfunction expandProps(css: string) {\n css = '\\n' + css // inject a newline to make the regex easier\n // Handle 'mx', 'my', 'px', 'py'\n css = css\n .replace(/([mp])x:([^;]*)/g, '$1l:$2;\\n$1r:$2')\n .replace(/([mp])y:([^;]*);/g, '$1t:$2;\\n$1b:$2')\n Object.entries(shorthandPropsMap).forEach(([k, v]) => {\n css = css.replace(new RegExp(`([ \\n\\t;])${k}:`, 'g'), `$1${v}:`)\n })\n return css.trim()\n}\n\n/** Find @keyframes, @media, @container queries in css **/\nfunction findQueries(css: string) {\n const queries = []\n for (const m of css.matchAll(/[@&]/gm)) {\n let query = ''\n let bodyStart = 0\n let openCount = 0\n for (let i = m.index!; i < css.length; i++) {\n if (css[i] === '{') {\n if (openCount === 0) {\n query = css.slice(m.index, i).trim()\n bodyStart = i + 1\n }\n openCount++\n } else if (css[i] === '}') {\n openCount--\n if (openCount === 0) {\n queries.push({\n start: m.index,\n end: i + 1,\n query,\n outerBody: css.slice(m.index, i + 1),\n innerBody: css.slice(bodyStart, i),\n })\n break\n }\n }\n }\n if (openCount !== 0) console.error(`${query} not closed: \"${css}\"`)\n }\n return queries\n}\n\n/** Trims whitespace for every line */\nfunction trim(css: string) {\n return css\n .split('\\n')\n .map(l => l.trim())\n .filter(l => l)\n .join('\\n')\n}\n\n/**\n * Assemble a string from a template string array and a list of placeholders.\n *\n * - If the first argument is a string, it is returned as is.\n *\n * i.e.\n * myFoo(...props: TemplateStringProps) => {\n * const inputStr = t2s(...props);\n * }\n * myFoo`hello ${name}` => 'hello world'\n * myFoo(`hello ${name}`) => 'hello world'\n */\nexport function t2s(...tsp: TemplateStringProps) {\n const [s, ...p] = tsp\n return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')\n}\nexport type TemplateStringProps = [\n strings: TemplateStringsArray | string,\n ...placeHolders: string[]\n]\n\n/**\n * Injects css to the page\n *\n * - Batches adds for performance\n *\n * @param css - css to be injected\n * @returns void\n */\nexport function addCss(css: string) {\n addCss.que.add(css)\n setTimeout(() => {\n const css = [...addCss.que].join('\\n')\n if (css) {\n addCss.que.clear()\n const s = document.createElement('style')\n s.id = `u${addCss.count++}`\n s.innerHTML = css\n document.head.appendChild(s)\n }\n }, 0)\n}\naddCss.que = new Set<string>()\naddCss.count = 0\n\n/**\n * Injects css and creates unique class names\n *\n * - Skips if already added\n *\n * @param css - string or template string, to be injected\n * @returns a unique class name\n */\nexport function createClass(...p: TemplateStringProps) {\n let css = t2s(...p)\n if (!css) return ''\n let className = createClass.history.get(css)\n if (!className) {\n className = 's' + createClass.count++\n createClass.history.set(css, className)\n\n css = deleteComments(css)\n css = expandProps(css)\n css = expandArrayValues(css)\n const qs = findQueries(css)\n\n for (const q of qs.reverse()) {\n css = css.slice(0, q.start) + css.slice(q.end)\n }\n\n css = `.${className}{\\n${css}\\n}\\n`\n css += qs\n .map(q => {\n if (q.query.startsWith('&')) {\n return `.${className}${q.query.slice(1)}{\\n${q.innerBody}\\n}`\n }\n if (q.query.startsWith('@keyframes')) {\n return q.outerBody\n }\n return `${q.query}{\\n.${className}{${q.innerBody}\\n}\\n}`\n })\n .join('\\n')\n\n css = trim(css) + '\\n\\n'\n\n addCss(css)\n }\n return className\n}\ncreateClass.count = 0\ncreateClass.history = new Map<string, string>()\n"],"mappings":"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","names":["breakPoints","classJoin","classes","c","deleteComments","css","expandArrayValues","l","_a","prop","vals","val","i","shorthandPropsMap","shorthandProps","expandProps","k","v","findQueries","queries","m","query","bodyStart","openCount","trim","t2s","tsp","s","p","addCss","createClass","className","qs","q"]}
package/src/index.ts CHANGED
@@ -1,278 +1,2 @@
1
- /** Breakpoints like chakra */
2
- const breakPoints = ['30em', '48em', '62em', '80em', '96em']
3
-
4
- /** Joins class names and filters out blanks */
5
- export function classJoin(...classes: any[]) {
6
- return classes.filter((c) => c && typeof c === 'string').join(' ')
7
- }
8
-
9
- // delete css comments i.e. {/* blah */}
10
- function deleteComments(css: string) {
11
- return css.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm, '')
12
- }
13
-
14
- /**
15
- * Expands array values into media queries
16
- *
17
- * Inspired by https://chakra-ui.com/docs/styled-system/responsive-styles
18
- */
19
- function expandArrayValues(css: string) {
20
- if (!css.includes('[')) return css
21
- return css
22
- .split('\n')
23
- .map((l) => {
24
- const [_, prop, vals] = [...l.matchAll(/([A-Za-z\-]*):[ ]*\[([^\]]+)\]/g)]?.[0] ?? []
25
- if (vals) {
26
- return vals
27
- .split(',')
28
- .map((val, i) => {
29
- val = val.trim()
30
- if (!val || val === 'null' || val === 'undefined') return ''
31
- if (i === 0) {
32
- return `${prop}: ${val};`
33
- }
34
- return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`
35
- })
36
- .join('\n')
37
- }
38
- return l
39
- })
40
- .join('\n')
41
- }
42
-
43
- export interface ShorthandProps {
44
- /** shorthand for css:align-items */
45
- ai?: string
46
- /** shorthand for css:border */
47
- b?: string | number
48
- /** shorthand for css:border-radius */
49
- br?: string | number
50
- /** shorthand for css:background */
51
- bg?: string
52
- /** shorthand for css:color */
53
- c?: string
54
- /** shorthand for css:display */
55
- d?: string
56
- /** shorthand for css:flex */
57
- f?: string
58
- /** shorthand for css:flex-direction */
59
- fd?: string
60
- /** shorthand for css:height */
61
- h?: number | string
62
- /** shorthand for css:inset */
63
- i?: number | string
64
- /** shorthand for css:justify-content */
65
- jc?: string
66
- /** shorthand for css:margin */
67
- m?: number | string
68
- /** shorthand for css:margin-left */
69
- ml?: number | string
70
- /** shorthand for css:margin-right */
71
- mr?: number | string
72
- /** shorthand for css:margin-top */
73
- mt?: number | string
74
- /** shorthand for css:margin-bottom */
75
- mb?: number | string
76
- /** shorthand for css:margin-top & margin-bottom */
77
- my?: number | string
78
- /** shorthand for css:margin-left & margin-right */
79
- mx?: number | string
80
- /** shorthand for css:max-width */
81
- maxW?: number | string
82
- /** shorthand for css:min-width */
83
- minW?: number | string
84
- /** shorthand for css:padding */
85
- p?: number | string
86
- /** shorthand for css:padding-left */
87
- pl?: number | string
88
- /** shorthand for css:padding-right */
89
- pr?: number | string
90
- /** shorthand for css:padding-top */
91
- pt?: number | string
92
- /** shorthand for css:padding-bottom */
93
- pb?: number | string
94
- /** shorthand for css:padding-top & padding-bottom */
95
- py?: number | string
96
- /** shorthand for css:padding-left & padding-right */
97
- px?: number | string
98
- /** shorthand for css:position */
99
- pos?: number | string
100
- /** shorthand for css:text-align */
101
- ta?: string
102
- /** shorthand for css:width */
103
- w?: number | string
104
- /** shorthand for css:z-index */
105
- z?: number | string
106
- }
107
- export const shorthandPropsMap: Record<keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>, string> = {
108
- ai: 'align-items',
109
- b: 'border',
110
- br: 'border-radius',
111
- bg: 'background',
112
- c: 'color',
113
- d: 'display',
114
- f: 'flex',
115
- fd: 'flex-direction',
116
- i: 'inset',
117
- h: 'height',
118
- jc: 'justify-content',
119
- m: 'margin',
120
- ml: 'margin-left',
121
- mr: 'margin-right',
122
- mt: 'margin-top',
123
- mb: 'margin-bottom',
124
- maxW: 'max-width',
125
- minW: 'min-width',
126
- p: 'padding',
127
- pl: 'padding-left',
128
- pr: 'padding-right',
129
- pt: 'padding-top',
130
- pb: 'padding-bottom',
131
- pos: 'position',
132
- ta: 'text-align',
133
- w: 'width',
134
- z: 'z-index',
135
- }
136
- export const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py']
137
-
138
- /** Expand short-hand css props to full */
139
- function expandProps(css: string) {
140
- css = '\n' + css // inject a newline to make the regex easier
141
- // Handle 'mx', 'my', 'px', 'py'
142
- css = css.replace(/([mp])x:([^;]*)/g, '$1l:$2;\n$1r:$2').replace(/([mp])y:([^;]*);/g, '$1t:$2;\n$1b:$2')
143
- Object.entries(shorthandPropsMap).forEach(([k, v]) => {
144
- css = css.replace(new RegExp(`([ \n\t;])${k}:`, 'g'), `$1${v}:`)
145
- })
146
- return css.trim()
147
- }
148
-
149
- /** Find @keyframes, @media, @container queries in css **/
150
- function findQueries(css: string) {
151
- const queries = []
152
- for (let m of css.matchAll(/[@&]/gm)) {
153
- let query = ''
154
- let bodyStart = 0
155
- let openCount = 0
156
- for (let i = m.index!; i < css.length; i++) {
157
- if (css[i] === '{') {
158
- if (openCount === 0) {
159
- query = css.slice(m.index, i).trim()
160
- bodyStart = i + 1
161
- }
162
- openCount++
163
- } else if (css[i] === '}') {
164
- openCount--
165
- if (openCount === 0) {
166
- queries.push({
167
- start: m.index,
168
- end: i + 1,
169
- query,
170
- outerBody: css.slice(m.index, i + 1),
171
- innerBody: css.slice(bodyStart, i),
172
- })
173
- break
174
- }
175
- }
176
- }
177
- if (openCount !== 0) console.error(`${query} not closed: "${css}"`)
178
- }
179
- return queries
180
- }
181
-
182
- /** Trims whitespace for every line */
183
- function trim(css: string) {
184
- return css
185
- .split('\n')
186
- .map((l) => l.trim())
187
- .filter((l) => l)
188
- .join('\n')
189
- }
190
-
191
- /**
192
- * Assemble a string from a template string array and a list of placeholders.
193
- *
194
- * - If the first argument is a string, it is returned as is.
195
- *
196
- * i.e.
197
- * myFoo(...props: TemplateStringProps) => {
198
- * const inputStr = t2s(...props);
199
- * }
200
- * myFoo`hello ${name}` => 'hello world'
201
- * myFoo(`hello ${name}`) => 'hello world'
202
- */
203
- export function t2s(...tsp: TemplateStringProps) {
204
- const [s, ...p] = tsp
205
- return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('')
206
- }
207
- export type TemplateStringProps = [strings: TemplateStringsArray | string, ...placeHolders: string[]]
208
-
209
- /**
210
- * Injects css to the page
211
- *
212
- * - Batches adds for performance
213
- *
214
- * @param css - css to be injected
215
- * @returns void
216
- */
217
- export function addCss(css: string) {
218
- addCss.que.add(css)
219
- setTimeout(() => {
220
- const css = [...addCss.que].join('\n')
221
- if (css) {
222
- addCss.que.clear()
223
- const s = document.createElement('style')
224
- s.id = `u${addCss.count++}`
225
- s.innerHTML = css
226
- document.head.appendChild(s)
227
- }
228
- }, 0)
229
- }
230
- addCss.que = new Set<string>()
231
- addCss.count = 0
232
-
233
- /**
234
- * Injects css and creates unique class names
235
- *
236
- * - Skips if already added
237
- *
238
- * @param css - string or template string, to be injected
239
- * @returns a unique class name
240
- */
241
- export default function createClass(...p: TemplateStringProps) {
242
- let css = t2s(...p)
243
- if (!css) return ''
244
- let className = createClass.history.get(css)
245
- if (!className) {
246
- className = 's' + createClass.count++
247
- createClass.history.set(css, className)
248
-
249
- css = deleteComments(css)
250
- css = expandProps(css)
251
- css = expandArrayValues(css)
252
- const qs = findQueries(css)
253
-
254
- for (let q of qs.reverse()) {
255
- css = css.slice(0, q.start) + css.slice(q.end)
256
- }
257
-
258
- css = `.${className}{\n${css}\n}\n`
259
- css += qs
260
- .map((q) => {
261
- if (q.query.startsWith('&')) {
262
- return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`
263
- }
264
- if (q.query.startsWith('@keyframes')) {
265
- return q.outerBody
266
- }
267
- return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`
268
- })
269
- .join('\n')
270
-
271
- css = trim(css) + '\n\n'
272
-
273
- addCss(css)
274
- }
275
- return className
276
- }
277
- createClass.count = 0
278
- createClass.history = new Map<string, string>()
1
+ export * from './core.js'
2
+ export {createClass as css} from './core.js'