@tamagui/web 1.13.4 → 1.14.0

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 (47) hide show
  1. package/dist/cjs/createComponent.js +2 -2
  2. package/dist/cjs/createComponent.js.map +3 -3
  3. package/dist/cjs/helpers/ThemeManager.js +1 -1
  4. package/dist/cjs/helpers/ThemeManager.js.map +3 -3
  5. package/dist/cjs/helpers/getSplitStyles.js +2 -2
  6. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  7. package/dist/cjs/hooks/useTheme.js +1 -1
  8. package/dist/cjs/hooks/useTheme.js.map +3 -3
  9. package/dist/cjs/types.js.map +1 -1
  10. package/dist/cjs/views/Theme.js +1 -1
  11. package/dist/cjs/views/Theme.js.map +3 -3
  12. package/dist/esm/createComponent.js +2 -2
  13. package/dist/esm/createComponent.js.map +3 -3
  14. package/dist/esm/createComponent.mjs +2 -2
  15. package/dist/esm/createComponent.mjs.map +3 -3
  16. package/dist/esm/helpers/ThemeManager.js +1 -1
  17. package/dist/esm/helpers/ThemeManager.js.map +3 -3
  18. package/dist/esm/helpers/ThemeManager.mjs +1 -1
  19. package/dist/esm/helpers/ThemeManager.mjs.map +3 -3
  20. package/dist/esm/helpers/getSplitStyles.js +2 -2
  21. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  22. package/dist/esm/helpers/getSplitStyles.mjs +2 -2
  23. package/dist/esm/helpers/getSplitStyles.mjs.map +2 -2
  24. package/dist/esm/hooks/useTheme.js +1 -1
  25. package/dist/esm/hooks/useTheme.js.map +3 -3
  26. package/dist/esm/hooks/useTheme.mjs +1 -1
  27. package/dist/esm/hooks/useTheme.mjs.map +3 -3
  28. package/dist/esm/views/Theme.js +1 -1
  29. package/dist/esm/views/Theme.js.map +3 -3
  30. package/dist/esm/views/Theme.mjs +1 -1
  31. package/dist/esm/views/Theme.mjs.map +3 -3
  32. package/package.json +9 -9
  33. package/src/createComponent.tsx +38 -5
  34. package/src/helpers/ThemeManager.tsx +40 -32
  35. package/src/helpers/getSplitStyles.tsx +0 -8
  36. package/src/hooks/useTheme.tsx +145 -93
  37. package/src/types.tsx +2 -2
  38. package/src/views/Theme.tsx +49 -27
  39. package/types/createComponent.d.ts.map +1 -1
  40. package/types/helpers/ThemeManager.d.ts +1 -0
  41. package/types/helpers/ThemeManager.d.ts.map +1 -1
  42. package/types/helpers/getSplitStyles.d.ts.map +1 -1
  43. package/types/hooks/useTheme.d.ts +5 -7
  44. package/types/hooks/useTheme.d.ts.map +1 -1
  45. package/types/types.d.ts +2 -2
  46. package/types/types.d.ts.map +1 -1
  47. package/types/views/Theme.d.ts.map +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/views/Theme.tsx"],
