react-native-unistyles 2.0.0-alpha.5 → 2.0.0-alpha.7

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 (100) hide show
  1. package/cxx/UnistylesRuntime.cpp +262 -0
  2. package/cxx/UnistylesRuntime.h +61 -0
  3. package/lib/commonjs/Unistyles.js +1 -1
  4. package/lib/commonjs/Unistyles.js.map +1 -1
  5. package/lib/commonjs/UnistylesEngine.js +9 -5
  6. package/lib/commonjs/UnistylesEngine.js.map +1 -1
  7. package/lib/commonjs/createStyleSheet.js.map +1 -1
  8. package/lib/commonjs/index.js +7 -0
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/types/cxx.js.map +1 -1
  11. package/lib/commonjs/useStyles.js +0 -2
  12. package/lib/commonjs/useStyles.js.map +1 -1
  13. package/lib/commonjs/useUnistyles.js.map +1 -1
  14. package/lib/commonjs/utils/breakpoints.js +11 -68
  15. package/lib/commonjs/utils/breakpoints.js.map +1 -1
  16. package/lib/commonjs/utils/common.js +3 -1
  17. package/lib/commonjs/utils/common.js.map +1 -1
  18. package/lib/commonjs/utils/index.js +8 -0
  19. package/lib/commonjs/utils/index.js.map +1 -1
  20. package/lib/commonjs/utils/mediaQueries.js +57 -155
  21. package/lib/commonjs/utils/mediaQueries.js.map +1 -1
  22. package/lib/commonjs/utils/mq.js +75 -0
  23. package/lib/commonjs/utils/mq.js.map +1 -0
  24. package/lib/commonjs/utils/styles.js +11 -51
  25. package/lib/commonjs/utils/styles.js.map +1 -1
  26. package/lib/module/Unistyles.js +2 -2
  27. package/lib/module/Unistyles.js.map +1 -1
  28. package/lib/module/UnistylesEngine.js +7 -3
  29. package/lib/module/UnistylesEngine.js.map +1 -1
  30. package/lib/module/createStyleSheet.js.map +1 -1
  31. package/lib/module/index.js +1 -0
  32. package/lib/module/index.js.map +1 -1
  33. package/lib/module/types/cxx.js.map +1 -1
  34. package/lib/module/useStyles.js +0 -3
  35. package/lib/module/useStyles.js.map +1 -1
  36. package/lib/module/useUnistyles.js.map +1 -1
  37. package/lib/module/utils/breakpoints.js +11 -68
  38. package/lib/module/utils/breakpoints.js.map +1 -1
  39. package/lib/module/utils/common.js +2 -0
  40. package/lib/module/utils/common.js.map +1 -1
  41. package/lib/module/utils/index.js +1 -0
  42. package/lib/module/utils/index.js.map +1 -1
  43. package/lib/module/utils/mediaQueries.js +57 -155
  44. package/lib/module/utils/mediaQueries.js.map +1 -1
  45. package/lib/module/utils/mq.js +69 -0
  46. package/lib/module/utils/mq.js.map +1 -0
  47. package/lib/module/utils/styles.js +10 -51
  48. package/lib/module/utils/styles.js.map +1 -1
  49. package/lib/typescript/src/Unistyles.d.ts +2 -2
  50. package/lib/typescript/src/Unistyles.d.ts.map +1 -1
  51. package/lib/typescript/src/UnistylesEngine.d.ts +4 -1
  52. package/lib/typescript/src/UnistylesEngine.d.ts.map +1 -1
  53. package/lib/typescript/src/createStyleSheet.d.ts +2 -5
  54. package/lib/typescript/src/createStyleSheet.d.ts.map +1 -1
  55. package/lib/typescript/src/index.d.ts +1 -0
  56. package/lib/typescript/src/index.d.ts.map +1 -1
  57. package/lib/typescript/src/types/breakpoints.d.ts +2 -1
  58. package/lib/typescript/src/types/breakpoints.d.ts.map +1 -1
  59. package/lib/typescript/src/types/core.d.ts +18 -16
  60. package/lib/typescript/src/types/core.d.ts.map +1 -1
  61. package/lib/typescript/src/types/cxx.d.ts +7 -1
  62. package/lib/typescript/src/types/cxx.d.ts.map +1 -1
  63. package/lib/typescript/src/types/index.d.ts +1 -1
  64. package/lib/typescript/src/types/index.d.ts.map +1 -1
  65. package/lib/typescript/src/types/mediaQueries.d.ts +5 -3
  66. package/lib/typescript/src/types/mediaQueries.d.ts.map +1 -1
  67. package/lib/typescript/src/useStyles.d.ts +2 -4
  68. package/lib/typescript/src/useStyles.d.ts.map +1 -1
  69. package/lib/typescript/src/useUnistyles.d.ts +4 -5
  70. package/lib/typescript/src/useUnistyles.d.ts.map +1 -1
  71. package/lib/typescript/src/utils/breakpoints.d.ts +2 -60
  72. package/lib/typescript/src/utils/breakpoints.d.ts.map +1 -1
  73. package/lib/typescript/src/utils/common.d.ts +2 -0
  74. package/lib/typescript/src/utils/common.d.ts.map +1 -1
  75. package/lib/typescript/src/utils/index.d.ts +1 -0
  76. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  77. package/lib/typescript/src/utils/mediaQueries.d.ts +8 -127
  78. package/lib/typescript/src/utils/mediaQueries.d.ts.map +1 -1
  79. package/lib/typescript/src/utils/mq.d.ts +15 -0
  80. package/lib/typescript/src/utils/mq.d.ts.map +1 -0
  81. package/lib/typescript/src/utils/styles.d.ts +1 -46
  82. package/lib/typescript/src/utils/styles.d.ts.map +1 -1
  83. package/package.json +10 -1
  84. package/src/Unistyles.ts +3 -3
  85. package/src/UnistylesEngine.ts +12 -3
  86. package/src/createStyleSheet.ts +2 -5
  87. package/src/index.ts +1 -0
  88. package/src/types/breakpoints.ts +6 -3
  89. package/src/types/core.ts +25 -22
  90. package/src/types/cxx.ts +8 -1
  91. package/src/types/index.ts +1 -1
  92. package/src/types/mediaQueries.ts +9 -4
  93. package/src/useStyles.ts +3 -6
  94. package/src/useUnistyles.ts +11 -4
  95. package/src/utils/breakpoints.ts +14 -71
  96. package/src/utils/common.ts +2 -0
  97. package/src/utils/index.ts +1 -0
  98. package/src/utils/mediaQueries.ts +102 -163
  99. package/src/utils/mq.ts +77 -0
  100. package/src/utils/styles.ts +13 -55
