@tamagui/core 1.0.1-beta.214 → 1.0.1-beta.216
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/constants/isDevTools.js +9 -1
- package/dist/cjs/constants/isDevTools.js.map +2 -2
- package/dist/cjs/createComponent.js +82 -156
- package/dist/cjs/createComponent.js.map +3 -3
- package/dist/cjs/helpers/createPropMapper.js.map +2 -2
- package/dist/cjs/helpers/getSplitStyles.js +74 -47
- package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
- package/dist/cjs/helpers/getStylesAtomic.js +5 -1
- package/dist/cjs/helpers/getStylesAtomic.js.map +2 -2
- package/dist/cjs/helpers/normalizeValueWithProperty.js +9 -5
- package/dist/cjs/helpers/normalizeValueWithProperty.js.map +2 -2
- package/dist/cjs/helpers/pseudoDescriptors.js +10 -0
- package/dist/cjs/helpers/pseudoDescriptors.js.map +2 -2
- package/dist/cjs/helpers/useShallowSetState.js +1 -1
- package/dist/cjs/helpers/useShallowSetState.js.map +2 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/views/TamaguiProvider.js +2 -5
- package/dist/cjs/views/TamaguiProvider.js.map +3 -3
- package/dist/esm/constants/isDevTools.js +9 -1
- package/dist/esm/constants/isDevTools.js.map +2 -2
- package/dist/esm/createComponent.js +83 -156
- package/dist/esm/createComponent.js.map +3 -3
- package/dist/esm/helpers/createPropMapper.js.map +2 -2
- package/dist/esm/helpers/getSplitStyles.js +75 -48
- package/dist/esm/helpers/getSplitStyles.js.map +2 -2
- package/dist/esm/helpers/getStylesAtomic.js +5 -1
- package/dist/esm/helpers/getStylesAtomic.js.map +2 -2
- package/dist/esm/helpers/normalizeValueWithProperty.js +9 -5
- package/dist/esm/helpers/normalizeValueWithProperty.js.map +2 -2
- package/dist/esm/helpers/pseudoDescriptors.js +10 -0
- package/dist/esm/helpers/pseudoDescriptors.js.map +2 -2
- package/dist/esm/helpers/useShallowSetState.js +1 -1
- package/dist/esm/helpers/useShallowSetState.js.map +2 -2
- package/dist/esm/views/TamaguiProvider.js +2 -5
- package/dist/esm/views/TamaguiProvider.js.map +3 -3
- package/package.json +12 -12
- package/src/constants/isDevTools.ts +10 -4
- package/src/createComponent.tsx +101 -208
- package/src/helpers/createPropMapper.ts +1 -0
- package/src/helpers/getSplitStyles.tsx +91 -57
- package/src/helpers/getStylesAtomic.ts +7 -2
- package/src/helpers/normalizeValueWithProperty.ts +11 -5
- package/src/helpers/pseudoDescriptors.ts +24 -3
- package/src/helpers/useShallowSetState.tsx +1 -1
- package/src/types.tsx +1 -1
- package/src/views/TamaguiProvider.tsx +5 -6
- package/types/helpers/getSplitStyles.d.ts +1 -1
- package/types/helpers/pseudoDescriptors.d.ts +8 -14
- package/types/types.d.ts +1 -1
|
@@ -7,7 +7,7 @@ function useShallowSetState(setter, debug, debugName) {
|
|
|
7
7
|
if (prev[key] !== next[key]) {
|
|
8
8
|
if (process.env.NODE_ENV === "development") {
|
|
9
9
|
if (debug === "verbose") {
|
|
10
|
-
console.
|
|
10
|
+
console.log(` \u25B2 setState ${debugName}`, next);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
return { ...prev, ...next };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/helpers/useShallowSetState.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useCallback } from 'react'\n\nexport function useShallowSetState<State extends Object>(\n setter: React.Dispatch<React.SetStateAction<State>>,\n debug?: boolean | 'verbose',\n debugName?: string\n) {\n return useCallback(\n (next: Partial<State>) => {\n setter((prev) => {\n for (const key in next) {\n if (prev[key] !== next[key]) {\n if (process.env.NODE_ENV === 'development') {\n if (debug === 'verbose') {\n // eslint-disable-next-line no-console\n console.
|
|
5
|
-
"mappings": "AAAA,SAAgB,mBAAmB;AAE5B,SAAS,mBACd,QACA,OACA,WACA;AACA,SAAO;AAAA,IACL,CAAC,SAAyB;AACxB,aAAO,CAAC,SAAS;AACf,mBAAW,OAAO,MAAM;AACtB,cAAI,KAAK,SAAS,KAAK,MAAM;AAC3B,gBAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,kBAAI,UAAU,WAAW;AAEvB,wBAAQ,
|
|
4
|
+
"sourcesContent": ["import React, { useCallback } from 'react'\n\nexport function useShallowSetState<State extends Object>(\n setter: React.Dispatch<React.SetStateAction<State>>,\n debug?: boolean | 'verbose',\n debugName?: string\n) {\n return useCallback(\n (next: Partial<State>) => {\n setter((prev) => {\n for (const key in next) {\n if (prev[key] !== next[key]) {\n if (process.env.NODE_ENV === 'development') {\n if (debug === 'verbose') {\n // eslint-disable-next-line no-console\n console.log(` \u25B2 setState ${debugName}`, next)\n }\n }\n return { ...prev, ...next }\n }\n }\n return prev\n })\n },\n [setter]\n )\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAgB,mBAAmB;AAE5B,SAAS,mBACd,QACA,OACA,WACA;AACA,SAAO;AAAA,IACL,CAAC,SAAyB;AACxB,aAAO,CAAC,SAAS;AACf,mBAAW,OAAO,MAAM;AACtB,cAAI,KAAK,SAAS,KAAK,MAAM;AAC3B,gBAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,kBAAI,UAAU,WAAW;AAEvB,wBAAQ,IAAI,oBAAe,aAAa,IAAI;AAAA,cAC9C;AAAA,YACF;AACA,mBAAO,EAAE,GAAG,MAAM,GAAG,KAAK;AAAA,UAC5B;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,7 +5,6 @@ import { ButtonInsideButtonContext } from "../contexts/ButtonInsideButtonContext
|
|
|
5
5
|
import { TextAncestorContext } from "../contexts/TextAncestorContext";
|
|
6
6
|
import { useMediaListeners } from "../hooks/useMedia";
|
|
7
7
|
import { ThemeProvider } from "./ThemeProvider";
|
|
8
|
-
import { getConfig } from "..";
|
|
9
8
|
function TamaguiProvider({
|
|
10
9
|
children,
|
|
11
10
|
disableInjectCSS,
|
|
@@ -13,10 +12,9 @@ function TamaguiProvider({
|
|
|
13
12
|
...themePropsProvider
|
|
14
13
|
}) {
|
|
15
14
|
if (isRSC) {
|
|
16
|
-
const { themes: themes2 } = getConfig();
|
|
17
15
|
return /* @__PURE__ */ jsx("span", {
|
|
18
16
|
style: { display: "contents" },
|
|
19
|
-
className: `t_${Object.keys(
|
|
17
|
+
className: `t_${Object.keys(config.themes)[0] || "light"}`,
|
|
20
18
|
children
|
|
21
19
|
});
|
|
22
20
|
}
|
|
@@ -35,7 +33,6 @@ function TamaguiProvider({
|
|
|
35
33
|
};
|
|
36
34
|
}, [config, disableInjectCSS]);
|
|
37
35
|
}
|
|
38
|
-
const { themes } = getConfig();
|
|
39
36
|
return /* @__PURE__ */ jsx(ButtonInsideButtonContext.Provider, {
|
|
40
37
|
value: false,
|
|
41
38
|
children: /* @__PURE__ */ jsx(TextAncestorContext.Provider, {
|
|
@@ -44,7 +41,7 @@ function TamaguiProvider({
|
|
|
44
41
|
themeClassNameOnRoot: config.themeClassNameOnRoot,
|
|
45
42
|
disableRootThemeClass: config.disableRootThemeClass,
|
|
46
43
|
...themePropsProvider,
|
|
47
|
-
defaultTheme: themePropsProvider.defaultTheme ?? Object.keys(themes)[0],
|
|
44
|
+
defaultTheme: themePropsProvider.defaultTheme ?? Object.keys(config.themes)[0],
|
|
48
45
|
children
|
|
49
46
|
})
|
|
50
47
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/views/TamaguiProvider.tsx"],
|
|
4
|
-
"sourcesContent": ["import { isClient, isRSC, isServer } from '@tamagui/constants'\nimport * as React from 'react'\n\nimport { ButtonInsideButtonContext } from '../contexts/ButtonInsideButtonContext'\nimport { TextAncestorContext } from '../contexts/TextAncestorContext'\nimport { useMediaListeners } from '../hooks/useMedia'\nimport type { TamaguiProviderProps } from '../types'\nimport { ThemeProvider } from './ThemeProvider'\
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": [
|
|
4
|
+
"sourcesContent": ["import { isClient, isRSC, isServer } from '@tamagui/constants'\nimport * as React from 'react'\n\nimport { ButtonInsideButtonContext } from '../contexts/ButtonInsideButtonContext'\nimport { TextAncestorContext } from '../contexts/TextAncestorContext'\nimport { useMediaListeners } from '../hooks/useMedia'\nimport type { TamaguiProviderProps } from '../types'\nimport { ThemeProvider } from './ThemeProvider'\n\nexport function TamaguiProvider({\n children,\n disableInjectCSS,\n config,\n ...themePropsProvider\n}: TamaguiProviderProps) {\n if (isRSC) {\n return (\n <span\n style={{ display: 'contents' }}\n className={`t_${Object.keys(config.themes)[0] || 'light'}`}\n >\n {children}\n </span>\n )\n }\n\n if (!isServer) {\n useMediaListeners(config)\n }\n\n if (isClient) {\n // inject CSS if asked to (not SSR compliant)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useLayoutEffect(() => {\n if (disableInjectCSS) return\n const style = document.createElement('style')\n style.appendChild(document.createTextNode(config.getCSS()))\n document.head.appendChild(style)\n return () => {\n document.head.removeChild(style)\n }\n }, [config, disableInjectCSS])\n }\n\n return (\n <ButtonInsideButtonContext.Provider value={false}>\n <TextAncestorContext.Provider value={false}>\n <ThemeProvider\n themeClassNameOnRoot={config.themeClassNameOnRoot}\n disableRootThemeClass={config.disableRootThemeClass}\n {...themePropsProvider}\n defaultTheme={themePropsProvider.defaultTheme ?? Object.keys(config.themes)[0]}\n >\n {children}\n </ThemeProvider>\n </TextAncestorContext.Provider>\n </ButtonInsideButtonContext.Provider>\n )\n}\n"],
|
|
5
|
+
"mappings": "AAiBM;AAjBN,SAAS,UAAU,OAAO,gBAAgB;AAC1C,YAAY,WAAW;AAEvB,SAAS,iCAAiC;AAC1C,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAElC,SAAS,qBAAqB;AAEvB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,KACG;AACL,GAAyB;AACvB,MAAI,OAAO;AACT,WACE,oBAAC;AAAA,MACC,OAAO,EAAE,SAAS,WAAW;AAAA,MAC7B,WAAW,KAAK,OAAO,KAAK,OAAO,MAAM,EAAE,MAAM;AAAA,MAEhD;AAAA,KACH;AAAA,EAEJ;AAEA,MAAI,CAAC,UAAU;AACb,sBAAkB,MAAM;AAAA,EAC1B;AAEA,MAAI,UAAU;AAGZ,UAAM,gBAAgB,MAAM;AAC1B,UAAI;AAAkB;AACtB,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,YAAY,SAAS,eAAe,OAAO,OAAO,CAAC,CAAC;AAC1D,eAAS,KAAK,YAAY,KAAK;AAC/B,aAAO,MAAM;AACX,iBAAS,KAAK,YAAY,KAAK;AAAA,MACjC;AAAA,IACF,GAAG,CAAC,QAAQ,gBAAgB,CAAC;AAAA,EAC/B;AAEA,SACE,oBAAC,0BAA0B,UAA1B;AAAA,IAAmC,OAAO;AAAA,IACzC,8BAAC,oBAAoB,UAApB;AAAA,MAA6B,OAAO;AAAA,MACnC,8BAAC;AAAA,QACC,sBAAsB,OAAO;AAAA,QAC7B,uBAAuB,OAAO;AAAA,QAC7B,GAAG;AAAA,QACJ,cAAc,mBAAmB,gBAAgB,OAAO,KAAK,OAAO,MAAM,EAAE;AAAA,QAE3E;AAAA,OACH;AAAA,KACF;AAAA,GACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/core",
|
|
3
|
-
"version": "1.0.1-beta.
|
|
3
|
+
"version": "1.0.1-beta.216",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"main": "dist/cjs",
|
|
6
6
|
"module": "dist/esm",
|
|
@@ -28,23 +28,23 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@expo/match-media": "^0.3.0",
|
|
31
|
-
"@tamagui/compose-refs": "^1.0.1-beta.
|
|
32
|
-
"@tamagui/constants": "^1.0.1-beta.
|
|
33
|
-
"@tamagui/helpers": "^1.0.1-beta.
|
|
34
|
-
"@tamagui/normalize-css-color-lite": "^1.0.1-beta.
|
|
35
|
-
"@tamagui/react-native-use-pressable": "^1.0.1-beta.
|
|
36
|
-
"@tamagui/react-native-use-responder-events": "^1.0.1-beta.
|
|
37
|
-
"@tamagui/types-react-native": "^1.0.1-beta.
|
|
38
|
-
"@tamagui/use-did-finish-ssr": "^1.0.1-beta.
|
|
39
|
-
"@tamagui/use-event": "^1.0.1-beta.
|
|
40
|
-
"@tamagui/use-force-update": "^1.0.1-beta.
|
|
31
|
+
"@tamagui/compose-refs": "^1.0.1-beta.216",
|
|
32
|
+
"@tamagui/constants": "^1.0.1-beta.216",
|
|
33
|
+
"@tamagui/helpers": "^1.0.1-beta.216",
|
|
34
|
+
"@tamagui/normalize-css-color-lite": "^1.0.1-beta.216",
|
|
35
|
+
"@tamagui/react-native-use-pressable": "^1.0.1-beta.216",
|
|
36
|
+
"@tamagui/react-native-use-responder-events": "^1.0.1-beta.216",
|
|
37
|
+
"@tamagui/types-react-native": "^1.0.1-beta.216",
|
|
38
|
+
"@tamagui/use-did-finish-ssr": "^1.0.1-beta.216",
|
|
39
|
+
"@tamagui/use-event": "^1.0.1-beta.216",
|
|
40
|
+
"@tamagui/use-force-update": "^1.0.1-beta.216"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"react": "*",
|
|
44
44
|
"react-dom": "*"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@tamagui/build": "^1.0.1-beta.
|
|
47
|
+
"@tamagui/build": "^1.0.1-beta.216",
|
|
48
48
|
"@types/node": "^16.11.9",
|
|
49
49
|
"@types/react": "^18.0.15",
|
|
50
50
|
"@types/react-native": "^0.69.2",
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
// for verbose logging outside node/cli
|
|
2
2
|
|
|
3
|
-
export const isDevTools =
|
|
4
|
-
process.env.NODE_ENV === 'development'
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export const isDevTools = (() => {
|
|
4
|
+
if (process.env.NODE_ENV === 'development') {
|
|
5
|
+
try {
|
|
6
|
+
return new Function('try {return this===window;}catch(e){ return false;}')()
|
|
7
|
+
} catch {
|
|
8
|
+
//
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return false
|
|
12
|
+
})()
|
package/src/createComponent.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { isClient, isRSC, isWeb, useIsomorphicLayoutEffect } from '@tamagui/cons
|
|
|
3
3
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
4
4
|
import {
|
|
5
5
|
composeEventHandlers,
|
|
6
|
+
stylePropsTransform,
|
|
6
7
|
stylePropsView,
|
|
7
8
|
validPseudoKeys,
|
|
8
9
|
validStyles,
|
|
@@ -36,7 +37,9 @@ import {
|
|
|
36
37
|
} from './helpers/getSplitStyles'
|
|
37
38
|
import { getAllSelectors } from './helpers/insertStyleRule'
|
|
38
39
|
import { mergeProps } from './helpers/mergeProps'
|
|
40
|
+
import { mergeTransform } from './helpers/mergeTransform'
|
|
39
41
|
import { proxyThemeVariables } from './helpers/proxyThemeVariables'
|
|
42
|
+
import { pseudoDescriptors } from './helpers/pseudoDescriptors'
|
|
40
43
|
import { useShallowSetState } from './helpers/useShallowSetState'
|
|
41
44
|
import { getRect, measureLayout, useElementLayout } from './hooks/useElementLayout'
|
|
42
45
|
import { addMediaQueryListener, getInitialMediaState } from './hooks/useMedia'
|
|
@@ -46,6 +49,7 @@ import {
|
|
|
46
49
|
SpaceDirection,
|
|
47
50
|
SpaceTokens,
|
|
48
51
|
SpacerProps,
|
|
52
|
+
SplitStyleState,
|
|
49
53
|
StaticConfig,
|
|
50
54
|
StaticConfigParsed,
|
|
51
55
|
StylableComponent,
|
|
@@ -162,16 +166,6 @@ export function createComponent<
|
|
|
162
166
|
? `is_${props.componentName}`
|
|
163
167
|
: defaultComponentClassName
|
|
164
168
|
|
|
165
|
-
if (debugProp) {
|
|
166
|
-
// eslint-disable-next-line no-console
|
|
167
|
-
console.log(`render ${componentName}`)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const forceUpdate = useForceUpdate()
|
|
171
|
-
const theme = useTheme(props.theme, componentName, props, forceUpdate)
|
|
172
|
-
|
|
173
|
-
// time`useTheme`
|
|
174
|
-
|
|
175
169
|
/**
|
|
176
170
|
* Component state for tracking animations, pseudos
|
|
177
171
|
*/
|
|
@@ -185,14 +179,46 @@ export function createComponent<
|
|
|
185
179
|
const setState = states[1]
|
|
186
180
|
const setStateShallow = useShallowSetState(setState, debugProp, componentName)
|
|
187
181
|
|
|
188
|
-
const
|
|
182
|
+
const useAnimations = tamaguiConfig.animations?.useAnimations as UseAnimationHook | undefined
|
|
183
|
+
// conditional but if ever true stays true
|
|
184
|
+
const hasEverAnimated = useRef(false)
|
|
185
|
+
const isAnimated = (() => {
|
|
186
|
+
const next = !!(useAnimations && props.animation)
|
|
187
|
+
if (next && !hasEverAnimated.current) {
|
|
188
|
+
hasEverAnimated.current = true
|
|
189
|
+
}
|
|
190
|
+
return next || hasEverAnimated.current
|
|
191
|
+
})()
|
|
192
|
+
const isReactNative = Boolean(
|
|
193
|
+
staticConfig.isReactNative || (isAnimated && tamaguiConfig.animations.isReactNative)
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
if (process.env.NODE_ENV === 'development') {
|
|
197
|
+
if (props['debug']) {
|
|
198
|
+
const name = `${
|
|
199
|
+
componentName || Component?.displayName || Component?.name || '[Unnamed Component]'
|
|
200
|
+
}`
|
|
201
|
+
const type = isReactNative ? '(rnw)' : ''
|
|
202
|
+
const dataIs = propsIn['data-is'] || ''
|
|
203
|
+
const banner = `${name}${dataIs ? ` ${dataIs}` : ''} ${type}`
|
|
204
|
+
// eslint-disable-next-line no-console
|
|
205
|
+
console.group(`%c ${banner}`, 'background: yellow;')
|
|
206
|
+
// eslint-disable-next-line no-console
|
|
207
|
+
console.log(`state`, state)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const forceUpdate = useForceUpdate()
|
|
212
|
+
const theme = useTheme(props.theme, componentName, props, forceUpdate)
|
|
213
|
+
|
|
214
|
+
const shouldSetMounted = needsMount && state.unmounted
|
|
189
215
|
const setMounted = shouldSetMounted
|
|
190
216
|
? () => {
|
|
191
217
|
// for some reason without some small delay it doesn't animate css
|
|
192
218
|
setTimeout(
|
|
193
219
|
() => {
|
|
194
220
|
setStateShallow({
|
|
195
|
-
|
|
221
|
+
unmounted: false,
|
|
196
222
|
})
|
|
197
223
|
},
|
|
198
224
|
isWeb ? 10 : 0
|
|
@@ -201,41 +227,14 @@ export function createComponent<
|
|
|
201
227
|
: undefined
|
|
202
228
|
|
|
203
229
|
const shouldAvoidClasses =
|
|
204
|
-
!!(props.animation && avoidClassesWhileAnimating) || !staticConfig.acceptsClassName
|
|
230
|
+
!isWeb || !!(props.animation && avoidClassesWhileAnimating) || !staticConfig.acceptsClassName
|
|
205
231
|
|
|
206
232
|
const shouldForcePseudo = !!propsIn.forceStyle
|
|
207
233
|
const hasTextAncestor = !!(isWeb && isText ? useContext(TextAncestorContext) : false)
|
|
208
|
-
const
|
|
209
|
-
!shouldAvoidClasses && !shouldForcePseudo
|
|
210
|
-
? {
|
|
211
|
-
...state,
|
|
212
|
-
hasTextAncestor,
|
|
213
|
-
dynamicStylesInline: true,
|
|
214
|
-
}
|
|
215
|
-
: ({
|
|
216
|
-
...state,
|
|
217
|
-
noClassNames: true,
|
|
218
|
-
dynamicStylesInline: true,
|
|
219
|
-
hasTextAncestor,
|
|
220
|
-
resolveVariablesAs: 'value',
|
|
221
|
-
} as const)
|
|
222
|
-
|
|
234
|
+
const noClassNames = shouldAvoidClasses || shouldForcePseudo
|
|
223
235
|
const languageContext = isRSC ? null : useContext(FontLanguageContext)
|
|
224
|
-
|
|
225
236
|
const isDisabled = props.disabled ?? props.accessibilityState?.disabled
|
|
226
237
|
|
|
227
|
-
const useAnimations = tamaguiConfig.animations?.useAnimations as UseAnimationHook | undefined
|
|
228
|
-
|
|
229
|
-
// conditional but if ever true stays true
|
|
230
|
-
const hasEverAnimated = useRef(false)
|
|
231
|
-
const isAnimated = (() => {
|
|
232
|
-
const next = !!(useAnimations && props.animation)
|
|
233
|
-
if (next && !hasEverAnimated.current) {
|
|
234
|
-
hasEverAnimated.current = true
|
|
235
|
-
}
|
|
236
|
-
return next || hasEverAnimated.current
|
|
237
|
-
})()
|
|
238
|
-
|
|
239
238
|
const isTaggable = !Component || typeof Component === 'string'
|
|
240
239
|
// default to tag, fallback to component (when both strings)
|
|
241
240
|
const element = isWeb
|
|
@@ -255,6 +254,13 @@ export function createComponent<
|
|
|
255
254
|
|
|
256
255
|
// time`setupStateConf`
|
|
257
256
|
|
|
257
|
+
const splitStyleState: SplitStyleState = {
|
|
258
|
+
...state,
|
|
259
|
+
noClassNames,
|
|
260
|
+
dynamicStylesInline: noClassNames,
|
|
261
|
+
hasTextAncestor,
|
|
262
|
+
resolveVariablesAs: 'value',
|
|
263
|
+
}
|
|
258
264
|
const splitStyles = useSplitStyles(
|
|
259
265
|
props,
|
|
260
266
|
staticConfig,
|
|
@@ -271,9 +277,6 @@ export function createComponent<
|
|
|
271
277
|
const hostRef = useServerRef<TamaguiElement>(null)
|
|
272
278
|
|
|
273
279
|
// animation setup
|
|
274
|
-
const isReactNative = Boolean(
|
|
275
|
-
staticConfig.isReactNative || (isAnimated && tamaguiConfig.animations.isReactNative)
|
|
276
|
-
)
|
|
277
280
|
const isAnimatedReactNativeWeb = isAnimated && avoidClassesWhileAnimating
|
|
278
281
|
|
|
279
282
|
if (process.env.NODE_ENV === 'development') {
|
|
@@ -283,22 +286,15 @@ export function createComponent<
|
|
|
283
286
|
}
|
|
284
287
|
|
|
285
288
|
if (debugProp) {
|
|
286
|
-
const name = `${
|
|
287
|
-
componentName || Component?.displayName || Component?.name || '[Unnamed Component]'
|
|
288
|
-
}`
|
|
289
|
-
const type = isReactNative ? 'rnw' : 'tamagui'
|
|
290
|
-
const banner = `${name} ${propsIn['data-is'] || ''} ${type}`
|
|
291
289
|
// eslint-disable-next-line no-console
|
|
292
|
-
console.
|
|
290
|
+
console.groupCollapsed('props')
|
|
293
291
|
// eslint-disable-next-line no-console
|
|
294
|
-
console.
|
|
295
|
-
// eslint-disable-next-line no-console
|
|
296
|
-
console.log('propsIn', propsIn, 'turned into', props, 'order', Object.keys(props))
|
|
292
|
+
console.log('props in', propsIn, 'mapped to', props, 'in order', Object.keys(props))
|
|
297
293
|
// eslint-disable-next-line no-console
|
|
298
294
|
console.log('splitStyles', splitStyles)
|
|
299
295
|
// eslint-disable-next-line no-console
|
|
300
296
|
console.log('className', Object.values(splitStyles.classNames))
|
|
301
|
-
if (
|
|
297
|
+
if (isClient) {
|
|
302
298
|
// eslint-disable-next-line no-console
|
|
303
299
|
console.log('ref', hostRef, '(click to view)')
|
|
304
300
|
}
|
|
@@ -320,9 +316,6 @@ export function createComponent<
|
|
|
320
316
|
mediaKeys,
|
|
321
317
|
} = splitStyles
|
|
322
318
|
|
|
323
|
-
const animationFeatureStylesIn = props.animation
|
|
324
|
-
? { ...defaultNativeStyle, ...splitStylesStyle }
|
|
325
|
-
: null
|
|
326
319
|
const propsWithAnimation = props as UseAnimationProps
|
|
327
320
|
|
|
328
321
|
// once you set animation prop don't remove it, you can set to undefined/false
|
|
@@ -336,9 +329,14 @@ export function createComponent<
|
|
|
336
329
|
hostRef,
|
|
337
330
|
staticConfig,
|
|
338
331
|
getStyle({ isExiting, isEntering, exitVariant, enterVariant } = {}) {
|
|
332
|
+
// TODO this function can mostly be moved entirely inside getSplitStyles
|
|
333
|
+
// I think theres bugs in merge(), and we can remove that fn entirely then
|
|
334
|
+
// also i think we need to merge both the exitVariant AND psuedos.exitStyle right now it chooses one
|
|
335
|
+
|
|
339
336
|
// we have to merge such that transforms keys all exist
|
|
340
|
-
const
|
|
337
|
+
const animationStyle = { ...defaultNativeStyle, ...splitStylesStyle }
|
|
341
338
|
|
|
339
|
+
// allows for enter/exit variants on styled()
|
|
342
340
|
const enterStyle = isEntering
|
|
343
341
|
? enterVariant && staticConfig.variants?.[enterVariant]['true']
|
|
344
342
|
? getSubStyle(
|
|
@@ -349,8 +347,8 @@ export function createComponent<
|
|
|
349
347
|
props,
|
|
350
348
|
state,
|
|
351
349
|
tamaguiConfig
|
|
352
|
-
)
|
|
353
|
-
:
|
|
350
|
+
)
|
|
351
|
+
: null
|
|
354
352
|
: null
|
|
355
353
|
|
|
356
354
|
const exitStyle = isExiting
|
|
@@ -363,41 +361,18 @@ export function createComponent<
|
|
|
363
361
|
props,
|
|
364
362
|
state,
|
|
365
363
|
tamaguiConfig
|
|
366
|
-
)
|
|
364
|
+
)
|
|
367
365
|
: pseudos.exitStyle
|
|
368
366
|
: null
|
|
369
367
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
// hoverStyle: { scale: 2 }
|
|
376
|
-
// enterStyle: { x: 100 }
|
|
377
|
-
// output:
|
|
378
|
-
// base: { x: 0, scale: 1 }
|
|
379
|
-
ensureBaseHasDefaults(
|
|
380
|
-
style,
|
|
381
|
-
// enterStyle,
|
|
382
|
-
pseudos.hoverStyle,
|
|
383
|
-
pseudos.focusStyle,
|
|
384
|
-
pseudos.pressStyle
|
|
385
|
-
)
|
|
386
|
-
|
|
387
|
-
enterStyle && isEntering && merge(style, enterStyle)
|
|
388
|
-
state.hover && pseudos.hoverStyle && merge(style, pseudos.hoverStyle)
|
|
389
|
-
state.focus && pseudos.focusStyle && merge(style, pseudos.focusStyle)
|
|
390
|
-
state.press && pseudos.pressStyle && merge(style, pseudos.pressStyle)
|
|
391
|
-
exitStyle && isExiting && merge(style, exitStyle)
|
|
392
|
-
|
|
393
|
-
if (process.env.NODE_ENV === 'development') {
|
|
394
|
-
if (debugProp === 'verbose') {
|
|
395
|
-
// eslint-disable-next-line no-console
|
|
396
|
-
console.log('animation style', style)
|
|
397
|
-
}
|
|
368
|
+
if (isEntering && enterStyle) {
|
|
369
|
+
merge(animationStyle, enterStyle)
|
|
370
|
+
}
|
|
371
|
+
if (isExiting && exitStyle) {
|
|
372
|
+
merge(animationStyle, exitStyle)
|
|
398
373
|
}
|
|
399
374
|
|
|
400
|
-
return
|
|
375
|
+
return animationStyle
|
|
401
376
|
},
|
|
402
377
|
//, delay
|
|
403
378
|
})
|
|
@@ -628,16 +603,7 @@ export function createComponent<
|
|
|
628
603
|
}
|
|
629
604
|
} else {
|
|
630
605
|
styles = [isWeb ? null : defaultNativeStyle, animationStyles ?? splitStylesStyle, medias]
|
|
631
|
-
|
|
632
|
-
const initPseudos = initialSplitStyles.pseudos
|
|
633
|
-
!state.mounted && addPseudoToStyles(styles, initPseudos, pseudos, 'enterStyle')
|
|
634
|
-
state.hover &&
|
|
635
|
-
addPseudoToStyles(styles, initPseudos, pseudos, 'hoverStyle', shouldForcePseudo)
|
|
636
|
-
state.focus &&
|
|
637
|
-
addPseudoToStyles(styles, initPseudos, pseudos, 'focusStyle', shouldForcePseudo)
|
|
638
|
-
state.press &&
|
|
639
|
-
addPseudoToStyles(styles, initPseudos, pseudos, 'pressStyle', shouldForcePseudo)
|
|
640
|
-
}
|
|
606
|
+
|
|
641
607
|
// ugly but for now...
|
|
642
608
|
if (shouldForcePseudo) {
|
|
643
609
|
const next = {}
|
|
@@ -723,19 +689,14 @@ export function createComponent<
|
|
|
723
689
|
|
|
724
690
|
// TODO need to loop active variants and see if they have matchin pseudos and apply as well
|
|
725
691
|
const initialPseudos = initialSplitStyles?.pseudos
|
|
726
|
-
const
|
|
727
|
-
|
|
728
|
-
initialPseudos?.pressStyle ||
|
|
729
|
-
onPress ||
|
|
730
|
-
onPressOut ||
|
|
731
|
-
onPressIn ||
|
|
732
|
-
onClick
|
|
733
|
-
)
|
|
692
|
+
const runtimePressStyle = noClassNames && (pseudos?.pressStyle || initialPseudos?.pressStyle)
|
|
693
|
+
const attachPress = !!(runtimePressStyle || onPress || onPressOut || onPressIn || onClick)
|
|
734
694
|
|
|
735
695
|
const isHoverable = isWeb
|
|
696
|
+
const runtimeHoverStyle = noClassNames && (pseudos?.hoverStyle || initialPseudos.hoverStyle)
|
|
736
697
|
const attachHover =
|
|
737
698
|
isHoverable &&
|
|
738
|
-
!!(
|
|
699
|
+
!!(runtimeHoverStyle || onHoverIn || onHoverOut || onMouseEnter || onMouseLeave)
|
|
739
700
|
|
|
740
701
|
const handlesPressEvents = !isWeb && !asChild
|
|
741
702
|
|
|
@@ -768,7 +729,7 @@ export function createComponent<
|
|
|
768
729
|
onMouseUp?.(e)
|
|
769
730
|
}
|
|
770
731
|
: undefined,
|
|
771
|
-
...(
|
|
732
|
+
...(attachHover && {
|
|
772
733
|
onMouseEnter: attachHover
|
|
773
734
|
? (e) => {
|
|
774
735
|
const next: Partial<typeof state> = {}
|
|
@@ -894,10 +855,7 @@ export function createComponent<
|
|
|
894
855
|
// EVENTS native
|
|
895
856
|
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
896
857
|
// add focus events
|
|
897
|
-
const attachFocus = !!(
|
|
898
|
-
(pseudos && pseudos.focusStyle) ||
|
|
899
|
-
(initialPseudos && initialPseudos.focusStyle)
|
|
900
|
-
)
|
|
858
|
+
const attachFocus = !!(pseudos.focusStyle || (initialPseudos && initialPseudos.focusStyle))
|
|
901
859
|
if (attachFocus) {
|
|
902
860
|
viewProps.onFocus = mergeEvent(viewProps.onFocus, () => {
|
|
903
861
|
setStateShallow({ focus: true })
|
|
@@ -909,11 +867,8 @@ export function createComponent<
|
|
|
909
867
|
|
|
910
868
|
// use Pressability to get smooth unPress when you press + hold + move out
|
|
911
869
|
// only ever create once, use .configure() to update later
|
|
912
|
-
const pressability = usePressability(events)
|
|
870
|
+
const pressability = usePressability(events ? { ...events, hitSlop } : {})
|
|
913
871
|
if (attachPress && events) {
|
|
914
|
-
if (hitSlop) {
|
|
915
|
-
viewProps.hitSlop = hitSlop
|
|
916
|
-
}
|
|
917
872
|
for (const key in pressability) {
|
|
918
873
|
const og = props[key]
|
|
919
874
|
const val = pressability[key]
|
|
@@ -989,12 +944,12 @@ export function createComponent<
|
|
|
989
944
|
press: false,
|
|
990
945
|
pressIn: false,
|
|
991
946
|
focus: false,
|
|
992
|
-
|
|
947
|
+
unmounted: true,
|
|
993
948
|
mediaState: getMediaStateObject(getInitialMediaState()),
|
|
994
949
|
}
|
|
995
950
|
defaultComponentStateMounted = {
|
|
996
951
|
...defaultComponentState,
|
|
997
|
-
|
|
952
|
+
unmounted: false,
|
|
998
953
|
}
|
|
999
954
|
}
|
|
1000
955
|
|
|
@@ -1052,14 +1007,13 @@ export function createComponent<
|
|
|
1052
1007
|
staticConfig,
|
|
1053
1008
|
initialTheme,
|
|
1054
1009
|
{
|
|
1055
|
-
|
|
1010
|
+
unmounted: false,
|
|
1056
1011
|
hover: false,
|
|
1057
1012
|
press: false,
|
|
1058
1013
|
pressIn: false,
|
|
1059
1014
|
focus: false,
|
|
1060
1015
|
resolveVariablesAs: 'both',
|
|
1061
1016
|
noClassNames,
|
|
1062
|
-
keepVariantsAsProps: true,
|
|
1063
1017
|
},
|
|
1064
1018
|
undefined,
|
|
1065
1019
|
undefined,
|
|
@@ -1071,7 +1025,9 @@ export function createComponent<
|
|
|
1071
1025
|
// otherwise it confuses variant functions getting className props
|
|
1072
1026
|
const [defaults, defaultsClassnames] = mergeProps(
|
|
1073
1027
|
component.defaultProps as any,
|
|
1074
|
-
|
|
1028
|
+
isWeb
|
|
1029
|
+
? { ...initialSplitStyles.pseudos, ...initialSplitStyles.viewProps }
|
|
1030
|
+
: initialSplitStyles.viewProps,
|
|
1075
1031
|
true
|
|
1076
1032
|
// conf.inverseShorthands
|
|
1077
1033
|
)
|
|
@@ -1102,6 +1058,17 @@ export function createComponent<
|
|
|
1102
1058
|
|
|
1103
1059
|
if (Object.keys(defaults).length) {
|
|
1104
1060
|
tamaguiDefaultProps = defaults
|
|
1061
|
+
|
|
1062
|
+
// temp bugfix, splitStyles isn't returning variables when resolveVariablesAs == 'both'
|
|
1063
|
+
if (!isWeb) {
|
|
1064
|
+
Object.keys(pseudoDescriptors).forEach((k) => {
|
|
1065
|
+
if (ourProps[k]) {
|
|
1066
|
+
// @ts-ignore
|
|
1067
|
+
initialSplitStyles.pseudos[k] = null
|
|
1068
|
+
tamaguiDefaultProps[k] = ourProps[k]
|
|
1069
|
+
}
|
|
1070
|
+
})
|
|
1071
|
+
}
|
|
1105
1072
|
}
|
|
1106
1073
|
|
|
1107
1074
|
// add debug logs
|
|
@@ -1244,7 +1211,6 @@ export function spacedChildren({
|
|
|
1244
1211
|
for (const [index, child] of childrenList.entries()) {
|
|
1245
1212
|
const isEmpty =
|
|
1246
1213
|
child === null || child === undefined || (Array.isArray(child) && child.length === 0)
|
|
1247
|
-
|
|
1248
1214
|
// push them all, but wrap some in Fragment
|
|
1249
1215
|
if (isEmpty || !child || (child['key'] && !isZStack)) {
|
|
1250
1216
|
final.push(child)
|
|
@@ -1255,14 +1221,9 @@ export function spacedChildren({
|
|
|
1255
1221
|
}
|
|
1256
1222
|
|
|
1257
1223
|
// first child unspaced avoid insert space
|
|
1258
|
-
if (isUnspaced(child) && index === 0)
|
|
1259
|
-
continue
|
|
1260
|
-
}
|
|
1261
|
-
|
|
1224
|
+
if (isUnspaced(child) && index === 0) continue
|
|
1262
1225
|
// no spacing on ZStack
|
|
1263
|
-
if (isZStack)
|
|
1264
|
-
continue
|
|
1265
|
-
}
|
|
1226
|
+
if (isZStack) continue
|
|
1266
1227
|
|
|
1267
1228
|
const next = childrenList[index + 1]
|
|
1268
1229
|
|
|
@@ -1330,23 +1291,6 @@ function isUnspaced(child: React.ReactNode) {
|
|
|
1330
1291
|
return child?.['type']?.['isVisuallyHidden'] || child?.['type']?.['isUnspaced']
|
|
1331
1292
|
}
|
|
1332
1293
|
|
|
1333
|
-
function addPseudoToStyles(
|
|
1334
|
-
styles: any[],
|
|
1335
|
-
initialPseudos: SplitStyleResult['pseudos'],
|
|
1336
|
-
pseudos: any,
|
|
1337
|
-
name: string,
|
|
1338
|
-
force = false
|
|
1339
|
-
) {
|
|
1340
|
-
// on web use pseudo object { hoverStyle } to keep specificity with concatClassName
|
|
1341
|
-
const pseudoStyle = pseudos[name]
|
|
1342
|
-
const shouldNestObject = isWeb && name !== 'enterStyle' && name !== 'exitStyle'
|
|
1343
|
-
const defaultPseudoStyle = initialPseudos[name]
|
|
1344
|
-
const style = defaultPseudoStyle ? { ...defaultPseudoStyle, ...pseudoStyle } : pseudoStyle
|
|
1345
|
-
if (style) {
|
|
1346
|
-
styles.push(shouldNestObject && !force ? { [name]: style } : style)
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
|
|
1350
1294
|
const DefaultProps = new Map()
|
|
1351
1295
|
|
|
1352
1296
|
function mergeConfigDefaultProps(
|
|
@@ -1385,68 +1329,17 @@ function mergeConfigDefaultProps(
|
|
|
1385
1329
|
return props
|
|
1386
1330
|
}
|
|
1387
1331
|
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
bottom: 0,
|
|
1393
|
-
opacity: 1,
|
|
1394
|
-
translateX: 0,
|
|
1395
|
-
translateY: 0,
|
|
1396
|
-
skew: 0,
|
|
1397
|
-
skewX: 0,
|
|
1398
|
-
skewY: 0,
|
|
1399
|
-
scale: 1,
|
|
1400
|
-
rotate: '0deg',
|
|
1401
|
-
rotateY: '0deg',
|
|
1402
|
-
rotateX: '0deg',
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
|
-
function ensureBaseHasDefaults(base: ViewStyle, ...pseudos: (ViewStyle | null | undefined)[]) {
|
|
1406
|
-
for (const pseudo of pseudos) {
|
|
1407
|
-
if (!pseudo) continue
|
|
1408
|
-
for (const key in pseudo) {
|
|
1409
|
-
const val = pseudo[key]
|
|
1410
|
-
// can we just use merge() here?
|
|
1411
|
-
if (key === 'transform') {
|
|
1412
|
-
if (typeof val === 'string') {
|
|
1413
|
-
continue
|
|
1414
|
-
}
|
|
1415
|
-
for (const t of val) {
|
|
1416
|
-
const tkey = Object.keys(t)[0]
|
|
1417
|
-
const defaultVal = defaults[tkey]
|
|
1418
|
-
const tDefaultVal = { [tkey]: defaultVal } as any
|
|
1419
|
-
if (!base.transform) {
|
|
1420
|
-
base.transform = [tDefaultVal]
|
|
1421
|
-
} else {
|
|
1422
|
-
if (!base.transform.find((x) => x[tkey])) {
|
|
1423
|
-
base.transform.push(tDefaultVal)
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
} else {
|
|
1428
|
-
if (!(key in base)) {
|
|
1429
|
-
base[key] = defaults[key]
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1332
|
+
// TODO need to delete existing prop because of weirdness in how we do this
|
|
1333
|
+
// real solution is to handle all this in getSplitStyle and have animation drviers
|
|
1334
|
+
// return a useAnimationIsExiting() so we can pass that as part of state: { exiting: true }
|
|
1335
|
+
// then we can remove this function and the getStyle() altogether
|
|
1436
1336
|
function merge(base: ViewStyle, next: ViewStyle) {
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
const { transform, ...rest } = next
|
|
1442
|
-
Object.assign(base, rest)
|
|
1443
|
-
for (const t of transform) {
|
|
1444
|
-
const key = Object.keys(t)[0]
|
|
1445
|
-
const existing = base.transform.find((x) => key in x)
|
|
1446
|
-
if (existing) {
|
|
1447
|
-
existing[key] = t[key]
|
|
1337
|
+
for (const key in next) {
|
|
1338
|
+
const val = next[key]
|
|
1339
|
+
if (key in stylePropsTransform) {
|
|
1340
|
+
mergeTransform(base, key, val, true)
|
|
1448
1341
|
} else {
|
|
1449
|
-
base
|
|
1342
|
+
base[key] = val
|
|
1450
1343
|
}
|
|
1451
1344
|
}
|
|
1452
1345
|
}
|