4
- "sourcesContent": ["import { isWeb } from '@tamagui/constants'\nimport { Children, cloneElement, isValidElement } from 'react'\n\nimport { variableToString } from '../createVariable.js'\nimport { ThemeManagerContext } from '../helpers/ThemeManagerContext.js'\nimport { useServerRef } from '../hooks/useServerHooks.js'\nimport { ChangedThemeResponse, useChangeThemeEffect } from '../hooks/useTheme.js'\nimport type { ThemeProps } from '../types.js'\n\nexport function Theme(props: ThemeProps) {\n // @ts-expect-error only for internal views\n if (props.disable) return props.children\n const isRoot = !!props['_isRoot']\n const themeState = useChangeThemeEffect(props, isRoot)\n const children = props['data-themeable']\n ? Children.map(props.children, (child) =>\n cloneElement(child, { ['data-themeable']: true })\n )\n : props.children\n\n return useThemedChildren(themeState, children, props, isRoot)\n}\n\nexport function useThemedChildren(\n themeState: ChangedThemeResponse,\n children: any,\n options: {\n forceClassName?: boolean\n shallow?: boolean\n passPropsToChildren?: boolean\n },\n isRoot = false\n) {\n const { themeManager, isNewTheme, className, theme } = themeState\n const { shallow, forceClassName } = options\n const hasEverThemed = useServerRef(false)\n if (isNewTheme) {\n hasEverThemed.current = true\n }\n\n if (isNewTheme || hasEverThemed.current || forceClassName || isRoot) {\n // be sure to memoize shouldReset to avoid reparenting\n let next = Children.toArray(children)\n\n // each children of these children wont get the theme\n if (shallow && themeManager) {\n next = next.map((child) => {\n return isValidElement(child)\n ? cloneElement(\n child,\n undefined,\n <Theme name={themeManager.state.parentName}>\n {(child as any).props.children}\n </Theme>\n )\n : child\n })\n }\n\n // tried this but themes css doesn't fully like it\n // if (shouldAttachClassName && options.passPropsToChildren) {\n // next = next.map((child: any) => {\n // const childStyle = child.props?.style\n // console.log('pass it down', className, child.props.className || '')\n // const newProps = {\n // className: (child.props.className || '') + ' ' + className,\n // style: Array.isArray(childStyle)\n // ? [colorStyle, ...childStyle]\n // : {\n // ...colorStyle,\n // ...childStyle,\n // },\n // }\n // return isValidElement(child) ? cloneElement(child as any, newProps) : child\n // })\n // }\n\n const wrapped = (\n <ThemeManagerContext.Provider value={themeManager}>\n {next}\n </ThemeManagerContext.Provider>\n )\n\n if (forceClassName === false) {\n return wrapped\n }\n\n if (isWeb && !options.passPropsToChildren) {\n // in order to provide currentColor, set color by default\n const themeColor = theme && isNewTheme ? variableToString(theme.color) : ''\n const colorStyle = {\n color: themeColor,\n }\n\n return (\n <span className={`${className || ''} _dsp_contents`} style={colorStyle}>\n {wrapped}\n </span>\n )\n }\n\n return wrapped\n }\n\n return children\n}\n"],
5
- "mappings": "AAmDc,cAAAA,MAAA,oBAnDd,OAAS,SAAAC,MAAa,qBACtB,OAAS,YAAAC,EAAU,gBAAAC,EAAc,kBAAAC,MAAsB,QAEvD,OAAS,oBAAAC,MAAwB,uBACjC,OAAS,uBAAAC,MAA2B,oCACpC,OAAS,gBAAAC,MAAoB,6BAC7B,OAA+B,wBAAAC,MAA4B,uBAGpD,SAASC,EAAMC,EAAmB,CAEvC,GAAIA,EAAM,QAAS,OAAOA,EAAM,SAChC,MAAMC,EAAS,CAAC,CAACD,EAAM,QACjBE,EAAaJ,EAAqBE,EAAOC,CAAM,EAC/CE,EAAWH,EAAM,gBAAgB,EACnCR,EAAS,IAAIQ,EAAM,SAAWI,GAC5BX,EAAaW,EAAO,CAAE,CAAC,gBAAgB,EAAG,EAAK,CAAC,CAClD,EACAJ,EAAM,SAEV,OAAOK,EAAkBH,EAAYC,EAAUH,EAAOC,CAAM,CAC9D,CAEO,SAASI,EACdH,EACAC,EACAG,EAKAL,EAAS,GACT,CACA,KAAM,CAAE,aAAAM,EAAc,WAAAC,EAAY,UAAAC,EAAW,MAAAC,CAAM,EAAIR,EACjD,CAAE,QAAAS,EAAS,eAAAC,CAAe,EAAIN,EAC9BO,EAAgBhB,EAAa,EAAK,EAKxC,GAJIW,IACFK,EAAc,QAAU,IAGtBL,GAAcK,EAAc,SAAWD,GAAkBX,EAAQ,CAEnE,IAAIa,EAAOtB,EAAS,QAAQW,CAAQ,EAGhCQ,GAAWJ,IACbO,EAAOA,EAAK,IAAKV,GACRV,EAAeU,CAAK,EACvBX,EACEW,EACA,OACAd,EAACS,EAAA,CAAM,KAAMQ,EAAa,MAAM,WAC5B,SAAAH,EAAc,MAAM,SACxB,CACF,EACAA,CACL,GAqBH,MAAMW,EACJzB,EAACM,EAAoB,SAApB,CAA6B,MAAOW,EAClC,SAAAO,EACH,EAGF,GAAIF,IAAmB,GACrB,OAAOG,EAGT,GAAIxB,GAAS,CAACe,EAAQ,oBAAqB,CAGzC,MAAMU,EAAa,CACjB,MAFiBN,GAASF,EAAab,EAAiBe,EAAM,KAAK,EAAI,EAGzE,EAEA,OACEpB,EAAC,QAAK,UAAW,GAAGmB,GAAa,mBAAoB,MAAOO,EACzD,SAAAD,EACH,CAEJ,CAEA,OAAOA,CACT,CAEA,OAAOZ,CACT",
6
- "names": ["jsx", "isWeb", "Children", "cloneElement", "isValidElement", "variableToString", "ThemeManagerContext", "useServerRef", "useChangeThemeEffect", "Theme", "props", "isRoot", "themeState", "children", "child", "useThemedChildren", "options", "themeManager", "isNewTheme", "className", "theme", "shallow", "forceClassName", "hasEverThemed", "next", "wrapped", "colorStyle"]
4
+ "sourcesContent": ["import { isWeb } from '@tamagui/constants'\nimport { Children, cloneElement, isValidElement, useEffect, useId, useMemo } from 'react'\n\nimport { variableToString } from '../createVariable.js'\nimport { ThemeManagerContext } from '../helpers/ThemeManagerContext.js'\nimport { useServerRef } from '../hooks/useServerHooks.js'\nimport { ChangedThemeResponse, useChangeThemeEffect } from '../hooks/useTheme.js'\nimport type { ThemeProps } from '../types.js'\n\nexport function Theme(props: ThemeProps) {\n // @ts-expect-error only for internal views\n if (props.disable) {\n return props.children\n }\n\n const isRoot = !!props['_isRoot']\n const themeState = useChangeThemeEffect(props, isRoot)\n\n let children = props['data-themeable']\n ? Children.map(props.children, (child) =>\n cloneElement(child, { ['data-themeable']: true })\n )\n : props.children\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug'] === 'visualize') {\n children = (\n <div style={{ display: 'inline', border: '1px solid #ccc' }}>\n <code>\n <pre>\n &lt;Theme /&gt;&nbsp;\n {JSON.stringify({\n name: themeState.themeManager?.state.name,\n parent: themeState.themeManager?.state.parentName,\n id: themeState.themeManager?.id,\n parentId: themeState.themeManager?.parentManager?.id,\n isNew: themeState.isNewTheme,\n })}\n </pre>\n </code>\n {children}\n </div>\n )\n }\n }\n\n return useThemedChildren(themeState, children, props, isRoot)\n}\n\nexport function useThemedChildren(\n themeState: ChangedThemeResponse,\n children: any,\n options: {\n forceClassName?: boolean\n shallow?: boolean\n passPropsToChildren?: boolean\n },\n isRoot = false\n) {\n const { themeManager, className, theme, isNewTheme } = themeState\n const { shallow, forceClassName } = options\n const hasEverThemed = useServerRef(false)\n if (isNewTheme) {\n hasEverThemed.current = true\n }\n\n const shouldRenderChildrenWithTheme =\n isNewTheme || hasEverThemed.current || forceClassName || isRoot\n\n return useMemo(() => {\n // console.warn(`re-render Theme`)\n\n if (!shouldRenderChildrenWithTheme) {\n return children\n }\n\n // be sure to memoize shouldReset to avoid reparenting\n let next = Children.toArray(children)\n\n // each children of these children wont get the theme\n if (shallow && themeManager) {\n next = next.map((child) => {\n return isValidElement(child)\n ? cloneElement(\n child,\n undefined,\n <Theme name={themeManager.state.parentName}>\n {(child as any).props.children}\n </Theme>\n )\n : child\n })\n }\n\n const wrapped = (\n <ThemeManagerContext.Provider value={themeManager}>\n {next}\n </ThemeManagerContext.Provider>\n )\n\n if (forceClassName === false) {\n return wrapped\n }\n\n if (isWeb && !options.passPropsToChildren) {\n // in order to provide currentColor, set color by default\n const themeColor = theme && isNewTheme ? variableToString(theme.color) : ''\n const colorStyle = {\n color: themeColor,\n }\n\n return (\n <span className={`${className || ''} _dsp_contents is_Theme`} style={colorStyle}>\n {wrapped}\n </span>\n )\n }\n\n return wrapped\n }, [\n shouldRenderChildrenWithTheme,\n themeManager,\n children,\n theme,\n isNewTheme,\n className,\n ])\n}\n"],
5
+ "mappings": "AA4BU,cAAAA,EACE,QAAAC,MADF,oBA5BV,OAAS,SAAAC,MAAa,qBACtB,OAAS,YAAAC,EAAU,gBAAAC,EAAc,kBAAAC,EAAkC,WAAAC,MAAe,QAElF,OAAS,oBAAAC,MAAwB,uBACjC,OAAS,uBAAAC,MAA2B,oCACpC,OAAS,gBAAAC,MAAoB,6BAC7B,OAA+B,wBAAAC,MAA4B,uBAGpD,SAASC,EAAMC,EAAmB,CATzC,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAWE,GAAIL,EAAM,QACR,OAAOA,EAAM,SAGf,MAAMM,EAAS,CAAC,CAACN,EAAM,QACjBO,EAAaT,EAAqBE,EAAOM,CAAM,EAErD,IAAIE,EAAWR,EAAM,gBAAgB,EACjCT,EAAS,IAAIS,EAAM,SAAWS,GAC5BjB,EAAaiB,EAAO,CAAE,CAAC,gBAAgB,EAAG,EAAK,CAAC,CAClD,EACAT,EAAM,SAEV,OAAI,QAAQ,IAAI,WAAa,eACvBA,EAAM,QAAa,cACrBQ,EACEnB,EAAC,OAAI,MAAO,CAAE,QAAS,SAAU,OAAQ,gBAAiB,EACxD,UAAAD,EAAC,QACC,SAAAC,EAAC,OAAI,0BAEF,KAAK,UAAU,CACd,MAAMY,EAAAM,EAAW,eAAX,YAAAN,EAAyB,MAAM,KACrC,QAAQC,EAAAK,EAAW,eAAX,YAAAL,EAAyB,MAAM,WACvC,IAAIC,EAAAI,EAAW,eAAX,YAAAJ,EAAyB,GAC7B,UAAUE,GAAAD,EAAAG,EAAW,eAAX,YAAAH,EAAyB,gBAAzB,YAAAC,EAAwC,GAClD,MAAOE,EAAW,UACpB,CAAC,GACH,EACF,EACCC,GACH,GAKCE,EAAkBH,EAAYC,EAAUR,EAAOM,CAAM,CAC9D,CAEO,SAASI,EACdH,EACAC,EACAG,EAKAL,EAAS,GACT,CACA,KAAM,CAAE,aAAAM,EAAc,UAAAC,EAAW,MAAAC,EAAO,WAAAC,CAAW,EAAIR,EACjD,CAAE,QAAAS,EAAS,eAAAC,CAAe,EAAIN,EAC9BO,EAAgBrB,EAAa,EAAK,EACpCkB,IACFG,EAAc,QAAU,IAG1B,MAAMC,EACJJ,GAAcG,EAAc,SAAWD,GAAkBX,EAE3D,OAAOZ,EAAQ,IAAM,CAGnB,GAAI,CAACyB,EACH,OAAOX,EAIT,IAAIY,EAAO7B,EAAS,QAAQiB,CAAQ,EAGhCQ,GAAWJ,IACbQ,EAAOA,EAAK,IAAKX,GACRhB,EAAegB,CAAK,EACvBjB,EACEiB,EACA,OACArB,EAACW,EAAA,CAAM,KAAMa,EAAa,MAAM,WAC5B,SAAAH,EAAc,MAAM,SACxB,CACF,EACAA,CACL,GAGH,MAAMY,EACJjC,EAACQ,EAAoB,SAApB,CAA6B,MAAOgB,EAClC,SAAAQ,EACH,EAGF,GAAIH,IAAmB,GACrB,OAAOI,EAGT,GAAI/B,GAAS,CAACqB,EAAQ,oBAAqB,CAGzC,MAAMW,EAAa,CACjB,MAFiBR,GAASC,EAAapB,EAAiBmB,EAAM,KAAK,EAAI,EAGzE,EAEA,OACE1B,EAAC,QAAK,UAAW,GAAGyB,GAAa,4BAA6B,MAAOS,EAClE,SAAAD,EACH,CAEJ,CAEA,OAAOA,CACT,EAAG,CACDF,EACAP,EACAJ,EACAM,EACAC,EACAF,CACF,CAAC,CACH",
6
+ "names": ["jsx", "jsxs", "isWeb", "Children", "cloneElement", "isValidElement", "useMemo", "variableToString", "ThemeManagerContext", "useServerRef", "useChangeThemeEffect", "Theme", "props", "_a", "_b", "_c", "_d", "_e", "isRoot", "themeState", "children", "child", "useThemedChildren", "options", "themeManager", "className", "theme", "isNewTheme", "shallow", "forceClassName", "hasEverThemed", "shouldRenderChildrenWithTheme", "next", "wrapped", "colorStyle"]
7
7
  }
