@hanzo/commerce 7.1.5 → 7.1.7

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.
Files changed (84) hide show
  1. package/components/Icons.tsx +34 -34
  2. package/components/add-to-cart-widget.tsx +181 -181
  3. package/components/buy/buy-card.tsx +259 -259
  4. package/components/buy/carousel-buy-card.tsx +245 -245
  5. package/components/buy/multi-family/all-variants-carousel.tsx +261 -261
  6. package/components/buy/multi-family/family-carousel/index.tsx +77 -77
  7. package/components/buy/multi-family/family-carousel/slide.tsx +83 -83
  8. package/components/buy/multi-family/family-carousel/state.ts +87 -87
  9. package/components/buy/multi-family/index.ts +2 -2
  10. package/components/buy/single-family-selector.tsx +90 -90
  11. package/components/buy/title-and-byline.tsx +25 -25
  12. package/components/cart/cart-accordian.tsx +59 -59
  13. package/components/cart/cart-panel/cart-line-item.tsx +76 -76
  14. package/components/cart/cart-panel/index.tsx +161 -159
  15. package/components/cart/cart-panel/promo-code.tsx +98 -98
  16. package/components/checkout/payment-step-form/card-icon-row.tsx +26 -26
  17. package/components/checkout/payment-step-form/card-icons/amex.tsx +32 -32
  18. package/components/checkout/payment-step-form/card-icons/diners-club.tsx +13 -13
  19. package/components/checkout/payment-step-form/card-icons/discover.tsx +25 -25
  20. package/components/checkout/payment-step-form/card-icons/jcb.tsx +26 -26
  21. package/components/checkout/payment-step-form/card-icons/mastercard.tsx +27 -27
  22. package/components/checkout/payment-step-form/card-icons/visa.tsx +25 -25
  23. package/components/checkout/payment-step-form/cc-button.tsx +17 -17
  24. package/components/checkout/payment-step-form/contact-form.tsx +49 -49
  25. package/components/checkout/payment-step-form/crypto-icons/btc.tsx +11 -11
  26. package/components/checkout/payment-step-form/crypto-icons/eth.tsx +20 -20
  27. package/components/checkout/payment-step-form/crypto-icons/usdt.tsx +13 -13
  28. package/components/checkout/payment-step-form/index.tsx +122 -122
  29. package/components/checkout/payment-step-form/methods/bank-transfer.tsx +79 -79
  30. package/components/checkout/payment-step-form/methods/card.tsx +232 -232
  31. package/components/checkout/payment-step-form/methods/crypto.tsx +227 -227
  32. package/components/checkout/payment-step-form/methods/index.ts +22 -22
  33. package/components/checkout/shipping-step-form.tsx +172 -172
  34. package/components/index.ts +12 -12
  35. package/components/item/product-card.tsx +48 -48
  36. package/components/item-selector/button.tsx +188 -188
  37. package/components/item-selector/carousel/index.tsx +197 -197
  38. package/components/item-selector/carousel/slider.tsx +40 -40
  39. package/components/item-selector/index.ts +5 -5
  40. package/components/item-selector/quantity-indicator.tsx +48 -48
  41. package/components/node-tabs/index.tsx +91 -91
  42. package/components/node-tabs/node-image.tsx +31 -31
  43. package/context/index.tsx +45 -45
  44. package/index.ts +12 -12
  45. package/package.json +60 -60
  46. package/service/debug.ts +41 -41
  47. package/service/get-instance.ts +2 -2
  48. package/service/impls/standalone/actual-line-item.ts +121 -121
  49. package/service/impls/standalone/index.ts +62 -62
  50. package/service/impls/standalone/localStorage.ts +34 -34
  51. package/service/impls/standalone/orders/firebase-app.ts +14 -14
  52. package/service/impls/standalone/orders/index.ts +128 -128
  53. package/service/impls/standalone/standalone-service.ts +550 -550
  54. package/service/path-utils.ts +25 -25
  55. package/service/sep.ts +6 -6
  56. package/tsconfig.json +10 -10
  57. package/types/README.md +1 -1
  58. package/types/category-node.ts +49 -49
  59. package/types/checkout.ts +46 -46
  60. package/types/commerce-config.ts +13 -13
  61. package/types/commerce-service.ts +121 -121
  62. package/types/family.ts +25 -25
  63. package/types/index.ts +15 -15
  64. package/types/item-selector.ts +96 -96
  65. package/types/line-item.ts +29 -29
  66. package/types/multi-family-selector-props.ts +19 -19
  67. package/types/product.ts +20 -20
  68. package/types/promo.ts +9 -9
  69. package/types/selection-ui-specifier.ts +51 -51
  70. package/types/string-mutator.ts +13 -13
  71. package/types/token-separators.ts +7 -7
  72. package/util/analytics.ts +20 -20
  73. package/util/countries.ts +195 -195
  74. package/util/error.ts +34 -34
  75. package/util/index.ts +70 -70
  76. package/util/item-selector-options-accessor.ts +34 -34
  77. package/util/line-item-ref.ts +23 -23
  78. package/util/multi-family-selector-options-accessor.ts +14 -14
  79. package/util/obs-string-mutator.ts +22 -22
  80. package/util/product-media-accessor.ts +58 -58
  81. package/util/promo-codes.ts +108 -108
  82. package/util/selection-ui-specifiers.ts +29 -29
  83. package/util/square-payment.ts +42 -42
  84. package/util/use-sync-sku-param-w-current-item.ts +88 -88
