@tamagui/core 1.0.0-alpha.4 → 1.0.0-alpha.8

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 (225) hide show
  1. package/dist/cjs/constants/constants.js +50 -0
  2. package/{_ → dist/cjs}/constants/constants.js.map +2 -2
  3. package/dist/cjs/constants/platform.js +43 -0
  4. package/dist/cjs/constants/platform.js.map +7 -0
  5. package/dist/cjs/constants/pseudos.js +25 -0
  6. package/{_ → dist/cjs}/constants/pseudos.js.map +2 -2
  7. package/{_ → dist/cjs}/constants/rnw.js +9 -3
  8. package/{_ → dist/cjs}/constants/rnw.js.map +2 -2
  9. package/dist/cjs/createComponent.js +531 -0
  10. package/dist/cjs/createComponent.js.map +7 -0
  11. package/dist/cjs/createFont.js +50 -0
  12. package/dist/cjs/createFont.js.map +7 -0
  13. package/{_ → dist/cjs}/createShorthands.js +9 -3
  14. package/{_ → dist/cjs}/createShorthands.js.map +2 -2
  15. package/dist/cjs/createTamagui.js +206 -0
  16. package/dist/cjs/createTamagui.js.map +7 -0
  17. package/dist/cjs/createTheme.js +42 -0
  18. package/{_ → dist/cjs}/createTheme.js.map +2 -2
  19. package/dist/cjs/createTokens.js +55 -0
  20. package/dist/cjs/createTokens.js.map +7 -0
  21. package/dist/cjs/createVariable.js +47 -0
  22. package/dist/cjs/createVariable.js.map +7 -0
  23. package/dist/cjs/helpers/addStylesUsingClassname.js +79 -0
  24. package/dist/cjs/helpers/addStylesUsingClassname.js.map +7 -0
  25. package/dist/cjs/helpers/createMediaStyle.js +56 -0
  26. package/{_ → dist/cjs}/helpers/createMediaStyle.js.map +2 -2
  27. package/dist/cjs/helpers/createPropMapper.js +190 -0
  28. package/dist/cjs/helpers/createPropMapper.js.map +7 -0
  29. package/dist/cjs/helpers/createTamaguiProvider.js +74 -0
  30. package/dist/cjs/helpers/createTamaguiProvider.js.map +7 -0
  31. package/dist/cjs/helpers/extendStaticConfig.js +82 -0
  32. package/dist/cjs/helpers/extendStaticConfig.js.map +7 -0
  33. package/dist/cjs/helpers/fixNativeShadow.js +14 -0
  34. package/dist/cjs/helpers/fixNativeShadow.js.map +7 -0
  35. package/{_ → dist/cjs}/helpers/fixNativeShadow.native.js +9 -3
  36. package/{_ → dist/cjs}/helpers/fixNativeShadow.native.js.map +2 -2
  37. package/dist/cjs/helpers/getSplitStyles.js +180 -0
  38. package/dist/cjs/helpers/getSplitStyles.js.map +7 -0
  39. package/dist/cjs/helpers/getStylesAtomic.js +117 -0
  40. package/{_ → dist/cjs}/helpers/getStylesAtomic.js.map +2 -2
  41. package/dist/cjs/helpers/getStylesAtomic.native.js +16 -0
  42. package/dist/cjs/helpers/getStylesAtomic.native.js.map +7 -0
  43. package/dist/cjs/helpers/insertStyleRule.js +46 -0
  44. package/{_ → dist/cjs}/helpers/insertStyleRule.js.map +2 -2
  45. package/dist/cjs/helpers/isObj.js +13 -0
  46. package/dist/cjs/helpers/isObj.js.map +7 -0
  47. package/dist/cjs/helpers/isTamaguiElement.js +33 -0
  48. package/dist/cjs/helpers/isTamaguiElement.js.map +7 -0
  49. package/dist/cjs/helpers/matchMedia.js +24 -0
  50. package/dist/cjs/helpers/matchMedia.js.map +7 -0
  51. package/dist/cjs/helpers/matchMedia.native.js +31 -0
  52. package/dist/cjs/helpers/matchMedia.native.js.map +7 -0
  53. package/dist/cjs/helpers/themeable.js +78 -0
  54. package/{_ → dist/cjs}/helpers/themeable.js.map +2 -2
  55. package/dist/cjs/helpers/validate.js +82 -0
  56. package/dist/cjs/helpers/validate.js.map +7 -0
  57. package/dist/cjs/hooks/useConstant.js +37 -0
  58. package/{_ → dist/cjs}/hooks/useConstant.js.map +2 -2
  59. package/dist/cjs/hooks/useFeatures.js +100 -0
  60. package/dist/cjs/hooks/useFeatures.js.map +7 -0
  61. package/{_ → dist/cjs}/hooks/useMedia.js +59 -28
  62. package/dist/cjs/hooks/useMedia.js.map +7 -0
  63. package/dist/cjs/hooks/usePressable.js +50 -0
  64. package/{_ → dist/cjs}/hooks/usePressable.js.map +2 -2
  65. package/dist/cjs/hooks/useTheme.js +111 -0
  66. package/dist/cjs/hooks/useTheme.js.map +7 -0
  67. package/dist/cjs/index.js +55 -0
  68. package/dist/cjs/index.js.map +7 -0
  69. package/dist/cjs/static/postProcessStyles.js +40 -0
  70. package/{_ → dist/cjs}/static/postProcessStyles.js.map +2 -2
  71. package/dist/cjs/static.js +34 -0
  72. package/dist/cjs/static.js.map +7 -0
  73. package/dist/cjs/styled.js +72 -0
  74. package/dist/cjs/styled.js.map +7 -0
  75. package/dist/cjs/types.js +4 -0
  76. package/dist/cjs/types.js.map +7 -0
  77. package/dist/cjs/views/Animated.js +129 -0
  78. package/{_ → dist/cjs}/views/Animated.js.map +2 -2
  79. package/dist/cjs/views/Stack.js +51 -0
  80. package/{_ → dist/cjs}/views/Stack.js.map +2 -2
  81. package/dist/cjs/views/Text.js +93 -0
  82. package/{_ → dist/cjs}/views/Text.js.map +2 -2
  83. package/dist/cjs/views/TextAncestorContext.js +41 -0
  84. package/{_ → dist/cjs}/views/TextAncestorContext.js.map +2 -2
  85. package/dist/cjs/views/Theme.js +88 -0
  86. package/dist/cjs/views/Theme.js.map +7 -0
  87. package/dist/cjs/views/ThemeContext.js +29 -0
  88. package/{_ → dist/cjs}/views/ThemeContext.js.map +2 -2
  89. package/dist/cjs/views/ThemeInverse.js +48 -0
  90. package/{_ → dist/cjs}/views/ThemeInverse.js.map +3 -3
  91. package/dist/cjs/views/ThemeManagerContext.js +84 -0
  92. package/dist/cjs/views/ThemeManagerContext.js.map +7 -0
  93. package/dist/cjs/views/ThemeProvider.js +67 -0
  94. package/{_ → dist/cjs}/views/ThemeProvider.js.map +2 -2
  95. package/dist/createComponent.js +49 -31
  96. package/dist/createComponent.js.map +2 -2
  97. package/dist/createFont.js +4 -0
  98. package/dist/createFont.js.map +2 -2
  99. package/dist/createTamagui.js +11 -2
  100. package/dist/createTamagui.js.map +2 -2
  101. package/dist/createTokens.js +4 -0
  102. package/dist/createTokens.js.map +2 -2
  103. package/dist/createVariable.js +3 -0
  104. package/dist/createVariable.js.map +2 -2
  105. package/dist/helpers/createPropMapper.js +2 -2
  106. package/dist/helpers/createPropMapper.js.map +1 -1
  107. package/dist/helpers/getSplitStyles.js +13 -23
  108. package/dist/helpers/getSplitStyles.js.map +2 -2
  109. package/dist/helpers/isComponent.js +10 -0
  110. package/dist/helpers/isComponent.js.map +7 -0
  111. package/dist/helpers/isTamaguiComponent.js +10 -0
  112. package/dist/helpers/isTamaguiComponent.js.map +7 -0
  113. package/dist/helpers/isTamaguiElement.js +10 -0
  114. package/dist/helpers/isTamaguiElement.js.map +7 -0
  115. package/dist/helpers/matchMedia.js +3 -0
  116. package/dist/helpers/matchMedia.js.map +2 -2
  117. package/dist/helpers/matchMedia.native.js +1 -0
  118. package/dist/helpers/matchMedia.native.js.map +2 -2
  119. package/dist/helpers/validate.js +60 -0
  120. package/dist/helpers/validate.js.map +7 -0
  121. package/dist/helpers/validateConfig.js +46 -0
  122. package/dist/helpers/validateConfig.js.map +7 -0
  123. package/dist/helpers/validateTokens.js +29 -0
  124. package/dist/helpers/validateTokens.js.map +7 -0
  125. package/dist/hooks/useFeatures.js +39 -51
  126. package/dist/hooks/useFeatures.js.map +2 -2
  127. package/dist/hooks/useMedia.js.map +1 -1
  128. package/dist/hooks/useTheme.js +5 -9
  129. package/dist/hooks/useTheme.js.map +2 -2
  130. package/dist/index.cjs +234 -135
  131. package/dist/index.cjs.map +3 -3
  132. package/dist/index.js +1 -1
  133. package/dist/index.js.map +2 -2
  134. package/dist/views/Theme.js +16 -7
  135. package/dist/views/Theme.js.map +2 -2
  136. package/dist/views/ThemeInverse.js +0 -1
  137. package/dist/views/ThemeInverse.js.map +2 -2
  138. package/dist/views/ThemeManagerContext.js +11 -5
  139. package/dist/views/ThemeManagerContext.js.map +2 -2
  140. package/package.json +18 -12
  141. package/src/createComponent.tsx +55 -40
  142. package/src/createFont.ts +5 -0
  143. package/src/createTamagui.ts +11 -1
  144. package/src/createTokens.ts +6 -1
  145. package/src/createVariable.ts +4 -0
  146. package/src/helpers/createPropMapper.ts +2 -2
  147. package/src/helpers/getSplitStyles.tsx +16 -26
  148. package/src/helpers/isTamaguiElement.tsx +5 -0
  149. package/src/helpers/matchMedia.native.ts +3 -0
  150. package/src/helpers/matchMedia.ts +9 -1
  151. package/src/helpers/validate.ts +59 -0
  152. package/src/hooks/useFeatures.tsx +54 -53
  153. package/src/hooks/useMedia.tsx +1 -1
  154. package/src/hooks/useTheme.tsx +7 -8
  155. package/src/index.ts +1 -1
  156. package/src/types.tsx +3 -2
  157. package/src/views/Theme.tsx +26 -9
  158. package/src/views/ThemeInverse.tsx +0 -1
  159. package/src/views/ThemeManagerContext.tsx +18 -6
  160. package/types.d.ts +10 -8
  161. package/.ultra.cache.json +0 -1
  162. package/_/constants/constants.js +0 -14
  163. package/_/constants/platform.js +0 -20
  164. package/_/constants/platform.js.map +0 -7
  165. package/_/constants/pseudos.js +0 -18
  166. package/_/createComponent.js +0 -427
  167. package/_/createComponent.js.map +0 -7
  168. package/_/createTamagui.js +0 -122
  169. package/_/createTamagui.js.map +0 -7
  170. package/_/createTheme.js +0 -20
  171. package/_/createTokens.js +0 -29
  172. package/_/createTokens.js.map +0 -7
  173. package/_/createVariable.js +0 -22
  174. package/_/createVariable.js.map +0 -7
  175. package/_/helpers/addStylesUsingClassname.js +0 -32
  176. package/_/helpers/addStylesUsingClassname.js.map +0 -7
  177. package/_/helpers/createMediaStyle.js +0 -34
  178. package/_/helpers/createTamaguiProvider.js +0 -42
  179. package/_/helpers/createTamaguiProvider.js.map +0 -7
  180. package/_/helpers/extendStaticConfig.js +0 -176
  181. package/_/helpers/extendStaticConfig.js.map +0 -7
  182. package/_/helpers/fixNativeShadow.js +0 -8
  183. package/_/helpers/fixNativeShadow.js.map +0 -7
  184. package/_/helpers/getSplitStyles.js +0 -160
  185. package/_/helpers/getSplitStyles.js.map +0 -7
  186. package/_/helpers/getStylesAtomic.js +0 -84
  187. package/_/helpers/getStylesAtomic.native.js +0 -10
  188. package/_/helpers/getStylesAtomic.native.js.map +0 -7
  189. package/_/helpers/insertStyleRule.js +0 -24
  190. package/_/helpers/matchMedia.js +0 -15
  191. package/_/helpers/matchMedia.js.map +0 -7
  192. package/_/helpers/matchMedia.native.js +0 -8
  193. package/_/helpers/matchMedia.native.js.map +0 -7
  194. package/_/helpers/themeable.js +0 -26
  195. package/_/hooks/useConstant.js +0 -15
  196. package/_/hooks/useFeatures.js +0 -75
  197. package/_/hooks/useFeatures.js.map +0 -7
  198. package/_/hooks/useForceUpdate.js +0 -28
  199. package/_/hooks/useForceUpdate.js.map +0 -7
  200. package/_/hooks/useMedia.js.map +0 -7
  201. package/_/hooks/usePressable.js +0 -14
  202. package/_/hooks/useTheme.js +0 -94
  203. package/_/hooks/useTheme.js.map +0 -7
  204. package/_/index.js +0 -30
  205. package/_/index.js.map +0 -7
  206. package/_/static/postProcessStyles.js +0 -18
  207. package/_/static.js +0 -12
  208. package/_/static.js.map +0 -7
  209. package/_/styled.js +0 -21
  210. package/_/styled.js.map +0 -7
  211. package/_/types.js +0 -1
  212. package/_/types.js.map +0 -7
  213. package/_/views/Animated.js +0 -79
  214. package/_/views/Stack.js +0 -12
  215. package/_/views/Text.js +0 -60
  216. package/_/views/TextAncestorContext.js +0 -19
  217. package/_/views/Theme.js +0 -57
  218. package/_/views/Theme.js.map +0 -7
  219. package/_/views/ThemeContext.js +0 -6
  220. package/_/views/ThemeInverse.js +0 -27
  221. package/_/views/ThemeManagerContext.js +0 -56
  222. package/_/views/ThemeManagerContext.js.map +0 -7
  223. package/_/views/ThemeProvider.js +0 -45
  224. package/src/views/SafeAreaProvider.tsx +0 -33
  225. package/tsconfig.json +0 -8
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ export * from "./helpers/isObj";
15
15
  export * from "./helpers/getStylesAtomic";
