@luxfi/core 5.2.7 → 5.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. package/commerce/ui/conf.ts +13 -13
  2. package/commerce/ui/context.tsx +126 -102
  3. package/commerce/ui/store.ts +304 -276
  4. package/components/access-code-input.tsx +71 -71
  5. package/components/auth/auth-listener.tsx +29 -29
  6. package/components/auth/auth-token/clear-auth-token.tsx +12 -12
  7. package/components/auth/auth-token/set-auth-token.tsx +16 -16
  8. package/components/auth/common-auth-domains.ts +16 -16
  9. package/components/auth/login-panel.tsx +107 -107
  10. package/components/back-button.tsx +42 -0
  11. package/components/chat-widget.tsx +85 -85
  12. package/components/commerce/add-widget.tsx +20 -20
  13. package/components/commerce/bag-button.tsx +98 -98
  14. package/components/commerce/buy-button.tsx +34 -34
  15. package/components/commerce/checkout-button.tsx +129 -129
  16. package/components/commerce/checkout-panel/dt-bag-carousel.tsx +36 -36
  17. package/components/commerce/checkout-panel/dt-checkout-panel.tsx +84 -66
  18. package/components/commerce/checkout-panel/index.tsx +129 -129
  19. package/components/commerce/checkout-panel/links-row.tsx +21 -21
  20. package/components/commerce/checkout-panel/mb-checkout-panel.tsx +54 -54
  21. package/components/commerce/checkout-panel/steps-indicator.tsx +39 -39
  22. package/components/commerce/checkout-panel/thank-you.tsx +18 -18
  23. package/components/commerce/checkout-widget/const.ts +13 -13
  24. package/components/commerce/checkout-widget/index.tsx +192 -192
  25. package/components/commerce/checkout-widget/obs-string-set.ts +48 -48
  26. package/components/commerce/checkout-widget/use-anim-clx-set.ts +58 -58
  27. package/components/commerce/desktop-bag-popup.tsx +78 -78
  28. package/components/commerce/desktop-nav-menu.tsx +130 -130
  29. package/components/commerce/drawer/index.tsx +99 -116
  30. package/components/commerce/drawer/micro.tsx +144 -144
  31. package/components/commerce/drawer/shell.tsx +85 -83
  32. package/components/commerce/mobile-bag-drawer.tsx +51 -51
  33. package/components/commerce/mobile-login-button.tsx +101 -101
  34. package/components/commerce/mobile-menu-toggle-button.tsx +35 -35
  35. package/components/commerce/mobile-nav-menu-ai.tsx +42 -44
  36. package/components/commerce/mobile-nav-menu-item.tsx +49 -49
  37. package/components/commerce/mobile-nav-menu.tsx +68 -68
  38. package/components/contact-dialog/contact-form.tsx +113 -113
  39. package/components/contact-dialog/disclaimer.tsx +13 -13
  40. package/components/contact-dialog/index.tsx +64 -64
  41. package/components/copyright.tsx +21 -21
  42. package/components/drawer-margin.tsx +25 -25
  43. package/components/footer.tsx +77 -77
  44. package/components/header/desktop.tsx +49 -49
  45. package/components/header/index.tsx +52 -52
  46. package/components/header/mobile.tsx +163 -166
  47. package/components/header/theme-toggle.tsx +26 -26
  48. package/components/icons/avatar.tsx +11 -11
  49. package/components/icons/bag-icon.tsx +10 -10
  50. package/components/icons/github.tsx +14 -14
  51. package/components/icons/index.tsx +43 -43
  52. package/components/icons/left-arrow.tsx +11 -11
  53. package/components/icons/lux-logo.tsx +10 -10
  54. package/components/icons/right-arrow.tsx +10 -10
  55. package/components/icons/search.tsx +12 -12
  56. package/components/icons/secure-delivery.tsx +13 -13
  57. package/components/icons/social-icon.tsx +35 -35
  58. package/components/icons/social-svg.css +3 -3
  59. package/components/icons/warpcast.tsx +58 -58
  60. package/components/icons/youtube-logo.tsx +59 -59
  61. package/components/index.ts +27 -25
  62. package/components/logo.tsx +89 -81
  63. package/components/main.tsx +27 -27
  64. package/components/mini-chart/index.tsx +7 -7
  65. package/components/mini-chart/mini-chart-props.ts +43 -43
  66. package/components/mini-chart/mini-chart.tsx +85 -85
  67. package/components/mini-chart/wrapper.tsx +23 -23
  68. package/components/not-found/index.tsx +28 -28
  69. package/components/not-found/not-found-content.mdx +5 -5
  70. package/components/scripts.tsx +24 -24
  71. package/components/tooltip.tsx +31 -0
  72. package/environment.d.ts +5 -5
  73. package/next/analytics/fpixel.ts +15 -15
  74. package/next/analytics/google-analytics.ts +13 -13
  75. package/next/analytics/index.ts +3 -3
  76. package/next/analytics/pixel-analytics.tsx +54 -54
  77. package/next/font/get-app-router-font-classes.ts +12 -12
  78. package/next/font/load-and-return-lux-next-fonts-on-import.ts +68 -68
  79. package/next/font/next-font-desc.ts +27 -27
  80. package/next/font/pages-router-font-vars.tsx +18 -18
  81. package/next/head-metadata/from-next/metadata-types.ts +158 -158
  82. package/next/head-metadata/from-next/opengraph-types.ts +267 -267
  83. package/next/head-metadata/from-next/twitter-types.ts +92 -92
  84. package/next/head-metadata/index.tsx +208 -208
  85. package/next/middleware/determine-device-mw.ts +16 -16
  86. package/package.json +79 -78
  87. package/root-layout/WHY_THIS_IS_SEPARATE.txt +1 -1
  88. package/root-layout/index.tsx +112 -112
  89. package/server-actions/firebase-app.ts +14 -14
  90. package/server-actions/index.ts +5 -5
  91. package/server-actions/store-contact.ts +51 -51
  92. package/site-def/footer/community.tsx +67 -67
  93. package/site-def/footer/company.ts +37 -37
  94. package/site-def/footer/ecosystem.ts +37 -37
  95. package/site-def/footer/index.tsx +26 -26
  96. package/site-def/footer/legal.ts +28 -28
  97. package/site-def/footer/network.ts +45 -45
  98. package/site-def/footer/svg/warpcast-logo.svg +11 -11
  99. package/site-def/index.ts +2 -2
  100. package/site-def/main-nav.tsx +338 -338
  101. package/style/cart-animation.css +29 -29
  102. package/style/checkout-animation.css +23 -23
  103. package/style/drawer-handle-overrides.css +160 -160
  104. package/style/lux-colors.css +85 -85
  105. package/style/lux-global.css +30 -30
  106. package/tailwind/fontFamily.tailwind.lux.ts +18 -18
  107. package/tailwind/index.ts +2 -2
  108. package/tailwind/lux-tw-fonts.ts +39 -39
  109. package/tailwind/tailwind.config.lux-preset.ts +10 -10
  110. package/tsconfig.json +15 -15
  111. package/types/chatbot-config.ts +6 -6
  112. package/types/chatbot-suggested-question.ts +7 -7
  113. package/types/contact-info.ts +10 -10
  114. package/types/index.ts +4 -4
  115. package/types/site-def.ts +43 -43
  116. package/components/commerce/checkout-panel/close-button.tsx +0 -26
