@redotech/redo-hydrogen 1.3.1 → 1.4.1
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/CHANGELOG.md +9 -0
- package/README.md +3 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/types.d.ts +11 -1
- package/package.json +5 -2
- package/rollup.config.js +1 -1
- package/src/components/icons/featured-laptop-2.svg +57 -0
- package/src/components/icons/featured-package-check.svg +57 -0
- package/src/components/icons/featured-refresh-cw-3.svg +57 -0
- package/src/components/icons/info.svg +20 -0
- package/src/components/icons/logo.svg +13 -0
- package/src/components/icons/modal-close-button.svg +37 -0
- package/src/components/icons/shield-tick.svg +13 -0
- package/src/components/redo-info-modal.tsx +432 -0
- package/src/index.ts +3 -1
- package/src/svg.d.ts +4 -3
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import { ReactNode, useState, useEffect } from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
3
|
+
import InfoIcon from "./icons/info.svg";
|
|
4
|
+
import ShieldIcon from "./icons/shield-tick.svg";
|
|
5
|
+
import { useRedoCoverageClient } from "../providers/redo-coverage-client";
|
|
6
|
+
import FeaturedPackageCheckIcon from "./icons/featured-package-check.svg";
|
|
7
|
+
import FeaturedLaptopIcon from "./icons/featured-laptop-2.svg";
|
|
8
|
+
import FeaturedRefreshIcon from "./icons/featured-refresh-cw-3.svg";
|
|
9
|
+
import RedoLogo from "./icons/logo.svg";
|
|
10
|
+
import CloseIcon from "./icons/modal-close-button.svg"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
interface RedoInfoModalProps {
|
|
14
|
+
showInfoIcon?: boolean;
|
|
15
|
+
onInfoClick?: () => void;
|
|
16
|
+
infoCardImageUrl?: string;
|
|
17
|
+
infoModalLogoUrl?: string;
|
|
18
|
+
infoModalImageUrl?: string;
|
|
19
|
+
infoModalContent?: ReactNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function useInjectStyle(styleContent: string) {
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const styleTag = document.createElement('style');
|
|
25
|
+
styleTag.textContent = styleContent;
|
|
26
|
+
document.head.appendChild(styleTag);
|
|
27
|
+
return () => {
|
|
28
|
+
document.head.removeChild(styleTag);
|
|
29
|
+
};
|
|
30
|
+
}, [styleContent]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const Modal = ({ open, onClose, infoModalLogoUrl, infoModalImageUrl, modalContent }:
|
|
34
|
+
{
|
|
35
|
+
open: boolean;
|
|
36
|
+
onClose: () => void;
|
|
37
|
+
infoModalLogoUrl?: string;
|
|
38
|
+
infoModalImageUrl?: string;
|
|
39
|
+
modalContent?: ReactNode;
|
|
40
|
+
}) => {
|
|
41
|
+
useInjectStyle( `
|
|
42
|
+
${fadeInKeyframes}
|
|
43
|
+
${slideInKeyframes}
|
|
44
|
+
|
|
45
|
+
@media (max-width: 768px) {
|
|
46
|
+
.redo-info-modal__container {
|
|
47
|
+
flex-direction: column !important;
|
|
48
|
+
align-items: stretch !important;
|
|
49
|
+
overflow: auto !important;
|
|
50
|
+
width: 95% !important;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.redo-info-modal__sideImageContainer {
|
|
54
|
+
width: 100% !important;
|
|
55
|
+
min-width: unset !important;
|
|
56
|
+
max-height: 140px !important;
|
|
57
|
+
overflow: hidden !important;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.redo-info-modal__sideImageContainer img {
|
|
61
|
+
height: 140px !important;
|
|
62
|
+
max-height: 140px !important;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.redo-info-modal__contentContainer {
|
|
66
|
+
width: 100% !important;
|
|
67
|
+
box-sizing: border-box !important;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
`);
|
|
71
|
+
|
|
72
|
+
if (!open) return <></>;
|
|
73
|
+
|
|
74
|
+
const fullModalContent = (
|
|
75
|
+
<div className="redo-info-modal__backgroundContainer" style={{
|
|
76
|
+
position: 'fixed',
|
|
77
|
+
top: 0,
|
|
78
|
+
left: 0,
|
|
79
|
+
right: 0,
|
|
80
|
+
bottom: 0,
|
|
81
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
82
|
+
display: 'flex',
|
|
83
|
+
alignItems: 'center',
|
|
84
|
+
justifyContent: 'center',
|
|
85
|
+
zIndex: 99999,
|
|
86
|
+
transform: 'translateZ(0)',
|
|
87
|
+
opacity: 1,
|
|
88
|
+
transition: 'opacity 0.2s ease-in-out',
|
|
89
|
+
animation: 'fadeIn 0.2s ease-in-out'
|
|
90
|
+
}} onClick={onClose}>
|
|
91
|
+
<div className="redo-info-modal__container" style={{
|
|
92
|
+
backgroundColor: 'white',
|
|
93
|
+
borderRadius: '8px',
|
|
94
|
+
width: '700px',
|
|
95
|
+
maxWidth: '900px',
|
|
96
|
+
position: 'absolute',
|
|
97
|
+
top: '50%',
|
|
98
|
+
left: '50%',
|
|
99
|
+
transform: 'translate(-50%, -50%)',
|
|
100
|
+
zIndex: 100000,
|
|
101
|
+
display: 'flex',
|
|
102
|
+
flexDirection: 'row',
|
|
103
|
+
alignItems: 'center',
|
|
104
|
+
justifyContent: 'left',
|
|
105
|
+
maxHeight: '95%',
|
|
106
|
+
boxShadow: '0 4px 8px 0 rgba(0, 0, 0, 0.2)',
|
|
107
|
+
opacity: 1,
|
|
108
|
+
transition: 'opacity 0.2s ease-in-out, transform 0.2s ease-in-out',
|
|
109
|
+
animation: 'slideIn 0.2s ease-in-out forwards',
|
|
110
|
+
minHeight: '100px',
|
|
111
|
+
}} onClick={e => e.stopPropagation()}>
|
|
112
|
+
<button
|
|
113
|
+
className="redo-info-modal__closeButton"
|
|
114
|
+
onClick={onClose}
|
|
115
|
+
style={{
|
|
116
|
+
position: 'absolute',
|
|
117
|
+
right: '16px',
|
|
118
|
+
top: '16px',
|
|
119
|
+
border: 'none',
|
|
120
|
+
background: 'none',
|
|
121
|
+
fontSize: '20px',
|
|
122
|
+
cursor: 'pointer',
|
|
123
|
+
padding: '4px',
|
|
124
|
+
zIndex: 1
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
<CloseIcon />
|
|
128
|
+
</button>
|
|
129
|
+
{infoModalImageUrl ? (
|
|
130
|
+
<div className="redo-info-modal__sideImageContainer" style={{
|
|
131
|
+
minWidth: '200px',
|
|
132
|
+
width: '200px',
|
|
133
|
+
backgroundImage: `url(${infoModalImageUrl})`,
|
|
134
|
+
backgroundSize: 'cover',
|
|
135
|
+
backgroundPosition: 'center center',
|
|
136
|
+
borderTopLeftRadius: '8px',
|
|
137
|
+
borderBottomLeftRadius: '8px',
|
|
138
|
+
alignSelf: 'stretch',
|
|
139
|
+
}}>
|
|
140
|
+
</div>
|
|
141
|
+
) : null}
|
|
142
|
+
{modalContent ? modalContent : (
|
|
143
|
+
<div className="redo-info-modal__contentContainer" style={{
|
|
144
|
+
padding: '24px',
|
|
145
|
+
fontFamily: 'Inter, "Helvetica Neue", Arial, sans-serif',
|
|
146
|
+
}}>
|
|
147
|
+
<div className="redo-info-modal__logoContainer" style={{
|
|
148
|
+
width: '100%',
|
|
149
|
+
height: '100%',
|
|
150
|
+
display: 'block',
|
|
151
|
+
marginBottom: '8px'
|
|
152
|
+
}}>
|
|
153
|
+
{infoModalLogoUrl ? (
|
|
154
|
+
<img src={infoModalLogoUrl} className="redo-info-modal__logo" style={{
|
|
155
|
+
width: 'auto',
|
|
156
|
+
height: '112px',
|
|
157
|
+
display: 'block',
|
|
158
|
+
}}/>
|
|
159
|
+
) : <RedoLogo width="112px" height="112px" display="block"/>}
|
|
160
|
+
</div>
|
|
161
|
+
<p style={{
|
|
162
|
+
fontSize: '20px',
|
|
163
|
+
fontWeight: '600'
|
|
164
|
+
}} className="redo-info-modal__title">
|
|
165
|
+
Checkout with confidence
|
|
166
|
+
</p>
|
|
167
|
+
|
|
168
|
+
<p style={{
|
|
169
|
+
fontSize: '14px',
|
|
170
|
+
color: '#666',
|
|
171
|
+
marginBottom: '24px'
|
|
172
|
+
}} className="redo-info-modal__description">
|
|
173
|
+
Shop with confidence, knowing your purchases are protected every step of the way.
|
|
174
|
+
</p>
|
|
175
|
+
|
|
176
|
+
<div className="redo-info-modal__benefitsContainer" style={{ marginBottom: '24px' }}>
|
|
177
|
+
<div className="redo-info-modal__benefit" style={{ marginBottom: '16px' }}>
|
|
178
|
+
<div className="redo-info-modal__benefitIconContainer" style={{ display: 'flex', flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'flex-start', gap: '10px' }}>
|
|
179
|
+
<div className="redo-info-modal__benefitIcon" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '36px', height: '36px' }}>
|
|
180
|
+
<FeaturedRefreshIcon height="32" width="32" />
|
|
181
|
+
</div>
|
|
182
|
+
<div className="redo-info-modal__benefitTextContainer" style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
|
183
|
+
<p className="redo-info-modal__benefitText" style={{ fontSize: '16px', fontWeight: '600', marginBottom: '4px' }}>
|
|
184
|
+
Free returns & exchanges
|
|
185
|
+
</p>
|
|
186
|
+
<p className="redo-info-modal__benefitSmallText" style={{ fontSize: '12px', color: '#666' }}>
|
|
187
|
+
Return or exchange your items for free. If you're not completely satisfied, we've got you covered.
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div className="redo-info-modal__benefit" style={{ marginBottom: '16px' }}>
|
|
194
|
+
<div className="redo-info-modal__benefitIconContainer" style={{ display: 'flex', flexDirection: 'row', alignItems: 'flex-start', gap: '10px' }}>
|
|
195
|
+
<div className="redo-info-modal__benefitIcon" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '36px', height: '36px' }}>
|
|
196
|
+
<FeaturedPackageCheckIcon height="32" width="32" />
|
|
197
|
+
</div>
|
|
198
|
+
<div className="redo-info-modal__benefitTextContainer" style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
|
199
|
+
<p className="redo-info-modal__benefitText" style={{
|
|
200
|
+
fontSize: '16px',
|
|
201
|
+
fontWeight: '600',
|
|
202
|
+
marginBottom: '4px'
|
|
203
|
+
}}>
|
|
204
|
+
Package protection
|
|
205
|
+
</p>
|
|
206
|
+
<p className="redo-info-modal__benefitSmallText" style={{
|
|
207
|
+
fontSize: '12px',
|
|
208
|
+
color: '#666'
|
|
209
|
+
}}>
|
|
210
|
+
Rest assured, if your package is lost, stolen, or damaged, we've got you covered.
|
|
211
|
+
</p>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<div className="redo-info-modal__benefit" style={{ marginBottom: '16px' }}>
|
|
217
|
+
<div className="redo-info-modal__benefitIconContainer" style={{ display: 'flex', flexDirection: 'row', alignItems: 'flex-start', gap: '10px' }}>
|
|
218
|
+
<div className="redo-info-modal__benefitIcon" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: '36px', height: '36px' }}>
|
|
219
|
+
<FeaturedLaptopIcon height="32" width="32" />
|
|
220
|
+
</div>
|
|
221
|
+
<div className="redo-info-modal__benefitTextContainer" style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
|
|
222
|
+
<p className="redo-info-modal__benefitText" style={{
|
|
223
|
+
fontSize: '16px',
|
|
224
|
+
fontWeight: '600',
|
|
225
|
+
marginBottom: '4px'
|
|
226
|
+
}}>
|
|
227
|
+
Easy return portal
|
|
228
|
+
</p>
|
|
229
|
+
<p className="redo-info-modal__benefitSmallText" style={{
|
|
230
|
+
fontSize: '12px',
|
|
231
|
+
color: '#666'
|
|
232
|
+
}}>
|
|
233
|
+
Skip all the back and forth, and submit your return in a few clicks.
|
|
234
|
+
</p>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
|
|
240
|
+
<p className="redo-info-modal__footerText" style={{
|
|
241
|
+
fontSize: '12px',
|
|
242
|
+
color: '#666',
|
|
243
|
+
}}>
|
|
244
|
+
By purchasing Redo, you agree and have read the{' '}
|
|
245
|
+
<a
|
|
246
|
+
href="https://www.getredo.com/privacy-policy"
|
|
247
|
+
target="_blank"
|
|
248
|
+
rel="noopener noreferrer"
|
|
249
|
+
style={{ color: '#000', textDecoration: 'underline' }}
|
|
250
|
+
>Privacy Policy</a> and{' '}
|
|
251
|
+
<a
|
|
252
|
+
href="https://www.getredo.com/terms-conditions"
|
|
253
|
+
target="_blank"
|
|
254
|
+
rel="noopener noreferrer"
|
|
255
|
+
style={{ color: '#000', textDecoration: 'underline' }}
|
|
256
|
+
>Terms and Conditions</a>.
|
|
257
|
+
{' '}Redo is subject to Merchant's Return Policy.
|
|
258
|
+
</p>
|
|
259
|
+
</div>
|
|
260
|
+
)}
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
return createPortal(fullModalContent, document.body);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const RedoInfoCard = ({
|
|
269
|
+
showInfoIcon = true,
|
|
270
|
+
onInfoClick,
|
|
271
|
+
infoCardImageUrl,
|
|
272
|
+
infoModalLogoUrl,
|
|
273
|
+
infoModalImageUrl,
|
|
274
|
+
infoModalContent,
|
|
275
|
+
}: RedoInfoModalProps) => {
|
|
276
|
+
const { price, eligible } = useRedoCoverageClient();
|
|
277
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
278
|
+
|
|
279
|
+
const handleInfoClick = () => {
|
|
280
|
+
if (onInfoClick) {
|
|
281
|
+
onInfoClick();
|
|
282
|
+
} else {
|
|
283
|
+
setIsModalOpen(true);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
if (!eligible) {
|
|
288
|
+
return <></>;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<>
|
|
293
|
+
<div className="redo-info-card__container" data-target="info-card-container" style={{
|
|
294
|
+
display: 'flex',
|
|
295
|
+
borderRadius: '4px',
|
|
296
|
+
padding: '12px',
|
|
297
|
+
alignItems: 'center',
|
|
298
|
+
gap: '12px',
|
|
299
|
+
marginTop: '8px'
|
|
300
|
+
}}>
|
|
301
|
+
<div className="redo-info-card__imageContainer" style={{
|
|
302
|
+
width: '44px',
|
|
303
|
+
height: '44px',
|
|
304
|
+
borderRadius: '100%',
|
|
305
|
+
display: 'flex',
|
|
306
|
+
justifyContent: 'center',
|
|
307
|
+
alignItems: 'center',
|
|
308
|
+
flexShrink: 0,
|
|
309
|
+
}}>
|
|
310
|
+
{infoCardImageUrl ? (
|
|
311
|
+
<img src={infoCardImageUrl} alt="Redo Info" className="redo-info-card__image" style={{
|
|
312
|
+
width: '100%',
|
|
313
|
+
height: '100%',
|
|
314
|
+
objectFit: 'contain'
|
|
315
|
+
}} />
|
|
316
|
+
) : (
|
|
317
|
+
<ShieldIcon style={{
|
|
318
|
+
width: '100%',
|
|
319
|
+
height: '100%',
|
|
320
|
+
color: 'black',
|
|
321
|
+
display: 'block',
|
|
322
|
+
viewBox: '0 0 24 24',
|
|
323
|
+
}}/>
|
|
324
|
+
)}
|
|
325
|
+
</div>
|
|
326
|
+
|
|
327
|
+
<div className="redo-info-card__content" data-target="text-and-buttons-container" style={{
|
|
328
|
+
flex: 1
|
|
329
|
+
}}>
|
|
330
|
+
<div className="redo-info-card__textWrapper" style={{
|
|
331
|
+
display: 'flex',
|
|
332
|
+
flexDirection: 'column',
|
|
333
|
+
}}>
|
|
334
|
+
<span className="redo-info-card__title" data-target="toggle-label" style={{
|
|
335
|
+
color: '#000000',
|
|
336
|
+
fontSize: '14px',
|
|
337
|
+
fontWeight: 600,
|
|
338
|
+
display: 'flex',
|
|
339
|
+
alignItems: 'center',
|
|
340
|
+
gap: '5px',
|
|
341
|
+
verticalAlign: 'middle'
|
|
342
|
+
}}>
|
|
343
|
+
Checkout+
|
|
344
|
+
{showInfoIcon && (
|
|
345
|
+
<span className="redo-info-card__infoIconWrapper" data-target="toggle-info">
|
|
346
|
+
<button
|
|
347
|
+
className="redo-info-card__infoButton"
|
|
348
|
+
data-target="toggle-info-button"
|
|
349
|
+
onClick={handleInfoClick}
|
|
350
|
+
type="button"
|
|
351
|
+
style={{
|
|
352
|
+
border: 'none',
|
|
353
|
+
background: 'none',
|
|
354
|
+
padding: 0,
|
|
355
|
+
cursor: 'pointer',
|
|
356
|
+
color: '#969696',
|
|
357
|
+
display: 'flex',
|
|
358
|
+
alignItems: 'center',
|
|
359
|
+
justifyContent: 'center'
|
|
360
|
+
}}
|
|
361
|
+
>
|
|
362
|
+
<InfoIcon
|
|
363
|
+
style={{
|
|
364
|
+
width: '16px',
|
|
365
|
+
height: '16px',
|
|
366
|
+
verticalAlign: 'middle'
|
|
367
|
+
}}
|
|
368
|
+
className="redo-info-card__infoIcon"
|
|
369
|
+
/>
|
|
370
|
+
</button>
|
|
371
|
+
</span>
|
|
372
|
+
)}
|
|
373
|
+
</span>
|
|
374
|
+
<p className="redo-info-card__subtext" data-target="toggle-subtext" style={{
|
|
375
|
+
color: '#000000',
|
|
376
|
+
fontSize: '12px',
|
|
377
|
+
lineHeight: '16px'
|
|
378
|
+
}}>
|
|
379
|
+
Free Returns + Package Protection
|
|
380
|
+
</p>
|
|
381
|
+
</div>
|
|
382
|
+
</div>
|
|
383
|
+
|
|
384
|
+
<div className="redo-info-card__priceContainer">
|
|
385
|
+
<p style={{
|
|
386
|
+
color: '#000000',
|
|
387
|
+
fontSize: '14px',
|
|
388
|
+
fontWeight: 400,
|
|
389
|
+
}} className="redo-info-card__price" data-target="price">${price}</p>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
|
|
393
|
+
{!onInfoClick && (
|
|
394
|
+
<Modal
|
|
395
|
+
open={isModalOpen}
|
|
396
|
+
onClose={() => setIsModalOpen(false)}
|
|
397
|
+
infoModalLogoUrl={infoModalLogoUrl}
|
|
398
|
+
infoModalImageUrl={infoModalImageUrl}
|
|
399
|
+
modalContent={infoModalContent}
|
|
400
|
+
/>
|
|
401
|
+
)}
|
|
402
|
+
</>
|
|
403
|
+
);
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
const fadeInKeyframes = `
|
|
407
|
+
@keyframes fadeIn {
|
|
408
|
+
from {
|
|
409
|
+
opacity: 0;
|
|
410
|
+
}
|
|
411
|
+
to {
|
|
412
|
+
opacity: 1;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
`;
|
|
416
|
+
|
|
417
|
+
const slideInKeyframes = `
|
|
418
|
+
@keyframes slideIn {
|
|
419
|
+
from {
|
|
420
|
+
opacity: 0;
|
|
421
|
+
transform: translate(-50%, -48%);
|
|
422
|
+
}
|
|
423
|
+
to {
|
|
424
|
+
opacity: 1;
|
|
425
|
+
transform: translate(-50%, -50%);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
`;
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
export { RedoInfoCard };
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { RedoCheckoutButtons } from "./components/redo-checkout-buttons";
|
|
|
3
3
|
import { REDO_REQUIRED_HOSTNAMES } from "./utils/security";
|
|
4
4
|
import { CartProductVariantFragment, CartAttributeKey, CartInfoToEnable, RedoContextValue, RedoCoverageClient, RedoError, RedoErrorType } from "./types";
|
|
5
5
|
import { LoadState, Loader, useLoad } from './utils/react-utils'
|
|
6
|
+
import { RedoInfoCard } from "./components/redo-info-modal";
|
|
6
7
|
|
|
7
8
|
export {
|
|
8
9
|
RedoCheckoutButtons,
|
|
@@ -10,7 +11,8 @@ export {
|
|
|
10
11
|
useRedoCoverageClient,
|
|
11
12
|
useLoad,
|
|
12
13
|
REDO_REQUIRED_HOSTNAMES,
|
|
13
|
-
RedoErrorType
|
|
14
|
+
RedoErrorType,
|
|
15
|
+
RedoInfoCard
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
export type {
|
package/src/svg.d.ts
CHANGED