@tamagui/core 1.0.1-beta.217 → 1.0.1-beta.219

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 (38) hide show
  1. package/dist/cjs/createComponent.js +6 -4
  2. package/dist/cjs/createComponent.js.map +2 -2
  3. package/dist/cjs/helpers/getSplitStyles.js +8 -4
  4. package/dist/cjs/helpers/getSplitStyles.js.map +2 -2
  5. package/dist/cjs/helpers/getStylesAtomic.js +2 -4
  6. package/dist/cjs/helpers/getStylesAtomic.js.map +2 -2
  7. package/dist/cjs/helpers/themeable.js +5 -10
  8. package/dist/cjs/helpers/themeable.js.map +2 -2
  9. package/dist/cjs/hooks/useMedia.js +1 -9
  10. package/dist/cjs/hooks/useMedia.js.map +2 -2
  11. package/dist/cjs/hooks/useTheme.js +28 -12
  12. package/dist/cjs/hooks/useTheme.js.map +2 -2
  13. package/dist/cjs/views/ThemeInverse.js +22 -16
  14. package/dist/cjs/views/ThemeInverse.js.map +2 -2
  15. package/dist/esm/createComponent.js +6 -4
  16. package/dist/esm/createComponent.js.map +2 -2
  17. package/dist/esm/helpers/getSplitStyles.js +8 -4
  18. package/dist/esm/helpers/getSplitStyles.js.map +2 -2
  19. package/dist/esm/helpers/getStylesAtomic.js +2 -4
  20. package/dist/esm/helpers/getStylesAtomic.js.map +2 -2
  21. package/dist/esm/helpers/themeable.js +5 -10
  22. package/dist/esm/helpers/themeable.js.map +2 -2
  23. package/dist/esm/hooks/useMedia.js +1 -9
  24. package/dist/esm/hooks/useMedia.js.map +2 -2
  25. package/dist/esm/hooks/useTheme.js +28 -12
  26. package/dist/esm/hooks/useTheme.js.map +2 -2
  27. package/dist/esm/views/ThemeInverse.js +21 -16
  28. package/dist/esm/views/ThemeInverse.js.map +2 -2
  29. package/package.json +12 -12
  30. package/src/createComponent.tsx +8 -6
  31. package/src/helpers/getSplitStyles.tsx +7 -4
  32. package/src/helpers/getStylesAtomic.ts +2 -4
  33. package/src/helpers/themeable.tsx +4 -8
  34. package/src/hooks/useMedia.tsx +2 -10
  35. package/src/hooks/useTheme.tsx +35 -20
  36. package/src/views/ThemeInverse.tsx +27 -19
  37. package/types/hooks/useTheme.d.ts +1 -1
  38. package/types/views/ThemeInverse.d.ts +5 -2
@@ -1,31 +1,36 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useIsomorphicLayoutEffect } from "@tamagui/constants";
2
+ import { isWeb, useIsomorphicLayoutEffect } from "@tamagui/constants";
3
3
  import { useState } from "react";
4
4
  import { useDefaultThemeName, useThemeName } from "../hooks/useTheme";
5
5
  import { Theme } from "./Theme";