@@ -1,49 +1,49 @@
1
- import React from 'react'
2
-
3
- import { NavItems } from '@hanzo/ui/primitives'
4
- import { cn } from '@hanzo/ui/util'
5
- import { AuthWidget } from '@hanzo/auth/components'
6
-
7
- import { Logo } from '..'
8
-
9
- import DesktopBagPopup from '../commerce/desktop-bag-popup'
10
- import BagButton from '../commerce/bag-button'
11
- import DesktopNav from '../commerce/desktop-nav-menu'
12
-
13
-
14
- import type { LinkDef } from '@hanzo/ui/types'
15
-
16
- const DesktopHeader: React.FC<{
17
- currentAs: string | undefined
18
- links: LinkDef[]
19
- className?: string
20
- }> = ({
21
- currentAs,
22
- links,
23
- className = ''
24
- }) => {
25
-
26
- // TODO move 13px into a size class and configure twMerge to recognize say, 'text-size-nav'
27
- // (vs be beat out by 'text-color-nav')
28
- return (
29
- <header className={cn('bg-background fixed z-header top-0 left-0 right-0', className)} >
30
- {/* md or larger */}
31
- <div className={
32
- 'flex flex-row h-[80px] items-center justify-between ' +
33
- 'px-[8px] w-full mx-auto max-w-screen'
34
- }>
35
- <Logo size='md' href='/' className='hidden lg:flex' key='two' layout='text-only'/>
36
- <Logo size='sm' href='/' className='hidden md:flex lg:hidden' key='one' layout='text-only'/>
37
- {/* md or larger */}
38
- <div className='flex gap-4 items-center'>
39
- <DesktopNav links = {links}/>
40
- <DesktopBagPopup popupClx='w-[340px]' trigger={<BagButton className='text-primary -mr-[3px] lg:min-w-0' />} />
41
- <AuthWidget/>
42
- </div>
43
- </div>
44
- </header>
45
- )
46
- }
47
-
48
- export default DesktopHeader
49
-
1
+ import React from 'react'
2
+
3
+ import { NavItems } from '@hanzo/ui/primitives'
4
+ import { cn } from '@hanzo/ui/util'
5
+ import { AuthWidget } from '@hanzo/auth/components'
6
+
7
+ import { Logo } from '..'
8
+
9
+ import DesktopBagPopup from '../commerce/desktop-bag-popup'
10
+ import BagButton from '../commerce/bag-button'
11
+ import DesktopNav from '../commerce/desktop-nav-menu'
12
+
13
+
14
+ import type { LinkDef } from '@hanzo/ui/types'
15
+
16
+ const DesktopHeader: React.FC<{
17
+ currentAs: string | undefined
18
+ links: LinkDef[]
19
+ className?: string
20
+ }> = ({
21
+ currentAs,
22
+ links,
23
+ className = ''
24
+ }) => {
25
+
26
+ // TODO move 13px into a size class and configure twMerge to recognize say, 'text-size-nav'
27
+ // (vs be beat out by 'text-color-nav')
28
+ return (
29
+ <header className={cn('bg-background fixed z-header top-0 left-0 right-0', className)} >
30
+ {/* md or larger */}
31
+ <div className={
32
+ 'flex flex-row h-[80px] items-center justify-between ' +
33
+ 'px-[8px] w-full mx-auto max-w-screen'
34
+ }>
35
+ <Logo size='md' href='/' outerClx='hidden lg:flex' key='two' variant='text-only'/>
36
+ <Logo size='sm' href='/' outerClx='hidden md:flex lg:hidden' key='one' variant='text-only'/>
37
+ {/* md or larger */}
38
+ <div className='flex gap-4 items-center'>
39
+ <DesktopNav links = {links}/>
40
+ <DesktopBagPopup popupClx='w-[340px]' trigger={<BagButton className='text-primary -mr-[3px] lg:min-w-0' />} />
41
+ <AuthWidget/>
42
+ </div>
43
+ </div>
44
+ </header>
45
+ )
46
+ }
47
+
48
+ export default DesktopHeader
49
+
@@ -1,52 +1,52 @@
1
- 'use client'
2
- import React from 'react'
3
-
4
- import type { SiteDef } from '../../site-def'
5
-
6
- import DesktopHeader from './desktop'
7
- import MobileHeader from './mobile'
8
- import { cn } from '@hanzo/ui/util'
9
- import { ChatWidget } from '../../components'
10
-
11
- const Header: React.FC<{
12
- siteDef: SiteDef
13
- className?: string
14
- }> = ({
15
- siteDef,
16
- className = ''
17
- }) => {
18
-
19
- // TODO
20
- const [open, setOpen] = React.useState<boolean>(false);
21
-
22
- const { nav: { common, featured }, currentAs } = siteDef
23
- const links = (featured) ? [...common, ...featured] : common
24
- const isDesktopView = (): boolean => {
25
- if (typeof window === 'undefined') return false
26
- return window.innerWidth > 768
27
- }
28
-
29
- return (<>
30
- <DesktopHeader
31
- className={cn(className, 'hidden md:flex')}
32
- links={links}
33
- currentAs={currentAs}
34
- />
35
- <MobileHeader
36
- className={cn(className, 'md:hidden')}
37
- links={links}
38
- currentAs={currentAs}
39
- setChatbotOpen={setOpen}
40
- />
41
- {isDesktopView() && (
42
- <ChatWidget
43
- title='LUX'
44
- subtitle='AI'
45
- chatbotUrl='https://lux.chat/iframe'
46
- suggestedQuestions={siteDef.chatbot?.suggestedQuestions ?? []}
47
- />
48
- )}
49
- </>)
50
- }
51
-
52
- export default Header
1
+ 'use client'
2
+ import React from 'react'
3
+
4
+ import type { SiteDef } from '../../site-def'
5
+
6
+ import DesktopHeader from './desktop'
7
+ import MobileHeader from './mobile'
8
+ import { cn } from '@hanzo/ui/util'
9
+ import { ChatWidget } from '../../components'
10
+
11
+ const Header: React.FC<{
12
+ siteDef: SiteDef
13
+ className?: string
14
+ }> = ({
15
+ siteDef,
16
+ className = ''
17
+ }) => {
18
+
19
+ // TODO
20
+ const [open, setOpen] = React.useState<boolean>(false);
21
+
22
+ const { nav: { common, featured }, currentAs } = siteDef
23
+ const links = (featured) ? [...common, ...featured] : common
24
+ const isDesktopView = (): boolean => {
25
+ if (typeof window === 'undefined') return false
26
+ return window.innerWidth > 768
27
+ }
28
+
29
+ return (<>
30
+ <DesktopHeader
31
+ className={cn(className, 'hidden md:flex')}
32
+ links={links}
33
+ currentAs={currentAs}
34
+ />
35
+ <MobileHeader
36
+ className={cn(className, 'md:hidden')}
37
+ links={links}
38
+ currentAs={currentAs}
39
+ setChatbotOpen={setOpen}
40
+ />
41
+ {isDesktopView() && (
42
+ <ChatWidget
43
+ title='LUX'
44
+ subtitle='AI'
45
+ chatbotUrl='https://lux.chat/iframe'
46
+ suggestedQuestions={siteDef.chatbot?.suggestedQuestions ?? []}
47
+ />
48
+ )}
49
+ </>)
50
+ }
51
+
52
+ export default Header
@@ -1,166 +1,163 @@
1
- 'use client'
2
- import React, { useState, useEffect } from 'react'
3
- import { useRouter } from 'next/navigation'
4
-
5
- import type { LinkDef } from '@hanzo/ui/types'
6
- import { cn } from '@hanzo/ui/util'
7
-
8
- import { CartPanel, useCommerce } from '@hanzo/commerce'
9
- import { AuthWidget, LoginPanel } from '@hanzo/auth/components'
10
- import sendGAEvent from '../../next/analytics/google-analytics'
11
- import * as Icons from '../icons'
12
-
13
- import { Logo } from '..'
14
-
15
- import MenuToggleButton from '../commerce/mobile-menu-toggle-button'
16
- import BagButton from '../commerce/bag-button'
17
- import MobileBagDrawer from '../commerce/mobile-bag-drawer'
18
- import NavMenu from '../commerce/mobile-nav-menu'
19
-
20
- const bagClx = 'mt-4 mb-8 border-none py-0 px-4 w-full ' +
21
- 'sm:min-w-[350px] sm:max-w-[500px] sm:mx-auto min-h-[60vh] max-h-[70vh] ' +
22
- 'sm:animate-in sm:zoom-in-90 '
23
-
24
- const MobileHeader: React.FC<{
25
- currentAs: string | undefined
26
- links: LinkDef[]
27
- className?: string,
28
- setChatbotOpen: (open: boolean) => void,
29
- }> = ({
30
- currentAs,
31
- links,
32
- className = '',
33
- setChatbotOpen,
34
- }) => {
35
- const cmmc = useCommerce()
36
- const [menuState, setMenuState] = useState<'closed' | 'nav' | 'login' | 'bag'>('closed')
37
- const [bagDrawerOpen, setBagDrawerOpen] = useState<boolean>(false)
38
- const router = useRouter()
39
-
40
- useEffect(() => {
41
- if (menuState === 'bag' || bagDrawerOpen) {
42
- sendGAEvent('view_cart', {
43
- items: cmmc.cartItems.map((item) => ({
44
- item_id: item.sku,
45
- item_name: item.title,
46
- item_category: item.familyId,
47
- price: item.price,
48
- quantity: item.quantity
49
- })),
50
- value: cmmc.cartTotal,
51
- currency: 'USD',
52
- })
53
- }
54
- }, [menuState, bagDrawerOpen])
55
-
56
- const menuOpen = () => (menuState !== 'closed')
57
-
58
- const onLoginChanged = (token: string) => {
59
- // by def, menu was in state 'login'
60
- if (!!token) { setMenuState('nav') }
61
- }
62
-
63
- const setMenuOpen = (open: boolean) => {
64
- if (!open) {
65
- setMenuState('closed')
66
- }
67
- else {
68
- setMenuState('nav')
69
- }
70
- }
71
-
72
- const handleCheckout = () => {
73
- setMenuState('closed')
74
- setBagDrawerOpen(false)
75
- router.push('/checkout')
76
- }
77
-
78
- const openBag = () => {
79
- if (menuOpen()) {
80
- setMenuState('bag')
81
- }
82
- else {
83
- setBagDrawerOpen(true)
84
- }
85
- }
86
- // header element MUST be fixed, and NOT sticky. Or else drawer breaks on mobile browsers
87
- return (<>
88
- <header className={cn(
89
- `bg-background fixed z-header top-0 left-0 w-full h-19 ${menuOpen() ? 'hidden' : 'block'}`,
90
- className
91
- )}>
92
- {/* smaller than md: mobile style drawer menu; h-11 is 44px, the standard mobile header height */}
93
- <div className="flex h-11 items-center justify-between pl-6 pr-4">
94
- <div className='h-[74px] w-pr-100 flex flex-row justify-between items-center font-bold'>
95
- <Logo href='/' size='sm' className={'top-[3px] h-full'} layout='text-only' />
96
- {/* Not that key to the cross-fade effect
97
- is that this is **on top of** the logo. */}
98
- {menuOpen() && (
99
- <div className={'absolute left-0 top-0 bottom-0 right-0 pl-8 ' +
100
- 'flex flex-row ' +
101
- 'bg-background animate-mobile-menu-open'
102
- }>
103
- <Icons.Avatar className='self-center ' />
104
- </div>
105
- )}
106
- <div className='flex gap-0 flex-row'>
107
- <BagButton className='text-primary -mr-[3px]' onClick={openBag} />
108
- <MenuToggleButton className='text-foreground' open={menuOpen()} setOpen={setMenuOpen} />
109
- </div>
110
-
111
- </div>
112
-
113
- </div>
114
- </header>
115
- <MobileBagDrawer
116
- className=''
117
- open={bagDrawerOpen}
118
- setOpen={setBagDrawerOpen}
119
- handleCheckout={handleCheckout}
120
- />
121
- {menuOpen() && (
122
- <div className={
123
- 'fixed top-0 left-0 w-full h-full ' +
124
- // z must below header itself
125
- 'flex flex-column bg-background z-below-header animate-mobile-menu-open'
126
- }>
127
- {menuState === 'login' ? (
128
- <LoginPanel noHeading onLoginChanged={onLoginChanged} className='sm:animate-in sm:zoom-in-90' />
129
- ) : (
130
- menuState === 'bag' ? (
131
-
132
- <CartPanel
133
- handleCheckout={() => { router.push('/checkout') }}
134
- className={bagClx}
135
- listClx='rounded-sm'
136
- scrollAfter={6}
137
- scrollHeightClx='h-[80vh]'
138
- itemClx='mt-2'
139
- totalClx='sticky px-1 pr-2 border rounded-sm -bottom-[1px] bg-level-1'
140
- buttonClx='max-w-[220px] flex-none'
141
- >
142
- <div className='flex flex-row items-center flex-none justify-center '>
143
- <Icons.bag className='mr-2 relative w-4 h-5 fill-foreground ' />
144
- <p className='font-heading text-foreground text-default'>Your Bag</p>
145
- </div>
146
- <div className='h-[1px] w-pr-80 bg-muted-3 mx-auto mt-1.5 flex-none' />
147
- </CartPanel>
148
-
149
- ) : ( /* menuState === 'nav' */
150
- <NavMenu
151
- currentAs={currentAs}
152
- links={links}
153
- className='sm:animate-in sm:zoom-in-90 w-full'
154
- commonItemClx='px-0 text-xl h-16 justify-start '
155
- setMenuState={setMenuState}
156
- setChatbotOpen={setChatbotOpen}
157
- setMenuOpen={setMenuOpen}
158
- />
159
- )
160
- )}
161
- </div>
162
- ) /* menuOpen */}
163
- </>)
164
- }
165
-
166
- export default MobileHeader
1
+ 'use client'
2
+ import React, { useState, useEffect } from 'react'
3
+ import { useRouter } from 'next/navigation'
4
+
5
+ import type { LinkDef } from '@hanzo/ui/types'
6
+ import { cn } from '@hanzo/ui/util'
7
+
8
+ import { CartPanel, useCommerce } from '@hanzo/commerce'
9
+ import { AuthWidget, LoginPanel } from '@hanzo/auth/components'
10
+ import sendGAEvent from '../../next/analytics/google-analytics'
11
+ import * as Icons from '../icons'
12
+
13
+ import { Logo } from '..'
14
+
15
+ import MenuToggleButton from '../commerce/mobile-menu-toggle-button'
16
+ import BagButton from '../commerce/bag-button'
17
+ import MobileBagDrawer from '../commerce/mobile-bag-drawer'
18
+ import NavMenu from '../commerce/mobile-nav-menu'
19
+
20
+ const bagClx = 'mt-4 mb-8 border-none py-0 px-4 w-full ' +
21
+ 'sm:min-w-[350px] sm:max-w-[500px] sm:mx-auto min-h-[60vh] max-h-[70vh] ' +
22
+ 'sm:animate-in sm:zoom-in-90 '
23
+
24
+ const MobileHeader: React.FC<{
25
+ currentAs: string | undefined
26
+ links: LinkDef[]
27
+ className?: string,
28
+ setChatbotOpen: (open: boolean) => void,
29
+ }> = ({
30
+ currentAs,
31
+ links,
32
+ className = '',
33
+ setChatbotOpen,
34
+ }) => {
35
+ const cmmc = useCommerce()
36
+ const [menuState, setMenuState] = useState<'closed' | 'nav' | 'login' | 'bag'>('closed')
37
+ const [bagDrawerOpen, setBagDrawerOpen] = useState<boolean>(false)
38
+ const router = useRouter()
39
+
40
+ useEffect(() => {
41
+ if (menuState === 'bag' || bagDrawerOpen) {
42
+ sendGAEvent('view_cart', {
43
+ items: cmmc.cartItems.map((item) => ({
44
+ item_id: item.sku,
45
+ item_name: item.title,
46
+ item_category: item.familyId,
47
+ price: item.price,
48
+ quantity: item.quantity
49
+ })),
50
+ value: cmmc.cartTotal,
51
+ currency: 'USD',
52
+ })
53
+ }
54
+ }, [menuState, bagDrawerOpen])
55
+
56
+ const menuOpen = () => (menuState !== 'closed')
57
+
58
+ const onLoginChanged = (token: string) => {
59
+ // by def, menu was in state 'login'
60
+ if (!!token) { setMenuState('nav') }
61
+ }
62
+
63
+ const setMenuOpen = (open: boolean) => {
64
+ if (!open) {
65
+ setMenuState('closed')
66
+ }
67
+ else {
68
+ setMenuState('nav')
69
+ }
70
+ }
71
+
72
+ const handleCheckout = () => {
73
+ setMenuState('closed')
74
+ setBagDrawerOpen(false)
75
+ router.push('/checkout')
76
+ }
77
+
78
+ const openBag = () => {
79
+ if (menuOpen()) {
80
+ setMenuState('bag')
81
+ }
82
+ else {
83
+ setBagDrawerOpen(true)
84
+ }
85
+ }
86
+ // header element MUST be fixed, and NOT sticky. Or else drawer breaks on mobile browsers
87
+ return (<>
88
+ <header className={cn(
89
+ `bg-background fixed z-header top-0 left-0 w-full ${menuOpen() ? 'hidden' : 'block'}`,
90
+ className
91
+ )}>
92
+ {/* smaller than md: mobile style drawer menu; h-11 is 44px, the standard mobile header height */}
93
+ <div className='w-full h-11 flex flex-row justify-between items-center font-bold pl-6 pr-4'>
94
+ <Logo href='/' size='sm' outerClx={'top-[3px] h-full'} variant='text-only' />
95
+ {/* Not that key to the cross-fade effect
96
+ is that this is **on top of** the logo. */}
97
+ {menuOpen() && (
98
+ <div className={'absolute left-0 top-0 bottom-0 right-0 pl-8 ' +
99
+ 'flex flex-row ' +
100
+ 'bg-background animate-mobile-menu-open'
101
+ }>
102
+ <Icons.Avatar className='self-center ' />
103
+ </div>
104
+ )}
105
+ <div className='flex gap-0 flex-row'>
106
+ <BagButton className='text-primary -mr-[3px]' onClick={openBag} />
107
+ <MenuToggleButton className='text-foreground' open={menuOpen()} setOpen={setMenuOpen} />
108
+ </div>
109
+
110
+ </div>
111
+ </header>
112
+ <MobileBagDrawer
113
+ className=''
114
+ open={bagDrawerOpen}
115
+ setOpen={setBagDrawerOpen}
116
+ handleCheckout={handleCheckout}
117
+ />
118
+ {menuOpen() && (
119
+ <div className={
120
+ 'fixed top-0 left-0 w-full h-full ' +
121
+ // z must below header itself
122
+ 'flex flex-column bg-background z-below-header animate-mobile-menu-open'
123
+ }>
124
+ {menuState === 'login' ? (
125
+ <LoginPanel noHeading onLoginChanged={onLoginChanged} className='sm:animate-in sm:zoom-in-90' />
126
+ ) : (
127
+ menuState === 'bag' ? (
128
+
129
+ <CartPanel
130
+ handleCheckout={() => { router.push('/checkout') }}
131
+ className={bagClx}
132
+ listClx='rounded-sm'
133
+ scrollAfter={6}
134
+ scrollHeightClx='h-[80vh]'
135
+ itemClx='mt-2'
136
+ totalClx='sticky px-1 pr-2 border rounded-sm -bottom-[1px] bg-level-1'
137
+ buttonClx='max-w-[220px] flex-none'
138
+ >
139
+ <div className='flex flex-row items-center flex-none justify-center '>
140
+ <Icons.bag className='mr-2 relative w-4 h-5 fill-foreground ' />
141
+ <p className='font-heading text-foreground text-default'>Your Bag</p>
142
+ </div>
143
+ <div className='h-[1px] w-pr-80 bg-muted-3 mx-auto mt-1.5 flex-none' />
144
+ </CartPanel>
145
+
146
+ ) : ( /* menuState === 'nav' */
147
+ <NavMenu
148
+ currentAs={currentAs}
149
+ links={links}
150
+ className='sm:animate-in sm:zoom-in-90 w-full'
151
+ commonItemClx='px-0 text-xl h-16 justify-start '
152
+ setMenuState={setMenuState}
153
+ setChatbotOpen={setChatbotOpen}
154
+ setMenuOpen={setMenuOpen}
155
+ />
156
+ )
157
+ )}
158
+ </div>
159
+ ) /* menuOpen */}
160
+ </>)
161
+ }
162
+
163
+ export default MobileHeader
@@ -1,26 +1,26 @@
1
- 'use client'
2
-
3
- import React from 'react'
4
- import { Moon, Sun } from 'lucide-react'
5
- import { useTheme } from 'next-themes'
6
-
7
- import { Button } from '@hanzo/ui/primitives'
8
-
9
- const ThemeToggle: React.FC = () => {
10
-
11
- const { setTheme, theme } = useTheme()
12
-
13
- return (
14
- <Button
15
- variant='ghost'
16
- size='icon'
17
- onClick={() => {setTheme(theme === 'light' ? 'dark' : 'light')}}
18
- >
19
- <Sun className='h-[1.5rem] w-[1.3rem] dark:hidden' />
20
- <Moon className='hidden h-5 w-5 dark:block' />
21
- <span className='sr-only'>Toggle theme</span>
22
- </Button>
23
- )
24
- }
25
-
26
- export default ThemeToggle
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+ import { Moon, Sun } from 'lucide-react'
5
+ import { useTheme } from 'next-themes'
6
+
7
+ import { Button } from '@hanzo/ui/primitives'
8
+
9
+ const ThemeToggle: React.FC = () => {
10
+
11
+ const { setTheme, theme } = useTheme()
12
+
13
+ return (
14
+ <Button
15
+ variant='ghost'
16
+ size='icon'
17
+ onClick={() => {setTheme(theme === 'light' ? 'dark' : 'light')}}
18
+ >
19
+ <Sun className='h-[1.5rem] w-[1.3rem] dark:hidden' />
20
+ <Moon className='hidden h-5 w-5 dark:block' />
21
+ <span className='sr-only'>Toggle theme</span>
22
+ </Button>
23
+ )
24
+ }
25
+
26
+ export default ThemeToggle
@@ -1,11 +1,11 @@
1
- import React from 'react'
2
- import { type LucideProps } from 'lucide-react'
3
-
4
- const Avatar: React.FC<LucideProps> = (props: LucideProps) => (
5
- <svg width="17" height="21" viewBox="0 0 17 21" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
6
- <path d="M8.66112 10.3544C6.14668 10.3544 4.32664 6.91073 4.32664 4.59206C4.32664 2.12213 6.27238 0.115723 8.66112 0.115723C11.0499 0.115723 12.9956 2.12514 12.9956 4.59206C12.9956 6.91398 11.1756 10.3544 8.66112 10.3544ZM8.66112 1.1542C6.82539 1.1542 5.33242 2.69703 5.33242 4.59185C5.33242 6.65402 6.94715 9.31553 8.66112 9.31553C10.3761 9.31553 11.9898 6.65387 11.9898 4.5925C11.9898 2.69668 10.4969 1.15398 8.66112 1.15398V1.1542Z" fill="white" />
7
- <path d="M6.79776 11.3345H10.5242C13.7802 11.3345 16.4302 14.0712 16.4302 17.4338C16.4302 19.0831 15.1297 20.423 13.5356 20.423H3.78923C2.19216 20.423 0.894689 19.0831 0.894689 17.4338C0.893706 14.0712 3.54156 11.3345 6.79776 11.3345ZM3.78819 19.3844H13.5337C14.5749 19.3844 15.4225 18.509 15.4225 17.4338C15.4225 14.6453 13.2253 12.3731 10.5223 12.3731H6.79862C4.0956 12.3731 1.89839 14.6423 1.89839 17.4338C1.89937 18.509 2.74701 19.3844 3.78816 19.3844H3.78819Z" fill="white" />
8
- </svg>
9
- )
10
-
11
- export default Avatar
1
+ import React from 'react'
2
+ import { type LucideProps } from 'lucide-react'
3
+
4
+ const Avatar: React.FC<LucideProps> = (props: LucideProps) => (
5
+ <svg width="17" height="21" viewBox="0 0 17 21" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
6
+ <path d="M8.66112 10.3544C6.14668 10.3544 4.32664 6.91073 4.32664 4.59206C4.32664 2.12213 6.27238 0.115723 8.66112 0.115723C11.0499 0.115723 12.9956 2.12514 12.9956 4.59206C12.9956 6.91398 11.1756 10.3544 8.66112 10.3544ZM8.66112 1.1542C6.82539 1.1542 5.33242 2.69703 5.33242 4.59185C5.33242 6.65402 6.94715 9.31553 8.66112 9.31553C10.3761 9.31553 11.9898 6.65387 11.9898 4.5925C11.9898 2.69668 10.4969 1.15398 8.66112 1.15398V1.1542Z" fill="white" />
7
+ <path d="M6.79776 11.3345H10.5242C13.7802 11.3345 16.4302 14.0712 16.4302 17.4338C16.4302 19.0831 15.1297 20.423 13.5356 20.423H3.78923C2.19216 20.423 0.894689 19.0831 0.894689 17.4338C0.893706 14.0712 3.54156 11.3345 6.79776 11.3345ZM3.78819 19.3844H13.5337C14.5749 19.3844 15.4225 18.509 15.4225 17.4338C15.4225 14.6453 13.2253 12.3731 10.5223 12.3731H6.79862C4.0956 12.3731 1.89839 14.6423 1.89839 17.4338C1.89937 18.509 2.74701 19.3844 3.78816 19.3844H3.78819Z" fill="white" />
8
+ </svg>
9
+ )
10
+
11
+ export default Avatar
@@ -1,10 +1,10 @@
1
- import React from 'react'
2
- import { type LucideProps } from 'lucide-react'
3
-
4
- const BagIcon: React.FC<LucideProps> = (props: LucideProps) => (
5
- <svg fill="none" viewBox="0 0 1019 1281" {...props}>
6
- <path d="m977.243 365.553h-175.407v-90.629c0-151.923-131.968-274.924-292.334-274.924-160.367 0-292.337 123.002-292.337 274.924v90.629h-175.4023c-23.3886 0-41.7627 17.051-41.7627 38.756v775.121c0 55.8 48.4456 100.76 108.582 100.76h801.84c60.138 0 108.578-44.96 108.578-100.76v-775.121c0-21.705-18.37-38.756-41.757-38.756zm-676.553-90.629c0-108.517 93.546-196.9408 208.812-196.9408 115.265 0 208.813 88.4218 208.813 196.9408v89.08h-417.625z" fill="currentColor"/>
7
- </svg>
8
- )
9
-
10
- export default BagIcon
1
+ import React from 'react'
2
+ import { type LucideProps } from 'lucide-react'
3
+
4
+ const BagIcon: React.FC<LucideProps> = (props: LucideProps) => (
5
+ <svg fill="none" viewBox="0 0 1019 1281" {...props}>
6
+ <path d="m977.243 365.553h-175.407v-90.629c0-151.923-131.968-274.924-292.334-274.924-160.367 0-292.337 123.002-292.337 274.924v90.629h-175.4023c-23.3886 0-41.7627 17.051-41.7627 38.756v775.121c0 55.8 48.4456 100.76 108.582 100.76h801.84c60.138 0 108.578-44.96 108.578-100.76v-775.121c0-21.705-18.37-38.756-41.757-38.756zm-676.553-90.629c0-108.517 93.546-196.9408 208.812-196.9408 115.265 0 208.813 88.4218 208.813 196.9408v89.08h-417.625z" fill="currentColor"/>
7
+ </svg>
8
+ )
9
+
10
+ export default BagIcon