@cssxjs/runtime 0.2.30 → 0.2.32

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/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.2.32](https://github.com/startupjs/startupjs/compare/v0.2.31...v0.2.32) (2026-01-25)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **runtime:** support var() in shorthand values and in various complex cases ([4483f54](https://github.com/startupjs/startupjs/commit/4483f54d9507ebb38eb5f056de3fcac39862cb30))
12
+
13
+
14
+
15
+
16
+
17
+ ## [0.2.31](https://github.com/startupjs/startupjs/compare/v0.2.30...v0.2.31) (2026-01-23)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **runtime:** improve performance of substituting var() in css ([282cb46](https://github.com/startupjs/startupjs/commit/282cb461369cdb951cc873973a2d0da97a682b9b))
23
+
24
+
25
+
26
+
27
+
6
28
  ## [0.2.30](https://github.com/startupjs/startupjs/compare/v0.2.29...v0.2.30) (2026-01-18)
7
29
 
8
30
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cssxjs/runtime",
3
- "version": "0.2.30",
3
+ "version": "0.2.32",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -39,7 +39,8 @@
39
39
  "micro-memoize": "^3.0.1"
40
40
  },
41
41
  "devDependencies": {
42
- "@startupjs/css-to-react-native-transform": "2.1.0-2",
42
+ "@cssxjs/loaders": "^0.2.32",
43
+ "@startupjs/css-to-react-native-transform": "2.1.0-3",
43
44
  "mocha": "^8.1.1"
44
45
  },
45
46
  "peerDependencies": {
@@ -54,5 +55,5 @@
54
55
  "optional": true
55
56
  }
56
57
  },
57
- "gitHead": "2fd171f6da726008a2386471bd5be4b5291e49ab"
58
+ "gitHead": "2d5f40fdc99ec3cbfb397741444993e2d09d7975"
58
59
  }
package/process.js CHANGED
@@ -4,11 +4,8 @@ import singletonVariables, { defaultVariables } from './variables.js'
4
4
  import matcher from './matcher.js'
5
5
  import { isPureReact } from './platformHelpers/index.js'
6
6
 
7
- // TODO: Improve css variables performance. Instead of rerunning finding variables each time
8
- // it has to work as a pipeline and pass the variables from one step to the next.
9
-
10
- const VARS_REGEX = /"var\(\s*(--[A-Za-z0-9_-]+)\s*,?\s*(.*?)\s*\)"/g
11
- const HAS_VAR_REGEX = /"var\(/
7
+ // Regex to match var() anywhere within a string value (handles both full and partial)
8
+ const VARS_REGEX = /var\(\s*(--[A-Za-z0-9_-]+)\s*,?\s*([^)]*)\s*\)/g
12
9
  const SUPPORT_UNIT = true
13
10
 
