@pyreon/unistyle 0.11.1 → 0.11.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.
Files changed (43) hide show
  1. package/package.json +8 -7
  2. package/src/__tests__/alignContent.test.ts +121 -0
  3. package/src/__tests__/borderRadius.test.ts +125 -0
  4. package/src/__tests__/camelToKebab.test.ts +44 -0
  5. package/src/__tests__/context.test.ts +147 -0
  6. package/src/__tests__/createMediaQueries.test.ts +98 -0
  7. package/src/__tests__/edge.test.ts +164 -0
  8. package/src/__tests__/enrichTheme.test.ts +56 -0
  9. package/src/__tests__/extendCss.test.ts +45 -0
  10. package/src/__tests__/index.test.ts +79 -0
  11. package/src/__tests__/makeItResponsive.test.ts +171 -0
  12. package/src/__tests__/processDescriptor.test.ts +320 -0
  13. package/src/__tests__/responsive.test.ts +177 -0
  14. package/src/__tests__/styles.test.ts +119 -0
  15. package/src/__tests__/units.test.ts +134 -0
  16. package/src/context.tsx +34 -0
  17. package/src/enrichTheme.ts +42 -0
  18. package/src/index.ts +89 -0
  19. package/src/responsive/breakpoints.ts +15 -0
  20. package/src/responsive/createMediaQueries.ts +43 -0
  21. package/src/responsive/index.ts +14 -0
  22. package/src/responsive/makeItResponsive.ts +118 -0
  23. package/src/responsive/normalizeTheme.ts +65 -0
  24. package/src/responsive/optimizeTheme.ts +39 -0
  25. package/src/responsive/sortBreakpoints.ts +10 -0
  26. package/src/responsive/transformTheme.ts +48 -0
  27. package/src/styles/alignContent.ts +58 -0
  28. package/src/styles/extendCss.ts +26 -0
  29. package/src/styles/index.ts +16 -0
  30. package/src/styles/shorthands/borderRadius.ts +89 -0
  31. package/src/styles/shorthands/edge.ts +108 -0
  32. package/src/styles/shorthands/index.ts +4 -0
  33. package/src/styles/styles/camelToKebab.ts +3 -0
  34. package/src/styles/styles/index.ts +33 -0
  35. package/src/styles/styles/processDescriptor.ts +100 -0
  36. package/src/styles/styles/propertyMap.ts +436 -0
  37. package/src/styles/styles/types.ts +366 -0
  38. package/src/styles/styles/utils.ts +62 -0
  39. package/src/types.ts +175 -0
  40. package/src/units/index.ts +6 -0
  41. package/src/units/stripUnit.ts +25 -0
  42. package/src/units/value.ts +47 -0
  43. package/src/units/values.ts +40 -0