@@ -1,35 +1,35 @@
1
- import {
2
- ShoppingCart,
3
- Menu,
4
- ChevronLeft,
5
- ChevronRight,
6
- Loader2,
7
- Check,
8
- Plus,
9
- Minus,
10
- ChevronDown,
11
- ChevronsLeft,
12
- ChevronsRight,
13
- Image,
14
- Trash2,
15
- Search,
16
- Barcode
17
- } from "lucide-react"
18
-
19
- export default {
20
- shoppingCart: ShoppingCart,
21
- menu: Menu,
22
- chevronLeft: ChevronLeft,
23
- chevronRight: ChevronRight,
24
- spinner: Loader2,
25
- check: Check,
26
- plus: Plus,
27
- minus: Minus,
28
- chevronDown: ChevronDown,
29
- chevronsLeft: ChevronsLeft,
30
- chevronsRight: ChevronsRight,
31
- placeholder: Image,
32
- trash: Trash2,
33
- search: Search,
34
- barcode: Barcode
1
+ import {
2
+ ShoppingCart,
3
+ Menu,
4
+ ChevronLeft,
5
+ ChevronRight,
6
+ Loader2,
7
+ Check,
8
+ Plus,
9
+ Minus,
10
+ ChevronDown,
11
+ ChevronsLeft,
12
+ ChevronsRight,
13
+ Image,
14
+ Trash2,
15
+ Search,
16
+ Barcode
17
+ } from "lucide-react"
18
+
19
+ export default {
20
+ shoppingCart: ShoppingCart,
21
+ menu: Menu,
22
+ chevronLeft: ChevronLeft,
23
+ chevronRight: ChevronRight,
24
+ spinner: Loader2,
25
+ check: Check,
26
+ plus: Plus,
27
+ minus: Minus,
28
+ chevronDown: ChevronDown,
29
+ chevronsLeft: ChevronsLeft,
30
+ chevronsRight: ChevronsRight,
31
+ placeholder: Image,
32
+ trash: Trash2,
33
+ search: Search,
34
+ barcode: Barcode
35
35
  }
@@ -1,181 +1,181 @@
1
- 'use client'
2
- import React, { useEffect, useRef } from 'react'
3
- import { reaction, type IReactionDisposer } from 'mobx'
4
- import { observer } from 'mobx-react-lite'
5
-
6
- import { Button, buttonVariants } from '@hanzo/ui/primitives'
7
- import { cn, type VariantProps } from '@hanzo/ui/util'
8
-
9
- import Icons from './Icons'
10
- import type { LineItem } from '../types'
11
- import { sendFBEvent, sendGAEvent } from '../util/analytics'
12
-
13
- const AddToCartWidget: React.FC<{
14
- item: LineItem
15
- disabled?: boolean
16
- className?: string
17
- buttonClx?: string
18
- variant?: 'minimal' | 'primary' | 'primary-smaller' | 'outline'
19
- onQuantityChanged?: (sku: string, oldV: number, newV: number) => void
20
- }> = observer(({
21
- item,
22
- variant='primary',
23
- disabled=false,
24
- className='',
25
- buttonClx='',
26
- onQuantityChanged
27
- }) => {
28
-
29
- const reactionDisposer = useRef<IReactionDisposer | undefined>(undefined)
30
- useEffect(() => {
31
- if (onQuantityChanged) {
32
- reactionDisposer.current = reaction(
33
- () => (item.quantity),
34
- (quantity: number, previous: number) => {
35
- onQuantityChanged(item.sku, quantity, previous)
36
- }
37
- )
38
- }
39
- return () => {
40
- if (reactionDisposer.current) {
41
- reactionDisposer.current()
42
- }
43
- }
44
- }, [])
45
-
46
- const ROUNDED_VAL = 'lg'
47
- // no need to safelist, since its used widely
48
- const ROUNDED_CLX = ` rounded-${ROUNDED_VAL} `
49
-
50
- const ghost = variant === 'minimal'
51
- const outline = variant === 'outline'
52
- const primary = variant === 'primary'
53
- const priSmaller = variant === 'primary-smaller'
54
-
55
- let iconClx = ghost ? 'h-4 w-4 md:h-3 md:w-3 text-muted-3 ' : (priSmaller ? 'h-4 w-6 px-0.5 opacity-70' : 'h-5 w-7 px-1 opacity-70 ')
56
- iconClx += ghost ? 'group-hover:text-foreground' : 'group-hover:opacity-100'
57
-
58
- let digitClx = ghost ? 'px-2 md:px-0.5 ' : 'sm:px-2 font-semibold '
59
- digitClx += (ghost || outline) ? 'text-foreground ' : 'text-primary-fg '
60
-
61
- if (disabled) {
62
- return (
63
- <div className={cn('flex flex-row items-stretch' + ROUNDED_CLX + (!(primary || priSmaller) ? 'bg-transparent' : 'bg-primary'), className)}>
64
- <div className={'text-sm flex items-center cursor-default ' + digitClx} >{item.quantity}</div>
65
- </div>
66
- )
67
- }
68
-
69
- const inc = () => {
70
- item.increment()
71
- sendGAEvent('add_to_cart', {
72
- items: [{
73
- item_id: item.sku,
74
- item_name: item.title,
75
- item_category: item.familyId,
76
- price: item.price,
77
- quantity: item.quantity
78
- }],
79
- value: item.price,
80
- currency: 'USD',
81
- })
82
- sendFBEvent('AddToCart', {
83
- content_ids: [item.sku],
84
- contents: [{
85
- id: item.sku,
86
- quantity: item.quantity
87
- }],
88
- content_name: item.title,
89
- value: item.price,
90
- currency: 'USD',
91
- })
92
- }
93
-
94
- const dec = () => {
95
- item.decrement()
96
- sendGAEvent('remove_from_cart', {
97
- items: [{
98
- item_id: item.sku,
99
- item_name: item.title,
100
- item_category: item.familyId,
101
- price: item.price,
102
- quantity: item.quantity
103
- }],
104
- value: item.price,
105
- currency: 'USD',
106
- })
107
- }
108
-
109
- return ( item.isInCart ? (
110
- <div className={cn(
111
- 'flex flex-row items-stretch justify-between ',
112
- // should match 'xs' and 'default' button heights
113
- (ghost || priSmaller ? 'h-8' : 'h-9'),
114
- ROUNDED_CLX,
115
- (primary || priSmaller ? 'bg-primary' : 'bg-transparent'),
116
- (outline ? 'border border-muted' : ''),
117
- className
118
- )}>
119
- <Button
120
- aria-label={'Remove a ' + item.title + ' from the cart'}
121
- size={ghost || priSmaller ? 'xs' : 'default'}
122
- variant={primary || priSmaller ? 'primary' : 'ghost'}
123
- rounded={ghost ? 'full' : ROUNDED_VAL}
124
- className={cn(
125
- 'lg:min-w-0 lg:px-2 grow justify-start group',
126
- (ghost || priSmaller ? 'px-1' : 'px-2'),
127
- (outline ? 'hover:bg-transparent' : ''),
128
- buttonClx,
129
- 'h-auto self-stretch' // must be smaller than normal
130
- )}
131
- key='left'
132
- onClick={dec}
133
- >
134
- {(item.quantity > 1) ? (
135
- <Icons.minus className={iconClx} aria-hidden='true'/>
136
- ) : (
137
- <Icons.trash className={iconClx} aria-hidden='true'/>
138
- )}
139
- </Button>
140
- <div className={cn(
141
- 'grow-0 shrink-0 flex items-center cursor-default xs:px-2',
142
- priSmaller ? 'text-xs' : 'text-sm',
143
- digitClx
144
- )}>
145
- {item.quantity}{ghost ? '' : ' in Bag'}
146
- </div>
147
- <Button
148
- aria-label={'Add another ' + item.title + ' to the cart'}
149
- size={ghost || priSmaller ? 'xs' : 'default'}
150
-
151
- variant={primary || priSmaller ? 'primary' : 'ghost'}
152
- rounded={ghost ? 'full' : ROUNDED_VAL}
153
- className={cn(
154
- 'lg:min-w-0 lg:px-2 grow justify-end group',
155
- (ghost || priSmaller ? 'px-1' : 'px-2'),
156
- (outline ? 'hover:bg-transparent' : ''),
157
- buttonClx,
158
- 'h-auto self-stretch' // must be smaller than normal
159
- )}
160
- onClick={inc}
161
- key='right'
162
- >
163
- <Icons.plus className={iconClx} aria-hidden='true'/>
164
- </Button>
165
- </div>
166
- ) : (
167
- <Button
168
- aria-label={'Add a ' + item.title + ' to cart'}
169
- size={ghost || priSmaller ? 'xs' : 'default'}
170
- variant={ghost ? 'ghost' : (primary || priSmaller ? 'primary' : 'outline')}
171
- rounded={ROUNDED_VAL}
172
- className={cn(buttonClx, className)}
173
- onClick={inc}
174
- >
175
- <span className='m1-1'>Add</span>
176
- <Icons.plus className='h-5 w-5 ml-1' aria-hidden='true'/>
177
- </Button>
178
- ))
179
- })
180
-
181
- export default AddToCartWidget
1
+ 'use client'
2
+ import React, { useEffect, useRef } from 'react'
3
+ import { reaction, type IReactionDisposer } from 'mobx'
4
+ import { observer } from 'mobx-react-lite'
5
+
6
+ import { Button, buttonVariants } from '@hanzo/ui/primitives'
7
+ import { cn, type VariantProps } from '@hanzo/ui/util'
8
+
9
+ import Icons from './Icons'
10
+ import type { LineItem } from '../types'
11
+ import { sendFBEvent, sendGAEvent } from '../util/analytics'
12
+
13
+ const AddToCartWidget: React.FC<{
14
+ item: LineItem
15
+ disabled?: boolean
16
+ className?: string
17
+ buttonClx?: string
18
+ variant?: 'minimal' | 'primary' | 'primary-smaller' | 'outline'
19
+ onQuantityChanged?: (sku: string, oldV: number, newV: number) => void
20
+ }> = observer(({
21
+ item,
22
+ variant='primary',
23
+ disabled=false,
24
+ className='',
25
+ buttonClx='',
26
+ onQuantityChanged
27
+ }) => {
28
+
29
+ const reactionDisposer = useRef<IReactionDisposer | undefined>(undefined)
30
+ useEffect(() => {
31
+ if (onQuantityChanged) {
32
+ reactionDisposer.current = reaction(
33
+ () => (item.quantity),
34
+ (quantity: number, previous: number) => {
35
+ onQuantityChanged(item.sku, quantity, previous)
36
+ }
37
+ )
38
+ }
39
+ return () => {
40
+ if (reactionDisposer.current) {
41
+ reactionDisposer.current()
42
+ }
43
+ }
44
+ }, [])
45
+
46
+ const ROUNDED_VAL = 'lg'
47
+ // no need to safelist, since its used widely
48
+ const ROUNDED_CLX = ` rounded-${ROUNDED_VAL} `
49
+
50
+ const ghost = variant === 'minimal'
51
+ const outline = variant === 'outline'
52
+ const primary = variant === 'primary'
53
+ const priSmaller = variant === 'primary-smaller'
54
+
55
+ let iconClx = ghost ? 'h-4 w-4 md:h-3 md:w-3 text-muted-3 ' : (priSmaller ? 'h-4 w-6 px-0.5 opacity-70' : 'h-5 w-7 px-1 opacity-70 ')
56
+ iconClx += ghost ? 'group-hover:text-foreground' : 'group-hover:opacity-100'
57
+
58
+ let digitClx = ghost ? 'px-2 md:px-0.5 ' : 'sm:px-2 font-semibold '
59
+ digitClx += (ghost || outline) ? 'text-foreground ' : 'text-primary-fg '
60
+
61
+ if (disabled) {
62
+ return (
63
+ <div className={cn('flex flex-row items-stretch' + ROUNDED_CLX + (!(primary || priSmaller) ? 'bg-transparent' : 'bg-primary'), className)}>
64
+ <div className={'text-sm flex items-center cursor-default ' + digitClx} >{item.quantity}</div>
65
+ </div>
66
+ )
67
+ }
68
+
69
+ const inc = () => {
70
+ item.increment()
71
+ sendGAEvent('add_to_cart', {
72
+ items: [{
73
+ item_id: item.sku,
74
+ item_name: item.title,
75
+ item_category: item.familyId,
76
+ price: item.price,
77
+ quantity: item.quantity
78
+ }],
79
+ value: item.price,
80
+ currency: 'USD',
81
+ })
82
+ sendFBEvent('AddToCart', {
83
+ content_ids: [item.sku],
84
+ contents: [{
85
+ id: item.sku,
86
+ quantity: item.quantity
87
+ }],
88
+ content_name: item.title,
89
+ value: item.price,
90
+ currency: 'USD',
91
+ })
92
+ }
93
+
94
+ const dec = () => {
95
+ item.decrement()
96
+ sendGAEvent('remove_from_cart', {
97
+ items: [{
98
+ item_id: item.sku,
99
+ item_name: item.title,
100
+ item_category: item.familyId,
101
+ price: item.price,
102
+ quantity: item.quantity
103
+ }],
104
+ value: item.price,
105
+ currency: 'USD',
106
+ })
107
+ }
108
+
109
+ return ( item.isInCart ? (
110
+ <div className={cn(
111
+ 'flex flex-row items-stretch justify-between ',
112
+ // should match 'xs' and 'default' button heights
113
+ (ghost || priSmaller ? 'h-8' : 'h-9'),
114
+ ROUNDED_CLX,
115
+ (primary || priSmaller ? 'bg-primary' : 'bg-transparent'),
116
+ (outline ? 'border border-muted' : ''),
117
+ className
118
+ )}>
119
+ <Button
120
+ aria-label={'Remove a ' + item.title + ' from the cart'}
121
+ size={ghost || priSmaller ? 'xs' : 'default'}
122
+ variant={primary || priSmaller ? 'primary' : 'ghost'}
123
+ rounded={ghost ? 'full' : ROUNDED_VAL}
124
+ className={cn(
125
+ 'lg:min-w-0 lg:px-2 grow justify-start group',
126
+ (ghost || priSmaller ? 'px-1' : 'px-2'),
127
+ (outline ? 'hover:bg-transparent' : ''),
128
+ buttonClx,
129
+ 'h-auto self-stretch' // must be smaller than normal
130
+ )}
131
+ key='left'
132
+ onClick={dec}
133
+ >
134
+ {(item.quantity > 1) ? (
135
+ <Icons.minus className={iconClx} aria-hidden='true'/>
136
+ ) : (
137
+ <Icons.trash className={iconClx} aria-hidden='true'/>
138
+ )}
139
+ </Button>
140
+ <div className={cn(
141
+ 'grow-0 shrink-0 flex items-center cursor-default xs:px-2',
142
+ priSmaller ? 'text-xs' : 'text-sm',
143
+ digitClx
144
+ )}>
145
+ {item.quantity}{ghost ? '' : ' in Bag'}
146
+ </div>
147
+ <Button
148
+ aria-label={'Add another ' + item.title + ' to the cart'}
149
+ size={ghost || priSmaller ? 'xs' : 'default'}
150
+
151
+ variant={primary || priSmaller ? 'primary' : 'ghost'}
152
+ rounded={ghost ? 'full' : ROUNDED_VAL}
153
+ className={cn(
154
+ 'lg:min-w-0 lg:px-2 grow justify-end group',
155
+ (ghost || priSmaller ? 'px-1' : 'px-2'),
156
+ (outline ? 'hover:bg-transparent' : ''),
157
+ buttonClx,
158
+ 'h-auto self-stretch' // must be smaller than normal
159
+ )}
160
+ onClick={inc}
161
+ key='right'
162
+ >
163
+ <Icons.plus className={iconClx} aria-hidden='true'/>
164
+ </Button>
165
+ </div>
166
+ ) : (
167
+ <Button
168
+ aria-label={'Add a ' + item.title + ' to cart'}
169
+ size={ghost || priSmaller ? 'xs' : 'default'}
170
+ variant={ghost ? 'ghost' : (primary || priSmaller ? 'primary' : 'outline')}
171
+ rounded={ROUNDED_VAL}
172
+ className={cn(buttonClx, className)}
173
+ onClick={inc}
174
+ >
175
+ <span className='m1-1'>Add</span>
176
+ <Icons.plus className='h-5 w-5 ml-1' aria-hidden='true'/>
177
+ </Button>
178
+ ))
179
+ })
180
+
181
+ export default AddToCartWidget