@tamagui/core 1.0.0-alpha.6 → 1.0.0-alpha.7
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/createFont.js +4 -0
- package/dist/createFont.js.map +2 -2
- package/dist/createTamagui.js +7 -0
- package/dist/createTamagui.js.map +2 -2
- package/dist/createTokens.js +4 -0
- package/dist/createTokens.js.map +2 -2
- package/dist/helpers/validate.js +60 -0
- package/dist/helpers/validate.js.map +7 -0
- package/dist/helpers/validateConfig.js +46 -0
- package/dist/helpers/validateConfig.js.map +7 -0
- package/dist/helpers/validateTokens.js +29 -0
- package/dist/helpers/validateTokens.js.map +7 -0
- package/dist/index.cjs +81 -7
- package/dist/index.cjs.map +3 -3
- package/dist/views/Theme.js +8 -6
- package/dist/views/Theme.js.map +2 -2
- package/dist/views/ThemeManagerContext.js +7 -1
- package/dist/views/ThemeManagerContext.js.map +2 -2
- package/package.json +3 -2
- package/src/createFont.ts +5 -0
- package/src/createTamagui.ts +8 -0
- package/src/createTokens.ts +6 -1
- package/src/helpers/validate.ts +59 -0
- package/src/types.tsx +1 -0
- package/src/views/Theme.tsx +17 -7
- package/src/views/ThemeManagerContext.tsx +11 -1
- package/types.d.ts +1 -0
package/dist/views/Theme.js
CHANGED
|
@@ -11,11 +11,13 @@ const Theme = /* @__PURE__ */ __name((props) => {
|
|
|
11
11
|
const themes = useContext(ThemeContext);
|
|
12
12
|
const [parentName, setParentName] = useState(parent.name || "light");
|
|
13
13
|
if (!themes) {
|
|
14
|
-
console.warn("no themes
|
|
14
|
+
console.warn("Error, no themes in context", props);
|
|
15
15
|
return props.children;
|
|
16
16
|
}
|
|
17
17
|
const name = props.name;
|
|
18
|
-
const
|
|
18
|
+
const nextNameParent = `${name}-${parentName}`;
|
|
19
|
+
const nextNameParentParent = `${name}-${parent.parentName}`;
|
|
20
|
+
const activeName = !name ? null : name in themes ? name : nextNameParent in themes ? nextNameParent : nextNameParentParent in themes ? nextNameParentParent : null;
|
|
19
21
|
const theme = activeName ? themes[activeName] : null;
|
|
20
22
|
const themeManager = useConstant(() => {
|
|
21
23
|
if (!theme) {
|
|
@@ -23,7 +25,7 @@ const Theme = /* @__PURE__ */ __name((props) => {
|
|
|
23
25
|
}
|
|
24
26
|
const manager = new ThemeManager();
|
|
25
27
|
if (name) {
|
|
26
|
-
manager.setActiveTheme(name, themes[name]);
|
|
28
|
+
manager.setActiveTheme({ name, theme: themes[name], parentName });
|
|
27
29
|
}
|
|
28
30
|
return manager;
|
|
29
31
|
});
|
|
@@ -31,14 +33,14 @@ const Theme = /* @__PURE__ */ __name((props) => {
|
|
|
31
33
|
if (!themeManager) {
|
|
32
34
|
return;
|
|
33
35
|
}
|
|
34
|
-
themeManager.setActiveTheme(activeName, theme);
|
|
36
|
+
themeManager.setActiveTheme({ name: activeName, theme, parentName });
|
|
35
37
|
return parent.onChangeTheme((next) => {
|
|
36
38
|
if (next) {
|
|
37
|
-
themeManager.setActiveTheme(next, themes[next]);
|
|
39
|
+
themeManager.setActiveTheme({ name: next, theme: themes[next], parentName });
|
|
38
40
|
setParentName(next);
|
|
39
41
|
}
|
|
40
42
|
});
|
|
41
|
-
}, [themes, activeName]);
|
|
43
|
+
}, [themes, activeName, parentName]);
|
|
42
44
|
if (!name || !theme) {
|
|
43
45
|
return props.children;
|
|
44
46
|
}
|
package/dist/views/Theme.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/views/Theme.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useContext, useState } from 'react'\n\nimport { isWeb, useIsomorphicLayoutEffect } from '../constants/platform'\nimport { getThemeParentClassName } from '../createTamagui'\nimport { useConstant } from '../hooks/useConstant'\nimport { ThemeName
|
|
5
|
-
"mappings": ";;AAAA;AAEA;AACA;AACA;AAEA;AACA;AAQO,MAAM,QAAQ,wBAAC,UAAsB;AAC1C,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,WAAW;AAC1B,QAAM,CAAC,YAAY,iBAAiB,SAAS,OAAO,QAAQ;AAC5D,MAAI,CAAC,QAAQ;AACX,YAAQ,KAAK
|
|
4
|
+
"sourcesContent": ["import React, { useContext, useState } from 'react'\n\nimport { isWeb, useIsomorphicLayoutEffect } from '../constants/platform'\nimport { getThemeParentClassName } from '../createTamagui'\nimport { useConstant } from '../hooks/useConstant'\nimport { ThemeName } from '../types'\nimport { ThemeContext } from './ThemeContext'\nimport { ThemeManager, ThemeManagerContext } from './ThemeManagerContext'\n\nexport type ThemeProps = {\n disableThemeClass?: boolean\n name: ThemeName | null\n children?: any\n}\n\nexport const Theme = (props: ThemeProps) => {\n const parent = useContext(ThemeManagerContext)\n const themes = useContext(ThemeContext)\n const [parentName, setParentName] = useState(parent.name || 'light')\n if (!themes) {\n console.warn('Error, no themes in context', props)\n return props.children\n }\n const name = props.name as string\n const nextNameParent = `${name}-${parentName}`\n const nextNameParentParent = `${name}-${parent.parentName}`\n const activeName = !name\n ? null\n : name in themes\n ? name\n : nextNameParent in themes\n ? nextNameParent\n : nextNameParentParent in themes\n ? nextNameParentParent\n : null\n const theme = activeName ? themes[activeName] : null\n const themeManager = useConstant<ThemeManager | null>(() => {\n if (!theme) {\n return null\n }\n const manager = new ThemeManager()\n if (name) {\n manager.setActiveTheme({ name, theme: themes[name], parentName })\n }\n return manager\n })\n\n useIsomorphicLayoutEffect(() => {\n if (!themeManager) {\n return\n }\n themeManager.setActiveTheme({ name: activeName, theme, parentName })\n return parent.onChangeTheme((next) => {\n if (next) {\n themeManager.setActiveTheme({ name: next, theme: themes[next], parentName })\n setParentName(next)\n }\n })\n }, [themes, activeName, parentName])\n\n if (!name || !theme) {\n return props.children\n }\n\n const contents = themeManager ? (\n <ThemeManagerContext.Provider value={themeManager}>\n {props.children}\n </ThemeManagerContext.Provider>\n ) : (\n props.children\n )\n\n if (isWeb) {\n if (props.disableThemeClass) {\n return contents\n }\n const color = themes[name]?.['color']?.['variable']\n return (\n <div\n className={getThemeParentClassName(name)}\n // in order to provide currentColor, set color by default\n style={{ display: 'contents', color }}\n >\n {contents}\n </div>\n )\n }\n\n return contents\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA;AAEA;AACA;AACA;AAEA;AACA;AAQO,MAAM,QAAQ,wBAAC,UAAsB;AAC1C,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,WAAW;AAC1B,QAAM,CAAC,YAAY,iBAAiB,SAAS,OAAO,QAAQ;AAC5D,MAAI,CAAC,QAAQ;AACX,YAAQ,KAAK,+BAA+B;AAC5C,WAAO,MAAM;AAAA;AAEf,QAAM,OAAO,MAAM;AACnB,QAAM,iBAAiB,GAAG,QAAQ;AAClC,QAAM,uBAAuB,GAAG,QAAQ,OAAO;AAC/C,QAAM,aAAa,CAAC,OAChB,OACA,QAAQ,SACR,OACA,kBAAkB,SAClB,iBACA,wBAAwB,SACxB,uBACA;AACJ,QAAM,QAAQ,aAAa,OAAO,cAAc;AAChD,QAAM,eAAe,YAAiC,MAAM;AAC1D,QAAI,CAAC,OAAO;AACV,aAAO;AAAA;AAET,UAAM,UAAU,IAAI;AACpB,QAAI,MAAM;AACR,cAAQ,eAAe,EAAE,MAAM,OAAO,OAAO,OAAO;AAAA;AAEtD,WAAO;AAAA;AAGT,4BAA0B,MAAM;AAC9B,QAAI,CAAC,cAAc;AACjB;AAAA;AAEF,iBAAa,eAAe,EAAE,MAAM,YAAY,OAAO;AACvD,WAAO,OAAO,cAAc,CAAC,SAAS;AACpC,UAAI,MAAM;AACR,qBAAa,eAAe,EAAE,MAAM,MAAM,OAAO,OAAO,OAAO;AAC/D,sBAAc;AAAA;AAAA;AAAA,KAGjB,CAAC,QAAQ,YAAY;AAExB,MAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,WAAO,MAAM;AAAA;AAGf,QAAM,WAAW,eACf,oCAAC,oBAAoB,UAArB;AAAA,IAA8B,OAAO;AAAA,KAClC,MAAM,YAGT,MAAM;AAGR,MAAI,OAAO;AACT,QAAI,MAAM,mBAAmB;AAC3B,aAAO;AAAA;AAET,UAAM,QAAQ,OAAO,QAAQ,WAAW;AACxC,WACE,oCAAC,OAAD;AAAA,MACE,WAAW,wBAAwB;AAAA,MAEnC,OAAO,EAAE,SAAS,YAAY;AAAA,OAE7B;AAAA;AAKP,SAAO;AAAA,GAzEY;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,16 +4,22 @@ import { createContext } from "react";
|
|
|
4
4
|
class ThemeManager {
|
|
5
5
|
constructor() {
|
|
6
6
|
this.name = "light";
|
|
7
|
+
this.parentName = null;
|
|
7
8
|
this.keys = new Map();
|
|
8
9
|
this.listeners = new Map();
|
|
9
10
|
this.callbacks = new Set();
|
|
10
11
|
this.theme = null;
|
|
11
12
|
}
|
|
12
|
-
setActiveTheme(
|
|
13
|
+
setActiveTheme({
|
|
14
|
+
name,
|
|
15
|
+
theme,
|
|
16
|
+
parentName
|
|
17
|
+
}) {
|
|
13
18
|
if (name === this.name)
|
|
14
19
|
return;
|
|
15
20
|
this.name = name;
|
|
16
21
|
this.theme = theme;
|
|
22
|
+
this.parentName = parentName || null;
|
|
17
23
|
this.update();
|
|
18
24
|
}
|
|
19
25
|
track(uuid, keys) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/views/ThemeManagerContext.tsx"],
|
|
4
|
-
"sourcesContent": ["import { createContext } from 'react'\n\nexport class ThemeManager {\n name: string | null = 'light'\n keys = new Map<any, Set<string>>()\n listeners = new Map<any, Function>()\n callbacks = new Set<Function>()\n theme = null\n\n setActiveTheme(name: string | null
|
|
5
|
-
"mappings": ";;AAAA;AAEO,mBAAmB;AAAA,EAAnB,cAFP;AAGE,gBAAsB;AACtB,gBAAO,IAAI;AACX,qBAAY,IAAI;AAChB,qBAAY,IAAI;AAChB,iBAAQ;AAAA;AAAA,EAER,eAAe,
|
|
4
|
+
"sourcesContent": ["import { createContext } from 'react'\n\nexport class ThemeManager {\n name: string | null = 'light'\n parentName: string | null = null\n keys = new Map<any, Set<string>>()\n listeners = new Map<any, Function>()\n callbacks = new Set<Function>()\n theme = null\n\n setActiveTheme({\n name,\n theme,\n parentName,\n }: {\n parentName?: string | null\n name: string | null\n theme?: any\n }) {\n if (name === this.name) return\n this.name = name\n this.theme = theme\n this.parentName = parentName || null\n this.update()\n }\n\n track(uuid: any, keys: Set<string>) {\n if (!this.name) return\n this.keys.set(uuid, keys)\n }\n\n update() {\n if (!this.name) {\n this.keys.clear()\n }\n for (const [uuid, keys] of this.keys.entries()) {\n if (keys.size) {\n this.listeners.get(uuid)?.()\n }\n }\n this.callbacks.forEach((cb) => cb(this.name))\n }\n\n onChangeTheme(cb: (name: string | null) => void) {\n this.callbacks.add(cb)\n return () => {\n this.callbacks.delete(cb)\n }\n }\n\n onUpdate(uuid: any, cb: Function) {\n this.listeners.set(uuid, cb)\n return () => {\n this.listeners.delete(uuid)\n this.keys.delete(uuid)\n }\n }\n}\n\nexport const ThemeManagerContext = createContext<ThemeManager>(new ThemeManager())\n"],
|
|
5
|
+
"mappings": ";;AAAA;AAEO,mBAAmB;AAAA,EAAnB,cAFP;AAGE,gBAAsB;AACtB,sBAA4B;AAC5B,gBAAO,IAAI;AACX,qBAAY,IAAI;AAChB,qBAAY,IAAI;AAChB,iBAAQ;AAAA;AAAA,EAER,eAAe;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,KAKC;AACD,QAAI,SAAS,KAAK;AAAM;AACxB,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,aAAa,cAAc;AAChC,SAAK;AAAA;AAAA,EAGP,MAAM,MAAW,MAAmB;AAClC,QAAI,CAAC,KAAK;AAAM;AAChB,SAAK,KAAK,IAAI,MAAM;AAAA;AAAA,EAGtB,SAAS;AACP,QAAI,CAAC,KAAK,MAAM;AACd,WAAK,KAAK;AAAA;AAEZ,eAAW,CAAC,MAAM,SAAS,KAAK,KAAK,WAAW;AAC9C,UAAI,KAAK,MAAM;AACb,aAAK,UAAU,IAAI;AAAA;AAAA;AAGvB,SAAK,UAAU,QAAQ,CAAC,OAAO,GAAG,KAAK;AAAA;AAAA,EAGzC,cAAc,IAAmC;AAC/C,SAAK,UAAU,IAAI;AACnB,WAAO,MAAM;AACX,WAAK,UAAU,OAAO;AAAA;AAAA;AAAA,EAI1B,SAAS,MAAW,IAAc;AAChC,SAAK,UAAU,IAAI,MAAM;AACzB,WAAO,MAAM;AACX,WAAK,UAAU,OAAO;AACtB,WAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AApDhB;AAyDA,MAAM,sBAAsB,cAA4B,IAAI;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/core",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.7",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@tamagui/build": "^1.0.0-alpha.2",
|
|
29
|
+
"@tamagui/ow": "^0.28.1",
|
|
29
30
|
"@types/react": "^17.0.35",
|
|
30
31
|
"esbuild": "^0.11.20",
|
|
31
32
|
"typescript": "^4.4.4"
|
|
@@ -36,5 +37,5 @@
|
|
|
36
37
|
"engines": {
|
|
37
38
|
"node": ">=16"
|
|
38
39
|
},
|
|
39
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "13694a98d31535846699004532630788177537e9"
|
|
40
41
|
}
|
package/src/createFont.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { validateFont } from './helpers/validate'
|
|
1
2
|
import { GenericFont } from './types'
|
|
2
3
|
|
|
3
4
|
export const createFont = <A extends GenericFont>(font: A): A => {
|
|
5
|
+
if (process.env.NODE_ENV === 'development') {
|
|
6
|
+
validateFont(font)
|
|
7
|
+
}
|
|
8
|
+
|
|
4
9
|
// fills in any missing values based on size keys being standard
|
|
5
10
|
const sizeKeys = Object.keys(font.size)
|
|
6
11
|
|
package/src/createTamagui.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { getStyleRules } from '@tamagui/helpers'
|
|
|
2
2
|
|
|
3
3
|
import { Variable, createVariable, isVariable } from './createVariable'
|
|
4
4
|
import { createTamaguiProvider } from './helpers/createTamaguiProvider'
|
|
5
|
+
import { validateConfig } from './helpers/validate'
|
|
5
6
|
import { configureMedia } from './hooks/useMedia'
|
|
6
7
|
import {
|
|
7
8
|
CreateTamaguiConfig,
|
|
@@ -46,6 +47,12 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
|
|
|
46
47
|
): Conf extends CreateTamaguiConfig<infer A, infer B, infer C, infer D>
|
|
47
48
|
? TamaguiInternalConfig<A, B, C, D>
|
|
48
49
|
: unknown {
|
|
50
|
+
if (process.env.NODE_ENV === 'development') {
|
|
51
|
+
// config is re-run by the @tamagui/static, dont double validate
|
|
52
|
+
if (!config['parsed']) {
|
|
53
|
+
validateConfig(config)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
49
56
|
// test env loads a few times as it runs diff tests
|
|
50
57
|
if (conf) {
|
|
51
58
|
console.warn('Called createTamagui twice! Should never do so')
|
|
@@ -157,6 +164,7 @@ export function createTamagui<Conf extends CreateTamaguiProps>(
|
|
|
157
164
|
themeConfig,
|
|
158
165
|
themeParsed,
|
|
159
166
|
tokensParsed,
|
|
167
|
+
parsed: true,
|
|
160
168
|
getCSS() {
|
|
161
169
|
return `${themeConfig.css}\n${[...getStyleRules()].join('\n')}`
|
|
162
170
|
},
|
package/src/createTokens.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Variable, createVariable } from './createVariable'
|
|
2
|
+
import { validateTokens } from './helpers/validate'
|
|
2
3
|
import { CreateTokens } from './types'
|
|
3
4
|
|
|
4
|
-
// tokens.color.dark.red ===>{ var: `color-dark-red`, val: '' }
|
|
5
|
+
// tokens.color.dark.red ===> { var: `color-dark-red`, val: '' }
|
|
5
6
|
|
|
6
7
|
export function createTokens<T extends CreateTokens>(tokens: T): MakeTokens<T> {
|
|
8
|
+
if (process.env.NODE_ENV === 'development') {
|
|
9
|
+
validateTokens(tokens)
|
|
10
|
+
}
|
|
11
|
+
|
|
7
12
|
return setupTokens(tokens) as any
|
|
8
13
|
}
|
|
9
14
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// published a patched version that works on native
|
|
2
|
+
import ow from '@tamagui/ow'
|
|
3
|
+
|
|
4
|
+
export const validateConfig = (conf: any) => {
|
|
5
|
+
if (!conf) {
|
|
6
|
+
console.warn('no conf?')
|
|
7
|
+
return
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
ow(conf, validConfig)
|
|
11
|
+
} catch (err: any) {
|
|
12
|
+
console.log('Given config:\n', JSON.stringify(conf, null, 2))
|
|
13
|
+
throw err
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const validConfig = ow.object.exactShape({
|
|
18
|
+
defaultTheme: ow.optional.string,
|
|
19
|
+
disableRootThemeClass: ow.optional.boolean,
|
|
20
|
+
shorthands: ow.optional.object.valuesOfType(ow.string),
|
|
21
|
+
themes: ow.object.valuesOfType(ow.object),
|
|
22
|
+
tokens: ow.object.valuesOfType(ow.object),
|
|
23
|
+
media: ow.object.valuesOfType(ow.object),
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const validFont = ow.object.exactShape({
|
|
27
|
+
family: ow.string,
|
|
28
|
+
size: ow.object.nonEmpty.valuesOfType(ow.number),
|
|
29
|
+
lineHeight: ow.object.nonEmpty.valuesOfType(ow.number),
|
|
30
|
+
weight: ow.object.nonEmpty.valuesOfType(ow.string),
|
|
31
|
+
letterSpacing: ow.object.nonEmpty.valuesOfType(ow.number),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const validTokens = ow.object.exactShape({
|
|
35
|
+
font: ow.object.valuesOfType(validFont),
|
|
36
|
+
size: ow.object.nonEmpty.valuesOfType(ow.number),
|
|
37
|
+
space: ow.object.nonEmpty.valuesOfType(ow.number),
|
|
38
|
+
zIndex: ow.object.nonEmpty.valuesOfType(ow.number),
|
|
39
|
+
radius: ow.object.nonEmpty.valuesOfType(ow.number),
|
|
40
|
+
color: ow.object.nonEmpty.valuesOfType(ow.string),
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
export const validateTokens = (tokens: any) => {
|
|
44
|
+
try {
|
|
45
|
+
ow(tokens, validTokens)
|
|
46
|
+
} catch (err: any) {
|
|
47
|
+
console.log('Given tokens:\n', JSON.stringify(tokens, null, 2))
|
|
48
|
+
throw err
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const validateFont = (font: any) => {
|
|
53
|
+
try {
|
|
54
|
+
ow(font, validFont)
|
|
55
|
+
} catch (err: any) {
|
|
56
|
+
console.log('Given font:\n', JSON.stringify(font, null, 2))
|
|
57
|
+
throw err
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/types.tsx
CHANGED
package/src/views/Theme.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import React, { useContext, useState } from 'react'
|
|
|
3
3
|
import { isWeb, useIsomorphicLayoutEffect } from '../constants/platform'
|
|
4
4
|
import { getThemeParentClassName } from '../createTamagui'
|
|
5
5
|
import { useConstant } from '../hooks/useConstant'
|
|
6
|
-
import { ThemeName
|
|
6
|
+
import { ThemeName } from '../types'
|
|
7
7
|
import { ThemeContext } from './ThemeContext'
|
|
8
8
|
import { ThemeManager, ThemeManagerContext } from './ThemeManagerContext'
|
|
9
9
|
|
|
@@ -18,11 +18,21 @@ export const Theme = (props: ThemeProps) => {
|
|
|
18
18
|
const themes = useContext(ThemeContext)
|
|
19
19
|
const [parentName, setParentName] = useState(parent.name || 'light')
|
|
20
20
|
if (!themes) {
|
|
21
|
-
console.warn('no themes
|
|
21
|
+
console.warn('Error, no themes in context', props)
|
|
22
22
|
return props.children
|
|
23
23
|
}
|
|
24
24
|
const name = props.name as string
|
|
25
|
-
const
|
|
25
|
+
const nextNameParent = `${name}-${parentName}`
|
|
26
|
+
const nextNameParentParent = `${name}-${parent.parentName}`
|
|
27
|
+
const activeName = !name
|
|
28
|
+
? null
|
|
29
|
+
: name in themes
|
|
30
|
+
? name
|
|
31
|
+
: nextNameParent in themes
|
|
32
|
+
? nextNameParent
|
|
33
|
+
: nextNameParentParent in themes
|
|
34
|
+
? nextNameParentParent
|
|
35
|
+
: null
|
|
26
36
|
const theme = activeName ? themes[activeName] : null
|
|
27
37
|
const themeManager = useConstant<ThemeManager | null>(() => {
|
|
28
38
|
if (!theme) {
|
|
@@ -30,7 +40,7 @@ export const Theme = (props: ThemeProps) => {
|
|
|
30
40
|
}
|
|
31
41
|
const manager = new ThemeManager()
|
|
32
42
|
if (name) {
|
|
33
|
-
manager.setActiveTheme(name, themes[name])
|
|
43
|
+
manager.setActiveTheme({ name, theme: themes[name], parentName })
|
|
34
44
|
}
|
|
35
45
|
return manager
|
|
36
46
|
})
|
|
@@ -39,14 +49,14 @@ export const Theme = (props: ThemeProps) => {
|
|
|
39
49
|
if (!themeManager) {
|
|
40
50
|
return
|
|
41
51
|
}
|
|
42
|
-
themeManager.setActiveTheme(activeName, theme)
|
|
52
|
+
themeManager.setActiveTheme({ name: activeName, theme, parentName })
|
|
43
53
|
return parent.onChangeTheme((next) => {
|
|
44
54
|
if (next) {
|
|
45
|
-
themeManager.setActiveTheme(next, themes[next])
|
|
55
|
+
themeManager.setActiveTheme({ name: next, theme: themes[next], parentName })
|
|
46
56
|
setParentName(next)
|
|
47
57
|
}
|
|
48
58
|
})
|
|
49
|
-
}, [themes, activeName])
|
|
59
|
+
}, [themes, activeName, parentName])
|
|
50
60
|
|
|
51
61
|
if (!name || !theme) {
|
|
52
62
|
return props.children
|
|
@@ -2,15 +2,25 @@ import { createContext } from 'react'
|
|
|
2
2
|
|
|
3
3
|
export class ThemeManager {
|
|
4
4
|
name: string | null = 'light'
|
|
5
|
+
parentName: string | null = null
|
|
5
6
|
keys = new Map<any, Set<string>>()
|
|
6
7
|
listeners = new Map<any, Function>()
|
|
7
8
|
callbacks = new Set<Function>()
|
|
8
9
|
theme = null
|
|
9
10
|
|
|
10
|
-
setActiveTheme(
|
|
11
|
+
setActiveTheme({
|
|
12
|
+
name,
|
|
13
|
+
theme,
|
|
14
|
+
parentName,
|
|
15
|
+
}: {
|
|
16
|
+
parentName?: string | null
|
|
17
|
+
name: string | null
|
|
18
|
+
theme?: any
|
|
19
|
+
}) {
|
|
11
20
|
if (name === this.name) return
|
|
12
21
|
this.name = name
|
|
13
22
|
this.theme = theme
|
|
23
|
+
this.parentName = parentName || null
|
|
14
24
|
this.update()
|
|
15
25
|
}
|
|
16
26
|
|
package/types.d.ts
CHANGED
|
@@ -97,6 +97,7 @@ export declare type TamaguiInternalConfig<A extends GenericTokens = GenericToken
|
|
|
97
97
|
tokensParsed: CreateTokens<Variable>;
|
|
98
98
|
themeConfig: any;
|
|
99
99
|
getCSS: () => string;
|
|
100
|
+
parsed: boolean;
|
|
100
101
|
};
|
|
101
102
|
export declare type UnionableString = string & {};
|
|
102
103
|
export declare type UnionableNumber = number & {};
|