@tamagui/web 1.112.1 → 1.112.3
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 +6 -141
- package/dist/cjs/createComponent.js.map +2 -2
- package/dist/cjs/createComponent.native.js +8 -143
- package/dist/cjs/createComponent.native.js.map +2 -2
- package/dist/cjs/createTamagui.js +2 -3
- package/dist/cjs/createTamagui.js.map +1 -1
- package/dist/cjs/createTamagui.native.js +2 -5
- package/dist/cjs/createTamagui.native.js.map +2 -2
- package/dist/cjs/helpers/getSplitStyles.js +2 -2
- package/dist/cjs/helpers/getSplitStyles.js.map +1 -1
- package/dist/cjs/helpers/getSplitStyles.native.js +2 -2
- package/dist/cjs/helpers/getSplitStyles.native.js.map +2 -2
- package/dist/cjs/helpers/getThemeCSSRules.js +2 -2
- package/dist/cjs/helpers/getThemeCSSRules.js.map +1 -1
- package/dist/cjs/helpers/insertStyleRule.js +1 -1
- package/dist/cjs/helpers/insertStyleRule.js.map +1 -1
- package/dist/cjs/helpers/insertStyleRule.native.js +1 -1
- package/dist/cjs/helpers/insertStyleRule.native.js.map +2 -2
- package/dist/cjs/helpers/setElementProps.js +4 -1
- package/dist/cjs/helpers/setElementProps.js.map +1 -1
- package/dist/cjs/helpers/sortString.js +21 -0
- package/dist/cjs/helpers/sortString.js.map +6 -0
- package/dist/cjs/helpers/sortString.native.js +28 -0
- package/dist/cjs/helpers/sortString.native.js.map +6 -0
- package/dist/cjs/helpers/subscribeToContextGroup.js +53 -0
- package/dist/cjs/helpers/subscribeToContextGroup.js.map +6 -0
- package/dist/cjs/helpers/subscribeToContextGroup.native.js +52 -0
- package/dist/cjs/helpers/subscribeToContextGroup.native.js.map +6 -0
- package/dist/cjs/hooks/useComponentState.js +113 -0
- package/dist/cjs/hooks/useComponentState.js.map +6 -0
- package/dist/cjs/hooks/useComponentState.native.js +127 -0
- package/dist/cjs/hooks/useComponentState.native.js.map +6 -0
- package/dist/cjs/hooks/useProps.js +3 -3
- package/dist/cjs/hooks/useProps.js.map +1 -1
- package/dist/cjs/hooks/useProps.native.js +3 -3
- package/dist/cjs/hooks/useProps.native.js.map +1 -1
- package/dist/cjs/setupHooks.js.map +1 -1
- package/dist/cjs/setupHooks.native.js +1 -1
- package/dist/cjs/setupHooks.native.js.map +1 -1
- package/dist/cjs/subscribeToContextGroup.js +53 -0
- package/dist/cjs/subscribeToContextGroup.js.map +6 -0
- package/dist/cjs/subscribeToContextGroup.native.js +52 -0
- package/dist/cjs/subscribeToContextGroup.native.js.map +6 -0
- package/dist/esm/createComponent.js +8 -151
- package/dist/esm/createComponent.js.map +2 -2
- package/dist/esm/createComponent.mjs +18 -182
- package/dist/esm/createComponent.mjs.map +1 -1
- package/dist/esm/createComponent.native.js +20 -200
- package/dist/esm/createComponent.native.js.map +1 -1
- package/dist/esm/createTamagui.js +2 -3
- package/dist/esm/createTamagui.js.map +1 -1
- package/dist/esm/createTamagui.mjs +2 -5
- package/dist/esm/createTamagui.mjs.map +1 -1
- package/dist/esm/createTamagui.native.js +2 -5
- package/dist/esm/createTamagui.native.js.map +1 -1
- package/dist/esm/helpers/getSplitStyles.js +2 -1
- package/dist/esm/helpers/getSplitStyles.js.map +1 -1
- package/dist/esm/helpers/getSplitStyles.mjs +2 -1
- package/dist/esm/helpers/getSplitStyles.mjs.map +1 -1
- package/dist/esm/helpers/getSplitStyles.native.js +2 -1
- package/dist/esm/helpers/getSplitStyles.native.js.map +1 -1
- package/dist/esm/helpers/getThemeCSSRules.js +2 -1
- package/dist/esm/helpers/getThemeCSSRules.js.map +1 -1
- package/dist/esm/helpers/getThemeCSSRules.mjs +2 -1
- package/dist/esm/helpers/getThemeCSSRules.mjs.map +1 -1
- package/dist/esm/helpers/insertStyleRule.js +1 -1
- package/dist/esm/helpers/insertStyleRule.js.map +1 -1
- package/dist/esm/helpers/insertStyleRule.mjs +1 -1
- package/dist/esm/helpers/insertStyleRule.mjs.map +1 -1
- package/dist/esm/helpers/insertStyleRule.native.js +1 -1
- package/dist/esm/helpers/insertStyleRule.native.js.map +1 -1
- package/dist/esm/helpers/setElementProps.js +4 -1
- package/dist/esm/helpers/setElementProps.js.map +1 -1
- package/dist/esm/helpers/setElementProps.mjs +4 -1
- package/dist/esm/helpers/setElementProps.mjs.map +1 -1
- package/dist/esm/helpers/sortString.js +5 -0
- package/dist/esm/helpers/sortString.js.map +6 -0
- package/dist/esm/helpers/sortString.mjs +3 -0
- package/dist/esm/helpers/sortString.mjs.map +1 -0
- package/dist/esm/helpers/sortString.native.js +5 -0
- package/dist/esm/helpers/sortString.native.js.map +1 -0
- package/dist/esm/helpers/subscribeToContextGroup.js +38 -0
- package/dist/esm/helpers/subscribeToContextGroup.js.map +6 -0
- package/dist/esm/helpers/subscribeToContextGroup.mjs +38 -0
- package/dist/esm/helpers/subscribeToContextGroup.mjs.map +1 -0
- package/dist/esm/helpers/subscribeToContextGroup.native.js +42 -0
- package/dist/esm/helpers/subscribeToContextGroup.native.js.map +1 -0
- package/dist/esm/hooks/useComponentState.js +107 -0
- package/dist/esm/hooks/useComponentState.js.map +6 -0
- package/dist/esm/hooks/useComponentState.mjs +135 -0
- package/dist/esm/hooks/useComponentState.mjs.map +1 -0
- package/dist/esm/hooks/useComponentState.native.js +147 -0
- package/dist/esm/hooks/useComponentState.native.js.map +1 -0
- package/dist/esm/hooks/useProps.js +2 -1
- package/dist/esm/hooks/useProps.js.map +1 -1
- package/dist/esm/hooks/useProps.mjs +2 -1
- package/dist/esm/hooks/useProps.mjs.map +1 -1
- package/dist/esm/hooks/useProps.native.js +2 -1
- package/dist/esm/hooks/useProps.native.js.map +1 -1
- package/dist/esm/setupHooks.js.map +1 -1
- package/dist/esm/setupHooks.mjs.map +1 -1
- package/dist/esm/setupHooks.native.js +0 -1
- package/dist/esm/setupHooks.native.js.map +1 -1
- package/dist/esm/subscribeToContextGroup.js +38 -0
- package/dist/esm/subscribeToContextGroup.js.map +6 -0
- package/dist/esm/subscribeToContextGroup.mjs +38 -0
- package/dist/esm/subscribeToContextGroup.mjs.map +1 -0
- package/dist/esm/subscribeToContextGroup.native.js +42 -0
- package/dist/esm/subscribeToContextGroup.native.js.map +1 -0
- package/package.json +12 -12
- package/src/createComponent.tsx +6 -316
- package/src/createTamagui.ts +11 -4
- package/src/helpers/getSplitStyles.tsx +2 -1
- package/src/helpers/getThemeCSSRules.ts +2 -1
- package/src/helpers/insertStyleRule.tsx +3 -1
- package/src/helpers/setElementProps.tsx +5 -1
- package/src/helpers/sortString.ts +1 -0
- package/src/helpers/subscribeToContextGroup.tsx +56 -0
- package/src/hooks/useComponentState.ts +258 -0
- package/src/hooks/useProps.tsx +2 -2
- package/src/setupHooks.ts +4 -5
- package/types/createComponent.d.ts +1 -30
- package/types/createComponent.d.ts.map +1 -1
- package/types/createTamagui.d.ts.map +1 -1
- package/types/helpers/getSplitStyles.d.ts.map +1 -1
- package/types/helpers/getThemeCSSRules.d.ts.map +1 -1
- package/types/helpers/insertStyleRule.d.ts.map +1 -1
- package/types/helpers/setElementProps.d.ts +1 -1
- package/types/helpers/setElementProps.d.ts.map +1 -1
- package/types/helpers/sortString.d.ts +2 -0
- package/types/helpers/sortString.d.ts.map +1 -0
- package/types/helpers/subscribeToContextGroup.d.ts +10 -0
- package/types/helpers/subscribeToContextGroup.d.ts.map +1 -0
- package/types/hooks/useComponentState.d.ts +22 -0
- package/types/hooks/useComponentState.d.ts.map +1 -0
- package/types/hooks/useProps.d.ts.map +1 -1
- package/types/setupHooks.d.ts +3 -2
- package/types/setupHooks.d.ts.map +1 -1
package/src/createComponent.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
1
|
import { composeRefs } from '@tamagui/compose-refs'
|
|
3
2
|
import { isClient, isServer, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
|
|
4
3
|
import {
|
|
@@ -7,29 +6,21 @@ import {
|
|
|
7
6
|
composeEventHandlers,
|
|
8
7
|
validStyles,
|
|
9
8
|
} from '@tamagui/helpers'
|
|
10
|
-
|
|
9
|
+
import React from 'react'
|
|
11
10
|
import { devConfig, getConfig, onConfiguredOnce } from './config'
|
|
12
11
|
import { stackDefaultStyles } from './constants/constants'
|
|
13
12
|
import { isDevTools } from './constants/isDevTools'
|
|
14
13
|
import { ComponentContext } from './contexts/ComponentContext'
|
|
15
14
|
import { didGetVariableValue, setDidGetVariableValue } from './createVariable'
|
|
16
|
-
import {
|
|
17
|
-
defaultComponentState,
|
|
18
|
-
defaultComponentStateMounted,
|
|
19
|
-
defaultComponentStateShouldEnter,
|
|
20
|
-
} from './defaultComponentState'
|
|
21
|
-
import {
|
|
22
|
-
createShallowSetState,
|
|
23
|
-
mergeIfNotShallowEqual,
|
|
24
|
-
} from './helpers/createShallowSetState'
|
|
15
|
+
import { defaultComponentStateMounted } from './defaultComponentState'
|
|
25
16
|
import { useSplitStyles } from './helpers/getSplitStyles'
|
|
26
|
-
import { isObj } from './helpers/isObj'
|
|
27
17
|
import { log } from './helpers/log'
|
|
28
18
|
import { mergeProps } from './helpers/mergeProps'
|
|
29
19
|
import { setElementProps } from './helpers/setElementProps'
|
|
20
|
+
import { subscribeToContextGroup } from './helpers/subscribeToContextGroup'
|
|
30
21
|
import { themeable } from './helpers/themeable'
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
22
|
+
import { useComponentState } from './hooks/useComponentState'
|
|
23
|
+
import { setMediaShouldUpdate, useMedia } from './hooks/useMedia'
|
|
33
24
|
import { useThemeWithState } from './hooks/useTheme'
|
|
34
25
|
import type { TamaguiComponentEvents } from './interfaces/TamaguiComponentEvents'
|
|
35
26
|
import type { TamaguiComponentState } from './interfaces/TamaguiComponentState'
|
|
@@ -38,8 +29,6 @@ import { hooks } from './setupHooks'
|
|
|
38
29
|
import type {
|
|
39
30
|
ComponentContextI,
|
|
40
31
|
DebugProp,
|
|
41
|
-
GroupState,
|
|
42
|
-
GroupStateListener,
|
|
43
32
|
LayoutEvent,
|
|
44
33
|
SizeTokens,
|
|
45
34
|
SpaceDirection,
|
|
@@ -51,7 +40,6 @@ import type {
|
|
|
51
40
|
StaticConfig,
|
|
52
41
|
StyleableOptions,
|
|
53
42
|
TamaguiComponent,
|
|
54
|
-
TamaguiComponentStateRef,
|
|
55
43
|
TamaguiElement,
|
|
56
44
|
TamaguiInternalConfig,
|
|
57
45
|
TextProps,
|
|
@@ -140,227 +128,6 @@ if (typeof document !== 'undefined') {
|
|
|
140
128
|
}
|
|
141
129
|
}
|
|
142
130
|
|
|
143
|
-
export const useComponentState = (
|
|
144
|
-
props: StackProps | TextProps | Record<string, any>,
|
|
145
|
-
{ animationDriver, groups }: ComponentContextI,
|
|
146
|
-
staticConfig: StaticConfig,
|
|
147
|
-
config: TamaguiInternalConfig
|
|
148
|
-
) => {
|
|
149
|
-
const useAnimations = animationDriver?.useAnimations as UseAnimationHook | undefined
|
|
150
|
-
|
|
151
|
-
const stateRef = React.useRef<TamaguiComponentStateRef>(
|
|
152
|
-
undefined as any as TamaguiComponentStateRef
|
|
153
|
-
)
|
|
154
|
-
if (!stateRef.current) {
|
|
155
|
-
stateRef.current = {}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// after we get states mount we need to turn off isAnimated for server side
|
|
159
|
-
const hasAnimationProp = Boolean(
|
|
160
|
-
'animation' in props || (props.style && hasAnimatedStyleValue(props.style))
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
// disable for now still ssr issues
|
|
164
|
-
const supportsCSSVars = animationDriver?.supportsCSSVars
|
|
165
|
-
const curStateRef = stateRef.current
|
|
166
|
-
|
|
167
|
-
const willBeAnimatedClient = (() => {
|
|
168
|
-
const next = !!(hasAnimationProp && !staticConfig.isHOC && useAnimations)
|
|
169
|
-
return Boolean(next || curStateRef.hasAnimated)
|
|
170
|
-
})()
|
|
171
|
-
|
|
172
|
-
const willBeAnimated = !isServer && willBeAnimatedClient
|
|
173
|
-
|
|
174
|
-
// once animated, always animated to preserve hooks / vdom structure
|
|
175
|
-
if (willBeAnimated && !curStateRef.hasAnimated) {
|
|
176
|
-
curStateRef.hasAnimated = true
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// HOOK
|
|
180
|
-
const presence =
|
|
181
|
-
(willBeAnimated &&
|
|
182
|
-
props['animatePresence'] !== false &&
|
|
183
|
-
animationDriver?.usePresence?.()) ||
|
|
184
|
-
null
|
|
185
|
-
const presenceState = presence?.[2]
|
|
186
|
-
const isExiting = presenceState?.isPresent === false
|
|
187
|
-
const isEntering = presenceState?.isPresent === true && presenceState.initial !== false
|
|
188
|
-
|
|
189
|
-
const hasEnterStyle = !!props.enterStyle
|
|
190
|
-
// finish animated logic, avoid isAnimated when unmounted
|
|
191
|
-
const hasRNAnimation = hasAnimationProp && animationDriver?.isReactNative
|
|
192
|
-
|
|
193
|
-
if (process.env.NODE_ENV === 'development' && time) time`pre-use-state`
|
|
194
|
-
|
|
195
|
-
const hasEnterState = hasEnterStyle || isEntering
|
|
196
|
-
|
|
197
|
-
// this can be conditional because its only ever needed with animations
|
|
198
|
-
const didHydrateOnce = willBeAnimated ? useDidHydrateOnce() : true
|
|
199
|
-
const shouldEnter = hasEnterState || (!didHydrateOnce && hasRNAnimation)
|
|
200
|
-
const shouldEnterFromUnhydrated = isWeb && !didHydrateOnce
|
|
201
|
-
|
|
202
|
-
const initialState = shouldEnter
|
|
203
|
-
? // on the very first render we switch all spring animation drivers to css rendering
|
|
204
|
-
// this is because we need to use css variables, which they don't support to do proper SSR
|
|
205
|
-
// without flickers of the wrong colors.
|
|
206
|
-
// but once we do that initial hydration and we are in client side rendering mode,
|
|
207
|
-
// we can avoid the extra re-render on mount
|
|
208
|
-
shouldEnterFromUnhydrated
|
|
209
|
-
? defaultComponentState
|
|
210
|
-
: defaultComponentStateShouldEnter
|
|
211
|
-
: defaultComponentStateMounted
|
|
212
|
-
|
|
213
|
-
// will be nice to deprecate half of these:
|
|
214
|
-
const disabled = isDisabled(props)
|
|
215
|
-
|
|
216
|
-
if (disabled != null) {
|
|
217
|
-
initialState.disabled = disabled
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// HOOK
|
|
221
|
-
const states = React.useState<TamaguiComponentState>(initialState)
|
|
222
|
-
|
|
223
|
-
const state = props.forceStyle ? { ...states[0], [props.forceStyle]: true } : states[0]
|
|
224
|
-
const setState = states[1]
|
|
225
|
-
|
|
226
|
-
const isHydrated = state.unmounted === false || state.unmounted === 'should-enter'
|
|
227
|
-
|
|
228
|
-
// only web server + initial client render run this when not hydrated:
|
|
229
|
-
let isAnimated = willBeAnimated
|
|
230
|
-
if (isWeb && hasRNAnimation && !staticConfig.isHOC && state.unmounted === true) {
|
|
231
|
-
isAnimated = false
|
|
232
|
-
curStateRef.willHydrate = true
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// immediately update disabled state and reset component state
|
|
236
|
-
if (disabled !== state.disabled) {
|
|
237
|
-
state.disabled = disabled
|
|
238
|
-
// if disabled remove all press/focus/hover states
|
|
239
|
-
if (disabled) {
|
|
240
|
-
Object.assign(state, defaultComponentStateMounted)
|
|
241
|
-
}
|
|
242
|
-
setState({ ...state })
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
let setStateShallow = createShallowSetState(setState, disabled, false, props.debug)
|
|
246
|
-
|
|
247
|
-
// if (isHydrated && state.unmounted === 'should-enter') {
|
|
248
|
-
// state.unmounted = true
|
|
249
|
-
// }
|
|
250
|
-
|
|
251
|
-
// set enter/exit variants onto our new props object
|
|
252
|
-
if (presenceState && isAnimated && isHydrated && staticConfig.variants) {
|
|
253
|
-
if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') {
|
|
254
|
-
console.warn(`has presenceState ${JSON.stringify(presenceState)}`)
|
|
255
|
-
}
|
|
256
|
-
const { enterVariant, exitVariant, enterExitVariant, custom } = presenceState
|
|
257
|
-
if (isObj(custom)) {
|
|
258
|
-
Object.assign(props, custom)
|
|
259
|
-
}
|
|
260
|
-
const exv = exitVariant ?? enterExitVariant
|
|
261
|
-
const env = enterVariant ?? enterExitVariant
|
|
262
|
-
if (state.unmounted && env && staticConfig.variants[env]) {
|
|
263
|
-
if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') {
|
|
264
|
-
console.warn(`Animating presence ENTER "${env}"`)
|
|
265
|
-
}
|
|
266
|
-
props[env] = true
|
|
267
|
-
} else if (isExiting && exv) {
|
|
268
|
-
if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') {
|
|
269
|
-
console.warn(`Animating presence EXIT "${exv}"`)
|
|
270
|
-
}
|
|
271
|
-
props[exv] = exitVariant !== enterExitVariant
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
let shouldAvoidClasses = !isWeb
|
|
276
|
-
|
|
277
|
-
// on server for SSR and animation compat added the && isHydrated but perhaps we want
|
|
278
|
-
// disableClassName="until-hydrated" to be more straightforward
|
|
279
|
-
// see issue if not, Button sets disableClassName to true <Button animation="" /> with
|
|
280
|
-
// the react-native driver errors because it tries to animate var(--color) to rbga(..)
|
|
281
|
-
if (isWeb) {
|
|
282
|
-
const { disableClassName } = props
|
|
283
|
-
|
|
284
|
-
const isAnimatedAndHydrated =
|
|
285
|
-
isAnimated && !supportsCSSVars && didHydrateOnce && !isServer
|
|
286
|
-
|
|
287
|
-
const isClassNameDisabled =
|
|
288
|
-
!staticConfig.acceptsClassName && (config.disableSSR || didHydrateOnce)
|
|
289
|
-
|
|
290
|
-
const isDisabledManually =
|
|
291
|
-
disableClassName && !isServer && didHydrateOnce && state.unmounted === true
|
|
292
|
-
|
|
293
|
-
if (isAnimatedAndHydrated || isDisabledManually || isClassNameDisabled) {
|
|
294
|
-
shouldAvoidClasses = true
|
|
295
|
-
|
|
296
|
-
if (process.env.NODE_ENV === 'development' && props.debug) {
|
|
297
|
-
log(`avoiding className`, {
|
|
298
|
-
isAnimatedAndHydrated,
|
|
299
|
-
isDisabledManually,
|
|
300
|
-
isClassNameDisabled,
|
|
301
|
-
})
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const groupName = props.group as any as string
|
|
307
|
-
|
|
308
|
-
if (groupName && !curStateRef.group) {
|
|
309
|
-
const listeners = new Set<GroupStateListener>()
|
|
310
|
-
curStateRef.group = {
|
|
311
|
-
listeners,
|
|
312
|
-
emit(name, state) {
|
|
313
|
-
listeners.forEach((l) => l(name, state))
|
|
314
|
-
},
|
|
315
|
-
subscribe(cb) {
|
|
316
|
-
listeners.add(cb)
|
|
317
|
-
return () => {
|
|
318
|
-
listeners.delete(cb)
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (groupName) {
|
|
325
|
-
// when we set state we also set our group state and emit an event for children listening:
|
|
326
|
-
const groupContextState = groups.state
|
|
327
|
-
const og = setStateShallow
|
|
328
|
-
setStateShallow = (state) => {
|
|
329
|
-
og(state)
|
|
330
|
-
curStateRef.group!.emit(groupName, {
|
|
331
|
-
pseudo: state,
|
|
332
|
-
})
|
|
333
|
-
// and mutate the current since its concurrent safe (children throw it in useState on mount)
|
|
334
|
-
const next = {
|
|
335
|
-
...groupContextState[groupName],
|
|
336
|
-
...state,
|
|
337
|
-
}
|
|
338
|
-
groupContextState[groupName] = next
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return {
|
|
343
|
-
curStateRef,
|
|
344
|
-
disabled,
|
|
345
|
-
groupName,
|
|
346
|
-
hasAnimationProp,
|
|
347
|
-
hasEnterStyle,
|
|
348
|
-
isAnimated,
|
|
349
|
-
isExiting,
|
|
350
|
-
isHydrated,
|
|
351
|
-
presence,
|
|
352
|
-
presenceState,
|
|
353
|
-
setState,
|
|
354
|
-
setStateShallow,
|
|
355
|
-
shouldAvoidClasses,
|
|
356
|
-
state,
|
|
357
|
-
stateRef,
|
|
358
|
-
supportsCSSVars,
|
|
359
|
-
willBeAnimated,
|
|
360
|
-
willBeAnimatedClient,
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
131
|
/**
|
|
365
132
|
* Only on native do we need the actual underlying View/Text
|
|
366
133
|
* On the web we avoid react-native dep altogether.
|
|
@@ -406,14 +173,7 @@ export function createComponent<
|
|
|
406
173
|
}
|
|
407
174
|
})
|
|
408
175
|
|
|
409
|
-
const {
|
|
410
|
-
Component,
|
|
411
|
-
isText,
|
|
412
|
-
isZStack,
|
|
413
|
-
isHOC,
|
|
414
|
-
validStyles = {},
|
|
415
|
-
variants = {},
|
|
416
|
-
} = staticConfig
|
|
176
|
+
const { Component, isText, isZStack, isHOC } = staticConfig
|
|
417
177
|
|
|
418
178
|
if (process.env.NODE_ENV === 'development' && staticConfig.defaultProps?.['debug']) {
|
|
419
179
|
if (process.env.IS_STATIC !== 'is_static') {
|
|
@@ -1757,75 +1517,5 @@ const AbsoluteFill: any = createComponent({
|
|
|
1757
1517
|
},
|
|
1758
1518
|
})
|
|
1759
1519
|
|
|
1760
|
-
function hasAnimatedStyleValue(style: Object) {
|
|
1761
|
-
return Object.keys(style).some((k) => {
|
|
1762
|
-
const val = style[k]
|
|
1763
|
-
return val && typeof val === 'object' && '_animation' in val
|
|
1764
|
-
})
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
1520
|
const fromPx = (val?: number | string) =>
|
|
1768
1521
|
typeof val !== 'string' ? val : +val.replace('px', '')
|
|
1769
|
-
|
|
1770
|
-
export const isDisabled = (props: any) => {
|
|
1771
|
-
return (
|
|
1772
|
-
props.disabled ||
|
|
1773
|
-
props.accessibilityState?.disabled ||
|
|
1774
|
-
props['aria-disabled'] ||
|
|
1775
|
-
props.accessibilityDisabled ||
|
|
1776
|
-
false
|
|
1777
|
-
)
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
export const subscribeToContextGroup = ({
|
|
1781
|
-
disabled = false,
|
|
1782
|
-
setStateShallow,
|
|
1783
|
-
pseudoGroups,
|
|
1784
|
-
mediaGroups,
|
|
1785
|
-
componentContext,
|
|
1786
|
-
state,
|
|
1787
|
-
}: {
|
|
1788
|
-
disabled?: boolean
|
|
1789
|
-
setStateShallow: (next?: Partial<TamaguiComponentState> | undefined) => void
|
|
1790
|
-
pseudoGroups?: Set<string>
|
|
1791
|
-
mediaGroups?: Set<string>
|
|
1792
|
-
componentContext: ComponentContextI
|
|
1793
|
-
state: TamaguiComponentState
|
|
1794
|
-
}) => {
|
|
1795
|
-
// parent group pseudo listening
|
|
1796
|
-
if (pseudoGroups || mediaGroups) {
|
|
1797
|
-
const current = {
|
|
1798
|
-
pseudo: {},
|
|
1799
|
-
media: {},
|
|
1800
|
-
} satisfies GroupState
|
|
1801
|
-
|
|
1802
|
-
if (process.env.NODE_ENV === 'development' && !componentContext.groups) {
|
|
1803
|
-
console.debug(`No context group found`)
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
return componentContext.groups?.subscribe?.((name, { layout, pseudo }) => {
|
|
1807
|
-
if (pseudo && pseudoGroups?.has(String(name))) {
|
|
1808
|
-
// we emit a partial so merge it + change reference so mergeIfNotShallowEqual runs
|
|
1809
|
-
Object.assign(current.pseudo, pseudo)
|
|
1810
|
-
persist()
|
|
1811
|
-
} else if (layout && mediaGroups) {
|
|
1812
|
-
const mediaState = getMediaState(mediaGroups, layout)
|
|
1813
|
-
const next = mergeIfNotShallowEqual(current.media, mediaState)
|
|
1814
|
-
if (next !== current.media) {
|
|
1815
|
-
Object.assign(current.media, next)
|
|
1816
|
-
persist()
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
function persist() {
|
|
1820
|
-
// force it to be referentially different so it always updates
|
|
1821
|
-
const group = {
|
|
1822
|
-
...state.group,
|
|
1823
|
-
[name]: current,
|
|
1824
|
-
}
|
|
1825
|
-
setStateShallow({
|
|
1826
|
-
group,
|
|
1827
|
-
})
|
|
1828
|
-
}
|
|
1829
|
-
})
|
|
1830
|
-
}
|
|
1831
|
-
}
|
package/src/createTamagui.ts
CHANGED
|
@@ -64,11 +64,18 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
|
|
|
64
64
|
let foundThemes: DedupedThemes | undefined
|
|
65
65
|
if (configIn.themes) {
|
|
66
66
|
const noThemes = Object.keys(configIn.themes).length === 0
|
|
67
|
-
|
|
67
|
+
if (noThemes) {
|
|
68
|
+
foundThemes = scanAllSheets(noThemes, tokensParsed)
|
|
69
|
+
}
|
|
70
|
+
if (process.env.TAMAGUI_REACT_19 && process.env.TAMAGUI_SKIP_THEME_OPTIMIZATION) {
|
|
71
|
+
// save some bundle
|
|
72
|
+
} else {
|
|
73
|
+
if (noThemes) {
|
|
74
|
+
listenForSheetChanges()
|
|
75
|
+
}
|
|
76
|
+
}
|
|
68
77
|
}
|
|
69
78
|
|
|
70
|
-
listenForSheetChanges()
|
|
71
|
-
|
|
72
79
|
let fontSizeTokens: Set<string> | null = null
|
|
73
80
|
let fontsParsed:
|
|
74
81
|
| {
|
|
@@ -164,7 +171,7 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
|
|
|
164
171
|
}
|
|
165
172
|
}
|
|
166
173
|
|
|
167
|
-
const themesIn =
|
|
174
|
+
const themesIn = configIn.themes as ThemesLikeObject
|
|
168
175
|
const dedupedThemes = foundThemes ?? getThemesDeduped(themesIn)
|
|
169
176
|
const themes = proxyThemesToParents(dedupedThemes)
|
|
170
177
|
|
|
@@ -71,6 +71,7 @@ import { pseudoDescriptors, pseudoPriorities } from './pseudoDescriptors'
|
|
|
71
71
|
import { skipProps } from './skipProps'
|
|
72
72
|
import { transformsToString } from './transformsToString'
|
|
73
73
|
import { isActivePlatform } from './isActivePlatform'
|
|
74
|
+
import { sortString } from './sortString'
|
|
74
75
|
|
|
75
76
|
const consoleGroupCollapsed = isWeb ? console.groupCollapsed : console.info
|
|
76
77
|
|
|
@@ -1108,7 +1109,7 @@ export const getSplitStyles: StyleSplitter = (
|
|
|
1108
1109
|
// to the "flat" transform props
|
|
1109
1110
|
styleState.style ||= {}
|
|
1110
1111
|
Object.entries(styleState.flatTransforms)
|
|
1111
|
-
.sort(([a], [b]) => a
|
|
1112
|
+
.sort(([a], [b]) => sortString(a, b))
|
|
1112
1113
|
.forEach(([key, val]) => {
|
|
1113
1114
|
mergeTransform(styleState.style!, key, val, true)
|
|
1114
1115
|
})
|
|
@@ -6,6 +6,7 @@ import { variableToString } from '../createVariable'
|
|
|
6
6
|
import type { CreateTamaguiProps, ThemeParsed } from '../types'
|
|
7
7
|
import { tokensValueToVariable } from './registerCSSVariable'
|
|
8
8
|
import { getSetting } from '../config'
|
|
9
|
+
import { sortString } from './sortString'
|
|
9
10
|
|
|
10
11
|
const darkLight = ['dark', 'light']
|
|
11
12
|
const lightDark = ['light', 'dark']
|
|
@@ -114,7 +115,7 @@ export function getThemeCSSRules(props: {
|
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
const selectors = [...selectorsSet].sort(
|
|
118
|
+
const selectors = [...selectorsSet].sort(sortString)
|
|
118
119
|
|
|
119
120
|
// only do our :root attach if it's not light/dark - not support sub themes on root saves a lot of effort/size
|
|
120
121
|
// this isBaseTheme logic could probably be done more efficiently above
|
|
@@ -39,6 +39,7 @@ function addTransform(identifier: string, css: string, rule?: CSSRule) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// once react 19 onyl supported we can remove most of this
|
|
42
43
|
// gets existing ones (client side)
|
|
43
44
|
// takes ~0.1ms for a fairly large page
|
|
44
45
|
// used now for three things:
|
|
@@ -308,7 +309,8 @@ function getTamaguiSelector(
|
|
|
308
309
|
return [getIdentifierFromTamaguiSelector(text), rule]
|
|
309
310
|
}
|
|
310
311
|
if (collectThemes) {
|
|
311
|
-
|
|
312
|
+
// only matches t_ starting selector chains
|
|
313
|
+
if (/^(:root\s?(\.t_[a-z0-9_]+\s*)+(,)?\s*)+$/i.test(text)) {
|
|
312
314
|
return [
|
|
313
315
|
text.slice(0, 20), // just used as uid
|
|
314
316
|
rule,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const sortString = (a: string, b: string) => (a < b ? -1 : a > b ? 1 : 0)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { mergeIfNotShallowEqual } from './createShallowSetState'
|
|
2
|
+
import { getMediaState } from '../hooks/useMedia'
|
|
3
|
+
import type { TamaguiComponentState, ComponentContextI, GroupState } from '../types'
|
|
4
|
+
|
|
5
|
+
export const subscribeToContextGroup = ({
|
|
6
|
+
disabled = false,
|
|
7
|
+
setStateShallow,
|
|
8
|
+
pseudoGroups,
|
|
9
|
+
mediaGroups,
|
|
10
|
+
componentContext,
|
|
11
|
+
state,
|
|
12
|
+
}: {
|
|
13
|
+
disabled?: boolean
|
|
14
|
+
setStateShallow: (next?: Partial<TamaguiComponentState> | undefined) => void
|
|
15
|
+
pseudoGroups?: Set<string>
|
|
16
|
+
mediaGroups?: Set<string>
|
|
17
|
+
componentContext: ComponentContextI
|
|
18
|
+
state: TamaguiComponentState
|
|
19
|
+
}) => {
|
|
20
|
+
// parent group pseudo listening
|
|
21
|
+
if (pseudoGroups || mediaGroups) {
|
|
22
|
+
const current = {
|
|
23
|
+
pseudo: {},
|
|
24
|
+
media: {},
|
|
25
|
+
} satisfies GroupState
|
|
26
|
+
|
|
27
|
+
if (process.env.NODE_ENV === 'development' && !componentContext.groups) {
|
|
28
|
+
console.debug(`No context group found`)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return componentContext.groups?.subscribe?.((name, { layout, pseudo }) => {
|
|
32
|
+
if (pseudo && pseudoGroups?.has(String(name))) {
|
|
33
|
+
// we emit a partial so merge it + change reference so mergeIfNotShallowEqual runs
|
|
34
|
+
Object.assign(current.pseudo, pseudo)
|
|
35
|
+
persist()
|
|
36
|
+
} else if (layout && mediaGroups) {
|
|
37
|
+
const mediaState = getMediaState(mediaGroups, layout)
|
|
38
|
+
const next = mergeIfNotShallowEqual(current.media, mediaState)
|
|
39
|
+
if (next !== current.media) {
|
|
40
|
+
Object.assign(current.media, next)
|
|
41
|
+
persist()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function persist() {
|
|
45
|
+
// force it to be referentially different so it always updates
|
|
46
|
+
const group = {
|
|
47
|
+
...state.group,
|
|
48
|
+
[name]: current,
|
|
49
|
+
}
|
|
50
|
+
setStateShallow({
|
|
51
|
+
group,
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
}
|