@@ -1,2 +1,2 @@
1
- import{jsx as h}from"react/jsx-runtime";import{isWeb as b}from"@tamagui/constants";import{Children as d,cloneElement as u,isValidElement as g}from"react";import{variableToString as y}from"../createVariable.js";import{ThemeManagerContext as v}from"../helpers/ThemeManagerContext.js";import{useServerRef as N}from"../hooks/useServerHooks.js";import{useChangeThemeEffect as P}from"../hooks/useTheme.js";function R(e){if(e.disable)return e.children;const r=!!e._isRoot,n=P(e,r),a=e["data-themeable"]?d.map(e.children,t=>u(t,{["data-themeable"]:!0})):e.children;return w(n,a,e,r)}function w(e,r,n,a=!1){const{themeManager:t,isNewTheme:s,className:T,theme:i}=e,{shallow:p,forceClassName:f}=n,c=N(!1);if(s&&(c.current=!0),s||c.current||f||a){let m=d.toArray(r);p&&t&&(m=m.map(o=>g(o)?u(o,void 0,h(R,{name:t.state.parentName,children:o.props.children})):o));const l=h(v.Provider,{value:t,children:m});if(f===!1)return l;if(b&&!n.passPropsToChildren){const C={color:i&&s?y(i.color):""};return h("span",{className:`${T||""} _dsp_contents`,style:C,children:l})}return l}return r}export{R as Theme,w as useThemedChildren};
1
+ import{jsx as d,jsxs as C}from"react/jsx-runtime";import{isWeb as b}from"@tamagui/constants";import{Children as T,cloneElement as g,isValidElement as v,useMemo as y}from"react";import{variableToString as M}from"../createVariable.js";import{ThemeManagerContext as E}from"../helpers/ThemeManagerContext.js";import{useServerRef as w}from"../hooks/useServerHooks.js";import{useChangeThemeEffect as P}from"../hooks/useTheme.js";function R(e){var r,m,o,n,l;if(e.disable)return e.children;const a=!!e._isRoot,t=P(e,a);let s=e["data-themeable"]?T.map(e.children,h=>g(h,{["data-themeable"]:!0})):e.children;return process.env.NODE_ENV==="development"&&e.debug==="visualize"&&(s=C("div",{style:{display:"inline",border:"1px solid #ccc"},children:[d("code",{children:C("pre",{children:["<Theme />\xA0",JSON.stringify({name:(r=t.themeManager)==null?void 0:r.state.name,parent:(m=t.themeManager)==null?void 0:m.state.parentName,id:(o=t.themeManager)==null?void 0:o.id,parentId:(l=(n=t.themeManager)==null?void 0:n.parentManager)==null?void 0:l.id,isNew:t.isNewTheme})]})}),s]})),x(t,s,e,a)}function x(e,a,t,s=!1){const{themeManager:r,className:m,theme:o,isNewTheme:n}=e,{shallow:l,forceClassName:h}=t,u=w(!1);n&&(u.current=!0);const p=n||u.current||h||s;return y(()=>{if(!p)return a;let c=T.toArray(a);l&&r&&(c=c.map(i=>v(i)?g(i,void 0,d(R,{name:r.state.parentName,children:i.props.children})):i));const f=d(E.Provider,{value:r,children:c});if(h===!1)return f;if(b&&!t.passPropsToChildren){const N={color:o&&n?M(o.color):""};return d("span",{className:`${m||""} _dsp_contents is_Theme`,style:N,children:f})}return f},[p,r,a,o,n,m])}export{R as Theme,x as useThemedChildren};
2
2
  //# sourceMappingURL=Theme.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/views/Theme.tsx"],
