@slimr/css 2.1.11 → 2.1.14

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.
Files changed (43) hide show
  1. package/README.md +58 -50
  2. package/cjs/addCss.d.ts +23 -0
  3. package/cjs/addCss.js +38 -0
  4. package/cjs/addCss.js.map +1 -0
  5. package/cjs/addCss.ts +33 -0
  6. package/cjs/createClass.d.ts +43 -0
  7. package/cjs/{src/createClass.js → createClass.js} +78 -132
  8. package/cjs/createClass.js.map +1 -0
  9. package/cjs/createClass.ts +82 -211
  10. package/{esm/src → cjs}/index.d.ts +1 -0
  11. package/cjs/{src/index.js → index.js} +1 -0
  12. package/cjs/index.js.map +1 -0
  13. package/cjs/index.ts +1 -0
  14. package/cjs/{src/createClass.d.ts → shorthandProps.d.ts} +7 -47
  15. package/cjs/shorthandProps.js +51 -0
  16. package/cjs/shorthandProps.js.map +1 -0
  17. package/cjs/shorthandProps.ts +118 -0
  18. package/esm/addCss.d.ts +23 -0
  19. package/esm/addCss.js +34 -0
  20. package/esm/addCss.js.map +1 -0
  21. package/esm/addCss.ts +33 -0
  22. package/esm/createClass.d.ts +43 -0
  23. package/esm/{src/createClass.js → createClass.js} +76 -128
  24. package/esm/createClass.js.map +1 -0
  25. package/esm/createClass.ts +82 -211
  26. package/{cjs/src → esm}/index.d.ts +1 -0
  27. package/esm/{src/index.js → index.js} +1 -0
  28. package/esm/index.js.map +1 -0
  29. package/esm/index.ts +1 -0
  30. package/esm/{src/createClass.d.ts → shorthandProps.d.ts} +7 -47
  31. package/esm/shorthandProps.js +47 -0
  32. package/esm/shorthandProps.js.map +1 -0
  33. package/esm/shorthandProps.ts +118 -0
  34. package/package.json +4 -1
  35. package/src/addCss.ts +33 -0
  36. package/src/createClass.ts +82 -211
  37. package/src/index.ts +1 -0
  38. package/src/shorthandProps.ts +118 -0
  39. package/tsconfig.json +1 -1
  40. package/cjs/src/createClass.js.map +0 -1
  41. package/cjs/src/index.js.map +0 -1
  42. package/esm/src/createClass.js.map +0 -1
  43. package/esm/src/index.js.map +0 -1
@@ -0,0 +1,43 @@
1
+ import { T2SProps } from '@slimr/util';
2
+ /**
3
+ * Joins class names and omits falsey props
4
+ *
5
+ * @param classes
6
+ * class names to be joined
7
+ *
8
+ * @returns a string of joined class names
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * classJoin('a', 'b', 'c') // 'a b c'
13
+ * classJoin('a', 0, 'b', null, 'c') // 'a b c'
14
+ * ```
15
+ */
16
+ export declare function classJoin(...classes: (string | 0 | null | undefined)[]): string;
17
+ /**
18
+ * Upserts and returns a unique css class for a given css string
19
+ *
20
+ * @param cssString
21
+ * string or template string, to be injected. Shorthand props are supported (see Readme).
22
+ *
23
+ * @returns a unique class name
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * c1 = createClass('c: red;') // queues the create of new css class 's0'
28
+ * c2 = createClass('c: red;') // is duplicate so will return 's0'
29
+ * c3 = createClass`c: red;` // same
30
+ * c4 = css`c: red;` // same
31
+ * // c1 = c2 = c3 = c4
32
+ * <div className={css`c: red;`} /> // will resolve to 's0' like above
33
+ * c5 = css`c: blue;` // queues the create of new css class 's1'
34
+ * c6 = css`w: [100%, null, 400px]` // width = 100% on mobile and table, 400px on desktop
35
+ * ```
36
+ * ...and the queue will be executed next javascript tick
37
+ */
38
+ export declare function createClass(...p: T2SProps): string;
39
+ export declare namespace createClass {
40
+ var breakPoints: string[];
41
+ var count: number;
42
+ var history: Map<string, string>;
43
+ }
@@ -1,9 +1,80 @@
1
- /** Breakpoints like chakra */
2
- export const breakPoints = ['30em', '48em', '62em', '80em', '96em'];
3
- /** Joins class names and filters out blanks */
1
+ import { t2s } from '@slimr/util';
2
+ import { addCss } from './addCss.js';
3
+ import { expandShorthands } from './shorthandProps.js';
4
+ /**
5
+ * Joins class names and omits falsey props
6
+ *
7
+ * @param classes
8
+ * class names to be joined
9
+ *
10
+ * @returns a string of joined class names
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * classJoin('a', 'b', 'c') // 'a b c'
15
+ * classJoin('a', 0, 'b', null, 'c') // 'a b c'
16
+ * ```
17
+ */
4
18
  export function classJoin(...classes) {
5
19
  return classes.filter(c => c && typeof c === 'string').join(' ');
6
20
  }