16
16
  export * from "./helpers/matchMedia";
17
17
  export * from "./helpers/themeable";
18
+ export * from "./helpers/isTamaguiElement";
18
19
  export * from "./hooks/useConstant";
19
20
  export * from "./hooks/useMedia";
20
21
  export * from "./hooks/useTheme";
@@ -25,7 +26,6 @@ export * from "./views/Theme";
25
26
  export * from "./views/ThemeInverse";
26
27
  export * from "./views/ThemeProvider";
27
28
  export * from "./views/TextAncestorContext";
28
- export * from "./views/SafeAreaProvider";
29
29
  export {
30
30
  createTokens
31
31
  };
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export * from './createComponent'\nexport * from './createShorthands'\nexport * from './createTheme'\nexport * from './createTamagui'\nexport * from './createFont'\nexport { createTokens } from './createTokens'\nexport * from './createVariable'\nexport * from './styled'\nexport * from './types'\n\nexport * from './constants/pseudos'\nexport * from './constants/constants'\nexport * from './constants/platform'\nexport * from './constants/rnw'\n\nexport * from './helpers/isObj'\nexport * from './helpers/getStylesAtomic'\nexport * from './helpers/matchMedia'\nexport * from './helpers/themeable'\n\nexport * from './hooks/useConstant'\nexport * from './hooks/useMedia'\nexport * from './hooks/useTheme'\n\nexport * from './views/Animated'\nexport * from './views/Stack'\nexport * from './views/Text'\nexport * from './views/Theme'\nexport * from './views/ThemeInverse'\nexport * from './views/ThemeProvider'\nexport * from './views/TextAncestorContext'\nexport * from './views/SafeAreaProvider'\n"],
5
- "mappings": "AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;",
4
+ "sourcesContent": ["export * from './createComponent'\nexport * from './createShorthands'\nexport * from './createTheme'\nexport * from './createTamagui'\nexport * from './createFont'\nexport { createTokens } from './createTokens'\nexport * from './createVariable'\nexport * from './styled'\nexport * from './types'\n\nexport * from './constants/pseudos'\nexport * from './constants/constants'\nexport * from './constants/platform'\nexport * from './constants/rnw'\n\nexport * from './helpers/isObj'\nexport * from './helpers/getStylesAtomic'\nexport * from './helpers/matchMedia'\nexport * from './helpers/themeable'\nexport * from './helpers/isTamaguiElement'\n\nexport * from './hooks/useConstant'\nexport * from './hooks/useMedia'\nexport * from './hooks/useTheme'\n\nexport * from './views/Animated'\nexport * from './views/Stack'\nexport * from './views/Text'\nexport * from './views/Theme'\nexport * from './views/ThemeInverse'\nexport * from './views/ThemeProvider'\nexport * from './views/TextAncestorContext'\n"],
5
+ "mappings": "AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;",
6
6
  "names": []
