@tamagui/core 1.0.1-beta.216 → 1.0.1-beta.218

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 (50) hide show
  1. package/dist/cjs/createComponent.js +43 -90
  2. package/dist/cjs/createComponent.js.map +2 -2
  3. package/dist/cjs/createTamagui.js +2 -2
  4. package/dist/cjs/createTamagui.js.map +1 -1
  5. package/dist/cjs/helpers/getSplitStyles.js +48 -38
  6. package/dist/cjs/helpers/getSplitStyles.js.map +3 -3
  7. package/dist/cjs/helpers/getStylesAtomic.js +2 -4
  8. package/dist/cjs/helpers/getStylesAtomic.js.map +2 -2
  9. package/dist/cjs/helpers/mergeProps.js.map +2 -2
  10. package/dist/cjs/helpers/normalizeValueWithProperty.js +7 -2
  11. package/dist/cjs/helpers/normalizeValueWithProperty.js.map +2 -2
  12. package/dist/cjs/helpers/useShallowSetState.js.map +2 -2
  13. package/dist/cjs/hooks/useMedia.js +35 -38
  14. package/dist/cjs/hooks/useMedia.js.map +2 -2
  15. package/dist/cjs/hooks/useTheme.js +28 -12
  16. package/dist/cjs/hooks/useTheme.js.map +2 -2
  17. package/dist/cjs/views/ThemeInverse.js +1 -2
  18. package/dist/cjs/views/ThemeInverse.js.map +2 -2
  19. package/dist/esm/createComponent.js +45 -96
  20. package/dist/esm/createComponent.js.map +2 -2
  21. package/dist/esm/createTamagui.js +2 -2
  22. package/dist/esm/createTamagui.js.map +1 -1
  23. package/dist/esm/helpers/getSplitStyles.js +48 -38
  24. package/dist/esm/helpers/getSplitStyles.js.map +3 -3
  25. package/dist/esm/helpers/getStylesAtomic.js +2 -4
  26. package/dist/esm/helpers/getStylesAtomic.js.map +2 -2
  27. package/dist/esm/helpers/mergeProps.js.map +2 -2
  28. package/dist/esm/helpers/normalizeValueWithProperty.js +7 -2
  29. package/dist/esm/helpers/normalizeValueWithProperty.js.map +2 -2
  30. package/dist/esm/helpers/useShallowSetState.js.map +2 -2
  31. package/dist/esm/hooks/useMedia.js +36 -39
  32. package/dist/esm/hooks/useMedia.js.map +2 -2
  33. package/dist/esm/hooks/useTheme.js +28 -12
  34. package/dist/esm/hooks/useTheme.js.map +2 -2
  35. package/dist/esm/views/ThemeInverse.js +1 -2
  36. package/dist/esm/views/ThemeInverse.js.map +2 -2
  37. package/package.json +16 -16
  38. package/src/createComponent.tsx +58 -115
  39. package/src/createTamagui.ts +2 -2
  40. package/src/helpers/getSplitStyles.tsx +47 -37
  41. package/src/helpers/getStylesAtomic.ts +2 -4
  42. package/src/helpers/mergeProps.ts +7 -7
  43. package/src/helpers/normalizeValueWithProperty.ts +9 -2
  44. package/src/helpers/useShallowSetState.tsx +3 -1
  45. package/src/hooks/useMedia.tsx +42 -42
  46. package/src/hooks/useTheme.tsx +35 -20
  47. package/src/views/ThemeInverse.tsx +1 -2
  48. package/types/helpers/mergeProps.d.ts +2 -2
  49. package/types/helpers/useShallowSetState.d.ts +2 -1
  50. package/types/hooks/useTheme.d.ts +1 -1
@@ -13,7 +13,7 @@ import {
13
13
  } from "../helpers/ThemeManager";
14
14
  import { GetThemeUnwrapped } from "./getThemeUnwrapped";
15
15
  import { useServerRef } from "./useServerHooks";
