@tamagui/web 1.13.4 → 1.14.0
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/createComponent.js +2 -2
- package/dist/cjs/createComponent.js.map +3 -3
- package/dist/cjs/helpers/ThemeManager.js +1 -1
- package/dist/cjs/helpers/ThemeManager.js.map +3 -3
- package/dist/cjs/helpers/getSplitStyles.js +2 -2
- package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
- package/dist/cjs/hooks/useTheme.js +1 -1
- package/dist/cjs/hooks/useTheme.js.map +3 -3
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/views/Theme.js +1 -1
- package/dist/cjs/views/Theme.js.map +3 -3
- package/dist/esm/createComponent.js +2 -2
- package/dist/esm/createComponent.js.map +3 -3
- package/dist/esm/createComponent.mjs +2 -2
- package/dist/esm/createComponent.mjs.map +3 -3
- package/dist/esm/helpers/ThemeManager.js +1 -1
- package/dist/esm/helpers/ThemeManager.js.map +3 -3
- package/dist/esm/helpers/ThemeManager.mjs +1 -1
- package/dist/esm/helpers/ThemeManager.mjs.map +3 -3
- package/dist/esm/helpers/getSplitStyles.js +2 -2
- package/dist/esm/helpers/getSplitStyles.js.map +2 -2
- package/dist/esm/helpers/getSplitStyles.mjs +2 -2
- package/dist/esm/helpers/getSplitStyles.mjs.map +2 -2
- package/dist/esm/hooks/useTheme.js +1 -1
- package/dist/esm/hooks/useTheme.js.map +3 -3
- package/dist/esm/hooks/useTheme.mjs +1 -1
- package/dist/esm/hooks/useTheme.mjs.map +3 -3
- package/dist/esm/views/Theme.js +1 -1
- package/dist/esm/views/Theme.js.map +3 -3
- package/dist/esm/views/Theme.mjs +1 -1
- package/dist/esm/views/Theme.mjs.map +3 -3
- package/package.json +9 -9
- package/src/createComponent.tsx +38 -5
- package/src/helpers/ThemeManager.tsx +40 -32
- package/src/helpers/getSplitStyles.tsx +0 -8
- package/src/hooks/useTheme.tsx +145 -93
- package/src/types.tsx +2 -2
- package/src/views/Theme.tsx +49 -27
- package/types/createComponent.d.ts.map +1 -1
- package/types/helpers/ThemeManager.d.ts +1 -0
- package/types/helpers/ThemeManager.d.ts.map +1 -1
- package/types/helpers/getSplitStyles.d.ts.map +1 -1
- package/types/hooks/useTheme.d.ts +5 -7
- package/types/hooks/useTheme.d.ts.map +1 -1
- package/types/types.d.ts +2 -2
- package/types/types.d.ts.map +1 -1
- package/types/views/Theme.d.ts.map +1 -1
package/src/hooks/useTheme.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { isClient, isRSC, isServer, isWeb } from '@tamagui/constants'
|
|
3
|
-
import { useContext, useEffect, useMemo, useState } from 'react'
|
|
3
|
+
import { useContext, useEffect, useLayoutEffect, useMemo, useState } from 'react'
|
|
4
4
|
|
|
5
5
|
import { getConfig } from '../config.js'
|
|
6
6
|
import { isDevTools } from '../constants/isDevTools.js'
|
|
7
|
+
import { isVariable } from '../createVariable.js'
|
|
7
8
|
import { createProxy } from '../helpers/createProxy.js'
|
|
8
9
|
import {
|
|
9
10
|
ThemeManager,
|
|
@@ -16,13 +17,20 @@ import { GetThemeUnwrapped } from './getThemeUnwrapped.js'
|
|
|
16
17
|
import { useServerRef } from './useServerHooks.js'
|
|
17
18
|
|
|
18
19
|
export type ChangedThemeResponse = {
|
|
20
|
+
isNewTheme: boolean
|
|
19
21
|
themeManager: ThemeManager | null
|
|
20
22
|
name: string
|
|
21
|
-
isNewTheme?: boolean
|
|
22
23
|
theme?: ThemeParsed | null
|
|
23
24
|
className?: string
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
type State = {
|
|
28
|
+
state: ThemeManagerState
|
|
29
|
+
themeManager: ThemeManager
|
|
30
|
+
isNewTheme: boolean
|
|
31
|
+
mounted?: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
const emptyProps = { name: null }
|
|
27
35
|
|
|
28
36
|
function getDefaultThemeProxied() {
|
|
@@ -39,11 +47,12 @@ export const useTheme = (props: ThemeProps = emptyProps): ThemeParsed => {
|
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
export const useThemeWithState = (props: ThemeProps) => {
|
|
42
|
-
const keys = useServerRef([])
|
|
50
|
+
const keys = useServerRef<string[]>([])
|
|
43
51
|
|
|
44
52
|
const changedTheme = useChangeThemeEffect(
|
|
45
53
|
props,
|
|
46
54
|
false,
|
|
55
|
+
keys.current,
|
|
47
56
|
isClient
|
|
48
57
|
? () => {
|
|
49
58
|
return props.shouldUpdate?.() ?? keys.current.length === 0
|
|
@@ -51,22 +60,15 @@ export const useThemeWithState = (props: ThemeProps) => {
|
|
|
51
60
|
: undefined
|
|
52
61
|
)
|
|
53
62
|
|
|
54
|
-
const { themeManager,
|
|
63
|
+
const { themeManager, theme, name, className } = changedTheme
|
|
55
64
|
|
|
56
|
-
if (process.env.NODE_ENV === 'development') {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
console.
|
|
61
|
-
}
|
|
62
|
-
if (props.debug === 'verbose') {
|
|
63
|
-
console.groupCollapsed(' 🔹 useTheme =>', name)
|
|
64
|
-
const logs = { ...props, name, className, ...(isDevTools && { theme }) }
|
|
65
|
-
for (const key in logs) {
|
|
66
|
-
console.log(' ', key, logs[key])
|
|
67
|
-
}
|
|
68
|
-
console.groupEnd()
|
|
65
|
+
if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') {
|
|
66
|
+
console.groupCollapsed(' 🔹 useTheme =>', name)
|
|
67
|
+
const logs = { ...props, name, className, ...(isDevTools && { theme }) }
|
|
68
|
+
for (const key in logs) {
|
|
69
|
+
console.log(' ', key, logs[key])
|
|
69
70
|
}
|
|
71
|
+
console.groupEnd()
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
if (!changedTheme.theme) {
|
|
@@ -77,8 +79,8 @@ export const useThemeWithState = (props: ThemeProps) => {
|
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
const proxiedTheme = useMemo(() => {
|
|
80
|
-
return getThemeProxied(changedTheme as any)
|
|
81
|
-
}, [theme,
|
|
82
|
+
return getThemeProxied(changedTheme as any, keys.current)
|
|
83
|
+
}, [theme, name, className, themeManager])
|
|
82
84
|
|
|
83
85
|
return {
|
|
84
86
|
...changedTheme,
|
|
@@ -86,14 +88,15 @@ export const useThemeWithState = (props: ThemeProps) => {
|
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
|
|
89
|
-
export function getThemeProxied(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}: Partial<ChangedThemeResponse> & {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
export function getThemeProxied(
|
|
92
|
+
{
|
|
93
|
+
theme,
|
|
94
|
+
themeManager,
|
|
95
|
+
}: Partial<ChangedThemeResponse> & {
|
|
96
|
+
theme: ThemeParsed
|
|
97
|
+
},
|
|
98
|
+
keys?: string[]
|
|
99
|
+
) {
|
|
97
100
|
return createProxy(theme, {
|
|
98
101
|
has(_, key) {
|
|
99
102
|
if (typeof key === 'string') {
|
|
@@ -107,7 +110,6 @@ export function getThemeProxied({
|
|
|
107
110
|
return theme
|
|
108
111
|
}
|
|
109
112
|
if (
|
|
110
|
-
key === 'undefined' ||
|
|
111
113
|
key === '__proto__' ||
|
|
112
114
|
key === '$typeof' ||
|
|
113
115
|
typeof key !== 'string' ||
|
|
@@ -115,25 +117,24 @@ export function getThemeProxied({
|
|
|
115
117
|
) {
|
|
116
118
|
return Reflect.get(_, key)
|
|
117
119
|
}
|
|
118
|
-
|
|
120
|
+
|
|
119
121
|
// auto convert variables to plain
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const currentKeys = keys?.current
|
|
125
|
-
if (val && currentKeys) {
|
|
122
|
+
const keyString = key[0] === '$' ? key.slice(1) : key
|
|
123
|
+
const val = themeManager.getValue(keyString)
|
|
124
|
+
|
|
125
|
+
if (val && keys) {
|
|
126
126
|
return new Proxy(val as any, {
|
|
127
127
|
// when they touch the actual value we only track it
|
|
128
128
|
// if its a variable (web), its ignored!
|
|
129
129
|
get(_, subkey) {
|
|
130
|
-
if (subkey === 'val' && !
|
|
131
|
-
|
|
130
|
+
if (subkey === 'val' && !keys.includes(keyString)) {
|
|
131
|
+
keys.push(keyString)
|
|
132
132
|
}
|
|
133
133
|
return Reflect.get(val as any, subkey)
|
|
134
134
|
},
|
|
135
135
|
})
|
|
136
136
|
}
|
|
137
|
+
|
|
137
138
|
return val
|
|
138
139
|
},
|
|
139
140
|
})
|
|
@@ -144,11 +145,13 @@ export const activeThemeManagers = new Set<ThemeManager>()
|
|
|
144
145
|
export const useChangeThemeEffect = (
|
|
145
146
|
props: ThemeProps,
|
|
146
147
|
root = false,
|
|
148
|
+
keys?: string[],
|
|
147
149
|
disableUpdate?: () => boolean
|
|
148
150
|
): ChangedThemeResponse => {
|
|
149
151
|
if (isRSC) {
|
|
150
152
|
// we need context working for this to work well
|
|
151
153
|
return {
|
|
154
|
+
isNewTheme: false,
|
|
152
155
|
...createState().state,
|
|
153
156
|
themeManager: null,
|
|
154
157
|
}
|
|
@@ -164,25 +167,35 @@ export const useChangeThemeEffect = (
|
|
|
164
167
|
if (disable) {
|
|
165
168
|
if (!parentManager) throw `❌`
|
|
166
169
|
return {
|
|
167
|
-
...parentManager.state,
|
|
168
170
|
isNewTheme: false,
|
|
171
|
+
...parentManager.state,
|
|
169
172
|
themeManager: parentManager,
|
|
170
173
|
}
|
|
171
174
|
}
|
|
172
175
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
const [themeState, setThemeState] = useState<State>(createState)
|
|
177
|
+
const { state, themeManager, mounted, isNewTheme } = themeState
|
|
178
|
+
const isInversingOnMount = Boolean(!themeState.mounted && props.inverse)
|
|
179
|
+
const shouldReturnParentState = isInversingOnMount
|
|
180
|
+
|
|
181
|
+
function getNextThemeManagerState(manager = themeManager) {
|
|
182
|
+
const next = manager.getState(
|
|
183
|
+
props,
|
|
184
|
+
parentManager === themeManager ? parentManager.parentManager : parentManager
|
|
185
|
+
)
|
|
186
|
+
return next
|
|
178
187
|
}
|
|
179
188
|
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
function getThemeManagerNextStateIfChanged(manager = themeManager) {
|
|
190
|
+
const next = getNextThemeManagerState(manager)
|
|
191
|
+
if (!next) return
|
|
192
|
+
if (disableUpdate?.() === true) return
|
|
193
|
+
if (!manager.getStateShouldChange(next, state)) return
|
|
194
|
+
return next
|
|
195
|
+
}
|
|
182
196
|
|
|
183
197
|
if (!isServer) {
|
|
184
198
|
useEffect(() => {
|
|
185
|
-
if (disable) return
|
|
186
199
|
// SSR safe inverse (because server can't know prefers scheme)
|
|
187
200
|
// could be done through fancy selectors like how we do prefers-media
|
|
188
201
|
// but may be a bit of explosion of selectors
|
|
@@ -190,85 +203,124 @@ export const useChangeThemeEffect = (
|
|
|
190
203
|
setThemeState({ ...themeState, mounted: true })
|
|
191
204
|
return
|
|
192
205
|
}
|
|
206
|
+
|
|
207
|
+
if (!isNewTheme) return
|
|
208
|
+
if (!themeManager) return
|
|
209
|
+
|
|
193
210
|
activeThemeManagers.add(themeManager)
|
|
194
|
-
|
|
195
|
-
// // console.log('hi', props, state, name, manager)
|
|
196
|
-
// if (state.theme !== manager.state.theme) {
|
|
197
|
-
// console.warn('now update to', manager.state.name)
|
|
198
|
-
// updateState(manager)
|
|
199
|
-
// }
|
|
200
|
-
// })
|
|
211
|
+
|
|
201
212
|
return () => {
|
|
202
213
|
activeThemeManagers.delete(themeManager)
|
|
203
|
-
// disposeChangeListener?.()
|
|
204
214
|
}
|
|
205
|
-
}, [
|
|
206
|
-
}
|
|
215
|
+
}, [isNewTheme, themeManager, state, debug])
|
|
207
216
|
|
|
208
|
-
|
|
209
|
-
|
|
217
|
+
// listen for parent change + notify children change
|
|
218
|
+
useLayoutEffect(() => {
|
|
219
|
+
const nextState = getThemeManagerNextStateIfChanged(themeManager)
|
|
220
|
+
|
|
221
|
+
if (nextState) {
|
|
222
|
+
if (isNewTheme) {
|
|
223
|
+
// if it's a new theme we can just update + publish to children
|
|
224
|
+
themeManager.updateState(nextState, true)
|
|
225
|
+
}
|
|
226
|
+
// if not we will be creating a whole new themeManager
|
|
227
|
+
setThemeState(createState)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const disposeChangeListener = parentManager?.onChangeTheme((name, manager) => {
|
|
231
|
+
if (keys?.length || isNewTheme) {
|
|
232
|
+
if (process.env.NODE_ENV === 'development' && props['debug'] && keys?.length) {
|
|
233
|
+
console.log(`onChangeTheme`, { props, name, manager, parentManager, keys })
|
|
234
|
+
}
|
|
235
|
+
setThemeState(createState)
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
return () => {
|
|
240
|
+
disposeChangeListener?.()
|
|
241
|
+
}
|
|
242
|
+
}, [
|
|
243
|
+
parentManager,
|
|
244
|
+
isNewTheme,
|
|
245
|
+
props.componentName,
|
|
246
|
+
props.inverse,
|
|
247
|
+
props.name,
|
|
248
|
+
props.reset,
|
|
249
|
+
])
|
|
250
|
+
}
|
|
210
251
|
|
|
211
252
|
if (shouldReturnParentState) {
|
|
212
253
|
if (!parentManager) throw 'impossible'
|
|
213
|
-
// prettier-ignore
|
|
214
|
-
if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') console.log('useTheme hasNoThemeUpdatingProps', parentManager.state.name, 'isInversingOnMount', isInversingOnMount)
|
|
215
254
|
return {
|
|
255
|
+
isNewTheme: false,
|
|
216
256
|
...parentManager.state,
|
|
217
257
|
className: isInversingOnMount ? '' : parentManager.state.className,
|
|
218
258
|
themeManager: parentManager,
|
|
219
|
-
isNewTheme: false,
|
|
220
259
|
}
|
|
221
260
|
}
|
|
222
261
|
|
|
223
|
-
// run inline in render
|
|
224
|
-
updateState()
|
|
225
|
-
|
|
226
262
|
return {
|
|
227
263
|
...state,
|
|
228
264
|
isNewTheme,
|
|
229
265
|
themeManager,
|
|
230
266
|
}
|
|
231
267
|
|
|
232
|
-
function createState(prev?: State) {
|
|
268
|
+
function createState(prev?: State): State {
|
|
233
269
|
if (prev && disableUpdate?.()) {
|
|
234
270
|
return prev
|
|
235
271
|
}
|
|
236
|
-
// returns previous theme manager if no change
|
|
237
|
-
const _ = new ThemeManager(props, root ? 'root' : parentManager)
|
|
238
|
-
const isNewTheme = _ !== parentManager
|
|
239
|
-
// prettier-ignore
|
|
240
272
|
|
|
241
|
-
//
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
273
|
+
// returns previous theme manager if no change
|
|
274
|
+
let themeManager: ThemeManager
|
|
275
|
+
let state: ThemeManagerState | undefined
|
|
276
|
+
|
|
277
|
+
const getNewThemeManager = () => {
|
|
278
|
+
return new ThemeManager(props, root ? 'root' : parentManager)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (prev?.themeManager) {
|
|
282
|
+
themeManager = prev.themeManager
|
|
283
|
+
|
|
284
|
+
const nextState = getThemeManagerNextStateIfChanged(themeManager)
|
|
285
|
+
|
|
286
|
+
if (nextState) {
|
|
287
|
+
state = nextState
|
|
288
|
+
|
|
289
|
+
if (!prev.isNewTheme || !isWeb) {
|
|
290
|
+
themeManager = getNewThemeManager()
|
|
291
|
+
} else {
|
|
292
|
+
themeManager.updateState(nextState, true)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
} else {
|
|
296
|
+
themeManager = getNewThemeManager()
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const isNewTheme = Boolean(
|
|
300
|
+
themeManager !== parentManager ||
|
|
301
|
+
(prev && themeManager.state.name !== prev.state.name)
|
|
302
|
+
)
|
|
245
303
|
|
|
246
304
|
// only inverse relies on this for ssr
|
|
247
305
|
const mounted = !props.inverse ? true : root || prev?.mounted
|
|
248
|
-
|
|
249
|
-
|
|
306
|
+
|
|
307
|
+
if (!state) {
|
|
308
|
+
state = isNewTheme ? { ...themeManager.state } : { ...parentManager!.state }
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const response = {
|
|
312
|
+
state,
|
|
313
|
+
themeManager,
|
|
250
314
|
isNewTheme,
|
|
251
|
-
state: { ..._.state },
|
|
252
|
-
themeManager: _,
|
|
253
315
|
mounted,
|
|
254
316
|
}
|
|
255
|
-
}
|
|
256
317
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const manager = updatingManager ?? themeManager
|
|
262
|
-
const next = manager.getState(props, parentManager)
|
|
263
|
-
const shouldChange = manager.getStateShouldChange(next, isNewTheme ? state : null)
|
|
264
|
-
// console.log(`got it`, next, isNewTheme, shouldChange, { ...updatingManager?.state })
|
|
265
|
-
if (shouldChange) {
|
|
266
|
-
setThemeState(createState)
|
|
267
|
-
} else {
|
|
268
|
-
if (!next && parentManager?.state.name !== state.name) {
|
|
269
|
-
// were changing back to parent state
|
|
270
|
-
setThemeState(createState)
|
|
271
|
-
}
|
|
318
|
+
if (process.env.NODE_ENV === 'development' && props['debug']) {
|
|
319
|
+
console.groupCollapsed(` 🔷 useChangeThemeEffect createState`)
|
|
320
|
+
console.log({ props, parentManager, themeManager, prev, response })
|
|
321
|
+
console.groupEnd()
|
|
272
322
|
}
|
|
323
|
+
|
|
324
|
+
return response
|
|
273
325
|
}
|
|
274
326
|
}
|
package/src/types.tsx
CHANGED
|
@@ -32,7 +32,7 @@ export type SpaceDirection = 'vertical' | 'horizontal' | 'both'
|
|
|
32
32
|
|
|
33
33
|
export type TamaguiElement = HTMLElement | View
|
|
34
34
|
|
|
35
|
-
export type DebugProp = boolean | 'break' | 'verbose'
|
|
35
|
+
export type DebugProp = boolean | 'break' | 'verbose' | 'visualize'
|
|
36
36
|
|
|
37
37
|
// base props that are accepted by createComponent (additional to react-native-web)
|
|
38
38
|
|
|
@@ -335,7 +335,7 @@ export interface ThemeProps {
|
|
|
335
335
|
componentName?: string
|
|
336
336
|
children?: any
|
|
337
337
|
reset?: boolean
|
|
338
|
-
debug?: DebugProp
|
|
338
|
+
debug?: DebugProp | any
|
|
339
339
|
inverse?: boolean
|
|
340
340
|
// on the web, for portals we need to re-insert className
|
|
341
341
|
forceClassName?: boolean
|
package/src/views/Theme.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isWeb } from '@tamagui/constants'
|
|
2
|
-
import { Children, cloneElement, isValidElement } from 'react'
|
|
2
|
+
import { Children, cloneElement, isValidElement, useEffect, useId, useMemo } from 'react'
|
|
3
3
|
|
|
4
4
|
import { variableToString } from '../createVariable.js'
|
|
5
5
|
import { ThemeManagerContext } from '../helpers/ThemeManagerContext.js'
|
|
@@ -9,15 +9,41 @@ import type { ThemeProps } from '../types.js'
|
|
|
9
9
|
|
|
10
10
|
export function Theme(props: ThemeProps) {
|
|
11
11
|
// @ts-expect-error only for internal views
|
|
12
|
-
if (props.disable)
|
|
12
|
+
if (props.disable) {
|
|
13
|
+
return props.children
|
|
14
|
+
}
|
|
15
|
+
|
|
13
16
|
const isRoot = !!props['_isRoot']
|
|
14
17
|
const themeState = useChangeThemeEffect(props, isRoot)
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
let children = props['data-themeable']
|
|
16
20
|
? Children.map(props.children, (child) =>
|
|
17
21
|
cloneElement(child, { ['data-themeable']: true })
|
|
18
22
|
)
|
|
19
23
|
: props.children
|
|
20
24
|
|
|
25
|
+
if (process.env.NODE_ENV === 'development') {
|
|
26
|
+
if (props['debug'] === 'visualize') {
|
|
27
|
+
children = (
|
|
28
|
+
<div style={{ display: 'inline', border: '1px solid #ccc' }}>
|
|
29
|
+
<code>
|
|
30
|
+
<pre>
|
|
31
|
+
<Theme />
|
|
32
|
+
{JSON.stringify({
|
|
33
|
+
name: themeState.themeManager?.state.name,
|
|
34
|
+
parent: themeState.themeManager?.state.parentName,
|
|
35
|
+
id: themeState.themeManager?.id,
|
|
36
|
+
parentId: themeState.themeManager?.parentManager?.id,
|
|
37
|
+
isNew: themeState.isNewTheme,
|
|
38
|
+
})}
|
|
39
|
+
</pre>
|
|
40
|
+
</code>
|
|
41
|
+
{children}
|
|
42
|
+
</div>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
21
47
|
return useThemedChildren(themeState, children, props, isRoot)
|
|
22
48
|
}
|
|
23
49
|
|
|
@@ -31,14 +57,23 @@ export function useThemedChildren(
|
|
|
31
57
|
},
|
|
32
58
|
isRoot = false
|
|
33
59
|
) {
|
|
34
|
-
const { themeManager,
|
|
60
|
+
const { themeManager, className, theme, isNewTheme } = themeState
|
|
35
61
|
const { shallow, forceClassName } = options
|
|
36
62
|
const hasEverThemed = useServerRef(false)
|
|
37
63
|
if (isNewTheme) {
|
|
38
64
|
hasEverThemed.current = true
|
|
39
65
|
}
|
|
40
66
|
|
|
41
|
-
|
|
67
|
+
const shouldRenderChildrenWithTheme =
|
|
68
|
+
isNewTheme || hasEverThemed.current || forceClassName || isRoot
|
|
69
|
+
|
|
70
|
+
return useMemo(() => {
|
|
71
|
+
// console.warn(`re-render Theme`)
|
|
72
|
+
|
|
73
|
+
if (!shouldRenderChildrenWithTheme) {
|
|
74
|
+
return children
|
|
75
|
+
}
|
|
76
|
+
|
|
42
77
|
// be sure to memoize shouldReset to avoid reparenting
|
|
43
78
|
let next = Children.toArray(children)
|
|
44
79
|
|
|
@@ -57,24 +92,6 @@ export function useThemedChildren(
|
|
|
57
92
|
})
|
|
58
93
|
}
|
|
59
94
|
|
|
60
|
-
// tried this but themes css doesn't fully like it
|
|
61
|
-
// if (shouldAttachClassName && options.passPropsToChildren) {
|
|
62
|
-
// next = next.map((child: any) => {
|
|
63
|
-
// const childStyle = child.props?.style
|
|
64
|
-
// console.log('pass it down', className, child.props.className || '')
|
|
65
|
-
// const newProps = {
|
|
66
|
-
// className: (child.props.className || '') + ' ' + className,
|
|
67
|
-
// style: Array.isArray(childStyle)
|
|
68
|
-
// ? [colorStyle, ...childStyle]
|
|
69
|
-
// : {
|
|
70
|
-
// ...colorStyle,
|
|
71
|
-
// ...childStyle,
|
|
72
|
-
// },
|
|
73
|
-
// }
|
|
74
|
-
// return isValidElement(child) ? cloneElement(child as any, newProps) : child
|
|
75
|
-
// })
|
|
76
|
-
// }
|
|
77
|
-
|
|
78
95
|
const wrapped = (
|
|
79
96
|
<ThemeManagerContext.Provider value={themeManager}>
|
|
80
97
|
{next}
|
|
@@ -93,14 +110,19 @@ export function useThemedChildren(
|
|
|
93
110
|
}
|
|
94
111
|
|
|
95
112
|
return (
|
|
96
|
-
<span className={`${className || ''} _dsp_contents`} style={colorStyle}>
|
|
113
|
+
<span className={`${className || ''} _dsp_contents is_Theme`} style={colorStyle}>
|
|
97
114
|
{wrapped}
|
|
98
115
|
</span>
|
|
99
116
|
)
|
|
100
117
|
}
|
|
101
118
|
|
|
102
119
|
return wrapped
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
120
|
+
}, [
|
|
121
|
+
shouldRenderChildrenWithTheme,
|
|
122
|
+
themeManager,
|
|
123
|
+
children,
|
|
124
|
+
theme,
|
|
125
|
+
isNewTheme,
|
|
126
|
+
className,
|
|
127
|
+
])
|
|
106
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createComponent.d.ts","sourceRoot":"","sources":["../src/createComponent.tsx"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"createComponent.d.ts","sourceRoot":"","sources":["../src/createComponent.tsx"],"names":[],"mappings":"AAGA,OAAO,KAYN,MAAM,OAAO,CAAA;AAiBd,OAAO,EACL,SAAS,EACT,cAAc,EACd,WAAW,EACX,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAEhB,qBAAqB,EAErB,cAAc,EAIf,MAAM,SAAS,CAAA;AAqBhB,eAAO,MAAM,qBAAqB,EAAE,qBAMnC,CAAA;AAeD,eAAO,MAAM,QAAQ,eAAsB,CAAA;AA8B3C,wBAAgB,eAAe,CAC7B,kBAAkB,SAAS,MAAM,GAAG,EAAE,EACtC,GAAG,GAAG,cAAc,EACpB,SAAS,GAAG,KAAK,EAEjB,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,kBAAkB,EACpD,eAAe,CAAC,EAAE,iBAAiB,4DAsyBpC;AAGD,eAAO,MAAM,QAAQ;YAAW;QAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;KAAE;;CAAmB,CAAA;AAMrE,eAAO,MAAM,MAAM,0DA8CjB,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAAA;IACnC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,mBAiGxD"}
|
|
@@ -16,6 +16,7 @@ export type ThemeManagerState = {
|
|
|
16
16
|
export declare function hasNoThemeUpdatingProps(props: ThemeProps): boolean;
|
|
17
17
|
export declare class ThemeManager {
|
|
18
18
|
props: ThemeProps;
|
|
19
|
+
id: number;
|
|
19
20
|
themeListeners: Set<ThemeListener>;
|
|
20
21
|
parentManager: ThemeManager | null;
|
|
21
22
|
state: ThemeManagerState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeManager.d.ts","sourceRoot":"","sources":["../../src/helpers/ThemeManager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAErD,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,EAAE,YAAY,KAAK,IAAI,CAAA;AAE9E,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;IACnC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAID,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,UAAU,WAExD;
|
|
1
|
+
{"version":3,"file":"ThemeManager.d.ts","sourceRoot":"","sources":["../../src/helpers/ThemeManager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAErD,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,EAAE,YAAY,KAAK,IAAI,CAAA;AAE9E,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;IACnC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAID,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,UAAU,WAExD;AAID,qBAAa,YAAY;IAOd,KAAK,EAAE,UAAU;IAN1B,EAAE,SAAQ;IACV,cAAc,qBAA2B;IACzC,aAAa,EAAE,YAAY,GAAG,IAAI,CAAO;IACzC,KAAK,EAAE,iBAAiB,CAAa;gBAG5B,KAAK,GAAE,UAAe,EAC7B,aAAa,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS;IAiC1D,WAAW,CACT,KAAK,GAAE,UAAU,GAAG;QAAE,UAAU,CAAC,EAAE,WAAW,CAAA;KAAqB,EACnE,MAAM,UAAO;IAuBf,iBAAiB,CACf,KAAK,aAAa,EAClB,KAAK,GAAE,iBAAiB,GAAG,IAAiB,EAC5C,aAAa,sBAAqB;IAYpC,oBAAoB,CAClB,SAAS,EAAE,iBAAiB,GAAG,IAAI,EACnC,KAAK,GAAE,iBAAiB,GAAG,IAAiB;IAQ9C,QAAQ,CAAC,KAAK,aAAa,EAAE,aAAa,sBAAqB;IAO/D,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAO;IACnC,IAAI,OAAO,gBAMV;IAGD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,iBAAiB;IAiB/C,MAAM;IAIN,aAAa,CAAC,EAAE,EAAE,aAAa;CAMhC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSplitStyles.d.ts","sourceRoot":"","sources":["../../src/helpers/getSplitStyles.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EAMd,eAAe,EACf,kBAAkB,EAElB,qBAAqB,EACrB,cAAc,EACd,WAAW,EAEZ,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,gCAAgC,CAAA;AAkBvC,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,cAAc,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE,kBAAkB,CAAA;IAChC,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,KAAK,EAAE,eAAe,CAAA;IACtB,IAAI,EAAE,qBAAqB,CAAA;IAC3B,eAAe,CAAC,EAAE,iBAAiB,CAAA;IACnC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA;AAsFhE,KAAK,aAAa,GAAG,CACnB,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAC7B,YAAY,EAAE,kBAAkB,EAChC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,eAAe,EACtB,iBAAiB,CAAC,EAAE,cAAc,GAAG,IAAI,EACzC,eAAe,CAAC,EAAE,mBAAmB,EAErC,WAAW,CAAC,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,SAAS,KACd,cAAc,CAAA;AAEnB,eAAO,MAAM,UAAU,MAAM,CAAA;AAqB7B,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"getSplitStyles.d.ts","sourceRoot":"","sources":["../../src/helpers/getSplitStyles.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EAMd,eAAe,EACf,kBAAkB,EAElB,qBAAqB,EACrB,cAAc,EACd,WAAW,EAEZ,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,gCAAgC,CAAA;AAkBvC,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,cAAc,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE,kBAAkB,CAAA;IAChC,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,KAAK,EAAE,eAAe,CAAA;IACtB,IAAI,EAAE,qBAAqB,CAAA;IAC3B,eAAe,CAAC,EAAE,iBAAiB,CAAA;IACnC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA;AAsFhE,KAAK,aAAa,GAAG,CACnB,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAC7B,YAAY,EAAE,kBAAkB,EAChC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,eAAe,EACtB,iBAAiB,CAAC,EAAE,cAAc,GAAG,IAAI,EACzC,eAAe,CAAC,EAAE,mBAAmB,EAErC,WAAW,CAAC,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,SAAS,KACd,cAAc,CAAA;AAEnB,eAAO,MAAM,UAAU,MAAM,CAAA;AAqB7B,eAAO,MAAM,cAAc,EAAE,aAwxB5B,CAAA;AA0FD,eAAO,MAAM,WAAW,eACV,aAAa,UACjB,MAAM,WACL,MAAM,sBACK,OAAO,wBACL,OAAO,KAC5B,cA6BF,CAAA;AAOD,eAAO,MAAM,cAAc,EAAE,aAU5B,CAAA;AA2BD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA"}
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { ThemeManager } from '../helpers/ThemeManager.js';
|
|
3
2
|
import type { ThemeParsed, ThemeProps } from '../types.js';
|
|
4
3
|
export type ChangedThemeResponse = {
|
|
4
|
+
isNewTheme: boolean;
|
|
5
5
|
themeManager: ThemeManager | null;
|
|
6
6
|
name: string;
|
|
7
|
-
isNewTheme?: boolean;
|
|
8
7
|
theme?: ThemeParsed | null;
|
|
9
8
|
className?: string;
|
|
10
9
|
};
|
|
11
10
|
export declare const useTheme: (props?: ThemeProps) => ThemeParsed;
|
|
12
11
|
export declare const useThemeWithState: (props: ThemeProps) => {
|
|
13
12
|
theme: ThemeParsed;
|
|
13
|
+
isNewTheme: boolean;
|
|
14
14
|
themeManager: ThemeManager | null;
|
|
15
15
|
name: string;
|
|
16
|
-
isNewTheme?: boolean | undefined;
|
|
17
16
|
className?: string | undefined;
|
|
18
17
|
} | null;
|
|
19
|
-
export declare function getThemeProxied({ theme, themeManager,
|
|
18
|
+
export declare function getThemeProxied({ theme, themeManager, }: Partial<ChangedThemeResponse> & {
|
|
20
19
|
theme: ThemeParsed;
|
|
21
|
-
|
|
22
|
-
}): ThemeParsed;
|
|
20
|
+
}, keys?: string[]): ThemeParsed;
|
|
23
21
|
export declare const activeThemeManagers: Set<ThemeManager>;
|
|
24
|
-
export declare const useChangeThemeEffect: (props: ThemeProps, root?: boolean, disableUpdate?: () => boolean) => ChangedThemeResponse;
|
|
22
|
+
export declare const useChangeThemeEffect: (props: ThemeProps, root?: boolean, keys?: string[], disableUpdate?: () => boolean) => ChangedThemeResponse;
|
|
25
23
|
//# sourceMappingURL=useTheme.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../src/hooks/useTheme.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useTheme.d.ts","sourceRoot":"","sources":["../../src/hooks/useTheme.tsx"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,EAGb,MAAM,4BAA4B,CAAA;AAEnC,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAI1D,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,OAAO,CAAA;IACnB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAA;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAoBD,eAAO,MAAM,QAAQ,WAAW,UAAU,KAAgB,WAEzD,CAAA;AAED,eAAO,MAAM,iBAAiB,UAAW,UAAU;;gBA7BrC,OAAO;kBACL,YAAY,GAAG,IAAI;UAC3B,MAAM;;QAmEb,CAAA;AAED,wBAAgB,eAAe,CAC7B,EACE,KAAK,EACL,YAAY,GACb,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG;IACjC,KAAK,EAAE,WAAW,CAAA;CACnB,EACD,IAAI,CAAC,EAAE,MAAM,EAAE,eA2ChB;AAED,eAAO,MAAM,mBAAmB,mBAA0B,CAAA;AAE1D,eAAO,MAAM,oBAAoB,UACxB,UAAU,yBAEV,MAAM,EAAE,kBACC,MAAM,OAAO,KAC5B,oBAgLF,CAAA"}
|
package/types/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { ThemeProviderProps } from './views/ThemeProvider.js';
|
|
|
9
9
|
export type { MediaStyleObject, StyleObject } from '@tamagui/helpers';
|
|
10
10
|
export type SpaceDirection = 'vertical' | 'horizontal' | 'both';
|
|
11
11
|
export type TamaguiElement = HTMLElement | View;
|
|
12
|
-
export type DebugProp = boolean | 'break' | 'verbose';
|
|
12
|
+
export type DebugProp = boolean | 'break' | 'verbose' | 'visualize';
|
|
13
13
|
type DivAttributes = HTMLAttributes<HTMLDivElement>;
|
|
14
14
|
export type TamaguiReactElement<P = any> = React.ReactElement<P> & {
|
|
15
15
|
type: TamaguiComponent;
|
|
@@ -199,7 +199,7 @@ export interface ThemeProps {
|
|
|
199
199
|
componentName?: string;
|
|
200
200
|
children?: any;
|
|
201
201
|
reset?: boolean;
|
|
202
|
-
debug?: DebugProp;
|
|
202
|
+
debug?: DebugProp | any;
|
|
203
203
|
inverse?: boolean;
|
|
204
204
|
forceClassName?: boolean;
|
|
205
205
|
shouldUpdate?: () => boolean;
|