@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/dist/components/commerce/product-card.js +297 -0
- package/dist/components/commerce/product-card.js.map +1 -0
- package/dist/components/commerce/product-link.js +2 -2
- package/dist/components/commerce/product-link.js.map +1 -1
- package/dist/components/ui/alert-dialog.js +1 -1
- package/dist/components/ui/alert-dialog.js.map +1 -1
- package/dist/components/ui/button.js +24 -20
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/carousel.js +2 -2
- package/dist/components/ui/carousel.js.map +1 -1
- package/dist/index.js +188 -176
- package/dist/index.js.map +1 -1
- package/dist/lib/formatMoney.js +15 -0
- package/dist/lib/formatMoney.js.map +1 -0
- package/package.json +1 -1
- package/src/components/commerce/product-card.tsx +427 -0
- package/src/components/commerce/product-link.tsx +2 -2
- package/src/components/index.ts +1 -0
- package/src/components/ui/alert-dialog.tsx +1 -1
- package/src/components/ui/button.tsx +17 -11
- package/src/components/ui/carousel.tsx +2 -2
- package/src/dev.tsx +175 -17
- package/src/index.css +143 -62
- package/src/lib/formatMoney.ts +21 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import {cva, type VariantProps} from 'class-variance-authority'
|
|
4
|
+
import {Slot as SlotPrimitive} from 'radix-ui'
|
|
5
|
+
|
|
6
|
+
import {useShopNavigation} from '../../hooks/navigation/useShopNavigation'
|
|
7
|
+
import {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'
|
|
8
|
+
import {formatMoney} from '../../lib/formatMoney'
|
|
9
|
+
import {cn} from '../../lib/utils'
|
|
10
|
+
import {
|
|
11
|
+
type Product,
|
|
12
|
+
type ProductVariant,
|
|
13
|
+
} from '../../types/minisSDK.generated.d'
|
|
14
|
+
import {Badge} from '../ui/badge'
|
|
15
|
+
import {Button} from '../ui/button'
|
|
16
|
+
import {Icon, type LucideIconName} from '../ui/icon'
|
|
17
|
+
import {Touchable} from '../ui/touchable'
|
|
18
|
+
|
|
19
|
+
const productCardVariants = cva(
|
|
20
|
+
'relative overflow-hidden rounded-xl border border-gray-200',
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
default: '',
|
|
25
|
+
priceOverlay: '',
|
|
26
|
+
compact: '',
|
|
27
|
+
},
|
|
28
|
+
touchable: {
|
|
29
|
+
true: 'cursor-pointer',
|
|
30
|
+
false: '',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
defaultVariants: {
|
|
34
|
+
variant: 'default',
|
|
35
|
+
touchable: true,
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
// Primitive components (building blocks)
|
|
41
|
+
export interface ProductCardRootProps
|
|
42
|
+
extends React.ComponentProps<'div'>,
|
|
43
|
+
VariantProps<typeof productCardVariants> {
|
|
44
|
+
variant?: 'default' | 'priceOverlay' | 'compact'
|
|
45
|
+
touchable?: boolean
|
|
46
|
+
asChild?: boolean
|
|
47
|
+
onPress?: () => void
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function ProductCardRoot({
|
|
51
|
+
className,
|
|
52
|
+
variant,
|
|
53
|
+
touchable = true,
|
|
54
|
+
asChild = false,
|
|
55
|
+
onPress,
|
|
56
|
+
...props
|
|
57
|
+
}: ProductCardRootProps) {
|
|
58
|
+
const Comp = asChild ? SlotPrimitive.Slot : 'div'
|
|
59
|
+
|
|
60
|
+
const content = (
|
|
61
|
+
<Comp
|
|
62
|
+
className={cn(
|
|
63
|
+
productCardVariants({variant, touchable}),
|
|
64
|
+
'border-0',
|
|
65
|
+
className
|
|
66
|
+
)}
|
|
67
|
+
{...props}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if (touchable && onPress) {
|
|
72
|
+
return (
|
|
73
|
+
<Touchable onPress={onPress} asChild>
|
|
74
|
+
{content}
|
|
75
|
+
</Touchable>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return content
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function ProductCardImageContainer({
|
|
83
|
+
className,
|
|
84
|
+
variant = 'default',
|
|
85
|
+
...props
|
|
86
|
+
}: React.ComponentProps<'div'> & {
|
|
87
|
+
variant?: 'default' | 'priceOverlay' | 'compact'
|
|
88
|
+
}) {
|
|
89
|
+
return (
|
|
90
|
+
<div
|
|
91
|
+
data-slot="product-card-image-container"
|
|
92
|
+
className={cn(
|
|
93
|
+
'relative overflow-hidden rounded-xl border border-gray-200',
|
|
94
|
+
'w-full aspect-square',
|
|
95
|
+
variant === 'compact' ? 'min-h-[104px]' : 'min-h-[134px]',
|
|
96
|
+
className
|
|
97
|
+
)}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function ProductCardImage({
|
|
104
|
+
className,
|
|
105
|
+
src,
|
|
106
|
+
alt,
|
|
107
|
+
...props
|
|
108
|
+
}: React.ComponentProps<'img'> & {
|
|
109
|
+
src?: string
|
|
110
|
+
alt?: string
|
|
111
|
+
}) {
|
|
112
|
+
return (
|
|
113
|
+
<div className="w-full h-full bg-gray-100 flex items-center justify-center">
|
|
114
|
+
{src ? (
|
|
115
|
+
<img
|
|
116
|
+
data-slot="product-card-image"
|
|
117
|
+
src={src}
|
|
118
|
+
alt={alt}
|
|
119
|
+
className={cn('w-full h-full object-cover', className)}
|
|
120
|
+
{...props}
|
|
121
|
+
/>
|
|
122
|
+
) : (
|
|
123
|
+
<div className="text-gray-400 text-sm">No Image</div>
|
|
124
|
+
)}
|
|
125
|
+
</div>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function ProductCardBadge({
|
|
130
|
+
className,
|
|
131
|
+
position = 'bottom-left',
|
|
132
|
+
children,
|
|
133
|
+
...props
|
|
134
|
+
}: React.ComponentProps<typeof Badge> & {
|
|
135
|
+
position?: 'top-left' | 'bottom-left'
|
|
136
|
+
}) {
|
|
137
|
+
return (
|
|
138
|
+
<div
|
|
139
|
+
className={cn(
|
|
140
|
+
'absolute z-10',
|
|
141
|
+
position === 'top-left' ? 'top-3 left-3' : 'bottom-2 left-2'
|
|
142
|
+
)}
|
|
143
|
+
>
|
|
144
|
+
<Badge
|
|
145
|
+
className={cn('bg-black/50 text-white rounded', className)}
|
|
146
|
+
{...props}
|
|
147
|
+
>
|
|
148
|
+
{children}
|
|
149
|
+
</Badge>
|
|
150
|
+
</div>
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function ProductCardFavoriteButton({
|
|
155
|
+
className,
|
|
156
|
+
onPress,
|
|
157
|
+
filled = false,
|
|
158
|
+
icon = 'Heart',
|
|
159
|
+
...props
|
|
160
|
+
}: React.ComponentProps<'div'> & {
|
|
161
|
+
onPress?: () => void
|
|
162
|
+
filled?: boolean
|
|
163
|
+
icon?: LucideIconName
|
|
164
|
+
}) {
|
|
165
|
+
return (
|
|
166
|
+
<div className={cn('absolute bottom-3 right-3 z-10', className)} {...props}>
|
|
167
|
+
<Touchable onPress={onPress} asChild>
|
|
168
|
+
<Button
|
|
169
|
+
variant="secondary"
|
|
170
|
+
size="icon"
|
|
171
|
+
className={cn(
|
|
172
|
+
'h-8 w-8 rounded-full border-0 shadow-sm',
|
|
173
|
+
filled ? 'bg-primary' : 'bg-grayscale-l6/60 backdrop-blur-sm'
|
|
174
|
+
)}
|
|
175
|
+
>
|
|
176
|
+
<Icon name={icon} filled={filled} className="h-4 w-4 text-white" />
|
|
177
|
+
</Button>
|
|
178
|
+
</Touchable>
|
|
179
|
+
</div>
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function ProductCardInfo({
|
|
184
|
+
className,
|
|
185
|
+
variant = 'default',
|
|
186
|
+
...props
|
|
187
|
+
}: React.ComponentProps<'div'> & {
|
|
188
|
+
variant?: 'default' | 'priceOverlay' | 'compact'
|
|
189
|
+
}) {
|
|
190
|
+
if (variant !== 'default') {
|
|
191
|
+
return null
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<div
|
|
196
|
+
data-slot="product-card-info"
|
|
197
|
+
className={cn('px-1 pt-2 pb-0 space-y-1', className)}
|
|
198
|
+
{...props}
|
|
199
|
+
/>
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function ProductCardTitle({
|
|
204
|
+
className,
|
|
205
|
+
children,
|
|
206
|
+
...props
|
|
207
|
+
}: React.ComponentProps<'h3'>) {
|
|
208
|
+
return (
|
|
209
|
+
<h3
|
|
210
|
+
data-slot="product-card-title"
|
|
211
|
+
className={cn(
|
|
212
|
+
'text-sm font-medium leading-tight text-gray-900',
|
|
213
|
+
'truncate overflow-hidden whitespace-nowrap text-ellipsis',
|
|
214
|
+
className
|
|
215
|
+
)}
|
|
216
|
+
{...props}
|
|
217
|
+
>
|
|
218
|
+
{children}
|
|
219
|
+
</h3>
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function ProductCardPrice({className, ...props}: React.ComponentProps<'div'>) {
|
|
224
|
+
return (
|
|
225
|
+
<div
|
|
226
|
+
data-slot="product-card-price"
|
|
227
|
+
className={cn('flex items-center gap-2', className)}
|
|
228
|
+
{...props}
|
|
229
|
+
/>
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function ProductCardCurrentPrice({
|
|
234
|
+
className,
|
|
235
|
+
...props
|
|
236
|
+
}: React.ComponentProps<'span'>) {
|
|
237
|
+
return (
|
|
238
|
+
<span
|
|
239
|
+
data-slot="product-card-current-price"
|
|
240
|
+
className={cn('text-sm font-semibold text-gray-900', className)}
|
|
241
|
+
{...props}
|
|
242
|
+
/>
|
|
243
|
+
)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function ProductCardOriginalPrice({
|
|
247
|
+
className,
|
|
248
|
+
...props
|
|
249
|
+
}: React.ComponentProps<'span'>) {
|
|
250
|
+
return (
|
|
251
|
+
<span
|
|
252
|
+
data-slot="product-card-original-price"
|
|
253
|
+
className={cn('text-sm text-gray-500 line-through', className)}
|
|
254
|
+
{...props}
|
|
255
|
+
/>
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface ProductCardProps {
|
|
260
|
+
product: Product
|
|
261
|
+
selectedProductVariant?: ProductVariant
|
|
262
|
+
variant?: 'default' | 'priceOverlay' | 'compact'
|
|
263
|
+
touchable?: boolean
|
|
264
|
+
badgeText?: string
|
|
265
|
+
badgeVariant?: 'default' | 'secondary' | 'destructive' | 'outline'
|
|
266
|
+
onFavoriteToggled?: (isFavorited: boolean) => void
|
|
267
|
+
sectionId?: string
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Composed ProductCard component
|
|
271
|
+
function ProductCard({
|
|
272
|
+
product,
|
|
273
|
+
selectedProductVariant,
|
|
274
|
+
variant = 'default',
|
|
275
|
+
touchable = true,
|
|
276
|
+
badgeText,
|
|
277
|
+
badgeVariant = 'secondary',
|
|
278
|
+
onFavoriteToggled,
|
|
279
|
+
}: ProductCardProps) {
|
|
280
|
+
const {navigateToProduct} = useShopNavigation()
|
|
281
|
+
const {saveProduct, unsaveProduct} = useSavedProductsActions()
|
|
282
|
+
|
|
283
|
+
const {
|
|
284
|
+
id,
|
|
285
|
+
title,
|
|
286
|
+
featuredImage,
|
|
287
|
+
price,
|
|
288
|
+
compareAtPrice,
|
|
289
|
+
isFavorited,
|
|
290
|
+
defaultVariantId,
|
|
291
|
+
shop,
|
|
292
|
+
} = product
|
|
293
|
+
|
|
294
|
+
// Use selected variant data if available
|
|
295
|
+
const displayImage = selectedProductVariant?.image || featuredImage
|
|
296
|
+
const displayPrice = selectedProductVariant?.price || price
|
|
297
|
+
const displayCompareAtPrice =
|
|
298
|
+
selectedProductVariant?.compareAtPrice || compareAtPrice
|
|
299
|
+
|
|
300
|
+
// Local state for optimistic UI updates
|
|
301
|
+
const [isFavoritedLocal, setIsFavoritedLocal] = React.useState(isFavorited)
|
|
302
|
+
|
|
303
|
+
const currencyCode = displayPrice?.currencyCode
|
|
304
|
+
const amount = displayPrice?.amount
|
|
305
|
+
const imageUrl = displayImage?.url
|
|
306
|
+
const imageAltText = displayImage?.altText || title
|
|
307
|
+
const compareAtPriceAmount = displayCompareAtPrice?.amount
|
|
308
|
+
const hasDiscount = compareAtPriceAmount && compareAtPriceAmount !== amount
|
|
309
|
+
|
|
310
|
+
const handlePress = React.useCallback(() => {
|
|
311
|
+
if (!touchable) return
|
|
312
|
+
|
|
313
|
+
navigateToProduct({
|
|
314
|
+
productId: id,
|
|
315
|
+
})
|
|
316
|
+
}, [navigateToProduct, id, touchable])
|
|
317
|
+
|
|
318
|
+
const handleFavoritePress = React.useCallback(async () => {
|
|
319
|
+
const previousState = isFavoritedLocal
|
|
320
|
+
|
|
321
|
+
// Optimistic update
|
|
322
|
+
setIsFavoritedLocal(!previousState)
|
|
323
|
+
onFavoriteToggled?.(!previousState)
|
|
324
|
+
|
|
325
|
+
try {
|
|
326
|
+
if (previousState) {
|
|
327
|
+
await unsaveProduct({
|
|
328
|
+
productId: id,
|
|
329
|
+
shopId: shop.id,
|
|
330
|
+
productVariantId: selectedProductVariant?.id || defaultVariantId,
|
|
331
|
+
})
|
|
332
|
+
} else {
|
|
333
|
+
await saveProduct({
|
|
334
|
+
productId: id,
|
|
335
|
+
shopId: shop.id,
|
|
336
|
+
productVariantId: selectedProductVariant?.id || defaultVariantId,
|
|
337
|
+
})
|
|
338
|
+
}
|
|
339
|
+
} catch (error) {
|
|
340
|
+
// Revert optimistic update on error
|
|
341
|
+
setIsFavoritedLocal(previousState)
|
|
342
|
+
onFavoriteToggled?.(previousState)
|
|
343
|
+
}
|
|
344
|
+
}, [
|
|
345
|
+
isFavoritedLocal,
|
|
346
|
+
id,
|
|
347
|
+
shop.id,
|
|
348
|
+
selectedProductVariant?.id,
|
|
349
|
+
defaultVariantId,
|
|
350
|
+
saveProduct,
|
|
351
|
+
unsaveProduct,
|
|
352
|
+
onFavoriteToggled,
|
|
353
|
+
])
|
|
354
|
+
|
|
355
|
+
return (
|
|
356
|
+
<ProductCardRoot
|
|
357
|
+
variant={variant}
|
|
358
|
+
touchable={touchable}
|
|
359
|
+
onPress={handlePress}
|
|
360
|
+
>
|
|
361
|
+
<ProductCardImageContainer variant={variant}>
|
|
362
|
+
<ProductCardImage src={imageUrl} alt={imageAltText} />
|
|
363
|
+
|
|
364
|
+
{/* Price overlay badge for priceOverlay variant */}
|
|
365
|
+
{variant === 'priceOverlay' && currencyCode && amount && (
|
|
366
|
+
<ProductCardBadge position="top-left">
|
|
367
|
+
{formatMoney(amount, currencyCode)}
|
|
368
|
+
</ProductCardBadge>
|
|
369
|
+
)}
|
|
370
|
+
|
|
371
|
+
{/* Custom badge */}
|
|
372
|
+
{badgeText && (
|
|
373
|
+
<ProductCardBadge position="bottom-left" variant={badgeVariant}>
|
|
374
|
+
{badgeText}
|
|
375
|
+
</ProductCardBadge>
|
|
376
|
+
)}
|
|
377
|
+
|
|
378
|
+
{/* Favorite button */}
|
|
379
|
+
<ProductCardFavoriteButton
|
|
380
|
+
filled={isFavoritedLocal}
|
|
381
|
+
onPress={handleFavoritePress}
|
|
382
|
+
/>
|
|
383
|
+
</ProductCardImageContainer>
|
|
384
|
+
|
|
385
|
+
{/* Product info for default variant */}
|
|
386
|
+
<ProductCardInfo variant={variant}>
|
|
387
|
+
<ProductCardTitle>{title}</ProductCardTitle>
|
|
388
|
+
|
|
389
|
+
<ProductCardPrice>
|
|
390
|
+
{hasDiscount ? (
|
|
391
|
+
<>
|
|
392
|
+
<ProductCardCurrentPrice>
|
|
393
|
+
{formatMoney(amount, currencyCode)}
|
|
394
|
+
</ProductCardCurrentPrice>
|
|
395
|
+
<ProductCardOriginalPrice>
|
|
396
|
+
{formatMoney(
|
|
397
|
+
compareAtPriceAmount,
|
|
398
|
+
displayCompareAtPrice?.currencyCode || currencyCode
|
|
399
|
+
)}
|
|
400
|
+
</ProductCardOriginalPrice>
|
|
401
|
+
</>
|
|
402
|
+
) : (
|
|
403
|
+
<ProductCardCurrentPrice>
|
|
404
|
+
{formatMoney(amount, currencyCode)}
|
|
405
|
+
</ProductCardCurrentPrice>
|
|
406
|
+
)}
|
|
407
|
+
</ProductCardPrice>
|
|
408
|
+
</ProductCardInfo>
|
|
409
|
+
</ProductCardRoot>
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export {
|
|
414
|
+
// Composed component
|
|
415
|
+
ProductCard,
|
|
416
|
+
// Primitive components for custom composition
|
|
417
|
+
ProductCardRoot,
|
|
418
|
+
ProductCardImageContainer,
|
|
419
|
+
ProductCardImage,
|
|
420
|
+
ProductCardBadge,
|
|
421
|
+
ProductCardFavoriteButton,
|
|
422
|
+
ProductCardInfo,
|
|
423
|
+
ProductCardTitle,
|
|
424
|
+
ProductCardPrice,
|
|
425
|
+
ProductCardCurrentPrice,
|
|
426
|
+
ProductCardOriginalPrice,
|
|
427
|
+
}
|
|
@@ -202,7 +202,7 @@ function ProductLinkActions({
|
|
|
202
202
|
>
|
|
203
203
|
<Touchable onPress={onActionPress} asChild>
|
|
204
204
|
<Button
|
|
205
|
-
variant="
|
|
205
|
+
variant="borderless"
|
|
206
206
|
size="icon"
|
|
207
207
|
className="h-auto w-auto p-0 hover:bg-transparent"
|
|
208
208
|
>
|
|
@@ -327,7 +327,7 @@ function ProductLink({product}: ProductLinkProps) {
|
|
|
327
327
|
className={cn(
|
|
328
328
|
'h-3 w-3',
|
|
329
329
|
i < Math.floor(averageRating!)
|
|
330
|
-
? 'text-
|
|
330
|
+
? 'text-primary'
|
|
331
331
|
: 'text-gray-300'
|
|
332
332
|
)}
|
|
333
333
|
/>
|
package/src/components/index.ts
CHANGED
|
@@ -130,7 +130,7 @@ function AlertDialogCancel({
|
|
|
130
130
|
}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
|
|
131
131
|
return (
|
|
132
132
|
<AlertDialogPrimitive.Cancel
|
|
133
|
-
className={cn(buttonVariants({variant: '
|
|
133
|
+
className={cn(buttonVariants({variant: 'outlined'}), className)}
|
|
134
134
|
{...props}
|
|
135
135
|
/>
|
|
136
136
|
)
|
|
@@ -10,17 +10,23 @@ const buttonVariants = cva(
|
|
|
10
10
|
{
|
|
11
11
|
variants: {
|
|
12
12
|
variant: {
|
|
13
|
-
|
|
13
|
+
primary:
|
|
14
14
|
'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
secondary: 'bg-slate-900 text-white shadow-xs hover:bg-slate-800',
|
|
16
|
+
tertiary:
|
|
17
|
+
'bg-slate-100 text-slate-900 shadow-xs hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-100 dark:hover:bg-slate-700',
|
|
18
|
+
blurred:
|
|
19
|
+
'bg-black/20 text-white shadow-xs hover:bg-black/30 backdrop-blur-md border border-white/20',
|
|
20
|
+
text: 'bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',
|
|
21
|
+
borderless: 'bg-transparent text-primary hover:text-primary/80',
|
|
22
|
+
borderlessUnbranded:
|
|
23
|
+
'bg-transparent text-foreground hover:text-foreground/80',
|
|
24
|
+
outlined:
|
|
25
|
+
'border border-border bg-background text-foreground shadow-xs hover:bg-accent hover:text-accent-foreground',
|
|
26
|
+
dangerous:
|
|
27
|
+
'bg-destructive text-white shadow-xs hover:bg-destructive/90',
|
|
28
|
+
'outlined-dangerous':
|
|
29
|
+
'border border-destructive bg-transparent text-destructive shadow-xs hover:bg-destructive/10',
|
|
24
30
|
},
|
|
25
31
|
size: {
|
|
26
32
|
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
|
@@ -30,7 +36,7 @@ const buttonVariants = cva(
|
|
|
30
36
|
},
|
|
31
37
|
},
|
|
32
38
|
defaultVariants: {
|
|
33
|
-
variant: '
|
|
39
|
+
variant: 'primary',
|
|
34
40
|
size: 'default',
|
|
35
41
|
},
|
|
36
42
|
}
|
|
@@ -173,7 +173,7 @@ function CarouselItem({className, ...props}: React.ComponentProps<'div'>) {
|
|
|
173
173
|
|
|
174
174
|
function CarouselPrevious({
|
|
175
175
|
className,
|
|
176
|
-
variant = '
|
|
176
|
+
variant = 'outlined',
|
|
177
177
|
size = 'icon',
|
|
178
178
|
...props
|
|
179
179
|
}: React.ComponentProps<typeof Button>) {
|
|
@@ -203,7 +203,7 @@ function CarouselPrevious({
|
|
|
203
203
|
|
|
204
204
|
function CarouselNext({
|
|
205
205
|
className,
|
|
206
|
-
variant = '
|
|
206
|
+
variant = 'outlined',
|
|
207
207
|
size = 'icon',
|
|
208
208
|
...props
|
|
209
209
|
}: React.ComponentProps<typeof Button>) {
|