7
7
  }
@@ -11,28 +11,37 @@ const Theme = /* @__PURE__ */ __name((props) => {
11
11
  const themes = useContext(ThemeContext);
12
12
  const [parentName, setParentName] = useState(parent.name || "light");
13
13
  if (!themes) {
14
- console.warn("no themes???", props);
14
+ console.warn("Error, no themes in context", props);
15
15
  return props.children;
16
16
  }
17
17
  const name = props.name;
18
- const theme = themes[name] || themes[`${name}-${parentName}`];
18
+ const nextNameParent = `${name}-${parentName}`;
19
+ const nextNameParentParent = `${name}-${parent.parentName}`;
20
+ const activeName = !name ? null : name in themes ? name : nextNameParent in themes ? nextNameParent : nextNameParentParent in themes ? nextNameParentParent : null;
21
+ const theme = activeName ? themes[activeName] : null;
19
22
  const themeManager = useConstant(() => {
23
+ if (!theme) {
24
+ return null;
25
+ }
20
26
  const manager = new ThemeManager();
21
27
  if (name) {
22
- manager.setActiveTheme(name, themes[name]);
28
+ manager.setActiveTheme({ name, theme: themes[name], parentName });
23
29
  }
24
30
  return manager;
25
31
  });
26
32
  useIsomorphicLayoutEffect(() => {
27
- themeManager.setActiveTheme(name, theme);
33
+ if (!themeManager) {
34
+ return;
35
+ }
36
+ themeManager.setActiveTheme({ name: activeName, theme, parentName });
28
37
  return parent.onChangeTheme((next) => {
29
38
  if (next) {
30
- themeManager.setActiveTheme(next, themes[next]);
39
+ themeManager.setActiveTheme({ name: next, theme: themes[next], parentName });
31
40
  setParentName(next);
32
41
  }
33
42
  });
34
- }, [themes, name]);
35
- if (!name) {
43
+ }, [themes, activeName, parentName]);
44
+ if (!name || !theme) {
36
45
  return props.children;
37
46
  }
38
47
  const contents = themeManager ? /* @__PURE__ */ React.createElement(ThemeManagerContext.Provider, {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/views/Theme.tsx"],
4
- "sourcesContent": ["import React, { useContext, useState } from 'react'\n\nimport { isWeb, useIsomorphicLayoutEffect } from '../constants/platform'\nimport { getThemeParentClassName } from '../createTamagui'\nimport { useConstant } from '../hooks/useConstant'\nimport { ThemeName, Themes } from '../types'\nimport { ThemeContext } from './ThemeContext'\nimport { ThemeManager, ThemeManagerContext } from './ThemeManagerContext'\n\nexport type ThemeProps = {\n disableThemeClass?: boolean\n name: ThemeName | null\n children?: any\n}\n\nexport const Theme = (props: ThemeProps) => {\n const parent = useContext(ThemeManagerContext)\n const themes = useContext(ThemeContext)\n const [parentName, setParentName] = useState(parent.name || 'light')\n if (!themes) {\n console.warn('no themes???', props)\n return props.children\n }\n const name = props.name as string\n const theme = themes[name] || themes[`${name}-${parentName}`]\n const themeManager = useConstant<ThemeManager>(() => {\n const manager = new ThemeManager()\n if (name) {\n manager.setActiveTheme(name, themes[name])\n }\n return manager\n })\n\n useIsomorphicLayoutEffect(() => {\n themeManager.setActiveTheme(name, theme)\n return parent.onChangeTheme((next) => {\n if (next) {\n themeManager.setActiveTheme(next, themes[next])\n setParentName(next)\n }\n })\n }, [themes, name])\n\n if (!name) {\n return props.children\n }\n\n const contents = themeManager ? (\n <ThemeManagerContext.Provider value={themeManager}>\n {props.children}\n </ThemeManagerContext.Provider>\n ) : (\n props.children\n )\n\n if (isWeb) {\n if (props.disableThemeClass) {\n return contents\n }\n const color = themes[name]?.['color']?.['variable']\n return (\n <div\n className={getThemeParentClassName(name)}\n // in order to provide currentColor, set color by default\n style={{ display: 'contents', color }}\n >\n {contents}\n </div>\n )\n }\n\n return contents\n}\n"],
5
- "mappings": ";;AAAA;AAEA;AACA;AACA;AAEA;AACA;AAQO,MAAM,QAAQ,wBAAC,UAAsB;AAC1C,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,WAAW;AAC1B,QAAM,CAAC,YAAY,iBAAiB,SAAS,OAAO,QAAQ;AAC5D,MAAI,CAAC,QAAQ;AACX,YAAQ,KAAK,gBAAgB;AAC7B,WAAO,MAAM;AAAA;AAEf,QAAM,OAAO,MAAM;AACnB,QAAM,QAAQ,OAAO,SAAS,OAAO,GAAG,QAAQ;AAChD,QAAM,eAAe,YAA0B,MAAM;AACnD,UAAM,UAAU,IAAI;AACpB,QAAI,MAAM;AACR,cAAQ,eAAe,MAAM,OAAO;AAAA;AAEtC,WAAO;AAAA;AAGT,4BAA0B,MAAM;AAC9B,iBAAa,eAAe,MAAM;AAClC,WAAO,OAAO,cAAc,CAAC,SAAS;AACpC,UAAI,MAAM;AACR,qBAAa,eAAe,MAAM,OAAO;AACzC,sBAAc;AAAA;AAAA;AAAA,KAGjB,CAAC,QAAQ;AAEZ,MAAI,CAAC,MAAM;AACT,WAAO,MAAM;AAAA;AAGf,QAAM,WAAW,eACf,oCAAC,oBAAoB,UAArB;AAAA,IAA8B,OAAO;AAAA,KAClC,MAAM,YAGT,MAAM;AAGR,MAAI,OAAO;AACT,QAAI,MAAM,mBAAmB;AAC3B,aAAO;AAAA;AAET,UAAM,QAAQ,OAAO,QAAQ,WAAW;AACxC,WACE,oCAAC,OAAD;AAAA,MACE,WAAW,wBAAwB;AAAA,MAEnC,OAAO,EAAE,SAAS,YAAY;AAAA,OAE7B;AAAA;AAKP,SAAO;AAAA,GAxDY;",
4
+ "sourcesContent": ["import React, { useContext, useState } from 'react'\n\nimport { isWeb, useIsomorphicLayoutEffect } from '../constants/platform'\nimport { getThemeParentClassName } from '../createTamagui'\nimport { useConstant } from '../hooks/useConstant'\nimport { ThemeName } from '../types'\nimport { ThemeContext } from './ThemeContext'\nimport { ThemeManager, ThemeManagerContext } from './ThemeManagerContext'\n\nexport type ThemeProps = {\n disableThemeClass?: boolean\n name: ThemeName | null\n children?: any\n}\n\nexport const Theme = (props: ThemeProps) => {\n const parent = useContext(ThemeManagerContext)\n const themes = useContext(ThemeContext)\n const [parentName, setParentName] = useState(parent.name || 'light')\n if (!themes) {\n console.warn('Error, no themes in context', props)\n return props.children\n }\n const name = props.name as string\n const nextNameParent = `${name}-${parentName}`\n const nextNameParentParent = `${name}-${parent.parentName}`\n const activeName = !name\n ? null\n : name in themes\n ? name\n : nextNameParent in themes\n ? nextNameParent\n : nextNameParentParent in themes\n ? nextNameParentParent\n : null\n const theme = activeName ? themes[activeName] : null\n const themeManager = useConstant<ThemeManager | null>(() => {\n if (!theme) {\n return null\n }\n const manager = new ThemeManager()\n if (name) {\n manager.setActiveTheme({ name, theme: themes[name], parentName })\n }\n return manager\n })\n\n useIsomorphicLayoutEffect(() => {\n if (!themeManager) {\n return\n }\n themeManager.setActiveTheme({ name: activeName, theme, parentName })\n return parent.onChangeTheme((next) => {\n if (next) {\n themeManager.setActiveTheme({ name: next, theme: themes[next], parentName })\n setParentName(next)\n }\n })\n }, [themes, activeName, parentName])\n\n if (!name || !theme) {\n return props.children\n }\n\n const contents = themeManager ? (\n <ThemeManagerContext.Provider value={themeManager}>\n {props.children}\n </ThemeManagerContext.Provider>\n ) : (\n props.children\n )\n\n if (isWeb) {\n if (props.disableThemeClass) {\n return contents\n }\n const color = themes[name]?.['color']?.['variable']\n return (\n <div\n className={getThemeParentClassName(name)}\n // in order to provide currentColor, set color by default\n style={{ display: 'contents', color }}\n >\n {contents}\n </div>\n )\n }\n\n return contents\n}\n"],
5
+ "mappings": ";;AAAA;AAEA;AACA;AACA;AAEA;AACA;AAQO,MAAM,QAAQ,wBAAC,UAAsB;AAC1C,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,WAAW;AAC1B,QAAM,CAAC,YAAY,iBAAiB,SAAS,OAAO,QAAQ;AAC5D,MAAI,CAAC,QAAQ;AACX,YAAQ,KAAK,+BAA+B;AAC5C,WAAO,MAAM;AAAA;AAEf,QAAM,OAAO,MAAM;AACnB,QAAM,iBAAiB,GAAG,QAAQ;AAClC,QAAM,uBAAuB,GAAG,QAAQ,OAAO;AAC/C,QAAM,aAAa,CAAC,OAChB,OACA,QAAQ,SACR,OACA,kBAAkB,SAClB,iBACA,wBAAwB,SACxB,uBACA;AACJ,QAAM,QAAQ,aAAa,OAAO,cAAc;AAChD,QAAM,eAAe,YAAiC,MAAM;AAC1D,QAAI,CAAC,OAAO;AACV,aAAO;AAAA;AAET,UAAM,UAAU,IAAI;AACpB,QAAI,MAAM;AACR,cAAQ,eAAe,EAAE,MAAM,OAAO,OAAO,OAAO;AAAA;AAEtD,WAAO;AAAA;AAGT,4BAA0B,MAAM;AAC9B,QAAI,CAAC,cAAc;AACjB;AAAA;AAEF,iBAAa,eAAe,EAAE,MAAM,YAAY,OAAO;AACvD,WAAO,OAAO,cAAc,CAAC,SAAS;AACpC,UAAI,MAAM;AACR,qBAAa,eAAe,EAAE,MAAM,MAAM,OAAO,OAAO,OAAO;AAC/D,sBAAc;AAAA;AAAA;AAAA,KAGjB,CAAC,QAAQ,YAAY;AAExB,MAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,WAAO,MAAM;AAAA;AAGf,QAAM,WAAW,eACf,oCAAC,oBAAoB,UAArB;AAAA,IAA8B,OAAO;AAAA,KAClC,MAAM,YAGT,MAAM;AAGR,MAAI,OAAO;AACT,QAAI,MAAM,mBAAmB;AAC3B,aAAO;AAAA;AAET,UAAM,QAAQ,OAAO,QAAQ,WAAW;AACxC,WACE,oCAAC,OAAD;AAAA,MACE,WAAW,wBAAwB;AAAA,MAEnC,OAAO,EAAE,SAAS,YAAY;AAAA,OAE7B;AAAA;AAKP,SAAO;AAAA,GAzEY;",
6
6
  "names": []
7
7
  }
@@ -15,7 +15,6 @@ const ThemeInverse = /* @__PURE__ */ __name((props) => {
15
15
  const themeName = useThemeName();
16
16
  const defaultTheme = useDefaultThemeName();
17
17
  const name = inversions[themeName] || inversions[defaultTheme] || null;
18
- console.log("todo fixme invert", { themeName, defaultTheme, next: name });
19
18
  return /* @__PURE__ */ React.createElement(Theme, {
20
19
  name
21
20
  }, props.children);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/views/ThemeInverse.tsx"],
4
- "sourcesContent": ["import React from 'react'\n\nimport { useDefaultThemeName, useThemeName } from '../hooks/useTheme'\nimport { Theme } from './Theme'\n\ntype StringRecord = { [key: string]: string }\n\nlet inversions: StringRecord = {\n light: 'dark',\n dark: 'light',\n}\n\nexport function setThemeInversions(next: StringRecord) {\n inversions = next\n}\n\nexport const ThemeInverse = (props: { children: any }) => {\n const themeName = useThemeName()\n const defaultTheme = useDefaultThemeName()\n const name = inversions[themeName] || inversions[defaultTheme] || null\n console.log('todo fixme invert', { themeName, defaultTheme, next: name })\n return <Theme name={name}>{props.children}</Theme>\n}\n"],
5
- "mappings": ";;AAAA;AAEA;AACA;AAIA,IAAI,aAA2B;AAAA,EAC7B,OAAO;AAAA,EACP,MAAM;AAAA;AAGD,4BAA4B,MAAoB;AACrD,eAAa;AAAA;AADC;AAIT,MAAM,eAAe,wBAAC,UAA6B;AACxD,QAAM,YAAY;AAClB,QAAM,eAAe;AACrB,QAAM,OAAO,WAAW,cAAc,WAAW,iBAAiB;AAClE,UAAQ,IAAI,qBAAqB,EAAE,WAAW,cAAc,MAAM;AAClE,SAAO,oCAAC,OAAD;AAAA,IAAO;AAAA,KAAa,MAAM;AAAA,GALP;",
4
+ "sourcesContent": ["import React from 'react'\n\nimport { useDefaultThemeName, useThemeName } from '../hooks/useTheme'\nimport { Theme } from './Theme'\n\ntype StringRecord = { [key: string]: string }\n\nlet inversions: StringRecord = {\n light: 'dark',\n dark: 'light',\n}\n\nexport function setThemeInversions(next: StringRecord) {\n inversions = next\n}\n\nexport const ThemeInverse = (props: { children: any }) => {\n const themeName = useThemeName()\n const defaultTheme = useDefaultThemeName()\n const name = inversions[themeName] || inversions[defaultTheme] || null\n return <Theme name={name}>{props.children}</Theme>\n}\n"],
5
+ "mappings": ";;AAAA;AAEA;AACA;AAIA,IAAI,aAA2B;AAAA,EAC7B,OAAO;AAAA,EACP,MAAM;AAAA;AAGD,4BAA4B,MAAoB;AACrD,eAAa;AAAA;AADC;AAIT,MAAM,eAAe,wBAAC,UAA6B;AACxD,QAAM,YAAY;AAClB,QAAM,eAAe;AACrB,QAAM,OAAO,WAAW,cAAc,WAAW,iBAAiB;AAClE,SAAO,oCAAC,OAAD;AAAA,IAAO;AAAA,KAAa,MAAM;AAAA,GAJP;",
6
6
  "names": []
7
7
  }
@@ -4,16 +4,22 @@ import { createContext } from "react";
4
4
  class ThemeManager {
5
5
  constructor() {
6
6
  this.name = "light";
7
+ this.parentName = null;
7
8
  this.keys = new Map();
8
9
  this.listeners = new Map();
9
- this.callbacks = new Set();
10
+ this.themeListeners = new Set();
10
11
  this.theme = null;
11
12
  }
12
- setActiveTheme(name, theme) {
13
+ setActiveTheme({
14
+ name,
15
+ theme,
16
+ parentName
17
+ }) {
13
18
  if (name === this.name)
14
19
  return;
15
20
  this.name = name;
16
21
  this.theme = theme;
22
+ this.parentName = parentName || null;
17
23
  this.update();
18
24
  }
19
25
  track(uuid, keys) {
@@ -30,12 +36,12 @@ class ThemeManager {
30
36
  this.listeners.get(uuid)?.();
31
37
  }
32
38
  }
33
- this.callbacks.forEach((cb) => cb(this.name));
39
+ this.themeListeners.forEach((cb) => cb(this.name, this));
34
40
  }
35
41
  onChangeTheme(cb) {
36
- this.callbacks.add(cb);
42
+ this.themeListeners.add(cb);
37
43
  return () => {
38
- this.callbacks.delete(cb);
44
+ this.themeListeners.delete(cb);
39
45
  };
40
46
  }
41
47
  onUpdate(uuid, cb) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/views/ThemeManagerContext.tsx"],
4
- "sourcesContent": ["import { createContext } from 'react'\n\nexport class ThemeManager {\n name: string | null = 'light'\n keys = new Map<any, Set<string>>()\n listeners = new Map<any, Function>()\n callbacks = new Set<Function>()\n theme = null\n\n setActiveTheme(name: string | null, theme?: any) {\n if (name === this.name) return\n this.name = name\n this.theme = theme\n this.update()\n }\n\n track(uuid: any, keys: Set<string>) {\n if (!this.name) return\n this.keys.set(uuid, keys)\n }\n\n update() {\n if (!this.name) {\n this.keys.clear()\n }\n for (const [uuid, keys] of this.keys.entries()) {\n if (keys.size) {\n this.listeners.get(uuid)?.()\n }\n }\n this.callbacks.forEach((cb) => cb(this.name))\n }\n\n onChangeTheme(cb: (name: string | null) => void) {\n this.callbacks.add(cb)\n return () => {\n this.callbacks.delete(cb)\n }\n }\n\n onUpdate(uuid: any, cb: Function) {\n this.listeners.set(uuid, cb)\n return () => {\n this.listeners.delete(uuid)\n this.keys.delete(uuid)\n }\n }\n}\n\nexport const ThemeManagerContext = createContext<ThemeManager>(new ThemeManager())\n"],
5
- "mappings": ";;AAAA;AAEO,mBAAmB;AAAA,EAAnB,cAFP;AAGE,gBAAsB;AACtB,gBAAO,IAAI;AACX,qBAAY,IAAI;AAChB,qBAAY,IAAI;AAChB,iBAAQ;AAAA;AAAA,EAER,eAAe,MAAqB,OAAa;AAC/C,QAAI,SAAS,KAAK;AAAM;AACxB,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK;AAAA;AAAA,EAGP,MAAM,MAAW,MAAmB;AAClC,QAAI,CAAC,KAAK;AAAM;AAChB,SAAK,KAAK,IAAI,MAAM;AAAA;AAAA,EAGtB,SAAS;AACP,QAAI,CAAC,KAAK,MAAM;AACd,WAAK,KAAK;AAAA;AAEZ,eAAW,CAAC,MAAM,SAAS,KAAK,KAAK,WAAW;AAC9C,UAAI,KAAK,MAAM;AACb,aAAK,UAAU,IAAI;AAAA;AAAA;AAGvB,SAAK,UAAU,QAAQ,CAAC,OAAO,GAAG,KAAK;AAAA;AAAA,EAGzC,cAAc,IAAmC;AAC/C,SAAK,UAAU,IAAI;AACnB,WAAO,MAAM;AACX,WAAK,UAAU,OAAO;AAAA;AAAA;AAAA,EAI1B,SAAS,MAAW,IAAc;AAChC,SAAK,UAAU,IAAI,MAAM;AACzB,WAAO,MAAM;AACX,WAAK,UAAU,OAAO;AACtB,WAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AA1ChB;AA+CA,MAAM,sBAAsB,cAA4B,IAAI;",
4
+ "sourcesContent": ["import { createContext } from 'react'\n\ntype ThemeListener = (name: string | null, themeManager: ThemeManager) => void\n\nexport class ThemeManager {\n name: string | null = 'light'\n parentName: string | null = null\n keys = new Map<any, Set<string>>()\n listeners = new Map<any, Function>()\n themeListeners = new Set<ThemeListener>()\n theme = null\n\n setActiveTheme({\n name,\n theme,\n parentName,\n }: {\n parentName?: string | null\n name: string | null\n theme?: any\n }) {\n if (name === this.name) return\n this.name = name\n this.theme = theme\n this.parentName = parentName || null\n this.update()\n }\n\n track(uuid: any, keys: Set<string>) {\n if (!this.name) return\n this.keys.set(uuid, keys)\n }\n\n update() {\n if (!this.name) {\n this.keys.clear()\n }\n for (const [uuid, keys] of this.keys.entries()) {\n if (keys.size) {\n this.listeners.get(uuid)?.()\n }\n }\n this.themeListeners.forEach((cb) => cb(this.name, this))\n }\n\n onChangeTheme(cb: ThemeListener) {\n this.themeListeners.add(cb)\n return () => {\n this.themeListeners.delete(cb)\n }\n }\n\n onUpdate(uuid: any, cb: Function) {\n this.listeners.set(uuid, cb)\n return () => {\n this.listeners.delete(uuid)\n this.keys.delete(uuid)\n }\n }\n}\n\nexport const ThemeManagerContext = createContext<ThemeManager>(new ThemeManager())\n"],
5
+ "mappings": ";;AAAA;AAIO,mBAAmB;AAAA,EAAnB,cAJP;AAKE,gBAAsB;AACtB,sBAA4B;AAC5B,gBAAO,IAAI;AACX,qBAAY,IAAI;AAChB,0BAAiB,IAAI;AACrB,iBAAQ;AAAA;AAAA,EAER,eAAe;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,KAKC;AACD,QAAI,SAAS,KAAK;AAAM;AACxB,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,aAAa,cAAc;AAChC,SAAK;AAAA;AAAA,EAGP,MAAM,MAAW,MAAmB;AAClC,QAAI,CAAC,KAAK;AAAM;AAChB,SAAK,KAAK,IAAI,MAAM;AAAA;AAAA,EAGtB,SAAS;AACP,QAAI,CAAC,KAAK,MAAM;AACd,WAAK,KAAK;AAAA;AAEZ,eAAW,CAAC,MAAM,SAAS,KAAK,KAAK,WAAW;AAC9C,UAAI,KAAK,MAAM;AACb,aAAK,UAAU,IAAI;AAAA;AAAA;AAGvB,SAAK,eAAe,QAAQ,CAAC,OAAO,GAAG,KAAK,MAAM;AAAA;AAAA,EAGpD,cAAc,IAAmB;AAC/B,SAAK,eAAe,IAAI;AACxB,WAAO,MAAM;AACX,WAAK,eAAe,OAAO;AAAA;AAAA;AAAA,EAI/B,SAAS,MAAW,IAAc;AAChC,SAAK,UAAU,IAAI,MAAM;AACzB,WAAO,MAAM;AACX,WAAK,UAAU,OAAO;AACtB,WAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AApDhB;AAyDA,MAAM,sBAAsB,cAA4B,IAAI;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,27 +1,33 @@
1
1
  {
2
2
  "name": "@tamagui/core",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.8",
4
4
  "source": "src/index.ts",
5
- "main": "dist/index.cjs",
6
- "module": "dist/index.js",
5
+ "main": "dist/cjs",
6
+ "module": "dist",
7
7
  "typings": "types.d.ts",
8
8
  "scripts": {
9
- "build": "tamagui-build",
10
- "watch": "tamagui-build --watch"
9
+ "build": "tamagui-build --separate",
10
+ "watch": "tamagui-build --separate --watch"
11
11
  },
12
+ "files": [
13
+ "_",
14
+ "types.d.ts",
15
+ "dist",
16
+ "src"
17
+ ],
12
18
  "dependencies": {
13
- "@tamagui/helpers": "^1.0.0-alpha.2",
14
- "@tamagui/use-debounce": "^1.0.0-alpha.4",
15
- "@tamagui/use-force-update": "^1.0.0-alpha.4",
19
+ "@tamagui/helpers": "^1.0.0-alpha.8",
20
+ "@tamagui/use-debounce": "^1.0.0-alpha.8",
21
+ "@tamagui/use-force-update": "^1.0.0-alpha.8",
16
22
  "react": "*",
17
- "react-dom": "*",
18
- "react-native-safe-area-context": "^3.3.0"
23
+ "react-dom": "*"
19
24
  },
20
25
  "peerDependencies": {
21
26
  "react-native-web": "*"
22
27
  },
23
28
  "devDependencies": {
24
- "@tamagui/build": "^1.0.0-alpha.2",
29
+ "@tamagui/build": "^1.0.0-alpha.8",
30
+ "@tamagui/ow": "^0.28.1",
25
31
  "@types/react": "^17.0.35",
26
32
  "esbuild": "^0.11.20",
27
33
  "typescript": "^4.4.4"
@@ -32,5 +38,5 @@
32
38
  "engines": {
33
39
  "node": ">=16"
34
40
  },
35
- "gitHead": "3e3b5401f9daea70cf9a99782d325f58357ca681"
41
+ "gitHead": "ecb0afe6782276b1f2ece90320fd2748f2f05c93"
36
42
  }
@@ -68,6 +68,44 @@ export function createComponent<A extends Object = DefaultProps>(
68
68
  // see onConfiguredOnce below which attaches a name then to this component
69
69
 
70
70
  const component = forwardRef<View, A>((props: any, forwardedRef) => {
71
+ const forceUpdate = useForceUpdate()
72
+ const features = useFeatures(props, { forceUpdate })
73
+ const manager = useContext(ThemeManagerContext)
74
+ const [state, set_] = useState(() => ({
75
+ hover: false,
76
+ press: false,
77
+ pressIn: false,
78
+ theme: manager.name,
79
+ }))
80
+ const set = (next: Partial<typeof state>) =>
81
+ set_((prev) => {
82
+ for (const key in next) {
83
+ if (prev[key] !== next[key]) {
84
+ return { ...prev, ...next }
85
+ }
86
+ }
87
+ return prev
88
+ })
89
+
90
+ // from react-native-web
91
+ if (process.env.NODE_ENV === 'development' && !isText && isWeb) {
92
+ Children.toArray(props.children).forEach((item) => {
93
+ if (typeof item === 'string') {
94
+ console.error(`Unexpected text node: ${item}. A text node cannot be a child of a <View>.`)
95
+ }
96
+ })
97
+ }
98
+
99
+ const hasTextAncestor = isWeb ? useContext(TextAncestorContext) : false
100
+ const hostRef = useRef(null)
101
+
102
+ const {
103
+ viewProps: viewPropsIn,
104
+ pseudos,
105
+ style,
106
+ classNames,
107
+ } = getSplitStyles(props, staticConfig, (manager.theme as any) || initialTheme)
108
+
71
109
  const {
72
110
  tag,
73
111
  hitSlop,
@@ -101,40 +139,19 @@ export function createComponent<A extends Object = DefaultProps>(
101
139
  onStartShouldSetResponderCapture,
102
140
  onMouseDown,
103
141
  onClick,
104
- // TODO feature load layou hook
105
- onLayout,
106
- } = props
107
142
 
108
- const forceUpdate = useForceUpdate()
109
- const features = useFeatures(props, { forceUpdate })
110
- const manager = useContext(ThemeManagerContext)
111
- const [state, set_] = useState(() => ({
112
- hover: false,
113
- press: false,
114
- pressIn: false,
115
- theme: manager.name,
116
- }))
117
- const set = (next: Partial<typeof state>) =>
118
- set_((prev) => {
119
- for (const key in next) {
120
- if (prev[key] !== next[key]) {
121
- return { ...prev, ...next }
122
- }
123
- }
124
- return prev
125
- })
143
+ accessible,
144
+ accessibilityRole,
126
145
 
127
- // from react-native-web
128
- if (process.env.NODE_ENV === 'development' && !isText && isWeb) {
129
- Children.toArray(props.children).forEach((item) => {
130
- if (typeof item === 'string') {
131
- console.error(`Unexpected text node: ${item}. A text node cannot be a child of a <View>.`)
132
- }
133
- })
134
- }
146
+ // TODO feature load layout hook
147
+ onLayout,
148
+ ...viewProps
149
+ } = viewPropsIn
135
150
 
136
- const hasTextAncestor = isWeb ? useContext(TextAncestorContext) : false
137
- const hostRef = useRef(null)
151
+ if (!isWeb) {
152
+ if (accessible) viewProps.accessible = accessible
153
+ if (accessibilityRole) viewProps.accessibilityRole = accessibilityRole
154
+ }
138
155
 
139
156
  if (isWeb) {
140
157
  // from react-native-web
@@ -160,12 +177,6 @@ export function createComponent<A extends Object = DefaultProps>(
160
177
 
161
178
  const isTracking = useRef(false)
162
179
 
163
- const { viewProps, pseudos, style, classNames } = getSplitStyles(
164
- props,
165
- staticConfig,
166
- (manager.theme as any) || initialTheme
167
- )
168
-
169
180
  // hasEverHadEvents prevents repareting if you remove onPress or similar...
170
181
  const internal = useRef<{ isMounted: boolean; hasEverHadEvents?: boolean }>()
171
182
  if (!internal.current) {
@@ -466,7 +477,7 @@ export function createComponent<A extends Object = DefaultProps>(
466
477
  } else {
467
478
  if (!hasWarnedOnce) {
468
479
  hasWarnedOnce = true
469
- console.log('⚠️ we need to account for default styles for media queries')
480
+ console.log('⚠️ TODO account for default styles for media queries')
470
481
  }
471
482
  }
472
483
  // @ts-ignore
@@ -489,10 +500,14 @@ export function createComponent<A extends Object = DefaultProps>(
489
500
  const res = component as any as StaticComponent<A, void>
490
501
 
491
502
  // add extractable HoC
492
- res['extractable'] = (Component: any) => {
503
+ res['extractable'] = (Component: any, conf?: StaticConfig) => {
493
504
  Component['staticConfig'] = extendStaticConfig(res, {
505
+ ...conf,
494
506
  neverFlatten: true,
495
- defaultProps: Component.defaultProps,
507
+ defaultProps: {
508
+ ...Component.defaultProps,
509
+ ...conf?.defaultProps,
510
+ },
496
511
  })
497
512
  return Component
498
513
  }
package/src/createFont.ts CHANGED
@@ -1,6 +1,11 @@
1
+ import { validateFont } from './helpers/validate'
1
2
  import { GenericFont } from './types'
2
3
 
3
4
  export const createFont = <A extends GenericFont>(font: A): A => {
5
+ if (process.env.NODE_ENV === 'development') {
6
+ validateFont(font)
7
+ }
8
+
4
9
  // fills in any missing values based on size keys being standard
5
10
  const sizeKeys = Object.keys(font.size)
6
11
 
@@ -2,6 +2,7 @@ import { getStyleRules } from '@tamagui/helpers'
2
2
 
3
3
  import { Variable, createVariable, isVariable } from './createVariable'
4
4
  import { createTamaguiProvider } from './helpers/createTamaguiProvider'
5
+ import { validateConfig } from './helpers/validate'
5
6
  import { configureMedia } from './hooks/useMedia'
6
7
  import {
7
8
  CreateTamaguiConfig,
@@ -27,7 +28,9 @@ export type CreateTamaguiProps = TamaguiProviderProps &
27
28
  let conf: TamaguiInternalConfig | null
28
29
 
29
30
  export const getHasConfigured = () => !!conf
30
- export const getTamaguiConfig = () => conf!
31
+
32
+ export const getTamagui = () => conf!
33
+ export const getTokens = () => conf!.tokensParsed
31
34
 
32
35
  type ConfigListener = (conf: TamaguiInternalConfig) => void
33
36
  const configListeners = new Set<ConfigListener>()
@@ -46,6 +49,12 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
46
49
  ): Conf extends CreateTamaguiConfig<infer A, infer B, infer C, infer D>
47
50
  ? TamaguiInternalConfig<A, B, C, D>
48
51
  : unknown {
52
+ if (process.env.NODE_ENV === 'development') {
53
+ // config is re-run by the @tamagui/static, dont double validate
54
+ if (!config['parsed']) {
55
+ validateConfig(config)
56
+ }
57
+ }
49
58
  // test env loads a few times as it runs diff tests
50
59
  if (conf) {
51
60
  console.warn('Called createTamagui twice! Should never do so')
@@ -157,6 +166,7 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
157
166
  themeConfig,
158
167
  themeParsed,
159
168
  tokensParsed,
169
+ parsed: true,
160
170
  getCSS() {
161
171
  return `${themeConfig.css}\n${[...getStyleRules()].join('\n')}`
162
172
  },
@@ -1,9 +1,14 @@
1
1
  import { Variable, createVariable } from './createVariable'
2
+ import { validateTokens } from './helpers/validate'
2
3
  import { CreateTokens } from './types'
3
4
 
4
- // tokens.color.dark.red ===>{ var: `color-dark-red`, val: '' }
5
+ // tokens.color.dark.red ===> { var: `color-dark-red`, val: '' }
5
6
 
6
7
  export function createTokens<T extends CreateTokens>(tokens: T): MakeTokens<T> {
8
+ if (process.env.NODE_ENV === 'development') {
9
+ validateTokens(tokens)
10
+ }
11
+
7
12
  return setupTokens(tokens) as any
8
13
  }
9
14
 
@@ -11,6 +11,10 @@ export class Variable {
11
11
  this.name = name
12
12
  this.variable = isWeb ? `var(--${name})` : this.val
13
13
  }
14
+
15
+ toString() {
16
+ return isWeb ? this.variable : this.val
17
+ }
14
18
  }
15
19
 
16
20
  type VariableIn = { val: string | number; name: string }
@@ -1,4 +1,4 @@
1
- import { getTamaguiConfig } from '../createTamagui'
1
+ import { getTamagui } from '../createTamagui'
2
2
  import { Variable } from '../createVariable'
3
3
  import { StaticConfig, TamaguiInternalConfig } from '../types'
4
4
  import { isObj } from './isObj'
@@ -9,7 +9,7 @@ export const createPropMapper = (c: StaticConfig) => {
9
9
  const defaultProps = c.defaultProps || {}
10
10
 
11
11
  return (key: string, value: any, theme: any, props: any) => {
12
- const conf = getTamaguiConfig()
12
+ const conf = getTamagui()
13
13
  if (!conf) {
14
14
  console.trace('no conf! err')
15
15
  return
@@ -8,7 +8,7 @@ import {
8
8
  import { ViewStyle } from 'react-native'
9
9
 
10
10
  import { isWeb } from '../constants/platform'
11
- import { mediaQueryConfig } from '../hooks/useMedia'
11
+ import { mediaQueryConfig, mediaState } from '../hooks/useMedia'
12
12
  import { StaticConfigParsed, ThemeObject } from '../types'
13
13
  import { createMediaStyle } from './createMediaStyle'
14
14
  import { fixNativeShadow } from './fixNativeShadow'
@@ -28,7 +28,6 @@ export const getSplitStyles = (
28
28
  const validStyleProps = staticConfig.isText ? stylePropsText : validStyles
29
29
  const viewProps: Record<string, any> = {}
30
30
  const style: any[] = []
31
- const blacklistProps = isSplittingDefaultProps ? blacklistDefaultProps : blacklistFinalProps
32
31
 
33
32
  let pseudos: { hoverStyle?: ViewStyle; pressStyle?: ViewStyle } | null = null
34
33
  let cur: ViewStyle | null = null
@@ -54,14 +53,15 @@ export const getSplitStyles = (
54
53
  const mediaProps = { ...props, ...valInit }
55
54
  // TODO media + hover
56
55
  const mediaStyle = getSubStyle(valInit, staticConfig, theme, props)
57
- const mediaStyles = getStylesAtomic(mediaStyle)
58
- if (process.env.NODE_ENV === 'development') {
59
- if (props['debug']) {
60
- console.log('mediaStyles', keyInit, { mediaProps, mediaStyle, mediaStyles })
56
+
57
+ if (isWeb) {
58
+ const mediaStyles = getStylesAtomic(mediaStyle)
59
+ if (process.env.NODE_ENV === 'development') {
60
+ if (props['debug']) {
61
+ console.log('mediaStyles', keyInit, { mediaProps, mediaStyle, mediaStyles })
62
+ }
61
63
  }
62
- }
63
- for (const style of mediaStyles) {
64
- if (isWeb) {
64
+ for (const style of mediaStyles) {
65
65
  const out = createMediaStyle(style, mediaKey, mediaQueryConfig)
66
66
  classNames = classNames || []
67
67
  classNames.push(out.identifier)
@@ -70,8 +70,10 @@ export const getSplitStyles = (
70
70
  if (process.env.NODE_ENV === 'development' && props['debug']) {
71
71
  console.log('mediaProp', style.identifier, out, mediaProps, mediaStyle, mediaStyles)
72
72
  }
73
- } else {
74
- console.log('TODO native media style logic')
73
+ }
74
+ } else {
75
+ if (mediaState[mediaKey]) {
76
+ style.push(mediaStyle)
75
77
  }
76
78
  }
77
79
  continue
@@ -130,8 +132,9 @@ export const getSplitStyles = (
130
132
  cur[key] = val
131
133
  continue
132
134
  }
133
- // TODO this blacklist should be configurable + better set up
134
- if (!blacklistProps[key]) {
135
+
136
+ // pass to view props
137
+ if (!staticConfig.variants || !(key in staticConfig.variants)) {
135
138
  viewProps[key] = val
136
139
  }
137
140
  }
@@ -181,19 +184,6 @@ const getSubStyle = (
181
184
  return styleOut
182
185
  }
183
186
 
184
- const blacklistDefaultProps = {
185
- ...validStyles,
186
- ...stylePropsText,
187
- }
188
-
189
- const blacklistFinalProps = {
190
- ...blacklistDefaultProps,
191
- tag: true,
192
- debug: true,
193
- space: true,
194
- hitSlop: true,
195
- }
196
-
197
187
  const mapTransformKeys = {
198
188
  x: 'translateX',
199
189
  y: 'translateY',
@@ -0,0 +1,5 @@
1
+ import React, { isValidElement } from 'react'
2
+
3
+ export const isTamaguiElement = (child: any): child is React.ReactElement => {
4
+ return isValidElement(child) && !!child.type['staticConfig']?.parsed
5
+ }
@@ -1,3 +1,6 @@
1
1
  import MediaQueryList from '@expo/match-media/build/MediaQueryList.js'
2
2
 
3
3
  export const matchMedia = (media: string) => new MediaQueryList(media)
4
+
5
+ // @ts-ignore
6
+ globalThis['matchMedia'] = matchMedia
@@ -2,7 +2,15 @@ export const matchMedia =
2
2
  (typeof window !== 'undefined' && window.matchMedia) ||
3
3
  (function matchMediaFallback(query: string) {
4
4
  return {
5
- addListener() {},
5
+ addListener() {
6
+ if (
7
+ process.env.NODE_ENV === 'development' &&
8
+ !process.env.IS_STATIC &&
9
+ process.env.TAMAGUI_TARGET !== 'web'
10
+ ) {
11
+ console.log('warning: matchMedia not loading! Is native picking up .native.js files?')
12
+ }
13
+ },
6
14
  removeListener() {},
7
15
  matches: false,
8
16
  }
@@ -0,0 +1,59 @@
1
+ // published a patched version that works on native
2
+ import ow from '@tamagui/ow'
3
+
4
+ export const validateConfig = (conf: any) => {
5
+ if (!conf) {
6
+ console.warn('no conf?')
7
+ return
8
+ }
9
+ try {
10
+ ow(conf, validConfig)
11
+ } catch (err: any) {
12
+ console.log('Given config:\n', JSON.stringify(conf, null, 2))
13
+ throw err
14
+ }
15
+ }
16
+
17
+ const validConfig = ow.object.exactShape({
18
+ defaultTheme: ow.optional.string,
19
+ disableRootThemeClass: ow.optional.boolean,
20
+ shorthands: ow.optional.object.valuesOfType(ow.string),
21
+ themes: ow.object.valuesOfType(ow.object),
22
+ tokens: ow.object.valuesOfType(ow.object),
23
+ media: ow.object.valuesOfType(ow.object),
24
+ })
25
+
26
+ const validFont = ow.object.exactShape({
27
+ family: ow.string,
28
+ size: ow.object.nonEmpty.valuesOfType(ow.number),
29
+ lineHeight: ow.object.nonEmpty.valuesOfType(ow.number),
30
+ weight: ow.object.nonEmpty.valuesOfType(ow.string),
31
+ letterSpacing: ow.object.nonEmpty.valuesOfType(ow.number),
32
+ })
33
+
34
+ const validTokens = ow.object.exactShape({
35
+ font: ow.object.valuesOfType(validFont),
36
+ size: ow.object.nonEmpty.valuesOfType(ow.number),
37
+ space: ow.object.nonEmpty.valuesOfType(ow.number),
38
+ zIndex: ow.object.nonEmpty.valuesOfType(ow.number),
39
+ radius: ow.object.nonEmpty.valuesOfType(ow.number),
40
+ color: ow.object.nonEmpty.valuesOfType(ow.string),
41
+ })
42
+
43
+ export const validateTokens = (tokens: any) => {
44
+ try {
45
+ ow(tokens, validTokens)
46
+ } catch (err: any) {
47
+ console.log('Given tokens:\n', JSON.stringify(tokens, null, 2))
48
+ throw err
49
+ }
50
+ }
51
+
52
+ export const validateFont = (font: any) => {
53
+ try {
54
+ ow(font, validFont)
55
+ } catch (err: any) {
56
+ console.log('Given font:\n', JSON.stringify(font, null, 2))
57
+ throw err
58
+ }
59
+ }