@luxfi/core 5.0.9 → 5.1.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/commerce/{data/index.ts → index.ts} +2 -1
- package/components/commerce/buy-drawer/drawer.tsx +4 -46
- package/components/commerce/buy-drawer/index.tsx +17 -215
- package/components/commerce/checkout-button.tsx +14 -27
- package/components/commerce/checkout-widget/index.tsx +37 -143
- package/components/commerce/checkout-widget/use-anim-clx-set.ts +1 -3
- package/components/commerce/checkout-widget/use-lagging-item-ref.ts +30 -0
- package/components/header/desktop.tsx +1 -1
- package/components/index.ts +8 -2
- package/conf/index.ts +0 -2
- package/package.json +10 -12
- package/root-layout/index.tsx +4 -6
- package/tsconfig.json +4 -4
- package/commerce/ui-context/commerce-ui.ts +0 -118
- package/commerce/ui-context/index.tsx +0 -50
- package/components/commerce/add-widget.tsx +0 -20
- package/components/commerce/buy-button.tsx +0 -34
- package/style/drawer-handle-overrides.css +0 -154
- /package/commerce/{data/AUTO-GEN-bullion-by-family.json → AUTO-GEN-bullion-by-family.json} +0 -0
- /package/commerce/{data/EDIT-ME-bullion-market-prices.ts → EDIT-ME-bullion-market-prices.ts} +0 -0
- /package/commerce/{data/assign-prices.ts → assign-prices.ts} +0 -0
- /package/commerce/{data/assign-videos-by-family-group.ts → assign-videos-by-family-group.ts} +0 -0
- /package/commerce/{data/bullion-price-1oz.ts → bullion-price-1oz.ts} +0 -0
- /package/{conf/lux-commerce-options.ts → commerce/lux-service-options.ts} +0 -0
@@ -13,5 +13,6 @@ export const getBullionFamilies = (videoMap: Map<string, VideoDef>) => (
|
|
13
13
|
)
|
14
14
|
)
|
15
15
|
|
16
|
-
export { default as serviceOptions } from '
|
16
|
+
export { default as serviceOptions } from './lux-service-options'
|
17
17
|
export { default as bullionPrice1oz } from './bullion-price-1oz'
|
18
|
+
|
@@ -3,70 +3,29 @@ import React, {type PropsWithChildren } from 'react'
|
|
3
3
|
|
4
4
|
import { X as LucideX} from 'lucide-react'
|
5
5
|
|
6
|
-
import {
|
7
|
-
Button,
|
8
|
-
Drawer,
|
9
|
-
DrawerContent,
|
10
|
-
DrawerHandle,
|
11
|
-
type DrawerProps,
|
12
|
-
useDrawerContext
|
13
|
-
} from '@hanzo/ui/primitives'
|
6
|
+
import { Button, Drawer, DrawerContent, type DrawerProps } from '@hanzo/ui/primitives'
|
14
7
|
import { cn } from '@hanzo/ui/util'
|
15
8
|
|
16
|
-
import '../../../style/drawer-handle-overrides.css'
|
17
|
-
|
18
9
|
const CommerceDrawer: React.FC<PropsWithChildren &
|
19
10
|
Omit<DrawerProps, 'onOpenChange'> &
|
20
11
|
{
|
21
12
|
setOpen: (b: boolean) => void
|
22
|
-
handleHandleClicked: () => void
|
23
13
|
drawerClx?: string
|
24
|
-
setActiveSPIndexSetter?: (fn: (snapPoint: number | string | null) => void) => void
|
25
14
|
}
|
26
15
|
> = ({
|
27
16
|
children,
|
28
17
|
open,
|
29
18
|
setOpen,
|
30
19
|
modal,
|
31
|
-
snapPoints,
|
32
|
-
setActiveSnapPoint,
|
33
|
-
activeSnapPoint,
|
34
|
-
handleHandleClicked,
|
35
|
-
setActiveSPIndexSetter,
|
36
20
|
drawerClx='',
|
37
21
|
...rest
|
38
|
-
}) =>
|
39
|
-
|
40
|
-
|
41
|
-
return (
|
22
|
+
}) => (
|
42
23
|
// @ts-ignore
|
43
|
-
<Drawer
|
44
|
-
|
45
|
-
onOpenChange={setOpen}
|
46
|
-
modal={modal}
|
47
|
-
snapPoints={snapPoints}
|
48
|
-
setActiveSnapPoint={setActiveSnapPoint}
|
49
|
-
activeSnapPoint={activeSnapPoint}
|
50
|
-
fastDragSkipsToEnd={false}
|
51
|
-
handleOnly={true}
|
52
|
-
setActiveSPIndexSetter={setActiveSPIndexSetter}
|
53
|
-
|
54
|
-
|
55
|
-
{...rest}
|
56
|
-
>
|
57
|
-
<DrawerContent defaultHandle={false} className={cn(
|
24
|
+
<Drawer open={open} onOpenChange={setOpen} modal={modal} {...rest}>
|
25
|
+
<DrawerContent modal={modal} className={cn(
|
58
26
|
'rounded-t-xl mt-6 pt-6',
|
59
27
|
drawerClx
|
60
28
|
)}>
|
61
|
-
|
62
|
-
<DrawerHandle
|
63
|
-
className={
|
64
|
-
'absolute left-0 right-0 mx-auto top-2 ' +
|
65
|
-
'w-[100px] h-3 rounded-full bg-level-3 hover:bg-level-2 shrink-0'
|
66
|
-
}
|
67
|
-
handleClick={handleHandleClicked}
|
68
|
-
/>
|
69
|
-
|
70
29
|
{children}
|
71
30
|
<Button
|
72
31
|
variant='ghost'
|
@@ -79,7 +38,6 @@ const CommerceDrawer: React.FC<PropsWithChildren &
|
|
79
38
|
</DrawerContent>
|
80
39
|
</Drawer>
|
81
40
|
)
|
82
|
-
}
|
83
41
|
|
84
42
|
|
85
43
|
export default CommerceDrawer
|
@@ -1,242 +1,44 @@
|
|
1
1
|
'use client'
|
2
|
-
import React
|
3
|
-
import {
|
4
|
-
import { action, computed, makeObservable, observable, reaction, type IReactionDisposer } from 'mobx'
|
2
|
+
import React from 'react'
|
3
|
+
import { useRouter } from 'next/navigation'
|
5
4
|
import { observer } from 'mobx-react-lite'
|
6
5
|
|
7
|
-
import {
|
8
|
-
|
9
|
-
import { useCommerceUI } from '../../../commerce/ui-context'
|
6
|
+
import { useCommerceUI, CarouselBuyCard } from '@hanzo/commerce'
|
10
7
|
|
11
8
|
import CommerceDrawer from './drawer'
|
12
9
|
import CheckoutButton from '../checkout-button'
|
13
10
|
|
14
|
-
const BUY = '700px'
|
15
|
-
const MICRO = '120px'
|
16
|
-
const BOTH = [MICRO, BUY]
|
17
|
-
const BUY_ONLY = [BUY]
|
18
|
-
const MICRO_ONLY = [MICRO]
|
19
|
-
|
20
|
-
type DrawerMode = 'checkout' | 'added' | 'buy' | 'buy-added' | 'buy-checkout' | 'none' | 'closed' // manually
|
21
|
-
type DrawerState = 'micro' | 'buy' | 'closed'
|
22
|
-
|
23
|
-
const MODE_TO_STATE = {
|
24
|
-
checkout: 'micro',
|
25
|
-
added: 'micro',
|
26
|
-
buy: 'buy',
|
27
|
-
'buy-checkout': 'buy',
|
28
|
-
'buy-added': 'buy',
|
29
|
-
none: 'closed',
|
30
|
-
closed: 'closed'
|
31
|
-
} satisfies Record<DrawerMode, DrawerState>
|
32
|
-
|
33
|
-
const MODE_TO_POINTS = {
|
34
|
-
checkout: MICRO_ONLY,
|
35
|
-
added: BOTH,
|
36
|
-
buy: BUY_ONLY,
|
37
|
-
'buy-checkout': BOTH,
|
38
|
-
'buy-added': BOTH,
|
39
|
-
none: BOTH,
|
40
|
-
closed: BOTH
|
41
|
-
}
|
42
|
-
|
43
|
-
|
44
|
-
class ObsDrawerState {
|
45
|
-
|
46
|
-
_mode: DrawerMode = 'none'
|
47
|
-
|
48
|
-
constructor() {
|
49
|
-
makeObservable(this, {
|
50
|
-
_mode: observable,
|
51
|
-
setMode: action,
|
52
|
-
mode: computed,
|
53
|
-
state: computed,
|
54
|
-
points: computed,
|
55
|
-
modal: computed,
|
56
|
-
activePoint: computed
|
57
|
-
})
|
58
|
-
}
|
59
|
-
|
60
|
-
get mode(): DrawerMode {return this._mode}
|
61
|
-
get state(): DrawerState { return MODE_TO_STATE[this._mode] }
|
62
|
-
get points(): (number | string)[] { return MODE_TO_POINTS[this._mode] }
|
63
|
-
get modal(): boolean { return this.state !== 'micro' }
|
64
|
-
get activePoint(): number | string | null {
|
65
|
-
if (this.state === 'buy') return BUY
|
66
|
-
if (this.state === 'micro') return MICRO
|
67
|
-
return null
|
68
|
-
}
|
69
|
-
|
70
|
-
setMode = (m: DrawerMode) => {this._mode = m}
|
71
|
-
}
|
72
|
-
|
73
11
|
const CommerceUIComponent: React.FC = observer(() => {
|
74
12
|
|
75
|
-
const cmmc = useCommerce()
|
76
13
|
const ui = useCommerceUI()
|
77
14
|
const router = useRouter()
|
78
|
-
const isCheckout = usePathname() === '/checkout'
|
79
|
-
|
80
|
-
const stateRef = useRef<ObsDrawerState>(new ObsDrawerState())
|
81
|
-
const reactionDisposers = useRef<IReactionDisposer[]>([])
|
82
|
-
|
83
|
-
const [activeSnapPoint, setActiveSnapPoint] = useState<string | number | null>(null)
|
84
|
-
const setterRef = useRef<((index: number ) => void) | undefined>(undefined)
|
85
|
-
|
86
|
-
useEffect(() => {
|
87
|
-
|
88
|
-
reactionDisposers.current.push(reaction(
|
89
|
-
|
90
|
-
() => ({
|
91
|
-
buy: !!ui.buyOptionsSkuPath,
|
92
|
-
added: !isCheckout && ui.item,
|
93
|
-
checkout: !isCheckout && !cmmc.cartEmpty,
|
94
|
-
closed: ui.closed
|
95
|
-
}),
|
96
|
-
({buy, added, checkout, closed}) => {
|
97
|
-
let mode: DrawerMode = 'none' // TODO: 'closed'
|
98
|
-
if (buy) {
|
99
|
-
if (added) {
|
100
|
-
mode = 'buy-added'
|
101
|
-
}
|
102
|
-
else if (checkout) {
|
103
|
-
mode = 'buy-checkout'
|
104
|
-
}
|
105
|
-
else {
|
106
|
-
mode = 'buy'
|
107
|
-
}
|
108
|
-
}
|
109
|
-
else {
|
110
|
-
if (closed) {
|
111
|
-
mode = 'closed'
|
112
|
-
}
|
113
|
-
else if (added) {
|
114
|
-
mode = 'added'
|
115
|
-
}
|
116
|
-
else if (checkout) {
|
117
|
-
mode = 'checkout'
|
118
|
-
}
|
119
|
-
}
|
120
|
-
stateRef.current.setMode(mode)
|
121
|
-
},
|
122
|
-
{equals: (val, prev) => (
|
123
|
-
val.buy === prev.buy
|
124
|
-
&&
|
125
|
-
val.added === prev.added
|
126
|
-
&&
|
127
|
-
val.checkout === prev.checkout
|
128
|
-
&&
|
129
|
-
val.closed === prev.closed
|
130
|
-
)}
|
131
|
-
)),
|
132
|
-
reactionDisposers.current.push(reaction(
|
133
|
-
() => ( stateRef.current.state ),
|
134
|
-
(s) => {
|
135
|
-
if (s === 'buy') {
|
136
|
-
//setterRef.current?.(stateRef.current.points.length - 1)
|
137
|
-
setActiveSnapPoint(BUY)
|
138
|
-
}
|
139
|
-
else if (s === 'micro') {
|
140
|
-
//setterRef.current?.(0)
|
141
|
-
setActiveSnapPoint(MICRO)
|
142
|
-
}
|
143
|
-
}
|
144
|
-
))
|
145
|
-
return () => {
|
146
|
-
reactionDisposers.current?.forEach((d) => {d()})
|
147
|
-
}
|
148
|
-
}, [isCheckout])
|
149
|
-
|
150
|
-
const _setActiveSnapPoint = (pt: string | number | null): void => {
|
151
|
-
console.log("ON CHANGE: ", pt)
|
152
|
-
setActiveSnapPoint(pt)
|
153
|
-
}
|
154
15
|
|
155
16
|
const handleCheckout = () => {
|
156
17
|
router.push('/checkout')
|
157
18
|
}
|
158
19
|
|
159
|
-
const reallyOnlyCloseDrawer = (b: boolean) => {
|
160
20
|
// Should only ever be called internally to close
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
const handleHandleClicked = () => {
|
165
|
-
console.log("HANDLE CLICKED")
|
166
|
-
|
167
|
-
if (stateRef.current.state === 'buy') {
|
168
|
-
const toks = stateRef.current.mode.split('-')
|
169
|
-
if (toks.length <= 1) {
|
170
|
-
console.log("CLOSING 'BUY' ... ")
|
171
|
-
ui.hideBuyOptions()
|
172
|
-
}
|
173
|
-
else {
|
174
|
-
console.log("CLOSING 'BUY' to ", toks[1])
|
175
|
-
ui.hideBuyOptions()
|
176
|
-
}
|
177
|
-
}
|
178
|
-
else if (stateRef.current.state === 'micro') {
|
179
|
-
if (stateRef.current.mode === 'checkout') {
|
180
|
-
console.log(" CLOSING 'CHECKOUT' ... ")
|
181
|
-
ui.setClosed(true)
|
182
|
-
}
|
183
|
-
else if (stateRef.current.mode === 'added') {
|
184
|
-
console.log(" OPENING 'ADDED' ... ")
|
185
|
-
ui.showBuyOptions(ui.item?.sku ?? '')
|
186
|
-
}
|
187
|
-
}
|
188
|
-
}
|
189
|
-
|
190
|
-
const handleCloseGesture = () => {
|
191
|
-
if (stateRef.current.state === 'buy') {
|
192
|
-
console.log(" CLOSING 'BUY' ... ")
|
193
|
-
const toks = stateRef.current.mode.split('-')
|
194
|
-
if (toks.length <= 1) {
|
195
|
-
stateRef.current.setMode('none')
|
196
|
-
}
|
197
|
-
else {
|
198
|
-
stateRef.current.setMode(toks[1] as DrawerMode) // 'checkout' or 'added'
|
199
|
-
}
|
200
|
-
return true // "handled!"
|
21
|
+
const reallyOnlyCloseDrawer = (b: boolean) => {
|
22
|
+
if (!b ) {
|
23
|
+
ui.hideBuyOptions()
|
201
24
|
}
|
202
|
-
console.log("DEFAULT CLOSE ACTION")
|
203
|
-
return false
|
204
25
|
}
|
205
26
|
|
206
|
-
|
207
|
-
const setActiveSPIndexSetter = (fn: (index: number ) => void): void => {
|
208
|
-
setterRef.current = fn
|
209
|
-
}
|
210
|
-
|
211
|
-
|
212
27
|
return (
|
213
28
|
<CommerceDrawer
|
214
|
-
open={
|
29
|
+
open={!!ui.buyOptionsSkuPath}
|
215
30
|
setOpen={reallyOnlyCloseDrawer}
|
216
|
-
drawerClx={'w-full
|
217
|
-
snapPoints={stateRef.current.points}
|
218
|
-
modal={stateRef.current.modal}
|
219
|
-
activeSnapPoint={activeSnapPoint}
|
220
|
-
setActiveSnapPoint={_setActiveSnapPoint}
|
221
|
-
handleHandleClicked={handleHandleClicked}
|
222
|
-
setActiveSPIndexSetter={setActiveSPIndexSetter}
|
223
|
-
handleCloseGesture={handleCloseGesture}
|
31
|
+
drawerClx={'w-full md:max-w-[550px] md:mx-auto lg:max-w-[50vw]'}
|
224
32
|
>
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
selectorClx='max-w-[475px]'
|
235
|
-
/>
|
236
|
-
)}
|
237
|
-
{stateRef.current.state === 'micro' && (
|
238
|
-
<p>Mode: {stateRef.current.mode}</p>
|
239
|
-
)}
|
33
|
+
<CarouselBuyCard
|
34
|
+
skuPath={ui.buyOptionsSkuPath!}
|
35
|
+
checkoutButton={
|
36
|
+
<CheckoutButton handleCheckout={handleCheckout} className='w-full min-w-[160px] sm:max-w-[320px]'/>
|
37
|
+
}
|
38
|
+
clx='w-full'
|
39
|
+
addBtnClx='w-full min-w-[160px] sm:max-w-[320px]'
|
40
|
+
selectorClx='max-w-[475px]'
|
41
|
+
/>
|
240
42
|
</CommerceDrawer>
|
241
43
|
)
|
242
44
|
})
|
@@ -2,6 +2,7 @@
|
|
2
2
|
import React, { useEffect, useRef } from 'react'
|
3
3
|
import { observable, type IObservableValue, reaction } from 'mobx'
|
4
4
|
import { observer } from 'mobx-react-lite'
|
5
|
+
import { type LucideProps } from 'lucide-react'
|
5
6
|
|
6
7
|
import { Button, type ButtonProps } from '@hanzo/ui/primitives'
|
7
8
|
import { cn } from '@hanzo/ui/util'
|
@@ -11,15 +12,11 @@ import * as Icons from '../icons'
|
|
11
12
|
|
12
13
|
const IconAndQuantity: React.FC<{
|
13
14
|
animateOnQuantityChange?: boolean
|
14
|
-
showArrow?: boolean
|
15
|
-
showQuantity?: boolean
|
16
15
|
clx?: string
|
17
16
|
iconClx?: string
|
18
17
|
digitClx?: string
|
19
18
|
}> = observer(({
|
20
|
-
animateOnQuantityChange=
|
21
|
-
showArrow=true,
|
22
|
-
showQuantity=true,
|
19
|
+
animateOnQuantityChange=true,
|
23
20
|
clx='',
|
24
21
|
iconClx='',
|
25
22
|
digitClx=''
|
@@ -50,7 +47,6 @@ const IconAndQuantity: React.FC<{
|
|
50
47
|
|
51
48
|
return (
|
52
49
|
<div className={cn('flex items-center justify-center', clx)}>
|
53
|
-
{showQuantity && (
|
54
50
|
<div className={cn(
|
55
51
|
'relative flex items-center justify-center mr-1',
|
56
52
|
((wiggleRef.current.get() === 'more') ?
|
@@ -64,13 +60,12 @@ const IconAndQuantity: React.FC<{
|
|
64
60
|
'absolute left-0 right-0 top-0 bottom-0',
|
65
61
|
digitClx
|
66
62
|
)}>
|
67
|
-
<div style={{
|
63
|
+
<div style={{color: 'white' /* tailwind bug? */, fontSize: '11px', position: 'relative', top: '1px' }}>{cmmc.cartQuantity}</div>
|
68
64
|
</div>
|
69
65
|
)}
|
70
66
|
<Icons.bag width='19' height='24' className={cn('relative -top-[3px] opacity-70' , iconClx)} aria-hidden="true" />
|
71
67
|
</div>
|
72
|
-
|
73
|
-
{showArrow && (<span style={{fontSize: '17px',}}>›</span>)}
|
68
|
+
<span style={{fontSize: '17px',}}>›</span>
|
74
69
|
</div>
|
75
70
|
)
|
76
71
|
})
|
@@ -78,7 +73,6 @@ const IconAndQuantity: React.FC<{
|
|
78
73
|
const CheckoutButton: React.FC<ButtonProps & {
|
79
74
|
handleCheckout: () => void
|
80
75
|
showQuantity?: boolean
|
81
|
-
showArrow?: boolean
|
82
76
|
animateOnQuantityChange?: boolean
|
83
77
|
centerText?: boolean
|
84
78
|
}> = ({
|
@@ -87,10 +81,8 @@ const CheckoutButton: React.FC<ButtonProps & {
|
|
87
81
|
rounded='lg',
|
88
82
|
className,
|
89
83
|
showQuantity=true,
|
90
|
-
showArrow=true,
|
91
84
|
animateOnQuantityChange=true,
|
92
85
|
centerText=true,
|
93
|
-
children,
|
94
86
|
...rest
|
95
87
|
}) => {
|
96
88
|
|
@@ -101,27 +93,22 @@ const CheckoutButton: React.FC<ButtonProps & {
|
|
101
93
|
variant={variant}
|
102
94
|
rounded={rounded}
|
103
95
|
className={cn(
|
104
|
-
'flex justify-between items-stretch group',
|
105
|
-
showQuantity ? (centerText ? 'px-1.5' : 'pl-2.5 pr-1.5') : '',
|
106
96
|
className,
|
97
|
+
'flex justify-between items-stretch',
|
98
|
+
showQuantity ? (centerText ? 'px-1.5' : 'pl-2.5 pr-1.5') : ''
|
107
99
|
)}
|
108
100
|
>
|
109
|
-
{centerText && (
|
101
|
+
{showQuantity && centerText && (
|
102
|
+
<IconAndQuantity clx='invisible' />
|
103
|
+
)}
|
104
|
+
<div className='flex justify-center items-center'>Checkout</div>
|
105
|
+
{showQuantity && (
|
110
106
|
<IconAndQuantity
|
111
|
-
|
112
|
-
|
113
|
-
|
107
|
+
animateOnQuantityChange={animateOnQuantityChange}
|
108
|
+
iconClx='fill-fg-foreground'
|
109
|
+
digitClx='text-primary-fg leading-none font-bold font-sans'
|
114
110
|
/>
|
115
111
|
)}
|
116
|
-
{children ?? (<div className='flex justify-center items-center'>Checkout</div>)}
|
117
|
-
<IconAndQuantity
|
118
|
-
clx='group-hover:scale-105 transition-scale transition-duration-300'
|
119
|
-
animateOnQuantityChange={animateOnQuantityChange}
|
120
|
-
showArrow={showArrow}
|
121
|
-
showQuantity={showQuantity}
|
122
|
-
iconClx='fill-background'
|
123
|
-
digitClx='text-foreground group-hover:opacity-80 leading-none font-bold font-sans'
|
124
|
-
/>
|
125
112
|
</Button>
|
126
113
|
)
|
127
114
|
}
|
@@ -1,104 +1,18 @@
|
|
1
1
|
'use client'
|
2
|
-
import React
|
2
|
+
import React from 'react'
|
3
3
|
import { createPortal } from 'react-dom'
|
4
4
|
import { usePathname, useRouter } from 'next/navigation'
|
5
5
|
import { observer } from 'mobx-react-lite'
|
6
6
|
|
7
7
|
import { cn } from '@hanzo/ui/util'
|
8
|
-
import { useStepAnimation } from '@hanzo/ui/util-client'
|
9
|
-
|
10
8
|
import { Image } from '@hanzo/ui/primitives'
|
11
9
|
|
12
|
-
import { useCommerceUI } from '
|
10
|
+
import { useCommerceUI } from '@hanzo/commerce'
|
13
11
|
|
14
12
|
import CheckoutButton from '../checkout-button'
|
15
13
|
import useAnimationClxSet from './use-anim-clx-set'
|
14
|
+
import useLaggingItemRef from './use-lagging-item-ref'
|
16
15
|
import CONST from './const'
|
17
|
-
import type { LineItem } from '@hanzo/commerce/types'
|
18
|
-
|
19
|
-
const transStyle = (t: { transition: string, from : string, to: string } | undefined) : any => (
|
20
|
-
t ? {
|
21
|
-
transitionProperty: t.transition,
|
22
|
-
transitionTimingFunction: CONST.animTimingFn,
|
23
|
-
transitionDuration: `${CONST.animDurationMs}ms`
|
24
|
-
} : {}
|
25
|
-
)
|
26
|
-
|
27
|
-
const transClx = (on: boolean, t: { transition: string, from : string, to: string } | undefined) : string => (
|
28
|
-
on ? (t?.from ?? '') : (t?.to ?? '')
|
29
|
-
)
|
30
|
-
|
31
|
-
const VARS: any = {
|
32
|
-
BR: {
|
33
|
-
pos: 'bottom-[24px] right-[66px]',
|
34
|
-
width: 'w-initial',
|
35
|
-
centerText: false,
|
36
|
-
coClx: 'w-auto',
|
37
|
-
infoClx: 'w-auto',
|
38
|
-
activeItemAnim: {
|
39
|
-
co: {
|
40
|
-
transition: 'none',
|
41
|
-
from : 'px-3 gap-2.5',
|
42
|
-
to: ''
|
43
|
-
},
|
44
|
-
coText: {
|
45
|
-
transition: 'max-width',
|
46
|
-
from : 'max-w-[100px]',
|
47
|
-
to: 'max-w-[0px]'
|
48
|
-
},
|
49
|
-
info: {
|
50
|
-
transition: 'transform, opacity',
|
51
|
-
from : 'scale-x-100 opacity-100 origin-right',
|
52
|
-
to: 'scale-x-0 opacity-0 origin-right'
|
53
|
-
}
|
54
|
-
},
|
55
|
-
showArrow: true
|
56
|
-
},
|
57
|
-
TR: {
|
58
|
-
pos: 'top-[48px] md:top-[80px] right-[28px]',
|
59
|
-
width: 'w-initial',
|
60
|
-
centerText: false,
|
61
|
-
showQuantity: false,
|
62
|
-
showArrow: true,
|
63
|
-
coClx: 'w-auto px-3 gap-1',
|
64
|
-
infoClx: 'w-auto',
|
65
|
-
activeItemAnim: {
|
66
|
-
co: {
|
67
|
-
transition: 'none',
|
68
|
-
from : 'px-3 gap-2.5',
|
69
|
-
to: ''
|
70
|
-
},
|
71
|
-
coText: {
|
72
|
-
transition: 'max-width',
|
73
|
-
from : 'max-w-[100px]',
|
74
|
-
to: 'max-w-[0px]'
|
75
|
-
},
|
76
|
-
info: {
|
77
|
-
transition: 'transform',
|
78
|
-
from : 'scale-x-100 origin-right',
|
79
|
-
to: 'scale-x-0 origin-right'
|
80
|
-
}
|
81
|
-
},
|
82
|
-
},
|
83
|
-
TRIO: {
|
84
|
-
pos: 'top-[48px] md:top-[70px] right-[28px]',
|
85
|
-
centerText: false,
|
86
|
-
showQuantity: true,
|
87
|
-
showArrow: true,
|
88
|
-
width: 'w-initial',
|
89
|
-
coClx: 'hidden',
|
90
|
-
infoClx: 'w-auto',
|
91
|
-
activeItemAnim: {
|
92
|
-
info: {
|
93
|
-
transition: 'transform, opacity',
|
94
|
-
from : 'scale-x-100 opacity-100',
|
95
|
-
to: 'scale-x-50 opacity-0'
|
96
|
-
}
|
97
|
-
},
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
const v = 'TR'
|
102
16
|
|
103
17
|
const CheckoutWidget: React.FC<{
|
104
18
|
clx?: string
|
@@ -112,78 +26,58 @@ const CheckoutWidget: React.FC<{
|
|
112
26
|
const clxSet = useAnimationClxSet(isCheckout)
|
113
27
|
|
114
28
|
const itemRef = useCommerceUI()
|
115
|
-
|
116
|
-
// for rendering content after itemRef.item() would return false
|
117
|
-
const persistentRef = useRef<LineItem | undefined>(undefined)
|
118
|
-
|
119
|
-
// Doing double duty of being initial step fn for StepAnimation,
|
120
|
-
// and also capturing the item for persistentRef :)
|
121
|
-
const initialStepFn = (): boolean => {
|
122
|
-
if (!!itemRef.item && !persistentRef.current) {
|
123
|
-
persistentRef.current = itemRef.item
|
124
|
-
}
|
125
|
-
return !!itemRef.item
|
126
|
-
}
|
127
|
-
const steps = useStepAnimation(initialStepFn, [CONST.animDurationMs, CONST.animDurationMs, CONST.animDurationMs])
|
29
|
+
const laggingRef = useLaggingItemRef(itemRef, CONST.animDurationMs)
|
128
30
|
|
129
31
|
const handleCheckout = () => { router.push('/checkout')}
|
130
32
|
|
131
33
|
return globalThis?.document?.body && createPortal(
|
132
34
|
(<div
|
133
35
|
className={cn(
|
134
|
-
|
135
|
-
'z-below-modal-2 fixed ',
|
136
|
-
|
137
|
-
'rounded-lg',
|
36
|
+
'min-w-[160px] sm:max-w-[320px] w-[calc(100%-72px)] ml-2 !h-10',
|
37
|
+
'z-below-modal-2 fixed bottom-[20px] left-0 right-0',
|
38
|
+
'rounded-lg bg-background',
|
138
39
|
'flex',
|
139
|
-
|
140
|
-
steps.notPast(1) ? 'gap-2' : '',
|
40
|
+
itemRef.item ? 'gap-2' : '',
|
141
41
|
clxSet.asArray.join(' ')
|
142
42
|
)}
|
143
|
-
style={
|
43
|
+
style={laggingRef.item ? {} : CONST.shadowStyle}
|
144
44
|
>
|
145
45
|
<div
|
146
46
|
className={cn(
|
147
47
|
'flex flex-row justify-between items-center',
|
148
|
-
|
149
|
-
|
150
|
-
steps.notPast(1) ? 'px-3 border rounded-lg bg-level-1 border-muted-3' : ''
|
48
|
+
itemRef.item ? CONST.compWidthClx.itemInfo : 'w-0',
|
49
|
+
laggingRef.item ? 'px-3 border rounded-lg border-muted-3' : ''
|
151
50
|
)}
|
152
|
-
style={
|
51
|
+
style={{
|
52
|
+
transitionProperty: 'width',
|
53
|
+
transitionTimingFunction: CONST.animTimingFn,
|
54
|
+
transitionDuration: `${CONST.animDurationMs}ms`
|
55
|
+
}}
|
153
56
|
>
|
154
|
-
{
|
155
|
-
<Image def={
|
156
|
-
)
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
57
|
+
{laggingRef.item?.img ? (
|
58
|
+
<Image def={laggingRef.item.img} constrainTo={CONST.itemImgConstraint} preload className='grow-0 shrink-0'/>
|
59
|
+
) : ( // placeholder so things align
|
60
|
+
<div style={{height: CONST.itemImgConstraint.h, width: CONST.itemImgConstraint.w}} className='bg-level-3 grow-0 shrink-0'/>
|
61
|
+
)}
|
62
|
+
|
63
|
+
<div className='text-muted grow ml-1'>
|
64
|
+
{laggingRef.item && (<>
|
65
|
+
<p className='whitespace-nowrap text-sm'>{laggingRef.item.title}</p>
|
66
|
+
<p className='whitespace-nowrap text-xxs' >recently added...</p>
|
67
|
+
</>)}
|
68
|
+
</div>
|
161
69
|
</div>
|
162
70
|
<CheckoutButton
|
163
71
|
handleCheckout={handleCheckout}
|
164
|
-
centerText={
|
165
|
-
variant='primary'
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
)}
|
174
|
-
style={transStyle(VARS[v].activeItemAnim.co)}
|
175
|
-
>
|
176
|
-
<div
|
177
|
-
className={cn(
|
178
|
-
'overflow-hidden',
|
179
|
-
'flex justify-center items-center',
|
180
|
-
transClx(steps.notPast(2), VARS[v].activeItemAnim.coText),
|
181
|
-
)}
|
182
|
-
style={transStyle(VARS[v].activeItemAnim.coText)}
|
183
|
-
>
|
184
|
-
Checkout
|
185
|
-
</div>
|
186
|
-
</CheckoutButton>
|
72
|
+
centerText={!!!itemRef.item}
|
73
|
+
variant='primary' rounded='lg'
|
74
|
+
className={cn(itemRef.item ? CONST.compWidthClx.checkout : 'w-full')}
|
75
|
+
style={{
|
76
|
+
transitionProperty: 'width',
|
77
|
+
transitionTimingFunction: CONST.animTimingFn,
|
78
|
+
transitionDuration: `${CONST.animDurationMs}ms`
|
79
|
+
}}
|
80
|
+
/>
|
187
81
|
</div>),
|
188
82
|
globalThis?.document?.body
|
189
83
|
)
|
@@ -1,10 +1,8 @@
|
|
1
1
|
import { useEffect, useRef } from 'react'
|
2
2
|
import { reaction, runInAction} from 'mobx'
|
3
3
|
|
4
|
-
import { useCommerce } from '@hanzo/commerce'
|
5
|
-
|
6
4
|
import ObsStringSet from './obs-string-set'
|
7
|
-
import { useCommerceUI } from '
|
5
|
+
import { useCommerce, useCommerceUI } from '@hanzo/commerce'
|
8
6
|
|
9
7
|
export default (isCheckout: boolean): ObsStringSet => {
|
10
8
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
2
|
+
import { reaction } from 'mobx'
|
3
|
+
|
4
|
+
import type { LineItem, ObsLineItemRef } from "@hanzo/commerce/types"
|
5
|
+
import { LineItemRef } from '@hanzo/commerce'
|
6
|
+
|
7
|
+
export default (orig: ObsLineItemRef, lagMs: number): ObsLineItemRef => {
|
8
|
+
|
9
|
+
// a ref that is synced to 'orig', but persists for lagMs longer
|
10
|
+
// so ui does not jump while animating out.
|
11
|
+
// (Fascilitates for start and end states in animation)
|
12
|
+
const laggingRef = useRef<LineItemRef>(new LineItemRef())
|
13
|
+
|
14
|
+
useEffect(() => (
|
15
|
+
reaction(
|
16
|
+
() => (orig.item),
|
17
|
+
(item: LineItem | undefined) => {
|
18
|
+
if (item) {
|
19
|
+
laggingRef.current.set(item)
|
20
|
+
}
|
21
|
+
else {
|
22
|
+
setTimeout(() => { laggingRef.current.set(undefined) }, lagMs)
|
23
|
+
}
|
24
|
+
},
|
25
|
+
{equals: (val, prev) => (val?.sku === prev?.sku)}
|
26
|
+
)
|
27
|
+
), [])
|
28
|
+
|
29
|
+
return laggingRef.current
|
30
|
+
}
|
@@ -29,7 +29,7 @@ const DesktopHeader: React.FC<{
|
|
29
29
|
{/* md or larger */}
|
30
30
|
<div className={
|
31
31
|
'flex flex-row h-[80px] items-center justify-between ' +
|
32
|
-
'px-[
|
32
|
+
'px-[8px] w-full mx-auto max-w-screen'
|
33
33
|
}>
|
34
34
|
<Logo size='md' href='/' className='hidden lg:flex' key='two' layout='text-only'/>
|
35
35
|
<Logo size='sm' href='/' className='hidden md:flex lg:hidden' key='one' layout='text-only'/>
|
package/components/index.ts
CHANGED
@@ -10,12 +10,18 @@ export { default as MiniChart } from './mini-chart'
|
|
10
10
|
export { default as NotFound } from './not-found'
|
11
11
|
|
12
12
|
export { default as AuthListener } from './auth/auth-listener'
|
13
|
-
export { default as AddWidget } from './commerce/add-widget'
|
14
13
|
export { default as BuyDrawer } from './commerce/buy-drawer'
|
15
|
-
export { default as BuyButton } from './commerce/buy-button'
|
16
14
|
export { default as CheckoutButton } from './commerce/checkout-button'
|
17
15
|
export { default as CheckoutPanel } from './commerce/checkout-panel'
|
18
16
|
export { default as CheckoutWidget } from './commerce/checkout-widget'
|
19
17
|
export { default as LoginPanel } from './auth/login-panel'
|
20
18
|
export { default as Scripts } from './scripts'
|
21
19
|
|
20
|
+
|
21
|
+
/* PLEASE KEEP
|
22
|
+
export {
|
23
|
+
default as HeadMetadata,
|
24
|
+
getTitleFromTemplateString,
|
25
|
+
TwitterComponent
|
26
|
+
} from './head-metadata'
|
27
|
+
*/
|
package/conf/index.ts
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@luxfi/core",
|
3
|
-
"version": "5.
|
3
|
+
"version": "5.1.1",
|
4
4
|
"description": "Library that contains shared UI primitives, support for a common design system, and other boilerplate support.",
|
5
5
|
"publishConfig": {
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
@@ -28,7 +28,6 @@
|
|
28
28
|
"exports": {
|
29
29
|
".": "./components/index.ts",
|
30
30
|
"./commerce": "./commerce/index.ts",
|
31
|
-
"./commerce-data": "./commerce/data/index.ts",
|
32
31
|
"./root-layout": "./root-layout/index.tsx",
|
33
32
|
"./server-actions": "./server-actions/index.ts",
|
34
33
|
"./next": "./next/index.ts",
|
@@ -39,9 +38,10 @@
|
|
39
38
|
},
|
40
39
|
"dependencies": {
|
41
40
|
"@hanzo/auth": "2.4.6",
|
42
|
-
"@hanzo/commerce": "7.0.
|
43
|
-
"@hanzo/ui": "3.7.
|
41
|
+
"@hanzo/commerce": "7.0.2",
|
42
|
+
"@hanzo/ui": "3.7.0",
|
44
43
|
"@next/third-parties": "^14.1.0",
|
44
|
+
"@types/node": "^20.12.12",
|
45
45
|
"cookies-next": "^4.1.1",
|
46
46
|
"date-fns": "^3.6.0",
|
47
47
|
"embla-carousel-autoplay": "^8.0.1",
|
@@ -51,15 +51,13 @@
|
|
51
51
|
"peerDependencies": {
|
52
52
|
"@hookform/resolvers": "^3.3.2",
|
53
53
|
"lucide-react": "^0.344.0",
|
54
|
-
"mobx": "^6.12.0",
|
55
|
-
"mobx-react-lite": "^4.0.5",
|
56
54
|
"next": "14.1.3",
|
57
55
|
"next-themes": "^0.2.1",
|
58
|
-
"react": "^18.
|
59
|
-
"react-dom": "^18.
|
60
|
-
"react-hook-form": "^7.
|
56
|
+
"react": "^18.2.0",
|
57
|
+
"react-dom": "^18.2.0",
|
58
|
+
"react-hook-form": "^7.44.2",
|
61
59
|
"validator": "^13.11.0",
|
62
|
-
"zod": "3.
|
60
|
+
"zod": "3.21.4"
|
63
61
|
},
|
64
62
|
"devDependencies": {
|
65
63
|
"@mdx-js/loader": "^3.0.0",
|
@@ -67,8 +65,8 @@
|
|
67
65
|
"@types/facebook-pixel": "^0.0.30",
|
68
66
|
"@types/gtag.js": "^0.0.19",
|
69
67
|
"@types/mdx": "^2.0.9",
|
70
|
-
"@types/react": "^18.
|
71
|
-
"@types/react-dom": "^18.
|
68
|
+
"@types/react": "^18.2.64",
|
69
|
+
"@types/react-dom": "^18.2.18",
|
72
70
|
"tailwindcss": "^3.4.2",
|
73
71
|
"typescript": "5.3.3"
|
74
72
|
}
|
package/root-layout/index.tsx
CHANGED
@@ -10,10 +10,9 @@ import { CommerceProvider } from '@hanzo/commerce'
|
|
10
10
|
import getAppRouterBodyFontClasses from '../next/font/get-app-router-font-classes'
|
11
11
|
import { FacebookPixelHead } from '../next/analytics/pixel-analytics'
|
12
12
|
|
13
|
-
import { CommerceUIProvider } from '../commerce/ui-context'
|
14
13
|
import { AuthListener, ChatWidget, Header, Scripts } from '../components'
|
15
|
-
|
16
14
|
import BuyDrawer from '../components/commerce/buy-drawer'
|
15
|
+
import CheckoutWidget from '../components/commerce/checkout-widget'
|
17
16
|
|
18
17
|
import { selectionUISpecifiers } from '../conf'
|
19
18
|
import type SiteDef from '../types/site-def'
|
@@ -100,10 +99,9 @@ const RootLayout: React.FC<PropsWithChildren & {
|
|
100
99
|
options={siteDef.commerce!.options}
|
101
100
|
uiSpecs={selectionUISpecifiers}
|
102
101
|
>
|
103
|
-
<
|
104
|
-
|
105
|
-
|
106
|
-
</CommerceUIProvider>
|
102
|
+
<Guts />
|
103
|
+
<BuyDrawer />
|
104
|
+
<CheckoutWidget />
|
107
105
|
</CommerceProvider>
|
108
106
|
) : (
|
109
107
|
<Guts />
|
package/tsconfig.json
CHANGED
@@ -1,118 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
action,
|
3
|
-
computed,
|
4
|
-
makeObservable,
|
5
|
-
observable,
|
6
|
-
} from 'mobx'
|
7
|
-
import type { CommerceService, LineItem, ObsLineItemRef } from '@hanzo/commerce/types'
|
8
|
-
|
9
|
-
|
10
|
-
interface CommerceUI extends ObsLineItemRef {
|
11
|
-
showBuyOptions: (skuPath: string) => void
|
12
|
-
hideBuyOptions: () => void
|
13
|
-
get buyOptionsSkuPath(): string | undefined
|
14
|
-
|
15
|
-
itemQuantityChanged(sku: string, val: number, prevVal: number): void
|
16
|
-
|
17
|
-
get closed(): boolean
|
18
|
-
setClosed(b: boolean): void
|
19
|
-
|
20
|
-
}
|
21
|
-
|
22
|
-
class CommerceUIStore implements CommerceUI {
|
23
|
-
|
24
|
-
static readonly TIMEOUT = 1500
|
25
|
-
_buyOptionsSkuPath: string | undefined = undefined
|
26
|
-
_closed: boolean = false
|
27
|
-
_paused: boolean = false
|
28
|
-
_activeItem: LineItem | undefined = undefined
|
29
|
-
_lastActivity: number | undefined = undefined
|
30
|
-
_service: CommerceService
|
31
|
-
|
32
|
-
constructor(s: CommerceService) {
|
33
|
-
this._service = s
|
34
|
-
makeObservable(this, {
|
35
|
-
_buyOptionsSkuPath: observable,
|
36
|
-
_activeItem: observable.shallow,
|
37
|
-
_closed: observable,
|
38
|
-
showBuyOptions: action,
|
39
|
-
hideBuyOptions: action,
|
40
|
-
buyOptionsSkuPath: computed,
|
41
|
-
itemQuantityChanged: action,
|
42
|
-
setClosed: action,
|
43
|
-
closed: computed,
|
44
|
-
tick: action,
|
45
|
-
item: computed
|
46
|
-
})
|
47
|
-
}
|
48
|
-
|
49
|
-
showBuyOptions = (skuPath: string): void => {
|
50
|
-
this._service.setCurrentItem(undefined)
|
51
|
-
this._buyOptionsSkuPath = skuPath
|
52
|
-
this._paused = true
|
53
|
-
this._closed = false
|
54
|
-
}
|
55
|
-
|
56
|
-
hideBuyOptions = (): void => {
|
57
|
-
this._buyOptionsSkuPath = undefined
|
58
|
-
this._paused = false
|
59
|
-
if (this._lastActivity) {
|
60
|
-
this._lastActivity = Date.now()
|
61
|
-
}
|
62
|
-
}
|
63
|
-
|
64
|
-
get buyOptionsSkuPath(): string | undefined {
|
65
|
-
return this._buyOptionsSkuPath
|
66
|
-
}
|
67
|
-
|
68
|
-
tick = () => {
|
69
|
-
if (
|
70
|
-
!this._paused
|
71
|
-
&&
|
72
|
-
this._lastActivity
|
73
|
-
&&
|
74
|
-
(Date.now() - this._lastActivity >= CommerceUIStore.TIMEOUT)
|
75
|
-
) {
|
76
|
-
this._activeItem = undefined
|
77
|
-
this._lastActivity = undefined
|
78
|
-
}
|
79
|
-
}
|
80
|
-
|
81
|
-
itemQuantityChanged = (sku: string, val: number, oldVal: number): void => {
|
82
|
-
|
83
|
-
if (val === 0) {
|
84
|
-
if (this._activeItem?.sku === sku) {
|
85
|
-
this._activeItem = undefined
|
86
|
-
this._lastActivity = undefined
|
87
|
-
}
|
88
|
-
// otherwise ignore
|
89
|
-
}
|
90
|
-
else if (val < oldVal) {
|
91
|
-
if (this._activeItem?.sku === sku) {
|
92
|
-
this._lastActivity = Date.now()
|
93
|
-
}
|
94
|
-
// otherwise ignore
|
95
|
-
}
|
96
|
-
else {
|
97
|
-
this._activeItem = this._service.getItemBySku(sku)
|
98
|
-
this._lastActivity = Date.now()
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
get item(): LineItem | undefined {
|
103
|
-
return this._activeItem
|
104
|
-
}
|
105
|
-
|
106
|
-
get closed(): boolean {
|
107
|
-
return this._closed
|
108
|
-
}
|
109
|
-
|
110
|
-
setClosed = (b: boolean): void => { this._closed = b}
|
111
|
-
|
112
|
-
dispose = () => {}
|
113
|
-
}
|
114
|
-
|
115
|
-
export {
|
116
|
-
CommerceUIStore,
|
117
|
-
type CommerceUI
|
118
|
-
}
|
@@ -1,50 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
import React, {
|
3
|
-
createContext,
|
4
|
-
useContext,
|
5
|
-
useRef,
|
6
|
-
type PropsWithChildren,
|
7
|
-
useEffect
|
8
|
-
} from 'react'
|
9
|
-
|
10
|
-
// https://dev.to/ivandotv/mobx-server-side-rendering-with-next-js-4m18
|
11
|
-
import { enableStaticRendering } from 'mobx-react-lite'
|
12
|
-
enableStaticRendering(typeof window === "undefined")
|
13
|
-
|
14
|
-
import { type CommerceUI, CommerceUIStore } from './commerce-ui'
|
15
|
-
import { useCommerce } from '@hanzo/commerce'
|
16
|
-
|
17
|
-
const CommerceUIContext = createContext<CommerceUIStore | undefined>(undefined)
|
18
|
-
|
19
|
-
const useCommerceUI = (): CommerceUI => {
|
20
|
-
return useContext(CommerceUIContext) as CommerceUIStore
|
21
|
-
}
|
22
|
-
|
23
|
-
const CommerceUIProvider: React.FC<PropsWithChildren & {
|
24
|
-
DEBUG_NO_TICK?: boolean
|
25
|
-
}> = ({
|
26
|
-
children,
|
27
|
-
DEBUG_NO_TICK=false
|
28
|
-
}) => {
|
29
|
-
|
30
|
-
const cmmc = useCommerce()
|
31
|
-
const valueRef = useRef<CommerceUIStore>(new CommerceUIStore(cmmc))
|
32
|
-
|
33
|
-
useEffect(() => {
|
34
|
-
|
35
|
-
//valueRef.current = new CommerceUIStore(cmmc)
|
36
|
-
return () => { valueRef.current?.dispose() }
|
37
|
-
}, [])
|
38
|
-
|
39
|
-
return (
|
40
|
-
<CommerceUIContext.Provider value={valueRef.current}>
|
41
|
-
{children}
|
42
|
-
</CommerceUIContext.Provider>
|
43
|
-
)
|
44
|
-
}
|
45
|
-
|
46
|
-
export {
|
47
|
-
useCommerceUI,
|
48
|
-
CommerceUIProvider
|
49
|
-
}
|
50
|
-
|
@@ -1,20 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
import React from 'react'
|
3
|
-
|
4
|
-
import type { LineItem } from '@hanzo/commerce/types'
|
5
|
-
import { AddToCartWidget } from '@hanzo/commerce'
|
6
|
-
|
7
|
-
import { useCommerceUI } from '../../commerce/ui-context'
|
8
|
-
|
9
|
-
const AddWidget: React.FC<{
|
10
|
-
item: LineItem
|
11
|
-
disabled?: boolean
|
12
|
-
className?: string
|
13
|
-
buttonClx?: string
|
14
|
-
variant?: 'minimal' | 'primary' | 'outline'
|
15
|
-
}> = (props) => {
|
16
|
-
const ui = useCommerceUI()
|
17
|
-
return <AddToCartWidget {...props} onQuantityChanged={ui.itemQuantityChanged}/>
|
18
|
-
}
|
19
|
-
|
20
|
-
export default AddWidget
|
@@ -1,34 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
import React, {type PropsWithChildren} from 'react'
|
3
|
-
|
4
|
-
import { Button, buttonVariants } from '@hanzo/ui/primitives'
|
5
|
-
import { type VariantProps } from '@hanzo/ui/util'
|
6
|
-
|
7
|
-
import { cn } from '@hanzo/ui/util'
|
8
|
-
import { useCommerceUI } from '../../commerce/ui-context'
|
9
|
-
|
10
|
-
const BuyButton: React.FC<
|
11
|
-
PropsWithChildren &
|
12
|
-
VariantProps<typeof buttonVariants> &
|
13
|
-
{
|
14
|
-
skuPath: string
|
15
|
-
className?: string
|
16
|
-
}
|
17
|
-
> = ({
|
18
|
-
skuPath,
|
19
|
-
children,
|
20
|
-
className='',
|
21
|
-
...rest
|
22
|
-
}) => {
|
23
|
-
|
24
|
-
const ui = useCommerceUI()
|
25
|
-
const handleClick = () => { ui.showBuyOptions(skuPath) }
|
26
|
-
|
27
|
-
return (
|
28
|
-
<Button onClick={handleClick} {...rest} className={cn(className, '')}>
|
29
|
-
{children}
|
30
|
-
</Button>
|
31
|
-
)
|
32
|
-
}
|
33
|
-
|
34
|
-
export default BuyButton
|
@@ -1,154 +0,0 @@
|
|
1
|
-
[vaul-drawer] {
|
2
|
-
touch-action: none;
|
3
|
-
transition: transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
|
4
|
-
}
|
5
|
-
|
6
|
-
[vaul-drawer][vaul-drawer-direction='bottom'] {
|
7
|
-
transform: translate3d(0, 100%, 0);
|
8
|
-
}
|
9
|
-
|
10
|
-
[vaul-drawer][vaul-drawer-direction='top'] {
|
11
|
-
transform: translate3d(0, -100%, 0);
|
12
|
-
}
|
13
|
-
|
14
|
-
[vaul-drawer][vaul-drawer-direction='left'] {
|
15
|
-
transform: translate3d(-100%, 0, 0);
|
16
|
-
}
|
17
|
-
|
18
|
-
[vaul-drawer][vaul-drawer-direction='right'] {
|
19
|
-
transform: translate3d(100%, 0, 0);
|
20
|
-
}
|
21
|
-
|
22
|
-
.vaul-dragging .vaul-scrollable [vault-drawer-direction='top'] {
|
23
|
-
overflow-y: hidden !important;
|
24
|
-
}
|
25
|
-
.vaul-dragging .vaul-scrollable [vault-drawer-direction='bottom'] {
|
26
|
-
overflow-y: hidden !important;
|
27
|
-
}
|
28
|
-
|
29
|
-
.vaul-dragging .vaul-scrollable [vault-drawer-direction='left'] {
|
30
|
-
overflow-x: hidden !important;
|
31
|
-
}
|
32
|
-
|
33
|
-
.vaul-dragging .vaul-scrollable [vault-drawer-direction='right'] {
|
34
|
-
overflow-x: hidden !important;
|
35
|
-
}
|
36
|
-
|
37
|
-
[vaul-drawer][vaul-drawer-visible='true'][vaul-drawer-direction='top'] {
|
38
|
-
transform: translate3d(0, var(--snap-point-height, 0), 0);
|
39
|
-
}
|
40
|
-
|
41
|
-
[vaul-drawer][vaul-drawer-visible='true'][vaul-drawer-direction='bottom'] {
|
42
|
-
transform: translate3d(0, var(--snap-point-height, 0), 0);
|
43
|
-
}
|
44
|
-
|
45
|
-
[vaul-drawer][vaul-drawer-visible='true'][vaul-drawer-direction='left'] {
|
46
|
-
transform: translate3d(var(--snap-point-height, 0), 0, 0);
|
47
|
-
}
|
48
|
-
|
49
|
-
[vaul-drawer][vaul-drawer-visible='true'][vaul-drawer-direction='right'] {
|
50
|
-
transform: translate3d(var(--snap-point-height, 0), 0, 0);
|
51
|
-
}
|
52
|
-
|
53
|
-
[vaul-overlay] {
|
54
|
-
opacity: 0;
|
55
|
-
transition: opacity 0.5s cubic-bezier(0.32, 0.72, 0, 1);
|
56
|
-
}
|
57
|
-
|
58
|
-
[vaul-overlay][vaul-drawer-visible='true'] {
|
59
|
-
opacity: 1;
|
60
|
-
}
|
61
|
-
|
62
|
-
[vaul-drawer]::after {
|
63
|
-
content: '';
|
64
|
-
position: absolute;
|
65
|
-
background: inherit;
|
66
|
-
background-color: inherit;
|
67
|
-
}
|
68
|
-
|
69
|
-
[vaul-drawer][vaul-drawer-direction='top']::after {
|
70
|
-
top: initial;
|
71
|
-
bottom: 100%;
|
72
|
-
left: 0;
|
73
|
-
right: 0;
|
74
|
-
height: 200%;
|
75
|
-
}
|
76
|
-
|
77
|
-
[vaul-drawer][vaul-drawer-direction='bottom']::after {
|
78
|
-
top: 100%;
|
79
|
-
bottom: initial;
|
80
|
-
left: 0;
|
81
|
-
right: 0;
|
82
|
-
height: 200%;
|
83
|
-
}
|
84
|
-
|
85
|
-
[vaul-drawer][vaul-drawer-direction='left']::after {
|
86
|
-
left: initial;
|
87
|
-
right: 100%;
|
88
|
-
top: 0;
|
89
|
-
bottom: 0;
|
90
|
-
width: 200%;
|
91
|
-
}
|
92
|
-
|
93
|
-
[vaul-drawer][vaul-drawer-direction='right']::after {
|
94
|
-
left: 100%;
|
95
|
-
right: initial;
|
96
|
-
top: 0;
|
97
|
-
bottom: 0;
|
98
|
-
width: 200%;
|
99
|
-
}
|
100
|
-
|
101
|
-
[vaul-handle] {
|
102
|
-
/* opacity: 0.8; */
|
103
|
-
touch-action: pan-y;
|
104
|
-
cursor: grab;
|
105
|
-
}
|
106
|
-
|
107
|
-
/* [vaul-handle]:hover, */
|
108
|
-
[vaul-handle]:active {
|
109
|
-
opacity: 1;
|
110
|
-
}
|
111
|
-
|
112
|
-
[vaul-handle]:active {
|
113
|
-
cursor: grabbing;
|
114
|
-
}
|
115
|
-
|
116
|
-
[vaul-handle-hitarea] {
|
117
|
-
position: absolute;
|
118
|
-
left: 50%;
|
119
|
-
top: 50%;
|
120
|
-
transform: translate(-50%, -50%);
|
121
|
-
width: max(100%, 2.75rem); /* 44px */
|
122
|
-
height: max(100%, 2.75rem); /* 44px */
|
123
|
-
touch-action: inherit;
|
124
|
-
}
|
125
|
-
|
126
|
-
[vaul-overlay][vaul-snap-points='true']:not([vaul-snap-points-overlay='true']):not([data-state='closed']) {
|
127
|
-
opacity: 0;
|
128
|
-
}
|
129
|
-
|
130
|
-
[vaul-overlay][vaul-snap-points-overlay='true']:not([vaul-drawer-visible='false']) {
|
131
|
-
opacity: 1;
|
132
|
-
}
|
133
|
-
|
134
|
-
/* This will allow us to not animate via animation, but still benefit from delaying unmount via Radix. */
|
135
|
-
@keyframes fake-animation {
|
136
|
-
from {
|
137
|
-
}
|
138
|
-
to {
|
139
|
-
}
|
140
|
-
}
|
141
|
-
|
142
|
-
@media (pointer: fine) {
|
143
|
-
[vaul-handle-hitarea] {
|
144
|
-
width: 100%;
|
145
|
-
height: 100%;
|
146
|
-
}
|
147
|
-
}
|
148
|
-
|
149
|
-
@media (hover: hover) and (pointer: fine) {
|
150
|
-
[vaul-drawer] {
|
151
|
-
user-select: none;
|
152
|
-
}
|
153
|
-
}
|
154
|
-
|
File without changes
|
/package/commerce/{data/EDIT-ME-bullion-market-prices.ts → EDIT-ME-bullion-market-prices.ts}
RENAMED
File without changes
|
File without changes
|
/package/commerce/{data/assign-videos-by-family-group.ts → assign-videos-by-family-group.ts}
RENAMED
File without changes
|
File without changes
|
File without changes
|