@tamagui/core 1.0.1-rc.9 → 1.0.2
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/config.js +3 -5
- package/dist/cjs/config.js.map +2 -2
- package/dist/cjs/constants/constants.js.map +2 -2
- package/dist/cjs/createComponent.js +25 -27
- package/dist/cjs/createComponent.js.map +2 -2
- package/dist/cjs/createFont.js.map +2 -2
- package/dist/cjs/createTamagui.js +2 -1
- package/dist/cjs/createTamagui.js.map +2 -2
- package/dist/cjs/helpers/ThemeManager.js +7 -17
- package/dist/cjs/helpers/ThemeManager.js.map +2 -2
- package/dist/cjs/helpers/Unwrap.js +29 -0
- package/dist/cjs/helpers/Unwrap.js.map +7 -0
- package/dist/cjs/helpers/cache.js +9 -13
- package/dist/cjs/helpers/cache.js.map +2 -2
- package/dist/cjs/helpers/expandStyle.js +29 -41
- package/dist/cjs/helpers/expandStyle.js.map +2 -2
- package/dist/cjs/helpers/getBoundingClientRect.js +3 -6
- package/dist/cjs/helpers/getBoundingClientRect.js.map +2 -2
- package/dist/cjs/helpers/getSplitStyles.js +8 -14
- package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
- package/dist/cjs/helpers/getStylesAtomic.js +12 -18
- package/dist/cjs/helpers/getStylesAtomic.js.map +2 -2
- package/dist/cjs/helpers/insertStyleRule.js +0 -2
- package/dist/cjs/helpers/insertStyleRule.js.map +2 -2
- package/dist/cjs/helpers/isTamaguiComponent.js +2 -7
- package/dist/cjs/helpers/isTamaguiComponent.js.map +2 -2
- package/dist/cjs/helpers/mergeProps.js +1 -1
- package/dist/cjs/helpers/mergeProps.js.map +2 -2
- package/dist/cjs/hooks/getThemeUnwrapped.js +1 -4
- package/dist/cjs/hooks/getThemeUnwrapped.js.map +2 -2
- package/dist/cjs/hooks/useTheme.js +45 -50
- package/dist/cjs/hooks/useTheme.js.map +3 -3
- package/dist/cjs/styled.js.map +2 -2
- package/dist/cjs/views/FontLanguage.js.map +2 -2
- package/dist/cjs/views/TamaguiProvider.js +3 -0
- package/dist/cjs/views/TamaguiProvider.js.map +2 -2
- package/dist/cjs/views/Text.js +0 -5
- package/dist/cjs/views/Text.js.map +2 -2
- package/dist/cjs/views/Theme.js +15 -21
- package/dist/cjs/views/Theme.js.map +3 -3
- package/dist/cjs/views/ThemeProvider.js +5 -6
- package/dist/cjs/views/ThemeProvider.js.map +2 -2
- package/dist/esm/config.js +3 -5
- package/dist/esm/config.js.map +2 -2
- package/dist/esm/constants/constants.js.map +2 -2
- package/dist/esm/createComponent.js +26 -28
- package/dist/esm/createComponent.js.map +2 -2
- package/dist/esm/createFont.js.map +2 -2
- package/dist/esm/createTamagui.js +2 -1
- package/dist/esm/createTamagui.js.map +2 -2
- package/dist/esm/helpers/ThemeManager.js +7 -17
- package/dist/esm/helpers/ThemeManager.js.map +2 -2
- package/dist/esm/helpers/Unwrap.js +5 -0
- package/dist/esm/helpers/Unwrap.js.map +7 -0
- package/dist/esm/helpers/cache.js +9 -12
- package/dist/esm/helpers/cache.js.map +2 -2
- package/dist/esm/helpers/expandStyle.js +26 -38
- package/dist/esm/helpers/expandStyle.js.map +2 -2
- package/dist/esm/helpers/getBoundingClientRect.js +3 -6
- package/dist/esm/helpers/getBoundingClientRect.js.map +2 -2
- package/dist/esm/helpers/getSplitStyles.js +8 -14
- package/dist/esm/helpers/getSplitStyles.js.map +2 -2
- package/dist/esm/helpers/getStylesAtomic.js +12 -18
- package/dist/esm/helpers/getStylesAtomic.js.map +2 -2
- package/dist/esm/helpers/insertStyleRule.js +0 -2
- package/dist/esm/helpers/insertStyleRule.js.map +2 -2
- package/dist/esm/helpers/isTamaguiComponent.js +2 -7
- package/dist/esm/helpers/isTamaguiComponent.js.map +2 -2
- package/dist/esm/helpers/mergeProps.js +1 -1
- package/dist/esm/helpers/mergeProps.js.map +2 -2
- package/dist/esm/hooks/getThemeUnwrapped.js +1 -4
- package/dist/esm/hooks/getThemeUnwrapped.js.map +2 -2
- package/dist/esm/hooks/useTheme.js +45 -50
- package/dist/esm/hooks/useTheme.js.map +3 -3
- package/dist/esm/styled.js.map +2 -2
- package/dist/esm/views/FontLanguage.js.map +2 -2
- package/dist/esm/views/TamaguiProvider.js +3 -0
- package/dist/esm/views/TamaguiProvider.js.map +2 -2
- package/dist/esm/views/Text.js +0 -5
- package/dist/esm/views/Text.js.map +2 -2
- package/dist/esm/views/Theme.js +14 -14
- package/dist/esm/views/Theme.js.map +2 -2
- package/dist/esm/views/ThemeProvider.js +5 -6
- package/dist/esm/views/ThemeProvider.js.map +2 -2
- package/package.json +13 -13
- package/src/config.ts +4 -6
- package/src/constants/constants.ts +0 -2
- package/src/createComponent.tsx +47 -43
- package/src/createFont.ts +0 -2
- package/src/createTamagui.ts +2 -1
- package/src/helpers/ThemeManager.tsx +10 -21
- package/src/helpers/cache.ts +8 -13
- package/src/helpers/expandStyle.ts +27 -41
- package/src/helpers/getBoundingClientRect.tsx +2 -5
- package/src/helpers/getSplitStyles.tsx +23 -14
- package/src/helpers/getStylesAtomic.ts +16 -24
- package/src/helpers/insertStyleRule.tsx +0 -2
- package/src/helpers/isTamaguiComponent.tsx +2 -6
- package/src/helpers/mergeProps.ts +1 -1
- package/src/hooks/getThemeUnwrapped.tsx +1 -3
- package/src/hooks/useTheme.tsx +67 -48
- package/src/styled.tsx +1 -1
- package/src/views/FontLanguage.tsx +0 -2
- package/src/views/TamaguiProvider.tsx +6 -0
- package/src/views/Text.tsx +0 -6
- package/src/views/Theme.tsx +15 -22
- package/src/views/ThemeProvider.tsx +8 -8
- package/types/createComponent.d.ts +1 -1
- package/types/helpers/ThemeManager.d.ts +1 -1
- package/types/helpers/cache.d.ts +4 -6
- package/types/hooks/useTheme.d.ts +1 -1
- package/types/views/Theme.d.ts +1 -1
package/dist/esm/views/Theme.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { isWeb } from "@tamagui/constants";
|
|
3
|
-
import
|
|
3
|
+
import { Children, cloneElement } from "react";
|
|
4
4
|
import { variableToString } from "../createVariable";
|
|
5
5
|
import { ThemeManagerContext } from "../helpers/ThemeManagerContext";
|
|
6
6
|
import { useChangeThemeEffect } from "../hooks/useTheme";
|
|
@@ -9,16 +9,16 @@ function Theme(props) {
|
|
|
9
9
|
return props.children;
|
|
10
10
|
}
|
|
11
11
|
const isRoot = !!props["_isRoot"];
|
|
12
|
-
const { name, theme, themeManager,
|
|
13
|
-
props,
|
|
14
|
-
isRoot
|
|
15
|
-
);
|
|
12
|
+
const { name, theme, themeManager, className } = useChangeThemeEffect(props, isRoot);
|
|
16
13
|
const disableThemeClass = props.disableThemeClass;
|
|
17
14
|
const missingTheme = !(name && theme);
|
|
18
|
-
let contents =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
let contents = useThemeManagerContext(
|
|
16
|
+
props["data-themeable"] ? Children.map(
|
|
17
|
+
props.children,
|
|
18
|
+
(child) => cloneElement(child, { ["data-themeable"]: true })
|
|
19
|
+
) : props.children,
|
|
20
|
+
themeManager
|
|
21
|
+
);
|
|
22
22
|
if (process.env.NODE_ENV === "development" && missingTheme) {
|
|
23
23
|
name && !theme && console.warn(`No theme found by name ${name}`);
|
|
24
24
|
return props.children;
|
|
@@ -38,10 +38,10 @@ function Theme(props) {
|
|
|
38
38
|
}
|
|
39
39
|
return contents;
|
|
40
40
|
}
|
|
41
|
-
function
|
|
42
|
-
|
|
41
|
+
function useThemeManagerContext(children, themeManager, shouldReset) {
|
|
42
|
+
const value = themeManager;
|
|
43
|
+
if (!value)
|
|
43
44
|
return children;
|
|
44
|
-
}
|
|
45
45
|
let next = children;
|
|
46
46
|
if (shouldReset && themeManager) {
|
|
47
47
|
next = /* @__PURE__ */ jsx(Theme, {
|
|
@@ -50,12 +50,12 @@ function wrapThemeManagerContext(children, themeManager, shouldReset) {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
return /* @__PURE__ */ jsx(ThemeManagerContext.Provider, {
|
|
53
|
-
value
|
|
53
|
+
value,
|
|
54
54
|
children: next
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
export {
|
|
58
58
|
Theme,
|
|
59
|
-
|
|
59
|
+
useThemeManagerContext
|
|
60
60
|
};
|
|
61
61
|
//# sourceMappingURL=Theme.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/views/Theme.tsx"],
|
|
4
|
-
"sourcesContent": ["import { isWeb } from '@tamagui/constants'\nimport React, { useMemo } from 'react'\n\nimport { variableToString } from '../createVariable'\nimport { ThemeManager } from '../helpers/ThemeManager'\nimport { ThemeManagerContext } from '../helpers/ThemeManagerContext'\nimport { useChangeThemeEffect } from '../hooks/useTheme'\nimport { ThemeProps } from '../types'\n\nexport function Theme(props: ThemeProps) {\n // @ts-expect-error only for internal views\n if (props.disable) {\n return props.children\n }\n\n const isRoot = !!props['_isRoot']\n const { name, theme, themeManager,
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { isWeb } from '@tamagui/constants'\nimport React, { Children, cloneElement, useMemo } from 'react'\n\nimport { variableToString } from '../createVariable'\nimport { ThemeManager } from '../helpers/ThemeManager'\nimport { ThemeManagerContext } from '../helpers/ThemeManagerContext'\nimport { useChangeThemeEffect } from '../hooks/useTheme'\nimport { ThemeProps } from '../types'\n\nexport function Theme(props: ThemeProps) {\n // @ts-expect-error only for internal views\n if (props.disable) {\n return props.children\n }\n\n const isRoot = !!props['_isRoot']\n const { name, theme, themeManager, className } = useChangeThemeEffect(props, isRoot)\n const disableThemeClass = props.disableThemeClass\n const missingTheme = !(name && theme)\n\n // memo here, changing theme without re-rendering all children is a critical optimization\n // may require some effort of end user to memoize but without this memo they'd have no option\n let contents = useThemeManagerContext(\n props['data-themeable']\n ? Children.map(props.children, (child) =>\n cloneElement(child, { ['data-themeable']: true })\n )\n : props.children,\n themeManager\n )\n\n if (process.env.NODE_ENV === 'development' && missingTheme) {\n // eslint-disable-next-line no-console\n name && !theme && console.warn(`No theme found by name ${name}`)\n return props.children\n }\n\n if (disableThemeClass || missingTheme) {\n return contents\n }\n\n if (isWeb) {\n const cn = [props.className, className, '_dsp_contents'].filter(Boolean).join(' ')\n contents = (\n <span\n className={cn}\n style={{\n // in order to provide currentColor, set color by default\n color: variableToString(theme?.color),\n }}\n >\n {contents}\n </span>\n )\n }\n\n return contents\n}\n\nexport function useThemeManagerContext(\n children: any,\n themeManager?: ThemeManager | null,\n shouldReset?: boolean\n) {\n // disabled super memoize it - listener first strategy\n const value = themeManager // useMemo(() => themeManager, [!!themeManager])\n // be sure to memoize themeManager to avoid reparenting\n if (!value) return children\n // be sure to memoize shouldReset to avoid reparenting\n let next = children\n // TODO likely not necessary if we do reset logic now in useTheme?\n // reset to parent theme\n if (shouldReset && themeManager) {\n next = <Theme name={themeManager.state.parentName}>{next}</Theme>\n }\n return <ThemeManagerContext.Provider value={value}>{next}</ThemeManagerContext.Provider>\n}\n"],
|
|
5
|
+
"mappings": "AA4CM;AA5CN,SAAS,aAAa;AACtB,SAAgB,UAAU,oBAA6B;AAEvD,SAAS,wBAAwB;AAEjC,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AAG9B,SAAS,MAAM,OAAmB;AAEvC,MAAI,MAAM,SAAS;AACjB,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,SAAS,CAAC,CAAC,MAAM;AACvB,QAAM,EAAE,MAAM,OAAO,cAAc,UAAU,IAAI,qBAAqB,OAAO,MAAM;AACnF,QAAM,oBAAoB,MAAM;AAChC,QAAM,eAAe,EAAE,QAAQ;AAI/B,MAAI,WAAW;AAAA,IACb,MAAM,oBACF,SAAS;AAAA,MAAI,MAAM;AAAA,MAAU,CAAC,UAC5B,aAAa,OAAO,EAAE,CAAC,mBAAmB,KAAK,CAAC;AAAA,IAClD,IACA,MAAM;AAAA,IACV;AAAA,EACF;AAEA,MAAI,QAAQ,IAAI,aAAa,iBAAiB,cAAc;AAE1D,YAAQ,CAAC,SAAS,QAAQ,KAAK,0BAA0B,MAAM;AAC/D,WAAO,MAAM;AAAA,EACf;AAEA,MAAI,qBAAqB,cAAc;AACrC,WAAO;AAAA,EACT;AAEA,MAAI,OAAO;AACT,UAAM,KAAK,CAAC,MAAM,WAAW,WAAW,eAAe,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AACjF,eACE,oBAAC;AAAA,MACC,WAAW;AAAA,MACX,OAAO;AAAA,QAEL,OAAO,iBAAiB,+BAAO,KAAK;AAAA,MACtC;AAAA,MAEC;AAAA,KACH;AAAA,EAEJ;AAEA,SAAO;AACT;AAEO,SAAS,uBACd,UACA,cACA,aACA;AAEA,QAAM,QAAQ;AAEd,MAAI,CAAC;AAAO,WAAO;AAEnB,MAAI,OAAO;AAGX,MAAI,eAAe,cAAc;AAC/B,WAAO,oBAAC;AAAA,MAAM,MAAM,aAAa,MAAM;AAAA,MAAa;AAAA,KAAK;AAAA,EAC3D;AACA,SAAO,oBAAC,oBAAoB,UAApB;AAAA,IAA6B;AAAA,IAAe;AAAA,GAAK;AAC3D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -17,13 +17,12 @@ const ThemeProvider = (props) => {
|
|
|
17
17
|
};
|
|
18
18
|
}, [props.defaultTheme, props.disableRootThemeClass, props.themeClassNameOnRoot]);
|
|
19
19
|
}
|
|
20
|
-
const value = useMemo(() => {
|
|
21
|
-
return {
|
|
22
|
-
defaultTheme: props.defaultTheme
|
|
23
|
-
};
|
|
24
|
-
}, []);
|
|
25
20
|
return /* @__PURE__ */ jsx(ThemeProviderRootContext.Provider, {
|
|
26
|
-
value
|
|
21
|
+
value: useMemo(() => {
|
|
22
|
+
return {
|
|
23
|
+
defaultTheme: props.defaultTheme
|
|
24
|
+
};
|
|
25
|
+
}, []),
|
|
27
26
|
children: /* @__PURE__ */ jsx(Theme, {
|
|
28
27
|
className: props.className,
|
|
29
28
|
name: props.defaultTheme,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/views/ThemeProvider.tsx"],
|
|
4
|
-
"sourcesContent": ["import { isClient } from '@tamagui/constants'\nimport { createContext, useLayoutEffect, useMemo } from 'react'\n\nimport { THEME_CLASSNAME_PREFIX } from '../constants/constants'\nimport { Theme } from './Theme'\n\nexport type ThemeProviderProps = {\n className?: string\n defaultTheme: string\n disableRootThemeClass?: boolean\n themeClassNameOnRoot?: boolean\n children?: any\n reset?: boolean\n}\n\nexport const ThemeProviderRootContext = createContext<Pick<\n ThemeProviderProps,\n 'defaultTheme'\n> | null>(null)\n\nexport const ThemeProvider = (props: ThemeProviderProps) => {\n // ensure theme is attached to root body node as well to work with modals by default\n if (isClient) {\n useLayoutEffect(() => {\n if (props.disableRootThemeClass) return\n const cn = `${THEME_CLASSNAME_PREFIX}${props.defaultTheme}`\n const target = props.themeClassNameOnRoot ? document.documentElement : document.body\n target.classList.add(cn)\n return () => {\n target.classList.remove(cn)\n }\n }, [props.defaultTheme, props.disableRootThemeClass, props.themeClassNameOnRoot])\n }\n\n
|
|
5
|
-
"mappings": "AA2CM;AA3CN,SAAS,gBAAgB;AACzB,SAAS,eAAe,iBAAiB,eAAe;AAExD,SAAS,8BAA8B;AACvC,SAAS,aAAa;AAWf,MAAM,2BAA2B,cAG9B,IAAI;AAEP,MAAM,gBAAgB,CAAC,UAA8B;AAE1D,MAAI,UAAU;AACZ,oBAAgB,MAAM;AACpB,UAAI,MAAM;AAAuB;AACjC,YAAM,KAAK,GAAG,yBAAyB,MAAM;AAC7C,YAAM,SAAS,MAAM,uBAAuB,SAAS,kBAAkB,SAAS;AAChF,aAAO,UAAU,IAAI,EAAE;AACvB,aAAO,MAAM;AACX,eAAO,UAAU,OAAO,EAAE;AAAA,MAC5B;AAAA,IACF,GAAG,CAAC,MAAM,cAAc,MAAM,uBAAuB,MAAM,oBAAoB,CAAC;AAAA,EAClF;AAEA,
|
|
4
|
+
"sourcesContent": ["import { isClient } from '@tamagui/constants'\nimport { createContext, useLayoutEffect, useMemo } from 'react'\n\nimport { THEME_CLASSNAME_PREFIX } from '../constants/constants'\nimport { Theme } from './Theme'\n\nexport type ThemeProviderProps = {\n className?: string\n defaultTheme: string\n disableRootThemeClass?: boolean\n themeClassNameOnRoot?: boolean\n children?: any\n reset?: boolean\n}\n\nexport const ThemeProviderRootContext = createContext<Pick<\n ThemeProviderProps,\n 'defaultTheme'\n> | null>(null)\n\nexport const ThemeProvider = (props: ThemeProviderProps) => {\n // ensure theme is attached to root body node as well to work with modals by default\n if (isClient) {\n useLayoutEffect(() => {\n if (props.disableRootThemeClass) return\n const cn = `${THEME_CLASSNAME_PREFIX}${props.defaultTheme}`\n const target = props.themeClassNameOnRoot ? document.documentElement : document.body\n target.classList.add(cn)\n return () => {\n target.classList.remove(cn)\n }\n }, [props.defaultTheme, props.disableRootThemeClass, props.themeClassNameOnRoot])\n }\n\n return (\n <ThemeProviderRootContext.Provider\n value={useMemo(() => {\n return {\n defaultTheme: props.defaultTheme,\n }\n // NOTE DON'T CHANGE THIS ITS ONLY USED BY useThemeName for SSR safety for now...\n }, [])}\n >\n <Theme\n className={props.className}\n name={props.defaultTheme}\n disableThemeClass={props.disableRootThemeClass}\n // @ts-expect-error\n _isRoot\n >\n {props.children}\n </Theme>\n </ThemeProviderRootContext.Provider>\n )\n}\n"],
|
|
5
|
+
"mappings": "AA2CM;AA3CN,SAAS,gBAAgB;AACzB,SAAS,eAAe,iBAAiB,eAAe;AAExD,SAAS,8BAA8B;AACvC,SAAS,aAAa;AAWf,MAAM,2BAA2B,cAG9B,IAAI;AAEP,MAAM,gBAAgB,CAAC,UAA8B;AAE1D,MAAI,UAAU;AACZ,oBAAgB,MAAM;AACpB,UAAI,MAAM;AAAuB;AACjC,YAAM,KAAK,GAAG,yBAAyB,MAAM;AAC7C,YAAM,SAAS,MAAM,uBAAuB,SAAS,kBAAkB,SAAS;AAChF,aAAO,UAAU,IAAI,EAAE;AACvB,aAAO,MAAM;AACX,eAAO,UAAU,OAAO,EAAE;AAAA,MAC5B;AAAA,IACF,GAAG,CAAC,MAAM,cAAc,MAAM,uBAAuB,MAAM,oBAAoB,CAAC;AAAA,EAClF;AAEA,SACE,oBAAC,yBAAyB,UAAzB;AAAA,IACC,OAAO,QAAQ,MAAM;AACnB,aAAO;AAAA,QACL,cAAc,MAAM;AAAA,MACtB;AAAA,IAEF,GAAG,CAAC,CAAC;AAAA,IAEL,8BAAC;AAAA,MACC,WAAW,MAAM;AAAA,MACjB,MAAM,MAAM;AAAA,MACZ,mBAAmB,MAAM;AAAA,MAEzB,SAAO;AAAA,MAEN,gBAAM;AAAA,KACT;AAAA,GACF;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"main": "dist/cjs",
|
|
6
6
|
"module": "dist/esm",
|
|
@@ -28,28 +28,28 @@
|
|
|
28
28
|
"reset.css"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@tamagui/compose-refs": "^1.0.
|
|
32
|
-
"@tamagui/constants": "^1.0.
|
|
33
|
-
"@tamagui/helpers": "^1.0.
|
|
34
|
-
"@tamagui/react-native-use-pressable": "^1.0.
|
|
35
|
-
"@tamagui/react-native-use-responder-events": "^1.0.
|
|
36
|
-
"@tamagui/use-did-finish-ssr": "^1.0.
|
|
37
|
-
"@tamagui/use-event": "^1.0.
|
|
38
|
-
"@tamagui/use-force-update": "^1.0.
|
|
31
|
+
"@tamagui/compose-refs": "^1.0.2",
|
|
32
|
+
"@tamagui/constants": "^1.0.2",
|
|
33
|
+
"@tamagui/helpers": "^1.0.2",
|
|
34
|
+
"@tamagui/react-native-use-pressable": "^1.0.2",
|
|
35
|
+
"@tamagui/react-native-use-responder-events": "^1.0.2",
|
|
36
|
+
"@tamagui/use-did-finish-ssr": "^1.0.2",
|
|
37
|
+
"@tamagui/use-event": "^1.0.2",
|
|
38
|
+
"@tamagui/use-force-update": "^1.0.2",
|
|
39
39
|
"normalize-css-color": "^1.0.2"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"react": "
|
|
43
|
-
"react-dom": "
|
|
42
|
+
"react": "*",
|
|
43
|
+
"react-dom": "*"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@tamagui/build": "^1.0.
|
|
46
|
+
"@tamagui/build": "^1.0.2",
|
|
47
47
|
"@testing-library/react": "^13.4.0",
|
|
48
48
|
"csstype": "^3.0.10",
|
|
49
49
|
"react": "^18.2.0",
|
|
50
50
|
"react-dom": "^18.2.0",
|
|
51
51
|
"typescript": "^4.7.4",
|
|
52
|
-
"vitest": "^0.
|
|
52
|
+
"vitest": "^0.26.2"
|
|
53
53
|
},
|
|
54
54
|
"exports": {
|
|
55
55
|
"./package.json": "./package.json",
|
package/src/config.ts
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import { ConfigListener, TamaguiInternalConfig,
|
|
1
|
+
import { ConfigListener, TamaguiInternalConfig, Tokens } from './types'
|
|
2
2
|
|
|
3
3
|
let conf: TamaguiInternalConfig | null
|
|
4
4
|
|
|
5
5
|
export const setConfig = (next: TamaguiInternalConfig) => {
|
|
6
6
|
conf = next
|
|
7
|
-
|
|
8
|
-
configListeners.forEach((cb) => cb(next))
|
|
9
|
-
}
|
|
7
|
+
configListeners.forEach((cb) => cb(next))
|
|
10
8
|
}
|
|
11
9
|
|
|
12
10
|
export const setConfigFont = (name: string, font: any, fontParsed: any) => {
|
|
13
11
|
if (process.env.NODE_ENV === 'development') {
|
|
14
12
|
if (!conf) throw new Error(`Haven't called createTamagui yet`)
|
|
15
13
|
}
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
conf!.fonts[name] = font
|
|
15
|
+
conf!.fontsParsed[`$${name}`] = fontParsed
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
export const getConfig = () => {
|
package/src/createComponent.tsx
CHANGED
|
@@ -20,7 +20,6 @@ import React, {
|
|
|
20
20
|
createElement,
|
|
21
21
|
forwardRef,
|
|
22
22
|
memo,
|
|
23
|
-
startTransition,
|
|
24
23
|
useCallback,
|
|
25
24
|
useContext,
|
|
26
25
|
useEffect,
|
|
@@ -61,7 +60,7 @@ import {
|
|
|
61
60
|
} from './types'
|
|
62
61
|
import { usePressability } from './vendor/Pressability'
|
|
63
62
|
import { Slot, mergeEvent } from './views/Slot'
|
|
64
|
-
import {
|
|
63
|
+
import { useThemeManagerContext } from './views/Theme'
|
|
65
64
|
|
|
66
65
|
// let t
|
|
67
66
|
// import { timer } from '@tamagui/timer'
|
|
@@ -558,7 +557,8 @@ export function createComponent<
|
|
|
558
557
|
|
|
559
558
|
if (process.env.NODE_ENV === 'development' && !isText && isWeb) {
|
|
560
559
|
Children.toArray(props.children).forEach((item) => {
|
|
561
|
-
|
|
560
|
+
// allow newlines because why not its annoying with mdx
|
|
561
|
+
if (typeof item === 'string' && item !== '\n') {
|
|
562
562
|
// eslint-disable-next-line no-console
|
|
563
563
|
console.error(
|
|
564
564
|
`Unexpected text node: ${item}. A text node cannot be a child of a <View>.`
|
|
@@ -585,10 +585,17 @@ export function createComponent<
|
|
|
585
585
|
const shouldSetMounted = needsMount && state.unmounted
|
|
586
586
|
useEffect(() => {
|
|
587
587
|
if (!shouldSetMounted) return
|
|
588
|
+
if (state.unmounted === true && needsMount) {
|
|
589
|
+
setStateShallow({
|
|
590
|
+
unmounted: false,
|
|
591
|
+
})
|
|
592
|
+
return
|
|
593
|
+
}
|
|
594
|
+
|
|
588
595
|
setStateShallow({
|
|
589
596
|
unmounted: false,
|
|
590
597
|
})
|
|
591
|
-
}, [shouldSetMounted])
|
|
598
|
+
}, [shouldSetMounted, state.unmounted])
|
|
592
599
|
|
|
593
600
|
let styles: Record<string, any>[]
|
|
594
601
|
|
|
@@ -618,11 +625,15 @@ export function createComponent<
|
|
|
618
625
|
const fontFamilyClassName = fontFamily ? `font_${fontFamily}` : ''
|
|
619
626
|
|
|
620
627
|
const classList = [
|
|
628
|
+
hasEnterStyle && ((state.unmounted && needsMount) || !isClient)
|
|
629
|
+
? 't_will-mount'
|
|
630
|
+
: '',
|
|
621
631
|
componentName ? componentClassName : '',
|
|
622
632
|
fontFamilyClassName,
|
|
623
633
|
themeIsNew ? theme.className : '',
|
|
624
634
|
classNames ? Object.values(classNames).join(' ') : '',
|
|
625
635
|
]
|
|
636
|
+
|
|
626
637
|
const className = classList.join(' ')
|
|
627
638
|
|
|
628
639
|
if (process.env.TAMAGUI_TARGET === 'web') {
|
|
@@ -811,23 +822,20 @@ export function createComponent<
|
|
|
811
822
|
stateRef.current.themeShouldReset = true
|
|
812
823
|
}
|
|
813
824
|
|
|
814
|
-
const
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
stateRef.current.hasProvidedThemeManager ? themeManager : undefined,
|
|
827
|
-
stateRef.current.themeShouldReset
|
|
828
|
-
)
|
|
825
|
+
const innerContent = useThemeManagerContext(
|
|
826
|
+
spacedChildren({
|
|
827
|
+
separator,
|
|
828
|
+
children,
|
|
829
|
+
space,
|
|
830
|
+
direction: props.spaceDirection || 'both',
|
|
831
|
+
isZStack,
|
|
832
|
+
}),
|
|
833
|
+
// only set context if changed theme
|
|
834
|
+
stateRef.current.hasProvidedThemeManager ? themeManager : undefined,
|
|
835
|
+
stateRef.current.themeShouldReset
|
|
836
|
+
)
|
|
829
837
|
|
|
830
|
-
let content:
|
|
838
|
+
let content = !children || asChild ? children : innerContent
|
|
831
839
|
|
|
832
840
|
if (asChild) {
|
|
833
841
|
elementType = Slot
|
|
@@ -865,7 +873,7 @@ export function createComponent<
|
|
|
865
873
|
}
|
|
866
874
|
}
|
|
867
875
|
|
|
868
|
-
content = createElement(elementType, viewProps,
|
|
876
|
+
content = createElement(elementType, viewProps, content)
|
|
869
877
|
|
|
870
878
|
if (process.env.TAMAGUI_TARGET === 'web') {
|
|
871
879
|
if (events || isAnimatedReactNativeWeb) {
|
|
@@ -921,7 +929,6 @@ export function createComponent<
|
|
|
921
929
|
styles,
|
|
922
930
|
pseudos,
|
|
923
931
|
content,
|
|
924
|
-
childEls,
|
|
925
932
|
shouldAvoidClasses,
|
|
926
933
|
avoidClasses: avoidClassesWhileAnimating,
|
|
927
934
|
animation: props.animation,
|
|
@@ -1162,41 +1169,38 @@ export type SpacedChildrenProps = {
|
|
|
1162
1169
|
separator?: React.ReactNode
|
|
1163
1170
|
}
|
|
1164
1171
|
|
|
1165
|
-
export function spacedChildren({
|
|
1166
|
-
isZStack,
|
|
1167
|
-
children,
|
|
1168
|
-
space,
|
|
1169
|
-
direction,
|
|
1170
|
-
spaceFlex,
|
|
1171
|
-
separator,
|
|
1172
|
-
}: SpacedChildrenProps) {
|
|
1172
|
+
export function spacedChildren(props: SpacedChildrenProps) {
|
|
1173
|
+
const { isZStack, children, space, direction, spaceFlex, separator } = props
|
|
1173
1174
|
const hasSpace = !!(space || spaceFlex)
|
|
1174
1175
|
const hasSeparator = !(separator === undefined || separator === null)
|
|
1175
1176
|
if (!(hasSpace || hasSeparator || isZStack)) {
|
|
1176
1177
|
return children
|
|
1177
1178
|
}
|
|
1179
|
+
|
|
1178
1180
|
const childrenList = Children.toArray(children)
|
|
1181
|
+
|
|
1179
1182
|
const len = childrenList.length
|
|
1180
|
-
if (len <= 1 && !isZStack) {
|
|
1181
|
-
if (len === 1) {
|
|
1182
|
-
// forward space! only when one component doesn't make sense to forward space to all children
|
|
1183
|
-
const [onlyChild] = childrenList
|
|
1184
|
-
if (React.isValidElement(onlyChild) && onlyChild.type?.['shouldForwardSpace']) {
|
|
1185
|
-
return React.cloneElement(onlyChild, {
|
|
1186
|
-
space,
|
|
1187
|
-
spaceFlex,
|
|
1188
|
-
separator,
|
|
1189
|
-
} as any)
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1183
|
+
if (len <= 1 && !isZStack && !childrenList[0]?.['type']?.['shouldForwardSpace']) {
|
|
1192
1184
|
return childrenList
|
|
1193
1185
|
}
|
|
1186
|
+
|
|
1194
1187
|
const final: React.ReactNode[] = []
|
|
1195
|
-
for (
|
|
1188
|
+
for (let [index, child] of childrenList.entries()) {
|
|
1196
1189
|
const isEmpty =
|
|
1197
1190
|
child === null ||
|
|
1198
1191
|
child === undefined ||
|
|
1199
1192
|
(Array.isArray(child) && child.length === 0)
|
|
1193
|
+
|
|
1194
|
+
// forward space
|
|
1195
|
+
if (!isEmpty && React.isValidElement(child) && child.type?.['shouldForwardSpace']) {
|
|
1196
|
+
child = React.cloneElement(child, {
|
|
1197
|
+
space,
|
|
1198
|
+
spaceFlex,
|
|
1199
|
+
separator,
|
|
1200
|
+
key: child.key,
|
|
1201
|
+
} as any)
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1200
1204
|
// push them all, but wrap some in Fragment
|
|
1201
1205
|
if (isEmpty || !child || (child['key'] && !isZStack)) {
|
|
1202
1206
|
final.push(child)
|
package/src/createFont.ts
CHANGED
|
@@ -34,7 +34,6 @@ const processSection = <T>(
|
|
|
34
34
|
|
|
35
35
|
export const createFont = <A extends GenericFont>(font: A): A => {
|
|
36
36
|
const sizeKeys = Object.keys(font.size)
|
|
37
|
-
|
|
38
37
|
const processedFont = Object.fromEntries(
|
|
39
38
|
Object.entries(font).map(([key, section]) => {
|
|
40
39
|
return [
|
|
@@ -47,6 +46,5 @@ export const createFont = <A extends GenericFont>(font: A): A => {
|
|
|
47
46
|
]
|
|
48
47
|
})
|
|
49
48
|
)
|
|
50
|
-
|
|
51
49
|
return Object.freeze(processedFont) as A
|
|
52
50
|
}
|
package/src/createTamagui.ts
CHANGED
|
@@ -212,7 +212,8 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
|
|
|
212
212
|
tokensParsed,
|
|
213
213
|
parsed: true,
|
|
214
214
|
getCSS: (separator = '\n') => {
|
|
215
|
-
return `.
|
|
215
|
+
return `.t_unmounted .t_will-mount {opacity:0;visibility:hidden;}
|
|
216
|
+
.is_Text .is_Text {display:inline-flex;}
|
|
216
217
|
._dsp_contents {display:contents;}
|
|
217
218
|
${themeConfig.cssRuleSets.join(separator)}
|
|
218
219
|
${themeConfig.themeRuleSets.join(separator)}
|
|
@@ -39,9 +39,10 @@ export class ThemeManager {
|
|
|
39
39
|
this.updateState(props, false)
|
|
40
40
|
return
|
|
41
41
|
}
|
|
42
|
-
if (!parentManager)
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if (!parentManager) throw `❌`
|
|
43
|
+
// copy over listeners
|
|
44
|
+
this.themeListeners = parentManager.themeListeners
|
|
45
|
+
|
|
45
46
|
// no change no props
|
|
46
47
|
if (hasNoThemeUpdatingProps(props)) {
|
|
47
48
|
return parentManager
|
|
@@ -101,9 +102,9 @@ export class ThemeManager {
|
|
|
101
102
|
state: ThemeManagerState | null = this.state
|
|
102
103
|
) {
|
|
103
104
|
if (!nextState?.theme || nextState.theme === state?.theme) {
|
|
104
|
-
return
|
|
105
|
+
return false
|
|
105
106
|
}
|
|
106
|
-
return
|
|
107
|
+
return true
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
getState(props = this.props, parentManager = this.parentManager) {
|
|
@@ -136,6 +137,7 @@ export class ThemeManager {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
notify() {
|
|
140
|
+
console.log('notify', this.themeListeners.size, this.themeListeners)
|
|
139
141
|
this.themeListeners.forEach((cb) => cb(this.state.name, this))
|
|
140
142
|
}
|
|
141
143
|
|
|
@@ -200,22 +202,9 @@ function getState(
|
|
|
200
202
|
? max // component name only don't search upwards
|
|
201
203
|
: 0
|
|
202
204
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
console.groupCollapsed('ThemeManager.getState()', props, {
|
|
207
|
-
parentName,
|
|
208
|
-
parentBaseTheme,
|
|
209
|
-
base,
|
|
210
|
-
min,
|
|
211
|
-
max,
|
|
212
|
-
isParentAComponentTheme,
|
|
213
|
-
}),
|
|
214
|
-
// eslint-disable-next-line no-console
|
|
215
|
-
console.trace(),
|
|
216
|
-
// eslint-disable-next-line no-console
|
|
217
|
-
console.groupEnd(),
|
|
218
|
-
]
|
|
205
|
+
// prettier-ignore
|
|
206
|
+
// eslint-disable-next-line no-console
|
|
207
|
+
if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') [ console.groupCollapsed('ThemeManager.getState()', props, { parentName, parentBaseTheme, base, min, max, isParentAComponentTheme }), console.trace(), console.groupEnd() ]
|
|
219
208
|
|
|
220
209
|
for (let i = max; i >= min; i--) {
|
|
221
210
|
let prefix = base.slice(0, i).join(THEME_NAME_SEPARATOR)
|
package/src/helpers/cache.ts
CHANGED
|
@@ -2,17 +2,12 @@ type Value = Object | Array<any> | string | number
|
|
|
2
2
|
|
|
3
3
|
export type Style = { [key: string]: Value }
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
get(key: string, valStr: string)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.v[key] ??= {}
|
|
14
|
-
this.v[key][valStr] = object
|
|
15
|
-
}
|
|
5
|
+
const v: Record<string, any> = {}
|
|
6
|
+
|
|
7
|
+
export const cache = {
|
|
8
|
+
get: (key: string, valStr: string) => v[key]?.[valStr],
|
|
9
|
+
set: (key: string, valStr: string, object: any) => {
|
|
10
|
+
v[key] ??= {}
|
|
11
|
+
v[key][valStr] = object
|
|
12
|
+
},
|
|
16
13
|
}
|
|
17
|
-
|
|
18
|
-
export const cache = new Cache()
|
|
@@ -30,25 +30,16 @@ export function expandStyle(key: string, value: any) {
|
|
|
30
30
|
|
|
31
31
|
// web only
|
|
32
32
|
switch (key) {
|
|
33
|
-
case 'aspectRatio': {
|
|
34
|
-
return [[key, value.toString()]]
|
|
35
|
-
}
|
|
36
|
-
|
|
37
33
|
case 'textAlignVertical': {
|
|
38
34
|
return [['verticalAlign', value === 'center' ? 'middle' : value]]
|
|
39
35
|
}
|
|
40
|
-
|
|
41
|
-
case 'textDecorationLine': {
|
|
42
|
-
return [['textDecorationLine', value]]
|
|
43
|
-
}
|
|
44
|
-
|
|
45
36
|
case 'writingDirection': {
|
|
46
37
|
return [['direction', value]]
|
|
47
38
|
}
|
|
48
39
|
}
|
|
49
40
|
}
|
|
50
41
|
|
|
51
|
-
const longKey =
|
|
42
|
+
const longKey = EXPANSIONS[key]
|
|
52
43
|
if (longKey) {
|
|
53
44
|
return longKey.map((key) => {
|
|
54
45
|
return [key, value]
|
|
@@ -56,41 +47,36 @@ export function expandStyle(key: string, value: any) {
|
|
|
56
47
|
}
|
|
57
48
|
}
|
|
58
49
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
],
|
|
50
|
+
const all = ['Top', 'Right', 'Bottom', 'Left']
|
|
51
|
+
const horiz = ['Right', 'Left']
|
|
52
|
+
const vert = ['Top', 'Bottom']
|
|
53
|
+
const xy = ['X', 'Y']
|
|
54
|
+
|
|
55
|
+
const EXPANSIONS: Record<string, string[]> = {
|
|
56
|
+
borderColor: ['TopColor', 'RightColor', 'BottomColor', 'LeftColor'],
|
|
66
57
|
borderRadius: [
|
|
67
|
-
'
|
|
68
|
-
'
|
|
69
|
-
'
|
|
70
|
-
'
|
|
71
|
-
],
|
|
72
|
-
borderWidth: [
|
|
73
|
-
'borderTopWidth',
|
|
74
|
-
'borderRightWidth',
|
|
75
|
-
'borderBottomWidth',
|
|
76
|
-
'borderLeftWidth',
|
|
58
|
+
'TopLeftRadius',
|
|
59
|
+
'TopRightRadius',
|
|
60
|
+
'BottomRightRadius',
|
|
61
|
+
'BottomLeftRadius',
|
|
77
62
|
],
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
63
|
+
borderWidth: ['TopWidth', 'RightWidth', 'BottomWidth', 'LeftWidth'],
|
|
64
|
+
margin: all,
|
|
65
|
+
marginHorizontal: horiz,
|
|
66
|
+
marginVertical: vert,
|
|
67
|
+
overscrollBehavior: xy,
|
|
68
|
+
padding: all,
|
|
69
|
+
paddingHorizontal: horiz,
|
|
70
|
+
paddingVertical: vert,
|
|
85
71
|
...(isWeb && {
|
|
86
72
|
// react-native only supports borderStyle
|
|
87
|
-
borderStyle: [
|
|
88
|
-
'borderTopStyle',
|
|
89
|
-
'borderRightStyle',
|
|
90
|
-
'borderBottomStyle',
|
|
91
|
-
'borderLeftStyle',
|
|
92
|
-
],
|
|
73
|
+
borderStyle: ['TopStyle', 'RightStyle', 'BottomStyle', 'LeftStyle'],
|
|
93
74
|
// react-native doesn't support X / Y
|
|
94
|
-
overflow:
|
|
75
|
+
overflow: xy,
|
|
95
76
|
}),
|
|
96
77
|
}
|
|
78
|
+
|
|
79
|
+
for (const parent in EXPANSIONS) {
|
|
80
|
+
const prefix = parent.slice(0, /[A-Z]/.exec(parent)?.index ?? parent.length)
|
|
81
|
+
EXPANSIONS[parent] = EXPANSIONS[parent].map((k) => `${prefix}${k}`)
|
|
82
|
+
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
export const getBoundingClientRect = (node: HTMLElement | null): void | DOMRect => {
|
|
2
|
-
if (!node) return
|
|
3
|
-
|
|
4
|
-
if (node.getBoundingClientRect) {
|
|
5
|
-
return node.getBoundingClientRect()
|
|
6
|
-
}
|
|
2
|
+
if (!node || node.nodeType !== 1) return
|
|
3
|
+
return node.getBoundingClientRect?.()
|
|
7
4
|
}
|
|
@@ -429,20 +429,12 @@ export const getSplitStyles: StyleSplitter = (
|
|
|
429
429
|
}
|
|
430
430
|
break
|
|
431
431
|
}
|
|
432
|
-
case '
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
}
|
|
432
|
+
case 'accessibilityLabelledBy':
|
|
433
|
+
case 'accessibilityFlowTo':
|
|
434
|
+
case 'accessibilityControls':
|
|
436
435
|
case 'accessibilityDescribedBy': {
|
|
437
|
-
viewProps[
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
case 'accessibilityFlowTo': {
|
|
441
|
-
viewProps['aria-flowto'] = processIDRefList(valInit)
|
|
442
|
-
break
|
|
443
|
-
}
|
|
444
|
-
case 'accessibilityLabelledBy': {
|
|
445
|
-
viewProps['aria-labelledby'] = processIDRefList(valInit)
|
|
436
|
+
viewProps[`aria-${keyInit.replace('accessibility', '').toLowerCase()}`] =
|
|
437
|
+
processIDRefList(valInit)
|
|
446
438
|
break
|
|
447
439
|
}
|
|
448
440
|
case 'accessibilityKeyShortcuts': {
|
|
@@ -646,7 +638,24 @@ export const getSplitStyles: StyleSplitter = (
|
|
|
646
638
|
}
|
|
647
639
|
}
|
|
648
640
|
} else {
|
|
649
|
-
|
|
641
|
+
let isDisabled = !state[descriptor.stateKey || descriptor.name]
|
|
642
|
+
|
|
643
|
+
// we never animate in on server side just show the full thing
|
|
644
|
+
// on client side we use CSS to hide the fully in SSR items, then
|
|
645
|
+
// un-hide and replay with original animation.
|
|
646
|
+
if (isWeb && !isClient && isEnter) {
|
|
647
|
+
isDisabled = false
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// console.log(
|
|
651
|
+
// 'isDisabled',
|
|
652
|
+
// state,
|
|
653
|
+
// descriptor.stateKey,
|
|
654
|
+
// state[descriptor.stateKey || descriptor.name],
|
|
655
|
+
// isDisabled,
|
|
656
|
+
// descriptor
|
|
657
|
+
// )
|
|
658
|
+
|
|
650
659
|
if (!isDisabled) {
|
|
651
660
|
usedKeys[key] ||= 1
|
|
652
661
|
}
|