14
11
  export function process (
@@ -65,63 +62,64 @@ export function process (
65
62
  return res
66
63
  }
67
64
 
68
- export function hasMedia (styles = {}) {
69
- for (const selector in styles) {
70
- if (/^@media/.test(selector)) {
71
- return true
65
+ function replaceVariablesInObject (obj) {
66
+ if (obj === null || obj === undefined) return obj
67
+ if (Array.isArray(obj)) {
68
+ return obj.map(item => replaceVariablesInObject(item))
69
+ }
70
+ if (typeof obj === 'object') {
71
+ const result = {}
72
+ for (const key of Object.keys(obj)) {
73
+ result[key] = replaceVariablesInObject(obj[key])
72
74
  }
75
+ return result
73
76
  }
74
- }
75
-
76
- export function hasVariables (...styleObjects) {
77
- for (const styleObject of styleObjects) {
78
- if (_hasVariables(styleObject)) return true
77
+ if (typeof obj === 'string' && obj.includes('var(')) {
78
+ return replaceVariablesInString(obj)
79
79
  }
80
+ return obj
80
81
  }
81
82
 
82
- function _hasVariables (styles = {}) {
83
- return HAS_VAR_REGEX.test(JSON.stringify(styles))
84
- }
85
-
86
- function replaceVariables (styles = {}) {
87
- let strStyles = JSON.stringify(styles)
88
- strStyles = strStyles.replace(VARS_REGEX, (match, varName, varDefault) => {
89
- let res
90
- res = singletonVariables[varName] ?? defaultVariables[varName] ?? varDefault
83
+ function replaceVariablesInString (str) {
84
+ // Replace all var() occurrences in the string
85
+ const result = str.replace(VARS_REGEX, (match, varName, varDefault) => {
86
+ let res = singletonVariables[varName] ?? defaultVariables[varName] ?? varDefault
91
87
  if (typeof res === 'string') {
92
88
  res = res.trim()
93
- // replace 'px' value with a pure number
94
- res = res.replace(/px$/, '')
95
89
  // sometimes compiler returns wrapped brackets. Remove them
96
90
  const bracketsCount = res.match(/^\(+/)?.[0]?.length || 0
97
91
  res = res.substring(bracketsCount, res.length - bracketsCount)
98
92
  }
99
- if (!isNumeric(res)) {
100
- res = `"${res}"`
101
- }
102
93
  return res
103
94
  })
104
- return JSON.parse(strStyles)
95
+
96
+ // After all replacements, check if the result is a pure numeric value
97
+ // If so, convert it to a number (stripping 'px' suffix if present)
98
+ const trimmed = result.trim()
99
+ const withoutPx = trimmed.replace(/px$/, '')
100
+ if (isNumeric(withoutPx)) {
101
+ return parseFloat(withoutPx)
102
+ }
103
+
104
+ return result
105
105
  }
106
106
 
107
107
  function transformStyles (styles) {
108
- if (styles) {
109
- // trigger rerender when cache is NOT used
110
- if (hasMedia(styles)) listenForDimensionsChange()
108
+ if (!styles) return {}
111
109
 
112
- // dynamically process @media queries and vh/vw units
113
- styles = dynamicProcess(styles)
110
+ // Dynamically process css variables.
111
+ // This will also auto-trigger rerendering on variable change when cache is not used
112
+ if (styles.__vars) {
113
+ styles = replaceVariablesInObject(styles)
114
+ }
114
115
 
115
- if (hasVariables(styles)) {
116
- // Dynamically process css variables.
117
- // This will also auto-trigger rerendering on variable change when cache is not used
118
- styles = replaceVariables(styles)
119
- }
116
+ // trigger rerender when cache is NOT used
117
+ if (styles.__hasMedia) listenForDimensionsChange()
120
118
 
121
- return styles
122
- } else {
123
- return {}
124
- }
119
+ // dynamically process @media queries and vh/vw units
120
+ styles = dynamicProcess(styles)
121
+
122
+ return styles
125
123
  }
126
124
 
127
125
  // If @media is used, force trigger access to the observable value.
package/processCached.js CHANGED
@@ -1,9 +1,7 @@
1
1
  import { singletonMemoize } from 'teamplay/cache'
2
2
  import dimensions from './dimensions.js'
3
3
  import singletonVariables from './variables.js'
4
- import { process as _process, hasMedia, listenForDimensionsChange, hasVariables } from './process.js'
5
-
6
- const VAR_NAMES_REGEX = /"var\(\s*--[A-Za-z0-9_-]+/g
4
+ import { process as _process, listenForDimensionsChange } from './process.js'
7
5
 
8
6
  export const process = singletonMemoize(_process, {
9
7
  cacheName: 'styles',
@@ -18,7 +16,7 @@ export const process = singletonMemoize(_process, {
18
16
  // IMPORTANT: This should be the same as the ones which go into the singletonMemoize function
19
17
  forceUpdateWhenChanged: (styleName, fileStyles, globalStyles, localStyles, inlineStyleProps) => {
20
18
  const args = {}
21
- const watchWidthChange = hasMedia(fileStyles) || hasMedia(globalStyles) || hasMedia(localStyles)
19
+ const watchWidthChange = fileStyles?.__hasMedia || globalStyles?.__hasMedia || localStyles?.__hasMedia
22
20
  if (watchWidthChange) {
23
21
  // trigger rerender when cache is used
24
22
  listenForDimensionsChange()
@@ -26,7 +24,7 @@ export const process = singletonMemoize(_process, {
26
24
  // the affected cache to recalculate
27
25
  args.dimensionsWidth = dimensions.width
28
26
  }
29
- if (hasVariables(fileStyles, globalStyles, localStyles)) {
27
+ if (fileStyles?.__vars || globalStyles?.__vars || localStyles?.__vars) {
30
28
  const variableNames = getVariableNames(fileStyles, globalStyles, localStyles)
31
29
  // trigger rerender when cache is used
32
30
  listenForVariablesChange(variableNames)
@@ -41,18 +39,14 @@ export const process = singletonMemoize(_process, {
41
39
  })
42
40
 
43
41
  function getVariableNames (...styleObjects) {
44
- let res = []
42
+ const vars = []
45
43
  for (const styleObject of styleObjects) {
46
- res = res.concat(_getVariableNames(styleObject))
44
+ if (!styleObject?.__vars) continue
45
+ for (const varName of styleObject.__vars) {
46
+ if (!vars.includes(varName)) vars.push(varName)
47
+ }
47
48
  }
48
- res = [...new Set(res)].sort() // remove duplicates and sort
49
- return res
50
- }
51
-
52
- function _getVariableNames (styles = {}) {
53
- let res = JSON.stringify(styles).match(VAR_NAMES_REGEX) || []
54
- res = res.map(i => i.replace(/"var\(\s*/, ''))
55
- return res
49
+ return vars.sort()
56
50
  }
57
51
 
58
52
  // If var() is used, force trigger access to the observable value.