@pyreon/unistyle 0.24.5 → 0.24.6
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 +7 -9
- package/src/__tests__/alignContent.test.ts +0 -121
- package/src/__tests__/borderRadius.test.ts +0 -125
- package/src/__tests__/camelToKebab.test.ts +0 -44
- package/src/__tests__/context.test.ts +0 -147
- package/src/__tests__/createMediaQueries.test.ts +0 -98
- package/src/__tests__/edge.test.ts +0 -164
- package/src/__tests__/enrichTheme.test.ts +0 -56
- package/src/__tests__/extendCss.test.ts +0 -45
- package/src/__tests__/index.test.ts +0 -79
- package/src/__tests__/makeItResponsive.test.ts +0 -431
- package/src/__tests__/manifest-snapshot.test.ts +0 -34
- package/src/__tests__/native-marker.test.ts +0 -9
- package/src/__tests__/optimizeBreakpointDeltas.test.ts +0 -124
- package/src/__tests__/processDescriptor.test.ts +0 -322
- package/src/__tests__/responsive.test.ts +0 -221
- package/src/__tests__/special-keys.test.ts +0 -120
- package/src/__tests__/styles.test.ts +0 -273
- package/src/__tests__/unistyle.browser.test.tsx +0 -169
- package/src/__tests__/units.test.ts +0 -134
- package/src/context.tsx +0 -44
- package/src/enrichTheme.ts +0 -42
- package/src/env.d.ts +0 -6
- package/src/index.ts +0 -91
- package/src/manifest.ts +0 -197
- package/src/responsive/breakpoints.ts +0 -15
- package/src/responsive/createMediaQueries.ts +0 -43
- package/src/responsive/index.ts +0 -15
- package/src/responsive/makeItResponsive.ts +0 -223
- package/src/responsive/normalizeTheme.ts +0 -79
- package/src/responsive/optimizeBreakpointDeltas.ts +0 -190
- package/src/responsive/optimizeTheme.ts +0 -60
- package/src/responsive/sortBreakpoints.ts +0 -10
- package/src/responsive/transformTheme.ts +0 -54
- package/src/styles/alignContent.ts +0 -62
- package/src/styles/extendCss.ts +0 -26
- package/src/styles/index.ts +0 -16
- package/src/styles/shorthands/borderRadius.ts +0 -89
- package/src/styles/shorthands/edge.ts +0 -108
- package/src/styles/shorthands/index.ts +0 -4
- package/src/styles/styles/camelToKebab.ts +0 -3
- package/src/styles/styles/index.ts +0 -132
- package/src/styles/styles/processDescriptor.ts +0 -136
- package/src/styles/styles/propertyMap.ts +0 -438
- package/src/styles/styles/types.ts +0 -368
- package/src/types.ts +0 -175
- package/src/units/index.ts +0 -6
- package/src/units/stripUnit.ts +0 -25
- package/src/units/value.ts +0 -47
- package/src/units/values.ts +0 -40
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { values } from '../../units'
|
|
2
|
-
import { borderRadius, edge } from '../shorthands'
|
|
3
|
-
import processDescriptor from './processDescriptor'
|
|
4
|
-
import propertyMap from './propertyMap'
|
|
5
|
-
import type { ITheme, InnerTheme, Theme } from './types'
|
|
6
|
-
|
|
7
|
-
// Dev-time counter sink — populated by `@pyreon/perf-harness` on install().
|
|
8
|
-
// No import so unistyle carries zero coupling to a private package.
|
|
9
|
-
const _countSink = globalThis as { __pyreon_count__?: (name: string, n?: number) => void }
|
|
10
|
-
|
|
11
|
-
export type { ITheme, Theme as StylesTheme }
|
|
12
|
-
|
|
13
|
-
type Css = (strings: TemplateStringsArray, ...args: any[]) => any
|
|
14
|
-
|
|
15
|
-
export type Styles = ({
|
|
16
|
-
theme,
|
|
17
|
-
css,
|
|
18
|
-
rootSize,
|
|
19
|
-
globalTheme,
|
|
20
|
-
}: {
|
|
21
|
-
theme: InnerTheme
|
|
22
|
-
css: Css
|
|
23
|
-
rootSize?: number | undefined
|
|
24
|
-
globalTheme?: Record<string, any> | undefined
|
|
25
|
-
}) => ReturnType<Css>
|
|
26
|
-
|
|
27
|
-
// ─── Tier 1: Key → descriptor-index lookup ──────────────────────────────────
|
|
28
|
-
// Built once at module init. Instead of scanning all 257 descriptors on every
|
|
29
|
-
// styles() call, we look up only the indices whose keys are present in the
|
|
30
|
-
// incoming theme object. Reduces iterations from ~257 to ~10-20 for a typical
|
|
31
|
-
// component that uses 5-10 properties.
|
|
32
|
-
|
|
33
|
-
const keyToIndices = new Map<string, number[]>()
|
|
34
|
-
|
|
35
|
-
for (let i = 0; i < propertyMap.length; i++) {
|
|
36
|
-
const d = propertyMap[i] as Record<string, any>
|
|
37
|
-
const addKey = (k: string) => {
|
|
38
|
-
let arr = keyToIndices.get(k)
|
|
39
|
-
if (!arr) {
|
|
40
|
-
arr = []
|
|
41
|
-
keyToIndices.set(k, arr)
|
|
42
|
-
}
|
|
43
|
-
arr.push(i)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (d.key) addKey(d.key)
|
|
47
|
-
if (d.keys) {
|
|
48
|
-
if (Array.isArray(d.keys)) {
|
|
49
|
-
for (const k of d.keys) addKey(k)
|
|
50
|
-
} else {
|
|
51
|
-
for (const inner of Object.values(d.keys as Record<string, string>)) {
|
|
52
|
-
addKey(inner)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// kind: 'special' descriptors carry only `id` (no key/keys). Index by id so
|
|
57
|
-
// the fast path resolves them when paired with non-special keys; otherwise
|
|
58
|
-
// fragments.length > 0 from non-special hits skips the fallback full-scan
|
|
59
|
-
// and the special is silently dropped.
|
|
60
|
-
if (d.id) addKey(d.id)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Convert a normalized theme object (Record<key, value>) into a CSS template
|
|
65
|
-
* by walking the property map. Each entry in propertyMap describes a single
|
|
66
|
-
* CSS property — its kind (simple / convert / convert_fallback / edge /
|
|
67
|
-
* border_radius), the input theme key(s) to read, and the output CSS name.
|
|
68
|
-
*
|
|
69
|
-
* Returns a `css` tagged template literal so makeItResponsive can embed the
|
|
70
|
-
* result inside the responsive breakpoint structure. Each call returns a
|
|
71
|
-
* FRESH array — the result CSSResult holds onto that array by reference,
|
|
72
|
-
* and reusing one module-level array across calls would clobber an earlier
|
|
73
|
-
* CSSResult's data when the next styles() call clears the shared array.
|
|
74
|
-
*
|
|
75
|
-
* IMPORTANT: the return MUST be wrapped in `css\`...\`` — NOT a plain
|
|
76
|
-
* string join. makeItResponsive embeds this result in another template
|
|
77
|
-
* literal, and the CSS interpolation chain requires a css template
|
|
78
|
-
* result (not a raw string) for correct nesting of media queries,
|
|
79
|
-
* pseudo-selectors, and @layer wrapping.
|
|
80
|
-
*/
|
|
81
|
-
// Module-level reusable Set — cleared before each synchronous styles() call.
|
|
82
|
-
// The fragments array CANNOT be module-level because the returned CSSResult
|
|
83
|
-
// captures it by reference; the next styles() call would clear-out the
|
|
84
|
-
// previous result before its consumer ever resolved it.
|
|
85
|
-
const _seen = new Set<number>()
|
|
86
|
-
|
|
87
|
-
const styles: Styles = ({ theme: t, css, rootSize }) => {
|
|
88
|
-
if (process.env.NODE_ENV !== 'production') _countSink.__pyreon_count__?.('unistyle.styles')
|
|
89
|
-
|
|
90
|
-
const calc = (...params: any[]) => values(params, rootSize)
|
|
91
|
-
const shorthand = edge(rootSize)
|
|
92
|
-
const borderRadiusFn = borderRadius(rootSize)
|
|
93
|
-
|
|
94
|
-
// Per-call fragments array — owned by the returned CSSResult.
|
|
95
|
-
const fragments: unknown[] = []
|
|
96
|
-
|
|
97
|
-
// Reuse module-level Set — safe because the Set is fully consumed before
|
|
98
|
-
// styles() returns. The fragments array is the one we MUST allocate fresh
|
|
99
|
-
// (see top-of-function comment) — its lifetime extends past this call.
|
|
100
|
-
_seen.clear()
|
|
101
|
-
|
|
102
|
-
// Fast path: iterate only descriptors whose keys are present in theme
|
|
103
|
-
for (const key of Object.keys(t)) {
|
|
104
|
-
const indices = keyToIndices.get(key)
|
|
105
|
-
if (!indices) continue
|
|
106
|
-
for (const idx of indices) {
|
|
107
|
-
if (_seen.has(idx)) continue
|
|
108
|
-
_seen.add(idx)
|
|
109
|
-
if (process.env.NODE_ENV !== 'production')
|
|
110
|
-
_countSink.__pyreon_count__?.('unistyle.descriptor')
|
|
111
|
-
fragments.push(processDescriptor(propertyMap[idx]!, t, css, calc, shorthand, borderRadiusFn))
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Fallback: if lookup produced nothing, full scan (handles edge cases
|
|
116
|
-
// where theme uses non-standard keys that aren't in propertyMap)
|
|
117
|
-
if (fragments.length === 0 && Object.keys(t).length > 0) {
|
|
118
|
-
if (process.env.NODE_ENV !== 'production')
|
|
119
|
-
_countSink.__pyreon_count__?.('unistyle.descriptor.fallback-scan')
|
|
120
|
-
for (const d of propertyMap) {
|
|
121
|
-
if (process.env.NODE_ENV !== 'production')
|
|
122
|
-
_countSink.__pyreon_count__?.('unistyle.descriptor')
|
|
123
|
-
fragments.push(processDescriptor(d, t, css, calc, shorthand, borderRadiusFn))
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return css`
|
|
128
|
-
${fragments}
|
|
129
|
-
`
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export default styles
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import type { Values } from '../../units/values'
|
|
2
|
-
import type { BorderRadius } from '../shorthands/borderRadius'
|
|
3
|
-
import type { Edge } from '../shorthands/edge'
|
|
4
|
-
import type { PropertyDescriptor } from './propertyMap'
|
|
5
|
-
import type { InnerTheme } from './types'
|
|
6
|
-
|
|
7
|
-
type Css = (strings: TemplateStringsArray, ...values: any[]) => any
|
|
8
|
-
type Calc = (...params: any[]) => ReturnType<Values>
|
|
9
|
-
|
|
10
|
-
/** Mirrors the Value / PropertyValue types used by edge and borderRadius shorthands. */
|
|
11
|
-
type Value = string | number | null | undefined
|
|
12
|
-
|
|
13
|
-
const toCssDecl = (css: string, v: unknown) => (v == null ? '' : `${css}: ${v};`)
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Converts a single property descriptor + theme values into a CSS fragment.
|
|
17
|
-
*
|
|
18
|
-
* - `simple` — pass-through (no unit conversion)
|
|
19
|
-
* - `convert` — number→rem via `calc()`
|
|
20
|
-
* - `convert_fallback` — picks first non-null from multiple theme keys, then converts
|
|
21
|
-
* - `edge` — delegates to the edge shorthand (margin, padding, inset, border-*)
|
|
22
|
-
* - `border_radius` — delegates to the border-radius shorthand
|
|
23
|
-
* - `special` — one-off logic (fullScreen, backgroundImage url wrapping, animation combo, etc.)
|
|
24
|
-
*
|
|
25
|
-
* IMPORTANT: special cases MUST return `css` tagged-template results,
|
|
26
|
-
* NOT plain strings. The caller (styles/index.ts) embeds these in another
|
|
27
|
-
* `css` template, and the interpolation chain requires template results
|
|
28
|
-
* for correct nesting of pseudo-selectors, media queries, and @layer
|
|
29
|
-
* wrapping. A previous "optimization" returned plain strings which broke
|
|
30
|
-
* responsive styles, hover states, and media-query generation.
|
|
31
|
-
*/
|
|
32
|
-
const processSpecial = (
|
|
33
|
-
d: Extract<PropertyDescriptor, { kind: 'special' }>,
|
|
34
|
-
t: InnerTheme,
|
|
35
|
-
css: Css,
|
|
36
|
-
): string | ReturnType<typeof css> => {
|
|
37
|
-
switch (d.id) {
|
|
38
|
-
case 'fullScreen':
|
|
39
|
-
if (!t.fullScreen) return ''
|
|
40
|
-
return css`
|
|
41
|
-
position: fixed;
|
|
42
|
-
top: 0;
|
|
43
|
-
left: 0;
|
|
44
|
-
right: 0;
|
|
45
|
-
bottom: 0;
|
|
46
|
-
`
|
|
47
|
-
|
|
48
|
-
case 'backgroundImage':
|
|
49
|
-
if (!t.backgroundImage) return ''
|
|
50
|
-
return css`
|
|
51
|
-
background-image: url(${t.backgroundImage});
|
|
52
|
-
`
|
|
53
|
-
|
|
54
|
-
case 'animation': {
|
|
55
|
-
const parts = [t.keyframe, t.animation].filter(Boolean).join(' ')
|
|
56
|
-
return parts ? `animation: ${parts};` : ''
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
case 'hideEmpty':
|
|
60
|
-
if (!t.hideEmpty) return ''
|
|
61
|
-
return css`
|
|
62
|
-
&:empty {
|
|
63
|
-
display: none;
|
|
64
|
-
}
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
case 'clearFix':
|
|
68
|
-
if (!t.clearFix) return ''
|
|
69
|
-
return css`
|
|
70
|
-
&::after {
|
|
71
|
-
clear: both;
|
|
72
|
-
content: '';
|
|
73
|
-
display: table;
|
|
74
|
-
}
|
|
75
|
-
`
|
|
76
|
-
|
|
77
|
-
case 'extendCss':
|
|
78
|
-
return (t.extendCss as string | undefined) ?? ''
|
|
79
|
-
|
|
80
|
-
default:
|
|
81
|
-
return ''
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const processDescriptor = (
|
|
86
|
-
d: PropertyDescriptor,
|
|
87
|
-
t: InnerTheme,
|
|
88
|
-
css: Css,
|
|
89
|
-
calc: Calc,
|
|
90
|
-
shorthand: ReturnType<Edge>,
|
|
91
|
-
borderRadiusFn: ReturnType<BorderRadius>,
|
|
92
|
-
): string | ReturnType<typeof css> => {
|
|
93
|
-
switch (d.kind) {
|
|
94
|
-
case 'simple':
|
|
95
|
-
return toCssDecl(d.css, t[d.key])
|
|
96
|
-
|
|
97
|
-
case 'convert':
|
|
98
|
-
return toCssDecl(d.css, calc(t[d.key]))
|
|
99
|
-
|
|
100
|
-
case 'convert_fallback':
|
|
101
|
-
return toCssDecl(d.css, calc(...d.keys.map((k) => t[k])))
|
|
102
|
-
|
|
103
|
-
case 'edge':
|
|
104
|
-
return (
|
|
105
|
-
shorthand(d.property, {
|
|
106
|
-
full: t[d.keys.full] as Value,
|
|
107
|
-
x: t[d.keys.x] as Value,
|
|
108
|
-
y: t[d.keys.y] as Value,
|
|
109
|
-
top: t[d.keys.top] as Value,
|
|
110
|
-
left: t[d.keys.left] as Value,
|
|
111
|
-
bottom: t[d.keys.bottom] as Value,
|
|
112
|
-
right: t[d.keys.right] as Value,
|
|
113
|
-
}) ?? ''
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
case 'border_radius':
|
|
117
|
-
return (
|
|
118
|
-
borderRadiusFn({
|
|
119
|
-
full: t[d.keys.full] as Value,
|
|
120
|
-
top: t[d.keys.top] as Value,
|
|
121
|
-
bottom: t[d.keys.bottom] as Value,
|
|
122
|
-
left: t[d.keys.left] as Value,
|
|
123
|
-
right: t[d.keys.right] as Value,
|
|
124
|
-
topLeft: t[d.keys.topLeft] as Value,
|
|
125
|
-
topRight: t[d.keys.topRight] as Value,
|
|
126
|
-
bottomLeft: t[d.keys.bottomLeft] as Value,
|
|
127
|
-
bottomRight: t[d.keys.bottomRight] as Value,
|
|
128
|
-
}) ?? ''
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
case 'special':
|
|
132
|
-
return processSpecial(d, t, css)
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export default processDescriptor
|