6
- const ThemeInverse = ({
7
- children,
8
- disable
9
- }) => {
6
+ const toggleTheme = (themeName) => {
7
+ return themeName.startsWith("light") ? "dark" : "light";
8
+ };
9
+ const useThemeInverse = (props = {}) => {
10
10
  const themeName = useThemeName();
11
11
  const defaultTheme = useDefaultThemeName();
12
12
  const [name, setName] = useState(null);
13
- useIsomorphicLayoutEffect(() => {
14
- if (themeName.startsWith("dark")) {
15
- setName("light");
16
- } else if (themeName.startsWith("light")) {
17
- setName("dark");
18
- }
19
- }, [defaultTheme, themeName]);
20
- if (disable) {
21
- return children;
13
+ if (isWeb) {
14
+ useIsomorphicLayoutEffect(() => {
15
+ setName(toggleTheme(themeName || defaultTheme || ""));
16
+ }, [defaultTheme, themeName]);
22
17
  }
18
+ return props.disable ? null : name;
19
+ };
20
+ const ThemeInverse = ({
21
+ children,
22
+ disable
23
+ }) => {
24
+ const inverseTheme = useThemeInverse({
25
+ disable
26
+ });
23
27
  return /* @__PURE__ */ jsx(Theme, {
24
- name,
28
+ name: inverseTheme,
25
29
  children
26
30
  });
27
31
  };
28
32
  export {
29
- ThemeInverse
33
+ ThemeInverse,
34
+ useThemeInverse
30
35
  };
31
36
  //# sourceMappingURL=ThemeInverse.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/views/ThemeInverse.tsx"],
4
- "sourcesContent": ["import { useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport React, { useState } from 'react'\n\nimport { useDefaultThemeName, useThemeName } from '../hooks/useTheme'\nimport { Theme } from './Theme'\n\nexport const ThemeInverse = ({\n children,\n disable,\n}: {\n children: React.ReactNode\n disable?: boolean\n}) => {\n const themeName = useThemeName()\n const defaultTheme = useDefaultThemeName()\n const [name, setName] = useState<null | string>(null)\n\n // ssr\n useIsomorphicLayoutEffect(() => {\n if (themeName.startsWith('dark')) {\n setName('light')\n } else if (themeName.startsWith('light')) {\n setName('dark')\n }\n }, [defaultTheme, themeName])\n\n if (disable) {\n return children as JSX.Element\n }\n\n return <Theme name={name}>{children}</Theme>\n}\n"],
5
- "mappings": "AA8BS;AA9BT,SAAS,iCAAiC;AAC1C,SAAgB,gBAAgB;AAEhC,SAAS,qBAAqB,oBAAoB;AAClD,SAAS,aAAa;AAEf,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAGM;AACJ,QAAM,YAAY,aAAa;AAC/B,QAAM,eAAe,oBAAoB;AACzC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAwB,IAAI;AAGpD,4BAA0B,MAAM;AAC9B,QAAI,UAAU,WAAW,MAAM,GAAG;AAChC,cAAQ,OAAO;AAAA,IACjB,WAAW,UAAU,WAAW,OAAO,GAAG;AACxC,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,cAAc,SAAS,CAAC;AAE5B,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAEA,SAAO,oBAAC;AAAA,IAAM;AAAA,IAAa;AAAA,GAAS;AACtC;",
4
+ "sourcesContent": ["import { isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport React, { useState } from 'react'\n\nimport { useDefaultThemeName, useThemeName } from '../hooks/useTheme'\nimport { Theme } from './Theme'\n\nexport type ThemeInverseProps = {\n disable?: boolean\n}\n\nconst toggleTheme = (themeName: string) => {\n return themeName.startsWith('light') ? 'dark' : 'light'\n}\n\nexport const useThemeInverse = (props: ThemeInverseProps = {}) => {\n const themeName = useThemeName()\n const defaultTheme = useDefaultThemeName()\n const [name, setName] = useState<null | string>(null)\n\n if (isWeb) {\n // for SSR must be in effect\n useIsomorphicLayoutEffect(() => {\n setName(toggleTheme(themeName || defaultTheme || ''))\n }, [defaultTheme, themeName])\n }\n\n return props.disable ? null : name\n}\n\nexport const ThemeInverse = ({\n children,\n disable,\n}: ThemeInverseProps & {\n children: React.ReactNode\n}) => {\n const inverseTheme = useThemeInverse({\n disable,\n })\n return <Theme name={inverseTheme}>{children}</Theme>\n}\n"],
5
+ "mappings": "AAsCS;AAtCT,SAAS,OAAO,iCAAiC;AACjD,SAAgB,gBAAgB;AAEhC,SAAS,qBAAqB,oBAAoB;AAClD,SAAS,aAAa;AAMtB,MAAM,cAAc,CAAC,cAAsB;AACzC,SAAO,UAAU,WAAW,OAAO,IAAI,SAAS;AAClD;AAEO,MAAM,kBAAkB,CAAC,QAA2B,CAAC,MAAM;AAChE,QAAM,YAAY,aAAa;AAC/B,QAAM,eAAe,oBAAoB;AACzC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAwB,IAAI;AAEpD,MAAI,OAAO;AAET,8BAA0B,MAAM;AAC9B,cAAQ,YAAY,aAAa,gBAAgB,EAAE,CAAC;AAAA,IACtD,GAAG,CAAC,cAAc,SAAS,CAAC;AAAA,EAC9B;AAEA,SAAO,MAAM,UAAU,OAAO;AAChC;AAEO,MAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAEM;AACJ,QAAM,eAAe,gBAAgB;AAAA,IACnC;AAAA,EACF,CAAC;AACD,SAAO,oBAAC;AAAA,IAAM,MAAM;AAAA,IAAe;AAAA,GAAS;AAC9C;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/core",
3
- "version": "1.0.1-beta.217",
3
+ "version": "1.0.1-beta.219",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/cjs",
6
6
  "module": "dist/esm",
@@ -28,23 +28,23 @@
28
28
  ],
29
29
  "dependencies": {
30
30
  "@expo/match-media": "^0.3.0",
31
- "@tamagui/compose-refs": "^1.0.1-beta.217",
32
- "@tamagui/constants": "^1.0.1-beta.217",
33
- "@tamagui/helpers": "^1.0.1-beta.217",
34
- "@tamagui/normalize-css-color-lite": "^1.0.1-beta.217",
35
- "@tamagui/react-native-use-pressable": "^1.0.1-beta.217",
36
- "@tamagui/react-native-use-responder-events": "^1.0.1-beta.217",
37
- "@tamagui/types-react-native": "^1.0.1-beta.217",
38
- "@tamagui/use-did-finish-ssr": "^1.0.1-beta.217",
39
- "@tamagui/use-event": "^1.0.1-beta.217",
40
- "@tamagui/use-force-update": "^1.0.1-beta.217"
31
+ "@tamagui/compose-refs": "^1.0.1-beta.219",
32
+ "@tamagui/constants": "^1.0.1-beta.219",
33
+ "@tamagui/helpers": "^1.0.1-beta.219",
34
+ "@tamagui/normalize-css-color-lite": "^1.0.1-beta.219",
35
+ "@tamagui/react-native-use-pressable": "^1.0.1-beta.219",
36
+ "@tamagui/react-native-use-responder-events": "^1.0.1-beta.219",
37
+ "@tamagui/types-react-native": "^1.0.1-beta.219",
38
+ "@tamagui/use-did-finish-ssr": "^1.0.1-beta.219",
39
+ "@tamagui/use-event": "^1.0.1-beta.219",
40
+ "@tamagui/use-force-update": "^1.0.1-beta.219"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "react": ">=18",
44
44
  "react-dom": ">=18"
45
45
  },
46
46
  "devDependencies": {
47
- "@tamagui/build": "^1.0.1-beta.217",
47
+ "@tamagui/build": "^1.0.1-beta.219",
48
48
  "@types/node": "^16.11.9",
49
49
  "@types/react": "^18.0.15",
50
50
  "@types/react-native": "^0.69.2",
@@ -212,8 +212,13 @@ export function createComponent<
212
212
  }
213
213
  }
