@hanzo/commerce 6.1.13 → 6.2.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/components/buy/_to_deprecate_select-family-item-card.tsx +3 -4
- package/components/buy/_to_deprecate_select-family-item-panel.tsx +4 -5
- package/components/buy/add-to-cart-widget.tsx +43 -32
- package/components/buy/buy-button.tsx +1 -1
- package/components/buy/buy-card.tsx +17 -26
- package/components/buy/buy-drawer.tsx +6 -25
- package/components/buy/carousel-buy-card.tsx +145 -194
- package/components/buy/foo.txt +27 -0
- package/components/cart/cart-panel/cart-line-item.tsx +1 -1
- package/components/checkout/payment-step-form/contact-form.tsx +2 -2
- package/components/checkout/payment-step-form/methods/crypto.tsx +1 -2
- package/components/checkout/shipping-step-form.tsx +5 -5
- package/components/index.ts +1 -3
- package/components/item-selector/button.tsx +175 -0
- package/components/item-selector/carousel.tsx +162 -0
- package/components/item-selector/index.ts +5 -0
- package/components/quantity-indicator.tsx +48 -0
- package/components/select-family/family-carousel/index.tsx +47 -38
- package/components/select-family/family-carousel/slide.tsx +83 -0
- package/components/select-family/family-carousel/state.ts +83 -0
- package/components/select-family/level-nodes-widget/index.tsx +2 -2
- package/components/select-family/level-nodes-widget/node-image.tsx +2 -2
- package/index.ts +7 -7
- package/package.json +7 -4
- package/service/context.tsx +8 -7
- package/service/debug.ts +41 -0
- package/service/get-instance.ts +3 -0
- package/service/impls/standalone/actual-line-item.ts +5 -7
- package/service/impls/standalone/index.ts +11 -3
- package/service/impls/standalone/standalone-service.ts +133 -38
- package/service/path-utils.ts +26 -0
- package/service/sep.ts +7 -0
- package/types/category-node.ts +38 -0
- package/types/commerce-service.ts +44 -12
- package/types/family.ts +4 -1
- package/types/index.ts +3 -2
- package/types/item-selector.ts +29 -14
- package/types/product.ts +5 -1
- package/types/selection-ui-specifier.ts +36 -0
- package/types/token-separators.ts +7 -0
- package/util/error.ts +34 -0
- package/util/index.ts +4 -1
- package/util/product-media-accessor.ts +58 -0
- package/util/promo-codes.ts +1 -2
- package/util/selection-ui-specifiers.ts +34 -0
- package/util/use-sync-sku-param-w-current-item.ts +2 -2
- package/components/select-family/family-carousel/family-slide.tsx +0 -36
- package/components/select-product/carousel-selector.tsx +0 -112
- package/components/select-product/image-selector.tsx +0 -162
- package/components/select-product/radio-selector.tsx +0 -125
- package/service/impls/index.ts +0 -3
- package/types/buy-ui-spec.ts +0 -8
- package/types/tree-node.ts +0 -24
- package/util/buy-ui-conf.ts +0 -35
- package/util/sep.ts +0 -5
|
@@ -1,261 +1,212 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import React, { useRef, useEffect, type ComponentType } from 'react'
|
|
3
|
-
import { reaction, type IReactionDisposer } from 'mobx'
|
|
4
3
|
import { observer } from 'mobx-react-lite'
|
|
5
4
|
|
|
6
5
|
import { cn } from '@hanzo/ui/util'
|
|
6
|
+
import { ApplyTypography, Button, MediaStack, Skeleton } from '@hanzo/ui/primitives'
|
|
7
7
|
|
|
8
8
|
import type {
|
|
9
|
-
SelectedPaths,
|
|
10
9
|
ItemSelectorProps,
|
|
11
|
-
ItemSelectorCompProps,
|
|
12
10
|
LineItem,
|
|
13
11
|
Family,
|
|
14
|
-
|
|
12
|
+
CategoryNode,
|
|
13
|
+
CategoryNodeRole,
|
|
14
|
+
SelectionUISpecifier,
|
|
15
|
+
ItemSelectorOptions,
|
|
15
16
|
} from '../../types'
|
|
16
17
|
|
|
17
18
|
import { useCommerce } from '../../service/context'
|
|
18
|
-
import
|
|
19
|
-
import { ObsStringMutator } from '../../util'
|
|
19
|
+
import * as pathUtils from '../../service/path-utils'
|
|
20
|
+
import { ObsStringMutator, getSelectionUISpecifier } from '../../util'
|
|
21
|
+
|
|
22
|
+
import { CarouselItemSelector, ButtonItemSelector } from '../item-selector'
|
|
23
|
+
import FamilyCarousel from '../select-family/family-carousel'
|
|
20
24
|
|
|
21
25
|
import AddToCartWidget from './add-to-cart-widget'
|
|
22
|
-
import { ApplyTypography, MediaStack } from '@hanzo/ui/primitives'
|
|
23
26
|
|
|
24
|
-
const
|
|
25
|
-
|
|
27
|
+
const SCROLL = {
|
|
28
|
+
scrollAfter: 5,
|
|
29
|
+
scrollHeightClx: 'h-[65vh]'
|
|
30
|
+
}
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
* starting with 'scrollAfter' elements,
|
|
29
|
-
* the list will scroll, and the card will
|
|
30
|
-
* have 'scrollHeightClx' applied to it to define and fix the height.
|
|
31
|
-
* This is most like something like '80vh'
|
|
32
|
-
* defaults are '5' and 'h-[70vh]'
|
|
33
|
-
* */
|
|
34
|
-
scrollAfter?: number
|
|
35
|
-
scrollHeightClx?: string
|
|
32
|
+
const MEDIA_CONSTRAINT = {w: 200, h: 200}
|
|
36
33
|
|
|
34
|
+
const CarouselBuyCard: React.FC<{
|
|
35
|
+
skuPath: string
|
|
37
36
|
clx?: string
|
|
38
|
-
famWidgetClx?: string
|
|
39
|
-
addWidgetClx?: string
|
|
40
|
-
selector: ComponentType<ItemSelectorProps>
|
|
41
|
-
selectorProps?: ItemSelectorCompProps
|
|
42
|
-
|
|
43
|
-
/** Show all items from all sibling families
|
|
44
|
-
* If skuPath defines a Family, the first of it's items will
|
|
45
|
-
* be selected. The facet widget will just select a the first
|
|
46
|
-
* item in the chosen Family without changings the overall set
|
|
47
|
-
* of choices. */
|
|
48
|
-
allVariants?: boolean
|
|
49
|
-
|
|
50
|
-
familyTabAs?: 'image' | 'label' | 'image-and-label'
|
|
51
|
-
showItemMedia?: boolean
|
|
52
|
-
|
|
53
|
-
onQuantityChanged?: (sku: string, oldV: number, newV: number) => void
|
|
54
37
|
mobile?: boolean
|
|
38
|
+
handleCheckout: () => void
|
|
39
|
+
onQuantityChanged?: (sku: string, oldV: number, newV: number) => void
|
|
55
40
|
}> = observer(({
|
|
56
41
|
skuPath,
|
|
57
|
-
scrollAfter=5,
|
|
58
|
-
scrollHeightClx='h-[80vh]',
|
|
59
42
|
clx='',
|
|
60
|
-
famWidgetClx='',
|
|
61
|
-
addWidgetClx='',
|
|
62
|
-
selector: Selector,
|
|
63
|
-
selectorProps={
|
|
64
|
-
clx: '',
|
|
65
|
-
soleItemClx: '',
|
|
66
|
-
itemClx: '',
|
|
67
|
-
ext: {}
|
|
68
|
-
},
|
|
69
|
-
familyTabAs='image-and-label',
|
|
70
|
-
showItemMedia=true,
|
|
71
|
-
allVariants=false,
|
|
72
43
|
mobile=false,
|
|
44
|
+
handleCheckout,
|
|
73
45
|
onQuantityChanged,
|
|
74
46
|
}) => {
|
|
75
47
|
|
|
76
48
|
const cmmc = useCommerce()
|
|
77
|
-
const inst = useRef<{
|
|
78
|
-
level: number,
|
|
79
|
-
reqFamily : Family | undefined
|
|
80
|
-
parentNode: ProductTreeNode | undefined
|
|
81
|
-
disposers: IReactionDisposer[]
|
|
82
|
-
} | undefined>(undefined)
|
|
83
49
|
|
|
50
|
+
const r = useRef<{
|
|
51
|
+
role: CategoryNodeRole
|
|
52
|
+
item: LineItem | undefined
|
|
53
|
+
family: Family | undefined
|
|
54
|
+
families: Family[] | undefined
|
|
55
|
+
node: CategoryNode
|
|
56
|
+
uiSpec: SelectionUISpecifier
|
|
57
|
+
single?: {
|
|
58
|
+
items: LineItem[]
|
|
59
|
+
Selector: ComponentType<ItemSelectorProps>
|
|
60
|
+
selOptions: ItemSelectorOptions | undefined
|
|
61
|
+
scrollable: boolean
|
|
62
|
+
showItemMedia: boolean
|
|
63
|
+
}
|
|
64
|
+
} | undefined>(undefined)
|
|
84
65
|
|
|
85
66
|
useEffect(() => {
|
|
86
67
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const toks = skuPath.split(SEP.TOK)
|
|
91
|
-
const level = toks.length - 1
|
|
92
|
-
if (level === 0) {
|
|
93
|
-
throw new Error('BuyCard.useEffect(): must specify at least at least one Level in skuPath!')
|
|
68
|
+
const peek = cmmc.peek(skuPath)
|
|
69
|
+
if (typeof peek === 'string') {
|
|
70
|
+
throw new Error(peek)
|
|
94
71
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
paths[l] = [toks[l]]
|
|
98
|
-
}
|
|
99
|
-
if (reqFamily) {
|
|
100
|
-
if (allVariants && level >= 2) {
|
|
101
|
-
// select all siblings of reqFamily.
|
|
102
|
-
// ie, go one level back
|
|
103
|
-
delete paths[level]
|
|
104
|
-
initialFamily = reqFamily
|
|
105
|
-
reqFamily = undefined
|
|
106
|
-
parentNode = cmmc.getNodeAtPath(toks.slice(0, -1).join(SEP.TOK))
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
// select siblings paths
|
|
111
|
-
if (allVariants) {
|
|
112
|
-
paths[level + 1] = [...parentNode!.subNodes!.map((node) => (node.skuToken))]
|
|
113
|
-
}
|
|
114
|
-
// Actually select the the first fam at the fam level,
|
|
115
|
-
else {
|
|
116
|
-
paths[level + 1] = [parentNode!.subNodes![0].skuToken]
|
|
117
|
-
}
|
|
72
|
+
if (peek.role === 'non-outermost') {
|
|
73
|
+
throw new Error(`BuyCard: skuPath ${skuPath} isn't an outermost tree node or product family!`)
|
|
118
74
|
}
|
|
119
75
|
|
|
120
|
-
const
|
|
121
|
-
initialFamily = initialFamily ? initialFamily : (reqFamily ? reqFamily : selFamilies[0])
|
|
122
|
-
cmmc.setCurrentItem(initialFamily.products[0].sku)
|
|
123
|
-
const currentFamily = new ObsStringMutator(initialFamily!.id.split(SEP.TOK).pop()!)
|
|
76
|
+
const uiSpec = getSelectionUISpecifier(skuPath)
|
|
124
77
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
disposers: []
|
|
78
|
+
r.current = {
|
|
79
|
+
...peek,
|
|
80
|
+
node: peek.node!, // else exception was thrown.
|
|
81
|
+
uiSpec,
|
|
130
82
|
}
|
|
131
83
|
|
|
132
|
-
if (
|
|
133
|
-
inst.current?.disposers.push(reaction(
|
|
134
|
-
() => {
|
|
135
|
-
const fams = cmmc.selectedFamilies
|
|
136
|
-
return (fams.length > 0) ? fams[0].id : undefined
|
|
137
|
-
},
|
|
138
|
-
(famId) => {
|
|
139
|
-
if (famId && famId !== cmmc.currentItem?.familyId) {
|
|
140
|
-
const fam = cmmc.getFamily(famId)
|
|
141
|
-
if (fam) {
|
|
142
|
-
cmmc.setCurrentItem(fam.products[0].sku)
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
))
|
|
147
|
-
}
|
|
84
|
+
if (peek.role === 'single-family') {
|
|
148
85
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
86
|
+
const singleSpec = uiSpec.singleFamily
|
|
87
|
+
const Selector: ComponentType<ItemSelectorProps> =
|
|
88
|
+
(singleSpec?.type === 'buttons') ? ButtonItemSelector : CarouselItemSelector
|
|
89
|
+
const selOptions = singleSpec?.options
|
|
90
|
+
const items = peek.family!.products as LineItem[]
|
|
152
91
|
|
|
153
|
-
|
|
92
|
+
r.current.single = {
|
|
93
|
+
items,
|
|
94
|
+
Selector,
|
|
95
|
+
selOptions,
|
|
96
|
+
scrollable: !!(items.length > SCROLL.scrollAfter),
|
|
97
|
+
showItemMedia: singleSpec?.type !== 'carousel'
|
|
98
|
+
}
|
|
154
99
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
100
|
+
const currItem = peek.item ?? peek.family!.products[0]
|
|
101
|
+
cmmc.setCurrentItem(currItem.sku)
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const initialFamily = peek.family ? peek.family : peek.families![0]
|
|
105
|
+
const currItem = peek.item ?? initialFamily.products[0]
|
|
106
|
+
cmmc.setCurrentItem(currItem.sku)
|
|
159
107
|
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const selectSku = (sku: string) => {
|
|
163
|
-
cmmc.setCurrentItem(sku)
|
|
164
|
-
const pathValue = cmmc.currentItem?.familyId.split(SEP.TOK).pop()!
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const famTitle = inst.current?.reqFamily ? inst.current.reqFamily.title : cmmc.selectedFamilies?.[0]?.title
|
|
168
|
-
|
|
169
|
-
const itemsToShow = (!cmmc.hasSelection) ? undefined :
|
|
170
|
-
allVariants ? cmmc.selectedItems : cmmc.selectedFamilies[0].products as LineItem[]
|
|
171
108
|
|
|
109
|
+
}, [])
|
|
172
110
|
|
|
173
111
|
const TitleArea: React.FC<{
|
|
174
112
|
title: string
|
|
175
113
|
byline?: string
|
|
176
114
|
clx?: string
|
|
115
|
+
bylineClx?: string
|
|
177
116
|
}> = ({
|
|
178
117
|
title,
|
|
179
118
|
byline,
|
|
180
|
-
clx=''
|
|
119
|
+
clx='',
|
|
120
|
+
bylineClx=''
|
|
181
121
|
}) => (
|
|
182
122
|
<ApplyTypography className={clx}>
|
|
183
123
|
<h3>{title}</h3>
|
|
184
|
-
{byline && (<h6>{byline}</h6>)}
|
|
124
|
+
{byline && (<h6 className={bylineClx}>{byline}</h6>)}
|
|
185
125
|
</ApplyTypography>
|
|
186
126
|
)
|
|
187
127
|
|
|
188
|
-
const scroll = !!(itemsToShow && itemsToShow.length > scrollAfter)
|
|
189
128
|
return (
|
|
190
129
|
<div className={cn(
|
|
191
|
-
'px-4 md:px-6 pt-3 pb-4 flex flex-col items-center min-h-[
|
|
130
|
+
'px-4 md:px-6 pt-3 pb-4 flex flex-col gap-4 items-center min-h-[40vh]',
|
|
192
131
|
clx,
|
|
193
|
-
|
|
194
|
-
)}
|
|
195
|
-
{
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
{
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
'
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
<Selector
|
|
237
|
-
items={itemsToShow}
|
|
238
|
-
selectedItemRef={cmmc}
|
|
239
|
-
selectSku={selectSku}
|
|
240
|
-
{...selectorProps}
|
|
241
|
-
scrollList={scroll}
|
|
242
|
-
showFamily={selectorProps.showFamily ?
|
|
243
|
-
selectorProps.showFamily
|
|
244
|
-
:
|
|
245
|
-
(allVariants && !inst.current?.reqFamily)
|
|
246
|
-
}
|
|
247
|
-
/>
|
|
248
|
-
)}
|
|
132
|
+
r.current?.single?.scrollable ? SCROLL.scrollHeightClx : 'h-auto'
|
|
133
|
+
)}>
|
|
134
|
+
{r.current?.single ? (<>
|
|
135
|
+
<TitleArea title={r.current?.family?.title ?? ''} clx=''/>
|
|
136
|
+
{(r.current.single.showItemMedia && cmmc.currentItem ) && (
|
|
137
|
+
<MediaStack
|
|
138
|
+
media={cmmc.currentItem}
|
|
139
|
+
constrainTo={MEDIA_CONSTRAINT}
|
|
140
|
+
clx={(r.current.single.scrollable ? 'shrink-0' : '')}
|
|
141
|
+
/>
|
|
142
|
+
)}
|
|
143
|
+
{(r.current.single.showItemMedia && !cmmc.currentItem ) && (
|
|
144
|
+
<Skeleton className={'w-[200px] h-[200px] my-4 ' + (r.current.single.scrollable ? 'shrink-0' : '')}/>
|
|
145
|
+
)}
|
|
146
|
+
{r.current.single.items && (
|
|
147
|
+
<r.current.single.Selector
|
|
148
|
+
items={r.current.single.items}
|
|
149
|
+
selectedItemRef={cmmc}
|
|
150
|
+
selectSku={cmmc.setCurrentItem.bind(cmmc)}
|
|
151
|
+
scrollable={r.current.single.scrollable}
|
|
152
|
+
mobile={mobile}
|
|
153
|
+
options={r.current.single.selOptions}
|
|
154
|
+
/>
|
|
155
|
+
)}
|
|
156
|
+
</>) : (<>
|
|
157
|
+
{r.current?.uiSpec.multiFamily?.showParentTitle && (
|
|
158
|
+
<TitleArea
|
|
159
|
+
title={r.current?.node.label ?? ''}
|
|
160
|
+
byline={r.current?.node.subNodesLabel}
|
|
161
|
+
clx={'mb-2 '}
|
|
162
|
+
bylineClx='!text-center font-bold text-muted mt-3'
|
|
163
|
+
/>
|
|
164
|
+
)}
|
|
165
|
+
{r.current?.families && ( // safegaurd for first render etc.
|
|
166
|
+
<FamilyCarousel
|
|
167
|
+
families={r.current?.families}
|
|
168
|
+
clx='w-full'
|
|
169
|
+
slideOptions={r.current?.uiSpec.multiFamily?.slide.options}
|
|
170
|
+
mediaConstraint={MEDIA_CONSTRAINT}
|
|
171
|
+
mobile={mobile}
|
|
172
|
+
/>
|
|
173
|
+
)}
|
|
174
|
+
</>)}
|
|
249
175
|
{(cmmc.currentItem) && (
|
|
250
|
-
<
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
176
|
+
<div className={cn(
|
|
177
|
+
'self-stretch mt-4 flex flex-col items-center gap-3',
|
|
178
|
+
(r.current?.single?.scrollable ? 'shrink-0' : '')
|
|
179
|
+
)}>
|
|
180
|
+
<AddToCartWidget
|
|
181
|
+
size='default'
|
|
182
|
+
item={cmmc.currentItem}
|
|
183
|
+
onQuantityChanged={onQuantityChanged}
|
|
184
|
+
variant={cmmc.cartEmpty ? 'primary' : 'outline'}
|
|
185
|
+
className='min-w-[160px] w-full sm:max-w-[320px]'
|
|
186
|
+
/>
|
|
187
|
+
{!cmmc.cartEmpty && (
|
|
188
|
+
<Button
|
|
189
|
+
onClick={handleCheckout}
|
|
190
|
+
variant='primary'
|
|
191
|
+
rounded='lg'
|
|
192
|
+
className='min-w-[160px] w-full sm:max-w-[320px]'
|
|
193
|
+
>
|
|
194
|
+
Checkout
|
|
195
|
+
</Button>
|
|
196
|
+
)}
|
|
197
|
+
</div>
|
|
256
198
|
)}
|
|
257
199
|
</div >
|
|
258
200
|
)
|
|
259
201
|
})
|
|
260
202
|
|
|
203
|
+
/* Above family carousel
|
|
204
|
+
<TitleArea
|
|
205
|
+
title={r.current?.node.label ?? ''}
|
|
206
|
+
byline={r.current?.node.subNodesLabel}
|
|
207
|
+
clx={'mb-2 '}
|
|
208
|
+
bylineClx='!text-center font-bold text-muted mt-3'
|
|
209
|
+
/>
|
|
210
|
+
*/
|
|
211
|
+
|
|
261
212
|
export default CarouselBuyCard
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{/*
|
|
2
|
+
<LevelNodesWidget
|
|
3
|
+
className={cn(
|
|
4
|
+
'grid gap-0 align-stretch justify-normal ' + `grid-cols-${inst.current.parentNode.subNodes!.length}`,
|
|
5
|
+
'border-b-2 rounded-lg border-level-3 mb-4 -mr-2 -ml-2 max-w-[460px] h-10', // height is needed for iPhone bug
|
|
6
|
+
(scroll ? 'shrink-0' : ''),
|
|
7
|
+
famWidgetClx
|
|
8
|
+
)}
|
|
9
|
+
mobile={mobile}
|
|
10
|
+
mutator={allVariants ?
|
|
11
|
+
{
|
|
12
|
+
get: () => (inst.current!.currentFamily.s),
|
|
13
|
+
set: setFamilyPath
|
|
14
|
+
}
|
|
15
|
+
:
|
|
16
|
+
getFacetValuesMutator(inst.current.level + 1, cmmc)
|
|
17
|
+
}
|
|
18
|
+
itemClx='flex-col h-auto gap-0 py-1 px-3'
|
|
19
|
+
buttonClx={
|
|
20
|
+
'h-full ' +
|
|
21
|
+
'!border-level-3'
|
|
22
|
+
}
|
|
23
|
+
levelNodes={inst.current.parentNode.subNodes!}
|
|
24
|
+
show={familyTabAs}
|
|
25
|
+
/>
|
|
26
|
+
*/}
|
|
27
|
+
</>)}
|
|
@@ -61,7 +61,7 @@ const CartLineItem: React.FC<{
|
|
|
61
61
|
</div>
|
|
62
62
|
<div className='flex flex-row items-center justify-between w-full'>
|
|
63
63
|
<div className='flex flex-row items-center'>
|
|
64
|
-
<AddToCartWidget className='' item={item} size='xs' buttonClx='h-8 md:h-6'
|
|
64
|
+
<AddToCartWidget className='' item={item} size='xs' buttonClx='h-8 md:h-6' variant='minimal'/>
|
|
65
65
|
{item.quantity > 1 && (<span className='pl-2.5'>{'@' + formatCurrencyValue(item.price)}</span>)}
|
|
66
66
|
</div>
|
|
67
67
|
<div className='flex flex-row gap-1 items-center justify-end'>
|
|
@@ -23,7 +23,7 @@ const ContactForm: React.FC<{
|
|
|
23
23
|
render={({ field }) => (
|
|
24
24
|
<FormItem className='w-full'>
|
|
25
25
|
<FormControl>
|
|
26
|
-
<Input {...field}
|
|
26
|
+
<Input {...field} placeholder='Full name'/>
|
|
27
27
|
</FormControl>
|
|
28
28
|
<FormMessage className='py-0 space-y-0 !m-0'/>
|
|
29
29
|
</FormItem>
|
|
@@ -35,7 +35,7 @@ const ContactForm: React.FC<{
|
|
|
35
35
|
render={({ field }) => (
|
|
36
36
|
<FormItem className='w-full'>
|
|
37
37
|
<FormControl>
|
|
38
|
-
<Input {...field}
|
|
38
|
+
<Input {...field} placeholder='Email'/>
|
|
39
39
|
</FormControl>
|
|
40
40
|
<FormMessage className='py-0 space-y-0 !m-0'/>
|
|
41
41
|
</FormItem>
|
|
@@ -178,7 +178,7 @@ const PayWithCrypto: React.FC<PaymentMethodComponentProps> = observer(({
|
|
|
178
178
|
<div className='flex gap-2 grid grid-cols-3'>
|
|
179
179
|
<Select onValueChange={(token) => {/*ONLY ETH setSelectedToken(token) */}} defaultValue='eth'>
|
|
180
180
|
<SelectTrigger>
|
|
181
|
-
<SelectValue defaultValue='eth'
|
|
181
|
+
<SelectValue defaultValue='eth' />
|
|
182
182
|
</SelectTrigger>
|
|
183
183
|
<SelectContent>
|
|
184
184
|
<SelectGroup>
|
|
@@ -192,7 +192,6 @@ const PayWithCrypto: React.FC<PaymentMethodComponentProps> = observer(({
|
|
|
192
192
|
<Input
|
|
193
193
|
value={amount ? amount/(10**18) : amount}
|
|
194
194
|
contentEditable={false}
|
|
195
|
-
className='border-muted-4'
|
|
196
195
|
/>
|
|
197
196
|
<div className='relative flex items-center gap-2 -top-[32px] justify-end px-2 py-1 rounded-lg bg-muted-4 w-fit text-xs float-right mr-3'>
|
|
198
197
|
<Eth height={10}/>
|
|
@@ -82,7 +82,7 @@ const ShippingStepForm: React.FC<CheckoutStepComponentProps> = ({
|
|
|
82
82
|
render={({ field }) => (
|
|
83
83
|
<FormItem className='space-y-1 w-full'>
|
|
84
84
|
<FormControl>
|
|
85
|
-
<Input {...field}
|
|
85
|
+
<Input {...field} placeholder='Address line 1'/>
|
|
86
86
|
</FormControl>
|
|
87
87
|
<FormMessage />
|
|
88
88
|
</FormItem>
|
|
@@ -94,7 +94,7 @@ const ShippingStepForm: React.FC<CheckoutStepComponentProps> = ({
|
|
|
94
94
|
render={({ field }) => (
|
|
95
95
|
<FormItem className='space-y-1 w-full'>
|
|
96
96
|
<FormControl>
|
|
97
|
-
<Input {...field}
|
|
97
|
+
<Input {...field} placeholder='Address line 2 (optional)'/>
|
|
98
98
|
</FormControl>
|
|
99
99
|
<FormMessage />
|
|
100
100
|
</FormItem>
|
|
@@ -107,7 +107,7 @@ const ShippingStepForm: React.FC<CheckoutStepComponentProps> = ({
|
|
|
107
107
|
render={({ field }) => (
|
|
108
108
|
<FormItem className='space-y-1 w-full'>
|
|
109
109
|
<FormControl>
|
|
110
|
-
<Input {...field}
|
|
110
|
+
<Input {...field} placeholder='Zip code'/>
|
|
111
111
|
</FormControl>
|
|
112
112
|
<FormMessage />
|
|
113
113
|
</FormItem>
|
|
@@ -119,7 +119,7 @@ const ShippingStepForm: React.FC<CheckoutStepComponentProps> = ({
|
|
|
119
119
|
render={({ field }) => (
|
|
120
120
|
<FormItem className='space-y-1 w-full'>
|
|
121
121
|
<FormControl>
|
|
122
|
-
<Input {...field}
|
|
122
|
+
<Input {...field} placeholder='City'/>
|
|
123
123
|
</FormControl>
|
|
124
124
|
<FormMessage />
|
|
125
125
|
</FormItem>
|
|
@@ -133,7 +133,7 @@ const ShippingStepForm: React.FC<CheckoutStepComponentProps> = ({
|
|
|
133
133
|
render={({ field }) => (
|
|
134
134
|
<FormItem className='space-y-1 w-full'>
|
|
135
135
|
<FormControl>
|
|
136
|
-
<Input {...field}
|
|
136
|
+
<Input {...field} placeholder='State (optional)'/>
|
|
137
137
|
</FormControl>
|
|
138
138
|
<FormMessage />
|
|
139
139
|
</FormItem>
|
package/components/index.ts
CHANGED
|
@@ -15,6 +15,4 @@ export { default as ShippingStepForm } from './checkout/shipping-step-form'
|
|
|
15
15
|
export { default as ProductCard } from './item/product-card'
|
|
16
16
|
export { Icons } from './Icons'
|
|
17
17
|
|
|
18
|
-
export
|
|
19
|
-
export { default as RadioItemSelector } from './select-product/radio-selector'
|
|
20
|
-
export { default as CarouselItemSelector, type CarouselItemSelectorPropsExt } from './select-product/carousel-selector'
|
|
18
|
+
export * from './item-selector'
|