@tamagui/core 1.0.1-beta.166 → 1.0.1-beta.168

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 (103) hide show
  1. package/dist/cjs/addTheme.js.map +1 -1
  2. package/dist/cjs/config.js.map +1 -1
  3. package/dist/cjs/constants/platform.js +4 -4
  4. package/dist/cjs/constants/platform.js.map +2 -2
  5. package/dist/cjs/constants/platform.native.js +3 -3
  6. package/dist/cjs/constants/platform.native.js.map +2 -2
  7. package/dist/cjs/createComponent.js +4 -2
  8. package/dist/cjs/createComponent.js.map +2 -2
  9. package/dist/cjs/createTamagui.js +1 -4
  10. package/dist/cjs/createTamagui.js.map +2 -2
  11. package/dist/cjs/createVariable.js +9 -0
  12. package/dist/cjs/createVariable.js.map +2 -2
  13. package/dist/cjs/helpers/ThemeManager.js.map +1 -1
  14. package/dist/cjs/helpers/getSplitStyles.js +16 -9
  15. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  16. package/dist/cjs/helpers/getThemeCSSRules.js.map +1 -1
  17. package/dist/cjs/helpers/isTamaguiElement.js.map +2 -2
  18. package/dist/cjs/hooks/useIsSSR.js +8 -4
  19. package/dist/cjs/hooks/useIsSSR.js.map +2 -2
  20. package/dist/cjs/hooks/useIsTouchDevice.js +1 -1
  21. package/dist/cjs/hooks/useIsTouchDevice.js.map +2 -2
  22. package/dist/cjs/hooks/useMedia.js +48 -29
  23. package/dist/cjs/hooks/useMedia.js.map +2 -2
  24. package/dist/cjs/hooks/useTheme.js +1 -1
  25. package/dist/cjs/hooks/useTheme.js.map +2 -2
  26. package/dist/cjs/styled.js +11 -8
  27. package/dist/cjs/styled.js.map +2 -2
  28. package/dist/cjs/types.js.map +1 -1
  29. package/dist/cjs/updateTheme.js.map +2 -2
  30. package/dist/cjs/views/TamaguiProvider.js +2 -2
  31. package/dist/cjs/views/TamaguiProvider.js.map +2 -2
  32. package/dist/esm/addTheme.js.map +1 -1
  33. package/dist/esm/config.js.map +1 -1
  34. package/dist/esm/constants/platform.js +3 -3
  35. package/dist/esm/constants/platform.js.map +2 -2
  36. package/dist/esm/constants/platform.native.js +2 -2
  37. package/dist/esm/constants/platform.native.js.map +2 -2
  38. package/dist/esm/createComponent.js +4 -2
  39. package/dist/esm/createComponent.js.map +2 -2
  40. package/dist/esm/createTamagui.js +1 -4
  41. package/dist/esm/createTamagui.js.map +2 -2
  42. package/dist/esm/createVariable.js +8 -0
  43. package/dist/esm/createVariable.js.map +2 -2
  44. package/dist/esm/helpers/ThemeManager.js.map +1 -1
  45. package/dist/esm/helpers/getSplitStyles.js +16 -9
  46. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  47. package/dist/esm/helpers/getThemeCSSRules.js.map +1 -1
  48. package/dist/esm/helpers/isTamaguiElement.js.map +2 -2
  49. package/dist/esm/hooks/useIsSSR.js +9 -5
  50. package/dist/esm/hooks/useIsSSR.js.map +2 -2
  51. package/dist/esm/hooks/useIsTouchDevice.js +2 -2
  52. package/dist/esm/hooks/useIsTouchDevice.js.map +2 -2
  53. package/dist/esm/hooks/useMedia.js +49 -30
  54. package/dist/esm/hooks/useMedia.js.map +2 -2
  55. package/dist/esm/hooks/useTheme.js +2 -2
  56. package/dist/esm/hooks/useTheme.js.map +2 -2
  57. package/dist/esm/styled.js +11 -8
  58. package/dist/esm/styled.js.map +2 -2
  59. package/dist/esm/updateTheme.js.map +2 -2
  60. package/dist/esm/views/TamaguiProvider.js +3 -3
  61. package/dist/esm/views/TamaguiProvider.js.map +2 -2
  62. package/package.json +10 -10
  63. package/src/addTheme.ts +3 -3
  64. package/src/config.ts +1 -1
  65. package/src/constants/platform.native.ts +1 -1
  66. package/src/constants/platform.ts +2 -2
  67. package/src/createComponent.tsx +10 -2
  68. package/src/createTamagui.ts +7 -10
  69. package/src/createVariable.ts +8 -1
  70. package/src/helpers/ThemeManager.tsx +4 -4
  71. package/src/helpers/getSplitStyles.tsx +25 -12
  72. package/src/helpers/getThemeCSSRules.ts +2 -2
  73. package/src/helpers/isTamaguiElement.tsx +3 -5
  74. package/src/hooks/useIsSSR.tsx +10 -5
  75. package/src/hooks/useIsTouchDevice.tsx +2 -2
  76. package/src/hooks/useMedia.tsx +65 -36
  77. package/src/hooks/useTheme.tsx +6 -6
  78. package/src/styled.tsx +40 -12
  79. package/src/types.tsx +45 -12
  80. package/src/updateTheme.ts +2 -2
  81. package/src/views/TamaguiProvider.tsx +3 -4
  82. package/types/addTheme.d.ts +2 -2
  83. package/types/config.d.ts +18 -2
  84. package/types/constants/platform.d.ts +1 -1
  85. package/types/constants/platform.native.d.ts +1 -1
  86. package/types/createVariable.d.ts +5 -0
  87. package/types/helpers/ThemeManager.d.ts +5 -5
  88. package/types/helpers/calc.d.ts +5 -0
  89. package/types/helpers/expandStyle.d.ts +4 -0
  90. package/types/helpers/expandStyles.d.ts +7 -0
  91. package/types/helpers/getSplitStyles.d.ts +3 -3
  92. package/types/helpers/getStylesAtomic.d.ts +4 -0
  93. package/types/helpers/getThemeCSSRules.d.ts +2 -2
  94. package/types/helpers/isTamaguiElement.d.ts +4 -6
  95. package/types/helpers/mergeProps.d.ts +13 -0
  96. package/types/helpers/normalizeValueWithProperty.d.ts +4 -0
  97. package/types/hooks/useIsSSR.d.ts +3 -1
  98. package/types/hooks/useMedia.d.ts +3 -3
  99. package/types/hooks/useTheme.d.ts +4 -4
  100. package/types/insertFont.d.ts +3 -0
  101. package/types/styled.d.ts +5 -1
  102. package/types/types.d.ts +112 -12
  103. package/types/updateTheme.d.ts +2 -2