4
- "sourcesContent": ["import { isWeb } from '@tamagui/constants'\nimport { Children, cloneElement, isValidElement } from 'react'\n\nimport { variableToString } from '../createVariable.js'\nimport { ThemeManagerContext } from '../helpers/ThemeManagerContext.js'\nimport { useServerRef } from '../hooks/useServerHooks.js'\nimport { ChangedThemeResponse, useChangeThemeEffect } from '../hooks/useTheme.js'\nimport type { ThemeProps } from '../types.js'\n\nexport function Theme(props: ThemeProps) {\n // @ts-expect-error only for internal views\n if (props.disable) return props.children\n const isRoot = !!props['_isRoot']\n const themeState = useChangeThemeEffect(props, isRoot)\n const children = props['data-themeable']\n ? Children.map(props.children, (child) =>\n cloneElement(child, { ['data-themeable']: true })\n )\n : props.children\n\n return useThemedChildren(themeState, children, props, isRoot)\n}\n\nexport function useThemedChildren(\n themeState: ChangedThemeResponse,\n children: any,\n options: {\n forceClassName?: boolean\n shallow?: boolean\n passPropsToChildren?: boolean\n },\n isRoot = false\n) {\n const { themeManager, isNewTheme, className, theme } = themeState\n const { shallow, forceClassName } = options\n const hasEverThemed = useServerRef(false)\n if (isNewTheme) {\n hasEverThemed.current = true\n }\n\n if (isNewTheme || hasEverThemed.current || forceClassName || isRoot) {\n // be sure to memoize shouldReset to avoid reparenting\n let next = Children.toArray(children)\n\n // each children of these children wont get the theme\n if (shallow && themeManager) {\n next = next.map((child) => {\n return isValidElement(child)\n ? cloneElement(\n child,\n undefined,\n <Theme name={themeManager.state.parentName}>\n {(child as any).props.children}\n </Theme>\n )\n : child\n })\n }\n\n // tried this but themes css doesn't fully like it\n // if (shouldAttachClassName && options.passPropsToChildren) {\n // next = next.map((child: any) => {\n // const childStyle = child.props?.style\n // console.log('pass it down', className, child.props.className || '')\n // const newProps = {\n // className: (child.props.className || '') + ' ' + className,\n // style: Array.isArray(childStyle)\n // ? [colorStyle, ...childStyle]\n // : {\n // ...colorStyle,\n // ...childStyle,\n // },\n // }\n // return isValidElement(child) ? cloneElement(child as any, newProps) : child\n // })\n // }\n\n const wrapped = (\n <ThemeManagerContext.Provider value={themeManager}>\n {next}\n </ThemeManagerContext.Provider>\n )\n\n if (forceClassName === false) {\n return wrapped\n }\n\n if (isWeb && !options.passPropsToChildren) {\n // in order to provide currentColor, set color by default\n const themeColor = theme && isNewTheme ? variableToString(theme.color) : ''\n const colorStyle = {\n color: themeColor,\n }\n\n return (\n <span className={`${className || ''} _dsp_contents`} style={colorStyle}>\n {wrapped}\n </span>\n )\n }\n\n return wrapped\n }\n\n return children\n}\n"],
5
- "mappings": "AAmDc,cAAAA,MAAA,oBAnDd,OAAS,SAAAC,MAAa,qBACtB,OAAS,YAAAC,EAAU,gBAAAC,EAAc,kBAAAC,MAAsB,QAEvD,OAAS,oBAAAC,MAAwB,uBACjC,OAAS,uBAAAC,MAA2B,oCACpC,OAAS,gBAAAC,MAAoB,6BAC7B,OAA+B,wBAAAC,MAA4B,uBAGpD,SAASC,EAAMC,EAAmB,CAEvC,GAAIA,EAAM,QAAS,OAAOA,EAAM,SAChC,MAAMC,EAAS,CAAC,CAACD,EAAM,QACjBE,EAAaJ,EAAqBE,EAAOC,CAAM,EAC/CE,EAAWH,EAAM,gBAAgB,EACnCR,EAAS,IAAIQ,EAAM,SAAWI,GAC5BX,EAAaW,EAAO,CAAE,CAAC,gBAAgB,EAAG,EAAK,CAAC,CAClD,EACAJ,EAAM,SAEV,OAAOK,EAAkBH,EAAYC,EAAUH,EAAOC,CAAM,CAC9D,CAEO,SAASI,EACdH,EACAC,EACAG,EAKAL,EAAS,GACT,CACA,KAAM,CAAE,aAAAM,EAAc,WAAAC,EAAY,UAAAC,EAAW,MAAAC,CAAM,EAAIR,EACjD,CAAE,QAAAS,EAAS,eAAAC,CAAe,EAAIN,EAC9BO,EAAgBhB,EAAa,EAAK,EAKxC,GAJIW,IACFK,EAAc,QAAU,IAGtBL,GAAcK,EAAc,SAAWD,GAAkBX,EAAQ,CAEnE,IAAIa,EAAOtB,EAAS,QAAQW,CAAQ,EAGhCQ,GAAWJ,IACbO,EAAOA,EAAK,IAAKV,GACRV,EAAeU,CAAK,EACvBX,EACEW,EACA,OACAd,EAACS,EAAA,CAAM,KAAMQ,EAAa,MAAM,WAC5B,SAAAH,EAAc,MAAM,SACxB,CACF,EACAA,CACL,GAqBH,MAAMW,EACJzB,EAACM,EAAoB,SAApB,CAA6B,MAAOW,EAClC,SAAAO,EACH,EAGF,GAAIF,IAAmB,GACrB,OAAOG,EAGT,GAAIxB,GAAS,CAACe,EAAQ,oBAAqB,CAGzC,MAAMU,EAAa,CACjB,MAFiBN,GAASF,EAAab,EAAiBe,EAAM,KAAK,EAAI,EAGzE,EAEA,OACEpB,EAAC,QAAK,UAAW,GAAGmB,GAAa,mBAAoB,MAAOO,EACzD,SAAAD,EACH,CAEJ,CAEA,OAAOA,CACT,CAEA,OAAOZ,CACT",
6
- "names": ["jsx", "isWeb", "Children", "cloneElement", "isValidElement", "variableToString", "ThemeManagerContext", "useServerRef", "useChangeThemeEffect", "Theme", "props", "isRoot", "themeState", "children", "child", "useThemedChildren", "options", "themeManager", "isNewTheme", "className", "theme", "shallow", "forceClassName", "hasEverThemed", "next", "wrapped", "colorStyle"]
4
+ "sourcesContent": ["import { isWeb } from '@tamagui/constants'\nimport { Children, cloneElement, isValidElement, useEffect, useId, useMemo } from 'react'\n\nimport { variableToString } from '../createVariable.js'\nimport { ThemeManagerContext } from '../helpers/ThemeManagerContext.js'\nimport { useServerRef } from '../hooks/useServerHooks.js'\nimport { ChangedThemeResponse, useChangeThemeEffect } from '../hooks/useTheme.js'\nimport type { ThemeProps } from '../types.js'\n\nexport function Theme(props: ThemeProps) {\n // @ts-expect-error only for internal views\n if (props.disable) {\n return props.children\n }\n\n const isRoot = !!props['_isRoot']\n const themeState = useChangeThemeEffect(props, isRoot)\n\n let children = props['data-themeable']\n ? Children.map(props.children, (child) =>\n cloneElement(child, { ['data-themeable']: true })\n )\n : props.children\n\n if (process.env.NODE_ENV === 'development') {\n if (props['debug'] === 'visualize') {\n children = (\n <div style={{ display: 'inline', border: '1px solid #ccc' }}>\n <code>\n <pre>\n &lt;Theme /&gt;&nbsp;\n {JSON.stringify({\n name: themeState.themeManager?.state.name,\n parent: themeState.themeManager?.state.parentName,\n id: themeState.themeManager?.id,\n parentId: themeState.themeManager?.parentManager?.id,\n isNew: themeState.isNewTheme,\n })}\n </pre>\n </code>\n {children}\n </div>\n )\n }\n }\n\n return useThemedChildren(themeState, children, props, isRoot)\n}\n\nexport function useThemedChildren(\n themeState: ChangedThemeResponse,\n children: any,\n options: {\n forceClassName?: boolean\n shallow?: boolean\n passPropsToChildren?: boolean\n },\n isRoot = false\n) {\n const { themeManager, className, theme, isNewTheme } = themeState\n const { shallow, forceClassName } = options\n const hasEverThemed = useServerRef(false)\n if (isNewTheme) {\n hasEverThemed.current = true\n }\n\n const shouldRenderChildrenWithTheme =\n isNewTheme || hasEverThemed.current || forceClassName || isRoot\n\n return useMemo(() => {\n // console.warn(`re-render Theme`)\n\n if (!shouldRenderChildrenWithTheme) {\n return children\n }\n\n // be sure to memoize shouldReset to avoid reparenting\n let next = Children.toArray(children)\n\n // each children of these children wont get the theme\n if (shallow && themeManager) {\n next = next.map((child) => {\n return isValidElement(child)\n ? cloneElement(\n child,\n undefined,\n <Theme name={themeManager.state.parentName}>\n {(child as any).props.children}\n </Theme>\n )\n : child\n })\n }\n\n const wrapped = (\n <ThemeManagerContext.Provider value={themeManager}>\n {next}\n </ThemeManagerContext.Provider>\n )\n\n if (forceClassName === false) {\n return wrapped\n }\n\n if (isWeb && !options.passPropsToChildren) {\n // in order to provide currentColor, set color by default\n const themeColor = theme && isNewTheme ? variableToString(theme.color) : ''\n const colorStyle = {\n color: themeColor,\n }\n\n return (\n <span className={`${className || ''} _dsp_contents is_Theme`} style={colorStyle}>\n {wrapped}\n </span>\n )\n }\n\n return wrapped\n }, [\n shouldRenderChildrenWithTheme,\n themeManager,\n children,\n theme,\n isNewTheme,\n className,\n ])\n}\n"],
5
+ "mappings": "AA4BU,cAAAA,EACE,QAAAC,MADF,oBA5BV,OAAS,SAAAC,MAAa,qBACtB,OAAS,YAAAC,EAAU,gBAAAC,EAAc,kBAAAC,EAAkC,WAAAC,MAAe,QAElF,OAAS,oBAAAC,MAAwB,uBACjC,OAAS,uBAAAC,MAA2B,oCACpC,OAAS,gBAAAC,MAAoB,6BAC7B,OAA+B,wBAAAC,MAA4B,uBAGpD,SAASC,EAAMC,EAAmB,CATzC,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAWE,GAAIL,EAAM,QACR,OAAOA,EAAM,SAGf,MAAMM,EAAS,CAAC,CAACN,EAAM,QACjBO,EAAaT,EAAqBE,EAAOM,CAAM,EAErD,IAAIE,EAAWR,EAAM,gBAAgB,EACjCT,EAAS,IAAIS,EAAM,SAAWS,GAC5BjB,EAAaiB,EAAO,CAAE,CAAC,gBAAgB,EAAG,EAAK,CAAC,CAClD,EACAT,EAAM,SAEV,OAAI,QAAQ,IAAI,WAAa,eACvBA,EAAM,QAAa,cACrBQ,EACEnB,EAAC,OAAI,MAAO,CAAE,QAAS,SAAU,OAAQ,gBAAiB,EACxD,UAAAD,EAAC,QACC,SAAAC,EAAC,OAAI,0BAEF,KAAK,UAAU,CACd,MAAMY,EAAAM,EAAW,eAAX,YAAAN,EAAyB,MAAM,KACrC,QAAQC,EAAAK,EAAW,eAAX,YAAAL,EAAyB,MAAM,WACvC,IAAIC,EAAAI,EAAW,eAAX,YAAAJ,EAAyB,GAC7B,UAAUE,GAAAD,EAAAG,EAAW,eAAX,YAAAH,EAAyB,gBAAzB,YAAAC,EAAwC,GAClD,MAAOE,EAAW,UACpB,CAAC,GACH,EACF,EACCC,GACH,GAKCE,EAAkBH,EAAYC,EAAUR,EAAOM,CAAM,CAC9D,CAEO,SAASI,EACdH,EACAC,EACAG,EAKAL,EAAS,GACT,CACA,KAAM,CAAE,aAAAM,EAAc,UAAAC,EAAW,MAAAC,EAAO,WAAAC,CAAW,EAAIR,EACjD,CAAE,QAAAS,EAAS,eAAAC,CAAe,EAAIN,EAC9BO,EAAgBrB,EAAa,EAAK,EACpCkB,IACFG,EAAc,QAAU,IAG1B,MAAMC,EACJJ,GAAcG,EAAc,SAAWD,GAAkBX,EAE3D,OAAOZ,EAAQ,IAAM,CAGnB,GAAI,CAACyB,EACH,OAAOX,EAIT,IAAIY,EAAO7B,EAAS,QAAQiB,CAAQ,EAGhCQ,GAAWJ,IACbQ,EAAOA,EAAK,IAAKX,GACRhB,EAAegB,CAAK,EACvBjB,EACEiB,EACA,OACArB,EAACW,EAAA,CAAM,KAAMa,EAAa,MAAM,WAC5B,SAAAH,EAAc,MAAM,SACxB,CACF,EACAA,CACL,GAGH,MAAMY,EACJjC,EAACQ,EAAoB,SAApB,CAA6B,MAAOgB,EAClC,SAAAQ,EACH,EAGF,GAAIH,IAAmB,GACrB,OAAOI,EAGT,GAAI/B,GAAS,CAACqB,EAAQ,oBAAqB,CAGzC,MAAMW,EAAa,CACjB,MAFiBR,GAASC,EAAapB,EAAiBmB,EAAM,KAAK,EAAI,EAGzE,EAEA,OACE1B,EAAC,QAAK,UAAW,GAAGyB,GAAa,4BAA6B,MAAOS,EAClE,SAAAD,EACH,CAEJ,CAEA,OAAOA,CACT,EAAG,CACDF,EACAP,EACAJ,EACAM,EACAC,EACAF,CACF,CAAC,CACH",
6
+ "names": ["jsx", "jsxs", "isWeb", "Children", "cloneElement", "isValidElement", "useMemo", "variableToString", "ThemeManagerContext", "useServerRef", "useChangeThemeEffect", "Theme", "props", "_a", "_b", "_c", "_d", "_e", "isRoot", "themeState", "children", "child", "useThemedChildren", "options", "themeManager", "className", "theme", "isNewTheme", "shallow", "forceClassName", "hasEverThemed", "shouldRenderChildrenWithTheme", "next", "wrapped", "colorStyle"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/web",
3
- "version": "1.13.4",
3
+ "version": "1.14.0",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/cjs",
6
6
  "module": "dist/esm",
@@ -27,19 +27,19 @@
27
27
  "reset.css"
28
28
  ],
