@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.
Files changed (50) hide show
  1. package/package.json +7 -9
  2. package/src/__tests__/alignContent.test.ts +0 -121
  3. package/src/__tests__/borderRadius.test.ts +0 -125
  4. package/src/__tests__/camelToKebab.test.ts +0 -44
  5. package/src/__tests__/context.test.ts +0 -147
  6. package/src/__tests__/createMediaQueries.test.ts +0 -98
  7. package/src/__tests__/edge.test.ts +0 -164
  8. package/src/__tests__/enrichTheme.test.ts +0 -56
  9. package/src/__tests__/extendCss.test.ts +0 -45
  10. package/src/__tests__/index.test.ts +0 -79
  11. package/src/__tests__/makeItResponsive.test.ts +0 -431
  12. package/src/__tests__/manifest-snapshot.test.ts +0 -34
  13. package/src/__tests__/native-marker.test.ts +0 -9
  14. package/src/__tests__/optimizeBreakpointDeltas.test.ts +0 -124
  15. package/src/__tests__/processDescriptor.test.ts +0 -322
  16. package/src/__tests__/responsive.test.ts +0 -221
  17. package/src/__tests__/special-keys.test.ts +0 -120
  18. package/src/__tests__/styles.test.ts +0 -273
  19. package/src/__tests__/unistyle.browser.test.tsx +0 -169
  20. package/src/__tests__/units.test.ts +0 -134
  21. package/src/context.tsx +0 -44
  22. package/src/enrichTheme.ts +0 -42
  23. package/src/env.d.ts +0 -6
  24. package/src/index.ts +0 -91
  25. package/src/manifest.ts +0 -197
  26. package/src/responsive/breakpoints.ts +0 -15
  27. package/src/responsive/createMediaQueries.ts +0 -43
  28. package/src/responsive/index.ts +0 -15
  29. package/src/responsive/makeItResponsive.ts +0 -223
  30. package/src/responsive/normalizeTheme.ts +0 -79
  31. package/src/responsive/optimizeBreakpointDeltas.ts +0 -190
  32. package/src/responsive/optimizeTheme.ts +0 -60
  33. package/src/responsive/sortBreakpoints.ts +0 -10
  34. package/src/responsive/transformTheme.ts +0 -54
  35. package/src/styles/alignContent.ts +0 -62
  36. package/src/styles/extendCss.ts +0 -26
  37. package/src/styles/index.ts +0 -16
  38. package/src/styles/shorthands/borderRadius.ts +0 -89
  39. package/src/styles/shorthands/edge.ts +0 -108
  40. package/src/styles/shorthands/index.ts +0 -4
  41. package/src/styles/styles/camelToKebab.ts +0 -3
  42. package/src/styles/styles/index.ts +0 -132
  43. package/src/styles/styles/processDescriptor.ts +0 -136
  44. package/src/styles/styles/propertyMap.ts +0 -438
  45. package/src/styles/styles/types.ts +0 -368
  46. package/src/types.ts +0 -175
  47. package/src/units/index.ts +0 -6
  48. package/src/units/stripUnit.ts +0 -25
  49. package/src/units/value.ts +0 -47
  50. 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