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

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 (42) hide show
  1. package/dist/cjs/createComponent.js +39 -81
  2. package/dist/cjs/createComponent.js.map +2 -2
  3. package/dist/cjs/createTamagui.js +2 -2
  4. package/dist/cjs/createTamagui.js.map +1 -1
  5. package/dist/cjs/helpers/createPropMapper.js.map +2 -2
  6. package/dist/cjs/helpers/getSplitStyles.js +44 -38
  7. package/dist/cjs/helpers/getSplitStyles.js.map +3 -3
  8. package/dist/cjs/helpers/mergeProps.js.map +2 -2
  9. package/dist/cjs/helpers/normalizeValueWithProperty.js +7 -2
  10. package/dist/cjs/helpers/normalizeValueWithProperty.js.map +2 -2
  11. package/dist/cjs/helpers/useShallowSetState.js.map +2 -2
  12. package/dist/cjs/hooks/useMedia.js +43 -38
  13. package/dist/cjs/hooks/useMedia.js.map +2 -2
  14. package/dist/cjs/views/ThemeInverse.js +1 -2
  15. package/dist/cjs/views/ThemeInverse.js.map +2 -2
  16. package/dist/esm/createComponent.js +41 -87
  17. package/dist/esm/createComponent.js.map +2 -2
  18. package/dist/esm/createTamagui.js +2 -2
  19. package/dist/esm/createTamagui.js.map +1 -1
  20. package/dist/esm/helpers/createPropMapper.js.map +2 -2
  21. package/dist/esm/helpers/getSplitStyles.js +44 -38
  22. package/dist/esm/helpers/getSplitStyles.js.map +3 -3
  23. package/dist/esm/helpers/mergeProps.js.map +2 -2
  24. package/dist/esm/helpers/normalizeValueWithProperty.js +7 -2
  25. package/dist/esm/helpers/normalizeValueWithProperty.js.map +2 -2
  26. package/dist/esm/helpers/useShallowSetState.js.map +2 -2
  27. package/dist/esm/hooks/useMedia.js +44 -39
  28. package/dist/esm/hooks/useMedia.js.map +2 -2
  29. package/dist/esm/views/ThemeInverse.js +1 -2
  30. package/dist/esm/views/ThemeInverse.js.map +2 -2
  31. package/package.json +16 -16
  32. package/src/createComponent.tsx +52 -103
  33. package/src/createTamagui.ts +2 -2
  34. package/src/helpers/createPropMapper.ts +1 -0
  35. package/src/helpers/getSplitStyles.tsx +44 -37
  36. package/src/helpers/mergeProps.ts +7 -7
  37. package/src/helpers/normalizeValueWithProperty.ts +9 -2
  38. package/src/helpers/useShallowSetState.tsx +3 -1
  39. package/src/hooks/useMedia.tsx +49 -41
  40. package/src/views/ThemeInverse.tsx +1 -2
  41. package/types/helpers/mergeProps.d.ts +2 -2
  42. package/types/helpers/useShallowSetState.d.ts +2 -1
@@ -12,16 +12,16 @@
12
12
  * - shorthands can be expanded before merging
13
13
  */
14
14
 
15
- type StringRecord = Record<string, string>
15
+ type AnyRecord = Record<string, any>
16
16
 
