@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.
- package/dist/cjs/createComponent.js +2 -2
- package/dist/cjs/createComponent.js.map +3 -3
- package/dist/cjs/helpers/ThemeManager.js +1 -1
- package/dist/cjs/helpers/ThemeManager.js.map +3 -3
- package/dist/cjs/helpers/getSplitStyles.js +2 -2
- package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
- package/dist/cjs/hooks/useTheme.js +1 -1
- package/dist/cjs/hooks/useTheme.js.map +3 -3
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/views/Theme.js +1 -1
- package/dist/cjs/views/Theme.js.map +3 -3
- package/dist/esm/createComponent.js +2 -2
- package/dist/esm/createComponent.js.map +3 -3
- package/dist/esm/createComponent.mjs +2 -2
- package/dist/esm/createComponent.mjs.map +3 -3
- package/dist/esm/helpers/ThemeManager.js +1 -1
- package/dist/esm/helpers/ThemeManager.js.map +3 -3
- package/dist/esm/helpers/ThemeManager.mjs +1 -1
- package/dist/esm/helpers/ThemeManager.mjs.map +3 -3
- package/dist/esm/helpers/getSplitStyles.js +2 -2
- package/dist/esm/helpers/getSplitStyles.js.map +2 -2
- package/dist/esm/helpers/getSplitStyles.mjs +2 -2
- package/dist/esm/helpers/getSplitStyles.mjs.map +2 -2
- package/dist/esm/hooks/useTheme.js +1 -1
- package/dist/esm/hooks/useTheme.js.map +3 -3
- package/dist/esm/hooks/useTheme.mjs +1 -1
- package/dist/esm/hooks/useTheme.mjs.map +3 -3
- package/dist/esm/views/Theme.js +1 -1
- package/dist/esm/views/Theme.js.map +3 -3
- package/dist/esm/views/Theme.mjs +1 -1
- package/dist/esm/views/Theme.mjs.map +3 -3
- package/package.json +9 -9
- package/src/createComponent.tsx +38 -5
- package/src/helpers/ThemeManager.tsx +40 -32
- package/src/helpers/getSplitStyles.tsx +0 -8
- package/src/hooks/useTheme.tsx +145 -93
- package/src/types.tsx +2 -2
- package/src/views/Theme.tsx +49 -27
- package/types/createComponent.d.ts.map +1 -1
- package/types/helpers/ThemeManager.d.ts +1 -0
- package/types/helpers/ThemeManager.d.ts.map +1 -1
- package/types/helpers/getSplitStyles.d.ts.map +1 -1
- package/types/hooks/useTheme.d.ts +5 -7
- package/types/hooks/useTheme.d.ts.map +1 -1
- package/types/types.d.ts +2 -2
- package/types/types.d.ts.map +1 -1
- 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
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "isWeb", "Children", "cloneElement", "isValidElement", "variableToString", "ThemeManagerContext", "useServerRef", "useChangeThemeEffect", "Theme", "props", "isRoot", "themeState", "children", "child", "useThemedChildren", "options", "themeManager", "
|
|
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 <Theme /> \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/dist/esm/views/Theme.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as
|
|
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
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "isWeb", "Children", "cloneElement", "isValidElement", "variableToString", "ThemeManagerContext", "useServerRef", "useChangeThemeEffect", "Theme", "props", "isRoot", "themeState", "children", "child", "useThemedChildren", "options", "themeManager", "
|
|
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 <Theme /> \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.
|
|
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.
|
|
31
|
-
"@tamagui/constants": "1.
|
|
32
|
-
"@tamagui/helpers": "1.
|
|
33
|
-
"@tamagui/normalize-css-color": "1.
|
|
34
|
-
"@tamagui/use-did-finish-ssr": "1.
|
|
35
|
-
"@tamagui/use-event": "1.
|
|
36
|
-
"@tamagui/use-force-update": "1.
|
|
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.
|
|
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",
|
package/src/createComponent.tsx
CHANGED
|
@@ -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-
|
|
296
|
+
// @ts-ignore this is internal use only
|
|
294
297
|
disable: props['data-themeable'],
|
|
295
|
-
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
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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
|
|
209
|
+
const isParentComponentTheme =
|
|
208
210
|
parentName && lastSegment[0].toUpperCase() === lastSegment[0]
|
|
209
|
-
if (
|
|
211
|
+
if (isParentComponentTheme) {
|
|
210
212
|
base.pop() // always remove componentName they can't nest
|
|
211
213
|
}
|
|
212
|
-
const parentBaseTheme =
|
|
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 === '
|
|
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
|
-
|
|
247
|
-
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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
|
-
|
|
281
|
-
|
|
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
|
|