@tamagui/web 1.14.3 → 1.14.5

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 (72) hide show
  1. package/dist/cjs/createComponent.js +1 -17
  2. package/dist/cjs/createComponent.js.map +2 -2
  3. package/dist/cjs/helpers/ThemeManager.js +38 -11
  4. package/dist/cjs/helpers/ThemeManager.js.map +2 -2
  5. package/dist/cjs/helpers/getSplitStyles.js +12 -3
  6. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  7. package/dist/cjs/hooks/useTheme.js +10 -8
  8. package/dist/cjs/hooks/useTheme.js.map +2 -2
  9. package/dist/cjs/index.js +0 -3
  10. package/dist/cjs/index.js.map +2 -2
  11. package/dist/cjs/styled.js +6 -1
  12. package/dist/cjs/styled.js.map +2 -2
  13. package/dist/cjs/types.js.map +1 -1
  14. package/dist/cjs/views/ThemeDebug.js +26 -7
  15. package/dist/cjs/views/ThemeDebug.js.map +3 -3
  16. package/dist/esm/createComponent.js +2 -19
  17. package/dist/esm/createComponent.js.map +2 -2
  18. package/dist/esm/createComponent.mjs +2 -19
  19. package/dist/esm/createComponent.mjs.map +2 -2
  20. package/dist/esm/helpers/ThemeManager.js +37 -11
  21. package/dist/esm/helpers/ThemeManager.js.map +2 -2
  22. package/dist/esm/helpers/ThemeManager.mjs +37 -11
  23. package/dist/esm/helpers/ThemeManager.mjs.map +2 -2
  24. package/dist/esm/helpers/getSplitStyles.js +12 -3
  25. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  26. package/dist/esm/helpers/getSplitStyles.mjs +12 -3
  27. package/dist/esm/helpers/getSplitStyles.mjs.map +2 -2
  28. package/dist/esm/hooks/useTheme.js +12 -9
  29. package/dist/esm/hooks/useTheme.js.map +2 -2
  30. package/dist/esm/hooks/useTheme.mjs +12 -9
  31. package/dist/esm/hooks/useTheme.mjs.map +2 -2
  32. package/dist/esm/index.js +0 -3
  33. package/dist/esm/index.js.map +2 -2
  34. package/dist/esm/index.mjs +0 -3
  35. package/dist/esm/index.mjs.map +2 -2
  36. package/dist/esm/styled.js +6 -1
  37. package/dist/esm/styled.js.map +2 -2
  38. package/dist/esm/styled.mjs +6 -1
  39. package/dist/esm/styled.mjs.map +2 -2
  40. package/dist/esm/views/ThemeDebug.js +26 -7
  41. package/dist/esm/views/ThemeDebug.js.map +3 -3
  42. package/dist/esm/views/ThemeDebug.mjs +26 -7
  43. package/dist/esm/views/ThemeDebug.mjs.map +3 -3
  44. package/package.json +9 -9
  45. package/src/createComponent.tsx +1 -14
  46. package/src/helpers/ThemeManager.tsx +49 -12
  47. package/src/helpers/getSplitStyles.tsx +13 -2
  48. package/src/hooks/useTheme.tsx +22 -8
  49. package/src/index.ts +0 -3
  50. package/src/styled.tsx +20 -3
  51. package/src/types.tsx +3 -2
  52. package/src/views/ThemeDebug.tsx +26 -4
  53. package/types/createComponent.d.ts +2 -2
  54. package/types/createComponent.d.ts.map +1 -1
  55. package/types/helpers/ThemeManager.d.ts +5 -3
  56. package/types/helpers/ThemeManager.d.ts.map +1 -1
  57. package/types/helpers/getSplitStyles.d.ts.map +1 -1
  58. package/types/hooks/useTheme.d.ts.map +1 -1
  59. package/types/index.d.ts +0 -3
  60. package/types/index.d.ts.map +1 -1
  61. package/types/styled.d.ts +1 -1
  62. package/types/styled.d.ts.map +1 -1
  63. package/types/types.d.ts +1 -1
  64. package/types/types.d.ts.map +1 -1
  65. package/types/views/Stack.d.ts +1 -1
  66. package/types/views/Stack.d.ts.map +1 -1
  67. package/types/views/Text.d.ts +1 -1
  68. package/types/views/Text.d.ts.map +1 -1
  69. package/types/views/ThemeDebug.d.ts +1 -2
  70. package/types/views/ThemeDebug.d.ts.map +1 -1
  71. package/src/addTheme.ts +0 -66
  72. package/src/updateTheme.ts +0 -27
@@ -7,17 +7,19 @@ function hasNoThemeUpdatingProps(props) {
7
7
  }
8
8
  let uid = 0;