16
- const useTheme = (themeName, componentName, props, forceUpdate) => {
16
+ const useTheme = (themeName, componentName, props, forceUpdate, disableTracking) => {
17
17
  if (isRSC) {
18
18
  const config = getConfig();
19
19
  return getThemeProxied(config.themes[config.defaultTheme], config.defaultTheme);
@@ -60,10 +60,33 @@ const useTheme = (themeName, componentName, props, forceUpdate) => {
60
60
  return themes[Object.keys(themes)[0]];
61
61
  }
62
62
  return useMemo(() => {
63
- return getThemeProxied(theme, name, className, themeManager, state, debugProp);
64
- }, [theme, name, className, themeManager, state, debugProp]);
63
+ return getThemeProxied({
64
+ theme,
65
+ name,
66
+ className,
67
+ themeManager,
68
+ onStringKeyAccess(key) {
69
+ if (disableTracking)
70
+ return;
71
+ if (state) {
72
+ if (state.current.isRendering && !state.current.keys.has(key)) {
73
+ state.current.keys.add(key);
74
+ if (process.env.NODE_ENV === "development" && debugProp === "verbose") {
75
+ console.log(" \u{1F538} tracking theme", key);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ });
81
+ }, [theme, name, className, themeManager, debugProp, disableTracking]);
65
82
  };
66
- function getThemeProxied(theme, name, className, themeManager, state, debugProp) {
83
+ function getThemeProxied({
84
+ theme,
85
+ name,
86
+ className,
87
+ themeManager,
88
+ onStringKeyAccess
89
+ }) {
67
90
  return createProxy(theme, {
68
91
  has(_, key) {
69
92
  if (typeof key === "string" && key[0] === "$") {
@@ -93,14 +116,7 @@ function getThemeProxied(theme, name, className, themeManager, state, debugProp)
93
116
  if (!themeManager) {
94
117
  return theme[key];
95
118
  }
96
- if (state) {
97
- if (state.current.isRendering && !state.current.keys.has(key)) {
98
- state.current.keys.add(key);
99
- if (process.env.NODE_ENV === "development" && debugProp === "verbose") {
100
- console.log(" \u{1F538} tracking theme", key);
101
- }
102
- }
103
- }
119
+ onStringKeyAccess == null ? void 0 : onStringKeyAccess(key);
104
120
  return themeManager.getValue(key);
105
121
  }
106
122
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/useTheme.tsx"],
4
- "sourcesContent": ["import { isRSC, isServer, useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport { useForceUpdate } from '@tamagui/use-force-update'\nimport React, { useContext, useLayoutEffect, useMemo, useRef, useState } from 'react'\n\nimport { getConfig } from '../config'\nimport { isDevTools } from '../constants/isDevTools'\nimport { ThemeContext } from '../contexts/ThemeContext'\nimport { areEqualSets } from '../helpers/areEqualSets'\nimport { createProxy } from '../helpers/createProxy'\nimport {\n GetNextThemeProps,\n ThemeManager,\n ThemeManagerContext,\n emptyManager,\n} from '../helpers/ThemeManager'\nimport { ThemeName, ThemeParsed } from '../types'\nimport { GetThemeUnwrapped } from './getThemeUnwrapped'\nimport { useServerRef } from './useServerHooks'\n\nexport interface ThemeProps {\n className?: string\n disableThemeClass?: boolean\n name: Exclude<ThemeName, number> | null\n componentName?: string\n children?: any\n reset?: boolean\n debug?: boolean | 'verbose'\n}\n\ninterface UseThemeState {\n uuid: Object\n keys: Set<string>\n isRendering: boolean\n}\n\nexport const useTheme = (\n themeName?: string | null,\n componentName?: string,\n props?: ThemeProps,\n forceUpdate?: any\n): ThemeParsed => {\n // TODO this can use useChangeThemeEffect almost ready\n if (isRSC) {\n const config = getConfig()\n // @ts-ignore\n return getThemeProxied(config.themes[config.defaultTheme], config.defaultTheme)\n }\n\n const state = useServerRef() as React.MutableRefObject<UseThemeState>\n if (!state.current) {\n state.current = {\n uuid: {},\n keys: new Set(),\n isRendering: true,\n }\n }\n\n const { name, theme, themes, themeManager, className } = useChangeThemeEffect(\n themeName,\n componentName,\n props,\n forceUpdate,\n state.current.uuid\n )\n\n if (process.env.NODE_ENV === 'development') {\n if (props?.debug === 'verbose') {\n // eslint-disable-next-line no-console\n console.groupCollapsed(' \uD83D\uDD39 useTheme =>', name)\n const logs = { themeName, componentName, name, className, ...(isDevTools && { theme }) }\n for (const key in logs) {\n // eslint-disable-next-line no-console\n console.log(' ', key, logs[key])\n }\n // eslint-disable-next-line no-console\n console.groupEnd()\n }\n }\n\n // track usage\n state.current.isRendering = true\n useIsomorphicLayoutEffect(() => {\n const st = state.current\n st.isRendering = false\n const cur = themeManager?.keys.get(st.uuid)\n if (!cur || !areEqualSets(st.keys, cur)) {\n themeManager?.track(st.uuid, st.keys)\n }\n })\n\n const debugProp = props && props['debug']\n\n if (!theme) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.warn('No theme with name', themeName)\n }\n return themes[Object.keys(themes)[0]]\n }\n\n return useMemo(() => {\n return getThemeProxied(theme, name, className, themeManager, state, debugProp)\n }, [theme, name, className, themeManager, state, debugProp])\n}\n\nfunction getThemeProxied(\n theme: any,\n name: string,\n className?: string,\n themeManager?: ThemeManager | null,\n state?: React.MutableRefObject<UseThemeState>,\n debugProp?: boolean | 'verbose'\n) {\n return createProxy(theme, {\n has(_, key) {\n if (typeof key === 'string' && key[0] === '$') {\n key = key.slice(1)\n }\n return Reflect.has(theme, key)\n },\n get(_, key) {\n if (key === GetThemeUnwrapped) {\n return theme\n }\n if (key === GetThemeManager) {\n return themeManager\n }\n if (key === 'name') {\n return name\n }\n if (key === 'className') {\n return className\n }\n if (!name || key === '__proto__' || typeof key === 'symbol' || key === '$typeof') {\n return Reflect.get(_, key)\n }\n // auto convert variables to plain\n if (key[0] === '$') {\n key = key.slice(1)\n }\n if (!themeManager) {\n return theme[key]\n }\n if (state) {\n if (state.current.isRendering && !state.current.keys.has(key)) {\n state.current.keys.add(key)\n if (process.env.NODE_ENV === 'development' && debugProp === 'verbose') {\n // eslint-disable-next-line no-console\n console.log(' \uD83D\uDD38 tracking theme', key)\n }\n }\n }\n return themeManager.getValue(key)\n },\n })\n}\n\nconst GetThemeManager = Symbol()\n\nexport const getThemeManager = (theme: any): ThemeManager | undefined => {\n if (!theme) return\n return theme[GetThemeManager]\n}\n\nexport function useThemeName(opts?: { parent?: true }): ThemeName {\n if (isRSC) {\n const config = getConfig()\n return config.themes[Object.keys(config.themes)[0]] as any\n }\n const parent = useContext(ThemeManagerContext)\n const [name, setName] = useState(parent?.name || '')\n\n useIsomorphicLayoutEffect(() => {\n if (!parent) return\n return parent.onChangeTheme((next, manager) => {\n const name = opts?.parent ? manager.parentName || next : next\n if (!name) return\n setName(name)\n })\n }, [parent])\n\n return name\n}\n\nexport const useDefaultThemeName = () => {\n return useContext(ThemeContext)?.defaultTheme\n}\n\nexport const activeThemeManagers = new Set<ThemeManager>()\n\nexport const useChangeThemeEffect = (\n name?: string | null,\n componentName?: string,\n props?: ThemeProps,\n forceUpdateProp?: any,\n uuid?: Object\n): {\n themes: Record<string, ThemeParsed>\n themeManager: ThemeManager | null\n name: string\n theme: ThemeParsed | null\n className?: string\n} => {\n const config = getConfig()\n\n if (process.env.NODE_ENV === 'development') {\n if (!config) {\n throw new Error(\n `Missing tamagui config, you either have a duplicate config, or haven't set it up. Be sure createTamagui is called before rendering.`\n )\n }\n }\n\n const { themes } = config\n\n if (isRSC) {\n // we need context working for this to work well\n const parentManager = new ThemeManager('light', 'light', themes.light)\n const next = parentManager.getNextTheme({\n name,\n componentName,\n themes,\n reset: props?.reset,\n })\n return {\n ...next,\n themes,\n themeManager: null,\n }\n }\n\n const debug = props && props['debug']\n const parentManager = useContext(ThemeManagerContext) || emptyManager\n const reset = props?.reset || false\n const getThemeProps: GetNextThemeProps = {\n name,\n componentName,\n themes,\n reset,\n }\n const next = parentManager.getNextTheme(getThemeProps, debug)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const forceUpdate = forceUpdateProp || useForceUpdate()\n\n const themeManager = useMemo(() => {\n return new ThemeManager(next.name, next.className, next.theme, parentManager, reset)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // not concurrent safe but fixes native (but breaks SSR and not needed on web (i think) so leave only on native)\n let didChange = false\n if (process.env.TAMAGUI_TARGET === 'native') {\n didChange = Boolean(\n next?.name !== themeManager.name || next?.className !== themeManager.className\n )\n if (didChange) {\n themeManager.update(next, false, false)\n }\n }\n\n if (!isServer) {\n useLayoutEffect(() => {\n themeManager.update(next, didChange)\n activeThemeManagers.add(themeManager)\n\n const disposeParentOnChange = parentManager.onChangeTheme(() => {\n const next = parentManager.getNextTheme(getThemeProps, debug)\n if (!next) return\n if (themeManager.update(next)) {\n if (uuid && !themeManager.isTracking(uuid)) {\n // no need to re-render if not tracking any keys\n return\n }\n if (process.env.NODE_ENV === 'development' && debug) {\n // eslint-disable-next-line no-console\n console.log('Changed theme', componentName, next, { props })\n }\n forceUpdate()\n }\n })\n\n return () => {\n activeThemeManagers.delete(themeManager)\n disposeParentOnChange()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [didChange, themes, next?.name, next?.className, componentName, debug])\n }\n\n return {\n ...(parentManager && {\n name: parentManager.name,\n theme: parentManager.theme,\n }),\n ...next,\n className: next.className === parentManager.className ? undefined : next.className,\n themes,\n themeManager,\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,OAAO,UAAU,iCAAiC;AAC3D,SAAS,sBAAsB;AAC/B,SAAgB,YAAY,iBAAiB,SAAiB,gBAAgB;AAE9E,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAkBtB,MAAM,WAAW,CACtB,WACA,eACA,OACA,gBACgB;AAEhB,MAAI,OAAO;AACT,UAAM,SAAS,UAAU;AAEzB,WAAO,gBAAgB,OAAO,OAAO,OAAO,eAAe,OAAO,YAAY;AAAA,EAChF;AAEA,QAAM,QAAQ,aAAa;AAC3B,MAAI,CAAC,MAAM,SAAS;AAClB,UAAM,UAAU;AAAA,MACd,MAAM,CAAC;AAAA,MACP,MAAM,oBAAI,IAAI;AAAA,MACd,aAAa;AAAA,IACf;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,OAAO,QAAQ,cAAc,UAAU,IAAI;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,QAAQ;AAAA,EAChB;AAEA,MAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,SAAI,+BAAO,WAAU,WAAW;AAE9B,cAAQ,eAAe,2BAAoB,IAAI;AAC/C,YAAM,OAAO,EAAE,WAAW,eAAe,MAAM,WAAW,GAAI,cAAc,EAAE,MAAM,EAAG;AACvF,iBAAW,OAAO,MAAM;AAEtB,gBAAQ,IAAI,MAAM,KAAK,KAAK,IAAI;AAAA,MAClC;AAEA,cAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AAGA,QAAM,QAAQ,cAAc;AAC5B,4BAA0B,MAAM;AAC9B,UAAM,KAAK,MAAM;AACjB,OAAG,cAAc;AACjB,UAAM,MAAM,6CAAc,KAAK,IAAI,GAAG;AACtC,QAAI,CAAC,OAAO,CAAC,aAAa,GAAG,MAAM,GAAG,GAAG;AACvC,mDAAc,MAAM,GAAG,MAAM,GAAG;AAAA,IAClC;AAAA,EACF,CAAC;AAED,QAAM,YAAY,SAAS,MAAM;AAEjC,MAAI,CAAC,OAAO;AACV,QAAI,QAAQ,IAAI,aAAa,eAAe;AAE1C,cAAQ,KAAK,sBAAsB,SAAS;AAAA,IAC9C;AACA,WAAO,OAAO,OAAO,KAAK,MAAM,EAAE;AAAA,EACpC;AAEA,SAAO,QAAQ,MAAM;AACnB,WAAO,gBAAgB,OAAO,MAAM,WAAW,cAAc,OAAO,SAAS;AAAA,EAC/E,GAAG,CAAC,OAAO,MAAM,WAAW,cAAc,OAAO,SAAS,CAAC;AAC7D;AAEA,SAAS,gBACP,OACA,MACA,WACA,cACA,OACA,WACA;AACA,SAAO,YAAY,OAAO;AAAA,IACxB,IAAI,GAAG,KAAK;AACV,UAAI,OAAO,QAAQ,YAAY,IAAI,OAAO,KAAK;AAC7C,cAAM,IAAI,MAAM,CAAC;AAAA,MACnB;AACA,aAAO,QAAQ,IAAI,OAAO,GAAG;AAAA,IAC/B;AAAA,IACA,IAAI,GAAG,KAAK;AACV,UAAI,QAAQ,mBAAmB;AAC7B,eAAO;AAAA,MACT;AACA,UAAI,QAAQ,iBAAiB;AAC3B,eAAO;AAAA,MACT;AACA,UAAI,QAAQ,QAAQ;AAClB,eAAO;AAAA,MACT;AACA,UAAI,QAAQ,aAAa;AACvB,eAAO;AAAA,MACT;AACA,UAAI,CAAC,QAAQ,QAAQ,eAAe,OAAO,QAAQ,YAAY,QAAQ,WAAW;AAChF,eAAO,QAAQ,IAAI,GAAG,GAAG;AAAA,MAC3B;AAEA,UAAI,IAAI,OAAO,KAAK;AAClB,cAAM,IAAI,MAAM,CAAC;AAAA,MACnB;AACA,UAAI,CAAC,cAAc;AACjB,eAAO,MAAM;AAAA,MACf;AACA,UAAI,OAAO;AACT,YAAI,MAAM,QAAQ,eAAe,CAAC,MAAM,QAAQ,KAAK,IAAI,GAAG,GAAG;AAC7D,gBAAM,QAAQ,KAAK,IAAI,GAAG;AAC1B,cAAI,QAAQ,IAAI,aAAa,iBAAiB,cAAc,WAAW;AAErE,oBAAQ,IAAI,8BAAuB,GAAG;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AACA,aAAO,aAAa,SAAS,GAAG;AAAA,IAClC;AAAA,EACF,CAAC;AACH;AAEA,MAAM,kBAAkB,OAAO;AAExB,MAAM,kBAAkB,CAAC,UAAyC;AACvE,MAAI,CAAC;AAAO;AACZ,SAAO,MAAM;AACf;AAEO,SAAS,aAAa,MAAqC;AAChE,MAAI,OAAO;AACT,UAAM,SAAS,UAAU;AACzB,WAAO,OAAO,OAAO,OAAO,KAAK,OAAO,MAAM,EAAE;AAAA,EAClD;AACA,QAAM,SAAS,WAAW,mBAAmB;AAC7C,QAAM,CAAC,MAAM,OAAO,IAAI,UAAS,iCAAQ,SAAQ,EAAE;AAEnD,4BAA0B,MAAM;AAC9B,QAAI,CAAC;AAAQ;AACb,WAAO,OAAO,cAAc,CAAC,MAAM,YAAY;AAC7C,YAAMA,SAAO,6BAAM,UAAS,QAAQ,cAAc,OAAO;AACzD,UAAI,CAACA;AAAM;AACX,cAAQA,KAAI;AAAA,IACd,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;AAEO,MAAM,sBAAsB,MAAM;AAxLzC;AAyLE,UAAO,gBAAW,YAAY,MAAvB,mBAA0B;AACnC;AAEO,MAAM,sBAAsB,oBAAI,IAAkB;AAElD,MAAM,uBAAuB,CAClC,MACA,eACA,OACA,iBACA,SAOG;AACH,QAAM,SAAS,UAAU;AAEzB,MAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,OAAO,IAAI;AAEnB,MAAI,OAAO;AAET,UAAMC,iBAAgB,IAAI,aAAa,SAAS,SAAS,OAAO,KAAK;AACrE,UAAMC,QAAOD,eAAc,aAAa;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,+BAAO;AAAA,IAChB,CAAC;AACD,WAAO;AAAA,MACL,GAAGC;AAAA,MACH;AAAA,MACA,cAAc;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,QAAQ,SAAS,MAAM;AAC7B,QAAM,gBAAgB,WAAW,mBAAmB,KAAK;AACzD,QAAM,SAAQ,+BAAO,UAAS;AAC9B,QAAM,gBAAmC;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,cAAc,aAAa,eAAe,KAAK;AAE5D,QAAM,cAAc,mBAAmB,eAAe;AAEtD,QAAM,eAAe,QAAQ,MAAM;AACjC,WAAO,IAAI,aAAa,KAAK,MAAM,KAAK,WAAW,KAAK,OAAO,eAAe,KAAK;AAAA,EAErF,GAAG,CAAC,CAAC;AAGL,MAAI,YAAY;AAChB,MAAI,QAAQ,IAAI,mBAAmB,UAAU;AAC3C,gBAAY;AAAA,OACV,6BAAM,UAAS,aAAa,SAAQ,6BAAM,eAAc,aAAa;AAAA,IACvE;AACA,QAAI,WAAW;AACb,mBAAa,OAAO,MAAM,OAAO,KAAK;AAAA,IACxC;AAAA,EACF;AAEA,MAAI,CAAC,UAAU;AACb,oBAAgB,MAAM;AACpB,mBAAa,OAAO,MAAM,SAAS;AACnC,0BAAoB,IAAI,YAAY;AAEpC,YAAM,wBAAwB,cAAc,cAAc,MAAM;AAC9D,cAAMA,QAAO,cAAc,aAAa,eAAe,KAAK;AAC5D,YAAI,CAACA;AAAM;AACX,YAAI,aAAa,OAAOA,KAAI,GAAG;AAC7B,cAAI,QAAQ,CAAC,aAAa,WAAW,IAAI,GAAG;AAE1C;AAAA,UACF;AACA,cAAI,QAAQ,IAAI,aAAa,iBAAiB,OAAO;AAEnD,oBAAQ,IAAI,iBAAiB,eAAeA,OAAM,EAAE,MAAM,CAAC;AAAA,UAC7D;AACA,sBAAY;AAAA,QACd;AAAA,MACF,CAAC;AAED,aAAO,MAAM;AACX,4BAAoB,OAAO,YAAY;AACvC,8BAAsB;AAAA,MACxB;AAAA,IAEF,GAAG,CAAC,WAAW,QAAQ,6BAAM,MAAM,6BAAM,WAAW,eAAe,KAAK,CAAC;AAAA,EAC3E;AAEA,SAAO;AAAA,IACL,GAAI,iBAAiB;AAAA,MACnB,MAAM,cAAc;AAAA,MACpB,OAAO,cAAc;AAAA,IACvB;AAAA,IACA,GAAG;AAAA,IACH,WAAW,KAAK,cAAc,cAAc,YAAY,SAAY,KAAK;AAAA,IACzE;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { isRSC, isServer, useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport { useForceUpdate } from '@tamagui/use-force-update'\nimport React, { useContext, useLayoutEffect, useMemo, useRef, useState } from 'react'\n\nimport { getConfig } from '../config'\nimport { isDevTools } from '../constants/isDevTools'\nimport { ThemeContext } from '../contexts/ThemeContext'\nimport { areEqualSets } from '../helpers/areEqualSets'\nimport { createProxy } from '../helpers/createProxy'\nimport {\n GetNextThemeProps,\n ThemeManager,\n ThemeManagerContext,\n emptyManager,\n} from '../helpers/ThemeManager'\nimport { ThemeName, ThemeParsed } from '../types'\nimport { GetThemeUnwrapped } from './getThemeUnwrapped'\nimport { useServerRef } from './useServerHooks'\n\nexport interface ThemeProps {\n className?: string\n disableThemeClass?: boolean\n name: Exclude<ThemeName, number> | null\n componentName?: string\n children?: any\n reset?: boolean\n debug?: boolean | 'verbose'\n}\n\ninterface UseThemeState {\n uuid: Object\n keys: Set<string>\n isRendering: boolean\n}\n\nexport const useTheme = (\n themeName?: string | null,\n componentName?: string,\n props?: ThemeProps,\n forceUpdate?: any,\n disableTracking?: boolean\n): ThemeParsed => {\n // TODO this can use useChangeThemeEffect almost ready\n if (isRSC) {\n const config = getConfig()\n // @ts-ignore\n return getThemeProxied(config.themes[config.defaultTheme], config.defaultTheme)\n }\n\n const state = useServerRef() as React.MutableRefObject<UseThemeState>\n if (!state.current) {\n state.current = {\n uuid: {},\n keys: new Set(),\n isRendering: true,\n }\n }\n\n const { name, theme, themes, themeManager, className } = useChangeThemeEffect(\n themeName,\n componentName,\n props,\n forceUpdate,\n state.current.uuid\n )\n\n if (process.env.NODE_ENV === 'development') {\n if (props?.debug === 'verbose') {\n // eslint-disable-next-line no-console\n console.groupCollapsed(' \uD83D\uDD39 useTheme =>', name)\n const logs = { themeName, componentName, name, className, ...(isDevTools && { theme }) }\n for (const key in logs) {\n // eslint-disable-next-line no-console\n console.log(' ', key, logs[key])\n }\n // eslint-disable-next-line no-console\n console.groupEnd()\n }\n }\n\n // track usage\n state.current.isRendering = true\n useIsomorphicLayoutEffect(() => {\n const st = state.current\n st.isRendering = false\n const cur = themeManager?.keys.get(st.uuid)\n if (!cur || !areEqualSets(st.keys, cur)) {\n themeManager?.track(st.uuid, st.keys)\n }\n })\n\n const debugProp = props && props['debug']\n\n if (!theme) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.warn('No theme with name', themeName)\n }\n return themes[Object.keys(themes)[0]]\n }\n\n return useMemo(() => {\n return getThemeProxied({\n theme,\n name,\n className,\n themeManager,\n onStringKeyAccess(key) {\n if (disableTracking) return\n if (state) {\n if (state.current.isRendering && !state.current.keys.has(key)) {\n state.current.keys.add(key)\n if (process.env.NODE_ENV === 'development' && debugProp === 'verbose') {\n // eslint-disable-next-line no-console\n console.log(' \uD83D\uDD38 tracking theme', key)\n }\n }\n }\n },\n })\n }, [theme, name, className, themeManager, debugProp, disableTracking])\n}\n\nfunction getThemeProxied({\n theme,\n name,\n className,\n themeManager,\n onStringKeyAccess,\n}: {\n theme: any\n name: string\n onStringKeyAccess?: (cb: string) => void\n className?: string\n themeManager?: ThemeManager | null\n}) {\n return createProxy(theme, {\n has(_, key) {\n if (typeof key === 'string' && key[0] === '$') {\n key = key.slice(1)\n }\n return Reflect.has(theme, key)\n },\n get(_, key) {\n if (key === GetThemeUnwrapped) {\n return theme\n }\n if (key === GetThemeManager) {\n return themeManager\n }\n if (key === 'name') {\n return name\n }\n if (key === 'className') {\n return className\n }\n if (!name || key === '__proto__' || typeof key === 'symbol' || key === '$typeof') {\n return Reflect.get(_, key)\n }\n // auto convert variables to plain\n if (key[0] === '$') {\n key = key.slice(1)\n }\n if (!themeManager) {\n return theme[key]\n }\n onStringKeyAccess?.(key)\n return themeManager.getValue(key)\n },\n })\n}\n\nconst GetThemeManager = Symbol()\n\nexport const getThemeManager = (theme: any): ThemeManager | undefined => {\n if (!theme) return\n return theme[GetThemeManager]\n}\n\nexport function useThemeName(opts?: { parent?: true }): ThemeName {\n if (isRSC) {\n const config = getConfig()\n return config.themes[Object.keys(config.themes)[0]] as any\n }\n const parent = useContext(ThemeManagerContext)\n const [name, setName] = useState(parent?.name || '')\n\n useIsomorphicLayoutEffect(() => {\n if (!parent) return\n return parent.onChangeTheme((next, manager) => {\n const name = opts?.parent ? manager.parentName || next : next\n if (!name) return\n setName(name)\n })\n }, [parent])\n\n return name\n}\n\nexport const useDefaultThemeName = () => {\n return useContext(ThemeContext)?.defaultTheme\n}\n\nexport const activeThemeManagers = new Set<ThemeManager>()\n\nexport const useChangeThemeEffect = (\n name?: string | null,\n componentName?: string,\n props?: ThemeProps,\n forceUpdateProp?: any,\n uuid?: Object\n): {\n themes: Record<string, ThemeParsed>\n themeManager: ThemeManager | null\n name: string\n theme: ThemeParsed | null\n className?: string\n} => {\n const config = getConfig()\n\n if (process.env.NODE_ENV === 'development') {\n if (!config) {\n throw new Error(\n `Missing tamagui config, you either have a duplicate config, or haven't set it up. Be sure createTamagui is called before rendering.`\n )\n }\n }\n\n const { themes } = config\n\n if (isRSC) {\n // we need context working for this to work well\n const parentManager = new ThemeManager('light', 'light', themes.light)\n const next = parentManager.getNextTheme({\n name,\n componentName,\n themes,\n reset: props?.reset,\n })\n return {\n ...next,\n themes,\n themeManager: null,\n }\n }\n\n const debug = props && props['debug']\n const parentManager = useContext(ThemeManagerContext) || emptyManager\n const reset = props?.reset || false\n const getThemeProps: GetNextThemeProps = {\n name,\n componentName,\n themes,\n reset,\n }\n const next = parentManager.getNextTheme(getThemeProps, debug)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const forceUpdate = forceUpdateProp || useForceUpdate()\n\n const themeManager = useMemo(() => {\n return new ThemeManager(next.name, next.className, next.theme, parentManager, reset)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // not concurrent safe but fixes native (but breaks SSR and not needed on web (i think) so leave only on native)\n let didChange = false\n if (process.env.TAMAGUI_TARGET === 'native') {\n didChange = Boolean(\n next?.name !== themeManager.name || next?.className !== themeManager.className\n )\n if (didChange) {\n themeManager.update(next, false, false)\n }\n }\n\n if (!isServer) {\n useLayoutEffect(() => {\n themeManager.update(next, didChange)\n activeThemeManagers.add(themeManager)\n\n const disposeParentOnChange = parentManager.onChangeTheme(() => {\n const next = parentManager.getNextTheme(getThemeProps, debug)\n if (!next) return\n if (themeManager.update(next)) {\n if (uuid && !themeManager.isTracking(uuid)) {\n // no need to re-render if not tracking any keys\n return\n }\n if (process.env.NODE_ENV === 'development' && debug) {\n // eslint-disable-next-line no-console\n console.log('Changed theme', componentName, next, { props })\n }\n forceUpdate()\n }\n })\n\n return () => {\n activeThemeManagers.delete(themeManager)\n disposeParentOnChange()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [didChange, themes, next?.name, next?.className, componentName, debug])\n }\n\n return {\n ...(parentManager && {\n name: parentManager.name,\n theme: parentManager.theme,\n }),\n ...next,\n className: next.className === parentManager.className ? undefined : next.className,\n themes,\n themeManager,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["name", "parentManager", "next"]
7
7
  }
@@ -13,8 +13,7 @@ const ThemeInverse = ({
13
13
  useIsomorphicLayoutEffect(() => {
14
14
  if (themeName.startsWith("dark")) {
15
15
  setName("light");
16
- }
17
- if (themeName.startsWith("light")) {
16
+ } else if (themeName.startsWith("light")) {
18
17
  setName("dark");
19
18
  }
20
19
  }, [defaultTheme, themeName]);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/views/ThemeInverse.tsx"],
4
- "sourcesContent": ["import { useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport React, { useState } from 'react'\n\nimport { useDefaultThemeName, useThemeName } from '../hooks/useTheme'\nimport { Theme } from './Theme'\n\nexport const ThemeInverse = ({\n children,\n disable,\n}: {\n children: React.ReactNode\n disable?: boolean\n}) => {\n const themeName = useThemeName()\n const defaultTheme = useDefaultThemeName()\n const [name, setName] = useState<null | string>(null)\n\n // ssr\n useIsomorphicLayoutEffect(() => {\n if (themeName.startsWith('dark')) {\n setName('light')\n }\n if (themeName.startsWith('light')) {\n setName('dark')\n }\n }, [defaultTheme, themeName])\n\n if (disable) {\n return children as JSX.Element\n }\n\n return <Theme name={name}>{children}</Theme>\n}\n"],
5
- "mappings": "AA+BS;AA/BT,SAAS,iCAAiC;AAC1C,SAAgB,gBAAgB;AAEhC,SAAS,qBAAqB,oBAAoB;AAClD,SAAS,aAAa;AAEf,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAGM;AACJ,QAAM,YAAY,aAAa;AAC/B,QAAM,eAAe,oBAAoB;AACzC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAwB,IAAI;AAGpD,4BAA0B,MAAM;AAC9B,QAAI,UAAU,WAAW,MAAM,GAAG;AAChC,cAAQ,OAAO;AAAA,IACjB;AACA,QAAI,UAAU,WAAW,OAAO,GAAG;AACjC,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,cAAc,SAAS,CAAC;AAE5B,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC;AAAA,IAAM;AAAA,IAAa;AAAA,GAAS;AACtC;",
4
+ "sourcesContent": ["import { useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport React, { useState } from 'react'\n\nimport { useDefaultThemeName, useThemeName } from '../hooks/useTheme'\nimport { Theme } from './Theme'\n\nexport const ThemeInverse = ({\n children,\n disable,\n}: {\n children: React.ReactNode\n disable?: boolean\n}) => {\n const themeName = useThemeName()\n const defaultTheme = useDefaultThemeName()\n const [name, setName] = useState<null | string>(null)\n\n // ssr\n useIsomorphicLayoutEffect(() => {\n if (themeName.startsWith('dark')) {\n setName('light')\n } else if (themeName.startsWith('light')) {\n setName('dark')\n }\n }, [defaultTheme, themeName])\n\n if (disable) {\n return children as JSX.Element\n }\n\n return <Theme name={name}>{children}</Theme>\n}\n"],
5
+ "mappings": "AA8BS;AA9BT,SAAS,iCAAiC;AAC1C,SAAgB,gBAAgB;AAEhC,SAAS,qBAAqB,oBAAoB;AAClD,SAAS,aAAa;AAEf,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAGM;AACJ,QAAM,YAAY,aAAa;AAC/B,QAAM,eAAe,oBAAoB;AACzC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAwB,IAAI;AAGpD,4BAA0B,MAAM;AAC9B,QAAI,UAAU,WAAW,MAAM,GAAG;AAChC,cAAQ,OAAO;AAAA,IACjB,WAAW,UAAU,WAAW,OAAO,GAAG;AACxC,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,cAAc,SAAS,CAAC;AAE5B,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC;AAAA,IAAM;AAAA,IAAa;AAAA,GAAS;AACtC;",
6
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.216",
3
+ "version": "1.0.1-beta.218",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/cjs",
6
6
  "module": "dist/esm",
@@ -28,30 +28,30 @@
28
28
  ],
29
29
  "dependencies": {
30
30
  "@expo/match-media": "^0.3.0",
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"
31
+ "@tamagui/compose-refs": "^1.0.1-beta.218",
32
+ "@tamagui/constants": "^1.0.1-beta.218",
33
+ "@tamagui/helpers": "^1.0.1-beta.218",
34
+ "@tamagui/normalize-css-color-lite": "^1.0.1-beta.218",
35
+ "@tamagui/react-native-use-pressable": "^1.0.1-beta.218",
36
+ "@tamagui/react-native-use-responder-events": "^1.0.1-beta.218",
37
+ "@tamagui/types-react-native": "^1.0.1-beta.218",
38
+ "@tamagui/use-did-finish-ssr": "^1.0.1-beta.218",
39
+ "@tamagui/use-event": "^1.0.1-beta.218",
40
+ "@tamagui/use-force-update": "^1.0.1-beta.218"
41
41
  },
42
42
  "peerDependencies": {
43
- "react": "*",
44
- "react-dom": "*"
43
+ "react": ">=18",
44
+ "react-dom": ">=18"
45
45
  },
46
46
  "devDependencies": {
47
- "@tamagui/build": "^1.0.1-beta.216",
47
+ "@tamagui/build": "^1.0.1-beta.218",
48
48
  "@types/node": "^16.11.9",
49
49
  "@types/react": "^18.0.15",
50
50
  "@types/react-native": "^0.69.2",
51
51
  "csstype": "^3.0.10",
52
52
  "esbuild": "^0.15.11",
53
- "react": "*",
54
- "react-dom": "*",
53
+ "react": ">=18",
54
+ "react-dom": ">=18",
55
55
  "typescript": "^4.7.4",
56
56
  "vitest": "^0.24.3"
57
57
  },
@@ -1,5 +1,5 @@
1
1
  import { useComposedRefs } from '@tamagui/compose-refs'
2
- import { isClient, isRSC, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
2
+ import { isClient, isRSC, isServer, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
3
3
  /* eslint-disable react-hooks/rules-of-hooks */
4
4
  import {
5
5
  composeEventHandlers,
@@ -29,23 +29,18 @@ import { stackDefaultStyles } from './constants/constants'
29
29
  import { FontLanguageContext } from './contexts/FontLanguageContext'
30
30
  import { TextAncestorContext } from './contexts/TextAncestorContext'
31
31
  import { extendStaticConfig, parseStaticConfig } from './helpers/extendStaticConfig'
32
- import {
33
- SplitStyleResult,
34
- getSubStyle,
35
- insertSplitStyles,
36
- useSplitStyles,
37
- } from './helpers/getSplitStyles'
32
+ import { getSubStyle, useSplitStyles } from './helpers/getSplitStyles'
38
33
  import { getAllSelectors } from './helpers/insertStyleRule'
39
34
  import { mergeProps } from './helpers/mergeProps'
40
35
  import { mergeTransform } from './helpers/mergeTransform'
41
36
  import { proxyThemeVariables } from './helpers/proxyThemeVariables'
42
- import { pseudoDescriptors } from './helpers/pseudoDescriptors'
43
37
  import { useShallowSetState } from './helpers/useShallowSetState'
44
38
  import { getRect, measureLayout, useElementLayout } from './hooks/useElementLayout'
45
39
  import { addMediaQueryListener, getInitialMediaState } from './hooks/useMedia'
46
40
  import { useServerRef, useServerState } from './hooks/useServerHooks'
47
41
  import { getThemeManager, useTheme } from './hooks/useTheme'
48
42
  import {
43
+ DebugProp,
49
44
  SpaceDirection,
50
45
  SpaceTokens,
51
46
  SpacerProps,
@@ -140,7 +135,6 @@ export function createComponent<
140
135
  let defaultNativeStyle: any
141
136
  let tamaguiDefaultProps: any
142
137
  let defaultTag: string | undefined
143
- let initialSplitStyles: SplitStyleResult
144
138
 
145
139
  // see onConfiguredOnce below which attaches a name then to this component
146
140
  const component = forwardRef<Ref, ComponentPropTypes>((propsIn: any, forwardedRef) => {
@@ -157,7 +151,7 @@ export function createComponent<
157
151
 
158
152
  // time`mergeProps`
159
153
 
160
- const debugProp = props['debug']
154
+ const debugProp = props['debug'] as DebugProp
161
155
  const { Component, isText, isZStack } = staticConfig
162
156
  const componentName = props.componentName || staticConfig.componentName
163
157
  const componentClassName = props.asChild
@@ -194,7 +188,7 @@ export function createComponent<
194
188
  )
195
189
 
196
190
  if (process.env.NODE_ENV === 'development') {
197
- if (props['debug']) {
191
+ if (debugProp) {
198
192
  const name = `${
199
193
  componentName || Component?.displayName || Component?.name || '[Unnamed Component]'
200
194
  }`
@@ -203,13 +197,28 @@ export function createComponent<
203
197
  const banner = `${name}${dataIs ? ` ${dataIs}` : ''} ${type}`
204
198
  // eslint-disable-next-line no-console
205
199
  console.group(`%c ${banner}`, 'background: yellow;')
206
- // eslint-disable-next-line no-console
207
- console.log(`state`, state)
200
+ if (!isServer) {
201
+ // eslint-disable-next-line no-console
202
+ console.log(`state`, state)
203
+ // eslint-disable-next-line no-console
204
+ console.groupCollapsed('props')
205
+ // eslint-disable-next-line no-console
206
+ console.log(props)
207
+ // eslint-disable-next-line no-console
208
+ console.log('order', Object.keys(props))
209
+ // eslint-disable-next-line no-console
210
+ console.groupEnd()
211
+ }
208
212
  }
209
213
  }
210
214
 
215
+ const shouldAvoidClasses =
216
+ !isWeb || !!(props.animation && avoidClassesWhileAnimating) || !staticConfig.acceptsClassName
217
+ const shouldForcePseudo = !!propsIn.forceStyle
218
+ const noClassNames = shouldAvoidClasses || shouldForcePseudo
219
+
211
220
  const forceUpdate = useForceUpdate()
212
- const theme = useTheme(props.theme, componentName, props, forceUpdate)
221
+ const theme = useTheme(props.theme, componentName, props, forceUpdate, !noClassNames)
213
222
 
214
223
  const shouldSetMounted = needsMount && state.unmounted
215
224
  const setMounted = shouldSetMounted
@@ -226,12 +235,7 @@ export function createComponent<
226
235
  }
227
236
  : undefined
228
237
 
229
- const shouldAvoidClasses =
230
- !isWeb || !!(props.animation && avoidClassesWhileAnimating) || !staticConfig.acceptsClassName
231
-
232
- const shouldForcePseudo = !!propsIn.forceStyle
233
238
  const hasTextAncestor = !!(isWeb && isText ? useContext(TextAncestorContext) : false)
234
- const noClassNames = shouldAvoidClasses || shouldForcePseudo
235
239
  const languageContext = isRSC ? null : useContext(FontLanguageContext)
236
240
  const isDisabled = props.disabled ?? props.accessibilityState?.disabled
237
241
 
@@ -254,19 +258,18 @@ export function createComponent<
254
258
 
255
259
  // time`setupStateConf`
256
260
 
257
- const splitStyleState: SplitStyleState = {
258
- ...state,
259
- noClassNames,
260
- dynamicStylesInline: noClassNames,
261
- hasTextAncestor,
262
- resolveVariablesAs: 'value',
263
- }
264
261
  const splitStyles = useSplitStyles(
265
262
  props,
266
263
  staticConfig,
267
264
  theme,
268
- splitStyleState,
269
- props.asChild ? null : initialSplitStyles,
265
+ {
266
+ ...state,
267
+ noClassNames,
268
+ dynamicStylesInline: noClassNames,
269
+ hasTextAncestor,
270
+ resolveVariablesAs: 'value',
271
+ },
272
+ null,
270
273
  languageContext || undefined,
271
274
  elementType,
272
275
  debugProp
@@ -593,7 +596,7 @@ export function createComponent<
593
596
  }, [unPress])
594
597
  }
595
598
 
596
- let styles: any[]
599
+ let styles: Record<string, any>[]
597
600
 
598
601
  if (isStringElement && shouldAvoidClasses && !shouldForcePseudo) {
599
602
  styles = {
@@ -607,11 +610,7 @@ export function createComponent<
607
610
  // ugly but for now...
608
611
  if (shouldForcePseudo) {
609
612
  const next = {}
610
- for (const style of styles) {
611
- if (style) {
612
- Object.assign(next, style)
613
- }
614
- }
613
+ styles.forEach((style) => Object.assign(next, style))
615
614
  // @ts-ignore
616
615
  Object.assign(splitStyles.style, next)
617
616
  }
@@ -677,6 +676,8 @@ export function createComponent<
677
676
  for (const style of styles) {
678
677
  if (style?.fontFamily) {
679
678
  style.fontFamily = overrideFace
679
+ delete style.fontWeight
680
+ delete style.fontStyle
680
681
  }
681
682
  }
682
683
  }
@@ -687,16 +688,11 @@ export function createComponent<
687
688
  viewProps.style = styles
688
689
  }
689
690
 
690
- // TODO need to loop active variants and see if they have matchin pseudos and apply as well
691
- const initialPseudos = initialSplitStyles?.pseudos
692
- const runtimePressStyle = noClassNames && (pseudos?.pressStyle || initialPseudos?.pressStyle)
691
+ const runtimePressStyle = !disabled && noClassNames && pseudos?.pressStyle
693
692
  const attachPress = !!(runtimePressStyle || onPress || onPressOut || onPressIn || onClick)
694
-
695
- const isHoverable = isWeb
696
- const runtimeHoverStyle = noClassNames && (pseudos?.hoverStyle || initialPseudos.hoverStyle)
697
- const attachHover =
698
- isHoverable &&
699
- !!(runtimeHoverStyle || onHoverIn || onHoverOut || onMouseEnter || onMouseLeave)
693
+ const runtimeHoverStyle = !disabled && noClassNames && pseudos?.hoverStyle
694
+ const isHoverable =
695
+ isWeb && !!(runtimeHoverStyle || onHoverIn || onHoverOut || onMouseEnter || onMouseLeave)
700
696
 
701
697
  const handlesPressEvents = !isWeb && !asChild
702
698
 
@@ -706,7 +702,7 @@ export function createComponent<
706
702
  ? false
707
703
  : Boolean(
708
704
  attachPress ||
709
- attachHover ||
705
+ isHoverable ||
710
706
  'pressStyle' in props ||
711
707
  'onPress' in props ||
712
708
  'onPressIn' in props ||
@@ -729,28 +725,28 @@ export function createComponent<
729
725
  onMouseUp?.(e)
730
726
  }
731
727
  : undefined,
732
- ...(attachHover && {
733
- onMouseEnter: attachHover
728
+ ...(isHoverable && {
729
+ onMouseEnter: isHoverable
734
730
  ? (e) => {
735
731
  const next: Partial<typeof state> = {}
736
- if (attachHover) {
732
+ if (isHoverable) {
737
733
  next.hover = true
738
734
  }
739
735
  if (state.pressIn) {
740
736
  next.press = true
741
737
  }
742
- if (attachHover || state.pressIn) {
738
+ if (isHoverable || state.pressIn) {
743
739
  setStateShallow(next)
744
740
  }
745
741
  onHoverIn?.(e)
746
742
  onMouseEnter?.(e)
747
743
  }
748
744
  : undefined,
749
- onMouseLeave: attachHover
745
+ onMouseLeave: isHoverable
750
746
  ? (e) => {
751
747
  const next: Partial<typeof state> = {}
752
748
  mouseUps.add(unPress)
753
- if (attachHover) {
749
+ if (isHoverable) {
754
750
  next.hover = false
755
751
  }
756
752
  if (state.pressIn) {
@@ -855,7 +851,7 @@ export function createComponent<
855
851
  // EVENTS native
856
852
  if (process.env.TAMAGUI_TARGET === 'native') {
857
853
  // add focus events
858
- const attachFocus = !!(pseudos.focusStyle || (initialPseudos && initialPseudos.focusStyle))
854
+ const attachFocus = !!pseudos.focusStyle
859
855
  if (attachFocus) {
860
856
  viewProps.onFocus = mergeEvent(viewProps.onFocus, () => {
861
857
  setStateShallow({ focus: true })
@@ -917,7 +913,7 @@ export function createComponent<
917
913
  if (typeof window !== 'undefined') {
918
914
  // prettier-ignore
919
915
  // eslint-disable-next-line no-console
920
- console.log({ state, shouldProvideThemeManager, isAnimated, isAnimatedReactNativeWeb, tamaguiDefaultProps, viewProps, splitStyles, animationStyles, handlesPressEvents, isStringElement, classNamesIn: props.className?.split(' '), classNamesOut: viewProps.className?.split(' '), events, shouldAttach, styles, pseudos, content, childEls, shouldAvoidClasses, avoidClasses: avoidClassesWhileAnimating, animation: props.animation, style: splitStylesStyle, defaultNativeStyle, initialSplitStyles, ...(typeof window !== 'undefined' ? { theme, themeClassName: theme.className, staticConfig, tamaguiConfig, events, shouldAvoidClasses, shouldForcePseudo, classNames: Object.fromEntries(Object.entries(classNames).map(([k, v]) => [v, getAllSelectors()[v]])) } : null) })
916
+ console.log({ state, shouldProvideThemeManager, isAnimated, isAnimatedReactNativeWeb, tamaguiDefaultProps, viewProps, splitStyles, animationStyles, handlesPressEvents, isStringElement, classNamesIn: props.className?.split(' '), classNamesOut: viewProps.className?.split(' '), events, shouldAttach, styles, pseudos, content, childEls, shouldAvoidClasses, avoidClasses: avoidClassesWhileAnimating, animation: props.animation, style: splitStylesStyle, defaultNativeStyle, ...(typeof window !== 'undefined' ? { theme, themeClassName: theme.className, staticConfig, tamaguiConfig, events, shouldAvoidClasses, shouldForcePseudo, classNames: Object.fromEntries(Object.entries(classNames).map(([k, v]) => [v, getAllSelectors()[v]])) } : null) })
921
917
  }
922
918
  // eslint-disable-next-line no-console
923
919
  console.groupEnd()
@@ -994,50 +990,22 @@ export function createComponent<
994
990
  const debug = defaultPropsIn['debug']
995
991
 
996
992
  // remove all classNames
997
- const [ourProps, ourClassNames] = mergeProps(defaultPropsIn, {}, true)
993
+ const [ourProps, ourClassNames] = mergeProps(defaultPropsIn, {})
998
994
 
999
995
  if (ourProps.tag) {
1000
996
  defaultTag = ourProps.tag
1001
997
  }
1002
998
 
1003
999
  const noClassNames = !staticConfig.acceptsClassName
1004
-
1005
- initialSplitStyles = insertSplitStyles(
1006
- ourProps,
1007
- staticConfig,
1008
- initialTheme,
1009
- {
1010
- unmounted: false,
1011
- hover: false,
1012
- press: false,
1013
- pressIn: false,
1014
- focus: false,
1015
- resolveVariablesAs: 'both',
1016
- noClassNames,
1017
- },
1018
- undefined,
1019
- undefined,
1020
- debug
1021
- )
1000
+ const { name, variants, defaultVariants, ...restProps } = ourProps
1022
1001
 
1023
1002
  // must preserve prop order
1024
1003
  // leave out className because we handle that already with initialSplitStyles.classNames
1025
1004
  // otherwise it confuses variant functions getting className props
1026
- const [defaults, defaultsClassnames] = mergeProps(
1027
- component.defaultProps as any,
1028
- isWeb
1029
- ? { ...initialSplitStyles.pseudos, ...initialSplitStyles.viewProps }
1030
- : initialSplitStyles.viewProps,
1031
- true
1032
- // conf.inverseShorthands
1033
- )
1034
-
1035
- // avoid passing className props to variants
1036
- initialSplitStyles.classNames = {
1037
- ...defaultsClassnames,
1038
- ...initialSplitStyles.classNames,
1039
- ...ourClassNames,
1040
- }
1005
+ const [defaults, defaultsClassnames] = mergeProps(component.defaultProps as any, {
1006
+ ...defaultVariants,
1007
+ ...restProps,
1008
+ })
1041
1009
 
1042
1010
  defaultNativeStyle = {}
1043
1011
 
@@ -1056,40 +1024,15 @@ export function createComponent<
1056
1024
  }
1057
1025
  }
1058
1026
 
1059
- if (Object.keys(defaults).length) {
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
- }
1072
- }
1027
+ // set to global
1028
+ tamaguiDefaultProps = defaults
1073
1029
 
1074
1030
  // add debug logs
1075
1031
  if (process.env.NODE_ENV === 'development' && debug) {
1076
1032
  if (process.env.IS_STATIC !== 'is_static') {
1033
+ // prettier-ignore
1077
1034
  // eslint-disable-next-line no-console
1078
- console.log(`🐛 [${staticConfig.componentName || 'Component'}]`, {
1079
- staticConfig,
1080
- initialSplitStyles,
1081
- tamaguiDefaultProps,
1082
- defaultNativeStyle,
1083
- defaults,
1084
- defaultPropsIn,
1085
- defaultPropsKeyOrder: Object.keys(staticConfig.defaultProps),
1086
- defaultPropsInKeyOrder: Object.keys(defaultPropsIn).map((k) => [k, defaultPropsIn[k]]),
1087
- ourProps,
1088
- ourClassNames,
1089
- defaultsClassnames,
1090
- defaultTag,
1091
- noClassNames,
1092
- })
1035
+ console.log(`🐛 [${staticConfig.componentName || 'Component'}]`, { staticConfig, tamaguiDefaultProps, defaultNativeStyle, defaults, defaultPropsIn, defaultPropsKeyOrder: Object.keys(staticConfig.defaultProps), defaultPropsInKeyOrder: Object.keys(defaultPropsIn).map((k) => [k, defaultPropsIn[k]]), ourProps, ourClassNames, defaultsClassnames, defaultTag, noClassNames, })
1093
1036
  }
1094
1037
  }
1095
1038
  })
@@ -195,8 +195,8 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
195
195
  tokensParsed,
196
196
  parsed: true,
197
197
  getCSS: () => `
198
- .is_Text .is_Text { display: inline-flex; }
199
- ._dsp_contents { display: contents; }
198
+ .is_Text .is_Text {display:inline-flex;}
199
+ ._dsp_contents {display:contents;}
200
200
  ${themeConfig.css}
201
201
  ${getAllRules().join('\n')}
202
202
  `,