@shopify/shop-minis-react 0.0.0-snapshot.20251219160956 → 0.0.0-snapshot.20251222174301
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/components/navigation/minis-router.js +8 -15
- package/dist/components/navigation/minis-router.js.map +1 -1
- package/dist/hooks/intents/useBarcodeScanner.js +10 -0
- package/dist/hooks/intents/useBarcodeScanner.js.map +1 -0
- package/dist/hooks/intents/useContentShare.js +10 -0
- package/dist/hooks/intents/useContentShare.js.map +1 -0
- package/dist/hooks/intents/useImageCapture.js +10 -0
- package/dist/hooks/intents/useImageCapture.js.map +1 -0
- package/dist/hooks/intents/useLocationSelection.js +10 -0
- package/dist/hooks/intents/useLocationSelection.js.map +1 -0
- package/dist/hooks/intents/usePaymentRequest.js +10 -0
- package/dist/hooks/intents/usePaymentRequest.js.map +1 -0
- package/dist/hooks/intents/useProductSelection.js +10 -0
- package/dist/hooks/intents/useProductSelection.js.map +1 -0
- package/dist/index.js +131 -118
- package/dist/index.js.map +1 -1
- package/dist/internal/useHandleIntent.js +26 -0
- package/dist/internal/useHandleIntent.js.map +1 -0
- package/dist/internal/useShopIntents.js +7 -0
- package/dist/internal/useShopIntents.js.map +1 -0
- package/dist/mocks.js +10 -11
- package/dist/mocks.js.map +1 -1
- package/dist/shop-minis-platform/src/intents/shared.js +19 -0
- package/dist/shop-minis-platform/src/intents/shared.js.map +1 -0
- package/package.json +2 -2
- package/src/components/navigation/minis-router.tsx +1 -9
- package/src/hooks/index.ts +3 -1
- package/src/hooks/intents/index.ts +42 -0
- package/src/hooks/intents/useBarcodeScanner.ts +43 -0
- package/src/hooks/intents/useContentShare.ts +47 -0
- package/src/hooks/intents/useImageCapture.ts +45 -0
- package/src/hooks/intents/useLocationSelection.ts +45 -0
- package/src/hooks/intents/usePaymentRequest.ts +47 -0
- package/src/hooks/intents/useProductSelection.ts +45 -0
- package/src/internal/useHandleIntent.ts +101 -0
- package/src/internal/useShopIntents.ts +13 -0
- package/src/mocks.ts +0 -1
- package/dist/hooks/events/useOnNavigateBack.js +0 -14
- package/dist/hooks/events/useOnNavigateBack.js.map +0 -1
- package/dist/internal/navigation-manager.js +0 -28
- package/dist/internal/navigation-manager.js.map +0 -1
- package/src/hooks/events/useOnNavigateBack.ts +0 -16
- package/src/internal/navigation-manager.tsx +0 -41
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {useCallback} from 'react'
|
|
2
|
+
|
|
3
|
+
import {IntentResultCode} from '@shopify/shop-minis-platform'
|
|
4
|
+
|
|
5
|
+
import type {ShopIntentResult} from '@shopify/shop-minis-platform'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for handling intent results
|
|
9
|
+
*/
|
|
10
|
+
export interface HandleIntentOptions<T> {
|
|
11
|
+
/**
|
|
12
|
+
* Handler called when user cancels the intent
|
|
13
|
+
* If not provided, cancellation is treated as a no-op (returns undefined)
|
|
14
|
+
*/
|
|
15
|
+
onCancel?: () => T | void
|
|
16
|
+
/**
|
|
17
|
+
* Handler called when intent fails
|
|
18
|
+
* If not provided, throws the error
|
|
19
|
+
*/
|
|
20
|
+
onError?: (error: {message: string; code?: string}) => T | void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Wrapper to handle intent results
|
|
25
|
+
*
|
|
26
|
+
* Unlike actions which can reject, intents ALWAYS resolve with a result code.
|
|
27
|
+
* This hook provides a cleaner API for handling intent results:
|
|
28
|
+
*
|
|
29
|
+
* - SUCCESS: Returns the data
|
|
30
|
+
* - CANCELLED: Calls onCancel or returns undefined
|
|
31
|
+
* - FAILED: Calls onError or throws the error
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const selectProduct = useHandleIntent(intents.selectProduct, {
|
|
35
|
+
* onCancel: () => console.log('User cancelled'),
|
|
36
|
+
* onError: (error) => console.error('Selection failed:', error)
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* const result = await selectProduct({multiSelect: true})
|
|
40
|
+
* // result is the data, or undefined if cancelled
|
|
41
|
+
*/
|
|
42
|
+
export const useHandleIntent = <T, Args extends unknown[]>(
|
|
43
|
+
intent: (...args: Args) => Promise<ShopIntentResult<T>>,
|
|
44
|
+
options?: HandleIntentOptions<T>
|
|
45
|
+
) => {
|
|
46
|
+
return useCallback(
|
|
47
|
+
async (...args: Args): Promise<T | void> => {
|
|
48
|
+
const result = await intent(...args)
|
|
49
|
+
|
|
50
|
+
switch (result.resultCode) {
|
|
51
|
+
case IntentResultCode.SUCCESS:
|
|
52
|
+
return result.data!
|
|
53
|
+
|
|
54
|
+
case IntentResultCode.CANCELLED:
|
|
55
|
+
if (options?.onCancel) {
|
|
56
|
+
return options.onCancel()
|
|
57
|
+
}
|
|
58
|
+
return undefined
|
|
59
|
+
|
|
60
|
+
case IntentResultCode.FAILED:
|
|
61
|
+
if (options?.onError) {
|
|
62
|
+
return options.onError(result.error!)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
throw new Error(result.error?.message || 'Intent failed')
|
|
66
|
+
|
|
67
|
+
default: {
|
|
68
|
+
// Exhaustiveness check
|
|
69
|
+
const _exhaustive: never = result.resultCode
|
|
70
|
+
throw new Error(`Unhandled result code: ${_exhaustive}`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
[intent, options]
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Alternative: Manual result handling without throwing
|
|
80
|
+
*
|
|
81
|
+
* Use this when you want to handle all result codes explicitly
|
|
82
|
+
* without throwing errors.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const selectProduct = useHandleIntentManual(intents.selectProduct)
|
|
86
|
+
*
|
|
87
|
+
* const result = await selectProduct({multiSelect: true})
|
|
88
|
+
* if (result.resultCode === 'SUCCESS') {
|
|
89
|
+
* console.log(result.data)
|
|
90
|
+
* }
|
|
91
|
+
*/
|
|
92
|
+
export const useHandleIntentManual = <T, Args extends unknown[]>(
|
|
93
|
+
intent: (...args: Args) => Promise<ShopIntentResult<T>>
|
|
94
|
+
) => {
|
|
95
|
+
return useCallback(
|
|
96
|
+
(...args: Args) => {
|
|
97
|
+
return intent(...args)
|
|
98
|
+
},
|
|
99
|
+
[intent]
|
|
100
|
+
)
|
|
101
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type {ShopIntents} from '@shopify/shop-minis-platform'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Internal hook to access Shop Intents
|
|
5
|
+
*
|
|
6
|
+
* This provides direct access to window.minisIntents
|
|
7
|
+
* Use specific intent hooks (like useProductSelection) instead of this hook directly
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export function useShopIntents(): ShopIntents {
|
|
12
|
+
return window.minisIntents
|
|
13
|
+
}
|
package/src/mocks.ts
CHANGED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { useRef as i, useEffect as o } from "react";
|
|
2
|
-
function s(n) {
|
|
3
|
-
const e = i(n);
|
|
4
|
-
e.current = n, o(() => {
|
|
5
|
-
const t = window.minisEvents.on("NAVIGATE_BACK", () => {
|
|
6
|
-
e.current();
|
|
7
|
-
});
|
|
8
|
-
return () => window.minisEvents.off(t);
|
|
9
|
-
}, []);
|
|
10
|
-
}
|
|
11
|
-
export {
|
|
12
|
-
s as useOnNavigateBack
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=useOnNavigateBack.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useOnNavigateBack.js","sources":["../../../src/hooks/events/useOnNavigateBack.ts"],"sourcesContent":["import {useEffect, useRef} from 'react'\n\nexport function useOnNavigateBack(callback: () => void) {\n // Using a ref allows the callback to be updated without triggering a re-render\n // This makes the hook nicer to use because developers don't need useCallback\n const callbackRef = useRef(callback)\n callbackRef.current = callback\n\n useEffect(() => {\n const listenerId = window.minisEvents.on('NAVIGATE_BACK', () => {\n callbackRef.current()\n })\n\n return () => window.minisEvents.off(listenerId)\n }, [])\n}\n"],"names":["useOnNavigateBack","callback","callbackRef","useRef","useEffect","listenerId"],"mappings":";AAEO,SAASA,EAAkBC,GAAsB;AAGhD,QAAAC,IAAcC,EAAOF,CAAQ;AACnC,EAAAC,EAAY,UAAUD,GAEtBG,EAAU,MAAM;AACd,UAAMC,IAAa,OAAO,YAAY,GAAG,iBAAiB,MAAM;AAC9D,MAAAH,EAAY,QAAQ;AAAA,IAAA,CACrB;AAED,WAAO,MAAM,OAAO,YAAY,IAAIG,CAAU;AAAA,EAChD,GAAG,EAAE;AACP;"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { useEffect as e } from "react";
|
|
2
|
-
import { useLocation as a } from "../shop-minis-react/node_modules/.pnpm/react-router@7.7.0_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-router/dist/development/chunk-EF7DTUVF.js";
|
|
3
|
-
import { useOnNavigateBack as r } from "../hooks/events/useOnNavigateBack.js";
|
|
4
|
-
import { useNavigateWithTransition as s } from "../hooks/navigation/useNavigateWithTransition.js";
|
|
5
|
-
import { useShopActions as h } from "./useShopActions.js";
|
|
6
|
-
function u() {
|
|
7
|
-
const t = a(), i = s(), { reportNavigationState: o } = h();
|
|
8
|
-
return e(() => {
|
|
9
|
-
const n = {
|
|
10
|
-
location: {
|
|
11
|
-
pathname: t.pathname,
|
|
12
|
-
search: t.search,
|
|
13
|
-
hash: t.hash,
|
|
14
|
-
key: t.key,
|
|
15
|
-
state: t.state
|
|
16
|
-
},
|
|
17
|
-
historyLength: typeof window > "u" ? 0 : window.history.length,
|
|
18
|
-
historyIndex: typeof window > "u" || !window.history.state?.idx ? null : window.history.state.idx
|
|
19
|
-
};
|
|
20
|
-
o(n);
|
|
21
|
-
}, [t, o]), r(() => {
|
|
22
|
-
i(-1);
|
|
23
|
-
}), null;
|
|
24
|
-
}
|
|
25
|
-
export {
|
|
26
|
-
u as NavigationManager
|
|
27
|
-
};
|
|
28
|
-
//# sourceMappingURL=navigation-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-manager.js","sources":["../../src/internal/navigation-manager.tsx"],"sourcesContent":["import {useEffect} from 'react'\n\nimport {useLocation} from 'react-router'\n\nimport {useOnNavigateBack} from '../hooks/events/useOnNavigateBack'\nimport {useNavigateWithTransition} from '../hooks/navigation/useNavigateWithTransition'\n\nimport {useShopActions} from './useShopActions'\n\nexport function NavigationManager() {\n const location = useLocation()\n const navigate = useNavigateWithTransition()\n const {reportNavigationState} = useShopActions()\n\n // Report navigation state on location changes\n useEffect(() => {\n const navigationState = {\n location: {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n key: location.key,\n state: location.state,\n },\n historyLength: typeof window === 'undefined' ? 0 : window.history.length,\n historyIndex:\n typeof window === 'undefined' || !window.history.state?.idx\n ? null\n : window.history.state.idx,\n }\n\n reportNavigationState(navigationState)\n }, [location, reportNavigationState])\n\n // Handle native back button press\n useOnNavigateBack(() => {\n navigate(-1)\n })\n\n return null\n}\n"],"names":["NavigationManager","location","useLocation","navigate","useNavigateWithTransition","reportNavigationState","useShopActions","useEffect","navigationState","useOnNavigateBack"],"mappings":";;;;;AASO,SAASA,IAAoB;AAClC,QAAMC,IAAWC,EAAY,GACvBC,IAAWC,EAA0B,GACrC,EAAC,uBAAAC,EAAqB,IAAIC,EAAe;AAG/C,SAAAC,EAAU,MAAM;AACd,UAAMC,IAAkB;AAAA,MACtB,UAAU;AAAA,QACR,UAAUP,EAAS;AAAA,QACnB,QAAQA,EAAS;AAAA,QACjB,MAAMA,EAAS;AAAA,QACf,KAAKA,EAAS;AAAA,QACd,OAAOA,EAAS;AAAA,MAClB;AAAA,MACA,eAAe,OAAO,SAAW,MAAc,IAAI,OAAO,QAAQ;AAAA,MAClE,cACE,OAAO,SAAW,OAAe,CAAC,OAAO,QAAQ,OAAO,MACpD,OACA,OAAO,QAAQ,MAAM;AAAA,IAC7B;AAEA,IAAAI,EAAsBG,CAAe;AAAA,EAAA,GACpC,CAACP,GAAUI,CAAqB,CAAC,GAGpCI,EAAkB,MAAM;AACtB,IAAAN,EAAS,EAAE;AAAA,EAAA,CACZ,GAEM;AACT;"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {useEffect, useRef} from 'react'
|
|
2
|
-
|
|
3
|
-
export function useOnNavigateBack(callback: () => void) {
|
|
4
|
-
// Using a ref allows the callback to be updated without triggering a re-render
|
|
5
|
-
// This makes the hook nicer to use because developers don't need useCallback
|
|
6
|
-
const callbackRef = useRef(callback)
|
|
7
|
-
callbackRef.current = callback
|
|
8
|
-
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
const listenerId = window.minisEvents.on('NAVIGATE_BACK', () => {
|
|
11
|
-
callbackRef.current()
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
return () => window.minisEvents.off(listenerId)
|
|
15
|
-
}, [])
|
|
16
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import {useEffect} from 'react'
|
|
2
|
-
|
|
3
|
-
import {useLocation} from 'react-router'
|
|
4
|
-
|
|
5
|
-
import {useOnNavigateBack} from '../hooks/events/useOnNavigateBack'
|
|
6
|
-
import {useNavigateWithTransition} from '../hooks/navigation/useNavigateWithTransition'
|
|
7
|
-
|
|
8
|
-
import {useShopActions} from './useShopActions'
|
|
9
|
-
|
|
10
|
-
export function NavigationManager() {
|
|
11
|
-
const location = useLocation()
|
|
12
|
-
const navigate = useNavigateWithTransition()
|
|
13
|
-
const {reportNavigationState} = useShopActions()
|
|
14
|
-
|
|
15
|
-
// Report navigation state on location changes
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
const navigationState = {
|
|
18
|
-
location: {
|
|
19
|
-
pathname: location.pathname,
|
|
20
|
-
search: location.search,
|
|
21
|
-
hash: location.hash,
|
|
22
|
-
key: location.key,
|
|
23
|
-
state: location.state,
|
|
24
|
-
},
|
|
25
|
-
historyLength: typeof window === 'undefined' ? 0 : window.history.length,
|
|
26
|
-
historyIndex:
|
|
27
|
-
typeof window === 'undefined' || !window.history.state?.idx
|
|
28
|
-
? null
|
|
29
|
-
: window.history.state.idx,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
reportNavigationState(navigationState)
|
|
33
|
-
}, [location, reportNavigationState])
|
|
34
|
-
|
|
35
|
-
// Handle native back button press
|
|
36
|
-
useOnNavigateBack(() => {
|
|
37
|
-
navigate(-1)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
return null
|
|
41
|
-
}
|