214
214
 
215
+ const shouldAvoidClasses =
216
+ !isWeb || !!(props.animation && avoidClassesWhileAnimating) || !staticConfig.acceptsClassName
217
+ const shouldForcePseudo = !!propsIn.forceStyle
218
+ const noClassNames = shouldAvoidClasses || shouldForcePseudo
219
+
215
220
  const forceUpdate = useForceUpdate()
216
- const theme = useTheme(props.theme, componentName, props, forceUpdate)
221
+ const theme = useTheme(props.theme, componentName, props, forceUpdate, !noClassNames)
217
222
 
218
223
  const shouldSetMounted = needsMount && state.unmounted
219
224
  const setMounted = shouldSetMounted
@@ -230,12 +235,7 @@ export function createComponent<
230
235
  }
231
236
  : undefined
232
237
 
233
- const shouldAvoidClasses =
234
- !isWeb || !!(props.animation && avoidClassesWhileAnimating) || !staticConfig.acceptsClassName
235
-
236
- const shouldForcePseudo = !!propsIn.forceStyle
237
238
  const hasTextAncestor = !!(isWeb && isText ? useContext(TextAncestorContext) : false)
238
- const noClassNames = shouldAvoidClasses || shouldForcePseudo
239
239
  const languageContext = isRSC ? null : useContext(FontLanguageContext)
