@tamagui/web 2.0.0-1768427228811 → 2.0.0-1768586279389
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/dist/cjs/_withStableStyle.cjs +5 -2
- package/dist/cjs/_withStableStyle.js +3 -3
- package/dist/cjs/_withStableStyle.js.map +1 -1
- package/dist/cjs/_withStableStyle.native.js +10 -2
- package/dist/cjs/_withStableStyle.native.js.map +1 -1
- package/dist/cjs/helpers/expandStyle.js.map +1 -1
- package/dist/cjs/helpers/expandStyle.native.js +62 -13
- package/dist/cjs/helpers/expandStyle.native.js.map +1 -1
- package/dist/cjs/helpers/getDynamicVal.cjs +22 -1
- package/dist/cjs/helpers/getDynamicVal.js +22 -1
- package/dist/cjs/helpers/getDynamicVal.js.map +1 -1
- package/dist/cjs/helpers/getDynamicVal.native.js +22 -1
- package/dist/cjs/helpers/getDynamicVal.native.js.map +1 -1
- package/dist/cjs/helpers/getSplitStyles.cjs +1 -19
- package/dist/cjs/helpers/getSplitStyles.js +2 -25
- package/dist/cjs/helpers/getSplitStyles.js.map +1 -1
- package/dist/cjs/helpers/getSplitStyles.native.js +8 -4
- package/dist/cjs/helpers/getSplitStyles.native.js.map +1 -1
- package/dist/cjs/helpers/propMapper.cjs +34 -12
- package/dist/cjs/helpers/propMapper.js +28 -12
- package/dist/cjs/helpers/propMapper.js.map +1 -1
- package/dist/cjs/helpers/propMapper.native.js +60 -14
- package/dist/cjs/helpers/propMapper.native.js.map +1 -1
- package/dist/esm/_withStableStyle.js +3 -2
- package/dist/esm/_withStableStyle.js.map +1 -1
- package/dist/esm/_withStableStyle.mjs +5 -2
- package/dist/esm/_withStableStyle.mjs.map +1 -1
- package/dist/esm/_withStableStyle.native.js +10 -2
- package/dist/esm/_withStableStyle.native.js.map +1 -1
- package/dist/esm/helpers/expandStyle.js.map +1 -1
- package/dist/esm/helpers/expandStyle.mjs.map +1 -1
- package/dist/esm/helpers/expandStyle.native.js +67 -18
- package/dist/esm/helpers/expandStyle.native.js.map +1 -1
- package/dist/esm/helpers/getDynamicVal.js +22 -1
- package/dist/esm/helpers/getDynamicVal.js.map +1 -1
- package/dist/esm/helpers/getDynamicVal.mjs +21 -1
- package/dist/esm/helpers/getDynamicVal.mjs.map +1 -1
- package/dist/esm/helpers/getDynamicVal.native.js +21 -1
- package/dist/esm/helpers/getDynamicVal.native.js.map +1 -1
- package/dist/esm/helpers/getSplitStyles.js +4 -32
- package/dist/esm/helpers/getSplitStyles.js.map +1 -1
- package/dist/esm/helpers/getSplitStyles.mjs +4 -22
- package/dist/esm/helpers/getSplitStyles.mjs.map +1 -1
- package/dist/esm/helpers/getSplitStyles.native.js +9 -5
- package/dist/esm/helpers/getSplitStyles.native.js.map +1 -1
- package/dist/esm/helpers/propMapper.js +28 -12
- package/dist/esm/helpers/propMapper.js.map +1 -1
- package/dist/esm/helpers/propMapper.mjs +34 -12
- package/dist/esm/helpers/propMapper.mjs.map +1 -1
- package/dist/esm/helpers/propMapper.native.js +57 -11
- package/dist/esm/helpers/propMapper.native.js.map +1 -1
- package/package.json +12 -12
- package/src/_withStableStyle.tsx +14 -1
- package/src/helpers/expandStyle.native.ts +124 -0
- package/src/helpers/expandStyle.ts +1 -9
- package/src/helpers/getDynamicVal.ts +35 -0
- package/src/helpers/getSplitStyles.tsx +34 -13
- package/src/helpers/propMapper.native.ts +619 -0
- package/src/helpers/propMapper.ts +85 -20
- package/src/types.tsx +79 -15
- package/types/_withStableStyle.d.ts.map +1 -1
- package/types/helpers/expandStyle.d.ts.map +1 -1
- package/types/helpers/expandStyle.native.d.ts +7 -0
- package/types/helpers/expandStyle.native.d.ts.map +1 -0
- package/types/helpers/getDynamicVal.d.ts +4 -0
- package/types/helpers/getDynamicVal.d.ts.map +1 -1
- package/types/helpers/getSplitStyles.d.ts.map +1 -1
- package/types/helpers/propMapper.d.ts.map +1 -1
- package/types/helpers/propMapper.native.d.ts +5 -0
- package/types/helpers/propMapper.native.d.ts.map +1 -0
- package/types/helpers/webPropsToSkip.native.d.ts +0 -6
- package/types/helpers/webPropsToSkip.native.d.ts.map +1 -1
- package/types/types.d.ts +59 -15
- package/types/types.d.ts.map +1 -1
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
import { isAndroid } from '@tamagui/constants'
|
|
2
|
+
import { tokenCategories } from '@tamagui/helpers'
|
|
3
|
+
import { getConfig } from '../config'
|
|
4
|
+
import { getVariableValue, isVariable } from '../createVariable'
|
|
5
|
+
import type {
|
|
6
|
+
GetStyleState,
|
|
7
|
+
PropMapper,
|
|
8
|
+
ResolveVariableAs,
|
|
9
|
+
SplitStyleProps,
|
|
10
|
+
StyleResolver,
|
|
11
|
+
TamaguiInternalConfig,
|
|
12
|
+
Variable,
|
|
13
|
+
VariantSpreadFunction,
|
|
14
|
+
} from '../types'
|
|
15
|
+
import { expandStyle } from './expandStyle'
|
|
16
|
+
import { getFontsForLanguage, getVariantExtras } from './getVariantExtras'
|
|
17
|
+
import { isObj } from './isObj'
|
|
18
|
+
import { normalizeStyle } from './normalizeStyle'
|
|
19
|
+
import { pseudoDescriptors } from './pseudoDescriptors'
|
|
20
|
+
import { isRemValue, resolveRem } from './resolveRem'
|
|
21
|
+
import { skipProps } from './skipProps'
|
|
22
|
+
|
|
23
|
+
// Token resolver for size (returns number) or color (returns string)
|
|
24
|
+
const resolveTok = (
|
|
25
|
+
v: any,
|
|
26
|
+
cat: 'size' | 'color',
|
|
27
|
+
sp: SplitStyleProps,
|
|
28
|
+
ss: Partial<GetStyleState>
|
|
29
|
+
) => {
|
|
30
|
+
if (typeof v === 'string' && v[0] === '$') {
|
|
31
|
+
const r = getTokenForKey(cat, v, sp, ss)
|
|
32
|
+
if (cat === 'size') return r != null ? +r || 0 : 0
|
|
33
|
+
return r != null ? String(r) : v
|
|
34
|
+
}
|
|
35
|
+
return cat === 'size' ? (typeof v === 'number' ? v : +v || 0) : v
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Native: resolve tokens in boxShadow object, keep as object
|
|
39
|
+
const boxShadowObjResolve = (
|
|
40
|
+
v: any,
|
|
41
|
+
sp: SplitStyleProps,
|
|
42
|
+
ss: Partial<GetStyleState>
|
|
43
|
+
): any =>
|
|
44
|
+
(Array.isArray(v) ? v : [v]).map((o) => ({
|
|
45
|
+
...(o.inset && { inset: true }),
|
|
46
|
+
offsetX: resolveTok(o.offsetX, 'size', sp, ss),
|
|
47
|
+
offsetY: resolveTok(o.offsetY, 'size', sp, ss),
|
|
48
|
+
...(o.blurRadius != null && { blurRadius: resolveTok(o.blurRadius, 'size', sp, ss) }),
|
|
49
|
+
...(o.spreadDistance != null && {
|
|
50
|
+
spreadDistance: resolveTok(o.spreadDistance, 'size', sp, ss),
|
|
51
|
+
}),
|
|
52
|
+
...(o.color != null && { color: resolveTok(o.color, 'color', sp, ss) }),
|
|
53
|
+
}))
|
|
54
|
+
|
|
55
|
+
// Native: resolve tokens in filter object, keep as object array
|
|
56
|
+
const filterObjResolve = (v: any, sp: SplitStyleProps, ss: Partial<GetStyleState>): any =>
|
|
57
|
+
(Array.isArray(v) ? v : [v]).map((o) => {
|
|
58
|
+
if ('blur' in o) return { blur: resolveTok(o.blur, 'size', sp, ss) }
|
|
59
|
+
if ('dropShadow' in o) {
|
|
60
|
+
const ds = o.dropShadow
|
|
61
|
+
return {
|
|
62
|
+
dropShadow: {
|
|
63
|
+
offsetX: resolveTok(ds.offsetX, 'size', sp, ss),
|
|
64
|
+
offsetY: resolveTok(ds.offsetY, 'size', sp, ss),
|
|
65
|
+
...(ds.blurRadius != null && {
|
|
66
|
+
blurRadius: resolveTok(ds.blurRadius, 'size', sp, ss),
|
|
67
|
+
}),
|
|
68
|
+
...(ds.color != null && { color: resolveTok(ds.color, 'color', sp, ss) }),
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return o
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
export const propMapper: PropMapper = (key, value, styleState, disabled, map) => {
|
|
76
|
+
if (disabled) {
|
|
77
|
+
return map(key, value)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
lastFontFamilyToken = null
|
|
81
|
+
|
|
82
|
+
if (!(process.env.TAMAGUI_TARGET === 'native' && isAndroid)) {
|
|
83
|
+
// this shouldnt be necessary and handled in the outer loop
|
|
84
|
+
if (key === 'elevationAndroid') return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const { conf, styleProps, staticConfig } = styleState
|
|
88
|
+
|
|
89
|
+
if (value === 'unset') {
|
|
90
|
+
const unsetVal = conf.unset?.[key]
|
|
91
|
+
if (unsetVal != null) {
|
|
92
|
+
value = unsetVal
|
|
93
|
+
} else {
|
|
94
|
+
// if no unset found, do nothing
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const { variants } = staticConfig
|
|
100
|
+
|
|
101
|
+
if (!styleProps.noExpand) {
|
|
102
|
+
if (variants && key in variants) {
|
|
103
|
+
const variantValue = resolveVariants(key, value, styleProps, styleState, '')
|
|
104
|
+
if (variantValue) {
|
|
105
|
+
variantValue.forEach(([key, value]) => map(key, value))
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// handle shorthands
|
|
112
|
+
if (!styleProps.disableExpandShorthands) {
|
|
113
|
+
if (key in conf.shorthands) {
|
|
114
|
+
key = conf.shorthands[key]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Capture original value before resolution (for context prop tracking)
|
|
119
|
+
const originalValue = value
|
|
120
|
+
|
|
121
|
+
if (value != null) {
|
|
122
|
+
// boxShadow object/array -> resolve tokens, keep as object array
|
|
123
|
+
if (key === 'boxShadow' && typeof value === 'object') {
|
|
124
|
+
value = boxShadowObjResolve(value, styleProps, styleState)
|
|
125
|
+
} else if (key === 'filter' && typeof value === 'object') {
|
|
126
|
+
// filter object/array -> resolve tokens, keep as object array
|
|
127
|
+
value = filterObjResolve(value, styleProps, styleState)
|
|
128
|
+
} else if (typeof value === 'string' && value[0] === '$') {
|
|
129
|
+
value = getTokenForKey(key, value, styleProps, styleState)
|
|
130
|
+
} else if (key === 'boxShadow' && typeof value === 'string' && value.includes('$')) {
|
|
131
|
+
// boxShadow with embedded $tokens - resolve each token
|
|
132
|
+
value = value.replace(/(\$[\w.-]+)/g, (t) => {
|
|
133
|
+
// $5, $-2 etc -> size token, otherwise -> color
|
|
134
|
+
const cat = /^\$-?\d/.test(t) ? 'size' : 'color'
|
|
135
|
+
const r = getTokenForKey(cat, t, styleProps, styleState)
|
|
136
|
+
return r != null ? String(r) : t
|
|
137
|
+
})
|
|
138
|
+
} else if (key === 'filter' && typeof value === 'string' && value.includes('$')) {
|
|
139
|
+
// filter with embedded $tokens - resolve each token
|
|
140
|
+
value = value.replace(/(\$[\w.-]+)/g, (t) => {
|
|
141
|
+
const cat = /^\$-?\d/.test(t) ? 'size' : 'color'
|
|
142
|
+
const r = getTokenForKey(cat, t, styleProps, styleState)
|
|
143
|
+
return r != null ? String(r) : t
|
|
144
|
+
})
|
|
145
|
+
} else if (isVariable(value)) {
|
|
146
|
+
value = resolveVariableValue(key, value, styleProps.resolveValues)
|
|
147
|
+
} else if (isRemValue(value)) {
|
|
148
|
+
value = resolveRem(value)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (value != null) {
|
|
153
|
+
if (key === 'fontFamily' && lastFontFamilyToken) {
|
|
154
|
+
styleState.fontFamily = lastFontFamilyToken
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const expanded = styleProps.noExpand ? null : expandStyle(key, value)
|
|
158
|
+
|
|
159
|
+
if (expanded) {
|
|
160
|
+
const max = expanded.length
|
|
161
|
+
for (let i = 0; i < max; i++) {
|
|
162
|
+
const [nkey, nvalue] = expanded[i]
|
|
163
|
+
map(nkey, nvalue, originalValue)
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
map(key, value, originalValue)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const resolveVariants: StyleResolver = (
|
|
172
|
+
key,
|
|
173
|
+
value,
|
|
174
|
+
styleProps,
|
|
175
|
+
styleState,
|
|
176
|
+
parentVariantKey
|
|
177
|
+
) => {
|
|
178
|
+
const { staticConfig, conf, debug } = styleState
|
|
179
|
+
const { variants } = staticConfig
|
|
180
|
+
if (!variants) return
|
|
181
|
+
|
|
182
|
+
let variantValue = getVariantDefinition(variants[key], value, conf)
|
|
183
|
+
|
|
184
|
+
if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
|
|
185
|
+
console.groupCollapsed(`♦️♦️♦️ resolve variant ${key}`)
|
|
186
|
+
console.info({
|
|
187
|
+
key,
|
|
188
|
+
value,
|
|
189
|
+
variantValue,
|
|
190
|
+
variants,
|
|
191
|
+
})
|
|
192
|
+
console.groupEnd()
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (!variantValue) {
|
|
196
|
+
// variant at key exists, but no matching variant
|
|
197
|
+
// disabling warnings, its fine to pass through, could re-enable later somehoiw
|
|
198
|
+
if (process.env.TAMAGUI_WARN_ON_MISSING_VARIANT === '1') {
|
|
199
|
+
// don't warn on missing booleans
|
|
200
|
+
if (typeof value !== 'boolean') {
|
|
201
|
+
const name = staticConfig.componentName || '[UnnamedComponent]'
|
|
202
|
+
console.warn(
|
|
203
|
+
`No variant found: ${name} has variant "${key}", but no matching value "${value}"`
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (typeof variantValue === 'function') {
|
|
211
|
+
const fn = variantValue as VariantSpreadFunction<any>
|
|
212
|
+
const extras = getVariantExtras(styleState)
|
|
213
|
+
variantValue = fn(value, extras)
|
|
214
|
+
|
|
215
|
+
if (
|
|
216
|
+
process.env.NODE_ENV === 'development' &&
|
|
217
|
+
debug === 'verbose' &&
|
|
218
|
+
process.env.TAMAGUI_TARGET !== 'native'
|
|
219
|
+
) {
|
|
220
|
+
console.groupCollapsed(' expanded functional variant', key)
|
|
221
|
+
console.info({ fn, variantValue, extras })
|
|
222
|
+
console.groupEnd()
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
let fontFamilyResult: any
|
|
227
|
+
|
|
228
|
+
if (isObj(variantValue)) {
|
|
229
|
+
const fontFamilyUpdate =
|
|
230
|
+
variantValue.fontFamily || variantValue[conf.inverseShorthands.fontFamily]
|
|
231
|
+
|
|
232
|
+
if (fontFamilyUpdate) {
|
|
233
|
+
fontFamilyResult = getFontFamilyFromNameOrVariable(fontFamilyUpdate, conf)
|
|
234
|
+
styleState.fontFamily = fontFamilyResult
|
|
235
|
+
|
|
236
|
+
if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
|
|
237
|
+
console.info(` updating font family`, fontFamilyResult)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
variantValue = resolveTokensAndVariants(
|
|
242
|
+
key,
|
|
243
|
+
variantValue,
|
|
244
|
+
styleProps,
|
|
245
|
+
styleState,
|
|
246
|
+
parentVariantKey
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (variantValue) {
|
|
251
|
+
const expanded = normalizeStyle(variantValue, !!styleProps.noNormalize)
|
|
252
|
+
|
|
253
|
+
if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
|
|
254
|
+
console.info(` expanding styles from `, variantValue, `to`, expanded)
|
|
255
|
+
}
|
|
256
|
+
const next = Object.entries(expanded)
|
|
257
|
+
|
|
258
|
+
// store any changed font family (only support variables for now)
|
|
259
|
+
if (fontFamilyResult && fontFamilyResult[0] === '$') {
|
|
260
|
+
lastFontFamilyToken = getVariableValue(fontFamilyResult)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return next
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// handles finding and resolving the fontFamily to the token name
|
|
268
|
+
// this is used as `font_[name]` in className for nice css variable support
|
|
269
|
+
export function getFontFamilyFromNameOrVariable(input: any, conf: TamaguiInternalConfig) {
|
|
270
|
+
if (isVariable(input)) {
|
|
271
|
+
const val = variableToFontNameCache.get(input)
|
|
272
|
+
if (val) return val
|
|
273
|
+
for (const key in conf.fontsParsed) {
|
|
274
|
+
const familyVariable = conf.fontsParsed[key].family
|
|
275
|
+
if (isVariable(familyVariable)) {
|
|
276
|
+
variableToFontNameCache.set(familyVariable, key)
|
|
277
|
+
if (familyVariable === input) {
|
|
278
|
+
return key
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
} else if (typeof input === 'string') {
|
|
283
|
+
if (input[0] === '$') {
|
|
284
|
+
return input
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const variableToFontNameCache = new WeakMap<Variable, string>()
|
|
290
|
+
|
|
291
|
+
const resolveTokensAndVariants: StyleResolver<Object> = (
|
|
292
|
+
key, // we dont use key assume value is object instead
|
|
293
|
+
value,
|
|
294
|
+
styleProps,
|
|
295
|
+
styleState,
|
|
296
|
+
parentVariantKey
|
|
297
|
+
) => {
|
|
298
|
+
const { conf, staticConfig, debug, theme } = styleState
|
|
299
|
+
const { variants } = staticConfig
|
|
300
|
+
const res = {}
|
|
301
|
+
|
|
302
|
+
if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
|
|
303
|
+
console.info(` - resolveTokensAndVariants`, key, value)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
for (const _key in value) {
|
|
307
|
+
const subKey = conf.shorthands[_key] || _key
|
|
308
|
+
const val = value[_key]
|
|
309
|
+
|
|
310
|
+
if (!styleProps.noSkip && subKey in skipProps) {
|
|
311
|
+
continue
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Track context overrides for any key that's in context props (issues #3670, #3676)
|
|
315
|
+
// Store the ORIGINAL token value (like '$8') before resolution so that
|
|
316
|
+
// children's functional variants can look up token values
|
|
317
|
+
if (staticConfig) {
|
|
318
|
+
const contextProps =
|
|
319
|
+
staticConfig.context?.props || staticConfig.parentStaticConfig?.context?.props
|
|
320
|
+
if (contextProps && subKey in contextProps) {
|
|
321
|
+
styleState.overriddenContextProps ||= {}
|
|
322
|
+
styleState.overriddenContextProps[subKey] = val
|
|
323
|
+
// Also track the original token value separately
|
|
324
|
+
styleState.originalContextPropValues ||= {}
|
|
325
|
+
styleState.originalContextPropValues[subKey] = val
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (styleProps.noExpand) {
|
|
330
|
+
res[subKey] = val
|
|
331
|
+
} else {
|
|
332
|
+
if (variants && subKey in variants) {
|
|
333
|
+
// avoids infinite loop if variant is matching a style prop
|
|
334
|
+
// eg: { variants: { flex: { true: { flex: 2 } } } }
|
|
335
|
+
if (parentVariantKey && parentVariantKey === key) {
|
|
336
|
+
res[subKey] =
|
|
337
|
+
// SYNC WITH *1
|
|
338
|
+
val[0] === '$' ? getTokenForKey(subKey, val, styleProps, styleState) : val
|
|
339
|
+
} else {
|
|
340
|
+
const variantOut = resolveVariants(subKey, val, styleProps, styleState, key)
|
|
341
|
+
|
|
342
|
+
// apply, merging sub-styles
|
|
343
|
+
if (variantOut) {
|
|
344
|
+
for (const [key, val] of variantOut) {
|
|
345
|
+
if (val == null) continue
|
|
346
|
+
if (key in pseudoDescriptors) {
|
|
347
|
+
res[key] ??= {}
|
|
348
|
+
Object.assign(res[key], val)
|
|
349
|
+
} else {
|
|
350
|
+
res[key] = val
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
continue
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (isVariable(val)) {
|
|
360
|
+
res[subKey] = resolveVariableValue(subKey, val, styleProps.resolveValues)
|
|
361
|
+
|
|
362
|
+
if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
|
|
363
|
+
console.info(`variable`, subKey, res[subKey])
|
|
364
|
+
}
|
|
365
|
+
continue
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (typeof val === 'string') {
|
|
369
|
+
// SYNC WITH *1
|
|
370
|
+
const fVal =
|
|
371
|
+
val[0] === '$'
|
|
372
|
+
? getTokenForKey(subKey, val, styleProps, styleState)
|
|
373
|
+
: isRemValue(val)
|
|
374
|
+
? resolveRem(val)
|
|
375
|
+
: val
|
|
376
|
+
|
|
377
|
+
res[subKey] = fVal
|
|
378
|
+
continue
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (isObj(val)) {
|
|
382
|
+
const subObject = resolveTokensAndVariants(subKey, val, styleProps, styleState, key)
|
|
383
|
+
|
|
384
|
+
if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
|
|
385
|
+
console.info(`object`, subKey, subObject)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// sub-objects: media queries, pseudos, shadowOffset
|
|
389
|
+
res[subKey] ??= {}
|
|
390
|
+
Object.assign(res[subKey], subObject)
|
|
391
|
+
} else {
|
|
392
|
+
// nullish values cant be tokens, need no extra parsing
|
|
393
|
+
res[subKey] = val
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (process.env.NODE_ENV === 'development') {
|
|
397
|
+
if (debug) {
|
|
398
|
+
if (res[subKey]?.[0] === '$') {
|
|
399
|
+
console.warn(
|
|
400
|
+
`⚠️ Missing token in theme ${theme.name}:`,
|
|
401
|
+
subKey,
|
|
402
|
+
res[subKey],
|
|
403
|
+
theme
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return res
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const tokenCats = ['size', 'color', 'radius', 'space', 'zIndex'].map((name) => ({
|
|
414
|
+
name,
|
|
415
|
+
spreadName: `...${name}`,
|
|
416
|
+
}))
|
|
417
|
+
|
|
418
|
+
// goes through specificity finding best matching variant function
|
|
419
|
+
function getVariantDefinition(variant: any, value: any, conf: TamaguiInternalConfig) {
|
|
420
|
+
if (!variant) return
|
|
421
|
+
if (typeof variant === 'function') {
|
|
422
|
+
return variant
|
|
423
|
+
}
|
|
424
|
+
const exact = variant[value]
|
|
425
|
+
if (exact) {
|
|
426
|
+
return exact
|
|
427
|
+
}
|
|
428
|
+
if (value != null) {
|
|
429
|
+
const { tokensParsed } = conf
|
|
430
|
+
for (const { name, spreadName } of tokenCats) {
|
|
431
|
+
if (spreadName in variant && name in tokensParsed && value in tokensParsed[name]) {
|
|
432
|
+
return variant[spreadName]
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
const fontSizeVariant = variant['...fontSize']
|
|
436
|
+
if (fontSizeVariant && conf.fontSizeTokens.has(value)) {
|
|
437
|
+
return fontSizeVariant
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
// fallback to catch all | size
|
|
441
|
+
return variant[`:${typeof value}`] || variant['...']
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const fontShorthand = {
|
|
445
|
+
fontSize: 'size',
|
|
446
|
+
fontWeight: 'weight',
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
let lastFontFamilyToken: any = null
|
|
450
|
+
let didLogMissingToken = false
|
|
451
|
+
|
|
452
|
+
export const getTokenForKey = (
|
|
453
|
+
key: string,
|
|
454
|
+
value: string,
|
|
455
|
+
styleProps: SplitStyleProps,
|
|
456
|
+
styleState: Partial<GetStyleState>
|
|
457
|
+
) => {
|
|
458
|
+
let resolveAs = styleProps.resolveValues || 'none'
|
|
459
|
+
|
|
460
|
+
if (resolveAs === 'none') {
|
|
461
|
+
return value
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const { theme, conf = getConfig(), context, fontFamily, staticConfig } = styleState
|
|
465
|
+
|
|
466
|
+
const themeValue = theme ? theme[value] || theme[value.slice(1)] : undefined
|
|
467
|
+
|
|
468
|
+
const tokensParsed = conf.tokensParsed
|
|
469
|
+
let valOrVar: any
|
|
470
|
+
let hasSet = false
|
|
471
|
+
|
|
472
|
+
const customTokenAccept = staticConfig?.accept?.[key]
|
|
473
|
+
if (customTokenAccept) {
|
|
474
|
+
const val = themeValue ?? tokensParsed[customTokenAccept][value]
|
|
475
|
+
if (val != null) {
|
|
476
|
+
resolveAs = 'value' // always resolve custom tokens as values
|
|
477
|
+
valOrVar = val
|
|
478
|
+
hasSet = true
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (themeValue) {
|
|
483
|
+
if (resolveAs === 'except-theme') {
|
|
484
|
+
return value
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
valOrVar = themeValue
|
|
488
|
+
if (process.env.NODE_ENV === 'development' && styleState.debug === 'verbose') {
|
|
489
|
+
globalThis.tamaguiAvoidTracking = true
|
|
490
|
+
console.info(
|
|
491
|
+
` - resolving ${key} to theme value ${value} resolveAs ${resolveAs}`,
|
|
492
|
+
valOrVar
|
|
493
|
+
)
|
|
494
|
+
globalThis.tamaguiAvoidTracking = false
|
|
495
|
+
}
|
|
496
|
+
hasSet = true
|
|
497
|
+
} else {
|
|
498
|
+
if (value in conf.specificTokens) {
|
|
499
|
+
hasSet = true
|
|
500
|
+
valOrVar = conf.specificTokens[value]
|
|
501
|
+
} else {
|
|
502
|
+
switch (key) {
|
|
503
|
+
case 'fontFamily': {
|
|
504
|
+
const fontsParsed = context?.language
|
|
505
|
+
? getFontsForLanguage(conf.fontsParsed, context.language)
|
|
506
|
+
: conf.fontsParsed
|
|
507
|
+
valOrVar = fontsParsed[value]?.family || value
|
|
508
|
+
lastFontFamilyToken = value
|
|
509
|
+
hasSet = true
|
|
510
|
+
break
|
|
511
|
+
}
|
|
512
|
+
case 'fontSize':
|
|
513
|
+
case 'lineHeight':
|
|
514
|
+
case 'letterSpacing':
|
|
515
|
+
case 'fontWeight': {
|
|
516
|
+
const fam = fontFamily || conf.defaultFontToken
|
|
517
|
+
if (fam) {
|
|
518
|
+
const fontsParsed = context?.language
|
|
519
|
+
? getFontsForLanguage(conf.fontsParsed, context.language)
|
|
520
|
+
: conf.fontsParsed
|
|
521
|
+
const font = fontsParsed[fam] || fontsParsed[conf.defaultFontToken]
|
|
522
|
+
valOrVar = font?.[fontShorthand[key] || key]?.[value] || value
|
|
523
|
+
hasSet = true
|
|
524
|
+
}
|
|
525
|
+
break
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
for (const cat in tokenCategories) {
|
|
529
|
+
if (key in tokenCategories[cat]) {
|
|
530
|
+
const res = tokensParsed[cat]?.[value]
|
|
531
|
+
|
|
532
|
+
if (res != null) {
|
|
533
|
+
valOrVar = res
|
|
534
|
+
hasSet = true
|
|
535
|
+
} else {
|
|
536
|
+
if (process.env.NODE_ENV === 'development') {
|
|
537
|
+
if (process.env.TAMAGUI_DISABLE_MISSING_TOKEN_LOG !== '1') {
|
|
538
|
+
if (!didLogMissingToken) {
|
|
539
|
+
didLogMissingToken = true
|
|
540
|
+
console.groupCollapsed(
|
|
541
|
+
`[tamagui] Warning: missing token ${key} in category ${cat} - ${value} (open for details)`
|
|
542
|
+
)
|
|
543
|
+
console.info(
|
|
544
|
+
`Note: this could just be due to you not setting all the theme tokens Tamagui expects, which is harmless, but
|
|
545
|
+
it also often can be because you have a duplicated Tamagui in your bundle, which can cause tricky bugs.`
|
|
546
|
+
)
|
|
547
|
+
console.info(
|
|
548
|
+
`To see if you have duplicated dependencies, in Chrome DevTools hit CMD+P and type TamaguiProvider.
|
|
549
|
+
If you see both a .cjs and a .mjs entry, it's duplicated.`
|
|
550
|
+
)
|
|
551
|
+
console.info(
|
|
552
|
+
`You can debug that issue by opening the .mjs and .cjs files and setting a breakpoint at the top of each.`
|
|
553
|
+
)
|
|
554
|
+
console.info(
|
|
555
|
+
`We only log this warning one time as it's sometimes harmless, to disable this log entirely set process.env.TAMAGUI_DISABLE_MISSING_TOKEN_LOG=1.`
|
|
556
|
+
)
|
|
557
|
+
console.groupEnd()
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (!hasSet) {
|
|
567
|
+
const spaceVar = tokensParsed.space[value]
|
|
568
|
+
if (spaceVar != null) {
|
|
569
|
+
valOrVar = spaceVar
|
|
570
|
+
hasSet = true
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if (hasSet) {
|
|
576
|
+
const out = resolveVariableValue(key, valOrVar, resolveAs)
|
|
577
|
+
if (process.env.NODE_ENV === 'development' && styleState.debug === 'verbose') {
|
|
578
|
+
globalThis.tamaguiAvoidTracking = true
|
|
579
|
+
console.info(`resolved`, resolveAs, valOrVar, out)
|
|
580
|
+
globalThis.tamaguiAvoidTracking = false
|
|
581
|
+
}
|
|
582
|
+
return out
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// they didn't define this token don't return anything, we could warn?
|
|
586
|
+
|
|
587
|
+
if (process.env.NODE_ENV === 'development' && styleState.debug === 'verbose') {
|
|
588
|
+
console.warn(`Warning: no token found for ${key}, omitting`)
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function resolveVariableValue(
|
|
593
|
+
key: string,
|
|
594
|
+
valOrVar: Variable | any,
|
|
595
|
+
resolveValues?: ResolveVariableAs
|
|
596
|
+
) {
|
|
597
|
+
if (resolveValues === 'none') {
|
|
598
|
+
return valOrVar
|
|
599
|
+
}
|
|
600
|
+
if (isVariable(valOrVar)) {
|
|
601
|
+
if (resolveValues === 'value') {
|
|
602
|
+
return valOrVar.val
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// @ts-expect-error this is fine until we can type better
|
|
606
|
+
const get = valOrVar?.get
|
|
607
|
+
|
|
608
|
+
// shadowColor doesn't support dynamic style
|
|
609
|
+
if (process.env.TAMAGUI_TARGET !== 'native' || key !== 'shadowColor') {
|
|
610
|
+
if (typeof get === 'function') {
|
|
611
|
+
const resolveDynamicFor = resolveValues === 'web' ? 'web' : undefined
|
|
612
|
+
return get(resolveDynamicFor)
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
return process.env.TAMAGUI_TARGET === 'native' ? valOrVar.val : valOrVar.variable
|
|
617
|
+
}
|
|
618
|
+
return valOrVar
|
|
619
|
+
}
|