21
+ /**
22
+ * Upserts and returns a unique css class for a given css string
23
+ *
24
+ * @param cssString
25
+ * string or template string, to be injected. Shorthand props are supported (see Readme).
26
+ *
27
+ * @returns a unique class name
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * c1 = createClass('c: red;') // queues the create of new css class 's0'
32
+ * c2 = createClass('c: red;') // is duplicate so will return 's0'
33
+ * c3 = createClass`c: red;` // same
34
+ * c4 = css`c: red;` // same
35
+ * // c1 = c2 = c3 = c4
36
+ * <div className={css`c: red;`} /> // will resolve to 's0' like above
37
+ * c5 = css`c: blue;` // queues the create of new css class 's1'
38
+ * c6 = css`w: [100%, null, 400px]` // width = 100% on mobile and table, 400px on desktop
39
+ * ```
40
+ * ...and the queue will be executed next javascript tick
41
+ */
42
+ export function createClass(...p) {
43
+ let css = t2s(...p);
44
+ if (!css)
45
+ return '';
46
+ let className = createClass.history.get(css);
47
+ if (!className) {
48
+ className = 's' + createClass.count++;
49
+ createClass.history.set(css, className);
50
+ css = deleteComments(css);
51
+ css = expandShorthands(css);
52
+ css = expandArrayValues(css);
53
+ const qs = findQueries(css);
54
+ for (const q of qs.reverse()) {
55
+ css = css.slice(0, q.start) + css.slice(q.end);
56
+ }
57
+ css = `.${className}{\n${css}\n}\n`;
58
+ css += qs
59
+ .map(q => {
60
+ if (q.query.startsWith('&')) {
61
+ return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`;
62
+ }
63
+ if (q.query.startsWith('@keyframes')) {
64
+ return q.outerBody;
65
+ }
66
+ return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`;
67
+ })
68
+ .join('\n');
69
+ css = trimByLine(css) + '\n\n';
70
+ addCss(css);
71
+ }
72
+ return className;
73
+ }
74
+ /** Breakpoints like chakra */
75
+ createClass.breakPoints = ['30em', '48em', '62em', '80em', '96em'];
76
+ createClass.count = 0;
77
+ createClass.history = new Map();
7
78
  /** delete css comments **/
8
79
  function deleteComments(css) {
9
80
  return css.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm, '');
@@ -31,7 +102,7 @@ function expandArrayValues(css) {
31
102
  if (i === 0) {
32
103
  return `${prop}: ${val};`;
33
104
  }
34
- return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`;
105
+ return `@media (min-width: ${createClass.breakPoints[i - 1]}) { ${prop}: ${val}; }`;
35
106
  })
36
107
  .join('\n');
37
108
  }
@@ -39,48 +110,6 @@ function expandArrayValues(css) {
39
110
  })
40
111
  .join('\n');
41
112
  }
42
- export const shorthandPropsMap = {
43
- ai: 'align-items',
44
- b: 'border',
45
- br: 'border-radius',
46
- bg: 'background',
47
- c: 'color',
48
- d: 'display',
49
- f: 'flex',
50
- fd: 'flex-direction',
51
- i: 'inset',
52
- h: 'height',
53
- jc: 'justify-content',
54
- m: 'margin',
55
- ml: 'margin-left',
56
- mr: 'margin-right',
57
- mt: 'margin-top',
58
- mb: 'margin-bottom',
59
- maxW: 'max-width',
60
- minW: 'min-width',
61
- p: 'padding',
62
- pl: 'padding-left',
63
- pr: 'padding-right',
64
- pt: 'padding-top',
65
- pb: 'padding-bottom',
66
- pos: 'position',
67
- ta: 'text-align',
68
- w: 'width',
69
- z: 'z-index',
70
- };
71
- export const shorthandProps = [...Object.keys(shorthandPropsMap), 'mx', 'my', 'px', 'py'];
72
- /** Expand short-hand css props to full */
73
- function expandProps(css) {
74
- css = '\n' + css; // inject a newline to make the regex easier
75
- // Handle 'mx', 'my', 'px', 'py'
76
- css = css
77
- .replace(/([mp])x:([^;]*)/g, '$1l:$2;\n$1r:$2')
78
- .replace(/([mp])y:([^;]*);/g, '$1t:$2;\n$1b:$2');
79
- Object.entries(shorthandPropsMap).forEach(([k, v]) => {
80
- css = css.replace(new RegExp(`([ \n\t;])${k}:`, 'g'), `$1${v}:`);
81
- });
82
- return css.trim();
83
- }
84
113
  /** Find @keyframes, @media, @container queries in css **/
85
114
  function findQueries(css) {
86
115
  const queries = [];
@@ -116,92 +145,11 @@ function findQueries(css) {
116
145
  return queries;
117
146
  }
118
147
  /** Trims whitespace for every line */
119
- function trim(css) {
148
+ function trimByLine(css) {
120
149
  return css
121
150
  .split('\n')
122
151
  .map(l => l.trim())
123
152
  .filter(l => l)
124
153
  .join('\n');
125
154
  }
126
- /**
127
- * Assemble a string from a template string array and a list of placeholders.
128
- *
129
- * - If the first argument is a string, it is returned as is.
130
- *
131
- * i.e.
132
- * myFoo(...props: TemplateStringProps) => {
133
- * const inputStr = t2s(...props);
134
- * }
135
- * myFoo`hello ${name}` => 'hello world'
136
- * myFoo(`hello ${name}`) => 'hello world'
137
- */
138
- export function t2s(...tsp) {
139
- const [s, ...p] = tsp;
140
- return typeof s === 'string' ? s : s.map((s, i) => s + (p?.[i] ?? '')).join('');
141
- }
142
- /**
143
- * Injects css to the page
144
- *
145
- * - Batches adds for performance
146
- *
147
- * @param css - css to be injected
148
- * @returns void
149
- */
150
- export function addCss(css) {
151
- addCss.que.add(css);
152
- setTimeout(() => {
153
- const css = [...addCss.que].join('\n');
154
- if (css) {
155
- addCss.que.clear();
156
- const s = document.createElement('style');
157
- s.id = `u${addCss.count++}`;
158
- s.innerHTML = css;
159
- document.head.appendChild(s);
160
- }
161
- }, 0);
162
- }
163
- addCss.que = new Set();
164
- addCss.count = 0;
165
- /**
166
- * Injects css and creates unique class names
167
- *
168
- * - Skips if already added
169
- *
170
- * @param css - string or template string, to be injected
171
- * @returns a unique class name
172
- */
173
- export function createClass(...p) {
174
- let css = t2s(...p);
175
- if (!css)
176
- return '';
177
- let className = createClass.history.get(css);
178
- if (!className) {
179
- className = 's' + createClass.count++;
180
- createClass.history.set(css, className);
181
- css = deleteComments(css);
182
- css = expandProps(css);
183
- css = expandArrayValues(css);
184
- const qs = findQueries(css);
185
- for (const q of qs.reverse()) {
186
- css = css.slice(0, q.start) + css.slice(q.end);
187
- }
188
- css = `.${className}{\n${css}\n}\n`;
189
- css += qs
190
- .map(q => {
191
- if (q.query.startsWith('&')) {
192
- return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`;
193
- }
194
- if (q.query.startsWith('@keyframes')) {
195
- return q.outerBody;
196
- }
197
- return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`;
198
- })
199
- .join('\n');
200
- css = trim(css) + '\n\n';
201
- addCss(css);
202
- }
203
- return className;
204
- }
205
- createClass.count = 0;
206
- createClass.history = new Map();
207
155
  //# sourceMappingURL=createClass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createClass.js","sourceRoot":"","sources":["../src/createClass.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,88 @@
1
- /** Breakpoints like chakra */
2
- export const breakPoints = ['30em', '48em', '62em', '80em', '96em']
1
+ import {T2SProps, t2s} from '@slimr/util'
3
2
 
4
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
- type allowableAny = any
3
+ import {addCss} from './addCss.js'
4
+ import {expandShorthands} from './shorthandProps.js'
6
5
 
7
- /** Joins class names and filters out blanks */
8
- export function classJoin(...classes: allowableAny[]) {
6
+ /**
7
+ * Joins class names and omits falsey props
8
+ *
9
+ * @param classes
10
+ * class names to be joined
11
+ *
12
+ * @returns a string of joined class names
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * classJoin('a', 'b', 'c') // 'a b c'
17
+ * classJoin('a', 0, 'b', null, 'c') // 'a b c'
18
+ * ```
19
+ */
20
+ export function classJoin(...classes: (string | 0 | null | undefined)[]) {
9
21
  return classes.filter(c => c && typeof c === 'string').join(' ')
10
22
  }
11
23
 
24
+ /**
25
+ * Upserts and returns a unique css class for a given css string
26
+ *
27
+ * @param cssString
28
+ * string or template string, to be injected. Shorthand props are supported (see Readme).
29
+ *
30
+ * @returns a unique class name
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * c1 = createClass('c: red;') // queues the create of new css class 's0'
35
+ * c2 = createClass('c: red;') // is duplicate so will return 's0'
36
+ * c3 = createClass`c: red;` // same
37
+ * c4 = css`c: red;` // same
38
+ * // c1 = c2 = c3 = c4
39
+ * <div className={css`c: red;`} /> // will resolve to 's0' like above
40
+ * c5 = css`c: blue;` // queues the create of new css class 's1'
41
+ * c6 = css`w: [100%, null, 400px]` // width = 100% on mobile and table, 400px on desktop
42
+ * ```
43
+ * ...and the queue will be executed next javascript tick
44
+ */
45
+ export function createClass(...p: T2SProps) {
46
+ let css = t2s(...p)
47
+ if (!css) return ''
48
+ let className = createClass.history.get(css)
49
+ if (!className) {
50
+ className = 's' + createClass.count++
51
+ createClass.history.set(css, className)
52
+
53
+ css = deleteComments(css)
54
+ css = expandShorthands(css)
55
+ css = expandArrayValues(css)
56
+ const qs = findQueries(css)
57
+
58
+ for (const q of qs.reverse()) {
59
+ css = css.slice(0, q.start) + css.slice(q.end)
60
+ }
61
+
62
+ css = `.${className}{\n${css}\n}\n`
63
+ css += qs
64
+ .map(q => {
65
+ if (q.query.startsWith('&')) {
66
+ return `.${className}${q.query.slice(1)}{\n${q.innerBody}\n}`
67
+ }
68
+ if (q.query.startsWith('@keyframes')) {
69
+ return q.outerBody
70
+ }
71
+ return `${q.query}{\n.${className}{${q.innerBody}\n}\n}`
72
+ })
73
+ .join('\n')
74
+
75
+ css = trimByLine(css) + '\n\n'
76
+
77
+ addCss(css)
78
+ }
79
+ return className
80
+ }
81
+ /** Breakpoints like chakra */
82
+ createClass.breakPoints = ['30em', '48em', '62em', '80em', '96em']
83
+ createClass.count = 0
84
+ createClass.history = new Map<string, string>()
85
+
12
86
  /** delete css comments **/
13
87
  function deleteComments(css: string) {
14
88
  return css.replace(/{\/\*[\s\S]*?(?=\*\/})\*\/}/gm, '')
@@ -35,7 +109,7 @@ function expandArrayValues(css: string) {
35
109
  if (i === 0) {
36
110
  return `${prop}: ${val};`
37
111
  }
38
- return `@media (min-width: ${breakPoints[i - 1]}) { ${prop}: ${val}; }`
112
+ return `@media (min-width: ${createClass.breakPoints[i - 1]}) { ${prop}: ${val}; }`
39
113
  })