240
240
  const isDisabled = props.disabled ?? props.accessibilityState?.disabled
241
241
 
@@ -676,6 +676,8 @@ export function createComponent<
676
676
  for (const style of styles) {
677
677
  if (style?.fontFamily) {
678
678
  style.fontFamily = overrideFace
679
+ delete style.fontWeight
680
+ delete style.fontStyle
679
681
  }
680
682
  }
681
683
  }
@@ -196,7 +196,7 @@ export const getSplitStyles: StyleSplitter = (
196
196
  const shouldDoClasses =
197
197
  staticConfig.acceptsClassName && (isWeb || IS_STATIC) && !state.noClassNames
198
198
 
199
- const style: ViewStyle = {}
199
+ let style: ViewStyle = {}
200
200
  let flatTransforms: Record<string, any> | undefined
201
201
 
202
202
  const len = propKeys.length
@@ -537,7 +537,7 @@ export const getSplitStyles: StyleSplitter = (
537
537
  conf,
538
538
  languageContext,
539
539
  true,
540
- true
540
+ state.noClassNames
541
541
  )
542
542
 
543
543
  const descriptor = pseudoDescriptors[key as keyof typeof pseudoDescriptors]
@@ -554,6 +554,7 @@ export const getSplitStyles: StyleSplitter = (
554
554
 
555
555
  if (shouldDoClasses) {
556
556
  const pseudoStyles = getAtomicStyle(pseudoStyleObject, descriptor)
557
+ if (debug) console.log('pseudoStyles', pseudoStyles)
557
558
  for (const psuedoStyle of pseudoStyles) {
558
559
  const fullKey = `${psuedoStyle.property}${PROP_SPLIT}${descriptor.name}`
559
560
  if (!usedKeys[fullKey]) {
@@ -612,7 +613,7 @@ export const getSplitStyles: StyleSplitter = (
612
613
  languageContext,
613
614
  // TODO try true like pseudo
614
615
  false,
615
- true
616
+ state.noClassNames
616
617
  )
617
618
 
618
619
  if (process.env.NODE_ENV === 'development' && debug === 'verbose') {
@@ -656,7 +657,6 @@ export const getSplitStyles: StyleSplitter = (
656
657
  }
657
658
 
658
659
  if (validStyleProps[key]) {
659
- usedKeys[key] = 1
660
660
  mergeStyle(key, val)
661
661
  continue
662
662
  }
@@ -725,6 +725,9 @@ export const getSplitStyles: StyleSplitter = (
725
725
  addStyleToInsertRules(rulesToInsert, atomicStyle)
726
726
  mergeClassName(transforms, classNames, key, atomicStyle.identifier)
727
727
  }
728
+ if (!IS_STATIC) {
729
+ style = {}
730
+ }
728
731
  }
729
732
  }
730
733
 
@@ -78,10 +78,8 @@ const generateAtomicStyles = (
78
78
  const style = styleIn as Record<string, string | null | undefined>
79
79
 
80
80
  // transform
81
- if (style.transform) {
82
- if (Array.isArray(style.transform)) {
83
- style.transform = style.transform.map(mapTransform).join(' ')
84
- }
81
+ if (style.transform && Array.isArray(style.transform)) {
82
+ style.transform = style.transform.map(mapTransform).join(' ')
85
83
  }
86
84
 
87
85
  styleToCSS(style)
@@ -16,17 +16,13 @@ export function themeable<Component extends (props: any) => any>(
16
16
  const withThemeComponent = forwardRef(function WithTheme(props: any, ref) {
17
17
  const { themeInverse, theme, ...rest } = props
18
18
  const element = React.createElement(component, { ...rest, ref } as any)
19
- if (themeInverse) {
20
- return <ThemeInverse>{element}</ThemeInverse>
21
- }
22
- if (theme || opts) {
23
- return (
19
+ return (
20
+ <ThemeInverse disable={!themeInverse}>
24
21
  <Theme componentName={opts?.componentName} name={(theme as any) || null}>
25
22
  {element}
26
23
  </Theme>
27
- )
28
- }
29
- return element
24
+ </ThemeInverse>
25
+ )
30
26
  })
31
27
 
32
28
  const withTheme: any = withThemeComponent
@@ -1,5 +1,4 @@
1
- import { useIsomorphicLayoutEffect } from '@tamagui/constants'
2
- import { MutableRefObject, useEffect, useMemo, useState, useSyncExternalStore } from 'react'
1
+ import { useEffect, useMemo, useSyncExternalStore } from 'react'
3
2
 
4
3
  import { getConfig } from '../config'
5
4
  import { createProxy } from '../helpers/createProxy'
@@ -140,16 +139,9 @@ export function useMediaListeners(config: TamaguiInternalConfig) {
140
139
  }, [])
141
140
  }
142
141
 
143
- const nextTick = process.nextTick || setImmediate
144
142
  const currentStateListeners = new Set<any>()
145
- let isUpdating = false
146
143
  function updateCurrentState() {
147
- if (isUpdating) return
148
- isUpdating = true
149
- nextTick(() => {
150
- currentStateListeners.forEach((cb) => cb(mediaState))
151
- isUpdating = false
152
- })
144
+ currentStateListeners.forEach((cb) => cb(mediaState))
153
145
  }
154
146
  function subscribe(subscriber: any) {
155
147
  currentStateListeners.add(subscriber)
@@ -37,7 +37,8 @@ export const useTheme = (
37
37
  themeName?: string | null,
38
38
  componentName?: string,
39
39
  props?: ThemeProps,
40
- forceUpdate?: any
40
+ forceUpdate?: any,
41
+ disableTracking?: boolean
41
42
  ): ThemeParsed => {
42
43
  // TODO this can use useChangeThemeEffect almost ready
43
44
  if (isRSC) {
@@ -99,18 +100,40 @@ export const useTheme = (
99
100
  }
100
101
 
101
102
  return useMemo(() => {
102
- return getThemeProxied(theme, name, className, themeManager, state, debugProp)
103
- }, [theme, name, className, themeManager, state, debugProp])
103
+ return getThemeProxied({
104
+ theme,
105
+ name,
106
+ className,
107
+ themeManager,
108
+ onStringKeyAccess(key) {
109
+ if (disableTracking) return
110
+ if (state) {
111
+ if (state.current.isRendering && !state.current.keys.has(key)) {
112
+ state.current.keys.add(key)
113
+ if (process.env.NODE_ENV === 'development' && debugProp === 'verbose') {
114
+ // eslint-disable-next-line no-console
115
+ console.log(' 🔸 tracking theme', key)
116
+ }
117
+ }
118
+ }
119
+ },
120
+ })
121
+ }, [theme, name, className, themeManager, debugProp, disableTracking])
104
122
  }
105
123
 
106
- function getThemeProxied(
107
- theme: any,
108
- name: string,
109
- className?: string,
110
- themeManager?: ThemeManager | null,
111
- state?: React.MutableRefObject<UseThemeState>,
112
- debugProp?: boolean | 'verbose'
113
- ) {
124
+ function getThemeProxied({
125
+ theme,
126
+ name,
127
+ className,
128
+ themeManager,
129
+ onStringKeyAccess,
130
+ }: {
131
+ theme: any
132
+ name: string
133
+ onStringKeyAccess?: (cb: string) => void
134
+ className?: string
135
+ themeManager?: ThemeManager | null
136
+ }) {
114
137
  return createProxy(theme, {
115
138
  has(_, key) {
116
139
  if (typeof key === 'string' && key[0] === '$') {
@@ -141,15 +164,7 @@ function getThemeProxied(
141
164
  if (!themeManager) {
142
165
  return theme[key]
143
166
  }
144
- if (state) {
145
- if (state.current.isRendering && !state.current.keys.has(key)) {
146
- state.current.keys.add(key)
147
- if (process.env.NODE_ENV === 'development' && debugProp === 'verbose') {
148
- // eslint-disable-next-line no-console
149
- console.log(' 🔸 tracking theme', key)
150
- }
151
- }
152
- }
167
+ onStringKeyAccess?.(key)
153
168
  return themeManager.getValue(key)
154
169
  },
155
170
  })
@@ -1,32 +1,40 @@
1
- import { useIsomorphicLayoutEffect } from '@tamagui/constants'
1
+ import { isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
2
2
  import React, { useState } from 'react'
3
3
 
4
4
  import { useDefaultThemeName, useThemeName } from '../hooks/useTheme'
5
5
  import { Theme } from './Theme'
6
6
 
7
- export const ThemeInverse = ({
8
- children,
9
- disable,
10
- }: {
11
- children: React.ReactNode
7
+ export type ThemeInverseProps = {
12
8
  disable?: boolean
13
- }) => {
9
+ }
10
+
11
+ const toggleTheme = (themeName: string) => {
12
+ return themeName.startsWith('light') ? 'dark' : 'light'
13
+ }
14
+
15
+ export const useThemeInverse = (props: ThemeInverseProps = {}) => {
14
16
  const themeName = useThemeName()
15
17
  const defaultTheme = useDefaultThemeName()
16
18
  const [name, setName] = useState<null | string>(null)
17
19
 
18
- // ssr
19
- useIsomorphicLayoutEffect(() => {
20
- if (themeName.startsWith('dark')) {
21
- setName('light')
22
- } else if (themeName.startsWith('light')) {
23
- setName('dark')
24
- }
25
- }, [defaultTheme, themeName])
26
-
27
- if (disable) {
28
- return children as JSX.Element
20
+ if (isWeb) {
21
+ // for SSR must be in effect
22
+ useIsomorphicLayoutEffect(() => {
23
+ setName(toggleTheme(themeName || defaultTheme || ''))
24
+ }, [defaultTheme, themeName])
29
25
  }
30
26
 
31
- return <Theme name={name}>{children}</Theme>
27
+ return props.disable ? null : name
28
+ }
29
+
30
+ export const ThemeInverse = ({
31
+ children,
32
+ disable,
33
+ }: ThemeInverseProps & {
34
+ children: React.ReactNode
35
+ }) => {
36
+ const inverseTheme = useThemeInverse({
37
+ disable,
38
+ })
39
+ return <Theme name={inverseTheme}>{children}</Theme>
32
40
  }
@@ -9,7 +9,7 @@ export interface ThemeProps {
9
9
  reset?: boolean;
10
10
  debug?: boolean | 'verbose';
11
11
  }
12
- export declare const useTheme: (themeName?: string | null, componentName?: string, props?: ThemeProps, forceUpdate?: any) => ThemeParsed;
12
+ export declare const useTheme: (themeName?: string | null, componentName?: string, props?: ThemeProps, forceUpdate?: any, disableTracking?: boolean) => ThemeParsed;
13
13
  export declare const getThemeManager: (theme: any) => ThemeManager | undefined;
14
14
  export declare function useThemeName(opts?: {
15
15
  parent?: true;
@@ -1,6 +1,9 @@
1
1
  import React from 'react';
2
- export declare const ThemeInverse: ({ children, disable, }: {
2
+ export declare type ThemeInverseProps = {
3
+ disable?: boolean;
4
+ };
5
+ export declare const useThemeInverse: (props?: ThemeInverseProps) => string | null;
6
+ export declare const ThemeInverse: ({ children, disable, }: ThemeInverseProps & {
3
7
  children: React.ReactNode;
4
- disable?: boolean | undefined;
5
8
  }) => JSX.Element;
6
9
  //# sourceMappingURL=ThemeInverse.d.ts.map