29
29
  "dependencies": {
30
- "@tamagui/compose-refs": "1.13.4",
31
- "@tamagui/constants": "1.13.4",
32
- "@tamagui/helpers": "1.13.4",
33
- "@tamagui/normalize-css-color": "1.13.4",
34
- "@tamagui/use-did-finish-ssr": "1.13.4",
35
- "@tamagui/use-event": "1.13.4",
36
- "@tamagui/use-force-update": "1.13.4"
30
+ "@tamagui/compose-refs": "1.14.0",
31
+ "@tamagui/constants": "1.14.0",
32
+ "@tamagui/helpers": "1.14.0",
33
+ "@tamagui/normalize-css-color": "1.14.0",
34
+ "@tamagui/use-did-finish-ssr": "1.14.0",
35
+ "@tamagui/use-event": "1.14.0",
36
+ "@tamagui/use-force-update": "1.14.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "react": "*"
40
40
  },
41
41
  "devDependencies": {
42
- "@tamagui/build": "1.13.4",
42
+ "@tamagui/build": "1.14.0",
43
43
  "@testing-library/react": "^13.4.0",
44
44
  "csstype": "^3.0.10",
45
45
  "react": "^18.2.0",
@@ -12,6 +12,7 @@ import React, {
12
12
  useEffect,
13
13
  useId,
14
14
  useRef,
15
+ useState,
15
16
  } from 'react'
16
17
 
17
18
  import { onConfiguredOnce } from './config.js'
@@ -183,7 +184,9 @@ export function createComponent<
183
184
  didAccessThemeVariableValue?: boolean
184
185
  }
