@oxyhq/bloom 0.52.0 → 0.53.0
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/lib/commonjs/bottom-sheet/BottomSheetBase.js +7 -4
- package/lib/commonjs/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/commonjs/connection-dots/ConnectionDots.web.js.map +1 -1
- package/lib/commonjs/design-tokens/shadows.js +4 -0
- package/lib/commonjs/design-tokens/shadows.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +26 -10
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/index.js +66 -66
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +90 -90
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/loading/Loading.web.js.map +1 -1
- package/lib/commonjs/loading/SpinnerIcon.web.js +10 -6
- package/lib/commonjs/loading/SpinnerIcon.web.js.map +1 -1
- package/lib/commonjs/motion/index.js +1 -1
- package/lib/commonjs/motion/index.web.js +32 -0
- package/lib/commonjs/motion/index.web.js.map +1 -0
- package/lib/commonjs/motion/motion.js +10 -2
- package/lib/commonjs/motion/motion.js.map +1 -1
- package/lib/commonjs/motion/motion.web.js +137 -0
- package/lib/commonjs/motion/motion.web.js.map +1 -0
- package/lib/commonjs/progressive-blur/index.web.js.map +1 -1
- package/lib/commonjs/styles/web-view-style.js +33 -0
- package/lib/commonjs/styles/web-view-style.js.map +1 -1
- package/lib/commonjs/tab-bar/TabBarBase.js +18 -4
- package/lib/commonjs/tab-bar/TabBarBase.js.map +1 -1
- package/lib/commonjs/tab-bar/index.js +5 -5
- package/lib/commonjs/tab-bar/index.js.map +1 -1
- package/lib/commonjs/tab-bar/index.web.js +5 -5
- package/lib/commonjs/tab-bar/index.web.js.map +1 -1
- package/lib/commonjs/tab-bar/shared.js +3 -3
- package/lib/commonjs/tab-bar/surface.web.js.map +1 -1
- package/lib/commonjs/tab-bar/use-footprint.js +56 -0
- package/lib/commonjs/tab-bar/use-footprint.js.map +1 -0
- package/lib/commonjs/toast/ToastRow.js +7 -3
- package/lib/commonjs/toast/ToastRow.js.map +1 -1
- package/lib/commonjs/toast/ToastSwipeHandler.js +29 -13
- package/lib/commonjs/toast/ToastSwipeHandler.js.map +1 -1
- package/lib/commonjs/toast/constants.js +29 -1
- package/lib/commonjs/toast/constants.js.map +1 -1
- package/lib/commonjs/toast/position-utils.js +9 -4
- package/lib/commonjs/toast/position-utils.js.map +1 -1
- package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js +12 -9
- package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
- package/lib/module/bottom-sheet/BottomSheetBase.js +7 -4
- package/lib/module/bottom-sheet/BottomSheetBase.js.map +1 -1
- package/lib/module/connection-dots/ConnectionDots.web.js.map +1 -1
- package/lib/module/design-tokens/shadows.js +4 -0
- package/lib/module/design-tokens/shadows.js.map +1 -1
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +26 -10
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -1
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/loading/Loading.web.js.map +1 -1
- package/lib/module/loading/SpinnerIcon.web.js +10 -6
- package/lib/module/loading/SpinnerIcon.web.js.map +1 -1
- package/lib/module/motion/index.js +1 -1
- package/lib/module/motion/index.js.map +1 -1
- package/lib/module/motion/index.web.js +10 -0
- package/lib/module/motion/index.web.js.map +1 -0
- package/lib/module/motion/motion.js +10 -2
- package/lib/module/motion/motion.js.map +1 -1
- package/lib/module/motion/motion.web.js +133 -0
- package/lib/module/motion/motion.web.js.map +1 -0
- package/lib/module/progressive-blur/index.web.js.map +1 -1
- package/lib/module/styles/web-view-style.js +33 -0
- package/lib/module/styles/web-view-style.js.map +1 -1
- package/lib/module/tab-bar/TabBarBase.js +18 -4
- package/lib/module/tab-bar/TabBarBase.js.map +1 -1
- package/lib/module/tab-bar/index.js +1 -1
- package/lib/module/tab-bar/index.js.map +1 -1
- package/lib/module/tab-bar/index.web.js +1 -1
- package/lib/module/tab-bar/index.web.js.map +1 -1
- package/lib/module/tab-bar/shared.js +3 -3
- package/lib/module/tab-bar/surface.web.js.map +1 -1
- package/lib/module/tab-bar/use-footprint.js +52 -0
- package/lib/module/tab-bar/use-footprint.js.map +1 -0
- package/lib/module/toast/ToastRow.js +8 -4
- package/lib/module/toast/ToastRow.js.map +1 -1
- package/lib/module/toast/ToastSwipeHandler.js +29 -13
- package/lib/module/toast/ToastSwipeHandler.js.map +1 -1
- package/lib/module/toast/constants.js +28 -1
- package/lib/module/toast/constants.js.map +1 -1
- package/lib/module/toast/position-utils.js +9 -4
- package/lib/module/toast/position-utils.js.map +1 -1
- package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js +12 -9
- package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
- package/lib/typescript/commonjs/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/connection-dots/ConnectionDots.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/design-tokens/shadows.d.ts +4 -0
- package/lib/typescript/commonjs/design-tokens/shadows.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -2
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/loading/Loading.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/loading/SpinnerIcon.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/motion/index.web.d.ts +9 -0
- package/lib/typescript/commonjs/motion/index.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/motion/motion.d.ts +14 -6
- package/lib/typescript/commonjs/motion/motion.d.ts.map +1 -1
- package/lib/typescript/commonjs/motion/motion.web.d.ts +79 -0
- package/lib/typescript/commonjs/motion/motion.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/progressive-blur/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/styles/web-view-style.d.ts +49 -0
- package/lib/typescript/commonjs/styles/web-view-style.d.ts.map +1 -1
- package/lib/typescript/commonjs/tab-bar/TabBarBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/tab-bar/index.d.ts +1 -1
- package/lib/typescript/commonjs/tab-bar/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/tab-bar/index.web.d.ts +1 -1
- package/lib/typescript/commonjs/tab-bar/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/tab-bar/shared.d.ts +3 -3
- package/lib/typescript/commonjs/tab-bar/surface.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/tab-bar/use-footprint.d.ts +31 -0
- package/lib/typescript/commonjs/tab-bar/use-footprint.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/ToastRow.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts +12 -6
- package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/constants.d.ts +26 -8
- package/lib/typescript/commonjs/toast/constants.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/position-utils.d.ts +8 -3
- package/lib/typescript/commonjs/toast/position-utils.d.ts.map +1 -1
- package/lib/typescript/commonjs/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
- package/lib/typescript/module/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
- package/lib/typescript/module/connection-dots/ConnectionDots.web.d.ts.map +1 -1
- package/lib/typescript/module/design-tokens/shadows.d.ts +4 -0
- package/lib/typescript/module/design-tokens/shadows.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -2
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/loading/Loading.web.d.ts.map +1 -1
- package/lib/typescript/module/loading/SpinnerIcon.web.d.ts.map +1 -1
- package/lib/typescript/module/motion/index.web.d.ts +9 -0
- package/lib/typescript/module/motion/index.web.d.ts.map +1 -0
- package/lib/typescript/module/motion/motion.d.ts +14 -6
- package/lib/typescript/module/motion/motion.d.ts.map +1 -1
- package/lib/typescript/module/motion/motion.web.d.ts +79 -0
- package/lib/typescript/module/motion/motion.web.d.ts.map +1 -0
- package/lib/typescript/module/progressive-blur/index.web.d.ts.map +1 -1
- package/lib/typescript/module/styles/web-view-style.d.ts +49 -0
- package/lib/typescript/module/styles/web-view-style.d.ts.map +1 -1
- package/lib/typescript/module/tab-bar/TabBarBase.d.ts.map +1 -1
- package/lib/typescript/module/tab-bar/index.d.ts +1 -1
- package/lib/typescript/module/tab-bar/index.d.ts.map +1 -1
- package/lib/typescript/module/tab-bar/index.web.d.ts +1 -1
- package/lib/typescript/module/tab-bar/index.web.d.ts.map +1 -1
- package/lib/typescript/module/tab-bar/shared.d.ts +3 -3
- package/lib/typescript/module/tab-bar/surface.web.d.ts.map +1 -1
- package/lib/typescript/module/tab-bar/use-footprint.d.ts +31 -0
- package/lib/typescript/module/tab-bar/use-footprint.d.ts.map +1 -0
- package/lib/typescript/module/toast/ToastRow.d.ts.map +1 -1
- package/lib/typescript/module/toast/ToastSwipeHandler.d.ts +12 -6
- package/lib/typescript/module/toast/ToastSwipeHandler.d.ts.map +1 -1
- package/lib/typescript/module/toast/constants.d.ts +26 -8
- package/lib/typescript/module/toast/constants.d.ts.map +1 -1
- package/lib/typescript/module/toast/position-utils.d.ts +8 -3
- package/lib/typescript/module/toast/position-utils.d.ts.map +1 -1
- package/lib/typescript/module/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/__tests__/Motion.test.tsx +31 -3
- package/src/__tests__/MotionWebFork.test.ts +140 -0
- package/src/__tests__/TabBarAnimatedShorthand.test.ts +135 -0
- package/src/__tests__/TabBarFootprint.test.tsx +172 -0
- package/src/__tests__/TabBarWebFork.test.ts +1 -1
- package/src/__tests__/ToastHostWebFork.test.ts +6 -2
- package/src/__tests__/Toaster.test.tsx +62 -1
- package/src/__tests__/toast-position-utils.test.ts +23 -7
- package/src/__tests__/web-css-style.test.ts +139 -0
- package/src/bottom-sheet/BottomSheetBase.tsx +11 -7
- package/src/connection-dots/ConnectionDots.web.tsx +4 -3
- package/src/design-tokens/shadows.ts +5 -1
- package/src/dialog/Dialog.tsx +1 -1
- package/src/dialog/Dialog.web.tsx +41 -26
- package/src/index.web.ts +2 -2
- package/src/loading/Loading.web.tsx +7 -5
- package/src/loading/SpinnerIcon.web.tsx +12 -9
- package/src/motion/index.web.ts +8 -0
- package/src/motion/motion.ts +14 -6
- package/src/motion/motion.web.ts +99 -0
- package/src/progressive-blur/index.web.tsx +4 -3
- package/src/styles/web-view-style.ts +50 -0
- package/src/tab-bar/TabBarBase.tsx +17 -12
- package/src/tab-bar/index.ts +1 -1
- package/src/tab-bar/index.web.tsx +1 -1
- package/src/tab-bar/shared.ts +3 -3
- package/src/tab-bar/surface.web.tsx +4 -3
- package/src/tab-bar/use-footprint.ts +50 -0
- package/src/toast/ToastRow.tsx +8 -3
- package/src/toast/ToastSwipeHandler.tsx +30 -12
- package/src/toast/constants.ts +28 -0
- package/src/toast/position-utils.ts +10 -5
- package/src/zoomable-image-gallery/ZoomableImageGallery.tsx +9 -8
- package/lib/commonjs/tab-bar/use-reserved-space.js +0 -50
- package/lib/commonjs/tab-bar/use-reserved-space.js.map +0 -1
- package/lib/module/tab-bar/use-reserved-space.js +0 -46
- package/lib/module/tab-bar/use-reserved-space.js.map +0 -1
- package/lib/typescript/commonjs/tab-bar/use-reserved-space.d.ts +0 -25
- package/lib/typescript/commonjs/tab-bar/use-reserved-space.d.ts.map +0 -1
- package/lib/typescript/module/tab-bar/use-reserved-space.d.ts +0 -25
- package/lib/typescript/module/tab-bar/use-reserved-space.d.ts.map +0 -1
- package/src/__tests__/TabBarReservedSpace.test.tsx +0 -150
- package/src/tab-bar/use-reserved-space.ts +0 -44
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WEB FORK of `motion.ts`. Same three names, same contract ("a value you hand to
|
|
3
|
+
* an `Animated.View`'s `entering` / `exiting`"), different mechanism — because on
|
|
4
|
+
* web the native mechanism does nothing at all and the obvious replacement is
|
|
5
|
+
* worse than nothing.
|
|
6
|
+
*
|
|
7
|
+
* WHY THE DEFAULT FILE CANNOT SERVE WEB. `motion.ts` exports custom
|
|
8
|
+
* `EntryExitAnimationFunction` worklet builders. Reanimated's web layout-animation
|
|
9
|
+
* manager resolves an animation by NAME: `tryGetAnimationConfig` reads
|
|
10
|
+
* `config.presetName` off the function, a custom builder has none, and
|
|
11
|
+
* `checkUndefinedAnimationFail` then bails to `makeElementVisible(element, 0)`.
|
|
12
|
+
* Measured in Chrome 5.x/reanimated 4.5.0: the card mounts at `transform: none`,
|
|
13
|
+
* `opacity: 1` and stays there for every sampled frame of both directions, with
|
|
14
|
+
* one `[Reanimated] Couldn't load entering/exiting animation` warning per element.
|
|
15
|
+
* Native is unaffected — it runs the builder directly, with no name lookup.
|
|
16
|
+
*
|
|
17
|
+
* WHY THE ENTER AND THE EXITS USE DIFFERENT MECHANISMS. Rebuilding all three as
|
|
18
|
+
* `Keyframe`s is the obvious fix and is only HALF right, because reanimated's two
|
|
19
|
+
* web directions differ in one decisive argument:
|
|
20
|
+
*
|
|
21
|
+
* - `exiting` -> `handleExitingAnimation` calls `setElementAnimation` on a
|
|
22
|
+
* throwaway clone with `shouldSavePosition` FALSE. The custom keyframe's
|
|
23
|
+
* `duration x 5` cleanup only tears that clone down, which is what it is for.
|
|
24
|
+
* A `Keyframe` here is safe AND exact: it compiles to a real CSS `@keyframes`
|
|
25
|
+
* rule, so the full scale + opacity shape survives.
|
|
26
|
+
* - `entering` -> `chooseAction` calls `setElementAnimation` on the REAL element
|
|
27
|
+
* with `shouldSavePosition` TRUE, and since a custom keyframe's generated
|
|
28
|
+
* `REA-ENTERING-n` name is absent from reanimated's built-in `Animations`
|
|
29
|
+
* map, `scheduleAnimationCleanup` fires
|
|
30
|
+
* `setElementPosition` at `duration x 5` — `position: absolute`, a frozen
|
|
31
|
+
* `top`/`left`/`width`/`height` snapshot, `transform` cleared. The animation
|
|
32
|
+
* plays and the element is then pinned, silently, one and a half seconds
|
|
33
|
+
* later. That is failure mode (C) in `~/Oxy/AGENTS.md` and it is strictly
|
|
34
|
+
* worse than the inert animation it would replace.
|
|
35
|
+
*
|
|
36
|
+
* So the enter uses a PREDEFINED builder, whose `presetName` IS in `Animations`
|
|
37
|
+
* and therefore skips `scheduleAnimationCleanup` entirely. Predefined builders
|
|
38
|
+
* cannot combine a fade with a scale, so the web enter keeps the fade and drops
|
|
39
|
+
* the 0.7 -> 1 growth. `ScreenTransition` in this same folder already made that
|
|
40
|
+
* trade for the same reason ("on web the slide is intentionally dropped").
|
|
41
|
+
*
|
|
42
|
+
* The imperative shared-value drive (failure mode (A)'s remedy, and what
|
|
43
|
+
* `toast/ToastRow.tsx` uses for its own enter) is the third option and is not
|
|
44
|
+
* available here: these are exported VALUES, not components, so there is no
|
|
45
|
+
* render to hang a `useSharedValue` off — and it could not express an exit at
|
|
46
|
+
* all, since keeping an unmounting element alive is exactly what `exiting` is for.
|
|
47
|
+
*
|
|
48
|
+
* WEB EASING IS LINEAR. `Keyframe` has no `.easing()` modifier, and a per-stop
|
|
49
|
+
* easing only survives `convertAnimationObjectToKeyframes` when it resolves to one
|
|
50
|
+
* of reanimated's seven `WebEasings` names (all of them ease-IN curves), while
|
|
51
|
+
* `.easing(Easing.bezier(...))` needs the `__closure` the worklets babel plugin
|
|
52
|
+
* adds — absent in every Oxy web build — and degrades to linear WITH a warning.
|
|
53
|
+
* `ShrinkAndPop` therefore carries an extra midpoint stop so its piecewise-linear
|
|
54
|
+
* web curve tracks the native `withTiming` segments closely rather than cutting
|
|
55
|
+
* the corner.
|
|
56
|
+
*/
|
|
57
|
+
import { type EntryOrExitLayoutType } from 'react-native-reanimated';
|
|
58
|
+
/**
|
|
59
|
+
* Entering: fade in.
|
|
60
|
+
*
|
|
61
|
+
* The scale is dropped on web — see the header. `FadeIn`'s own default duration
|
|
62
|
+
* is already 300ms, matching the native builder, and the bare class is exported
|
|
63
|
+
* rather than a `.duration()` instance so nothing shares a mutable builder.
|
|
64
|
+
*/
|
|
65
|
+
export declare const ScaleAndFadeIn: EntryOrExitLayoutType;
|
|
66
|
+
/** Exiting counterpart to {@link ScaleAndFadeIn}: fade out while shrinking to 70%. */
|
|
67
|
+
export declare const ScaleAndFadeOut: EntryOrExitLayoutType;
|
|
68
|
+
/**
|
|
69
|
+
* Exiting with a brief "pop": the scale dips to 70%, overshoots to 110%, and the
|
|
70
|
+
* element fades out.
|
|
71
|
+
*
|
|
72
|
+
* Stops are the native timeline sampled at its own breakpoints, so every property
|
|
73
|
+
* is declared at every stop and nothing depends on CSS's cross-stop interpolation:
|
|
74
|
+
* scale reaches 0.7 at 75ms (30%) and 1.1 at 225ms (90%); opacity holds until
|
|
75
|
+
* 125ms (50%) and then falls to 0 by 250ms. The 50% stop's 0.8333 scale and the
|
|
76
|
+
* 90% stop's 0.2 opacity are the native values at those instants.
|
|
77
|
+
*/
|
|
78
|
+
export declare const ShrinkAndPop: EntryOrExitLayoutType;
|
|
79
|
+
//# sourceMappingURL=motion.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motion.web.d.ts","sourceRoot":"","sources":["../../../../src/motion/motion.web.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AAOjC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,qBAA8B,CAAC;AAE5D,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,qBAGD,CAAC;AAE9B;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,qBAMF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../../src/progressive-blur/index.web.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../../src/progressive-blur/index.web.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,SAAa,EACb,SAAiB,EACjB,GAAG,IAAI,EACR,EAAE,oBAAoB,2CAkBtB;yBAvBe,eAAe"}
|
|
@@ -18,4 +18,53 @@ import type { ViewStyle } from 'react-native';
|
|
|
18
18
|
* where Yoga silently ignores it.
|
|
19
19
|
*/
|
|
20
20
|
export declare const WEB_POSITION_FIXED: ViewStyle["position"];
|
|
21
|
+
/**
|
|
22
|
+
* A `ViewStyle` that may ALSO carry CSS react-native-web forwards straight to the
|
|
23
|
+
* DOM node but React Native does not model at all.
|
|
24
|
+
*
|
|
25
|
+
* This is the OTHER shape of the same RN/RNW type gap `WEB_POSITION_FIXED`
|
|
26
|
+
* covers, and it needs a different escape hatch because the two are structurally
|
|
27
|
+
* different: `position` is a key RN DOES model, just with a narrower value union,
|
|
28
|
+
* so a value-level cast is enough and it can still be written inside an ordinary
|
|
29
|
+
* style object. The properties below have no key on `ViewStyle` at all, so the
|
|
30
|
+
* whole OBJECT has to cross the boundary.
|
|
31
|
+
*
|
|
32
|
+
* ANNOTATE, DO NOT CAST. Every `.web` fork used to spell this `{ … } as ViewStyle`
|
|
33
|
+
* inline. That is not a widening, it is SILENCING: `as` only requires the two
|
|
34
|
+
* types to be COMPARABLE, so `{ animatoin: '…' } as ViewStyle` compiles happily
|
|
35
|
+
* and the typo ships as a style key react-native-web drops on the floor.
|
|
36
|
+
* Annotating with this interface restores excess-property checking — a key that
|
|
37
|
+
* is neither a real RN style nor a listed web-only property is a compile error —
|
|
38
|
+
* and, unlike a widening helper function, it erases completely, so the emitted
|
|
39
|
+
* JavaScript is byte-identical to the cast it replaces.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* const glass: WebCssStyle = { backdropFilter: 'blur(24px)' };
|
|
43
|
+
* // …then pass it anywhere a `ViewStyle` is expected.
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* Only add a key here once react-native-web is confirmed to pass it through and
|
|
47
|
+
* RN has no equivalent. Several near-misses do NOT belong: RN 0.83 models
|
|
48
|
+
* `cursor`, `boxShadow`, `filter` and `pointerEvents` on `ViewStyle` directly, so
|
|
49
|
+
* those need no widening at all (`userSelect` is the trap — RN declares it on
|
|
50
|
+
* `TextStyle` only). Prefixed spellings sit alongside the standard ones because
|
|
51
|
+
* Safari still needs them for `backdrop-filter` and `mask-image`.
|
|
52
|
+
*/
|
|
53
|
+
export interface WebCssStyle extends ViewStyle {
|
|
54
|
+
/** CSS `animation` shorthand. Bloom's web forks self-inject the `@keyframes`. */
|
|
55
|
+
animation?: string;
|
|
56
|
+
animationDelay?: string;
|
|
57
|
+
transitionProperty?: string;
|
|
58
|
+
transitionDuration?: string;
|
|
59
|
+
transitionTimingFunction?: string;
|
|
60
|
+
backdropFilter?: string;
|
|
61
|
+
WebkitBackdropFilter?: string;
|
|
62
|
+
maskImage?: string;
|
|
63
|
+
WebkitMaskImage?: string;
|
|
64
|
+
backgroundImage?: string;
|
|
65
|
+
scrollbarWidth?: 'auto' | 'thin' | 'none';
|
|
66
|
+
scrollbarColor?: string;
|
|
67
|
+
/** RN declares this on `TextStyle`, not `ViewStyle`. */
|
|
68
|
+
userSelect?: 'auto' | 'none' | 'text' | 'contain' | 'all';
|
|
69
|
+
}
|
|
21
70
|
//# sourceMappingURL=web-view-style.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-view-style.d.ts","sourceRoot":"","sources":["../../../../src/styles/web-view-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kBAAkB,EAAc,SAAS,CAAC,UAAU,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"web-view-style.d.ts","sourceRoot":"","sources":["../../../../src/styles/web-view-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kBAAkB,EAAc,SAAS,CAAC,UAAU,CAAC,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;CAC3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabBarBase.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/TabBarBase.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,OAAO,EAiBL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAe,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"TabBarBase.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/TabBarBase.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,OAAO,EAiBL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAe,MAAM,SAAS,CAAC;AA0a3E;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,aAAa,CAAC,kBAAkB,CAAC,EAC1C,IAAI,EAAE,aAAa,CAAC,oBAAoB,CAAC;YAElB,WAAW;;EAGnC;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC;YAC1C,iBAAiB;;EAG/C"}
|
|
@@ -8,6 +8,6 @@ export declare const TabBarButton: {
|
|
|
8
8
|
};
|
|
9
9
|
export { MINIMIZE_SPRING, setMinimized, TabBarMinimizeProvider, useMinimizeOnScroll, useMinimizeState, useTabBarMinimized, } from './minimize-context';
|
|
10
10
|
export type { MinimizeState } from './minimize-context';
|
|
11
|
-
export {
|
|
11
|
+
export { useTabBarFootprint } from './use-footprint';
|
|
12
12
|
export type { TabBarButtonProps, TabBarItem, TabBarProps, TabBarTheme } from './types';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/index.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,MAAM;;;CAA+C,CAAC;AACnE,eAAO,MAAM,YAAY;;;CAAkC,CAAC;AAE5D,OAAO,EACL,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/index.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,MAAM;;;CAA+C,CAAC;AACnE,eAAO,MAAM,YAAY;;;CAAkC,CAAC;AAE5D,OAAO,EACL,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -8,6 +8,6 @@ export declare const TabBarButton: {
|
|
|
8
8
|
};
|
|
9
9
|
export { MINIMIZE_SPRING, setMinimized, TabBarMinimizeProvider, useMinimizeOnScroll, useMinimizeState, useTabBarMinimized, } from './minimize-context';
|
|
10
10
|
export type { MinimizeState } from './minimize-context';
|
|
11
|
-
export {
|
|
11
|
+
export { useTabBarFootprint } from './use-footprint';
|
|
12
12
|
export type { TabBarButtonProps, TabBarItem, TabBarProps, TabBarTheme } from './types';
|
|
13
13
|
//# sourceMappingURL=index.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/index.web.tsx"],"names":[],"mappings":"AAqBA,eAAO,MAAM,MAAM;;;CAA+C,CAAC;AACnE,eAAO,MAAM,YAAY;;;CAAkC,CAAC;AAE5D,OAAO,EACL,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/index.web.tsx"],"names":[],"mappings":"AAqBA,eAAO,MAAM,MAAM;;;CAA+C,CAAC;AACnE,eAAO,MAAM,YAAY;;;CAAkC,CAAC;AAE5D,OAAO,EACL,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -29,9 +29,9 @@ export declare const LABEL_FONT_SIZE = 9.5;
|
|
|
29
29
|
/**
|
|
30
30
|
* Vertical gap between the bottom of the pill and the bottom of the window.
|
|
31
31
|
*
|
|
32
|
-
* The safe-area inset is folded in HERE, which is why anything
|
|
33
|
-
*
|
|
34
|
-
* number from this same function) rather than adding `insets.bottom` to a
|
|
32
|
+
* The safe-area inset is folded in HERE, which is why anything accounting for
|
|
33
|
+
* the bar in its own layout must go through `useTabBarFootprint` (which derives
|
|
34
|
+
* its number from this same function) rather than adding `insets.bottom` to a
|
|
35
35
|
* hardcoded height — that double-counts the inset.
|
|
36
36
|
*/
|
|
37
37
|
export declare function tabBarBottomGap(bottomInset: number): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.web.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/surface.web.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"surface.web.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/surface.web.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAkBnD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,kBAAkB,2CAWjE;yBAXe,aAAa"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vertical space the tab bar OCCUPIES above the bottom of the window, in
|
|
3
|
+
* px: its own height plus its own bottom offset, and nothing else.
|
|
4
|
+
*
|
|
5
|
+
* It is deliberately the raw footprint, with no clearance folded in. Clearance
|
|
6
|
+
* is a consumer decision and it differs per call site — a scroll view wants the
|
|
7
|
+
* footprint plus a breathing gap so the last row clears the pill, while a
|
|
8
|
+
* floating action button anchored by `bottom` already supplies its own gap and
|
|
9
|
+
* wants the footprint bare. Baking a margin in here would place that FAB too
|
|
10
|
+
* high and make one word mean two things inside a single file. Add your own:
|
|
11
|
+
*
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const footprint = useTabBarFootprint();
|
|
14
|
+
*
|
|
15
|
+
* <Animated.ScrollView contentContainerStyle={{ paddingBottom: footprint + 12 }} />
|
|
16
|
+
* <Fab style={{ position: 'absolute', right: 16, bottom: footprint }} />
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* The value ALREADY INCLUDES the bottom safe-area inset — the bar folds the
|
|
20
|
+
* inset into its own gap, so this is measured from the true window edge, not
|
|
21
|
+
* from the safe area. Never write `footprint + insets.bottom`: that counts the
|
|
22
|
+
* home indicator twice and strands a visible band of dead space under every
|
|
23
|
+
* list (114px accounted for a 76px bar on an iOS device or PWA). Whatever you
|
|
24
|
+
* add on top is your own clearance — never the inset a second time.
|
|
25
|
+
*
|
|
26
|
+
* It is the EXPANDED height, deliberately. The bar minimizes while scrolling
|
|
27
|
+
* down and re-expands on the way up, so measuring the minimized height would
|
|
28
|
+
* hide the end of a list the moment the user scrolled back to it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useTabBarFootprint(): number;
|
|
31
|
+
//# sourceMappingURL=use-footprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-footprint.d.ts","sourceRoot":"","sources":["../../../../src/tab-bar/use-footprint.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastRow.d.ts","sourceRoot":"","sources":["../../../../src/toast/ToastRow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ToastRow.d.ts","sourceRoot":"","sources":["../../../../src/toast/ToastRow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA4B/B,OAAO,KAAK,EAEV,aAAa,EAEb,QAAQ,EACR,WAAW,EACZ,MAAM,SAAS,CAAC;AAwDjB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAHR,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI;kCAiVzC,CAAC"}
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
* Derived from sonner-native v0.26.4 — src/gestures.tsx
|
|
3
3
|
* (MIT © Gunnar Torfi Steinarsson). See the top-level NOTICE.
|
|
4
4
|
*
|
|
5
|
-
* W2 — the animated style reads `translate`, `direction`, `position`,
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* W2 — the animated style reads `translate`, `direction`, `position`, `rowWidth`
|
|
6
|
+
* and `isAndroid`; ALL of them are in the dependency array. On web without the
|
|
7
|
+
* worklets babel plugin reanimated re-runs the mapper on its deps rather than on
|
|
8
|
+
* auto-tracked reads, so a missing dep freezes the swipe transform at its first
|
|
9
|
+
* frame (upstream omits `position` and `isAndroid`, so a toast that changes
|
|
10
|
+
* position mid-life swipes the wrong way).
|
|
11
|
+
*
|
|
12
|
+
* W12 — this wrapper is THE row box, so it is where `TOAST_MAX_ROW_WIDTH` caps
|
|
13
|
+
* and centres the toast. Capping here rather than on `ToastContent`'s card
|
|
14
|
+
* covers `toast.custom` JSX and `unstyled` rows too, which never reach that
|
|
15
|
+
* card. Every distance the gesture measures is a fraction of the capped
|
|
16
|
+
* `rowWidth`, not of the window — see the constant.
|
|
11
17
|
*/
|
|
12
18
|
import * as React from 'react';
|
|
13
19
|
import { type ViewStyle } from 'react-native';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastSwipeHandler.d.ts","sourceRoot":"","sources":["../../../../src/toast/ToastSwipeHandler.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ToastSwipeHandler.d.ts","sourceRoot":"","sources":["../../../../src/toast/ToastSwipeHandler.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAetB,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAWzD,KAAK,sBAAsB,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG;IAC5D,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC,EAAE,CAAC;IAC9C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACnD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CACtC,KAAK,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,CAuJhD,CAAC"}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Derived from sonner-native v0.26.4 — src/constants.ts and src/animations.ts
|
|
3
|
-
* (MIT © Gunnar Torfi Steinarsson). See the top-level NOTICE.
|
|
4
|
-
*
|
|
5
|
-
* The two animation durations live HERE rather than in `animations.ts` so
|
|
6
|
-
* `toast-store.ts` never has to import a Reanimated-dependent module: the store
|
|
7
|
-
* stays pure JS and its suite needs zero React Native mocks.
|
|
8
|
-
*/
|
|
9
1
|
import type { AutoWiggle, ToastPosition, ToastSwipeDirection, ToastTheme, ToastVariant } from './types';
|
|
10
2
|
/** Fallback row height until a toast has been measured. */
|
|
11
3
|
export declare const ESTIMATED_TOAST_HEIGHT = 70;
|
|
@@ -13,6 +5,32 @@ export declare const CLOSE_BUTTON_HIT_AREA = 60;
|
|
|
13
5
|
export declare const OUTSIDE_PRESS_PADDING = 20;
|
|
14
6
|
/** However deep a stack gets, a buried row never narrows past this scale. */
|
|
15
7
|
export declare const MIN_STACK_SCALE_X = 0.8;
|
|
8
|
+
/**
|
|
9
|
+
* W12 — HOW WIDE A TOAST ROW IS ALLOWED TO GET.
|
|
10
|
+
*
|
|
11
|
+
* sonner-native has no cap: the row is `width: '100%'` and the card inside it is
|
|
12
|
+
* inset by `marginHorizontal: space.lg`, so the card is always
|
|
13
|
+
* screen-width-minus-32. That is correct for the platform it was written for and
|
|
14
|
+
* wrong everywhere else — on a 1280px desktop viewport it produces a ~1248px
|
|
15
|
+
* card, which reads as a page banner rather than a toast. sonner (web) instead
|
|
16
|
+
* fixes the card at `--width: 356px`.
|
|
17
|
+
*
|
|
18
|
+
* The cap therefore sizes the ROW BOX, which carries the card's two `space.lg`
|
|
19
|
+
* gutters, so the visible card lands on sonner's 356px on any viewport wide
|
|
20
|
+
* enough to reach it. `maxWidth` needs no platform fork because it degrades by
|
|
21
|
+
* itself: below a 388px viewport the row is still screen-width and the card is
|
|
22
|
+
* still screen-width-minus-32, exactly as before, so phone portrait — the case
|
|
23
|
+
* the mobile sizing was right for — is untouched. Above it (desktop, tablet,
|
|
24
|
+
* phone landscape) the row caps and centres.
|
|
25
|
+
*
|
|
26
|
+
* `ToastSwipeHandler`'s dismiss threshold and `calculateStackScaleX`'s depth cue
|
|
27
|
+
* are fractions of this row width, NOT of the window: at 1280px a
|
|
28
|
+
* window-relative threshold would demand a 320px drag from a 388px card, and a
|
|
29
|
+
* window-relative squeeze would shrink a buried row by 4px instead of 16px.
|
|
30
|
+
* A consumer who overrides the cap through `toastOptions.toastContainerStyle`
|
|
31
|
+
* moves the card only; both of those keep measuring against this default.
|
|
32
|
+
*/
|
|
33
|
+
export declare const TOAST_MAX_ROW_WIDTH: number;
|
|
16
34
|
/** Enter animation length; also the auto-close timer's head start and the overlay teardown delay. */
|
|
17
35
|
export declare const ENTERING_ANIMATION_DURATION = 300;
|
|
18
36
|
export declare const STACKING_ANIMATION_DURATION = 600;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/toast/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/toast/constants.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,2DAA2D;AAC3D,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,mBAAmB,QAAqB,CAAC;AAEtD,qGAAqG;AACrG,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,eAAO,MAAM,aAAa,EAAE;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB,EAAE,mBAAmB,CAAC;IAC7C,OAAO,EAAE,YAAY,GAAG,SAAS,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,kBAAkB,EAAE,UAAU,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;CA8B3B,CAAC"}
|
|
@@ -5,16 +5,21 @@ export declare const getOrderedToastIds: (toasts: ToastProps[], position: ToastP
|
|
|
5
5
|
*
|
|
6
6
|
* Scale rather than width: changing the real width would rewrap the text. Returns
|
|
7
7
|
* 1 (no squeeze) for a single row, an expanded stack, stacking turned off, or
|
|
8
|
-
* before the
|
|
8
|
+
* before the row width is known.
|
|
9
|
+
*
|
|
10
|
+
* `rowWidth` is the row's OWN width, not the window's. Upstream can use the
|
|
11
|
+
* screen width because its row is always full-bleed; Bloom's is capped at
|
|
12
|
+
* `TOAST_MAX_ROW_WIDTH`, and dividing a fixed `stackGap` inset by a 1280px window
|
|
13
|
+
* would shrink a buried row by 4 visible pixels instead of the intended 16.
|
|
9
14
|
*/
|
|
10
|
-
export declare const calculateStackScaleX: ({ index, numberOfToasts, enableStacking, position, isExpanded, stackGap,
|
|
15
|
+
export declare const calculateStackScaleX: ({ index, numberOfToasts, enableStacking, position, isExpanded, stackGap, rowWidth, }: {
|
|
11
16
|
index: number;
|
|
12
17
|
numberOfToasts: number;
|
|
13
18
|
enableStacking: boolean;
|
|
14
19
|
position: ToastPosition;
|
|
15
20
|
isExpanded: boolean;
|
|
16
21
|
stackGap: number;
|
|
17
|
-
|
|
22
|
+
rowWidth: number;
|
|
18
23
|
}) => number;
|
|
19
24
|
export declare const calculateToastPosition: ({ index, numberOfToasts, enableStacking, position, allToastHeights, gap, orderedToastIds, isExpanded, stackGap, }: {
|
|
20
25
|
index: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position-utils.d.ts","sourceRoot":"","sources":["../../../../src/toast/position-utils.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzD,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,UAAU,EAAE,EACpB,UAAU,aAAa,EACvB,gBAAgB,OAAO,KACtB,KAAK,CAAC,MAAM,GAAG,MAAM,CAQvB,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"position-utils.d.ts","sourceRoot":"","sources":["../../../../src/toast/position-utils.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzD,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,UAAU,EAAE,EACpB,UAAU,aAAa,EACvB,gBAAgB,OAAO,KACtB,KAAK,CAAC,MAAM,GAAG,MAAM,CAQvB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAAI,sFAQlC;IACD,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAG,MASH,CAAC;AAaF,eAAO,MAAM,sBAAsB,GAAI,mHAUpC;IACD,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAG,MAoDH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZoomableImageGallery.d.ts","sourceRoot":"","sources":["../../../../src/zoomable-image-gallery/ZoomableImageGallery.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAkEjF,OAAO,KAAK,EAGV,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ZoomableImageGallery.d.ts","sourceRoot":"","sources":["../../../../src/zoomable-image-gallery/ZoomableImageGallery.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAkEjF,OAAO,KAAK,EAGV,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AA64BjB,eAAO,MAAM,oBAAoB,8GAA4B,CAAC;AAyK9D,eAAe,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/bloom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -477,6 +477,11 @@
|
|
|
477
477
|
},
|
|
478
478
|
"./motion": {
|
|
479
479
|
"react-native": "./src/motion/index.ts",
|
|
480
|
+
"browser": {
|
|
481
|
+
"types": "./lib/typescript/module/motion/index.web.d.ts",
|
|
482
|
+
"import": "./lib/module/motion/index.web.js",
|
|
483
|
+
"require": "./lib/commonjs/motion/index.web.js"
|
|
484
|
+
},
|
|
480
485
|
"import": {
|
|
481
486
|
"types": "./lib/typescript/module/motion/index.d.ts",
|
|
482
487
|
"default": "./lib/module/motion/index.js"
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text } from 'react-native';
|
|
3
3
|
import { render } from '@testing-library/react-native';
|
|
4
|
+
import type {
|
|
5
|
+
EntryOrExitLayoutType,
|
|
6
|
+
LayoutAnimation,
|
|
7
|
+
} from 'react-native-reanimated';
|
|
4
8
|
|
|
5
9
|
import {
|
|
6
10
|
ScaleAndFadeIn,
|
|
@@ -12,21 +16,45 @@ import {
|
|
|
12
16
|
// The reanimated mock resolves `withTiming(v)` -> v, `withDelay(d, v)` -> v and
|
|
13
17
|
// `withSequence(...v)` -> last, so the builder output is deterministic.
|
|
14
18
|
|
|
19
|
+
/**
|
|
20
|
+
* The presets are typed as reanimated's `entering`/`exiting` union so the two
|
|
21
|
+
* platform files present ONE contract and nothing can depend on the mechanism.
|
|
22
|
+
* These tests are about the native mechanism specifically, so they narrow back
|
|
23
|
+
* down through a runtime check rather than a cast: a predefined builder is a
|
|
24
|
+
* class (it carries the `createInstance` static), a custom worklet builder is a
|
|
25
|
+
* plain function.
|
|
26
|
+
*/
|
|
27
|
+
const isWorkletBuilder = (
|
|
28
|
+
preset: EntryOrExitLayoutType,
|
|
29
|
+
): preset is () => LayoutAnimation =>
|
|
30
|
+
// A predefined builder is a class and carries the `createInstance` static; a
|
|
31
|
+
// custom worklet builder is a plain nullary function.
|
|
32
|
+
typeof preset === 'function' &&
|
|
33
|
+
!('createInstance' in preset) &&
|
|
34
|
+
preset.length === 0;
|
|
35
|
+
|
|
36
|
+
const runNativeBuilder = (preset: EntryOrExitLayoutType): LayoutAnimation => {
|
|
37
|
+
if (!isWorkletBuilder(preset)) {
|
|
38
|
+
throw new Error('expected the native preset to be a custom worklet builder');
|
|
39
|
+
}
|
|
40
|
+
return preset();
|
|
41
|
+
};
|
|
42
|
+
|
|
15
43
|
describe('motion presets', () => {
|
|
16
44
|
it('ScaleAndFadeIn enters from 70% scale and transparent', () => {
|
|
17
|
-
const { initialValues, animations } = ScaleAndFadeIn
|
|
45
|
+
const { initialValues, animations } = runNativeBuilder(ScaleAndFadeIn);
|
|
18
46
|
expect(initialValues).toEqual({ opacity: 0, transform: [{ scale: 0.7 }] });
|
|
19
47
|
expect(animations).toEqual({ opacity: 1, transform: [{ scale: 1 }] });
|
|
20
48
|
});
|
|
21
49
|
|
|
22
50
|
it('ScaleAndFadeOut exits to 70% scale and transparent', () => {
|
|
23
|
-
const { initialValues, animations } = ScaleAndFadeOut
|
|
51
|
+
const { initialValues, animations } = runNativeBuilder(ScaleAndFadeOut);
|
|
24
52
|
expect(initialValues).toEqual({ opacity: 1, transform: [{ scale: 1 }] });
|
|
25
53
|
expect(animations).toEqual({ opacity: 0, transform: [{ scale: 0.7 }] });
|
|
26
54
|
});
|
|
27
55
|
|
|
28
56
|
it('ShrinkAndPop overshoots to 110% before leaving', () => {
|
|
29
|
-
const { initialValues, animations } = ShrinkAndPop
|
|
57
|
+
const { initialValues, animations } = runNativeBuilder(ShrinkAndPop);
|
|
30
58
|
expect(initialValues).toEqual({ opacity: 1, transform: [{ scale: 1 }] });
|
|
31
59
|
// withSequence resolves to its final keyframe (the 1.1 overshoot) in the mock.
|
|
32
60
|
expect(animations.transform).toEqual([{ scale: 1.1 }]);
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression guard for the `motion` web fork.
|
|
3
|
+
*
|
|
4
|
+
* The bug: `motion.ts`'s custom worklet builders are INERT on web. Reanimated's
|
|
5
|
+
* web layout-animation manager resolves an animation by preset name, a custom
|
|
6
|
+
* builder has none, and `startWebLayoutAnimation` falls through to
|
|
7
|
+
* `makeElementVisible` — the element appears at its final frame with one
|
|
8
|
+
* `[Reanimated] Couldn't load entering/exiting animation` warning apiece.
|
|
9
|
+
*
|
|
10
|
+
* The trap: rebuilding all three as `Keyframe`s fixes the exits and makes the
|
|
11
|
+
* ENTER worse. Reanimated's `entering` path calls `setElementAnimation` with
|
|
12
|
+
* `shouldSavePosition` TRUE, and any animation name absent from its built-in
|
|
13
|
+
* `Animations` map — which every custom `Keyframe` is, since they mint a fresh
|
|
14
|
+
* `REA-ENTERING-n` rule — also gets a `scheduleAnimationCleanup` that pins the
|
|
15
|
+
* element with `position: absolute` and a frozen box at `duration x 5`. That is
|
|
16
|
+
* failure mode (C) in `~/Oxy/AGENTS.md`.
|
|
17
|
+
*
|
|
18
|
+
* So the invariant is asymmetric, and BOTH halves are load-bearing:
|
|
19
|
+
* entering -> a PREDEFINED builder (its `presetName` is in `Animations`, so no
|
|
20
|
+
* cleanup is ever scheduled), never a `Keyframe`.
|
|
21
|
+
* exiting -> a `Keyframe` is safe (the cleanup only reaps the throwaway clone)
|
|
22
|
+
* and is the only mechanism that can express the full shape.
|
|
23
|
+
*
|
|
24
|
+
* The actual motion is verified in a real browser — jest cannot run reanimated's
|
|
25
|
+
* web layout-animation manager.
|
|
26
|
+
*/
|
|
27
|
+
import { readFileSync } from 'node:fs';
|
|
28
|
+
import { join } from 'node:path';
|
|
29
|
+
|
|
30
|
+
import { Keyframe } from 'react-native-reanimated';
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
ScaleAndFadeIn,
|
|
34
|
+
ScaleAndFadeOut,
|
|
35
|
+
ShrinkAndPop,
|
|
36
|
+
} from '../motion/motion.web';
|
|
37
|
+
|
|
38
|
+
const SRC = join(__dirname, '..');
|
|
39
|
+
const read = (rel: string) => readFileSync(join(SRC, rel), 'utf8');
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Upstream's `ReanimatedKeyframe` type hides the instance state that the web
|
|
43
|
+
* layout manager actually reads (`createCustomKeyFrameAnimation` takes
|
|
44
|
+
* `config.definitions` raw, `getDurationFromConfig` takes `config.durationV`), so
|
|
45
|
+
* the test narrows to it with a runtime-checked predicate rather than a cast.
|
|
46
|
+
*/
|
|
47
|
+
type KeyframeState = {
|
|
48
|
+
definitions: Record<string, Record<string, unknown>>;
|
|
49
|
+
durationV: number | undefined;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const isKeyframeState = (value: unknown): value is KeyframeState =>
|
|
53
|
+
value instanceof Keyframe && 'definitions' in value;
|
|
54
|
+
|
|
55
|
+
const stateOf = (preset: unknown): KeyframeState => {
|
|
56
|
+
if (!isKeyframeState(preset)) {
|
|
57
|
+
throw new Error('expected a Keyframe');
|
|
58
|
+
}
|
|
59
|
+
return preset;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
describe('motion web fork', () => {
|
|
63
|
+
it('never hands a Keyframe to `entering`', () => {
|
|
64
|
+
// The whole reason the enter and the exits use different mechanisms.
|
|
65
|
+
expect(ScaleAndFadeIn instanceof Keyframe).toBe(false);
|
|
66
|
+
expect(typeof ScaleAndFadeIn).toBe('object');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('uses a predefined reanimated builder for the enter', () => {
|
|
70
|
+
const web = read('motion/motion.web.ts');
|
|
71
|
+
expect(web).toMatch(/export const ScaleAndFadeIn[^=]*=\s*FadeIn;/);
|
|
72
|
+
expect(web).toMatch(/import \{[\s\S]*\bFadeIn\b[\s\S]*\} from 'react-native-reanimated'/);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('uses a Keyframe for both exits', () => {
|
|
76
|
+
expect(ScaleAndFadeOut instanceof Keyframe).toBe(true);
|
|
77
|
+
expect(ShrinkAndPop instanceof Keyframe).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('keeps the full scale + opacity shape on ScaleAndFadeOut', () => {
|
|
81
|
+
expect(stateOf(ScaleAndFadeOut).definitions).toEqual({
|
|
82
|
+
from: { opacity: 1, transform: [{ scale: 1 }] },
|
|
83
|
+
to: { opacity: 0, transform: [{ scale: 0.7 }] },
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Every stop declares every animated property, so the CSS the web parser emits
|
|
89
|
+
* does not depend on cross-stop interpolation, and the intermediate values are
|
|
90
|
+
* the native timeline sampled at those instants (250ms total: scale 1 -> 0.7 by
|
|
91
|
+
* 75ms, -> 1.1 by 225ms; opacity held to 125ms, then to 0 by 250ms).
|
|
92
|
+
*/
|
|
93
|
+
it('samples the native ShrinkAndPop timeline at every stop', () => {
|
|
94
|
+
const stops = stateOf(ShrinkAndPop).definitions;
|
|
95
|
+
expect(Object.keys(stops)).toEqual(['0', '30', '50', '90', '100']);
|
|
96
|
+
for (const [percent, style] of Object.entries(stops)) {
|
|
97
|
+
expect({ percent, keys: Object.keys(style).sort() }).toEqual({
|
|
98
|
+
percent,
|
|
99
|
+
keys: ['opacity', 'transform'],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
expect(stops['0']).toEqual({ opacity: 1, transform: [{ scale: 1 }] });
|
|
103
|
+
expect(stops['30']).toEqual({ opacity: 1, transform: [{ scale: 0.7 }] });
|
|
104
|
+
expect(stops['90']).toEqual({ opacity: 0.2, transform: [{ scale: 1.1 }] });
|
|
105
|
+
expect(stops['100']).toEqual({ opacity: 0, transform: [{ scale: 1.1 }] });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('matches the native durations', () => {
|
|
109
|
+
// `withTiming`'s default for the pair the native file animates, and
|
|
110
|
+
// 75 + 150 for the pop's two sequenced scale legs.
|
|
111
|
+
expect(stateOf(ScaleAndFadeOut).durationV).toBe(300);
|
|
112
|
+
expect(stateOf(ShrinkAndPop).durationV).toBe(250);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('leaves the native file on its custom worklet builders', () => {
|
|
116
|
+
const native = read('motion/motion.ts');
|
|
117
|
+
expect(native).toMatch(/'worklet';/);
|
|
118
|
+
expect(native).not.toMatch(/\bKeyframe\b/);
|
|
119
|
+
expect(native).not.toMatch(/\bFadeIn\b/);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('is wired as a web-forked subpath', () => {
|
|
123
|
+
const script = readFileSync(
|
|
124
|
+
join(SRC, '..', 'scripts', 'generate-platform-exports.mjs'),
|
|
125
|
+
'utf8',
|
|
126
|
+
);
|
|
127
|
+
// Between the WEB_FORKED_SUBPATHS opener and its closing bracket.
|
|
128
|
+
const forked = script.slice(
|
|
129
|
+
script.indexOf('const WEB_FORKED_SUBPATHS'),
|
|
130
|
+
script.indexOf(']);', script.indexOf('const WEB_FORKED_SUBPATHS')),
|
|
131
|
+
);
|
|
132
|
+
expect(forked).toContain("'./motion'");
|
|
133
|
+
|
|
134
|
+
const pkg: { exports: Record<string, { browser?: { import?: string } }> } =
|
|
135
|
+
JSON.parse(readFileSync(join(SRC, '..', 'package.json'), 'utf8'));
|
|
136
|
+
expect(pkg.exports['./motion']?.browser?.import).toBe(
|
|
137
|
+
'./lib/module/motion/index.web.js',
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
});
|