40
114
  .join('\n')
41
115
  }
@@ -44,117 +118,6 @@ function expandArrayValues(css: string) {
44
118
  .join('\n')
45
119
  }
46
120
 
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
121
  /** Find @keyframes, @media, @container queries in css **/
159
122
  function findQueries(css: string) {
160
123
  const queries = []
@@ -189,102 +152,10 @@ function findQueries(css: string) {
189
152
  }
190
153
 
191
154
  /** Trims whitespace for every line */
192
- function trim(css: string) {
155
+ function trimByLine(css: string) {
193
156
  return css
194
157
  .split('\n')
195
158
  .map(l => l.trim())
196
159
  .filter(l => l)
197
160
  .join('\n')
198
161
  }
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>()
@@ -1,2 +1,3 @@
1
1
  export * from './createClass.js';
2
+ export * from './shorthandProps.js';
2
3
  export { createClass as css } from './createClass.js';
@@ -1,3 +1,4 @@
1
1
  export * from './createClass.js';
2
+ export * from './shorthandProps.js';
2
3
  export { createClass as css } from './createClass.js';
3
4
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,OAAO,EAAC,WAAW,IAAI,GAAG,EAAC,MAAM,kBAAkB,CAAA"}
package/esm/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './createClass.js'
2
+ export * from './shorthandProps.js'
2
3
  export {createClass as css} from './createClass.js'
@@ -1,8 +1,6 @@
1
- /** Breakpoints like chakra */
2
- export declare const breakPoints: string[];
3
- type allowableAny = any;
4
- /** Joins class names and filters out blanks */
5
- export declare function classJoin(...classes: allowableAny[]): string;
1
+ /**
2
+ * All the shorthand props that can be used in the css prop
3
+ */
6
4
  export interface ShorthandProps {
7
5
  /** shorthand for css:align-items */
8
6
  ai?: string;
@@ -67,49 +65,11 @@ export interface ShorthandProps {
67
65
  /** shorthand for css:z-index */
68
66
  z?: number | string;
69
67
  }
70
- export declare const shorthandPropsMap: Record<keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>, string>;
71
- export 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
- export declare function t2s(...tsp: TemplateStringProps): string;
85
- export type TemplateStringProps = [
86
- strings: TemplateStringsArray | string,
87
- ...placeHolders: string[]
88
- ];
89
68
  /**
90
- * Injects css to the page
91
- *
92
- * - Batches adds for performance
93
- *
94
- * @param css - css to be injected
95
- * @returns void
69
+ * Expand short-hand css props to full
96
70
  */
97
- export declare function addCss(css: string): void;
98
- export declare namespace addCss {
99
- var que: Set<string>;
100
- var count: number;
101
- }
71
+ export declare function expandShorthands(css: string): string;
102
72
  /**
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
73
+ * Map shorthand props to their full css prop
109
74
  */
110
- export declare function createClass(...p: TemplateStringProps): string;
111
- export declare namespace createClass {
112
- var count: number;
113
- var history: Map<string, string>;
114
- }
115
- export {};
75
+ export declare const shorthandPropsMap: Record<keyof Omit<ShorthandProps, 'mx' | 'my' | 'px' | 'py'>, string>;