@tamagui/web 1.101.1 → 1.101.2

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 (33) hide show
  1. package/dist/cjs/createComponent.js +1 -1
  2. package/dist/cjs/createComponent.js.map +1 -1
  3. package/dist/cjs/createComponent.native.js +1 -1
  4. package/dist/cjs/createComponent.native.js.map +2 -2
  5. package/dist/cjs/hooks/useDidHydrateOnce.js +2 -10
  6. package/dist/cjs/hooks/useDidHydrateOnce.js.map +1 -1
  7. package/dist/cjs/hooks/useDidHydrateOnce.native.js +2 -2
  8. package/dist/cjs/hooks/useDidHydrateOnce.native.js.map +2 -2
  9. package/dist/cjs/hooks/useMedia.js +35 -27
  10. package/dist/cjs/hooks/useMedia.js.map +2 -2
  11. package/dist/cjs/hooks/useMedia.native.js +34 -47
  12. package/dist/cjs/hooks/useMedia.native.js.map +2 -2
  13. package/dist/esm/createComponent.js +1 -1
  14. package/dist/esm/createComponent.js.map +1 -1
  15. package/dist/esm/createComponent.mjs +1 -1
  16. package/dist/esm/createComponent.native.js +1 -1
  17. package/dist/esm/createComponent.native.js.map +2 -2
  18. package/dist/esm/hooks/useDidHydrateOnce.js +3 -11
  19. package/dist/esm/hooks/useDidHydrateOnce.js.map +1 -1
  20. package/dist/esm/hooks/useDidHydrateOnce.mjs +3 -11
  21. package/dist/esm/hooks/useDidHydrateOnce.native.js +1 -2
  22. package/dist/esm/hooks/useDidHydrateOnce.native.js.map +2 -2
  23. package/dist/esm/hooks/useMedia.js +35 -28
  24. package/dist/esm/hooks/useMedia.js.map +2 -2
  25. package/dist/esm/hooks/useMedia.mjs +30 -37
  26. package/dist/esm/hooks/useMedia.native.js +34 -48
  27. package/dist/esm/hooks/useMedia.native.js.map +2 -2
  28. package/package.json +11 -11
  29. package/src/createComponent.tsx +1 -1
  30. package/src/hooks/useDidHydrateOnce.tsx +21 -21
  31. package/src/hooks/useMedia.tsx +69 -56
  32. package/types/hooks/useMedia.d.ts +5 -5
  33. package/types/hooks/useMedia.d.ts.map +1 -1
@@ -1,6 +1,7 @@
1
1
  import { isServer, isWeb, useIsomorphicLayoutEffect } from '@tamagui/constants'
2
- import { useRef, useState } from 'react'
3
- import { getConfig } from '../config'
2
+ import { useRef, useState, useSyncExternalStore } from 'react'
3
+
4
+ import { getConfig, setTokens } from '../config'
4
5
  import { matchMedia } from '../helpers/matchMedia'
5
6
  import { pseudoDescriptors } from '../helpers/pseudoDescriptors'