185
186
  )
186
- stateRef.current ??= {}
187
+ stateRef.current ||= {}
188
+
189
+ const hostRef = useServerRef<TamaguiElement>(null)
187
190
 
188
191
  /**
189
192
  * Component state for tracking animations, pseudos
@@ -290,9 +293,10 @@ export function createComponent<
290
293
  componentName,
291
294
  reset: props.reset,
292
295
  inverse: props.themeInverse,
293
- // @ts-expect-error
296
+ // @ts-ignore this is internal use only
294
297
  disable: props['data-themeable'],
295
- debug: props.debug,
298
+ debug:
299
+ process.env.NODE_ENV === 'development' && props.debug ? { hostRef } : undefined,
296
300
  shouldUpdate: () => !!stateRef.current.didAccessThemeVariableValue,
297
301
  })!
298
302
 
@@ -342,8 +346,6 @@ export function createComponent<
342
346
  keys: noClassNames && isMediaSpaced ? (splitStyles.hasMedia as any) : null,
343
347
  })
344
348
 
345
- const hostRef = useServerRef<TamaguiElement>(null)
346
-
347
349
  // animation setup
348
350
  const isAnimatedReactNativeWeb = isAnimated && avoidClassesWhileAnimating
349
351
 
@@ -730,6 +732,37 @@ export function createComponent<
730
732
  // passPropsToChildren: true,
731
733
  })
732
734
 
735
+ if (process.env.NODE_ENV === 'development') {
736
+ if (props['debug'] === 'visualize') {
737
+ const [onChangeCount, setOnChangeCount] = useState(0)
738
+
739
+ useEffect(() => {
740
+ themeState.themeManager?.onChangeTheme((name, manager) => {
741
+ setOnChangeCount((p) => ++p)
742
+ console.warn(`🖤`, name)
743
+ })
744
+ }, [themeState.themeManager])
745
+
746
+ content = (
747
+ <>
748
+ {content}
749
+ <code>
750
+ <pre>
751
+ {JSON.stringify({
752
+ name: themeState.themeManager?.state.name,
753
+ parent: themeState.themeManager?.state.parentName,
754
+ id: themeState.themeManager?.id,
755
+ parentId: themeState.themeManager?.parentManager?.id,
756
+ isNew: themeState.isNewTheme,
757
+ onChangeCount,
758
+ })}
759
+ </pre>
760
+ </code>
761
+ </>
762
+ )
763
+ }
764
+ }
765
+
733
766
  if (process.env.TAMAGUI_TARGET === 'web') {
734
767
  if (events || isAnimatedReactNativeWeb) {
735
768
  content = (
@@ -26,7 +26,10 @@ export function hasNoThemeUpdatingProps(props: ThemeProps) {
26
26
  return !(props.name || props.componentName || props.inverse || props.reset)
27
27
  }
28
28
 
29
+ let uid = 0
30
+
29
31
  export class ThemeManager {
32
+ id = uid++
30
33
  themeListeners = new Set<ThemeListener>()
31
34
  parentManager: ThemeManager | null = null
32
35
  state: ThemeManagerState = emptyState
@@ -41,26 +44,28 @@ export class ThemeManager {
41
44
  }
42
45
  if (!parentManager) {
43
46
  if (process.env.NODE_ENV !== 'production') {
44
- console.trace()
45
- throw new Error(`No parent manager given`)
47
+ throw new Error(
48
+ `No parent manager given, this is likely due to duplicated Tamagui dependencies. Check your lockfile for mis-matched versions.`
49
+ )
46
50
  }
47
51
  throw `❌`
48
52
  }
49
- // copy over listeners
50
- this.themeListeners = parentManager.themeListeners
51
53
 
52
54
  // no change no props
53
55
  if (hasNoThemeUpdatingProps(props)) {
54
56
  return parentManager
55
57
  }
58
+
56
59
  if (parentManager) {
57
60
  this.parentManager = parentManager
58
61
  }
62
+
59
63
  const updatedState = this.getStateIfChanged(props)
60
64
  if (updatedState) {
61
65
  this.state = updatedState
62
66
  return
63
67
  }
68
+
64
69
  return parentManager || this
65
70
  }
66
71
 
@@ -76,6 +81,7 @@ export class ThemeManager {
76
81
  }
77
82
  const nextState = this.getStateIfChanged(props)
78
83
  if (nextState) {
84
+ this.props = props
79
85
  this.state = nextState
80
86
  return true
81
87
  }
@@ -172,24 +178,20 @@ function getNextThemeClassName(name: string, isInverting = false) {
172
178
  return next.replace('light_', '').replace('dark_', '')
173
179
  }
174
180
 
175
- const cache = new WeakMap<ThemeProps, [ThemeManager, ThemeManagerState | null]>()
176
-
177
181
  function getState(
178
182
  props: ThemeProps,
179
183
  parentManager?: ThemeManager | null
180
184
  ): ThemeManagerState | null {
181
- const cached = cache.get(props)
182
- if (cached && cached[0] === parentManager) {
183
- return cached[1]
184
- }
185
-
186
185
  const themes = getThemes()
187
186
 
188
187
  if (props.name && props.reset) {
189
188
  throw new Error('Cannot reset + set new name')
190
189
  }
190
+
191
191
  if (props.reset && !parentManager?.parentManager) {
192
- console.warn('Cannot reset no grandparent exists')
192
+ if (process.env.NODE_ENV === 'development') {
193
+ console.warn('Cannot reset no grandparent exists')
194
+ }
193
195
  return null
194
196
  }
195
197
 
@@ -204,12 +206,12 @@ function getState(
204
206
  // components look for most specific, fallback upwards
205
207
  const base = parentName.split(THEME_NAME_SEPARATOR)
206
208
  const lastSegment = base[base.length - 1]
207
- const isParentAComponentTheme =
209
+ const isParentComponentTheme =
208
210
  parentName && lastSegment[0].toUpperCase() === lastSegment[0]
209
- if (isParentAComponentTheme) {
211
+ if (isParentComponentTheme) {
210
212
  base.pop() // always remove componentName they can't nest
211
213
  }
212
- const parentBaseTheme = isParentAComponentTheme
214
+ const parentBaseTheme = isParentComponentTheme
213
215
  ? base.slice(0, base.length).join(THEME_NAME_SEPARATOR)
214
216
  : parentName
215
217
  const max = base.length
@@ -218,9 +220,18 @@ function getState(
218
220
  ? max // component name only don't search upwards
219
221
  : 0
220
222
 
221
- // prettier-ignore
222
223
  // eslint-disable-next-line no-console
223
- if (process.env.NODE_ENV === 'development' && props.debug === 'verbose') [ console.groupCollapsed('ThemeManager.getState()', props, { parentName, parentBaseTheme, base, min, max, isParentAComponentTheme }), console.trace(), console.groupEnd() ]
224
+ if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {
225
+ console.groupCollapsed('ThemeManager.getState()')
226
+ console.log({
227
+ parentName,
228
+ parentBaseTheme,
229
+ base,
230
+ min,
231
+ max,
232
+ isParentComponentTheme,
233
+ })
234
+ }
224
235
 
225
236
  for (let i = max; i >= min; i--) {
226
237
  let prefix = base.slice(0, i).join(THEME_NAME_SEPARATOR)
@@ -243,12 +254,8 @@ function getState(
243
254
  if (componentName) {
244
255
  // components only look for component themes
245
256
  if (nextName) {
246
- potentials.push(
247
- `${prefix.slice(
248
- 0,
249
- prefix.indexOf(THEME_NAME_SEPARATOR)
250
- )}_${nextName}_${componentName}`
251
- )
257
+ const beforeSeparator = prefix.slice(0, prefix.indexOf(THEME_NAME_SEPARATOR))
258
+ potentials.push(`${beforeSeparator}_${nextName}_${componentName}`)
252
259
  }
253
260
  potentials.push(`${prefix}_${componentName}`)
254
261
  if (nextName) {
@@ -258,15 +265,11 @@ function getState(
258
265
 
259
266
  const found = potentials.find((t) => t in themes)
260
267
 
261
- // eslint-disable-next-line no-console
262
- if (process.env.NODE_ENV === 'development' && props.debug === 'verbose')
263
- console.log('getState found', found, 'from', potentials, 'parentName', parentName)
268
+ if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {
269
+ console.log(' - ', { found, potentials })
270
+ }
264
271
 
265
272
  if (found) {
266
- // optimization return null if not changed
267
- if (found === parentName) {
268
- break
269
- }
270
273
  result = {
271
274
  name: found,
272
275
  theme: getThemeUnwrapped(themes[found]),
@@ -277,8 +280,13 @@ function getState(
277
280
  }
278
281
  }
279
282
 
280
- if (parentManager) {
281
- cache.set(props, [parentManager, result])
283
+ // eslint-disable-next-line no-console
284
+ if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {
285
+ console.log({
286
+ result,
287
+ })
288
+ console.trace()
289
+ console.groupEnd()
282
290
  }
283
291
 
284
292
  return result
@@ -881,14 +881,6 @@ export const getSplitStyles: StyleSplitter = (
881
881
  // always do this at the very end to preserve the order strictly (animations, origin)
882
882
  // and allow proper merging of all pseudos before applying
883
883
  if (flatTransforms) {
884
- if (process.env.NODE_ENV === 'development' && debug) {
885
- // eslint-disable-next-line no-console
886
- console.log(
887
- 'Merging flat transforms, transform before',
888
- [...(style.transform || [])],
889
- flatTransforms
890
- )
891
- }
892
884
  mergeTransforms(style, flatTransforms, true)
893
885
  }
894
886