9
9
  class ThemeManager {
10
- constructor(props = {}, parentManager) {
10
+ constructor(props = {}, parentManagerIn) {
11
11
  this.props = props;
12
12
  this.id = uid++;
13
+ this.isComponent = false;
13
14
  this.themeListeners = /* @__PURE__ */ new Set();
14
15
  this.parentManager = null;
15
16
  this.state = emptyState;
16
17
  this._allKeys = null;
17
- if (parentManager === "root") {
18
+ if (parentManagerIn === "root") {
18
19
  this.updateState(props, false);
19
20
  return;
20
21
  }
22
+ const parentManager = getNonComponentParentManager(parentManagerIn);
21
23
  if (!parentManager) {
22
24
  if (process.env.NODE_ENV !== "production") {
23
25
  throw new Error(
@@ -32,15 +34,13 @@ class ThemeManager {
32
34
  if (parentManager) {
33
35
  this.parentManager = parentManager;
34
36
  }
35
- const updatedState = this.getStateIfChanged(props);
36
- if (updatedState) {
37
- this.state = updatedState;
37
+ if (this.updateState(props, false)) {
38
38
  return;
39
39
  }
40
40
  return parentManager || this;
41
41
  }
42
- updateState(props = this.props || {}, notify = true) {
43
- const shouldFlush = (() => {
42
+ updateState(props = this.props || {}, shouldNotify = true) {
43
+ const isChanging = (() => {
44
44
  if (props.forceTheme) {
45
45
  this.state.theme = props.forceTheme;
46
46
  this.state.name = props.name || "";
@@ -53,9 +53,18 @@ class ThemeManager {
53
53
  return true;
54
54
  }
55
55
  })();
56
- if (shouldFlush) {
56
+ if (isChanging) {
57
+ const names = this.state.name.split("_");
58
+ const lastName = names[names.length - 1][0];
59
+ this.isComponent = lastName[0] === lastName[0].toUpperCase();
57
60
  this._allKeys = null;
58
- notify && this.notify();
61
+ if (process.env.NODE_ENV === "development") {
62
+ this["_numChangeEventsSent"] ??= 0;
63
+ this["_numChangeEventsSent"]++;
64
+ }
65
+ if (shouldNotify) {
66
+ this.notify();
67
+ }
59
68
  return this.state;
60
69
  }
61
70
  }
@@ -106,7 +115,11 @@ class ThemeManager {
106
115
  notify() {
107
116
  this.themeListeners.forEach((cb) => cb(this.state.name, this));
108
117
  }
109
- onChangeTheme(cb) {
118
+ onChangeTheme(cb, debugId) {
119
+ if (process.env.NODE_ENV === "development" && debugId) {
120
+ this._listeningIds ??= /* @__PURE__ */ new Set();
121
+ this._listeningIds.add(debugId);
122
+ }
110
123
  this.themeListeners.add(cb);
111
124
  return () => {
112
125
  this.themeListeners.delete(cb);
@@ -150,6 +163,7 @@ function getState(props, parentManager) {
150
163
  if (process.env.NODE_ENV === "development" && typeof props.debug === "string") {
151
164
  console.groupCollapsed("ThemeManager.getState()");
152
165
  console.log({
166
+ props,
153
167
  parentName,
154
168
  parentBaseTheme,
155
169
  base,
@@ -201,7 +215,7 @@ function getState(props, parentManager) {
201
215
  }
202
216
  }
203
217
  if (process.env.NODE_ENV === "development" && typeof props.debug === "string") {
204
- console.log({
218
+ console.warn("ThemeManager.getState():", {
205
219
  result
206
220
  });
207
221
  console.trace();
@@ -212,8 +226,20 @@ function getState(props, parentManager) {
212
226
  const inverseThemeName = (themeName) => {
213
227
  return themeName.startsWith("light") ? themeName.replace(/^light/, "dark") : themeName.replace(/^dark/, "light");
214
228
  };
229
+ function getNonComponentParentManager(themeManager) {
230
+ let res = themeManager;
231
+ while (res) {
232
+ if (res == null ? void 0 : res.isComponent) {
233
+ res = res.parentManager;
234
+ } else {
235
+ break;
236
+ }
237
+ }
238
+ return res;
239
+ }
215
240
  export {
216
241
  ThemeManager,
242
+ getNonComponentParentManager,
217
243
  hasNoThemeUpdatingProps
218
244
  };
219
245
  //# sourceMappingURL=ThemeManager.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/helpers/ThemeManager.tsx"],
4
- "sourcesContent": ["import { getThemes, getTokens } from '../config.js'\nimport { THEME_CLASSNAME_PREFIX, THEME_NAME_SEPARATOR } from '../constants/constants.js'\nimport { getThemeUnwrapped } from '../hooks/getThemeUnwrapped.js'\nimport { ThemeParsed, ThemeProps } from '../types.js'\n\ntype ThemeListener = (name: string | null, themeManager: ThemeManager) => void\n\nexport type SetActiveThemeProps = {\n className?: string\n parentManager?: ThemeManager | null\n name?: string | null\n theme?: any\n reset?: boolean\n}\n\nexport type ThemeManagerState = {\n name: string\n theme?: ThemeParsed | null\n className?: string\n parentName?: string\n}\n\nconst emptyState: ThemeManagerState = { name: '' }\n\nexport function hasNoThemeUpdatingProps(props: ThemeProps) {\n return !(props.name || props.componentName || props.inverse || props.reset)\n}\n\nlet uid = 0\n\nexport class ThemeManager {\n id = uid++\n themeListeners = new Set<ThemeListener>()\n parentManager: ThemeManager | null = null\n state: ThemeManagerState = emptyState\n\n constructor(\n public props: ThemeProps = {},\n parentManager?: ThemeManager | 'root' | null | undefined\n ) {\n if (parentManager === 'root') {\n this.updateState(props, false)\n return\n }\n if (!parentManager) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `No parent manager given, this is likely due to duplicated Tamagui dependencies. Check your lockfile for mis-matched versions.`\n )\n }\n throw `\u274C`\n }\n\n // no change no props\n if (hasNoThemeUpdatingProps(props)) {\n return parentManager\n }\n\n if (parentManager) {\n this.parentManager = parentManager\n }\n\n const updatedState = this.getStateIfChanged(props)\n if (updatedState) {\n this.state = updatedState\n return\n }\n\n return parentManager || this\n }\n\n updateState(\n props: ThemeProps & { forceTheme?: ThemeParsed } = this.props || {},\n notify = true\n ) {\n const shouldFlush = (() => {\n if (props.forceTheme) {\n this.state.theme = props.forceTheme\n this.state.name = props.name || ''\n return true\n }\n const nextState = this.getStateIfChanged(props)\n if (nextState) {\n this.props = props\n this.state = nextState\n return true\n }\n })()\n if (shouldFlush) {\n // reset any derived state\n this._allKeys = null\n notify && this.notify()\n return this.state\n }\n }\n\n getStateIfChanged(\n props = this.props,\n state: ThemeManagerState | null = this.state,\n parentManager = this.parentManager\n ) {\n const _ = this.getState(props, parentManager)\n // is removing\n if (state && state !== emptyState && !_) {\n return parentManager?.state\n }\n if (this.getStateShouldChange(_, state)) {\n return _\n }\n }\n\n getStateShouldChange(\n nextState: ThemeManagerState | null,\n state: ThemeManagerState | null = this.state\n ) {\n if (!nextState?.theme || nextState.theme === state?.theme) {\n return false\n }\n return true\n }\n\n getState(props = this.props, parentManager = this.parentManager) {\n return (\n getState(props, parentManager) ||\n (process.env.TAMAGUI_TARGET === 'native' ? parentManager?.state || null : null)\n )\n }\n\n _allKeys: Set<string> | null = null\n get allKeys() {\n this._allKeys ||= new Set([\n ...(this.parentManager?.allKeys || []),\n ...Object.keys(this.state.theme || {}),\n ])\n return this._allKeys\n }\n\n // gets value going up to parents\n getValue(key: string, state?: ThemeManagerState) {\n if (!key) return\n let theme = (state || this.state).theme\n let manager = this as ThemeManager | null\n while (theme && manager) {\n if (key in theme) {\n return theme[key]\n }\n manager = manager.parentManager\n theme = manager?.state.theme\n }\n const tokens = getTokens()\n if (key in tokens.color) {\n return tokens.color[key]\n }\n }\n\n notify() {\n this.themeListeners.forEach((cb) => cb(this.state.name, this))\n }\n\n onChangeTheme(cb: ThemeListener) {\n this.themeListeners.add(cb)\n return () => {\n this.themeListeners.delete(cb)\n }\n }\n}\n\nfunction getNextThemeClassName(name: string, props: ThemeProps) {\n const next = `t_sub_theme ${THEME_CLASSNAME_PREFIX}${name}`\n if (props.inverse || props.forceClassName) {\n return (\n next +\n // ensure you invert to base dark as well as specific dark\n // ... logic should likely be elsewhere\n (next.includes('dark_') ? ` t_dark` : next.includes('light_') ? ` t_light` : '')\n )\n }\n return next.replace('light_', '').replace('dark_', '')\n}\n\nfunction getState(\n props: ThemeProps,\n parentManager?: ThemeManager | null\n): ThemeManagerState | null {\n const themes = getThemes()\n\n if (props.name && props.reset) {\n throw new Error('Cannot reset + set new name')\n }\n\n if (props.reset && !parentManager?.parentManager) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('Cannot reset no grandparent exists')\n }\n return null\n }\n\n let result: ThemeManagerState | null = null\n\n const nextName = props.reset\n ? parentManager?.parentManager?.state?.name || ''\n : props.name || ''\n const { componentName } = props\n const parentName = parentManager?.state?.name || ''\n\n // components look for most specific, fallback upwards\n const base = parentName.split(THEME_NAME_SEPARATOR)\n const lastSegment = base[base.length - 1]\n const isParentComponentTheme =\n parentName && lastSegment[0].toUpperCase() === lastSegment[0]\n if (isParentComponentTheme) {\n base.pop() // always remove componentName they can't nest\n }\n const parentBaseTheme = isParentComponentTheme\n ? base.slice(0, base.length).join(THEME_NAME_SEPARATOR)\n : parentName\n const max = base.length\n const min =\n componentName && !nextName\n ? max // component name only don't search upwards\n : 0\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.groupCollapsed('ThemeManager.getState()')\n console.log({\n parentName,\n parentBaseTheme,\n base,\n min,\n max,\n isParentComponentTheme,\n })\n }\n\n for (let i = max; i >= min; i--) {\n let prefix = base.slice(0, i).join(THEME_NAME_SEPARATOR)\n if (props.inverse) {\n prefix = inverseThemeName(prefix)\n }\n const potentials: string[] = []\n if (prefix && prefix !== parentBaseTheme) {\n potentials.push(prefix)\n }\n if (nextName) {\n potentials.unshift(prefix ? `${prefix}_${nextName}` : nextName)\n }\n if (i === 1) {\n const lastSegment = potentials.findIndex((x) => !x.includes('_'))\n if (lastSegment > 0) {\n potentials.splice(lastSegment, 0, nextName) // last try prefer our new name to parent\n }\n }\n if (componentName) {\n // components only look for component themes\n if (nextName) {\n const beforeSeparator = prefix.slice(0, prefix.indexOf(THEME_NAME_SEPARATOR))\n potentials.push(`${beforeSeparator}_${nextName}_${componentName}`)\n }\n potentials.push(`${prefix}_${componentName}`)\n if (nextName) {\n potentials.unshift(`${prefix}_${nextName}_${componentName}`)\n }\n }\n\n const found = potentials.find((t) => t in themes)\n\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.log(' - ', { found, potentials })\n }\n\n if (found) {\n result = {\n name: found,\n theme: getThemeUnwrapped(themes[found]),\n className: getNextThemeClassName(found, props),\n parentName,\n }\n break\n }\n }\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.log({\n result,\n })\n console.trace()\n console.groupEnd()\n }\n\n return result\n}\n\nconst inverseThemeName = (themeName: string) => {\n return themeName.startsWith('light')\n ? themeName.replace(/^light/, 'dark')\n : themeName.replace(/^dark/, 'light')\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { getThemes, getTokens } from '../config.js'\nimport { THEME_CLASSNAME_PREFIX, THEME_NAME_SEPARATOR } from '../constants/constants.js'\nimport { getThemeUnwrapped } from '../hooks/getThemeUnwrapped.js'\nimport { ThemeParsed, ThemeProps } from '../types.js'\n\ntype ThemeListener = (name: string | null, themeManager: ThemeManager) => void\n\nexport type SetActiveThemeProps = {\n className?: string\n parentManager?: ThemeManager | null\n name?: string | null\n theme?: any\n reset?: boolean\n}\n\nexport type ThemeManagerState = {\n name: string\n theme?: ThemeParsed | null\n className?: string\n parentName?: string\n}\n\nconst emptyState: ThemeManagerState = { name: '' }\n\nexport function hasNoThemeUpdatingProps(props: ThemeProps) {\n return !(props.name || props.componentName || props.inverse || props.reset)\n}\n\nlet uid = 0\n\nexport class ThemeManager {\n id = uid++\n isComponent = false\n themeListeners = new Set<ThemeListener>()\n parentManager: ThemeManager | null = null\n state: ThemeManagerState = emptyState\n\n constructor(\n public props: ThemeProps = {},\n parentManagerIn?: ThemeManager | 'root' | null | undefined\n ) {\n if (parentManagerIn === 'root') {\n this.updateState(props, false)\n return\n }\n\n const parentManager = getNonComponentParentManager(parentManagerIn)\n\n if (!parentManager) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `No parent manager given, this is likely due to duplicated Tamagui dependencies. Check your lockfile for mis-matched versions.`\n )\n }\n throw `\u274C`\n }\n\n // no change no props\n if (hasNoThemeUpdatingProps(props)) {\n return parentManager\n }\n\n if (parentManager) {\n this.parentManager = parentManager\n }\n\n if (this.updateState(props, false)) {\n return\n }\n\n return parentManager || this\n }\n\n updateState(\n props: ThemeProps & { forceTheme?: ThemeParsed } = this.props || {},\n shouldNotify = true\n ) {\n const isChanging = (() => {\n if (props.forceTheme) {\n this.state.theme = props.forceTheme\n this.state.name = props.name || ''\n return true\n }\n const nextState = this.getStateIfChanged(props)\n if (nextState) {\n this.props = props\n this.state = nextState\n return true\n }\n })()\n\n if (isChanging) {\n const names = this.state.name.split('_')\n const lastName = names[names.length - 1][0]\n this.isComponent = lastName[0] === lastName[0].toUpperCase()\n this._allKeys = null\n\n if (process.env.NODE_ENV === 'development') {\n this['_numChangeEventsSent'] ??= 0\n this['_numChangeEventsSent']++\n }\n\n if (shouldNotify) {\n this.notify()\n }\n\n return this.state\n }\n }\n\n getStateIfChanged(\n props = this.props,\n state: ThemeManagerState | null = this.state,\n parentManager = this.parentManager\n ) {\n const _ = this.getState(props, parentManager)\n // is removing\n if (state && state !== emptyState && !_) {\n return parentManager?.state\n }\n if (this.getStateShouldChange(_, state)) {\n return _\n }\n }\n\n getStateShouldChange(\n nextState: ThemeManagerState | null,\n state: ThemeManagerState | null = this.state\n ) {\n if (!nextState?.theme || nextState.theme === state?.theme) {\n return false\n }\n return true\n }\n\n getState(props = this.props, parentManager = this.parentManager) {\n return (\n getState(props, parentManager) ||\n (process.env.TAMAGUI_TARGET === 'native' ? parentManager?.state || null : null)\n )\n }\n\n _allKeys: Set<string> | null = null\n get allKeys() {\n this._allKeys ||= new Set([\n ...(this.parentManager?.allKeys || []),\n ...Object.keys(this.state.theme || {}),\n ])\n return this._allKeys\n }\n\n // gets value going up to parents\n getValue(key: string, state?: ThemeManagerState) {\n if (!key) return\n let theme = (state || this.state).theme\n let manager = this as ThemeManager | null\n while (theme && manager) {\n if (key in theme) {\n return theme[key]\n }\n manager = manager.parentManager\n theme = manager?.state.theme\n }\n const tokens = getTokens()\n if (key in tokens.color) {\n return tokens.color[key]\n }\n }\n\n notify() {\n this.themeListeners.forEach((cb) => cb(this.state.name, this))\n }\n\n onChangeTheme(cb: ThemeListener, debugId?: number) {\n if (process.env.NODE_ENV === 'development' && debugId) {\n // @ts-ignore\n this._listeningIds ??= new Set()\n // @ts-ignore\n this._listeningIds.add(debugId)\n }\n\n this.themeListeners.add(cb)\n return () => {\n this.themeListeners.delete(cb)\n }\n }\n}\n\nfunction getNextThemeClassName(name: string, props: ThemeProps) {\n const next = `t_sub_theme ${THEME_CLASSNAME_PREFIX}${name}`\n if (props.inverse || props.forceClassName) {\n return (\n next +\n // ensure you invert to base dark as well as specific dark\n // ... logic should likely be elsewhere\n (next.includes('dark_') ? ` t_dark` : next.includes('light_') ? ` t_light` : '')\n )\n }\n return next.replace('light_', '').replace('dark_', '')\n}\n\nfunction getState(\n props: ThemeProps,\n parentManager?: ThemeManager | null\n): ThemeManagerState | null {\n const themes = getThemes()\n\n if (props.name && props.reset) {\n throw new Error('Cannot reset + set new name')\n }\n\n if (props.reset && !parentManager?.parentManager) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('Cannot reset no grandparent exists')\n }\n return null\n }\n\n let result: ThemeManagerState | null = null\n\n const nextName = props.reset\n ? parentManager?.parentManager?.state?.name || ''\n : props.name || ''\n const { componentName } = props\n const parentName = parentManager?.state?.name || ''\n\n // components look for most specific, fallback upwards\n const base = parentName.split(THEME_NAME_SEPARATOR)\n const lastSegment = base[base.length - 1]\n const isParentComponentTheme =\n parentName && lastSegment[0].toUpperCase() === lastSegment[0]\n if (isParentComponentTheme) {\n base.pop() // always remove componentName they can't nest\n }\n const parentBaseTheme = isParentComponentTheme\n ? base.slice(0, base.length).join(THEME_NAME_SEPARATOR)\n : parentName\n const max = base.length\n const min =\n componentName && !nextName\n ? max // component name only don't search upwards\n : 0\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.groupCollapsed('ThemeManager.getState()')\n console.log({\n props,\n parentName,\n parentBaseTheme,\n base,\n min,\n max,\n isParentComponentTheme,\n })\n }\n\n for (let i = max; i >= min; i--) {\n let prefix = base.slice(0, i).join(THEME_NAME_SEPARATOR)\n if (props.inverse) {\n prefix = inverseThemeName(prefix)\n }\n const potentials: string[] = []\n if (prefix && prefix !== parentBaseTheme) {\n potentials.push(prefix)\n }\n if (nextName) {\n potentials.unshift(prefix ? `${prefix}_${nextName}` : nextName)\n }\n if (i === 1) {\n const lastSegment = potentials.findIndex((x) => !x.includes('_'))\n if (lastSegment > 0) {\n potentials.splice(lastSegment, 0, nextName) // last try prefer our new name to parent\n }\n }\n if (componentName) {\n // components only look for component themes\n if (nextName) {\n const beforeSeparator = prefix.slice(0, prefix.indexOf(THEME_NAME_SEPARATOR))\n potentials.push(`${beforeSeparator}_${nextName}_${componentName}`)\n }\n potentials.push(`${prefix}_${componentName}`)\n if (nextName) {\n potentials.unshift(`${prefix}_${nextName}_${componentName}`)\n }\n }\n\n const found = potentials.find((t) => t in themes)\n\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.log(' - ', { found, potentials })\n }\n\n if (found) {\n result = {\n name: found,\n theme: getThemeUnwrapped(themes[found]),\n className: getNextThemeClassName(found, props),\n parentName,\n }\n break\n }\n }\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.warn('ThemeManager.getState():', {\n result,\n })\n console.trace()\n console.groupEnd()\n }\n\n return result\n}\n\nconst inverseThemeName = (themeName: string) => {\n return themeName.startsWith('light')\n ? themeName.replace(/^light/, 'dark')\n : themeName.replace(/^dark/, 'light')\n}\n\nexport function getNonComponentParentManager(themeManager?: ThemeManager | null) {\n // components never inherit from components\n // example <Switch><Switch.Thumb /></Switch>\n // the Switch theme shouldn't be considered parent of Thumb\n let res = themeManager\n while (res) {\n if (res?.isComponent) {\n res = res.parentManager\n } else {\n break\n }\n }\n return res\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["lastSegment"]
7
7
  }
@@ -7,17 +7,19 @@ function hasNoThemeUpdatingProps(props) {
7
7
  }
8
8
  let uid = 0;
9
9
  class ThemeManager {
10
- constructor(props = {}, parentManager) {
10
+ constructor(props = {}, parentManagerIn) {
11
11
  this.props = props;
12
12
  this.id = uid++;
13
+ this.isComponent = false;
13
14
  this.themeListeners = /* @__PURE__ */ new Set();
14
15
  this.parentManager = null;
15
16
  this.state = emptyState;
16
17
  this._allKeys = null;
17
- if (parentManager === "root") {
18
+ if (parentManagerIn === "root") {
18
19
  this.updateState(props, false);
19
20
  return;
20
21
  }
22
+ const parentManager = getNonComponentParentManager(parentManagerIn);
21
23
  if (!parentManager) {
22
24
  if (process.env.NODE_ENV !== "production") {
23
25
  throw new Error(
@@ -32,15 +34,13 @@ class ThemeManager {
32
34
  if (parentManager) {
33
35
  this.parentManager = parentManager;
34
36
  }
35
- const updatedState = this.getStateIfChanged(props);
36
- if (updatedState) {
37
- this.state = updatedState;
37
+ if (this.updateState(props, false)) {
38
38
  return;
39
39
  }
40
40
  return parentManager || this;
41
41
  }
42
- updateState(props = this.props || {}, notify = true) {
43
- const shouldFlush = (() => {
42
+ updateState(props = this.props || {}, shouldNotify = true) {
43
+ const isChanging = (() => {
44
44
  if (props.forceTheme) {
45
45
  this.state.theme = props.forceTheme;
46
46
  this.state.name = props.name || "";
@@ -53,9 +53,18 @@ class ThemeManager {
53
53
  return true;
54
54
  }
55
55
  })();
56
- if (shouldFlush) {
56
+ if (isChanging) {
57
+ const names = this.state.name.split("_");
58
+ const lastName = names[names.length - 1][0];
59
+ this.isComponent = lastName[0] === lastName[0].toUpperCase();
57
60
  this._allKeys = null;
58
- notify && this.notify();
61
+ if (process.env.NODE_ENV === "development") {
62
+ this["_numChangeEventsSent"] ??= 0;
63
+ this["_numChangeEventsSent"]++;
64
+ }
65
+ if (shouldNotify) {
66
+ this.notify();
67
+ }
59
68
  return this.state;
60
69
  }
61
70
  }
@@ -106,7 +115,11 @@ class ThemeManager {
106
115
  notify() {
107
116
  this.themeListeners.forEach((cb) => cb(this.state.name, this));
108
117
  }
109
- onChangeTheme(cb) {
118
+ onChangeTheme(cb, debugId) {
119
+ if (process.env.NODE_ENV === "development" && debugId) {
120
+ this._listeningIds ??= /* @__PURE__ */ new Set();
121
+ this._listeningIds.add(debugId);
122
+ }
110
123
  this.themeListeners.add(cb);
111
124
  return () => {
112
125
  this.themeListeners.delete(cb);
@@ -150,6 +163,7 @@ function getState(props, parentManager) {
150
163
  if (process.env.NODE_ENV === "development" && typeof props.debug === "string") {
151
164
  console.groupCollapsed("ThemeManager.getState()");
152
165
  console.log({
166
+ props,
153
167
  parentName,
154
168
  parentBaseTheme,
155
169
  base,
@@ -201,7 +215,7 @@ function getState(props, parentManager) {
201
215
  }
202
216
  }
203
217
  if (process.env.NODE_ENV === "development" && typeof props.debug === "string") {
204
- console.log({
218
+ console.warn("ThemeManager.getState():", {
205
219
  result
206
220
  });
207
221
  console.trace();
@@ -212,8 +226,20 @@ function getState(props, parentManager) {
212
226
  const inverseThemeName = (themeName) => {
213
227
  return themeName.startsWith("light") ? themeName.replace(/^light/, "dark") : themeName.replace(/^dark/, "light");
214
228
  };
229
+ function getNonComponentParentManager(themeManager) {
230
+ let res = themeManager;
231
+ while (res) {
232
+ if (res == null ? void 0 : res.isComponent) {
233
+ res = res.parentManager;
234
+ } else {
235
+ break;
236
+ }
237
+ }
238
+ return res;
239
+ }
215
240
  export {
216
241
  ThemeManager,
242
+ getNonComponentParentManager,
217
243
  hasNoThemeUpdatingProps
218
244
  };
219
245
  //# sourceMappingURL=ThemeManager.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/helpers/ThemeManager.tsx"],
4
- "sourcesContent": ["import { getThemes, getTokens } from '../config.js'\nimport { THEME_CLASSNAME_PREFIX, THEME_NAME_SEPARATOR } from '../constants/constants.js'\nimport { getThemeUnwrapped } from '../hooks/getThemeUnwrapped.js'\nimport { ThemeParsed, ThemeProps } from '../types.js'\n\ntype ThemeListener = (name: string | null, themeManager: ThemeManager) => void\n\nexport type SetActiveThemeProps = {\n className?: string\n parentManager?: ThemeManager | null\n name?: string | null\n theme?: any\n reset?: boolean\n}\n\nexport type ThemeManagerState = {\n name: string\n theme?: ThemeParsed | null\n className?: string\n parentName?: string\n}\n\nconst emptyState: ThemeManagerState = { name: '' }\n\nexport function hasNoThemeUpdatingProps(props: ThemeProps) {\n return !(props.name || props.componentName || props.inverse || props.reset)\n}\n\nlet uid = 0\n\nexport class ThemeManager {\n id = uid++\n themeListeners = new Set<ThemeListener>()\n parentManager: ThemeManager | null = null\n state: ThemeManagerState = emptyState\n\n constructor(\n public props: ThemeProps = {},\n parentManager?: ThemeManager | 'root' | null | undefined\n ) {\n if (parentManager === 'root') {\n this.updateState(props, false)\n return\n }\n if (!parentManager) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `No parent manager given, this is likely due to duplicated Tamagui dependencies. Check your lockfile for mis-matched versions.`\n )\n }\n throw `\u274C`\n }\n\n // no change no props\n if (hasNoThemeUpdatingProps(props)) {\n return parentManager\n }\n\n if (parentManager) {\n this.parentManager = parentManager\n }\n\n const updatedState = this.getStateIfChanged(props)\n if (updatedState) {\n this.state = updatedState\n return\n }\n\n return parentManager || this\n }\n\n updateState(\n props: ThemeProps & { forceTheme?: ThemeParsed } = this.props || {},\n notify = true\n ) {\n const shouldFlush = (() => {\n if (props.forceTheme) {\n this.state.theme = props.forceTheme\n this.state.name = props.name || ''\n return true\n }\n const nextState = this.getStateIfChanged(props)\n if (nextState) {\n this.props = props\n this.state = nextState\n return true\n }\n })()\n if (shouldFlush) {\n // reset any derived state\n this._allKeys = null\n notify && this.notify()\n return this.state\n }\n }\n\n getStateIfChanged(\n props = this.props,\n state: ThemeManagerState | null = this.state,\n parentManager = this.parentManager\n ) {\n const _ = this.getState(props, parentManager)\n // is removing\n if (state && state !== emptyState && !_) {\n return parentManager?.state\n }\n if (this.getStateShouldChange(_, state)) {\n return _\n }\n }\n\n getStateShouldChange(\n nextState: ThemeManagerState | null,\n state: ThemeManagerState | null = this.state\n ) {\n if (!nextState?.theme || nextState.theme === state?.theme) {\n return false\n }\n return true\n }\n\n getState(props = this.props, parentManager = this.parentManager) {\n return (\n getState(props, parentManager) ||\n (process.env.TAMAGUI_TARGET === 'native' ? parentManager?.state || null : null)\n )\n }\n\n _allKeys: Set<string> | null = null\n get allKeys() {\n this._allKeys ||= new Set([\n ...(this.parentManager?.allKeys || []),\n ...Object.keys(this.state.theme || {}),\n ])\n return this._allKeys\n }\n\n // gets value going up to parents\n getValue(key: string, state?: ThemeManagerState) {\n if (!key) return\n let theme = (state || this.state).theme\n let manager = this as ThemeManager | null\n while (theme && manager) {\n if (key in theme) {\n return theme[key]\n }\n manager = manager.parentManager\n theme = manager?.state.theme\n }\n const tokens = getTokens()\n if (key in tokens.color) {\n return tokens.color[key]\n }\n }\n\n notify() {\n this.themeListeners.forEach((cb) => cb(this.state.name, this))\n }\n\n onChangeTheme(cb: ThemeListener) {\n this.themeListeners.add(cb)\n return () => {\n this.themeListeners.delete(cb)\n }\n }\n}\n\nfunction getNextThemeClassName(name: string, props: ThemeProps) {\n const next = `t_sub_theme ${THEME_CLASSNAME_PREFIX}${name}`\n if (props.inverse || props.forceClassName) {\n return (\n next +\n // ensure you invert to base dark as well as specific dark\n // ... logic should likely be elsewhere\n (next.includes('dark_') ? ` t_dark` : next.includes('light_') ? ` t_light` : '')\n )\n }\n return next.replace('light_', '').replace('dark_', '')\n}\n\nfunction getState(\n props: ThemeProps,\n parentManager?: ThemeManager | null\n): ThemeManagerState | null {\n const themes = getThemes()\n\n if (props.name && props.reset) {\n throw new Error('Cannot reset + set new name')\n }\n\n if (props.reset && !parentManager?.parentManager) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('Cannot reset no grandparent exists')\n }\n return null\n }\n\n let result: ThemeManagerState | null = null\n\n const nextName = props.reset\n ? parentManager?.parentManager?.state?.name || ''\n : props.name || ''\n const { componentName } = props\n const parentName = parentManager?.state?.name || ''\n\n // components look for most specific, fallback upwards\n const base = parentName.split(THEME_NAME_SEPARATOR)\n const lastSegment = base[base.length - 1]\n const isParentComponentTheme =\n parentName && lastSegment[0].toUpperCase() === lastSegment[0]\n if (isParentComponentTheme) {\n base.pop() // always remove componentName they can't nest\n }\n const parentBaseTheme = isParentComponentTheme\n ? base.slice(0, base.length).join(THEME_NAME_SEPARATOR)\n : parentName\n const max = base.length\n const min =\n componentName && !nextName\n ? max // component name only don't search upwards\n : 0\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.groupCollapsed('ThemeManager.getState()')\n console.log({\n parentName,\n parentBaseTheme,\n base,\n min,\n max,\n isParentComponentTheme,\n })\n }\n\n for (let i = max; i >= min; i--) {\n let prefix = base.slice(0, i).join(THEME_NAME_SEPARATOR)\n if (props.inverse) {\n prefix = inverseThemeName(prefix)\n }\n const potentials: string[] = []\n if (prefix && prefix !== parentBaseTheme) {\n potentials.push(prefix)\n }\n if (nextName) {\n potentials.unshift(prefix ? `${prefix}_${nextName}` : nextName)\n }\n if (i === 1) {\n const lastSegment = potentials.findIndex((x) => !x.includes('_'))\n if (lastSegment > 0) {\n potentials.splice(lastSegment, 0, nextName) // last try prefer our new name to parent\n }\n }\n if (componentName) {\n // components only look for component themes\n if (nextName) {\n const beforeSeparator = prefix.slice(0, prefix.indexOf(THEME_NAME_SEPARATOR))\n potentials.push(`${beforeSeparator}_${nextName}_${componentName}`)\n }\n potentials.push(`${prefix}_${componentName}`)\n if (nextName) {\n potentials.unshift(`${prefix}_${nextName}_${componentName}`)\n }\n }\n\n const found = potentials.find((t) => t in themes)\n\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.log(' - ', { found, potentials })\n }\n\n if (found) {\n result = {\n name: found,\n theme: getThemeUnwrapped(themes[found]),\n className: getNextThemeClassName(found, props),\n parentName,\n }\n break\n }\n }\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.log({\n result,\n })\n console.trace()\n console.groupEnd()\n }\n\n return result\n}\n\nconst inverseThemeName = (themeName: string) => {\n return themeName.startsWith('light')\n ? themeName.replace(/^light/, 'dark')\n : themeName.replace(/^dark/, 'light')\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { getThemes, getTokens } from '../config.js'\nimport { THEME_CLASSNAME_PREFIX, THEME_NAME_SEPARATOR } from '../constants/constants.js'\nimport { getThemeUnwrapped } from '../hooks/getThemeUnwrapped.js'\nimport { ThemeParsed, ThemeProps } from '../types.js'\n\ntype ThemeListener = (name: string | null, themeManager: ThemeManager) => void\n\nexport type SetActiveThemeProps = {\n className?: string\n parentManager?: ThemeManager | null\n name?: string | null\n theme?: any\n reset?: boolean\n}\n\nexport type ThemeManagerState = {\n name: string\n theme?: ThemeParsed | null\n className?: string\n parentName?: string\n}\n\nconst emptyState: ThemeManagerState = { name: '' }\n\nexport function hasNoThemeUpdatingProps(props: ThemeProps) {\n return !(props.name || props.componentName || props.inverse || props.reset)\n}\n\nlet uid = 0\n\nexport class ThemeManager {\n id = uid++\n isComponent = false\n themeListeners = new Set<ThemeListener>()\n parentManager: ThemeManager | null = null\n state: ThemeManagerState = emptyState\n\n constructor(\n public props: ThemeProps = {},\n parentManagerIn?: ThemeManager | 'root' | null | undefined\n ) {\n if (parentManagerIn === 'root') {\n this.updateState(props, false)\n return\n }\n\n const parentManager = getNonComponentParentManager(parentManagerIn)\n\n if (!parentManager) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `No parent manager given, this is likely due to duplicated Tamagui dependencies. Check your lockfile for mis-matched versions.`\n )\n }\n throw `\u274C`\n }\n\n // no change no props\n if (hasNoThemeUpdatingProps(props)) {\n return parentManager\n }\n\n if (parentManager) {\n this.parentManager = parentManager\n }\n\n if (this.updateState(props, false)) {\n return\n }\n\n return parentManager || this\n }\n\n updateState(\n props: ThemeProps & { forceTheme?: ThemeParsed } = this.props || {},\n shouldNotify = true\n ) {\n const isChanging = (() => {\n if (props.forceTheme) {\n this.state.theme = props.forceTheme\n this.state.name = props.name || ''\n return true\n }\n const nextState = this.getStateIfChanged(props)\n if (nextState) {\n this.props = props\n this.state = nextState\n return true\n }\n })()\n\n if (isChanging) {\n const names = this.state.name.split('_')\n const lastName = names[names.length - 1][0]\n this.isComponent = lastName[0] === lastName[0].toUpperCase()\n this._allKeys = null\n\n if (process.env.NODE_ENV === 'development') {\n this['_numChangeEventsSent'] ??= 0\n this['_numChangeEventsSent']++\n }\n\n if (shouldNotify) {\n this.notify()\n }\n\n return this.state\n }\n }\n\n getStateIfChanged(\n props = this.props,\n state: ThemeManagerState | null = this.state,\n parentManager = this.parentManager\n ) {\n const _ = this.getState(props, parentManager)\n // is removing\n if (state && state !== emptyState && !_) {\n return parentManager?.state\n }\n if (this.getStateShouldChange(_, state)) {\n return _\n }\n }\n\n getStateShouldChange(\n nextState: ThemeManagerState | null,\n state: ThemeManagerState | null = this.state\n ) {\n if (!nextState?.theme || nextState.theme === state?.theme) {\n return false\n }\n return true\n }\n\n getState(props = this.props, parentManager = this.parentManager) {\n return (\n getState(props, parentManager) ||\n (process.env.TAMAGUI_TARGET === 'native' ? parentManager?.state || null : null)\n )\n }\n\n _allKeys: Set<string> | null = null\n get allKeys() {\n this._allKeys ||= new Set([\n ...(this.parentManager?.allKeys || []),\n ...Object.keys(this.state.theme || {}),\n ])\n return this._allKeys\n }\n\n // gets value going up to parents\n getValue(key: string, state?: ThemeManagerState) {\n if (!key) return\n let theme = (state || this.state).theme\n let manager = this as ThemeManager | null\n while (theme && manager) {\n if (key in theme) {\n return theme[key]\n }\n manager = manager.parentManager\n theme = manager?.state.theme\n }\n const tokens = getTokens()\n if (key in tokens.color) {\n return tokens.color[key]\n }\n }\n\n notify() {\n this.themeListeners.forEach((cb) => cb(this.state.name, this))\n }\n\n onChangeTheme(cb: ThemeListener, debugId?: number) {\n if (process.env.NODE_ENV === 'development' && debugId) {\n // @ts-ignore\n this._listeningIds ??= new Set()\n // @ts-ignore\n this._listeningIds.add(debugId)\n }\n\n this.themeListeners.add(cb)\n return () => {\n this.themeListeners.delete(cb)\n }\n }\n}\n\nfunction getNextThemeClassName(name: string, props: ThemeProps) {\n const next = `t_sub_theme ${THEME_CLASSNAME_PREFIX}${name}`\n if (props.inverse || props.forceClassName) {\n return (\n next +\n // ensure you invert to base dark as well as specific dark\n // ... logic should likely be elsewhere\n (next.includes('dark_') ? ` t_dark` : next.includes('light_') ? ` t_light` : '')\n )\n }\n return next.replace('light_', '').replace('dark_', '')\n}\n\nfunction getState(\n props: ThemeProps,\n parentManager?: ThemeManager | null\n): ThemeManagerState | null {\n const themes = getThemes()\n\n if (props.name && props.reset) {\n throw new Error('Cannot reset + set new name')\n }\n\n if (props.reset && !parentManager?.parentManager) {\n if (process.env.NODE_ENV === 'development') {\n console.warn('Cannot reset no grandparent exists')\n }\n return null\n }\n\n let result: ThemeManagerState | null = null\n\n const nextName = props.reset\n ? parentManager?.parentManager?.state?.name || ''\n : props.name || ''\n const { componentName } = props\n const parentName = parentManager?.state?.name || ''\n\n // components look for most specific, fallback upwards\n const base = parentName.split(THEME_NAME_SEPARATOR)\n const lastSegment = base[base.length - 1]\n const isParentComponentTheme =\n parentName && lastSegment[0].toUpperCase() === lastSegment[0]\n if (isParentComponentTheme) {\n base.pop() // always remove componentName they can't nest\n }\n const parentBaseTheme = isParentComponentTheme\n ? base.slice(0, base.length).join(THEME_NAME_SEPARATOR)\n : parentName\n const max = base.length\n const min =\n componentName && !nextName\n ? max // component name only don't search upwards\n : 0\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.groupCollapsed('ThemeManager.getState()')\n console.log({\n props,\n parentName,\n parentBaseTheme,\n base,\n min,\n max,\n isParentComponentTheme,\n })\n }\n\n for (let i = max; i >= min; i--) {\n let prefix = base.slice(0, i).join(THEME_NAME_SEPARATOR)\n if (props.inverse) {\n prefix = inverseThemeName(prefix)\n }\n const potentials: string[] = []\n if (prefix && prefix !== parentBaseTheme) {\n potentials.push(prefix)\n }\n if (nextName) {\n potentials.unshift(prefix ? `${prefix}_${nextName}` : nextName)\n }\n if (i === 1) {\n const lastSegment = potentials.findIndex((x) => !x.includes('_'))\n if (lastSegment > 0) {\n potentials.splice(lastSegment, 0, nextName) // last try prefer our new name to parent\n }\n }\n if (componentName) {\n // components only look for component themes\n if (nextName) {\n const beforeSeparator = prefix.slice(0, prefix.indexOf(THEME_NAME_SEPARATOR))\n potentials.push(`${beforeSeparator}_${nextName}_${componentName}`)\n }\n potentials.push(`${prefix}_${componentName}`)\n if (nextName) {\n potentials.unshift(`${prefix}_${nextName}_${componentName}`)\n }\n }\n\n const found = potentials.find((t) => t in themes)\n\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.log(' - ', { found, potentials })\n }\n\n if (found) {\n result = {\n name: found,\n theme: getThemeUnwrapped(themes[found]),\n className: getNextThemeClassName(found, props),\n parentName,\n }\n break\n }\n }\n\n // eslint-disable-next-line no-console\n if (process.env.NODE_ENV === 'development' && typeof props.debug === 'string') {\n console.warn('ThemeManager.getState():', {\n result,\n })\n console.trace()\n console.groupEnd()\n }\n\n return result\n}\n\nconst inverseThemeName = (themeName: string) => {\n return themeName.startsWith('light')\n ? themeName.replace(/^light/, 'dark')\n : themeName.replace(/^dark/, 'light')\n}\n\nexport function getNonComponentParentManager(themeManager?: ThemeManager | null) {\n // components never inherit from components\n // example <Switch><Switch.Thumb /></Switch>\n // the Switch theme shouldn't be considered parent of Thumb\n let res = themeManager\n while (res) {\n if (res?.isComponent) {\n res = res.parentManager\n } else {\n break\n }\n }\n return res\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["lastSegment"]
7
7
  }
@@ -60,7 +60,11 @@ if (process.env.TAMAGUI_TARGET === "native") {
60
60
  cursor: true,
61
61
  contain: true,
62
62
  boxSizing: true,
63
- boxShadow: true
63
+ boxShadow: true,
64
+ outlineStyle: true,
65
+ outlineOffset: true,
66
+ outlineWidth: true,
67
+ outlineColor: true
64
68
  });
65
69
  }
66
70
  const accessibilityDirectMap = {};
@@ -402,7 +406,7 @@ const getSplitStyles = (props, staticConfig, theme, state, parentSplitStyles, la
402
406
  isMedia = isMediaKey(key);
403
407
  isPseudo = key in validPseudoKeys;
404
408
  const isMediaOrPseudo = isMedia || isPseudo;
405
- if (!isMediaOrPseudo && usedKeys[key]) {
409
+ if (!isMediaOrPseudo && key in usedKeys) {
406
410
  if (process.env.NODE_ENV === "developmnet" && debug === "verbose") {
407
411
  console.log(`Used media/pseudo ${key}`);
408
412
  }
@@ -450,7 +454,7 @@ const getSplitStyles = (props, staticConfig, theme, state, parentSplitStyles, la
450
454
  }
451
455
  }
452
456
  } else {
453
- if (usedKeys[key]) {
457
+ if (key in usedKeys) {
454
458
  continue;
455
459
  }
456
460
  let isDisabled = !state[descriptor.stateKey || descriptor.name];
@@ -791,6 +795,11 @@ const getSubStyle = (styleState, subKey, styleIn, avoidDefaultProps, avoidMergeT
791
795
  languageContext,
792
796
  avoidDefaultProps
793
797
  );
798
+ if (!staticConfig.isHOC) {
799
+ if (key in skipProps) {
800
+ continue;
801
+ }
802
+ }
794
803
  if (!expanded)
795
804
  continue;
796
805
  for (const [skey, sval] of expanded) {