@shopify/shop-minis-react 0.0.3 → 0.0.4

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/src/dev.tsx CHANGED
@@ -4,6 +4,7 @@ import ReactDOM from 'react-dom/client'
4
4
  import {toast} from 'sonner'
5
5
 
6
6
  import './index.css'
7
+ import {ProductCard} from './components/commerce/product-card'
7
8
  import {ProductLink} from './components/commerce/product-link'
8
9
  import {
9
10
  Accordion,
@@ -116,6 +117,129 @@ function App() {
116
117
  <p className="text-gray-600 mt-2">Shop app specific components</p>
117
118
  </div>
118
119
 
120
+ {/* ProductCard Examples */}
121
+ <div className="space-y-4">
122
+ <h3 className="text-2xl font-semibold">ProductCard</h3>
123
+ <div className="space-y-6">
124
+ {/* Default Variant - Full Size */}
125
+ <div className="space-y-2">
126
+ <h4 className="text-lg font-medium">Default</h4>
127
+
128
+ <ProductCard
129
+ product={{
130
+ id: '1',
131
+ title: 'The Hero Snowboard',
132
+ price: {amount: '702.95', currencyCode: CurrencyCode.USD},
133
+ featuredImage: {
134
+ url: 'https://images.unsplash.com/photo-1551524164-687a55dd1126?w=400&h=400&fit=crop&crop=center',
135
+ altText: 'The Hero Snowboard',
136
+ },
137
+ shop: {id: 'shop1', name: 'Snow Sports Co.'},
138
+ defaultVariantId: 'variant1',
139
+ isFavorited: false,
140
+ reviewAnalytics: {},
141
+ }}
142
+ variant="default"
143
+ />
144
+ </div>
145
+
146
+ {/* Grid Layout for Variants */}
147
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4 max-w-4xl">
148
+ {/* Default with discount */}
149
+ <div className="space-y-2">
150
+ <h4 className="text-sm font-medium">
151
+ Default (with discount)
152
+ </h4>
153
+ <ProductCard
154
+ product={{
155
+ id: '2',
156
+ title: 'The Hero Snowboard',
157
+ price: {amount: '605.95', currencyCode: CurrencyCode.USD},
158
+ compareAtPrice: {
159
+ amount: '702.95',
160
+ currencyCode: CurrencyCode.USD,
161
+ },
162
+ featuredImage: {
163
+ url: 'https://images.unsplash.com/photo-1551524164-687a55dd1126?w=400&h=400&fit=crop&crop=center',
164
+ altText: 'The Hero Snowboard',
165
+ },
166
+ shop: {id: 'shop1', name: 'Snow Sports Co.'},
167
+ defaultVariantId: 'variant2',
168
+ isFavorited: true,
169
+ reviewAnalytics: {},
170
+ }}
171
+ variant="default"
172
+ />
173
+ </div>
174
+
175
+ {/* Price Overlay */}
176
+ <div className="space-y-2">
177
+ <h4 className="text-sm font-medium">Price Overlay</h4>
178
+ <ProductCard
179
+ product={{
180
+ id: '3',
181
+ title: 'The Hero Snowboard',
182
+ price: {amount: '702.95', currencyCode: CurrencyCode.USD},
183
+ featuredImage: {
184
+ url: 'https://images.unsplash.com/photo-1551524164-687a55dd1126?w=400&h=400&fit=crop&crop=center',
185
+ altText: 'The Hero Snowboard',
186
+ },
187
+ shop: {id: 'shop1', name: 'Snow Sports Co.'},
188
+ defaultVariantId: 'variant3',
189
+ isFavorited: false,
190
+ reviewAnalytics: {},
191
+ }}
192
+ variant="priceOverlay"
193
+ />
194
+ </div>
195
+
196
+ {/* With Badge */}
197
+ <div className="space-y-2">
198
+ <h4 className="text-sm font-medium">With Badge</h4>
199
+ <ProductCard
200
+ product={{
201
+ id: '4',
202
+ title: 'The Hero Snowboard',
203
+ price: {amount: '702.95', currencyCode: CurrencyCode.USD},
204
+ featuredImage: {
205
+ url: 'https://images.unsplash.com/photo-1551524164-687a55dd1126?w=400&h=400&fit=crop&crop=center',
206
+ altText: 'The Hero Snowboard',
207
+ },
208
+ shop: {id: 'shop1', name: 'Snow Sports Co.'},
209
+ defaultVariantId: 'variant4',
210
+ isFavorited: true,
211
+ reviewAnalytics: {},
212
+ }}
213
+ variant="default"
214
+ badgeText="Sponsored"
215
+ badgeVariant="secondary"
216
+ />
217
+ </div>
218
+
219
+ {/* Compact */}
220
+ <div className="space-y-2">
221
+ <h4 className="text-sm font-medium">Compact</h4>
222
+ <ProductCard
223
+ product={{
224
+ id: '5',
225
+ title: 'The Hero Snowboard',
226
+ price: {amount: '702.95', currencyCode: CurrencyCode.USD},
227
+ featuredImage: {
228
+ url: 'https://images.unsplash.com/photo-1551524164-687a55dd1126?w=400&h=400&fit=crop&crop=center',
229
+ altText: 'The Hero Snowboard',
230
+ },
231
+ shop: {id: 'shop1', name: 'Snow Sports Co.'},
232
+ defaultVariantId: 'variant5',
233
+ isFavorited: false,
234
+ reviewAnalytics: {},
235
+ }}
236
+ variant="compact"
237
+ />
238
+ </div>
239
+ </div>
240
+ </div>
241
+ </div>
242
+
119
243
  {/* ProductLink Examples */}
120
244
  <div className="space-y-4">
121
245
  <h3 className="text-2xl font-semibold">ProductLink</h3>
@@ -240,7 +364,7 @@ function App() {
240
364
  <h3 className="text-2xl font-semibold">Alert Dialog</h3>
241
365
  <AlertDialog open={alertOpen} onOpenChange={setAlertOpen}>
242
366
  <AlertDialogTrigger asChild>
243
- <Button variant="outline">Show Alert Dialog</Button>
367
+ <Button variant="outlined">Show Alert Dialog</Button>
244
368
  </AlertDialogTrigger>
245
369
  <AlertDialogContent>
246
370
  <AlertDialogHeader>
@@ -295,15 +419,49 @@ function App() {
295
419
  {/* Button */}
296
420
  <div className="space-y-4">
297
421
  <h3 className="text-2xl font-semibold">Button</h3>
298
- <div className="flex flex-wrap gap-4">
299
- <Button>Default Button</Button>
300
- <Button variant="destructive">Destructive</Button>
301
- <Button variant="outline">Outline</Button>
302
- <Button variant="secondary">Secondary</Button>
303
- <Button variant="ghost">Ghost</Button>
304
- <Button variant="link">Link</Button>
305
- <Button size="sm">Small</Button>
306
- <Button size="lg">Large</Button>
422
+ <div className="space-y-4">
423
+ {/* Core Variants */}
424
+ <>
425
+ <h4 className="text-lg font-medium mb-2">Core Variants</h4>
426
+ <div className="flex flex-wrap gap-2">
427
+ <Button variant="primary">Primary</Button>
428
+ <Button variant="secondary">Secondary</Button>
429
+ <Button variant="tertiary">Tertiary</Button>
430
+ <Button variant="outlined">Outlined</Button>
431
+ <Button variant="text">Text</Button>
432
+ <Button variant="borderless">Borderless</Button>
433
+ <Button variant="borderlessUnbranded">
434
+ Borderless Unbranded
435
+ </Button>
436
+ </div>
437
+ </>
438
+
439
+ {/* Special Variants */}
440
+ <>
441
+ <h4 className="text-lg font-medium mb-2">Special Variants</h4>
442
+ <div className="flex flex-wrap gap-2">
443
+ <Button variant="blurred">Blurred</Button>
444
+ <Button variant="dangerous">Dangerous</Button>
445
+ <Button variant="outlined-dangerous">
446
+ Outlined Dangerous
447
+ </Button>
448
+ </div>
449
+ </>
450
+
451
+ {/* Sizes */}
452
+ <>
453
+ <h4 className="text-lg font-medium mb-2">Sizes</h4>
454
+ <div className="flex flex-wrap items-center gap-2">
455
+ <Button size="sm">Small</Button>
456
+ <Button size="default">Default</Button>
457
+ <Button size="lg">Large</Button>
458
+ <Button size="icon">
459
+ <span role="img" aria-label="Target">
460
+ 🎯
461
+ </span>
462
+ </Button>
463
+ </div>
464
+ </>
307
465
  </div>
308
466
  </div>
309
467
 
@@ -318,7 +476,7 @@ function App() {
318
476
  contains.
319
477
  </CardDescription>
320
478
  <CardAction>
321
- <Button size="sm" variant="outline">
479
+ <Button size="sm" variant="outlined">
322
480
  Action
323
481
  </Button>
324
482
  </CardAction>
@@ -374,7 +532,7 @@ function App() {
374
532
  <h3 className="text-2xl font-semibold">Dialog</h3>
375
533
  <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
376
534
  <DialogTrigger asChild>
377
- <Button variant="outline">Open Dialog</Button>
535
+ <Button variant="outlined">Open Dialog</Button>
378
536
  </DialogTrigger>
379
537
  <DialogContent className="sm:max-w-[425px]">
380
538
  <DialogHeader>
@@ -418,7 +576,7 @@ function App() {
418
576
  <h3 className="text-2xl font-semibold">Drawer</h3>
419
577
  <Drawer>
420
578
  <DrawerTrigger asChild>
421
- <Button variant="outline">Open Drawer</Button>
579
+ <Button variant="outlined">Open Drawer</Button>
422
580
  </DrawerTrigger>
423
581
  <DrawerContent>
424
582
  <div className="mx-auto w-full max-w-sm">
@@ -431,7 +589,7 @@ function App() {
431
589
  <div className="p-4 pb-0">
432
590
  <div className="flex items-center justify-center space-x-2">
433
591
  <Button
434
- variant="outline"
592
+ variant="outlined"
435
593
  size="icon"
436
594
  className="h-8 w-8 shrink-0 rounded-full"
437
595
  onClick={() =>
@@ -449,7 +607,7 @@ function App() {
449
607
  </div>
450
608
  </div>
451
609
  <Button
452
- variant="outline"
610
+ variant="outlined"
453
611
  size="icon"
454
612
  className="h-8 w-8 shrink-0 rounded-full"
455
613
  onClick={() =>
@@ -463,7 +621,7 @@ function App() {
463
621
  <DrawerFooter>
464
622
  <Button>Submit</Button>
465
623
  <DrawerClose asChild>
466
- <Button variant="outline">Cancel</Button>
624
+ <Button variant="outlined">Cancel</Button>
467
625
  </DrawerClose>
468
626
  </DrawerFooter>
469
627
  </div>
@@ -586,7 +744,7 @@ function App() {
586
744
  <h3 className="text-2xl font-semibold">Sheet</h3>
587
745
  <Sheet>
588
746
  <SheetTrigger asChild>
589
- <Button variant="outline">Open Sheet</Button>
747
+ <Button variant="outlined">Open Sheet</Button>
590
748
  </SheetTrigger>
591
749
  <SheetContent>
592
750
  <SheetHeader>
package/src/index.css CHANGED
@@ -40,75 +40,156 @@
40
40
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
41
41
  --color-sidebar-border: var(--sidebar-border);
42
42
  --color-sidebar-ring: var(--sidebar-ring);
43
+
44
+ /* Grayscale palette colors for Tailwind */
45
+ --color-grayscale-d100: var(--grayscale-d100);
46
+ --color-grayscale-d93: var(--grayscale-d93);
47
+ --color-grayscale-d90: var(--grayscale-d90);
48
+ --color-grayscale-d80: var(--grayscale-d80);
49
+ --color-grayscale-d70: var(--grayscale-d70);
50
+ --color-grayscale-d60: var(--grayscale-d60);
51
+ --color-grayscale-d50: var(--grayscale-d50);
52
+ --color-grayscale-l40: var(--grayscale-l40);
53
+ --color-grayscale-l20: var(--grayscale-l20);
54
+ --color-grayscale-l10: var(--grayscale-l10);
55
+ --color-grayscale-l6: var(--grayscale-l6);
56
+ --color-grayscale-l5: var(--grayscale-l5);
57
+ --color-grayscale-l0: var(--grayscale-l0);
43
58
  }
44
59
 
45
60
  :root {
46
61
  --radius: 0.65rem;
47
- --background: oklch(1 0 0);
48
- --foreground: oklch(0.141 0.005 285.823);
49
- --card: oklch(1 0 0);
50
- --card-foreground: oklch(0.141 0.005 285.823);
51
- --popover: oklch(1 0 0);
52
- --popover-foreground: oklch(0.141 0.005 285.823);
53
- --primary: oklch(0.606 0.25 292.717);
54
- --primary-foreground: oklch(0.969 0.016 293.756);
55
- --secondary: oklch(0.967 0.001 286.375);
56
- --secondary-foreground: oklch(0.21 0.006 285.885);
57
- --muted: oklch(0.967 0.001 286.375);
58
- --muted-foreground: oklch(0.552 0.016 285.938);
59
- --accent: oklch(0.967 0.001 286.375);
60
- --accent-foreground: oklch(0.21 0.006 285.885);
61
- --destructive: oklch(0.577 0.245 27.325);
62
- --border: oklch(0.92 0.004 286.32);
63
- --input: oklch(0.92 0.004 286.32);
64
- --ring: oklch(0.606 0.25 292.717);
65
- --chart-1: oklch(0.646 0.222 41.116);
66
- --chart-2: oklch(0.6 0.118 184.704);
67
- --chart-3: oklch(0.398 0.07 227.392);
68
- --chart-4: oklch(0.828 0.189 84.429);
69
- --chart-5: oklch(0.769 0.188 70.08);
70
- --sidebar: oklch(0.985 0 0);
71
- --sidebar-foreground: oklch(0.141 0.005 285.823);
72
- --sidebar-primary: oklch(0.606 0.25 292.717);
73
- --sidebar-primary-foreground: oklch(0.969 0.016 293.756);
74
- --sidebar-accent: oklch(0.967 0.001 286.375);
75
- --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
76
- --sidebar-border: oklch(0.92 0.004 286.32);
77
- --sidebar-ring: oklch(0.606 0.25 292.717);
62
+
63
+ /* Palette Colors - Purple */
64
+ --purple-d80: #1b163b;
65
+ --purple-d60: #322c7d;
66
+ --purple-d50: #4524db;
67
+ --purple-p40: #5433eb;
68
+ --purple-l30: #6445ed;
69
+ --purple-l20: #9c83f8;
70
+ --purple-l10: #dbd1ff;
71
+ --purple-l5: #eeeaff;
72
+ --purple-l2: #f7f5ff;
73
+
74
+ /* Palette Colors - Grayscale */
75
+ --grayscale-d100: #000000;
76
+ --grayscale-d93: #121212;
77
+ --grayscale-d90: #1a1a1a;
78
+ --grayscale-d80: #2a2a2a;
79
+ --grayscale-d70: #404040;
80
+ --grayscale-d60: #656667;
81
+ --grayscale-d50: #6f7071;
82
+ --grayscale-l40: #a6a8a9;
83
+ --grayscale-l20: #c9cbcc;
84
+ --grayscale-l10: #e1e4e5;
85
+ --grayscale-l6: #eef0f1;
86
+ --grayscale-l5: #f2f4f5;
87
+ --grayscale-l0: #ffffff;
88
+
89
+ /* Palette Colors - Green */
90
+ --green-d90: #002e24;
91
+ --green-d80: #004839;
92
+ --green-d70: #008552;
93
+ --green-l30: #92d08d;
94
+ --green-l20: #baebcb;
95
+ --green-l10: #d2f2de;
96
+ --green-l5: #e4f6eb;
97
+
98
+ /* Palette Colors - Poppy */
99
+ --poppy-d80: #481609;
100
+ --poppy-d70: #832711;
101
+ --poppy-d50: #d92a0f;
102
+ --poppy-l40: #f05d38;
103
+ --poppy-l20: #ff967d;
104
+ --poppy-l10: #ffd2c2;
105
+ --poppy-l4: #ffece9;
106
+
107
+ /* Palette Colors - Ochre */
108
+ --ochre-d90: #443600;
109
+ --ochre-d70: #8c6e01;
110
+ --ochre-d60: #c29d05;
111
+ --ochre-l50: #e3be2b;
112
+ --ochre-l30: #f8db67;
113
+ --ochre-l20: #ffec9f;
114
+ --ochre-l10: #fff4cb;
115
+ --ochre-l6: #fff9e2;
116
+
117
+ /* Palette Colors - Brand */
118
+ --brand-aqua: #8dc0c6;
119
+ --brand-violet: #a327c2;
120
+ --brand-magenta: #d354ff;
121
+ --brand-olive: #8b8f01;
122
+ --brand-lime: #c7de00;
123
+ --brand-sage: #d8e59d;
124
+ --brand-sand: #f4f4ed;
125
+
126
+ /* Semantic Colors */
127
+ --background: var(--grayscale-l0);
128
+ --foreground: var(--grayscale-d100);
129
+ --card: var(--grayscale-l0);
130
+ --card-foreground: var(--grayscale-d100);
131
+ --popover: var(--grayscale-l0);
132
+ --popover-foreground: var(--grayscale-d100);
133
+ --primary: var(--purple-p40);
134
+ --primary-foreground: var(--grayscale-l0);
135
+ --secondary: var(--grayscale-l5);
136
+ --secondary-foreground: var(--grayscale-d70);
137
+ --muted: var(--grayscale-l5);
138
+ --muted-foreground: var(--grayscale-d70);
139
+ --accent: var(--grayscale-l5);
140
+ --accent-foreground: var(--grayscale-d70);
141
+ --destructive: var(--poppy-d50);
142
+ --border: rgba(0, 0, 0, 0.1);
143
+ --input: var(--grayscale-l20);
144
+ --ring: var(--purple-p40);
145
+ --chart-1: var(--ochre-d90);
146
+ --chart-2: var(--green-d70);
147
+ --chart-3: var(--green-l30);
148
+ --chart-4: var(--grayscale-d50);
149
+ --chart-5: var(--green-l20);
150
+ --sidebar: var(--grayscale-l5);
151
+ --sidebar-foreground: var(--grayscale-d100);
152
+ --sidebar-primary: var(--purple-p40);
153
+ --sidebar-primary-foreground: var(--purple-l20);
154
+ --sidebar-accent: var(--grayscale-l5);
155
+ --sidebar-accent-foreground: var(--grayscale-d70);
156
+ --sidebar-border: rgba(0, 0, 0, 0.1);
157
+ --sidebar-ring: var(--purple-p40);
78
158
  }
79
159
 
80
160
  .dark {
81
- --background: oklch(0.141 0.005 285.823);
82
- --foreground: oklch(0.985 0 0);
83
- --card: oklch(0.21 0.006 285.885);
84
- --card-foreground: oklch(0.985 0 0);
85
- --popover: oklch(0.21 0.006 285.885);
86
- --popover-foreground: oklch(0.985 0 0);
87
- --primary: oklch(0.541 0.281 293.009);
88
- --primary-foreground: oklch(0.969 0.016 293.756);
89
- --secondary: oklch(0.274 0.006 286.033);
90
- --secondary-foreground: oklch(0.985 0 0);
91
- --muted: oklch(0.274 0.006 286.033);
92
- --muted-foreground: oklch(0.705 0.015 286.067);
93
- --accent: oklch(0.274 0.006 286.033);
94
- --accent-foreground: oklch(0.985 0 0);
95
- --destructive: oklch(0.704 0.191 22.216);
96
- --border: oklch(1 0 0 / 10%);
97
- --input: oklch(1 0 0 / 15%);
98
- --ring: oklch(0.541 0.281 293.009);
99
- --chart-1: oklch(0.488 0.243 264.376);
100
- --chart-2: oklch(0.696 0.17 162.48);
101
- --chart-3: oklch(0.769 0.188 70.08);
102
- --chart-4: oklch(0.627 0.265 303.9);
103
- --chart-5: oklch(0.645 0.246 16.439);
104
- --sidebar: oklch(0.21 0.006 285.885);
105
- --sidebar-foreground: oklch(0.985 0 0);
106
- --sidebar-primary: oklch(0.541 0.281 293.009);
107
- --sidebar-primary-foreground: oklch(0.969 0.016 293.756);
108
- --sidebar-accent: oklch(0.274 0.006 286.033);
109
- --sidebar-accent-foreground: oklch(0.985 0 0);
110
- --sidebar-border: oklch(1 0 0 / 10%);
111
- --sidebar-ring: oklch(0.541 0.281 293.009);
161
+ /* Dark mode semantic colors */
162
+ --background: var(--grayscale-d93);
163
+ --foreground: var(--grayscale-l0);
164
+ --card: var(--grayscale-d93);
165
+ --card-foreground: var(--grayscale-l0);
166
+ --popover: var(--grayscale-d93);
167
+ --popover-foreground: var(--grayscale-l0);
168
+ --primary: var(--purple-l20);
169
+ --primary-foreground: var(--grayscale-d100);
170
+ --secondary: var(--grayscale-d80);
171
+ --secondary-foreground: var(--grayscale-l0);
172
+ --muted: var(--grayscale-d80);
173
+ --muted-foreground: var(--grayscale-l20);
174
+ --accent: var(--grayscale-d80);
175
+ --accent-foreground: var(--grayscale-l0);
176
+ --destructive: var(--poppy-l40);
177
+ --border: rgba(255, 255, 255, 0.2);
178
+ --input: var(--grayscale-l40);
179
+ --ring: var(--purple-l20);
180
+ --chart-1: var(--green-l30);
181
+ --chart-2: var(--grayscale-d60);
182
+ --chart-3: var(--green-l20);
183
+ --chart-4: var(--grayscale-d60);
184
+ --chart-5: var(--ochre-l30);
185
+ --sidebar: var(--grayscale-d80);
186
+ --sidebar-foreground: var(--grayscale-l0);
187
+ --sidebar-primary: var(--purple-l20);
188
+ --sidebar-primary-foreground: var(--purple-l10);
189
+ --sidebar-accent: var(--grayscale-d80);
190
+ --sidebar-accent-foreground: var(--grayscale-l0);
191
+ --sidebar-border: rgba(255, 255, 255, 0.2);
192
+ --sidebar-ring: var(--purple-l20);
112
193
  }
113
194
 
114
195
  @layer base {
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Formats money amount with appropriate currency symbol
3
+ * Uses browser's Intl.NumberFormat for consistent currency formatting
4
+ */
5
+ export function formatMoney(amount: string, currencyCode: string): string {
6
+ try {
7
+ // Use en-US specifically for USD to get $ instead of US$
8
+ // For other currencies, use browser locale but fallback to en-US
9
+ const locale =
10
+ currencyCode === 'USD' ? 'en-US' : navigator.language || 'en-US'
11
+
12
+ return new Intl.NumberFormat(locale, {
13
+ style: 'currency',
14
+ currency: currencyCode,
15
+ }).format(Number(amount))
16
+ } catch (error) {
17
+ // Fallback if currency code is invalid or not supported
18
+ console.warn(`Invalid currency code: ${currencyCode}`, error)
19
+ return `${currencyCode} ${amount}`
20
+ }
21
+ }