6
7
  import type {
@@ -8,12 +9,12 @@ import type {
8
9
  DebugProp,
9
10
  IsMediaType,
10
11
  MediaQueries,
12
+ MediaQueryKey,
11
13
  MediaQueryObject,
12
14
  MediaQueryState,
13
15
  TamaguiInternalConfig,
14
16
  UseMediaState,
15
17
  } from '../types'
16
- import { useDidHydrateOnce } from './useDidHydrateOnce'
17
18
  import { getDisableSSR } from './useDisableSSR'
18
19
 
19
20
  export let mediaState: MediaQueryState =
@@ -120,9 +121,7 @@ export function setupMediaListeners() {
120
121
  setupVersion = mediaVersion
121
122
 
122
123
  // hmr, undo existing before re-binding
123
- if (process.env.NODE_ENV === 'development') {
124
- unlisten()
125
- }
124
+ unlisten()
126
125
 
127
126
  for (const key in mediaQueryConfig) {
128
127
  const str = mediaObjectToString(mediaQueryConfig[key], key)
@@ -169,46 +168,42 @@ type MediaKeysState = {
169
168
  [key: string]: any
170
169
  }
171
170
 
172
- type UpdateState = {
171
+ type MediaState = {
172
+ prev?: MediaKeysState
173
173
  enabled?: boolean
174
- prev: MediaKeysState
175
- touched?: string[] | null
174
+ keys?: MediaQueryKey[] | null
176
175
  }
177
176
 
178
- const States = new WeakMap<any, UpdateState>()
177
+ const States = new WeakMap<any, MediaState>()
179
178
 
180
- export function setMediaShouldUpdate(ref: any, props: Partial<UpdateState>) {
179
+ export function setMediaShouldUpdate(ref: any, props: MediaState) {
181
180
  return States.set(ref, {
182
181
  ...(States.get(ref) as any),
183
182
  ...props,
184
183
  })
185
184
  }
186
185
 
187
- function getSnapshot({ touched, prev, enabled }: UpdateState) {
188
- if (enabled === false) {
189
- return prev
190
- }
191
- const hasntUpdated = !touched || touched.every((key) => mediaState[key] === prev[key])
192
- if (hasntUpdated) {
193
- return prev
194
- }
195
- return mediaState
186
+ type UseMediaInternalState = {
187
+ prev: MediaKeysState
188
+ keys?: string[]
196
189
  }
197
190
 
198
- // TODO once you touch a media key it never untouches, to avoid an extra useEffect on every component
199
- // ideally we don't do that, but useMedia usage is lower and generally its not super expensive
200
- // i think in the future we implement this by sharing a single useEffect in createComponent somehow
191
+ function subscribe(subscriber: any) {
192
+ listeners.add(subscriber)
193
+ return () => {
194
+ listeners.delete(subscriber)
195
+ }
196
+ }
201
197
 
202
198
  export function useMedia(
203
199
  uidIn?: any,
204
200
  componentContext?: ComponentContextI,
205
- debug: DebugProp = false
201
+ debug?: DebugProp
206
202
  ): UseMediaState {
207
203
  const uid = uidIn ?? useRef()
208
-
209
- const hasHydrated = useDidHydrateOnce()
210
- const isHydrated = !isWeb || getDisableSSR(componentContext) || hasHydrated
211
- const initialState = isHydrated ? mediaState : initState
204
+ // performance boost to avoid using context twice
205
+ const disableSSR = getDisableSSR(componentContext)
206
+ const initialState = (disableSSR || !isWeb ? mediaState : initState) || {}
212
207
 
213
208
  let componentState = States.get(uid)
214
209
  if (!componentState) {
@@ -216,43 +211,61 @@ export function useMedia(
216
211
  States.set(uid, componentState)
217
212
  }
218
213
 
219
- const [state, setState] = useState(initialState)
214
+ const getSnapshot = () => {
215
+ if (!componentState) {
216
+ return initialState
217
+ }
220
218
 
221
- useIsomorphicLayoutEffect(() => {
222
- function update() {
223
- setState((prev) => {
224
- const componentState = States.get(uid)!
225
- if (process.env.NODE_ENV === 'development' && debug) {
226
- console.info('useMedia() update?', getSnapshot(componentState) !== prev, {
227
- componentState,
228
- touched: [...(componentState.touched || [])],
229
- prev: { ...componentState.prev },
230
- next: getSnapshot(componentState),
231
- mediaState: { ...mediaState },
232
- })
233
- }
234
- const next = getSnapshot(componentState)
235
- if (next !== prev) {
236
- componentState.prev = next
237
- return next
238
- }
239
- return prev
240
- })
219
+ const { keys, prev = initialState } = componentState
220
+
221
+ if (componentState && componentState.enabled === false) {
222
+ return prev
241
223
  }
242
224
 
243
- update()
225
+ const testKeys =
226
+ componentState?.keys ??
227
+ ((!componentState || componentState.enabled) && keys) ??
228
+ null
244
229
 
245
- listeners.add(update)
246
- return () => {
247
- listeners.delete(update)
230
+ const hasntUpdated =
231
+ !testKeys || testKeys?.every((key) => mediaState[key] === prev[key])
232
+
233
+ if (hasntUpdated) {
234
+ return prev
248
235
  }
249
- }, [uid])
236
+
237
+ componentState.prev = mediaState
238
+
239
+ return mediaState
240
+ }
241
+
242
+ let state: MediaQueryState
243
+
244
+ if (process.env.TAMAGUI_SYNC_MEDIA_QUERY) {
245
+ state = useSyncExternalStore<MediaQueryState>(
246
+ subscribe,
247
+ getSnapshot,
248
+ () => initialState
249
+ )
250
+ } else {
251
+ const [internalState, setState] = useState(initialState)
252
+ state = internalState
253
+
254
+ useIsomorphicLayoutEffect(() => {
255
+ function update() {
256
+ setState(getSnapshot)
257
+ }
258
+
259
+ update()
260
+ return subscribe(update)
261
+ }, [])
262
+ }
250
263
 
251
264
  return new Proxy(state, {
252
265
  get(_, key) {
253
266
  if (typeof key === 'string') {
254
- componentState.touched ||= []
255
- if (!componentState.touched.includes(key)) componentState.touched.push(key)
267
+ componentState.keys ||= []
268
+ if (!componentState.keys.includes(key)) componentState.keys.push(key)
256
269
  if (process.env.NODE_ENV === 'development' && debug) {
257
270
  console.info(`useMedia() TOUCH`, key)
258
271
  }
@@ -1,4 +1,4 @@
1
- import type { ComponentContextI, DebugProp, IsMediaType, MediaQueries, MediaQueryObject, MediaQueryState, TamaguiInternalConfig, UseMediaState } from '../types';
1
+ import type { ComponentContextI, DebugProp, IsMediaType, MediaQueries, MediaQueryKey, MediaQueryObject, MediaQueryState, TamaguiInternalConfig, UseMediaState } from '../types';
2
2
  export declare let mediaState: MediaQueryState;
3
3
  export declare const mediaQueryConfig: MediaQueries;
4
4
  export declare const getMedia: () => MediaQueryState;
@@ -10,12 +10,12 @@ export declare function setupMediaListeners(): void;
10
10
  type MediaKeysState = {
11
11
  [key: string]: any;
12
12
  };
13
- type UpdateState = {
13
+ type MediaState = {
14
+ prev?: MediaKeysState;
14
15
  enabled?: boolean;
15
- prev: MediaKeysState;
16
- touched?: string[] | null;
16
+ keys?: MediaQueryKey[] | null;
17
17
  };
18
- export declare function setMediaShouldUpdate(ref: any, props: Partial<UpdateState>): WeakMap<any, UpdateState>;
18
+ export declare function setMediaShouldUpdate(ref: any, props: MediaState): WeakMap<any, MediaState>;
19
19
  export declare function useMedia(uidIn?: any, componentContext?: ComponentContextI, debug?: DebugProp): UseMediaState;
20
20
  export declare const getMediaImportanceIfMoreImportant: (mediaKey: string, key: string, importancesUsed: Record<string, number>, isSizeMedia: boolean) => number | null;
21
21
  export declare function mediaObjectToString(query: string | MediaQueryObject, key?: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"useMedia.d.ts","sourceRoot":"","sources":["../../src/hooks/useMedia.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,aAAa,EACd,MAAM,UAAU,CAAA;AAIjB,eAAO,IAAI,UAAU,EAAE,eAmBN,CAAA;AAEjB,eAAO,MAAM,gBAAgB,EAAE,YAAiB,CAAA;AAEhD,eAAO,MAAM,QAAQ,uBAAmB,CAAA;AAExC,eAAO,MAAM,SAAS,aAAoB,CAAA;AAI1C,eAAO,MAAM,UAAU,QAAS,MAAM,KAAG,WAOxC,CAAA;AAUD,eAAO,MAAM,qBAAqB,QAAS,MAAM,WAchD,CAAA;AAMD,eAAO,MAAM,cAAc,WAAY,qBAAqB,SAiB3D,CAAA;AAaD,wBAAgB,mBAAmB,SAmClC;AAkBD,KAAK,cAAc,GAAG;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,cAAc,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAC1B,CAAA;AAID,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,6BAKzE;AAiBD,wBAAgB,QAAQ,CACtB,KAAK,CAAC,EAAE,GAAG,EACX,gBAAgB,CAAC,EAAE,iBAAiB,EACpC,KAAK,GAAE,SAAiB,GACvB,aAAa,CAyDf;AAED,eAAO,MAAM,iCAAiC,aAClC,MAAM,OACX,MAAM,mBACM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,eAC1B,OAAO,kBAQrB,CAAA;AASD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,CAAC,EAAE,MAAM,UAwBjF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,UAE1C;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,WAY9C"}
1
+ {"version":3,"file":"useMedia.d.ts","sourceRoot":"","sources":["../../src/hooks/useMedia.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,aAAa,EACd,MAAM,UAAU,CAAA;AAGjB,eAAO,IAAI,UAAU,EAAE,eAmBN,CAAA;AAEjB,eAAO,MAAM,gBAAgB,EAAE,YAAiB,CAAA;AAEhD,eAAO,MAAM,QAAQ,uBAAmB,CAAA;AAExC,eAAO,MAAM,SAAS,aAAoB,CAAA;AAI1C,eAAO,MAAM,UAAU,QAAS,MAAM,KAAG,WAOxC,CAAA;AAUD,eAAO,MAAM,qBAAqB,QAAS,MAAM,WAchD,CAAA;AAMD,eAAO,MAAM,cAAc,WAAY,qBAAqB,SAiB3D,CAAA;AAaD,wBAAgB,mBAAmB,SAiClC;AAkBD,KAAK,cAAc,GAAG;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,aAAa,EAAE,GAAG,IAAI,CAAA;CAC9B,CAAA;AAID,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,4BAK/D;AAcD,wBAAgB,QAAQ,CACtB,KAAK,CAAC,EAAE,GAAG,EACX,gBAAgB,CAAC,EAAE,iBAAiB,EACpC,KAAK,CAAC,EAAE,SAAS,GAChB,aAAa,CA0Ef;AAED,eAAO,MAAM,iCAAiC,aAClC,MAAM,OACX,MAAM,mBACM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,eAC1B,OAAO,kBAQrB,CAAA;AASD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,CAAC,EAAE,MAAM,UAwBjF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,UAE1C;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,WAY9C"}