17
17
  export const mergeProps = (
18
18
  a: Object,
19
19
  b: Object,
20
20
  leaveOutClassNames = false,
21
- inverseShorthands?: StringRecord
21
+ inverseShorthands?: AnyRecord
22
22
  ) => {
23
- const out: StringRecord = {}
24
- const outCns: StringRecord = leaveOutClassNames ? {} : (null as any)
23
+ const out: AnyRecord = {}
24
+ const outCns: AnyRecord = leaveOutClassNames ? {} : (null as any)
25
25
  for (const key in a) {
26
26
  mergeProp(out, outCns, a, b, key, leaveOutClassNames, inverseShorthands)
27
27
  }
@@ -32,13 +32,13 @@ export const mergeProps = (
32
32
  }
33
33
 
34
34
  function mergeProp(
35
- out: StringRecord,
36
- outCns: StringRecord,
35
+ out: AnyRecord,
36
+ outCns: AnyRecord,
37
37
  a: Object,
38
38
  b: Object | undefined,
39
39
  key: string,
40
40
  leaveOutClassNames: boolean,
41
- inverseShorthands?: StringRecord
41
+ inverseShorthands?: AnyRecord
42
42
  ) {
43
43
  const val = a[key]
44
44
  const shorthand = inverseShorthands ? inverseShorthands[key] : null
@@ -3,6 +3,8 @@
3
3
  * Copyright (c) Nicolas Gallagher licensed under the MIT license.
4
4
  */
5
5
 
6
+ import { isWeb } from '@tamagui/constants'
7
+
6
8
  import { getAllSelectors } from './insertStyleRule'
7
9
  import { normalizeColor } from './normalizeColor'
8
10
 
@@ -20,9 +22,11 @@ export function normalizeValueWithProperty(value: any, property?: string): any {
20
22
  if (
21
23
  process.env.TAMAGUI_TARGET === 'web' &&
22
24
  typeof value === 'number' &&
23
- (property === undefined || !unitlessNumbers[property])
25
+ (property === undefined || (!unitlessNumbers[property] && !stringNumbers[property]))
24
26
  ) {
25
27
  res = `${value}px`
28
+ } else if (isWeb && property !== undefined && stringNumbers[property]) {
29
+ res = `${res}`
26
30
  } else if (property && colorProps[property]) {
27
31
  res = normalizeColor(value)
28
32
  cache[value] = res
@@ -45,6 +49,10 @@ const colorProps = {
45
49
  textShadowColor: true,
46
50
  }
47
51
 
52
+ const stringNumbers = {
53
+ zIndex: true,
54
+ }
55
+
48
56
  const unitlessNumbers = {
49
57
  WebkitLineClamp: true,
50
58
  animationIterationCount: true,
@@ -74,7 +82,6 @@ const unitlessNumbers = {
74
82
  orphans: true,
75
83
  tabSize: true,
76
84
  widows: true,
77
- zIndex: true,
78
85
  zoom: true,
79
86
  scale: true,
80
87
  scaleX: true,
@@ -1,8 +1,10 @@
1
1
  import React, { useCallback } from 'react'
2
2
 
3
+ import { DebugProp } from '../types'
4
+
3
5
  export function useShallowSetState<State extends Object>(
4
6
  setter: React.Dispatch<React.SetStateAction<State>>,
5
- debug?: boolean | 'verbose',
7
+ debug?: DebugProp,
6
8
  debugName?: string
7
9
  ) {
8
10
  return useCallback(
@@ -1,5 +1,5 @@
1
1
  import { useIsomorphicLayoutEffect } from '@tamagui/constants'
2
- import { MutableRefObject, useEffect, useMemo, useState } from 'react'
2
+ import { MutableRefObject, useEffect, useMemo, useState, useSyncExternalStore } from 'react'
3
3
 
4
4
  import { getConfig } from '../config'
5
5
  import { createProxy } from '../helpers/createProxy'
@@ -54,15 +54,12 @@ export function removeMediaQueryListener(key: MediaQueryKey, cb: MediaListener)
54
54
 
55
55
  export const mediaQueryConfig: MediaQueries = {}
56
56
 
57
- export const getMedia = () => {
58
- return mediaState
59
- }
57
+ export const getMedia = () => mediaState
60
58
 
61
59
  // for SSR capture it at time of startup
62
- let curState: MediaQueryState
63
60
  let initState: MediaQueryState
64
61
  export const getInitialMediaState = () => {
65
- return (getConfig().disableSSR ? curState : initState) || {}
62
+ return (getConfig().disableSSR ? mediaState : initState) || {}
66
63
  }
67
64
 
68
65
  let mediaKeysOrdered: string[]
@@ -79,8 +76,8 @@ export const configureMedia = (config: TamaguiInternalConfig) => {
79
76
  mediaState[key] = mediaQueryDefaultActive?.[key] || false
80
77
  }
81
78
  Object.assign(mediaQueryConfig, media)
82
- curState = { ...mediaState }
83
- initState = curState
79
+ initState = { ...mediaState }
80
+ updateCurrentState()
84
81
  mediaKeysOrdered = Object.keys(media)
85
82
  if (config.disableSSR) {
86
83
  setupMediaListeners()
@@ -126,7 +123,7 @@ function setupMediaListeners() {
126
123
  const next = !!getMatch().matches
127
124
  if (next === mediaState[key]) return
128
125
  mediaState[key] = next
129
- curState = { ...mediaState }
126
+ updateCurrentState()
130
127
  const cur = listeners[key]
131
128
  if (cur?.size) {
132
129
  cur.forEach((cb) => cb(next))
@@ -143,45 +140,56 @@ export function useMediaListeners(config: TamaguiInternalConfig) {
143
140
  }, [])
144
141
  }
145
142
 
143
+ const nextTick = process.nextTick || setImmediate
144
+ const currentStateListeners = new Set<any>()
145
+ let isUpdating = false
146
+ function updateCurrentState() {
147
+ if (isUpdating) return
148
+ isUpdating = true
149
+ nextTick(() => {
150
+ currentStateListeners.forEach((cb) => cb(mediaState))
151
+ isUpdating = false
152
+ })
153
+ }
154
+ function subscribe(subscriber: any) {
155
+ currentStateListeners.add(subscriber)
156
+ return () => currentStateListeners.delete(subscriber)
157
+ }
158
+
159
+ type MediaKeysState = {
160
+ [key: string]: any
161
+ }
162
+
146
163
  export function useMedia(): {
147
164
  [key in MediaQueryKey]: boolean
148
165
  } {
149
- const keys = useSafeRef({} as Record<string, boolean>)
150
- const [state, setState] = useState<MediaQueryState>(() => getMediaState(initState || {}, keys))
166
+ const keys = useSafeRef<MediaKeysState>({ prev: initState })
151
167
 
152
- function updateState() {
153
- setState((prev) => {
154
- for (const key in keys.current) {
155
- if (prev[key] !== mediaState[key]) {
156
- return getMediaState({ ...mediaState }, keys)
157
- }
168
+ const state = useSyncExternalStore<MediaQueryState>(
169
+ subscribe,
170
+ () => {
171
+ const { prev, ...curKeys } = keys.current
172
+ const shouldUpdate = !prev || Object.keys(curKeys).some((k) => mediaState[k] !== prev[k])
173
+ if (shouldUpdate) {
174
+ const next = { ...mediaState }
175
+ keys.current.prev = next
176
+ return next
158
177
  }
159
178
  return prev
160
- })
161
- }
162
-
163
- useIsomorphicLayoutEffect(() => {
164
- updateState()
165
- const disposers = Object.keys(keys.current).map((key) =>
166
- addMediaQueryListener(key, updateState)
167
- )
168
- return () => {
169
- disposers.forEach((cb) => cb())
170
- }
171
- }, [keys.current])
172
-
173
- return state
174
- }
175
-
176
- function getMediaState(state: MediaQueryState, keys: MutableRefObject<Record<string, boolean>>) {
177
- return new Proxy(state, {
178
- get(_, key: string) {
179
- if (!keys.current[key]) {
180
- keys.current[key] = true
181
- }
182
- return Reflect.get(state, key)
183
179
  },
184
- })
180
+ () => initState
181
+ )
182
+
183
+ return useMemo(() => {
184
+ return new Proxy(state, {
185
+ get(_, key: string) {
186
+ if (!keys.current[key]) {
187
+ keys.current[key] = true
188
+ }
189
+ return Reflect.get(state, key)
190
+ },
191
+ })
192
+ }, [state])
185
193
  }
186
194
 
187
195
  /**
@@ -19,8 +19,7 @@ export const ThemeInverse = ({
19
19
  useIsomorphicLayoutEffect(() => {
20
20
  if (themeName.startsWith('dark')) {
21
21
  setName('light')
22
- }
23
- if (themeName.startsWith('light')) {
22
+ } else if (themeName.startsWith('light')) {
24
23
  setName('dark')
25
24
  }
26
25
  }, [defaultTheme, themeName])
@@ -11,7 +11,7 @@
11
11
  * - classNames can be extracted out separately
12
12
  * - shorthands can be expanded before merging
13
13
  */
14
- declare type StringRecord = Record<string, string>;
15
- export declare const mergeProps: (a: Object, b: Object, leaveOutClassNames?: boolean, inverseShorthands?: StringRecord) => readonly [StringRecord, StringRecord];
14
+ declare type AnyRecord = Record<string, any>;
15
+ export declare const mergeProps: (a: Object, b: Object, leaveOutClassNames?: boolean, inverseShorthands?: AnyRecord) => readonly [AnyRecord, AnyRecord];
16
16
  export {};
17
17
  //# sourceMappingURL=mergeProps.d.ts.map
@@ -1,3 +1,4 @@
1
1
  import React from 'react';
2
- export declare function useShallowSetState<State extends Object>(setter: React.Dispatch<React.SetStateAction<State>>, debug?: boolean | 'verbose', debugName?: string): (next: Partial<State>) => void;
2
+ import { DebugProp } from '../types';
3
+ export declare function useShallowSetState<State extends Object>(setter: React.Dispatch<React.SetStateAction<State>>, debug?: DebugProp, debugName?: string): (next: Partial<State>) => void;
3
4
  //# sourceMappingURL=useShallowSetState.d.ts.map