@@ -1,12 +1,10 @@
1
1
  import React, { isValidElement } from 'react'
2
2
 
3
- import { StaticConfig } from '../types'
3
+ import { TamaguiComponent } from '../types'
4
4
  import { isTamaguiComponent } from './isTamaguiComponent'
5
5
 
6
- export type TamaguiReactElement = React.ReactElement & {
7
- type: {
8
- staticConfig: StaticConfig
9
- }
6
+ export type TamaguiReactElement<P = any> = React.ReactElement<P> & {
7
+ type: TamaguiComponent
10
8
  }
11
9
 
12
10
  export const isTamaguiElement = (child: any, name?: string): child is TamaguiReactElement => {
@@ -1,18 +1,23 @@
1
1
  import { useState } from 'react'
2
2
 
3
- import { isSSR, isWeb, useIsomorphicLayoutEffect } from '../constants/platform'
3
+ import { isServer, isWeb, useIsomorphicLayoutEffect } from '../constants/platform'
4
4
  import { startTransition } from '../helpers/startTransition'
5
5
 
6
6
  // because any change before first useEffect causes hydration / mismatch issues
7
7
 
8
- export const useIsSSR = () => {
8
+ export const useIsSSR = (props?: { immediate?: boolean }) => {
9
9
  const [val, setVal] = useState(true)
10
10
 
11
11
  useIsomorphicLayoutEffect(() => {
12
- if (isWeb && !isSSR) {
13
- startTransition(() => {
12
+ if (isWeb && !isServer) {
13
+ // could also have a global tamagui `config.immediateSSRTransition`
14
+ if (props?.immediate) {
14
15
  setVal(false)
15
- })
16
+ } else {
17
+ startTransition(() => {
18
+ setVal(false)
19
+ })
20
+ }
16
21
  }
17
22
  }, [])
18
23
 
@@ -1,13 +1,13 @@
1
1
  import { useState } from 'react'
2
2
 
3
- import { isSSR, isTouchable, isWeb, useIsomorphicLayoutEffect } from '../constants/platform'
3
+ import { isServer, isTouchable, isWeb, useIsomorphicLayoutEffect } from '../constants/platform'
4
4
 
5
5
  // ssr friendly
6
6
 
7
7
  export const useIsTouchDevice = () => {
8
8
  const [touchOnly, setTouchOnly] = useState(false)
9
9
 
10
- if (isWeb && !isSSR) {
10
+ if (isWeb && !isServer) {
11
11
  // only ever false on web SSR (env), so run effect conditionally
12
12
  // eslint-disable-next-line react-hooks/rules-of-hooks
13
13
  useIsomorphicLayoutEffect(() => {
@@ -1,20 +1,39 @@
1
- import { useMemo, useState } from 'react'
1
+ import { useEffect, useMemo, useState } from 'react'
2
2
 
3
3
  import { useIsomorphicLayoutEffect } from '../constants/platform'
4
4
  import { matchMedia } from '../helpers/matchMedia'
5
5
  import {
6
- ConfigureMediaQueryOptions,
7
6
  MediaQueries,
8
7
  MediaQueryKey,
9
8
  MediaQueryObject,
10
9
  MediaQueryState,
10
+ TamaguiInternalConfig,
11
11
  } from '../types'
12
12
  import { useSafeRef } from './useSafeRef'
13
13
 
14
- export const mediaState: MediaQueryState = {} as any
14
+ export const mediaState: MediaQueryState =
15
+ // development time safeguard
16
+ process.env.NODE_ENV === 'development'
17
+ ? new Proxy(
18
+ {},
19
+ {
20
+ get(target, key) {
21
+ if (typeof key === 'string' && key[0] === '$') {
22
+ throw new Error(`Access of mediaState should never include $`)
23
+ }
24
+ return Reflect.get(target, key)
25
+ },
26
+ }
27
+ )
28
+ : ({} as any)
29
+
15
30
  const mediaQueryListeners: { [key: string]: Set<Function> } = {}
16
31
 
17
32
  export function addMediaQueryListener(key: MediaQueryKey, cb: any) {
33
+ if (process.env.NODE_ENV === 'development' && key[0] === '$') {
34
+ // eslint-disable-next-line no-console
35
+ console.warn(`Warning, listening to media queries shouldn't use the "$" prefix`)
36
+ }
18
37
  mediaQueryListeners[key] = mediaQueryListeners[key] || new Set()
19
38
  mediaQueryListeners[key].add(cb)
20
39
  return () => removeMediaQueryListener(key, cb)
@@ -35,29 +54,17 @@ const dispose = new Set<Function>()
35
54
  // for SSR capture it at time of startup
36
55
  let initialMediaState: MediaQueryState | null
37
56
 
38
- export const configureMedia = ({
39
- queries,
40
- defaultActive = {},
41
- }: ConfigureMediaQueryOptions = {}) => {
42
- if (!queries) return
43
-
44
- // support hot reload
45
- if (initialMediaState) {
46
- if (process.env.NODE_ENV === 'development') {
47
- if (JSON.stringify(queries) === JSON.stringify(mediaQueryConfig)) {
48
- // hmr avoid update
49
- return
50
- }
51
- }
52
- setupMediaListeners()
53
- }
54
-
55
- Object.assign(mediaQueryConfig, queries)
56
- // start in the initial state
57
- for (const key in queries) {
58
- mediaState[key] = defaultActive[key] || false
57
+ export const configureMedia = (config: TamaguiInternalConfig) => {
58
+ const { media, mediaQueryDefaultActive } = config
59
+ if (!media) return
60
+ for (const key in media) {
61
+ mediaState[key] = mediaQueryDefaultActive?.[key] || false
59
62
  }
63
+ Object.assign(mediaQueryConfig, media)
60
64
  initialMediaState = { ...mediaState }
65
+ if (config.disableSSR) {
66
+ setupMediaListeners()
67
+ }
61
68
  }
62
69
 
63
70
  function unlisten() {
@@ -65,7 +72,20 @@ function unlisten() {
65
72
  dispose.clear()
66
73
  }
67
74
 
75
+ /**
76
+ * Note: This should *not* set the state on the first render!
77
+ * Because to avoid hydration issues SSR must match the server
78
+ * *and then* re-render with the actual media query state.
79
+ */
80
+ let configuredKey = ''
68
81
  function setupMediaListeners() {
82
+ // avoid setting up more than once per config
83
+ const nextKey = JSON.stringify(mediaQueryConfig)
84
+ if (nextKey === configuredKey) {
85
+ return
86
+ }
87
+ configuredKey = nextKey
88
+
69
89
  // hmr, undo existing before re-binding
70
90
  unlisten()
71
91
 
@@ -79,6 +99,7 @@ function setupMediaListeners() {
79
99
  // react native needs these deprecated apis for now
80
100
  match.addListener(update)
81
101
  dispose.add(() => match.removeListener(update))
102
+
82
103
  update()
83
104
 
84
105
  function update() {
@@ -87,16 +108,18 @@ function setupMediaListeners() {
87
108
  mediaState[key] = next
88
109
  const listeners = mediaQueryListeners[key]
89
110
  if (listeners?.size) {
90
- for (const cb of [...listeners]) {
91
- cb()
92
- }
111
+ listeners.forEach((cb) => cb())
93
112
  }
94
113
  }
95
114
  }
96
115
  }
97
116
 
98
- export function useMediaQueryListeners() {
99
- useIsomorphicLayoutEffect(() => {
117
+ export function useMediaQueryListeners(config: TamaguiInternalConfig) {
118
+ if (config.disableSSR) {
119
+ return
120
+ }
121
+
122
+ useEffect(() => {
100
123
  setupMediaListeners()
101
124
  return unlisten
102
125
  }, [])
@@ -105,7 +128,7 @@ export function useMediaQueryListeners() {
105
128
  export function useMedia(): {
106
129
  [key in MediaQueryKey]: boolean
107
130
  } {
108
- const [state, setState] = useState(initialMediaState!)
131
+ const [state, setState] = useState(initialMediaState || {})
109
132
  const keys = useSafeRef({} as Record<string, boolean>)
110
133
 
111
134
  function updateState() {
@@ -120,13 +143,12 @@ export function useMedia(): {
120
143
  }
121
144
 
122
145
  useIsomorphicLayoutEffect(() => {
123
- const listeners: Function[] = []
124
- for (const key in keys.current) {
125
- listeners.push(addMediaQueryListener(key, updateState))
126
- }
146
+ const disposes: Function[] = Object.keys(keys.current).map((key) =>
147
+ addMediaQueryListener(key, updateState)
148
+ )
127
149
  updateState()
128
150
  return () => {
129
- listeners.forEach((cb) => cb())
151
+ disposes.forEach((cb) => cb())
130
152
  }
131
153
  })
132
154
 
@@ -134,8 +156,15 @@ export function useMedia(): {
134
156
  () =>
135
157
  new Proxy(state, {
136
158
  get(_, key: string) {
159
+ if (process.env.NODE_ENV === 'development') {
160
+ if (!initialMediaState) {
161
+ throw new Error(
162
+ `To use useMedia() you must pass in media configuration to createTamagui, none was found.`
163
+ )
164
+ }
165
+ }
137
166
  if (!keys.current[key]) {
138
- keys.current = { ...keys.current, [key]: true }
167
+ keys.current[key] = true
139
168
  }
140
169
  return Reflect.get(state, key)
141
170
  },
@@ -3,7 +3,7 @@ import React, { useContext, useLayoutEffect, useMemo, useRef, useState } from 'r
3
3
 
4
4
  import { getConfig } from '../config'
5
5
  import { isDevTools } from '../constants/isDevTools'
6
- import { isRSC, isSSR, useIsomorphicLayoutEffect } from '../constants/platform'
6
+ import { isRSC, isServer, useIsomorphicLayoutEffect } from '../constants/platform'
7
7
  import { ThemeContext } from '../contexts/ThemeContext'
8
8
  import { areEqualSets } from '../helpers/areEqualSets'
9
9
  import {
@@ -12,7 +12,7 @@ import {
12
12
  ThemeManagerContext,
13
13
  emptyManager,
14
14
  } from '../helpers/ThemeManager'
15
- import { ThemeName, ThemeObject } from '../types'
15
+ import { ThemeName, ThemeParsed } from '../types'
16
16
  import { GetThemeUnwrapped } from './getThemeUnwrapped'
17
17
  import { useConstant } from './useConstant'
18
18
  import { useServerRef } from './useServerHooks'
@@ -38,7 +38,7 @@ export const useTheme = (
38
38
  componentName?: string,
39
39
  props?: ThemeProps,
40
40
  forceUpdate?: any
41
- ): ThemeObject => {
41
+ ): ThemeParsed => {
42
42
  // TODO this can use useChangeThemeEffect almost ready
43
43
  if (isRSC) {
44
44
  const config = getConfig()
@@ -195,10 +195,10 @@ export const useChangeThemeEffect = (
195
195
  forceUpdateProp?: any,
196
196
  uuid?: Object
197
197
  ): {
198
- themes: Record<string, ThemeObject>
198
+ themes: Record<string, ThemeParsed>
199
199
  themeManager: ThemeManager | null
200
200
  name: string
201
- theme: ThemeObject | null
201
+ theme: ThemeParsed | null
202
202
  className?: string
203
203
  } => {
204
204
  const { themes } = getConfig()
@@ -236,7 +236,7 @@ export const useChangeThemeEffect = (
236
236
  return new ThemeManager(next.name, next.className, next.theme, parentManager, reset)
237
237
  })
238
238
 
239
- if (!isSSR) {
239
+ if (!isServer) {
240
240
  useLayoutEffect(() => {
241
241
  themeManager.update(next)
242
242
 
package/src/styled.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Image, Text, TextInput } from 'react-native'
2
2
 
3
3
  import { createComponent } from './createComponent'
4
+ import { TamaguiReactElement, isTamaguiElement } from './helpers/isTamaguiElement'
4
5
  import { RNComponents } from './helpers/RNComponents'
5
6
  import {
6
7
  GetProps,
@@ -22,6 +23,20 @@ export type StyledOptions<ParentComponent extends StylableComponent> = GetProps<
22
23
  defaultVariants?: { [key: string]: any }
23
24
  }
24
25
 
26
+ // can't infer from styled(<YStack />) which would be nice
27
+ // * excessively deep type instantiation
28
+
29
+ type GetBaseProps<A extends StylableComponent> =
30
+ // A extends TamaguiReactElement
31
+ // ? GetBaseProps<A['type']> :
32
+ A extends TamaguiComponent<any, any, infer P> ? P : GetProps<A>
33
+
34
+ type GetVariantProps<A extends StylableComponent> =
35
+ // A extends TamaguiReactElement
36
+ // ? GetVariantProps<A['type']>
37
+ // :
38
+ A extends TamaguiComponent<any, any, any, infer V> ? V : {}
39
+
25
40
  export function styled<
26
41
  ParentComponent extends StylableComponent,
27
42
  Variants extends VariantDefinitions<ParentComponent> | void = VariantDefinitions<ParentComponent> | void
@@ -33,9 +48,18 @@ export function styled<
33
48
  variants?: Variants | undefined
34
49
  // thought i had this typed, but can't get it linked
35
50
  defaultVariants?: { [key: string]: any }
51
+ acceptsClassName?: boolean
36
52
  },
37
53
  staticExtractionOptions?: Partial<StaticConfig>
38
54
  ) {
55
+ // * excessively deep type instantiation
56
+ // if (isTamaguiElement(Component)) {
57
+ // const props = Component.props
58
+ // // @ts-ignore
59
+ // Component = Component.type
60
+ // options = options ? { ...props, ...options } : props
61
+ // }
62
+
39
63
  const staticConfigProps = (() => {
40
64
  const parentStaticConfig =
41
65
  'staticConfig' in Component ? (Component.staticConfig as StaticConfig) : null
@@ -50,7 +74,13 @@ export function styled<
50
74
  }
51
75
 
52
76
  if (options) {
53
- const { variants, name, defaultVariants, ...defaultProps } = options
77
+ const {
78
+ variants,
79
+ name,
80
+ defaultVariants,
81
+ acceptsClassName: acceptsClassNameProp,
82
+ ...defaultProps
83
+ } = options
54
84
  if (defaultVariants) {
55
85
  Object.assign(defaultProps, defaultVariants)
56
86
  }
@@ -61,12 +91,7 @@ export function styled<
61
91
  RNComponents.add(Component)
62
92
  isReactNativeWeb = true
63
93
  } else {
64
- if (process.env.NODE_ENV === 'development') {
65
- // eslint-disable-next-line no-console
66
- console.warn(
67
- `Invalid styled() component: Tamagui only accepts react-native Text, View, Image, TextInput, or another styled Tamagui view`
68
- )
69
- }
94
+ // assuming some sort of non-tamagui non-rn view, will always use style={}
70
95
  }
71
96
  }
72
97
  const reactNativeWebComponent = isReactNativeWeb
@@ -84,6 +109,8 @@ export function styled<
84
109
  isInput || staticExtractionOptions?.isText || parentStaticConfig?.isText || Comp === Text
85
110
  )
86
111
 
112
+ const acceptsClassName = acceptsClassNameProp ?? (isTamagui || isReactNativeWeb)
113
+
87
114
  const conf: Partial<StaticConfig> = {
88
115
  ...staticExtractionOptions,
89
116
  ...(!isTamagui && {
@@ -102,10 +129,12 @@ export function styled<
102
129
  isInput,
103
130
  isText,
104
131
  isImage,
132
+ acceptsClassName,
105
133
  }
106
134
 
107
135
  // TODO compiler doesn't have logic to include children, de-opt (see EnsureFlexed for test usage)
108
- if (defaultProps.children) {
136
+ // bail on non className views as well
137
+ if (defaultProps.children || !acceptsClassName) {
109
138
  conf.neverFlatten = true
110
139
  }
111
140
 
@@ -117,10 +146,9 @@ export function styled<
117
146
  const component = createComponent(staticConfigProps, Component)
118
147
 
119
148
  // get parent props without pseudos and medias so we can rebuild both with new variants
120
- type ParentPropsBase = ParentComponent extends TamaguiComponent<any, any, infer P>
121
- ? P
122
- : GetProps<ParentComponent>
123
- type ParentVariants = ParentComponent extends TamaguiComponent<any, any, any, infer V> ? V : {}
149
+ // get parent props without pseudos and medias so we can rebuild both with new variants
150
+ type ParentPropsBase = GetBaseProps<ParentComponent>
151
+ type ParentVariants = GetVariantProps<ParentComponent>
124
152
 
125
153
  type OurVariants = Variants extends void
126
154
  ? {}
package/src/types.tsx CHANGED
@@ -17,6 +17,7 @@ import {
17
17
 
18
18
  import { Variable } from './createVariable'
19
19
  import { ResolveVariableTypes } from './helpers/createPropMapper'
20
+ import { TamaguiReactElement } from './static'
20
21
  import { RNWTextProps, RNWViewProps } from './types-rnw'
21
22
  import { FontLanguageProps } from './views/FontLanguage.types'
22
23
  import { ThemeProviderProps } from './views/ThemeProvider'
@@ -161,7 +162,12 @@ export type CreateTamaguiConfig<
161
162
  fonts: RemoveLanguagePostfixes<F>
162
163
  fontLanguages: GetLanguagePostfixes<F> extends never ? string[] : GetLanguagePostfixes<F>[]
163
164
  tokens: A
164
- themes: B
165
+ // parsed
166
+ themes: {
167
+ [Name in keyof B]: {
168
+ [Key in keyof B[Name]]: Variable
169
+ }
170
+ }
165
171
  shorthands: C
166
172
  media: D
167
173
  animations: AnimationDriver<E>
@@ -229,13 +235,16 @@ export type GenericTamaguiConfig = CreateTamaguiConfig<
229
235
  >
230
236
 
231
237
  // since TamaguiConfig will be re-declared, these will all be typed globally
232
- export type ThemeObject = TamaguiConfig['themes'][keyof TamaguiConfig['themes']]
238
+ export type ThemeDefinition = TamaguiConfig['themes'][keyof TamaguiConfig['themes']]
239
+ export type ThemeKeys = keyof ThemeDefinition
240
+ export type ThemeParsed = {
241
+ [key in ThemeKeys]: Variable
242
+ }
233
243
  export type Tokens = TamaguiConfig['tokens']
234
244
  export type Shorthands = TamaguiConfig['shorthands']
235
245
  export type Media = TamaguiConfig['media']
236
246
  export type Themes = TamaguiConfig['themes']
237
247
  export type ThemeName = GetAltThemeNames<keyof Themes>
238
- export type ThemeKeys = keyof ThemeObject
239
248
  export type ThemeTokens = `$${ThemeKeys}`
240
249
  export type AnimationKeys = Omit<GetAnimationKeys<TamaguiConfig>, number>
241
250
  export type FontLanguages = ArrayIntersection<TamaguiConfig['fontLanguages']>
@@ -263,6 +272,26 @@ export type CreateTamaguiProps = {
263
272
  }
264
273
 
265
274
  defaultTheme?: string
275
+
276
+ /**
277
+ * *Advanced use case* For all CSS extracted views, this has no effect.
278
+ *
279
+ * For SSR compatibility on the web, Tamagui will render once with the settings
280
+ * from `mediaQueryDefaultActive` set for all media queries. Then, it will render
281
+ * again after the initial render using the proper media query values. This is so that
282
+ * hydration will match perfectly with the server.
283
+ *
284
+ * Setting disableSSR will avoid this second render by setting the media query state
285
+ * to the actual browser dimensions on initial load. This is only useful for client-only
286
+ * apps.
287
+ *
288
+ */
289
+ disableSSR?: boolean
290
+
291
+ /**
292
+ * Disable inserting a theme class in the DOM or context, allowing you to manually place it higher.
293
+ * For custom use cases like integration with next-theme.
294
+ */
266
295
  disableRootThemeClass?: boolean
267
296
 
268
297
  defaultProps?: Record<string, any> & {
@@ -313,9 +342,6 @@ export type TamaguiInternalConfig<
313
342
  getCSS: () => string
314
343
  parsed: boolean
315
344
  inverseShorthands: Record<string, string>
316
-
317
- // just passed in from CreateTamaguiProps
318
- themeClassNameOnRoot?: boolean
319
345
  }
320
346
 
321
347
  export type GetAnimationKeys<A extends GenericTamaguiConfig> = keyof A['animations']['animations']
@@ -351,10 +377,6 @@ export type MediaProps<A> = {
351
377
  export type MediaQueries = {
352
378
  [key in MediaQueryKey]: MediaQueryObject
353
379
  }
354
- export type ConfigureMediaQueryOptions = {
355
- queries?: MediaQueries
356
- defaultActive?: Record<MediaQueryKey, boolean>
357
- }
358
380
 
359
381
  export type TransformStyleProps = {
360
382
  x?: number
@@ -422,7 +444,7 @@ export type SizeTokens = GetTokenString<keyof Tokens['size']> | number
422
444
  export type SpaceTokens = GetTokenString<keyof Tokens['space']> | number | boolean
423
445
  export type ColorTokens =
424
446
  | GetTokenString<keyof Tokens['color']>
425
- | GetTokenString<keyof ThemeObject>
447
+ | GetTokenString<keyof ThemeParsed>
426
448
  | CSSColorNames
427
449
  export type ZIndexTokens = GetTokenString<keyof Tokens['zIndex']> | number
428
450
  export type RadiusTokens = GetTokenString<keyof Tokens['radius']> | number
@@ -639,7 +661,7 @@ export type TamaguiProviderProps = Partial<Omit<ThemeProviderProps, 'children'>>
639
661
  export type PropMapper = (
640
662
  key: string,
641
663
  value: any,
642
- theme: ThemeObject,
664
+ theme: ThemeParsed,
643
665
  props: Record<string, any>,
644
666
  state: Partial<SplitStyleState>,
645
667
  languageContext?: FontLanguageProps,
@@ -772,6 +794,13 @@ export type StaticConfig = {
772
794
  * Used insternally to attach default props to names
773
795
  */
774
796
  parentNames?: string[]
797
+
798
+ /**
799
+ * By default if styled() doesn't recognize a parent Tamagui compoent or specific react-native views,
800
+ * it will assume the passed in component only accepts style={} for react-native compatibility.
801
+ * Setting `acceptsClassName: true` indicates Tamagui can pass in className props.
802
+ */
803
+ acceptsClassName?: boolean
775
804
  }
776
805
 
777
806
  /**
@@ -782,6 +811,8 @@ export type StaticConfig = {
782
811
 
783
812
  export type StylableComponent =
784
813
  | TamaguiComponent
814
+ // * excessively deep type instantiation
815
+ // | TamaguiReactElement
785
816
  | React.Component
786
817
  | React.ForwardRefExoticComponent<any>
787
818
  | ReactComponentWithRef<any, any>
@@ -809,6 +840,8 @@ export type GetBaseProps<A extends StylableComponent> = A extends TamaguiCompone
809
840
  : never
810
841
 
811
842
  export type GetProps<A extends StylableComponent> = A extends TamaguiComponent<infer Props>
843
+ ? Props
844
+ : A extends TamaguiReactElement<infer Props>
812
845
  ? Props
813
846
  : A extends React.Component<infer Props>
814
847
  ? GetGenericComponentTamaguiProps<Props>
@@ -1,8 +1,8 @@
1
1
  import { addTheme } from './addTheme'
2
2
  import { activeThemeManagers } from './hooks/useTheme'
3
- import { ThemeObject } from './types'
3
+ import { ThemeDefinition } from './types'
4
4
 
5
- export function updateTheme({ name, theme }: { name: string; theme: ThemeObject }) {
5
+ export function updateTheme({ name, theme }: { name: string; theme: ThemeDefinition }) {
6
6
  const next = addTheme({ name, theme, insertCSS: true, update: true })
7
7
 
8
8
  if (process.env.TAMAGUI_TARGET === 'native') {
@@ -1,7 +1,6 @@
1
- import { useForceUpdate } from '@tamagui/use-force-update'
2
1
  import * as React from 'react'
3
2
 
4
- import { isClient, isRSC, isSSR } from '../constants/platform'
3
+ import { isClient, isRSC, isServer } from '../constants/platform'
5
4
  import { ButtonInsideButtonContext } from '../contexts/ButtonInsideButtonContext'
6
5
  import { TextAncestorProvider } from '../contexts/TextAncestorContext'
7
6
  import { useMediaQueryListeners } from '../hooks/useMedia'
@@ -22,8 +21,8 @@ export function TamaguiProvider({
22
21
  )
23
22
  }
24
23
 
25
- if (!isSSR) {
26
- useMediaQueryListeners()
24
+ if (!isServer) {
25
+ useMediaQueryListeners(config)
27
26
  }
28
27
 
29
28
  if (isClient) {
@@ -1,7 +1,7 @@
1
- import { ThemeObject } from './types';
1
+ import { ThemeDefinition } from './types';
2
2
  export declare function addTheme({ name: themeName, theme: themeIn, insertCSS, update, }: {
3
3
  name: string;
4
- theme: ThemeObject;
4
+ theme: ThemeDefinition;
5
5
  insertCSS?: boolean;
6
6
  update?: boolean;
7
7
  }): {
package/types/config.d.ts CHANGED
@@ -17,8 +17,24 @@ export declare const getConfig: () => TamaguiInternalConfig<import("./types").Cr
17
17
  }, import("./types").GenericFonts>;
18
18
  export declare const getTokens: () => import("./types").CreateTokens<import("./createVariable").Variable<import("./createVariable").VariableValue>>;
19
19
  export declare const getThemes: () => {
20
- [key: string]: Partial<import("./types").TamaguiBaseTheme> & {
21
- [key: string]: import("./types").VariableVal;
20
+ [x: string]: {
21
+ [x: string]: import("./createVariable").Variable<import("./createVariable").VariableValue>;
22
+ background?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
23
+ backgroundHover?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
24
+ backgroundPress?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
25
+ backgroundFocus?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
26
+ color?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
27
+ colorHover?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
28
+ colorPress?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
29
+ colorFocus?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
30
+ borderColor?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
31
+ borderColorHover?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
32
+ borderColorPress?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
33
+ borderColorFocus?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
34
+ shadowColor?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
35
+ shadowColorHover?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
36
+ shadowColorPress?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
37
+ shadowColorFocus?: import("./createVariable").Variable<import("./createVariable").VariableValue> | undefined;
22
38
  };
23
39
  };
24
40
  export declare const configListeners: Set<ConfigListener>;
@@ -3,7 +3,7 @@ export declare const isAndroid: boolean;
3
3
  export declare const isIOS: boolean;
4
4
  export declare const isWeb: boolean;
5
5
  export declare const isWindowDefined: boolean;
6
- export declare const isSSR: boolean;
6
+ export declare const isServer: boolean;
7
7
  export declare const isClient: boolean;
8
8
  export declare const isRSC: any;
9
9
  export declare const useIsomorphicLayoutEffect: typeof useEffect;
@@ -3,7 +3,7 @@ export declare const isAndroid: boolean;
3
3
  export declare const isIOS: boolean;
4
4
  export declare const isWeb = false;
5
5
  export declare const isWindowDefined = false;
6
- export declare const isSSR = false;
6
+ export declare const isServer = false;
7
7
  export declare const isClient = false;
8
8
  export declare const isRSC = false;
9
9
  export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Should rename this to Token
3
+ * Moving to objects for React Server Components support
4
+ */
1
5
  declare const IS_VAR = "__isVar__";
2
6
  export declare type VariableValue = string | number;
3
7
  declare type VariableIn<A extends VariableValue = VariableValue> = {
@@ -20,6 +24,7 @@ export declare const createVariable: <A extends string | number = any>(props: Va
20
24
  };
21
25
  export declare function variableToString(vrble?: any, getValue?: boolean): string;
22
26
  export declare function isVariable(v: Variable | any): v is Variable;
27
+ export declare function getVariable(nameOrVariable: Variable | string): string;
23
28
  export declare function getVariableValue(v: Variable | any): any;
24
29
  export declare function getVariableName(v: Variable | any): any;
25
30
  export declare function getVariableVariable(v: Variable | any): any;