@@ -0,0 +1,366 @@
1
+ type PropertyValue = string | number | null | undefined
2
+ type Color = string | null | undefined
3
+
4
+ export interface ITheme {
5
+ // Special
6
+ fullScreen?: boolean
7
+ hideEmpty?: boolean
8
+ clearFix?: boolean
9
+ extendCss?: string | ((css: (...args: any[]) => string) => string)
10
+
11
+ // Position
12
+ all?: string
13
+ display?: string
14
+ position?: string
15
+ boxSizing?: string
16
+ float?: string
17
+
18
+ // Inset
19
+ inset?: PropertyValue
20
+ insetX?: PropertyValue
21
+ insetY?: PropertyValue
22
+ top?: PropertyValue
23
+ left?: PropertyValue
24
+ bottom?: PropertyValue
25
+ right?: PropertyValue
26
+
27
+ // Sizing
28
+ width?: PropertyValue
29
+ minWidth?: PropertyValue
30
+ maxWidth?: PropertyValue
31
+ height?: PropertyValue
32
+ minHeight?: PropertyValue
33
+ maxHeight?: PropertyValue
34
+ size?: PropertyValue
35
+ minSize?: PropertyValue
36
+ maxSize?: PropertyValue
37
+ gap?: PropertyValue
38
+ aspectRatio?: string
39
+ contain?: string
40
+ containerType?: string
41
+ containerName?: string
42
+ container?: string
43
+ inlineSize?: PropertyValue
44
+ blockSize?: PropertyValue
45
+ minInlineSize?: PropertyValue
46
+ minBlockSize?: PropertyValue
47
+ maxInlineSize?: PropertyValue
48
+ maxBlockSize?: PropertyValue
49
+
50
+ // Spacing
51
+ margin?: PropertyValue
52
+ marginX?: PropertyValue
53
+ marginY?: PropertyValue
54
+ marginTop?: PropertyValue
55
+ marginLeft?: PropertyValue
56
+ marginBottom?: PropertyValue
57
+ marginRight?: PropertyValue
58
+ padding?: PropertyValue
59
+ paddingX?: PropertyValue
60
+ paddingY?: PropertyValue
61
+ paddingTop?: PropertyValue
62
+ paddingLeft?: PropertyValue
63
+ paddingBottom?: PropertyValue
64
+ paddingRight?: PropertyValue
65
+
66
+ // Logical spacing
67
+ marginInline?: PropertyValue
68
+ marginInlineStart?: PropertyValue
69
+ marginInlineEnd?: PropertyValue
70
+ marginBlock?: PropertyValue
71
+ marginBlockStart?: PropertyValue
72
+ marginBlockEnd?: PropertyValue
73
+ paddingInline?: PropertyValue
74
+ paddingInlineStart?: PropertyValue
75
+ paddingInlineEnd?: PropertyValue
76
+ paddingBlock?: PropertyValue
77
+ paddingBlockStart?: PropertyValue
78
+ paddingBlockEnd?: PropertyValue
79
+
80
+ // Logical inset
81
+ insetInline?: PropertyValue
82
+ insetInlineStart?: PropertyValue
83
+ insetInlineEnd?: PropertyValue
84
+ insetBlock?: PropertyValue
85
+ insetBlockStart?: PropertyValue
86
+ insetBlockEnd?: PropertyValue
87
+
88
+ // Flex
89
+ alignContent?: string
90
+ alignItems?: string
91
+ alignSelf?: string
92
+ flex?: string | number
93
+ flexBasis?: string | number
94
+ flexDirection?: string
95
+ flexFlow?: string
96
+ flexGrow?: number
97
+ flexShrink?: number
98
+ flexWrap?: string
99
+ justifyContent?: string
100
+ justifyItems?: string
101
+ justifySelf?: string
102
+ placeItems?: string
103
+ placeContent?: string
104
+ placeSelf?: string
105
+ rowGap?: PropertyValue
106
+ columnGap?: PropertyValue
107
+
108
+ // Grid
109
+ grid?: string
110
+ gridArea?: string
111
+ gridAutoColumns?: PropertyValue
112
+ gridAutoFlow?: string
113
+ gridAutoRows?: PropertyValue
114
+ gridColumn?: string
115
+ gridColumnEnd?: string
116
+ gridColumnGap?: PropertyValue
117
+ gridColumnStart?: PropertyValue
118
+ gridGap?: PropertyValue
119
+ gridRow?: string
120
+ gridRowStart?: string
121
+ gridRowEnd?: string
122
+ gridRowGap?: PropertyValue
123
+ gridTemplate?: string
124
+ gridTemplateAreas?: string
125
+ gridTemplateColumns?: string
126
+ gridTemplateRows?: string
127
+
128
+ // Positioning
129
+ objectFit?: string
130
+ objectPosition?: string
131
+ order?: number
132
+ opacity?: number | string
133
+ resize?: string
134
+ verticalAlign?: string
135
+
136
+ // Font & text
137
+ lineHeight?: string | number
138
+ font?: string
139
+ fontFamily?: string
140
+ fontSize?: PropertyValue
141
+ fontSizeAdjust?: PropertyValue
142
+ fontStretch?: PropertyValue
143
+ fontStyle?: string
144
+ fontVariant?: string
145
+ fontWeight?: string | number
146
+ fontKerning?: string
147
+ fontFeatureSettings?: string
148
+ fontVariationSettings?: string
149
+ fontOpticalSizing?: string
150
+ textAlign?: string
151
+ textAlignLast?: string
152
+ textTransform?: string
153
+ textDecoration?: string
154
+ textDecorationColor?: Color
155
+ textDecorationLine?: string
156
+ textDecorationStyle?: string
157
+ textDecorationThickness?: string
158
+ textUnderlineOffset?: string
159
+ textEmphasis?: string
160
+ textEmphasisColor?: Color
161
+ textEmphasisStyle?: string
162
+ letterSpacing?: string
163
+ wordSpacing?: string
164
+ textIndent?: string
165
+ textJustify?: string
166
+ textOverflow?: string
167
+ textShadow?: string
168
+ textWrap?: string
169
+ textRendering?: string
170
+ whiteSpace?: string
171
+ wordBreak?: string
172
+ wordWrap?: string
173
+ writingMode?: string
174
+ direction?: string
175
+ hyphens?: string
176
+
177
+ // List
178
+ listStyle?: string
179
+ listStyleImage?: string
180
+ listStylePosition?: string
181
+ listStyleType?: string
182
+
183
+ // Background & colors
184
+ color?: Color
185
+ background?: string
186
+ backgroundColor?: Color
187
+ backgroundImage?: string
188
+ backgroundAttachment?: string
189
+ backgroundClip?: string
190
+ backgroundOrigin?: string
191
+ backgroundPosition?: string
192
+ backgroundRepeat?: string
193
+ backgroundSize?: string
194
+
195
+ // Borders
196
+ borderRadius?: PropertyValue
197
+ borderRadiusTop?: PropertyValue
198
+ borderRadiusBottom?: PropertyValue
199
+ borderRadiusLeft?: PropertyValue
200
+ borderRadiusRight?: PropertyValue
201
+ borderRadiusTopLeft?: PropertyValue
202
+ borderRadiusTopRight?: PropertyValue
203
+ borderRadiusBottomLeft?: PropertyValue
204
+ borderRadiusBottomRight?: PropertyValue
205
+ border?: string
206
+ borderTop?: string
207
+ borderBottom?: string
208
+ borderLeft?: string
209
+ borderRight?: string
210
+ borderWidth?: PropertyValue
211
+ borderWidthX?: PropertyValue
212
+ borderWidthY?: PropertyValue
213
+ borderWidthTop?: PropertyValue
214
+ borderWidthLeft?: PropertyValue
215
+ borderWidthBottom?: PropertyValue
216
+ borderWidthRight?: PropertyValue
217
+ borderStyle?: string
218
+ borderStyleX?: string
219
+ borderStyleY?: string
220
+ borderStyleTop?: string
221
+ borderStyleLeft?: string
222
+ borderStyleBottom?: string
223
+ borderStyleRight?: string
224
+ borderColor?: Color
225
+ borderColorX?: Color
226
+ borderColorY?: Color
227
+ borderColorTop?: Color
228
+ borderColorLeft?: Color
229
+ borderColorBottom?: Color
230
+ borderColorRight?: Color
231
+ borderImage?: string
232
+ borderImageOutset?: string
233
+ borderImageRepeat?: string
234
+ borderImageSlice?: string
235
+ borderImageSource?: string
236
+ borderImageWidth?: string
237
+ borderSpacing?: string
238
+
239
+ // Logical borders
240
+ borderInline?: string
241
+ borderBlock?: string
242
+ borderInlineStart?: string
243
+ borderInlineEnd?: string
244
+ borderBlockStart?: string
245
+ borderBlockEnd?: string
246
+
247
+ // Visual effects
248
+ backfaceVisibility?: string
249
+ boxShadow?: string
250
+ filter?: string
251
+ backdropFilter?: string
252
+ mixBlendMode?: string
253
+ backgroundBlendMode?: string
254
+ isolation?: string
255
+ outline?: string
256
+ outlineColor?: Color
257
+ outlineOffset?: string
258
+ outlineStyle?: string
259
+ outlineWidth?: string
260
+
261
+ // Animations
262
+ keyframe?: string
263
+ animation?: string
264
+ animationName?: string
265
+ animationDuration?: string
266
+ animationTimingFunction?: string
267
+ animationDelay?: string
268
+ animationIterationCount?: string | number
269
+ animationDirection?: string
270
+ animationFillMode?: string
271
+ animationPlayState?: string
272
+ transition?: string
273
+ transitionDelay?: string
274
+ transitionDuration?: string
275
+ transitionProperty?: string
276
+ transitionTimingFunction?: string
277
+
278
+ // Transform
279
+ transform?: string
280
+ transformOrigin?: string
281
+ transformStyle?: string
282
+ translate?: string
283
+ rotate?: string
284
+ scale?: string | number
285
+ willChange?: string
286
+
287
+ // Scroll
288
+ scrollBehavior?: string
289
+ scrollSnapType?: string
290
+ scrollSnapAlign?: string
291
+ scrollSnapStop?: string
292
+ scrollMargin?: string
293
+ scrollPadding?: string
294
+ overscrollBehavior?: string
295
+ overscrollBehaviorX?: string
296
+ overscrollBehaviorY?: string
297
+
298
+ // Interaction
299
+ cursor?: string
300
+ pointerEvents?: string
301
+ userSelect?: string
302
+ touchAction?: string
303
+ scrollbarWidth?: string
304
+ scrollbarColor?: string
305
+ scrollbarGutter?: string
306
+ caretColor?: Color
307
+ accentColor?: Color
308
+ colorScheme?: string
309
+
310
+ // Other
311
+ captionSide?: string
312
+ clear?: string
313
+ clip?: string
314
+ clipPath?: string
315
+ content?: string
316
+ contentVisibility?: string
317
+ counterIncrement?: string
318
+ counterReset?: string
319
+ emptyCells?: string
320
+ zIndex?: number | string
321
+ overflow?: string
322
+ overflowWrap?: string
323
+ overflowX?: string
324
+ overflowY?: string
325
+ perspective?: string
326
+ perspectiveOrigin?: string
327
+ quotes?: string
328
+ tabSize?: string | number
329
+ tableLayout?: string
330
+ visibility?: string
331
+ appearance?: string
332
+ imageRendering?: string
333
+
334
+ // Masks
335
+ maskImage?: string
336
+ maskSize?: string
337
+ maskPosition?: string
338
+ maskRepeat?: string
339
+
340
+ // Shapes
341
+ shapeOutside?: string
342
+ shapeMargin?: string
343
+ shapeImageThreshold?: string | number
344
+
345
+ // Columns
346
+ columnCount?: number | string
347
+ columnWidth?: string
348
+ columnRule?: string
349
+ columns?: string
350
+
351
+ // Fragmentation
352
+ breakBefore?: string
353
+ breakAfter?: string
354
+ breakInside?: string
355
+ orphans?: number
356
+ widows?: number
357
+ printColorAdjust?: string
358
+ }
359
+
360
+ export type InnerTheme = {
361
+ [K in keyof ITheme]?: ITheme[K] | null | undefined
362
+ }
363
+
364
+ export type Theme = {
365
+ [K in keyof InnerTheme]?: InnerTheme[K] | (() => ITheme[K])
366
+ }
@@ -0,0 +1,62 @@
1
+ import type { PropertyValue } from "../../types"
2
+ import value from "../../units/value"
3
+
4
+ const isValidValue = (v: unknown) => !!v || v === 0
5
+
6
+ type SideValues = {
7
+ top: PropertyValue | null | undefined
8
+ left: PropertyValue | null | undefined
9
+ right: PropertyValue | null | undefined
10
+ bottom: PropertyValue | null | undefined
11
+ x: PropertyValue | null | undefined
12
+ y: PropertyValue | null | undefined
13
+ full: PropertyValue | null | undefined
14
+ }
15
+
16
+ // top - right - bottom - left
17
+ const resolveSides = ({ top, left, right, bottom, x, y, full }: SideValues) => {
18
+ const sides = [full, full, full, full]
19
+
20
+ if (isValidValue(x)) {
21
+ sides[1] = x
22
+ sides[3] = x
23
+ }
24
+
25
+ if (isValidValue(y)) {
26
+ sides[0] = y
27
+ sides[2] = y
28
+ }
29
+
30
+ if (isValidValue(top)) sides[0] = top
31
+ if (isValidValue(right)) sides[1] = right
32
+ if (isValidValue(bottom)) sides[2] = bottom
33
+ if (isValidValue(left)) sides[3] = left
34
+
35
+ return sides
36
+ }
37
+
38
+ const formatSpacing = (property: string, sides: (PropertyValue | null | undefined)[]) => {
39
+ const [t, r, b, l] = sides
40
+
41
+ if (sides.every((val, _, arr) => isValidValue(val) && val === arr[0])) return `${property}: ${t};`
42
+
43
+ if (t === b && r === l) return `${property}: ${value(t)} ${value(r)};`
44
+
45
+ if (t && r === l && b) return `${property}: ${value(t)} ${value(r)} ${value(b)};`
46
+
47
+ if (sides.every((val) => !!val))
48
+ return `${property}: ${value(t)} ${value(r)} ${value(b)} ${value(l)};`
49
+
50
+ let output = ""
51
+ if (t) output += `${property}-top: ${value(t)};`
52
+ if (b) output += `${property}-bottom: ${value(b)};`
53
+ if (l) output += `${property}-left: ${value(l)};`
54
+ if (r) output += `${property}-right: ${value(r)};`
55
+
56
+ return output
57
+ }
58
+
59
+ export type SpacingShorthand = (property: "padding" | "margin") => (props: SideValues) => string
60
+
61
+ export const spacingShorthand: SpacingShorthand = (property) => (props) =>
62
+ formatSpacing(property, resolveSides(props))
package/src/types.ts ADDED
@@ -0,0 +1,175 @@
1
+ import type { config } from "@pyreon/ui-core"
2
+
3
+ export type Css = typeof config.css
4
+
5
+ export type Defaults = "initial" | "inherit"
6
+ export type Units = "px" | "rem" | "em" | "%" | "vh" | "vw" | "vmin" | "vmax" | "ex"
7
+ export type UnitValue = number | `${number}${Units}`
8
+ export type PropertyValue = UnitValue | "auto" | Defaults | `calc(${string | number})`
9
+
10
+ export type Size = "max-content" | "min-content" | "fit-content"
11
+
12
+ export type Color =
13
+ | `#${string | number}`
14
+ | "currentColor"
15
+ | "transparent"
16
+ | `rgb(${number}, ${number}, ${number})`
17
+ | `rgb(${number},${number},${number})`
18
+ | `rgba(${number}, ${number}, ${number}, ${number})`
19
+ | `rgba(${number},${number},${number},${number})`
20
+ | `hsl(${number}, ${number}%, ${number}%)`
21
+ | `hsl(${number},${number}%,${number}%)`
22
+ | `hsla(${number}, ${number}%, ${number}%, ${number})`
23
+ | `hsla(${number},${number}%,${number}%,${number})`
24
+ | BrowserColors
25
+ | Defaults
26
+
27
+ export type BrowserColors =
28
+ | "black"
29
+ | "silver"
30
+ | "gray"
31
+ | "white"
32
+ | "maroon"
33
+ | "red"
34
+ | "purple"
35
+ | "fuchsia"
36
+ | "green"
37
+ | "lime"
38
+ | "olive"
39
+ | "yellow"
40
+ | "navy"
41
+ | "blue"
42
+ | "teal"
43
+ | "aqua"
44
+ | "orange"
45
+ | "aliceblue"
46
+ | "antiquewhite"
47
+ | "aquamarine"
48
+ | "azure"
49
+ | "beige"
50
+ | "bisque"
51
+ | "blanchedalmond"
52
+ | "blueviolet"
53
+ | "brown"
54
+ | "burlywood"
55
+ | "cadetblue"
56
+ | "chartreuse"
57
+ | "chocolate"
58
+ | "coral"
59
+ | "cornflowerblue"
60
+ | "cornsilk"
61
+ | "crimson"
62
+ | "cyan"
63
+ | "darkblue"
64
+ | "darkcyan"
65
+ | "darkgoldenrod"
66
+ | "darkgray"
67
+ | "darkgreen"
68
+ | "darkgrey"
69
+ | "darkkhaki"
70
+ | "darkmagenta"
71
+ | "darkolivegreen"
72
+ | "darkorange"
73
+ | "darkorchid"
74
+ | "darkred"
75
+ | "darksalmon"
76
+ | "darkseagreen"
77
+ | "darkslateblue"
78
+ | "darkslategray"
79
+ | "darkslategrey"
80
+ | "darkturquoise"
81
+ | "darkviolet"
82
+ | "deeppink"
83
+ | "deepskyblue"
84
+ | "dimgray"
85
+ | "dimgrey"
86
+ | "dodgerblue"
87
+ | "firebrick"
88
+ | "floralwhite"
89
+ | "forestgreen"
90
+ | "gainsboro"
91
+ | "ghostwhite"
92
+ | "gold"
93
+ | "goldenrod"
94
+ | "greenyellow"
95
+ | "grey"
96
+ | "honeydew"
97
+ | "hotpink"
98
+ | "indianred"
99
+ | "indigo"
100
+ | "ivory"
101
+ | "khaki"
102
+ | "lavender"
103
+ | "lavenderblush"
104
+ | "lawngreen"
105
+ | "lemonchiffon"
106
+ | "lightblue"
107
+ | "lightcoral"
108
+ | "lightcyan"
109
+ | "lightgoldenrodyellow"
110
+ | "lightgray"
111
+ | "lightgreen"
112
+ | "lightgrey"
113
+ | "lightpink"
114
+ | "lightsalmon"
115
+ | "lightseagreen"
116
+ | "lightskyblue"
117
+ | "lightslategray"
118
+ | "lightslategrey"
119
+ | "lightsteelblue"
120
+ | "lightyellow"
121
+ | "limegreen"
122
+ | "linen"
123
+ | "magenta"
124
+ | "mediumaquamarine"
125
+ | "mediumblue"
126
+ | "mediumorchid"
127
+ | "mediumpurple"
128
+ | "mediumseagreen"
129
+ | "mediumslateblue"
130
+ | "mediumspringgreen"
131
+ | "mediumturquoise"
132
+ | "mediumvioletred"
133
+ | "midnightblue"
134
+ | "mintcream"
135
+ | "mistyrose"
136
+ | "moccasin"
137
+ | "navajowhite"
138
+ | "oldlace"
139
+ | "olivedrab"
140
+ | "orangered"
141
+ | "orchid"
142
+ | "palegoldenrod"
143
+ | "palegreen"
144
+ | "paleturquoise"
145
+ | "palevioletred"
146
+ | "papayawhip"
147
+ | "peachpuff"
148
+ | "peru"
149
+ | "pink"
150
+ | "plum"
151
+ | "powderblue"
152
+ | "rosybrown"
153
+ | "royalblue"
154
+ | "saddlebrown"
155
+ | "salmon"
156
+ | "sandybrown"
157
+ | "seagreen"
158
+ | "seashell"
159
+ | "sienna"
160
+ | "skyblue"
161
+ | "slateblue"
162
+ | "slategray"
163
+ | "slategrey"
164
+ | "snow"
165
+ | "springgreen"
166
+ | "steelblue"
167
+ | "tan"
168
+ | "thistle"
169
+ | "tomato"
170
+ | "turquoise"
171
+ | "violet"
172
+ | "wheat"
173
+ | "whitesmoke"
174
+ | "yellowgreen"
175
+ | "rebeccapurple"
@@ -0,0 +1,6 @@
1
+ export type { StripUnit } from "./stripUnit"
2
+ export { default as stripUnit } from "./stripUnit"
3
+ export type { Value } from "./value"
4
+ export { default as value } from "./value"
5
+ export type { Values } from "./values"
6
+ export { default as values } from "./values"
@@ -0,0 +1,25 @@
1
+ type Value<V> = V extends string ? number : V
2
+ type Unit<V> = V extends string ? string : undefined
3
+
4
+ export type StripUnit = <V extends string | number, UR extends boolean = false>(
5
+ value: V,
6
+ unitReturn?: UR,
7
+ ) => UR extends true ? [Value<V>, Unit<V>] : Value<V>
8
+
9
+ const stripUnit = ((value: string | number, unitReturn?: boolean) => {
10
+ const cssRegex = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/
11
+
12
+ if (typeof value !== "string") return unitReturn ? [value, undefined] : value
13
+
14
+ const matchedValue = value.match(cssRegex)
15
+
16
+ if (unitReturn) {
17
+ if (matchedValue) return [parseFloat(value), matchedValue[2]]
18
+ return [value, undefined]
19
+ }
20
+
21
+ if (matchedValue) return parseFloat(value)
22
+ return value
23
+ }) as StripUnit
24
+
25
+ export default stripUnit
@@ -0,0 +1,47 @@
1
+ import stripUnit from "./stripUnit"
2
+
3
+ type CssUnits =
4
+ | "px"
5
+ | "rem"
6
+ | "%"
7
+ | "em"
8
+ | "ex"
9
+ | "cm"
10
+ | "mm"
11
+ | "in"
12
+ | "pt"
13
+ | "pc"
14
+ | "ch"
15
+ | "vh"
16
+ | "vw"
17
+ | "vmin"
18
+ | "vmax"
19
+
20
+ const isNotValue = (val: unknown) => !val && val !== 0
21
+
22
+ export type Value = (
23
+ param: string | number | null | undefined,
24
+ rootSize?: number,
25
+ outputUnit?: CssUnits,
26
+ ) => string | number | null
27
+
28
+ const value: Value = (param, rootSize = 16, outputUnit = "rem"): string | number | null => {
29
+ if (isNotValue(param)) return null
30
+
31
+ // After the guard above, param is guaranteed to be string | number (non-null)
32
+ const p = param as string | number
33
+
34
+ const [val, unit] = stripUnit(p as string, true)
35
+ if (isNotValue(val)) return null
36
+ if (val === 0 || typeof val === "string") return p
37
+
38
+ const canConvert = rootSize && !Number.isNaN(val)
39
+ if (canConvert && !unit && outputUnit === "px") return `${val}${outputUnit}`
40
+ if (canConvert && !unit) return `${val / rootSize}rem`
41
+ if (canConvert && unit === "px" && outputUnit === "rem") return `${val / rootSize}rem`
42
+ if (unit) return p
43
+
44
+ return `${val}${outputUnit}`
45
+ }
46
+
47
+ export default value