@cloudparse/up-miniapps-sdk 0.6.3 → 0.6.6

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/dist/index.d.cts CHANGED
@@ -214,7 +214,16 @@ interface IFidelityTransaction {
214
214
  /**
215
215
  * The initialization options required to set up the Mini-App SDK.
216
216
  */
217
- type IInitializationOptions = {};
217
+ type IInitializationOptions = {
218
+ /**
219
+ * The Mini-App's own dark/light theme preference, applied by the host
220
+ * immediately from the INITIALIZE payload — pass it here instead of a
221
+ * separate `sdk.updateContext({isDark})` call right after `initialize()`
222
+ * resolves, which left the host rendering its own theme for the whole
223
+ * round-trip before flipping to the Mini-App's real one.
224
+ */
225
+ isDark?: boolean;
226
+ };
218
227
  /**
219
228
  * The post initialization response
220
229
  */
@@ -1134,6 +1143,25 @@ declare const useMockLocation: () => MockLocationContextType | null;
1134
1143
  */
1135
1144
  declare function renderMap(containerId: string, props?: MapProps): react_dom_client.Root;
1136
1145
 
1146
+ interface PullToRefreshIndicatorState {
1147
+ /** 0 (no pull) to 1 (at/past the trigger threshold). */
1148
+ progress: number;
1149
+ isRefreshing: boolean;
1150
+ }
1151
+ interface PullToRefreshProps {
1152
+ onRefresh: () => Promise<void> | void;
1153
+ children: React__default.ReactNode;
1154
+ className?: string;
1155
+ disabled?: boolean;
1156
+ /** Visual (post-resistance) px of pull required to trigger a refresh. Default 64. */
1157
+ pullThreshold?: number;
1158
+ /** Visual cap so the indicator never drags further than this. Default 96. */
1159
+ maxPull?: number;
1160
+ /** Fully replaces the default indicator — e.g. a brand-specific spinner/logo. */
1161
+ renderIndicator?: (state: PullToRefreshIndicatorState) => React__default.ReactNode;
1162
+ }
1163
+ declare const PullToRefresh: ({ onRefresh, children, className, disabled, pullThreshold, maxPull, renderIndicator, }: PullToRefreshProps) => React__default.JSX.Element;
1164
+
1137
1165
  interface QRScannerProps {
1138
1166
  /** Called once with the decoded string the moment a QR code is detected. Scanning stops immediately after. */
1139
1167
  onScan: (data: string) => void;
@@ -1797,4 +1825,4 @@ interface BroadcastWsServiceClient<TMessage extends WsMessage = WsMessage> {
1797
1825
  declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateChannelWsServiceOptions<TMessage>): WsServiceClient<TMessage>;
1798
1826
  declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateBroadcastWsServiceOptions<TMessage>): BroadcastWsServiceClient<TMessage>;
1799
1827
 
1800
- export { type ApiServiceClient, type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type BroadcastWsServiceClient, type CenterCallbackParams, type CreateApiServiceOptions, type CreateBroadcastWsServiceOptions, type CreateChannelWsServiceOptions, type CreateWsServiceOptions, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, type WsConnectionStatus, type WsMessage, type WsServiceClient, createApiService, createWsService, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };
1828
+ export { type ApiServiceClient, type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type BroadcastWsServiceClient, type CenterCallbackParams, type CreateApiServiceOptions, type CreateBroadcastWsServiceOptions, type CreateChannelWsServiceOptions, type CreateWsServiceOptions, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, PullToRefresh, type PullToRefreshIndicatorState, type PullToRefreshProps, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, type WsConnectionStatus, type WsMessage, type WsServiceClient, createApiService, createWsService, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };
package/dist/index.d.ts CHANGED
@@ -214,7 +214,16 @@ interface IFidelityTransaction {
214
214
  /**
215
215
  * The initialization options required to set up the Mini-App SDK.
216
216
  */
217
- type IInitializationOptions = {};
217
+ type IInitializationOptions = {
218
+ /**
219
+ * The Mini-App's own dark/light theme preference, applied by the host
220
+ * immediately from the INITIALIZE payload — pass it here instead of a
221
+ * separate `sdk.updateContext({isDark})` call right after `initialize()`
222
+ * resolves, which left the host rendering its own theme for the whole
223
+ * round-trip before flipping to the Mini-App's real one.
224
+ */
225
+ isDark?: boolean;
226
+ };
218
227
  /**
219
228
  * The post initialization response
220
229
  */
@@ -1134,6 +1143,25 @@ declare const useMockLocation: () => MockLocationContextType | null;
1134
1143
  */
1135
1144
  declare function renderMap(containerId: string, props?: MapProps): react_dom_client.Root;
1136
1145
 
1146
+ interface PullToRefreshIndicatorState {
1147
+ /** 0 (no pull) to 1 (at/past the trigger threshold). */
1148
+ progress: number;
1149
+ isRefreshing: boolean;
1150
+ }
1151
+ interface PullToRefreshProps {
1152
+ onRefresh: () => Promise<void> | void;
1153
+ children: React__default.ReactNode;
1154
+ className?: string;
1155
+ disabled?: boolean;
1156
+ /** Visual (post-resistance) px of pull required to trigger a refresh. Default 64. */
1157
+ pullThreshold?: number;
1158
+ /** Visual cap so the indicator never drags further than this. Default 96. */
1159
+ maxPull?: number;
1160
+ /** Fully replaces the default indicator — e.g. a brand-specific spinner/logo. */
1161
+ renderIndicator?: (state: PullToRefreshIndicatorState) => React__default.ReactNode;
1162
+ }
1163
+ declare const PullToRefresh: ({ onRefresh, children, className, disabled, pullThreshold, maxPull, renderIndicator, }: PullToRefreshProps) => React__default.JSX.Element;
1164
+
1137
1165
  interface QRScannerProps {
1138
1166
  /** Called once with the decoded string the moment a QR code is detected. Scanning stops immediately after. */
1139
1167
  onScan: (data: string) => void;
@@ -1797,4 +1825,4 @@ interface BroadcastWsServiceClient<TMessage extends WsMessage = WsMessage> {
1797
1825
  declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateChannelWsServiceOptions<TMessage>): WsServiceClient<TMessage>;
1798
1826
  declare function createWsService<TMessage extends WsMessage = WsMessage>(options: CreateBroadcastWsServiceOptions<TMessage>): BroadcastWsServiceClient<TMessage>;
1799
1827
 
1800
- export { type ApiServiceClient, type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type BroadcastWsServiceClient, type CenterCallbackParams, type CreateApiServiceOptions, type CreateBroadcastWsServiceOptions, type CreateChannelWsServiceOptions, type CreateWsServiceOptions, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, type WsConnectionStatus, type WsMessage, type WsServiceClient, createApiService, createWsService, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };
1828
+ export { type ApiServiceClient, type BridgeMessageType, BridgeMocker, type BridgeMockerProps, type BroadcastWsServiceClient, type CenterCallbackParams, type CreateApiServiceOptions, type CreateBroadcastWsServiceOptions, type CreateChannelWsServiceOptions, type CreateWsServiceOptions, type CustomControl, DebugConsole, type DebugConsoleProps, type DeclarativeJourneyOptions, type DrawerState, type EtaData, type FidelityTransactionTypeType, type FlyToParams, GeolocationEvent, GlobalEvent, type HapticStyleType, type IBridgeEnvelope, type IContextState, type IEdgeInsets, type IFidelityBalance, type IFidelityHistoryParams, type IFidelityTransaction, type IGenerateQrCodeOptions, type IInitializationOptions, type IInitializationResponse, type ILocationData, type INetworkOptions, type INetworkResponse, type IPaymentRequest, type IPickImageResult, type ISaveImageResult, type IUserProfile, type LiveRoutingOptions, type LiveRoutingResult, type LocationStreamConfig, Map, MapControls, MapControlsContext, type MapControlsProps, type MapControlsState, type MapInsets, MapMenu, MapMenuDivider, type MapMenuDividerProps, MapMenuFooter, type MapMenuFooterProps, MapMenuItem, type MapMenuItemProps, type MapMenuProps, MapMenuTitle, type MapMenuTitleProps, type MapProps, type MenuItem, MiniAppSDK, MockLocationContext, type MockLocationContextType, type NetworkMethodType, type POI, PullToRefresh, type PullToRefreshIndicatorState, type PullToRefreshProps, QRScanner, type QRScannerProps, RouteLayer, type RouteLayerProps, RouteRequest, RouteResponse, RouteStep, type SDKEvent, SDKMapProvider, SDKProvider, type SDKProviderProps, type ScrollConfig, type StreamAccelerometerData, type StreamHeadingData, type StreamLocationData, type StreamUpdatePayload, type SwipeAxisPriority, SwipeCarousel, type SwipeCarouselItem, type SwipeCarouselProps, type SwipeCarouselVerticalDragConfig, UIEvent, type UseJourneyOptions, type UseJourneyResult, type UserLocationState, type WsConnectionStatus, type WsMessage, type WsServiceClient, createApiService, createWsService, sdk as default, renderMap, sdk, useIsMocked, useJourney, useLiveRouting, useMapControls, useMockLocation, useRoute, useTrimmedRoute, useUserLocation };
package/dist/index.js CHANGED
@@ -3331,7 +3331,7 @@ async function generateQrCode(data, options = {}) {
3331
3331
  const size = options.size ?? DEFAULT_SIZE;
3332
3332
  const color = options.color ?? DEFAULT_COLOR;
3333
3333
  const backgroundColor = options.backgroundColor ?? DEFAULT_BACKGROUND;
3334
- const label = options.label || (options.appName ? `UP - ${options.appName}` : "");
3334
+ const label = options.label || (options.appName ? `${options.appName} by UP` : "");
3335
3335
  const qr = new QRCodeStyling({
3336
3336
  backgroundOptions: {
3337
3337
  color: backgroundColor,
@@ -3490,7 +3490,7 @@ var loadImage2 = (src) => new Promise((resolve, reject) => {
3490
3490
  });
3491
3491
 
3492
3492
  // package.json
3493
- var version = "0.6.3";
3493
+ var version = "0.6.6";
3494
3494
 
3495
3495
  // src/sdk.ts
3496
3496
  function deepFreeze(obj) {
@@ -4636,18 +4636,268 @@ var DebugConsole = ({
4636
4636
  ] });
4637
4637
  };
4638
4638
 
4639
- // src/components/QRScanner.tsx
4640
- import jsQR2 from "jsqr";
4639
+ // src/components/PullToRefresh.tsx
4641
4640
  import { useEffect as useEffect10, useRef as useRef10, useState as useState11 } from "react";
4642
4641
  import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
4643
- function QRScanner({ onScan, onError, className = "" }) {
4644
- const videoRef = useRef10(null);
4645
- const canvasRef = useRef10(null);
4646
- const streamRef = useRef10(null);
4647
- const tickRequestRef = useRef10(null);
4648
- const hasScannedRef = useRef10(false);
4649
- const [isReady, setIsReady] = useState11(false);
4642
+ var DEFAULT_PULL_THRESHOLD = 64;
4643
+ var DEFAULT_MAX_PULL = 96;
4644
+ var RESISTANCE = 0.5;
4645
+ var DRAG_DEADZONE = 8;
4646
+ var FLING_FRICTION = 0.95;
4647
+ var FLING_MIN_VELOCITY = 0.02;
4648
+ function DefaultIndicator({ progress, isRefreshing }) {
4649
+ return /* @__PURE__ */ jsxs14(
4650
+ "div",
4651
+ {
4652
+ style: {
4653
+ alignItems: "center",
4654
+ background: "rgba(24, 24, 27, 0.9)",
4655
+ border: "1px solid rgba(255, 255, 255, 0.1)",
4656
+ borderRadius: 9999,
4657
+ boxShadow: "0 4px 16px -4px rgba(0, 0, 0, 0.5)",
4658
+ display: "flex",
4659
+ height: 28,
4660
+ justifyContent: "center",
4661
+ width: 28
4662
+ },
4663
+ children: [
4664
+ /* @__PURE__ */ jsxs14(
4665
+ "svg",
4666
+ {
4667
+ height: 14,
4668
+ style: {
4669
+ animation: isRefreshing ? "up-sdk-ptr-spin 0.8s linear infinite" : void 0,
4670
+ color: isRefreshing ? "#a78bfa" : "#a1a1aa",
4671
+ transform: isRefreshing ? void 0 : `rotate(${progress * 360}deg)`
4672
+ },
4673
+ viewBox: "0 0 24 24",
4674
+ width: 14,
4675
+ children: [
4676
+ /* @__PURE__ */ jsx18("title", { children: "Refreshing" }),
4677
+ /* @__PURE__ */ jsx18(
4678
+ "path",
4679
+ {
4680
+ d: "M21 12a9 9 0 1 1-2.64-6.36",
4681
+ fill: "none",
4682
+ stroke: "currentColor",
4683
+ strokeLinecap: "round",
4684
+ strokeWidth: 2.5
4685
+ }
4686
+ )
4687
+ ]
4688
+ }
4689
+ ),
4690
+ /* @__PURE__ */ jsx18("style", { children: "@keyframes up-sdk-ptr-spin { to { transform: rotate(360deg); } }" })
4691
+ ]
4692
+ }
4693
+ );
4694
+ }
4695
+ var PullToRefresh = ({
4696
+ onRefresh,
4697
+ children,
4698
+ className = "",
4699
+ disabled = false,
4700
+ pullThreshold = DEFAULT_PULL_THRESHOLD,
4701
+ maxPull = DEFAULT_MAX_PULL,
4702
+ renderIndicator
4703
+ }) => {
4704
+ const containerRef = useRef10(null);
4705
+ const startYRef = useRef10(null);
4706
+ const lastYRef = useRef10(0);
4707
+ const lastMoveTimeRef = useRef10(0);
4708
+ const velocityRef = useRef10(0);
4709
+ const pointerIdRef = useRef10(null);
4710
+ const isPullingRef = useRef10(false);
4711
+ const pullDistanceRef = useRef10(0);
4712
+ const flingRafRef = useRef10(null);
4713
+ const [pullDistance, setPullDistance] = useState11(0);
4714
+ const [isRefreshing, setIsRefreshing] = useState11(false);
4715
+ const [isTracking, setIsTracking] = useState11(false);
4716
+ const disabledRef = useRef10(disabled);
4717
+ disabledRef.current = disabled;
4718
+ const onRefreshRef = useRef10(onRefresh);
4719
+ onRefreshRef.current = onRefresh;
4720
+ const pullThresholdRef = useRef10(pullThreshold);
4721
+ pullThresholdRef.current = pullThreshold;
4722
+ const maxPullRef = useRef10(maxPull);
4723
+ maxPullRef.current = maxPull;
4650
4724
  useEffect10(() => {
4725
+ const el = containerRef.current;
4726
+ if (!el) return;
4727
+ const updatePullDistance = (value) => {
4728
+ pullDistanceRef.current = value;
4729
+ setPullDistance(value);
4730
+ };
4731
+ const stopFling = () => {
4732
+ if (flingRafRef.current !== null) {
4733
+ cancelAnimationFrame(flingRafRef.current);
4734
+ flingRafRef.current = null;
4735
+ }
4736
+ };
4737
+ const resetTracking = () => {
4738
+ pointerIdRef.current = null;
4739
+ startYRef.current = null;
4740
+ isPullingRef.current = false;
4741
+ setIsTracking(false);
4742
+ updatePullDistance(0);
4743
+ };
4744
+ const runFling = () => {
4745
+ velocityRef.current *= FLING_FRICTION;
4746
+ if (Math.abs(velocityRef.current) < FLING_MIN_VELOCITY) {
4747
+ flingRafRef.current = null;
4748
+ return;
4749
+ }
4750
+ el.scrollTop -= velocityRef.current * 16;
4751
+ if (el.scrollTop <= 0 || el.scrollTop >= el.scrollHeight - el.clientHeight) {
4752
+ flingRafRef.current = null;
4753
+ return;
4754
+ }
4755
+ flingRafRef.current = requestAnimationFrame(runFling);
4756
+ };
4757
+ const handlePointerDown = (e) => {
4758
+ if (disabledRef.current) return;
4759
+ if (pointerIdRef.current !== null) return;
4760
+ stopFling();
4761
+ pointerIdRef.current = e.pointerId;
4762
+ startYRef.current = e.clientY;
4763
+ lastYRef.current = e.clientY;
4764
+ lastMoveTimeRef.current = performance.now();
4765
+ velocityRef.current = 0;
4766
+ isPullingRef.current = false;
4767
+ setIsTracking(true);
4768
+ try {
4769
+ el.setPointerCapture(e.pointerId);
4770
+ } catch {
4771
+ }
4772
+ };
4773
+ const handlePointerMove = (e) => {
4774
+ if (startYRef.current === null || e.pointerId !== pointerIdRef.current) {
4775
+ return;
4776
+ }
4777
+ const totalDelta = e.clientY - startYRef.current;
4778
+ if (!isPullingRef.current && Math.abs(totalDelta) < DRAG_DEADZONE) {
4779
+ return;
4780
+ }
4781
+ const now = performance.now();
4782
+ const stepDelta = e.clientY - lastYRef.current;
4783
+ const dt = Math.max(now - lastMoveTimeRef.current, 1);
4784
+ velocityRef.current = stepDelta / dt;
4785
+ lastYRef.current = e.clientY;
4786
+ lastMoveTimeRef.current = now;
4787
+ if (e.cancelable) e.preventDefault();
4788
+ const atTop = el.scrollTop <= 0;
4789
+ if (atTop && totalDelta > 0) {
4790
+ isPullingRef.current = true;
4791
+ updatePullDistance(
4792
+ Math.min(
4793
+ Math.max(totalDelta - DRAG_DEADZONE, 0) * RESISTANCE,
4794
+ maxPullRef.current
4795
+ )
4796
+ );
4797
+ return;
4798
+ }
4799
+ if (isPullingRef.current) {
4800
+ isPullingRef.current = false;
4801
+ updatePullDistance(0);
4802
+ }
4803
+ el.scrollTop -= stepDelta;
4804
+ };
4805
+ const handlePointerEnd = (e) => {
4806
+ if (startYRef.current === null || e.pointerId !== pointerIdRef.current) {
4807
+ return;
4808
+ }
4809
+ const wasPulling = isPullingRef.current;
4810
+ pointerIdRef.current = null;
4811
+ startYRef.current = null;
4812
+ isPullingRef.current = false;
4813
+ setIsTracking(false);
4814
+ if (!wasPulling) {
4815
+ if (Math.abs(velocityRef.current) > FLING_MIN_VELOCITY) {
4816
+ stopFling();
4817
+ flingRafRef.current = requestAnimationFrame(runFling);
4818
+ }
4819
+ return;
4820
+ }
4821
+ const shouldRefresh = pullDistanceRef.current >= pullThresholdRef.current;
4822
+ if (!shouldRefresh) {
4823
+ updatePullDistance(0);
4824
+ return;
4825
+ }
4826
+ setIsRefreshing(true);
4827
+ updatePullDistance(pullThresholdRef.current);
4828
+ Promise.resolve(onRefreshRef.current()).catch((err) => {
4829
+ console.error("Pull-to-refresh failed:", err);
4830
+ }).finally(() => {
4831
+ setIsRefreshing(false);
4832
+ updatePullDistance(0);
4833
+ });
4834
+ };
4835
+ const handlePointerCancel = (e) => {
4836
+ if (e.pointerId !== pointerIdRef.current) return;
4837
+ stopFling();
4838
+ resetTracking();
4839
+ };
4840
+ el.addEventListener("pointerdown", handlePointerDown);
4841
+ el.addEventListener("pointermove", handlePointerMove, { passive: false });
4842
+ el.addEventListener("pointerup", handlePointerEnd);
4843
+ el.addEventListener("pointercancel", handlePointerCancel);
4844
+ return () => {
4845
+ stopFling();
4846
+ el.removeEventListener("pointerdown", handlePointerDown);
4847
+ el.removeEventListener("pointermove", handlePointerMove);
4848
+ el.removeEventListener("pointerup", handlePointerEnd);
4849
+ el.removeEventListener("pointercancel", handlePointerCancel);
4850
+ };
4851
+ }, []);
4852
+ const indicatorHeight = isRefreshing ? pullThreshold : pullDistance;
4853
+ const progress = Math.min(indicatorHeight / pullThreshold, 1);
4854
+ const isSettling = pullDistance === 0 && !isRefreshing && !isTracking;
4855
+ return /* @__PURE__ */ jsxs14(
4856
+ "div",
4857
+ {
4858
+ className: `up-sdk-pull-to-refresh ${className}`,
4859
+ ref: containerRef,
4860
+ style: {
4861
+ overflowY: "auto",
4862
+ overscrollBehavior: "none",
4863
+ touchAction: "none"
4864
+ },
4865
+ children: [
4866
+ /* @__PURE__ */ jsx18("style", { children: ".up-sdk-pull-to-refresh::-webkit-scrollbar { display: none; } .up-sdk-pull-to-refresh { scrollbar-width: none; -ms-overflow-style: none; }" }),
4867
+ /* @__PURE__ */ jsx18(
4868
+ "div",
4869
+ {
4870
+ style: {
4871
+ alignItems: "center",
4872
+ display: "flex",
4873
+ height: indicatorHeight,
4874
+ justifyContent: "center",
4875
+ overflow: "hidden",
4876
+ transition: isSettling ? "height 0.2s ease-out" : "none",
4877
+ userSelect: "none",
4878
+ width: "100%"
4879
+ },
4880
+ children: renderIndicator ? renderIndicator({ isRefreshing, progress }) : /* @__PURE__ */ jsx18(DefaultIndicator, { isRefreshing, progress })
4881
+ }
4882
+ ),
4883
+ children
4884
+ ]
4885
+ }
4886
+ );
4887
+ };
4888
+
4889
+ // src/components/QRScanner.tsx
4890
+ import jsQR2 from "jsqr";
4891
+ import { useEffect as useEffect11, useRef as useRef11, useState as useState12 } from "react";
4892
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
4893
+ function QRScanner({ onScan, onError, className = "" }) {
4894
+ const videoRef = useRef11(null);
4895
+ const canvasRef = useRef11(null);
4896
+ const streamRef = useRef11(null);
4897
+ const tickRequestRef = useRef11(null);
4898
+ const hasScannedRef = useRef11(false);
4899
+ const [isReady, setIsReady] = useState12(false);
4900
+ useEffect11(() => {
4651
4901
  let cancelled = false;
4652
4902
  hasScannedRef.current = false;
4653
4903
  const cleanup = () => {
@@ -4730,7 +4980,7 @@ function QRScanner({ onScan, onError, className = "" }) {
4730
4980
  cleanup();
4731
4981
  };
4732
4982
  }, []);
4733
- return /* @__PURE__ */ jsxs14(
4983
+ return /* @__PURE__ */ jsxs15(
4734
4984
  "div",
4735
4985
  {
4736
4986
  className,
@@ -4742,7 +4992,7 @@ function QRScanner({ onScan, onError, className = "" }) {
4742
4992
  position: "relative"
4743
4993
  },
4744
4994
  children: [
4745
- /* @__PURE__ */ jsx18(
4995
+ /* @__PURE__ */ jsx19(
4746
4996
  "video",
4747
4997
  {
4748
4998
  playsInline: true,
@@ -4750,8 +5000,8 @@ function QRScanner({ onScan, onError, className = "" }) {
4750
5000
  style: { height: "100%", objectFit: "cover", width: "100%" }
4751
5001
  }
4752
5002
  ),
4753
- /* @__PURE__ */ jsx18("canvas", { ref: canvasRef, style: { display: "none" } }),
4754
- isReady && /* @__PURE__ */ jsx18(
5003
+ /* @__PURE__ */ jsx19("canvas", { ref: canvasRef, style: { display: "none" } }),
5004
+ isReady && /* @__PURE__ */ jsx19(
4755
5005
  "div",
4756
5006
  {
4757
5007
  style: {
@@ -4773,7 +5023,7 @@ function QRScanner({ onScan, onError, className = "" }) {
4773
5023
 
4774
5024
  // src/components/SDKProvider.tsx
4775
5025
  import { createContext as createContext3, useContext as useContext6, useMemo as useMemo8 } from "react";
4776
- import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
5026
+ import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
4777
5027
  var SDKContext = createContext3({ isMocked: false });
4778
5028
  var useIsMocked = () => useContext6(SDKContext).isMocked;
4779
5029
  var SDKProvider = ({
@@ -4783,24 +5033,24 @@ var SDKProvider = ({
4783
5033
  }) => {
4784
5034
  const isMocked = typeof window !== "undefined" && !(window.__UP_REACT_NATIVE_APP__ === true || !!window.ReactNativeWebView);
4785
5035
  const value = useMemo8(() => ({ isMocked }), [isMocked]);
4786
- const content = /* @__PURE__ */ jsxs15(Fragment5, { children: [
5036
+ const content = /* @__PURE__ */ jsxs16(Fragment5, { children: [
4787
5037
  children,
4788
- (debug || isMocked) && /* @__PURE__ */ jsx19(DebugConsole, {})
5038
+ (debug || isMocked) && /* @__PURE__ */ jsx20(DebugConsole, {})
4789
5039
  ] });
4790
5040
  if (isMocked) {
4791
- return /* @__PURE__ */ jsx19(SDKContext.Provider, { value, children: /* @__PURE__ */ jsx19(BridgeMocker, { ...mockerProps, children: content }) });
5041
+ return /* @__PURE__ */ jsx20(SDKContext.Provider, { value, children: /* @__PURE__ */ jsx20(BridgeMocker, { ...mockerProps, children: content }) });
4792
5042
  }
4793
- return /* @__PURE__ */ jsx19(SDKContext.Provider, { value, children: content });
5043
+ return /* @__PURE__ */ jsx20(SDKContext.Provider, { value, children: content });
4794
5044
  };
4795
5045
 
4796
5046
  // src/components/SwipeCarousel.tsx
4797
5047
  import {
4798
- useEffect as useEffect11,
5048
+ useEffect as useEffect12,
4799
5049
  useLayoutEffect,
4800
- useRef as useRef11,
4801
- useState as useState12
5050
+ useRef as useRef12,
5051
+ useState as useState13
4802
5052
  } from "react";
4803
- import { jsx as jsx20 } from "react/jsx-runtime";
5053
+ import { jsx as jsx21 } from "react/jsx-runtime";
4804
5054
  var DIRECTION_LOCK_THRESHOLD_PX = 8;
4805
5055
  var SWIPE_DISTANCE_THRESHOLD_PX = 40;
4806
5056
  var SWIPE_VELOCITY_THRESHOLD = 0.4;
@@ -4827,28 +5077,28 @@ var SwipeCarousel = ({
4827
5077
  overscan = DEFAULT_OVERSCAN,
4828
5078
  visibleOverscan = DEFAULT_VISIBLE_OVERSCAN
4829
5079
  }) => {
4830
- const containerRef = useRef11(null);
4831
- const [containerWidth, setContainerWidth] = useState12(0);
4832
- const [dragX, setDragX] = useState12(0);
4833
- const [dragY, setDragY] = useState12(0);
4834
- const [isDraggingX, setIsDraggingX] = useState12(false);
4835
- const [isDraggingY, setIsDraggingY] = useState12(false);
4836
- const touchStateRef = useRef11(null);
4837
- const [internalIndex, setInternalIndex] = useState12(
5080
+ const containerRef = useRef12(null);
5081
+ const [containerWidth, setContainerWidth] = useState13(0);
5082
+ const [dragX, setDragX] = useState13(0);
5083
+ const [dragY, setDragY] = useState13(0);
5084
+ const [isDraggingX, setIsDraggingX] = useState13(false);
5085
+ const [isDraggingY, setIsDraggingY] = useState13(false);
5086
+ const touchStateRef = useRef12(null);
5087
+ const [internalIndex, setInternalIndex] = useState13(
4838
5088
  () => Math.max(
4839
5089
  0,
4840
5090
  items.findIndex((item) => item.id === activeId)
4841
5091
  )
4842
5092
  );
4843
- const prevActiveIdRef = useRef11(activeId);
4844
- const [timingWaiting, setTimingWaiting] = useState12(true);
4845
- useEffect11(() => {
5093
+ const prevActiveIdRef = useRef12(activeId);
5094
+ const [timingWaiting, setTimingWaiting] = useState13(true);
5095
+ useEffect12(() => {
4846
5096
  const timer = setTimeout(() => {
4847
5097
  setTimingWaiting(false);
4848
5098
  }, 1e3);
4849
5099
  return () => clearTimeout(timer);
4850
5100
  }, []);
4851
- useEffect11(() => {
5101
+ useEffect12(() => {
4852
5102
  if (activeId !== prevActiveIdRef.current) {
4853
5103
  const idx = items.findIndex((item) => item.id === activeId);
4854
5104
  if (idx !== -1) setInternalIndex(idx);
@@ -4977,7 +5227,7 @@ var SwipeCarousel = ({
4977
5227
  };
4978
5228
  const windowStart = Math.max(0, activeIndex - overscan);
4979
5229
  const windowEnd = Math.min(items.length - 1, activeIndex + overscan);
4980
- return /* @__PURE__ */ jsx20(
5230
+ return /* @__PURE__ */ jsx21(
4981
5231
  "div",
4982
5232
  {
4983
5233
  className: `relative overflow-hidden touch-pan-y ${className ?? ""}`,
@@ -4986,7 +5236,7 @@ var SwipeCarousel = ({
4986
5236
  onTouchMove: handleTouchMove,
4987
5237
  onTouchStart: handleTouchStart,
4988
5238
  ref: containerRef,
4989
- children: /* @__PURE__ */ jsx20(
5239
+ children: /* @__PURE__ */ jsx21(
4990
5240
  "div",
4991
5241
  {
4992
5242
  className: "relative h-full",
@@ -5001,7 +5251,7 @@ var SwipeCarousel = ({
5001
5251
  const verticalOffset = isActive ? dragY : 0;
5002
5252
  const distance = Math.abs(index - activeIndex);
5003
5253
  const isVisible = distance <= visibleOverscan;
5004
- return /* @__PURE__ */ jsx20(
5254
+ return /* @__PURE__ */ jsx21(
5005
5255
  "div",
5006
5256
  {
5007
5257
  className: `absolute top-0 left-0 h-full shrink-0 ${itemClassName ?? ""} ${item.className ?? ""}`,
@@ -5276,6 +5526,7 @@ export {
5276
5526
  MapMenuTitle,
5277
5527
  MiniAppSDK,
5278
5528
  MockLocationContext,
5529
+ PullToRefresh,
5279
5530
  QRScanner,
5280
5531
  RouteLayer,
5281
5532
  SDKMapProvider,