@@ -1,92 +1,110 @@
1
+ import type { UnistylesBreakpoints } from 'react-native-unistyles'
1
2
  import type { ScreenSize } from '../types'
3
+ import type { MediaQueries } from '../types'
4
+
5
+ const parseLhs = (lhs: string, breakpoints: UnistylesBreakpoints, hasRhs: boolean) => {
6
+ const matches = lhs.match(/([([])|([^[\]()]+)|([\])])/g)
7
+
8
+ if (!hasRhs) {
9
+ const [openBracket, value, closeBracket] = matches as [string, string, string]
10
+ const spacelessValue = value?.trim()
11
+ const parsedNumber = Number(spacelessValue)
12
+
13
+ const parsedValue = isNaN(parsedNumber)
14
+ ? breakpoints[spacelessValue as keyof UnistylesBreakpoints] as number
15
+ : parsedNumber
16
+
17
+ return [
18
+ Number(openBracket === '('),
19
+ closeBracket === ')'
20
+ ? parsedValue - 1
21
+ : parsedValue
22
+ ]
23
+ }
24
+
25
+ const [openBracket, value] = matches as [string, string]
2
26
 
3
- /**
4
- * Extracts numeric values from a coded string.
5
- *
6
- * The function is designed to process strings that have a format like "w[100,200]" or "h[300]".
7
- * It removes characters 'w', 'h', '[', and ']' from the input string and then extracts the numbers.
8
- *
9
- * @param {string} codedValue - The input string to extract values from.
10
- * @returns {Array<number>} An array of extracted numbers. Can contain one or two numbers based on the input format.
11
- *
12
- * @example
13
- * extractValues("w[100,200]") // returns [100, 200]
14
- * extractValues("h[300]") // returns [300]
15
- * extractValues("h[,300]") // returns [0,300]
16
- * extractValues("h[100,]") // returns [100]
17
- */
18
- export const extractValues = (codedValue: string): Array<number> => {
19
- const cleanedValue = codedValue.replace(/[wh ]/g, '')
20
- const [left, right] = cleanedValue.split(',') as [string, string | undefined]
21
-
22
- if (!right) {
23
- const lh = left.startsWith('[')
24
- ? Number(left.replace(/[[\]()]/g, ''))
25
- : Number(left.replace(/[[\]()]/g, '')) + 1
26
-
27
- return [lh]
27
+ if (!value) {
28
+ return [Number(openBracket === '(')]
28
29
  }
29
30
 
30
- const lh = left.startsWith('[')
31
- ? Number(left.replace('[', ''))
32
- : Number(left.replace('(', '')) + 1
33
- const rh = right.endsWith(']')
34
- ? Number(right.replace(']', ''))
35
- : Number(right.replace(')', '')) - 1
31
+ const spacelessValue = value?.trim()
32
+ const parsedNumber = Number(spacelessValue)
33
+
34
+ const parsedValue = isNaN(parsedNumber)
35
+ ? breakpoints[spacelessValue as keyof UnistylesBreakpoints] as number
36
+ : parsedNumber
37
+
38
+ return openBracket === '('
39
+ ? [parsedValue - 1]
40
+ : [parsedValue]
41
+ }
36
42
 
37
- return [lh, rh]
43
+ const parseRhs = (rhs: string, breakpoints: UnistylesBreakpoints) => {
44
+ const matches = rhs.match(/([([])|([^[\]()]+)|([\])])/g)
45
+ const [value, closeBrackets] = matches as [string, string]
46
+ const spacelessValue = value.trim()
47
+ const parsedNumber = Number(spacelessValue)
48
+
49
+ const parsedValue = isNaN(parsedNumber)
50
+ ? breakpoints[spacelessValue as keyof UnistylesBreakpoints] as number
51
+ : parsedNumber
52
+
53
+ return [
54
+ closeBrackets === ')'
55
+ ? parsedValue - 1
56
+ : parsedValue
57
+ ]
38
58
  }
39
59
 
40
- /**
41
- * Determines if the given screen size matches the specified breakpoint query.
42
- *
43
- * The function checks if the screen size (width and/or height) falls within the range
44
- * specified by the breakpoint query. The query can specify width (using 'w'), height (using 'h'),
45
- * or both.
46
- *
47
- * @param {string} query - The breakpoint query string. Examples: 'w[100,200]', 'h[300]', 'w[100,200]h[300,400]'.
48
- * @param {ScreenSize} screenSize - The screen size to check against the breakpoint query.
49
- * @returns {boolean} True if the screen size matches the breakpoint query, false otherwise.
50
- *
51
- * @example
52
- * const screenSize = { width: 150, height: 350 }
53
- * isWithinBreakpoint('w[100,200]', screenSize) // returns true
54
- * isWithinBreakpoint('h[400]', screenSize) // returns false
55
- */
56
- export const isWithinBreakpoint = (query: string, screenSize: ScreenSize): boolean => {
57
- if (query.includes('w') && query.includes('h')) {
58
- return isWithinTheWidthAndHeight(query, screenSize)
60
+ export const extractValues = (pattern: string, breakpoints: UnistylesBreakpoints): Array<number> => {
61
+ const [lhs, rhs] = pattern
62
+ .replace(/(:w|:h)/g, '')
63
+ .split(',') as [string, string | undefined]
64
+
65
+ if (!rhs) {
66
+ return parseLhs(lhs, breakpoints, false)
67
+ }
68
+
69
+ const [parsedLhs] = parseLhs(lhs, breakpoints, true)
70
+
71
+ if (parsedLhs === undefined || isNaN(parsedLhs)) {
72
+ return []
73
+ }
74
+
75
+ const [parsedRhs] = parseRhs(rhs, breakpoints)
76
+
77
+ if (parsedRhs === undefined || isNaN(parsedRhs)) {
78
+ return []
79
+ }
80
+
81
+ return [
82
+ parsedLhs,
83
+ parsedRhs
84
+ ]
85
+ }
86
+
87
+ export const isWithinBreakpoint = (query: string, screenSize: ScreenSize, breakpoints: UnistylesBreakpoints): boolean => {
88
+ const hasWidthBreakpoint = query.includes(':w')
89
+ const hasHeightBreakpoint = query.includes(':h')
90
+
91
+ if (hasWidthBreakpoint && hasHeightBreakpoint) {
92
+ return isWithinTheWidthAndHeight(query, screenSize, breakpoints)
59
93
  }
60
94
 
61
- if (query.charAt(0) === 'w') {
62
- return isWithinTheWidth(query, screenSize.width)
95
+ if (hasWidthBreakpoint) {
96
+ return isWithinTheWidth(query, screenSize.width, breakpoints)
63
97
  }
64
98
 
65
- if (query.charAt(0) === 'h') {
66
- return isWithinTheHeight(query, screenSize.height)
99
+ if (hasHeightBreakpoint) {
100
+ return isWithinTheHeight(query, screenSize.height, breakpoints)
67
101
  }
68
102
 
69
103
  return false
70
104
  }
71
105
 
72
- /**
73
- * Determines if the given width matches the specified width range in the query.
74
- *
75
- * The function checks if the provided width falls within the range specified by the query.
76
- * The query specifies a width range using a format like 'w[100,200]'. If only one value is provided,
77
- * it's treated as a minimum width.
78
- *
79
- * @param {string} query - The width query string. Examples: 'w[100,200]' or 'w[100]'.
80
- * @param {number} width - The width to check against the query.
81
- * @returns {boolean} True if the width matches the query range, false otherwise.
82
- *
83
- * @example
84
- * isWithinTheWidth('w[100,200]', 150) // returns true
85
- * isWithinTheWidth('w[100]', 50) // returns false
86
- * isWithinTheWidth('w[100]', 150) // returns true
87
- */
88
- export const isWithinTheWidth = (query: string, width: number): boolean => {
89
- const [minWidth, maxWidth] = extractValues(query) as [number, number | undefined]
106
+ export const isWithinTheWidth = (query: string, width: number, breakpoints: UnistylesBreakpoints): boolean => {
107
+ const [minWidth, maxWidth] = extractValues(query, breakpoints) as [number, number | undefined]
90
108
 
91
109
  if (maxWidth && width >= minWidth && width <= maxWidth) {
92
110
  return true
@@ -95,24 +113,8 @@ export const isWithinTheWidth = (query: string, width: number): boolean => {
95
113
  return !maxWidth && width >= minWidth
96
114
  }
97
115
 
98
- /**
99
- * Determines if the given height matches the specified height range in the query.
100
- *
101
- * The function checks if the provided height falls within the range specified by the query.
102
- * The query specifies a height range using a format like 'h[100,200]'. If only one value is provided,
103
- * it's treated as a minimum height.
104
- *
105
- * @param {string} query - The height query string. Examples: 'h[100,200]' or 'h[100]'.
106
- * @param {number} height - The height to check against the query.
107
- * @returns {boolean} True if the height matches the query range, false otherwise.
108
- *
109
- * @example
110
- * isWithinTheHeight('h[100,200]', 150) // returns true
111
- * isWithinTheHeight('h[100]', 50) // returns false
112
- * isWithinTheHeight('h[100]', 150) // returns true
113
- */
114
- export const isWithinTheHeight = (query: string, height: number): boolean => {
115
- const [minHeight, maxHeight] = extractValues(query) as [number, number | undefined]
116
+ export const isWithinTheHeight = (query: string, height: number, breakpoints: UnistylesBreakpoints): boolean => {
117
+ const [minHeight, maxHeight] = extractValues(query, breakpoints) as [number, number | undefined]
116
118
 
117
119
  if (maxHeight && height >= minHeight && height <= maxHeight) {
118
120
  return true
@@ -121,92 +123,29 @@ export const isWithinTheHeight = (query: string, height: number): boolean => {
121
123
  return !maxHeight && height >= minHeight
122
124
  }
123
125
 
124
- /**
125
- * Determines if the given screen size matches both the specified width and height ranges in the query.
126
- *
127
- * The function checks if the provided screen size (both width and height) falls within the ranges
128
- * specified by the query. The query can specify both width and height using a format like 'w[100,200]:h[300,400]'.
129
- *
130
- * @param {string} query - The combined width and height query string. Example: 'w[100,200]:h[300,400]'.
131
- * @param {ScreenSize} screenSize - The screen size to check against the query.
132
- * @returns {boolean} True if the screen size matches both the width and height ranges in the query, false otherwise.
133
- *
134
- * @example
135
- * const screenSize = { width: 150, height: 350 }
136
- * isWithinTheWidthAndHeight('w[100,200]:h[300,400]', screenSize) // returns true
137
- * isWithinTheWidthAndHeight('w[100,200]:h[400,500]', screenSize) // returns false
138
- */
139
- export const isWithinTheWidthAndHeight = (query: string, screenSize: ScreenSize): boolean => {
126
+ export const isWithinTheWidthAndHeight = (query: string, screenSize: ScreenSize, breakpoints: UnistylesBreakpoints): boolean => {
140
127
  const result = query
141
128
  .split(':')
142
129
  .filter(Boolean)
143
- .map(q => isWithinBreakpoint(q, screenSize))
130
+ .map(q => isWithinBreakpoint(`:${q}`, screenSize, breakpoints))
144
131
  .filter(Boolean)
145
132
 
146
133
  return result.length === 2
147
134
  }
148
135
 
149
- /**
150
- * Checks if the given query string is a valid custom media query.
151
- *
152
- * The valid custom media query formats include:
153
- * - :w[200]
154
- * - :w[0, 200]
155
- * - :w[, 300]
156
- * - :h[200]
157
- * - :h[0, 500]
158
- * - :h[,200]
159
- * - :w[100, 300]:h[200,500]
160
- * - :h[200,500]:w[100, 300]
161
- *
162
- * @param {string} query - The query string to be checked.
163
- * @returns {boolean} Returns `true` if the query is a valid custom media query, otherwise `false`.
164
- * @example
165
- *
166
- * isMediaQuery(':w[200]') // true
167
- * isMediaQuery(':w100]') // false
168
- */
169
136
  export const isMediaQuery = (query: string): boolean => {
170
- const regex = /^(?:(:w\[\d*(?:,\s?\d+)?])?(:h\[\d*(?:,\s?\d+)?])?|(:h\[\d*(?:,\s?\d+)?])?(:w\[\d*(?:,\s?\d+)?])?)$/
137
+ const regex = /(:w|:h)/
171
138
 
172
139
  return query.length > 0 && regex.test(query)
173
140
  }
174
141
 
175
- /**
176
- * Retrieves the first matching custom media query key based on the provided screen size.
177
- *
178
- * The function processes an array of media queries and returns the first query that matches
179
- * the given screen size. The media queries can be in formats like:
180
- * - w[200]
181
- * - w[0, 200]
182
- * - w[, 300]
183
- * - h[200]
184
- * - h[0, 500]
185
- * - h[,200]
186
- * - w[100, 300]:h[200,500]
187
- * - h[200,500]:w[100, 300]
188
- *
189
- * @param {Array<[string, string | number]>} mediaQueries - An array of tuples containing media query keys and associated values.
190
- * @param {ScreenSize} screenSize - An object representing the screen size to be checked against the media queries.
191
- * @returns {string | undefined} Returns the first matching media query key or `undefined` if no match is found.
192
- * @example
193
- *
194
- * const queries = [[':w[200]', 'value1'], [':h[300,500]', 'value2']]
195
- * const size = { width: 250, height: 400 }
196
- * getKeyForCustomMediaQuery(queries, size) // ':w[200]
197
- */
198
- export const getKeyForCustomMediaQuery = (mediaQueries: Array<[string, string | number | undefined]>, screenSize: ScreenSize): string | undefined => {
142
+ export const getKeyForCustomMediaQuery = (
143
+ mediaQueries: Array<[keyof UnistylesBreakpoints | MediaQueries, string | number | undefined]>,
144
+ screenSize: ScreenSize,
145
+ breakpoints: UnistylesBreakpoints
146
+ ): string | undefined => {
199
147
  const [matchedQuery] = mediaQueries
200
- .flatMap(([key]) => {
201
- if (key.includes('w') && key.includes('h')) {
202
- return isWithinBreakpoint(key, screenSize) ? key : undefined
203
- }
204
-
205
- return key
206
- .split(':')
207
- .filter(Boolean)
208
- .map(query => isWithinBreakpoint(query, screenSize) ? key : undefined)
209
- })
148
+ .flatMap(([key]) => isWithinBreakpoint(key, screenSize, breakpoints) ? key : undefined)
210
149
  .filter(Boolean)
211
150
 
212
151
  return matchedQuery
@@ -0,0 +1,77 @@
1
+ import type { UnistylesBreakpoints } from '../global'
2
+ import { unistyles } from '../Unistyles'
3
+
4
+ const MQSymbol = Symbol('unistyles-mq')
5
+
6
+ type MQValue = keyof UnistylesBreakpoints | number
7
+
8
+ type HeightHandler = {
9
+ width(wMin?: MQValue, wMax?: MQValue): typeof MQSymbol
10
+ } & typeof MQSymbol
11
+
12
+ type WidthHandler = {
13
+ height(hMin?: MQValue, hMax?: MQValue): typeof MQSymbol
14
+ } & typeof MQSymbol
15
+
16
+ type FinalHandler = {
17
+ [MQSymbol]: true
18
+ }
19
+
20
+ enum MQProp {
21
+ toString = 'toString',
22
+ width = 'width',
23
+ height = 'height'
24
+ }
25
+
26
+ const getMQValue = (value: MQValue) => {
27
+ if (typeof value === 'number') {
28
+ return value
29
+ }
30
+
31
+ return unistyles.registry.breakpoints[value] ?? 0
32
+ }
33
+
34
+ export const mq = {
35
+ height: (hMin: MQValue = 0, hMax: MQValue = Infinity) => new Proxy<HeightHandler>({} as HeightHandler, {
36
+ get: (target, prop, receiver) => {
37
+ if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
38
+ return () => `:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
39
+ }
40
+
41
+ if (prop === MQProp.width) {
42
+ return (wMin: MQValue = 0, wMax: MQValue = Infinity) => new Proxy<FinalHandler>({} as FinalHandler, {
43
+ get: (target, prop, receiver) => {
44
+ if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
45
+ return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
46
+ }
47
+
48
+ return Reflect.get(target, prop, receiver)
49
+ }
50
+ })
51
+ }
52
+
53
+ return Reflect.get(target, prop, receiver)
54
+ }
55
+ }),
56
+ width: (wMin: MQValue = 0, wMax: MQValue = Infinity) => new Proxy({} as WidthHandler, {
57
+ get: (target, prop, receiver) => {
58
+ if (prop === Symbol.toPrimitive || prop === MQProp.toString) {
59
+ return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]`
60
+ }
61
+
62
+ if (prop === MQProp.height) {
63
+ return (hMin: MQValue = 0, hMax: MQValue = Infinity) => new Proxy<FinalHandler>({} as FinalHandler, {
64
+ get: (target, prop, receiver) => {
65
+ if (prop === Symbol.toPrimitive || MQProp.toString) {
66
+ return () => `:w[${getMQValue(wMin)}, ${getMQValue(wMax)}]:h[${getMQValue(hMin)}, ${getMQValue(hMax)}]`
67
+ }
68
+
69
+ return Reflect.get(target, prop, receiver)
70
+ }
71
+ })
72
+ }
73
+
74
+ return Reflect.get(target, prop, receiver)
75
+ }
76
+ })
77
+ }
@@ -1,30 +1,9 @@
1
- import type { CustomNamedStyles, ScreenSize } from '../types'
1
+ import type { CustomNamedStyles, MediaQueries, ScreenSize } from '../types'
2
2
  import { getValueForBreakpoint } from './breakpoints'
3
3
  import { normalizeStyles } from './normalizeStyles'
4
- import { isWeb } from './common'
5
4
  import type { UnistylesBreakpoints } from '../global'
5
+ import { isAndroid, isIOS, isWeb } from './common'
6
6
 
7
- /**
8
- * Proxies a function to parse its return value for custom media queries or breakpoints.
9
- *
10
- * @template B - An object type where keys represent breakpoint names and values represent breakpoint values.
11
- *
12
- * @param {Function} fn - The function to be proxified.
13
- * @param {keyof B & string} breakpoint - The breakpoint name to check against.
14
- * @param {ScreenSize} screenSize - An object representing the screen size to be checked against the media queries.
15
- * @param breakpointPairs - sorted pairs of breakpoints
16
- *
17
- * @returns {Function} Returns the proxified function
18
- *
19
- * @example
20
- *
21
- * const myFunction = () => ({ ':w[200]': 'value1', sm: 'value2' })
22
- * const screenSize = { width: 250, height: 400 }
23
- * const breakpoints = { sm: 300, md: 600 }
24
- *
25
- * const proxifiedFunction = proxifyFunction(myFunction, 'sm', screenSize, breakpoints)
26
- * proxifiedFunction() // parsed style based on screenSize and breakpoints
27
- */
28
7
  export const proxifyFunction = (
29
8
  fn: Function, breakpoint: keyof UnistylesBreakpoints & string,
30
9
  screenSize: ScreenSize
@@ -33,37 +12,20 @@ export const proxifyFunction = (
33
12
  parseStyle(target.apply(thisArg, argumentsList), breakpoint, screenSize)
34
13
  })
35
14
 
36
- /**
37
- * Parses a style object to resolve custom media queries or breakpoints based on the provided screen size and breakpoints.
38
- *
39
- * The function processes each key-value pair in the style object. If the value is a function or a valid style (not an object or a 'transform' key),
40
- * it is returned as-is. Otherwise, the function attempts to resolve the value based on the provided breakpoint, screen size, and defined breakpoints.
41
- *
42
- * @template T - The type of the style object.
43
- * @template B - An object type where keys represent breakpoint names and values represent breakpoint values.
44
- *
45
- * @param {CustomNamedStyles<T, B>} style - The style object to be parsed.
46
- * @param {keyof B & string} breakpoint - The breakpoint name to check against.
47
- * @param {ScreenSize} screenSize - An object representing the screen size to be checked against the media queries.
48
- * @param breakpointPairs - sorted pairs of breakpoints
49
- *
50
- * @returns {Record<string, string | number | Function>} Returns the parsed style object with resolved custom media queries or breakpoints.
51
- *
52
- * @example
53
- *
54
- * const style = { fontSize: { sm: '12px', md: '16px' } }
55
- * const screenSize = { width: 300, height: 400 }
56
- * const breakpoints = { xs: 0, sm: 300, md: 600 }
57
- *
58
- * const parsedStyle = parseStyle(style, 'sm', screenSize, breakpoints)
59
- * // { fontSize: '12px' }
60
- */
15
+ export const isPlatformColor = <T extends {}>(value: T): boolean => {
16
+ if (isIOS) {
17
+ return 'semantic' in value && typeof value.semantic === 'object'
18
+ }
19
+
20
+ return isAndroid && 'resource_paths' in value && typeof value.resource_paths === 'object'
21
+ }
22
+
61
23
  export const parseStyle = <T>(
62
24
  style: CustomNamedStyles<T>,
63
25
  breakpoint: keyof UnistylesBreakpoints & string,
64
26
  screenSize: ScreenSize
65
27
  ): T => {
66
- const entries = Object.entries(style) as [[
28
+ const entries = Object.entries(style || {}) as [[
67
29
  keyof T,
68
30
  CustomNamedStyles<T> | Record<keyof UnistylesBreakpoints & string, string | number | undefined>]
69
31
  ]
@@ -90,7 +52,7 @@ export const parseStyle = <T>(
90
52
  }
91
53
 
92
54
  const isDynamicFunction = typeof value === 'function'
93
- const isValidStyle = typeof value !== 'object'
55
+ const isValidStyle = typeof value !== 'object' || isPlatformColor(value)
94
56
 
95
57
  if (isDynamicFunction || isValidStyle) {
96
58
  return [key, value]
@@ -98,11 +60,7 @@ export const parseStyle = <T>(
98
60
 
99
61
  return [
100
62
  key,
101
- getValueForBreakpoint(
102
- value as Record<keyof UnistylesBreakpoints & string, string | number | undefined>,
103
- breakpoint,
104
- screenSize
105
- )
63
+ getValueForBreakpoint(value as Record<keyof UnistylesBreakpoints | MediaQueries, string | number | undefined>)
106
64
  ]
107
65
  })
108
66
  )