@shopify/shop-minis-react 0.2.1 → 0.2.3
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/_virtual/index10.js +2 -2
- package/dist/_virtual/index4.js +3 -2
- package/dist/_virtual/index4.js.map +1 -1
- package/dist/_virtual/index7.js +2 -3
- package/dist/_virtual/index7.js.map +1 -1
- package/dist/_virtual/index9.js +2 -2
- package/dist/internal/useReportInteraction.js +21 -0
- package/dist/internal/useReportInteraction.js.map +1 -0
- package/dist/providers/ImagePickerProvider.js +122 -63
- package/dist/providers/ImagePickerProvider.js.map +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js +1 -1
- package/dist/utils/getWindowLocationPathname.js +7 -0
- package/dist/utils/getWindowLocationPathname.js.map +1 -0
- package/eslint/rules/prefer-sdk-components.cjs +0 -79
- package/eslint/rules/validate-manifest.cjs +86 -2
- package/generated-hook-maps/component-scopes-map.json +18 -0
- package/package.json +1 -2
- package/src/providers/ImagePickerProvider.test.tsx +391 -0
- package/src/providers/ImagePickerProvider.tsx +93 -12
package/dist/_virtual/index10.js
CHANGED
package/dist/_virtual/index4.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { __require as r } from "../shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js";
|
|
2
|
+
var i = r();
|
|
2
3
|
export {
|
|
3
|
-
|
|
4
|
+
i as s
|
|
4
5
|
};
|
|
5
6
|
//# sourceMappingURL=index4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
package/dist/_virtual/index7.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
var i = r();
|
|
1
|
+
var r = {};
|
|
3
2
|
export {
|
|
4
|
-
|
|
3
|
+
r as __exports
|
|
5
4
|
};
|
|
6
5
|
//# sourceMappingURL=index7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
package/dist/_virtual/index9.js
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useCallback as n } from "react";
|
|
2
|
+
import { getWindowLocationPathname as a } from "../utils/getWindowLocationPathname.js";
|
|
3
|
+
import { useHandleAction as c } from "./useHandleAction.js";
|
|
4
|
+
import { useShopActions as i } from "./useShopActions.js";
|
|
5
|
+
const d = () => {
|
|
6
|
+
const { reportInteraction: r } = i(), o = c(r);
|
|
7
|
+
return { reportInteraction: n(
|
|
8
|
+
(t) => {
|
|
9
|
+
const e = {
|
|
10
|
+
...t,
|
|
11
|
+
pageValue: t.pageValue || a()
|
|
12
|
+
};
|
|
13
|
+
return o(e);
|
|
14
|
+
},
|
|
15
|
+
[o]
|
|
16
|
+
) };
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
d as useReportInteraction
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=useReportInteraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useReportInteraction.js","sources":["../../src/internal/useReportInteraction.ts"],"sourcesContent":["import {useCallback} from 'react'\n\nimport {ReportInteractionParams} from '@shopify/shop-minis-platform/actions'\n\nimport {getWindowLocationPathname} from '../utils/getWindowLocationPathname'\n\nimport {useHandleAction} from './useHandleAction'\nimport {useShopActions} from './useShopActions'\n\ninterface UseReportInteractionReturns {\n /**\n * Report a user interaction event for analytics.\n */\n reportInteraction: (params: ReportInteractionParams) => Promise<void>\n}\n\nexport const useReportInteraction = (): UseReportInteractionReturns => {\n const {reportInteraction} = useShopActions()\n const handleAction = useHandleAction(reportInteraction)\n\n const report = useCallback(\n (params: ReportInteractionParams) => {\n const enrichedParams = {\n ...params,\n pageValue: params.pageValue || getWindowLocationPathname(),\n }\n return handleAction(enrichedParams)\n },\n [handleAction]\n )\n\n return {reportInteraction: report}\n}\n"],"names":["useReportInteraction","reportInteraction","useShopActions","handleAction","useHandleAction","useCallback","params","enrichedParams","getWindowLocationPathname"],"mappings":";;;;AAgBO,MAAMA,IAAuB,MAAmC;AAC/D,QAAA,EAAC,mBAAAC,EAAiB,IAAIC,EAAe,GACrCC,IAAeC,EAAgBH,CAAiB;AAa/C,SAAA,EAAC,mBAXOI;AAAA,IACb,CAACC,MAAoC;AACnC,YAAMC,IAAiB;AAAA,QACrB,GAAGD;AAAA,QACH,WAAWA,EAAO,aAAaE,EAA0B;AAAA,MAC3D;AACA,aAAOL,EAAaI,CAAc;AAAA,IACpC;AAAA,IACA,CAACJ,CAAY;AAAA,EACf,EAEiC;AACnC;"}
|
|
@@ -1,108 +1,167 @@
|
|
|
1
|
-
import { jsxs as x, jsx as
|
|
2
|
-
import { useRef as
|
|
1
|
+
import { jsxs as x, jsx as h } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as p, useCallback as d, useEffect as I, useMemo as V, createContext as b, useContext as A } from "react";
|
|
3
3
|
import { useRequestPermissions as L } from "../hooks/util/useRequestPermissions.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
import { useReportInteraction as M } from "../internal/useReportInteraction.js";
|
|
5
|
+
const R = b(null);
|
|
6
|
+
function F() {
|
|
7
|
+
const g = A(R);
|
|
8
|
+
if (!g)
|
|
8
9
|
throw new Error(
|
|
9
10
|
"useImagePickerContext must be used within an ImagePickerProvider"
|
|
10
11
|
);
|
|
11
|
-
return
|
|
12
|
+
return g;
|
|
12
13
|
}
|
|
13
|
-
function
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
const { input:
|
|
17
|
-
|
|
14
|
+
function N({ children: g }) {
|
|
15
|
+
const k = p(null), _ = p(null), E = p(null), t = p(null), e = p(null), f = p(null), n = p(null), { requestPermission: y } = L(), { reportInteraction: r } = M(), a = d(() => {
|
|
16
|
+
if (f.current) {
|
|
17
|
+
const { input: c, handler: i } = f.current;
|
|
18
|
+
c.removeEventListener("cancel", i), f.current = null;
|
|
18
19
|
}
|
|
19
|
-
}, []),
|
|
20
|
-
|
|
21
|
-
new Error(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
}, []), m = d(() => {
|
|
21
|
+
if (e.current) {
|
|
22
|
+
const c = new Error(
|
|
23
|
+
"New file picker opened before previous completed"
|
|
24
|
+
);
|
|
25
|
+
n.current === "gallery" ? r({
|
|
26
|
+
interactionType: "image_picker_error",
|
|
27
|
+
interactionValue: c.message
|
|
28
|
+
}) : n.current === "camera" && r({
|
|
29
|
+
interactionType: "camera_error",
|
|
30
|
+
interactionValue: c.message
|
|
31
|
+
}), e.current(c), t.current = null, e.current = null, n.current = null;
|
|
32
|
+
}
|
|
33
|
+
}, [r]), C = d(
|
|
34
|
+
(c) => {
|
|
35
|
+
const i = c.target.files?.[0];
|
|
36
|
+
i && t.current && (n.current === "gallery" ? r({
|
|
37
|
+
interactionType: "image_picker_success"
|
|
38
|
+
}) : n.current === "camera" && r({
|
|
39
|
+
interactionType: "camera_success"
|
|
40
|
+
}), t.current(i), t.current = null, e.current = null, n.current = null, a()), c.target.value = "";
|
|
27
41
|
},
|
|
28
|
-
[r]
|
|
29
|
-
),
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
if (!
|
|
33
|
-
|
|
42
|
+
[a, r]
|
|
43
|
+
), P = d(() => new Promise((c, i) => {
|
|
44
|
+
m(), a(), t.current = c, e.current = i, n.current = "gallery";
|
|
45
|
+
const u = k.current;
|
|
46
|
+
if (!u) {
|
|
47
|
+
const o = new Error("Gallery input not found");
|
|
48
|
+
r({
|
|
49
|
+
interactionType: "image_picker_error",
|
|
50
|
+
interactionValue: o.message
|
|
51
|
+
}), i(o), t.current = null, e.current = null, n.current = null;
|
|
34
52
|
return;
|
|
35
53
|
}
|
|
36
|
-
const
|
|
37
|
-
|
|
54
|
+
const s = () => {
|
|
55
|
+
if (e.current) {
|
|
56
|
+
const o = new Error("User cancelled file selection");
|
|
57
|
+
r({
|
|
58
|
+
interactionType: "image_picker_error",
|
|
59
|
+
interactionValue: o.message
|
|
60
|
+
}), e.current(o), t.current = null, e.current = null, n.current = null;
|
|
61
|
+
}
|
|
62
|
+
a();
|
|
38
63
|
};
|
|
39
|
-
|
|
40
|
-
|
|
64
|
+
u.addEventListener("cancel", s), f.current = { input: u, handler: s }, r({
|
|
65
|
+
interactionType: "image_picker_open"
|
|
66
|
+
}), y({ permission: "CAMERA" }).then(() => {
|
|
67
|
+
u.click();
|
|
41
68
|
}).catch(() => {
|
|
42
|
-
|
|
69
|
+
u.click();
|
|
43
70
|
});
|
|
44
|
-
}), [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
71
|
+
}), [
|
|
72
|
+
m,
|
|
73
|
+
a,
|
|
74
|
+
y,
|
|
75
|
+
r
|
|
76
|
+
]), v = d(
|
|
77
|
+
(c = "back") => new Promise((i, u) => {
|
|
78
|
+
m(), a(), t.current = i, e.current = u, n.current = "camera";
|
|
79
|
+
const s = c === "front" ? _.current : E.current;
|
|
80
|
+
if (!s) {
|
|
81
|
+
const l = new Error("Camera input not found");
|
|
82
|
+
r({
|
|
83
|
+
interactionType: "camera_error",
|
|
84
|
+
interactionValue: l.message
|
|
85
|
+
}), u(l), t.current = null, e.current = null, n.current = null;
|
|
50
86
|
return;
|
|
51
87
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
88
|
+
const o = () => {
|
|
89
|
+
if (e.current) {
|
|
90
|
+
const l = new Error("User cancelled camera");
|
|
91
|
+
r({
|
|
92
|
+
interactionType: "camera_error",
|
|
93
|
+
interactionValue: l.message
|
|
94
|
+
}), e.current(l), t.current = null, e.current = null, n.current = null;
|
|
95
|
+
}
|
|
96
|
+
a();
|
|
54
97
|
};
|
|
55
|
-
|
|
56
|
-
|
|
98
|
+
s.addEventListener("cancel", o), f.current = { input: s, handler: o }, r({
|
|
99
|
+
interactionType: "camera_open"
|
|
100
|
+
}), y({ permission: "CAMERA" }).then(({ granted: l }) => {
|
|
101
|
+
if (l)
|
|
102
|
+
s.click();
|
|
103
|
+
else {
|
|
104
|
+
const w = new Error("Camera permission not granted");
|
|
105
|
+
r({
|
|
106
|
+
interactionType: "camera_error",
|
|
107
|
+
interactionValue: w.message
|
|
108
|
+
}), u(w), t.current = null, e.current = null, n.current = null;
|
|
109
|
+
}
|
|
57
110
|
}).catch(() => {
|
|
58
|
-
|
|
111
|
+
const l = new Error("Camera permission not granted");
|
|
112
|
+
u(l), t.current = null, e.current = null, n.current = null;
|
|
59
113
|
});
|
|
60
114
|
}),
|
|
61
|
-
[
|
|
115
|
+
[
|
|
116
|
+
m,
|
|
117
|
+
a,
|
|
118
|
+
y,
|
|
119
|
+
r
|
|
120
|
+
]
|
|
62
121
|
);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}, [
|
|
66
|
-
const
|
|
122
|
+
I(() => () => {
|
|
123
|
+
m(), a();
|
|
124
|
+
}, [m, a]);
|
|
125
|
+
const T = V(
|
|
67
126
|
() => ({
|
|
68
|
-
openCamera:
|
|
69
|
-
openGallery:
|
|
127
|
+
openCamera: v,
|
|
128
|
+
openGallery: P
|
|
70
129
|
}),
|
|
71
|
-
[
|
|
130
|
+
[v, P]
|
|
72
131
|
);
|
|
73
|
-
return /* @__PURE__ */ x(
|
|
74
|
-
|
|
75
|
-
/* @__PURE__ */
|
|
132
|
+
return /* @__PURE__ */ x(R.Provider, { value: T, children: [
|
|
133
|
+
g,
|
|
134
|
+
/* @__PURE__ */ h(
|
|
76
135
|
"input",
|
|
77
136
|
{
|
|
78
|
-
ref:
|
|
137
|
+
ref: k,
|
|
79
138
|
type: "file",
|
|
80
139
|
accept: "image/*",
|
|
81
|
-
onChange:
|
|
140
|
+
onChange: C,
|
|
82
141
|
style: { display: "none" },
|
|
83
142
|
"aria-hidden": "true"
|
|
84
143
|
}
|
|
85
144
|
),
|
|
86
|
-
/* @__PURE__ */
|
|
145
|
+
/* @__PURE__ */ h(
|
|
87
146
|
"input",
|
|
88
147
|
{
|
|
89
|
-
ref:
|
|
148
|
+
ref: _,
|
|
90
149
|
type: "file",
|
|
91
150
|
accept: "image/*",
|
|
92
151
|
capture: "user",
|
|
93
|
-
onChange:
|
|
152
|
+
onChange: C,
|
|
94
153
|
style: { display: "none" },
|
|
95
154
|
"aria-hidden": "true"
|
|
96
155
|
}
|
|
97
156
|
),
|
|
98
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ h(
|
|
99
158
|
"input",
|
|
100
159
|
{
|
|
101
|
-
ref:
|
|
160
|
+
ref: E,
|
|
102
161
|
type: "file",
|
|
103
162
|
accept: "image/*",
|
|
104
163
|
capture: "environment",
|
|
105
|
-
onChange:
|
|
164
|
+
onChange: C,
|
|
106
165
|
style: { display: "none" },
|
|
107
166
|
"aria-hidden": "true"
|
|
108
167
|
}
|
|
@@ -110,7 +169,7 @@ function U({ children: f }) {
|
|
|
110
169
|
] });
|
|
111
170
|
}
|
|
112
171
|
export {
|
|
113
|
-
|
|
114
|
-
|
|
172
|
+
N as ImagePickerProvider,
|
|
173
|
+
F as useImagePickerContext
|
|
115
174
|
};
|
|
116
175
|
//# sourceMappingURL=ImagePickerProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImagePickerProvider.js","sources":["../../src/providers/ImagePickerProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useRef,\n useCallback,\n useEffect,\n useMemo,\n} from 'react'\n\nimport {useRequestPermissions} from '../hooks/util/useRequestPermissions'\n\nexport type CameraFacing = 'front' | 'back'\n\ninterface ImagePickerContextValue {\n openCamera: (cameraFacing?: CameraFacing) => Promise<File>\n openGallery: () => Promise<File>\n}\n\nconst ImagePickerContext = createContext<ImagePickerContextValue | null>(null)\n\nexport function useImagePickerContext() {\n const context = useContext(ImagePickerContext)\n if (!context) {\n throw new Error(\n 'useImagePickerContext must be used within an ImagePickerProvider'\n )\n }\n return context\n}\n\ninterface ImagePickerProviderProps {\n children: React.ReactNode\n}\n\nexport function ImagePickerProvider({children}: ImagePickerProviderProps) {\n const galleryInputRef = useRef<HTMLInputElement>(null)\n const frontCameraInputRef = useRef<HTMLInputElement>(null)\n const backCameraInputRef = useRef<HTMLInputElement>(null)\n const resolveRef = useRef<((file: File) => void) | null>(null)\n const rejectRef = useRef<((reason: Error) => void) | null>(null)\n const activeCancelHandlerRef = useRef<{\n input: HTMLInputElement\n handler: () => void\n } | null>(null)\n\n const {requestPermission} = useRequestPermissions()\n\n const cleanupCancelHandler = useCallback(() => {\n if (activeCancelHandlerRef.current) {\n const {input, handler} = activeCancelHandlerRef.current\n input.removeEventListener('cancel', handler)\n activeCancelHandlerRef.current = null\n }\n }, [])\n\n const rejectPendingPromise = useCallback(() => {\n if (rejectRef.current) {\n rejectRef.current(\n new Error('New file picker opened before previous completed')\n )\n resolveRef.current = null\n rejectRef.current = null\n }\n }, [])\n\n const handleFileChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0]\n\n if (file && resolveRef.current) {\n resolveRef.current(file)\n\n resolveRef.current = null\n rejectRef.current = null\n\n cleanupCancelHandler()\n }\n\n event.target.value = ''\n },\n [cleanupCancelHandler]\n )\n\n const openGallery = useCallback(() => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n resolveRef.current = resolve\n rejectRef.current = reject\n\n const input = galleryInputRef.current\n\n if (!input) {\n reject(new Error('Gallery input not found'))\n resolveRef.current = null\n rejectRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n rejectRef.current(new Error('User cancelled file selection'))\n resolveRef.current = null\n rejectRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n requestPermission({permission: 'CAMERA'})\n .then(() => {\n // This will show both Camera and Gallery\n input.click()\n })\n .catch(() => {\n // Show only Gallery\n input.click()\n })\n })\n }, [rejectPendingPromise, cleanupCancelHandler, requestPermission])\n\n const openCamera = useCallback(\n (cameraFacing: CameraFacing = 'back') => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n resolveRef.current = resolve\n rejectRef.current = reject\n\n const input =\n cameraFacing === 'front'\n ? frontCameraInputRef.current\n : backCameraInputRef.current\n\n if (!input) {\n reject(new Error('Camera input not found'))\n resolveRef.current = null\n rejectRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n rejectRef.current(new Error('User cancelled camera'))\n resolveRef.current = null\n rejectRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n requestPermission({permission: 'CAMERA'})\n .then(({granted}) => {\n if (granted) {\n input.click()\n } else {\n reject(new Error('Camera permission not granted'))\n resolveRef.current = null\n rejectRef.current = null\n }\n })\n .catch(() => {\n reject(new Error('Camera permission not granted'))\n resolveRef.current = null\n rejectRef.current = null\n })\n })\n },\n [rejectPendingPromise, cleanupCancelHandler, requestPermission]\n )\n\n useEffect(() => {\n return () => {\n rejectPendingPromise()\n cleanupCancelHandler()\n }\n }, [rejectPendingPromise, cleanupCancelHandler])\n\n const contextValue: ImagePickerContextValue = useMemo(\n () => ({\n openCamera,\n openGallery,\n }),\n [openCamera, openGallery]\n )\n\n return (\n <ImagePickerContext.Provider value={contextValue}>\n {children}\n <input\n ref={galleryInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={frontCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"user\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={backCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n </ImagePickerContext.Provider>\n )\n}\n"],"names":["ImagePickerContext","createContext","useImagePickerContext","context","useContext","ImagePickerProvider","children","galleryInputRef","useRef","frontCameraInputRef","backCameraInputRef","resolveRef","rejectRef","activeCancelHandlerRef","requestPermission","useRequestPermissions","cleanupCancelHandler","useCallback","input","handler","rejectPendingPromise","handleFileChange","event","file","openGallery","resolve","reject","handleCancel","openCamera","cameraFacing","granted","useEffect","contextValue","useMemo","jsxs","jsx"],"mappings":";;;AAkBA,MAAMA,IAAqBC,EAA8C,IAAI;AAEtE,SAASC,IAAwB;AAChC,QAAAC,IAAUC,EAAWJ,CAAkB;AAC7C,MAAI,CAACG;AACH,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAEK,SAAAA;AACT;AAMgB,SAAAE,EAAoB,EAAC,UAAAC,KAAqC;AAClE,QAAAC,IAAkBC,EAAyB,IAAI,GAC/CC,IAAsBD,EAAyB,IAAI,GACnDE,IAAqBF,EAAyB,IAAI,GAClDG,IAAaH,EAAsC,IAAI,GACvDI,IAAYJ,EAAyC,IAAI,GACzDK,IAAyBL,EAGrB,IAAI,GAER,EAAC,mBAAAM,EAAiB,IAAIC,EAAsB,GAE5CC,IAAuBC,EAAY,MAAM;AAC7C,QAAIJ,EAAuB,SAAS;AAClC,YAAM,EAAC,OAAAK,GAAO,SAAAC,EAAO,IAAIN,EAAuB;AAC1C,MAAAK,EAAA,oBAAoB,UAAUC,CAAO,GAC3CN,EAAuB,UAAU;AAAA,IAAA;AAAA,EAErC,GAAG,EAAE,GAECO,IAAuBH,EAAY,MAAM;AAC7C,IAAIL,EAAU,YACFA,EAAA;AAAA,MACR,IAAI,MAAM,kDAAkD;AAAA,IAC9D,GACAD,EAAW,UAAU,MACrBC,EAAU,UAAU;AAAA,EAExB,GAAG,EAAE,GAECS,IAAmBJ;AAAA,IACvB,CAACK,MAA+C;AAC9C,YAAMC,IAAOD,EAAM,OAAO,QAAQ,CAAC;AAE/B,MAAAC,KAAQZ,EAAW,YACrBA,EAAW,QAAQY,CAAI,GAEvBZ,EAAW,UAAU,MACrBC,EAAU,UAAU,MAECI,EAAA,IAGvBM,EAAM,OAAO,QAAQ;AAAA,IACvB;AAAA,IACA,CAACN,CAAoB;AAAA,EACvB,GAEMQ,IAAcP,EAAY,MACvB,IAAI,QAAc,CAACQ,GAASC,MAAW;AACvB,IAAAN,EAAA,GACAJ,EAAA,GAErBL,EAAW,UAAUc,GACrBb,EAAU,UAAUc;AAEpB,UAAMR,IAAQX,EAAgB;AAE9B,QAAI,CAACW,GAAO;AACH,MAAAQ,EAAA,IAAI,MAAM,yBAAyB,CAAC,GAC3Cf,EAAW,UAAU,MACrBC,EAAU,UAAU;AACpB;AAAA,IAAA;AAGF,UAAMe,IAAe,MAAM;AACzB,MAAIf,EAAU,YACZA,EAAU,QAAQ,IAAI,MAAM,+BAA+B,CAAC,GAC5DD,EAAW,UAAU,MACrBC,EAAU,UAAU,OAEDI,EAAA;AAAA,IACvB;AAEM,IAAAE,EAAA,iBAAiB,UAAUS,CAAY,GAC7Cd,EAAuB,UAAU,EAAC,OAAAK,GAAO,SAASS,EAAY,GAE9Db,EAAkB,EAAC,YAAY,SAAA,CAAS,EACrC,KAAK,MAAM;AAEV,MAAAI,EAAM,MAAM;AAAA,IAAA,CACb,EACA,MAAM,MAAM;AAEX,MAAAA,EAAM,MAAM;AAAA,IAAA,CACb;AAAA,EAAA,CACJ,GACA,CAACE,GAAsBJ,GAAsBF,CAAiB,CAAC,GAE5Dc,IAAaX;AAAA,IACjB,CAACY,IAA6B,WACrB,IAAI,QAAc,CAACJ,GAASC,MAAW;AACvB,MAAAN,EAAA,GACAJ,EAAA,GAErBL,EAAW,UAAUc,GACrBb,EAAU,UAAUc;AAEpB,YAAMR,IACJW,MAAiB,UACbpB,EAAoB,UACpBC,EAAmB;AAEzB,UAAI,CAACQ,GAAO;AACH,QAAAQ,EAAA,IAAI,MAAM,wBAAwB,CAAC,GAC1Cf,EAAW,UAAU,MACrBC,EAAU,UAAU;AACpB;AAAA,MAAA;AAGF,YAAMe,IAAe,MAAM;AACzB,QAAIf,EAAU,YACZA,EAAU,QAAQ,IAAI,MAAM,uBAAuB,CAAC,GACpDD,EAAW,UAAU,MACrBC,EAAU,UAAU,OAEDI,EAAA;AAAA,MACvB;AAEM,MAAAE,EAAA,iBAAiB,UAAUS,CAAY,GAC7Cd,EAAuB,UAAU,EAAC,OAAAK,GAAO,SAASS,EAAY,GAE5Cb,EAAA,EAAC,YAAY,SAAQ,CAAC,EACrC,KAAK,CAAC,EAAC,SAAAgB,QAAa;AACnB,QAAIA,IACFZ,EAAM,MAAM,KAELQ,EAAA,IAAI,MAAM,+BAA+B,CAAC,GACjDf,EAAW,UAAU,MACrBC,EAAU,UAAU;AAAA,MACtB,CACD,EACA,MAAM,MAAM;AACJ,QAAAc,EAAA,IAAI,MAAM,+BAA+B,CAAC,GACjDf,EAAW,UAAU,MACrBC,EAAU,UAAU;AAAA,MAAA,CACrB;AAAA,IAAA,CACJ;AAAA,IAEH,CAACQ,GAAsBJ,GAAsBF,CAAiB;AAAA,EAChE;AAEA,EAAAiB,EAAU,MACD,MAAM;AACU,IAAAX,EAAA,GACAJ,EAAA;AAAA,EACvB,GACC,CAACI,GAAsBJ,CAAoB,CAAC;AAE/C,QAAMgB,IAAwCC;AAAA,IAC5C,OAAO;AAAA,MACL,YAAAL;AAAA,MACA,aAAAJ;AAAA,IAAA;AAAA,IAEF,CAACI,GAAYJ,CAAW;AAAA,EAC1B;AAEA,SACG,gBAAAU,EAAAlC,EAAmB,UAAnB,EAA4B,OAAOgC,GACjC,UAAA;AAAA,IAAA1B;AAAA,IACD,gBAAA6B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK5B;AAAA,QACL,MAAK;AAAA,QACL,QAAO;AAAA,QACP,UAAUc;AAAA,QACV,OAAO,EAAC,SAAS,OAAM;AAAA,QACvB,eAAY;AAAA,MAAA;AAAA,IACd;AAAA,IACA,gBAAAc;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK1B;AAAA,QACL,MAAK;AAAA,QACL,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,UAAUY;AAAA,QACV,OAAO,EAAC,SAAS,OAAM;AAAA,QACvB,eAAY;AAAA,MAAA;AAAA,IACd;AAAA,IACA,gBAAAc;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKzB;AAAA,QACL,MAAK;AAAA,QACL,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,UAAUW;AAAA,QACV,OAAO,EAAC,SAAS,OAAM;AAAA,QACvB,eAAY;AAAA,MAAA;AAAA,IAAA;AAAA,EACd,GACF;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"ImagePickerProvider.js","sources":["../../src/providers/ImagePickerProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useRef,\n useCallback,\n useEffect,\n useMemo,\n} from 'react'\n\nimport {useRequestPermissions} from '../hooks/util/useRequestPermissions'\nimport {useReportInteraction} from '../internal/useReportInteraction'\n\nexport type CameraFacing = 'front' | 'back'\n\ninterface ImagePickerContextValue {\n openCamera: (cameraFacing?: CameraFacing) => Promise<File>\n openGallery: () => Promise<File>\n}\n\nconst ImagePickerContext = createContext<ImagePickerContextValue | null>(null)\n\nexport function useImagePickerContext() {\n const context = useContext(ImagePickerContext)\n if (!context) {\n throw new Error(\n 'useImagePickerContext must be used within an ImagePickerProvider'\n )\n }\n return context\n}\n\ninterface ImagePickerProviderProps {\n children: React.ReactNode\n}\n\nexport function ImagePickerProvider({children}: ImagePickerProviderProps) {\n const galleryInputRef = useRef<HTMLInputElement>(null)\n const frontCameraInputRef = useRef<HTMLInputElement>(null)\n const backCameraInputRef = useRef<HTMLInputElement>(null)\n const resolveRef = useRef<((file: File) => void) | null>(null)\n const rejectRef = useRef<((reason: Error) => void) | null>(null)\n const activeCancelHandlerRef = useRef<{\n input: HTMLInputElement\n handler: () => void\n } | null>(null)\n const activeOperationRef = useRef<'gallery' | 'camera' | null>(null)\n\n const {requestPermission} = useRequestPermissions()\n const {reportInteraction} = useReportInteraction()\n\n const cleanupCancelHandler = useCallback(() => {\n if (activeCancelHandlerRef.current) {\n const {input, handler} = activeCancelHandlerRef.current\n input.removeEventListener('cancel', handler)\n activeCancelHandlerRef.current = null\n }\n }, [])\n\n const rejectPendingPromise = useCallback(() => {\n if (rejectRef.current) {\n const error = new Error(\n 'New file picker opened before previous completed'\n )\n if (activeOperationRef.current === 'gallery') {\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n } else if (activeOperationRef.current === 'camera') {\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n }\n\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n }, [reportInteraction])\n\n const handleFileChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0]\n\n if (file && resolveRef.current) {\n // Report success based on the active operation\n if (activeOperationRef.current === 'gallery') {\n reportInteraction({\n interactionType: 'image_picker_success',\n })\n } else if (activeOperationRef.current === 'camera') {\n reportInteraction({\n interactionType: 'camera_success',\n })\n }\n\n resolveRef.current(file)\n\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n\n cleanupCancelHandler()\n }\n\n event.target.value = ''\n },\n [cleanupCancelHandler, reportInteraction]\n )\n\n const openGallery = useCallback(() => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n resolveRef.current = resolve\n rejectRef.current = reject\n activeOperationRef.current = 'gallery'\n\n const input = galleryInputRef.current\n\n if (!input) {\n const error = new Error('Gallery input not found')\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n const error = new Error('User cancelled file selection')\n reportInteraction({\n interactionType: 'image_picker_error',\n interactionValue: error.message,\n })\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n reportInteraction({\n interactionType: 'image_picker_open',\n })\n\n requestPermission({permission: 'CAMERA'})\n .then(() => {\n // This will show both Camera and Gallery\n input.click()\n })\n .catch(() => {\n // Show only Gallery\n input.click()\n })\n })\n }, [\n rejectPendingPromise,\n cleanupCancelHandler,\n requestPermission,\n reportInteraction,\n ])\n\n const openCamera = useCallback(\n (cameraFacing: CameraFacing = 'back') => {\n return new Promise<File>((resolve, reject) => {\n rejectPendingPromise()\n cleanupCancelHandler()\n\n resolveRef.current = resolve\n rejectRef.current = reject\n activeOperationRef.current = 'camera'\n\n const input =\n cameraFacing === 'front'\n ? frontCameraInputRef.current\n : backCameraInputRef.current\n\n if (!input) {\n const error = new Error('Camera input not found')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n return\n }\n\n const handleCancel = () => {\n if (rejectRef.current) {\n const error = new Error('User cancelled camera')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n rejectRef.current(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n cleanupCancelHandler()\n }\n\n input.addEventListener('cancel', handleCancel)\n activeCancelHandlerRef.current = {input, handler: handleCancel}\n\n reportInteraction({\n interactionType: 'camera_open',\n })\n\n requestPermission({permission: 'CAMERA'})\n .then(({granted}) => {\n if (granted) {\n input.click()\n } else {\n const error = new Error('Camera permission not granted')\n reportInteraction({\n interactionType: 'camera_error',\n interactionValue: error.message,\n })\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n }\n })\n .catch(() => {\n const error = new Error('Camera permission not granted')\n reject(error)\n resolveRef.current = null\n rejectRef.current = null\n activeOperationRef.current = null\n })\n })\n },\n [\n rejectPendingPromise,\n cleanupCancelHandler,\n requestPermission,\n reportInteraction,\n ]\n )\n\n useEffect(() => {\n return () => {\n rejectPendingPromise()\n cleanupCancelHandler()\n }\n }, [rejectPendingPromise, cleanupCancelHandler])\n\n const contextValue: ImagePickerContextValue = useMemo(\n () => ({\n openCamera,\n openGallery,\n }),\n [openCamera, openGallery]\n )\n\n return (\n <ImagePickerContext.Provider value={contextValue}>\n {children}\n <input\n ref={galleryInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={frontCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"user\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n <input\n ref={backCameraInputRef}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={handleFileChange}\n style={{display: 'none'}}\n aria-hidden=\"true\"\n />\n </ImagePickerContext.Provider>\n )\n}\n"],"names":["ImagePickerContext","createContext","useImagePickerContext","context","useContext","ImagePickerProvider","children","galleryInputRef","useRef","frontCameraInputRef","backCameraInputRef","resolveRef","rejectRef","activeCancelHandlerRef","activeOperationRef","requestPermission","useRequestPermissions","reportInteraction","useReportInteraction","cleanupCancelHandler","useCallback","input","handler","rejectPendingPromise","error","handleFileChange","event","file","openGallery","resolve","reject","handleCancel","openCamera","cameraFacing","granted","useEffect","contextValue","useMemo","jsxs","jsx"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as r } from "../../../../../../../_virtual/
|
|
1
|
+
import { __module as r } from "../../../../../../../_virtual/index9.js";
|
|
2
2
|
import { __require as o } from "../cjs/use-sync-external-store-shim.production.js";
|
|
3
3
|
import { __require as i } from "../cjs/use-sync-external-store-shim.development.js";
|
|
4
4
|
var e;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getWindowLocationPathname.js","sources":["../../src/utils/getWindowLocationPathname.ts"],"sourcesContent":["export function getWindowLocationPathname(): string {\n if (typeof window !== 'undefined' && window.location) {\n return window.location.pathname || '/'\n }\n return ''\n}\n"],"names":["getWindowLocationPathname"],"mappings":"AAAO,SAASA,IAAoC;AAClD,SAAI,OAAO,SAAW,OAAe,OAAO,WACnC,OAAO,SAAS,YAAY,MAE9B;AACT;"}
|
|
@@ -12,7 +12,6 @@ module.exports = {
|
|
|
12
12
|
category: 'Best Practices',
|
|
13
13
|
recommended: true,
|
|
14
14
|
},
|
|
15
|
-
fixable: 'code',
|
|
16
15
|
messages: {
|
|
17
16
|
preferSdkComponent:
|
|
18
17
|
'Use <{{sdkComponent}}> from @shopify/shop-minis-react instead of <{{nativeElement}}>. The SDK component provides optimized performance, consistent styling, and additional features.',
|
|
@@ -52,9 +51,6 @@ module.exports = {
|
|
|
52
51
|
...(options.components || {}),
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
// eslint-disable-next-line @shopify/prefer-module-scope-constants
|
|
56
|
-
const SDK_PACKAGE = '@shopify/shop-minis-react'
|
|
57
|
-
|
|
58
54
|
return {
|
|
59
55
|
JSXOpeningElement(node) {
|
|
60
56
|
const elementName = node.name.name
|
|
@@ -70,81 +66,6 @@ module.exports = {
|
|
|
70
66
|
nativeElement: elementName,
|
|
71
67
|
sdkComponent,
|
|
72
68
|
},
|
|
73
|
-
fix(fixer) {
|
|
74
|
-
const sourceCode = context.getSourceCode()
|
|
75
|
-
const openingElement = node
|
|
76
|
-
const jsxElement = node.parent
|
|
77
|
-
|
|
78
|
-
// Get the closing element if it exists
|
|
79
|
-
const closingElement = jsxElement.closingElement
|
|
80
|
-
|
|
81
|
-
const fixes = []
|
|
82
|
-
|
|
83
|
-
// Fix opening tag
|
|
84
|
-
const openingTagStart = openingElement.name.range[0]
|
|
85
|
-
const openingTagEnd = openingElement.name.range[1]
|
|
86
|
-
fixes.push(
|
|
87
|
-
fixer.replaceTextRange(
|
|
88
|
-
[openingTagStart, openingTagEnd],
|
|
89
|
-
sdkComponent
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
// Fix closing tag if it exists (not self-closing)
|
|
94
|
-
if (closingElement) {
|
|
95
|
-
const closingTagStart = closingElement.name.range[0]
|
|
96
|
-
const closingTagEnd = closingElement.name.range[1]
|
|
97
|
-
fixes.push(
|
|
98
|
-
fixer.replaceTextRange(
|
|
99
|
-
[closingTagStart, closingTagEnd],
|
|
100
|
-
sdkComponent
|
|
101
|
-
)
|
|
102
|
-
)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Add import if it doesn't exist
|
|
106
|
-
const program = sourceCode.ast
|
|
107
|
-
const imports = program.body.filter(
|
|
108
|
-
importNode => importNode.type === 'ImportDeclaration'
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
// Check if we already import from the SDK
|
|
112
|
-
const sdkImport = imports.find(
|
|
113
|
-
importNode => importNode.source.value === SDK_PACKAGE
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
if (sdkImport) {
|
|
117
|
-
// Check if this component is already imported
|
|
118
|
-
const hasComponent = sdkImport.specifiers.some(
|
|
119
|
-
spec =>
|
|
120
|
-
spec.type === 'ImportSpecifier' &&
|
|
121
|
-
spec.imported.name === sdkComponent
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
if (!hasComponent) {
|
|
125
|
-
// Add component to existing import
|
|
126
|
-
const lastSpecifier =
|
|
127
|
-
sdkImport.specifiers[sdkImport.specifiers.length - 1]
|
|
128
|
-
fixes.push(
|
|
129
|
-
fixer.insertTextAfter(lastSpecifier, `, ${sdkComponent}`)
|
|
130
|
-
)
|
|
131
|
-
}
|
|
132
|
-
} else {
|
|
133
|
-
// Add new import statement
|
|
134
|
-
const firstNode = program.body[0]
|
|
135
|
-
const importStatement = `import {${sdkComponent}} from '${SDK_PACKAGE}'\n`
|
|
136
|
-
|
|
137
|
-
if (firstNode) {
|
|
138
|
-
fixes.push(fixer.insertTextBefore(firstNode, importStatement))
|
|
139
|
-
} else {
|
|
140
|
-
fixes.push(
|
|
141
|
-
fixer.insertTextAfterRange([0, 0], importStatement)
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return fixes
|
|
147
|
-
},
|
|
148
69
|
})
|
|
149
70
|
}
|
|
150
71
|
},
|