@hanzo/ui 2.0.5 → 2.5.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/assets/lux-site-icons/android-chrome-192x192.png +0 -0
- package/assets/lux-site-icons/android-chrome-512x512.png +0 -0
- package/assets/lux-site-icons/apple-touch-icon.png +0 -0
- package/assets/lux-site-icons/favicon-16x16.png +0 -0
- package/assets/lux-site-icons/favicon-32x32.png +0 -0
- package/assets/lux-site-icons/favicon.ico +0 -0
- package/assets/standard-docs/LUX-NFT-Terms-and-Conditions.pdf +0 -0
- package/assets/standard-docs/LUX-Privacy-Policy.pdf +0 -0
- package/blocks/components/card-block.tsx +1 -1
- package/blocks/components/screenful-block/index.tsx +11 -1
- package/common/chat-widget.tsx +75 -0
- package/common/contact-dialog/contact-form.tsx +111 -0
- package/common/contact-dialog/disclaimer.tsx +13 -0
- package/common/contact-dialog/index.tsx +48 -0
- package/common/copyright.tsx +21 -0
- package/common/drawer-menu.tsx +54 -0
- package/common/footer.tsx +77 -0
- package/common/head-metadata/from-next/metadata-types.ts +158 -0
- package/common/head-metadata/from-next/opengraph-types.ts +267 -0
- package/common/head-metadata/from-next/twitter-types.ts +92 -0
- package/common/head-metadata/index.tsx +208 -0
- package/common/header/index.tsx +66 -0
- package/common/header/mobile-nav.tsx +72 -0
- package/common/header/theme-toggle.tsx +26 -0
- package/common/icons/index.tsx +34 -0
- package/common/icons/lux-logo.tsx +10 -0
- package/common/icons/secure-delivery.tsx +13 -0
- package/common/icons/social-icon.tsx +35 -0
- package/common/index.ts +14 -0
- package/common/logo.tsx +71 -0
- package/common/mini-chart/index.tsx +8 -0
- package/common/mini-chart/mini-chart-props.ts +44 -0
- package/common/mini-chart/mini-chart.tsx +76 -0
- package/common/mini-chart/wrapper.tsx +23 -0
- package/context-providers/index.ts +1 -0
- package/{style → context-providers}/theme-provider.tsx +2 -2
- package/next/README.md +11 -0
- package/next/analytics/fpixel.ts +18 -0
- package/next/analytics/pixel-analytics.tsx +55 -0
- package/next/determine-device-middleware.ts +16 -0
- package/next/fonts/DrukTextWide-Bold-Trial.otf +0 -0
- package/next/fonts/DrukTextWide-Heavy-Trial.otf +0 -0
- package/next/fonts/DrukTextWide-Medium-Trial.otf +0 -0
- package/next/fonts/DrukWide-Bold-Trial.otf +0 -0
- package/next/fonts/DrukWide-Heavy-Trial.otf +0 -0
- package/next/fonts/DrukWide-Medium-Trial.otf +0 -0
- package/next/get-app-router-font-classes.ts +12 -0
- package/next/load-and-return-lux-next-fonts-on-import.ts +94 -0
- package/next/next-font-desc.ts +28 -0
- package/next/not-found-content.mdx +5 -0
- package/next/not-found.tsx +23 -0
- package/next/pages-router-font-vars.tsx +18 -0
- package/next/root-layout.tsx +62 -0
- package/package.json +12 -10
- package/primitives/carousel.tsx +263 -0
- package/primitives/index.ts +8 -1
- package/primitives/toggle-group.tsx +1 -1
- package/primitives/youtube-embed.tsx +1 -1
- package/siteDef/footer/community.tsx +67 -0
- package/siteDef/footer/company.ts +37 -0
- package/siteDef/footer/ecosystem.ts +37 -0
- package/siteDef/footer/index.tsx +26 -0
- package/siteDef/footer/legal.ts +28 -0
- package/siteDef/footer/network.ts +37 -0
- package/siteDef/footer/svg/warpcast-logo.svg +12 -0
- package/siteDef/main-nav.ts +35 -0
- package/style/hanzo-default-colors.css +2 -2
- package/style/social-svg.css +3 -0
- package/tailwind/{fontSize.tailwind.ts → fonts.tailwind.ts} +19 -1
- package/tailwind/index.ts +15 -4
- package/tailwind/lux-tw-fonts.ts +37 -0
- package/tailwind/{tailwind.config.hanzo-preset.js → tailwind.config.base.js} +2 -4
- package/tailwind/typo-plugin/get-plugin-styles.js +42 -42
- package/tailwind/typography-test.mdx +1 -1
- package/types/index.ts +15 -5
- package/types/site-def.ts +36 -0
- package/primitives/icons/index.ts +0 -18
- package/tailwind/fontFamily.tailwind.ts +0 -7
- package/tailwind/tailwind.config.hanzo-preset.d.ts +0 -5
- /package/{primitives → common}/icons/github.tsx +0 -0
- /package/{primitives → common}/icons/youtube-logo.tsx +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
import nextFonts from './load-and-return-lux-next-fonts-on-import'
|
|
3
|
+
import type NextFontDesc from './next-font-desc'
|
|
4
|
+
|
|
5
|
+
const PagesRouterFontVars: React.FC = () => {
|
|
6
|
+
|
|
7
|
+
const fontVars = nextFonts.map((fd: NextFontDesc) => (
|
|
8
|
+
`${fd.cssVar}: ${fd.nextFont.style.fontFamily};`
|
|
9
|
+
)).join('\n')
|
|
10
|
+
|
|
11
|
+
return <style jsx global>{`
|
|
12
|
+
html {
|
|
13
|
+
${fontVars}
|
|
14
|
+
}
|
|
15
|
+
`}</style>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default PagesRouterFontVars
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { type PropsWithChildren } from 'react'
|
|
2
|
+
|
|
3
|
+
import type { Viewport } from 'next'
|
|
4
|
+
|
|
5
|
+
import Header from '../common/header'
|
|
6
|
+
import type { SiteDef } from '../types'
|
|
7
|
+
import getAppRouterBodyFontClasses from './get-app-router-font-classes'
|
|
8
|
+
import { FacebookPixelHead, FacebookPixel } from './analytics/pixel-analytics'
|
|
9
|
+
import { GoogleAnalytics } from '@next/third-parties/google'
|
|
10
|
+
|
|
11
|
+
// Next 14: https://nextjs.org/docs/app/building-your-application/upgrading/codemods#use-viewport-export
|
|
12
|
+
const viewport = {
|
|
13
|
+
themeColor: [
|
|
14
|
+
{ media: '(prefers-color-scheme: light)', color: 'white' },
|
|
15
|
+
{ media: '(prefers-color-scheme: dark)', color: 'black' },
|
|
16
|
+
],
|
|
17
|
+
} satisfies Viewport
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
These '.variable' fields are actually autogenerate css classnames that *define* the actual
|
|
21
|
+
css variables ('--<ugly-name>') that one asks for in the tailwind classes.
|
|
22
|
+
They are what make them available in the global scope. So this MUST
|
|
23
|
+
be done like this for the tailwind font classes to work.
|
|
24
|
+
|
|
25
|
+
(...not to be confused with the css var itself. This field should be named something else!)
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
re body: overflow-y-hidden overflow-x-hidden, h-full
|
|
30
|
+
We cannot have these on body tag for scroll-snap to work on iOS!
|
|
31
|
+
*/
|
|
32
|
+
const bodyClasses =
|
|
33
|
+
'bg-background text-foreground flex flex-col min-h-full ' +
|
|
34
|
+
getAppRouterBodyFontClasses()
|
|
35
|
+
|
|
36
|
+
const RootLayout: React.FC<PropsWithChildren & {
|
|
37
|
+
siteDef: SiteDef
|
|
38
|
+
header?: boolean
|
|
39
|
+
}> = ({
|
|
40
|
+
header = true,
|
|
41
|
+
siteDef,
|
|
42
|
+
children,
|
|
43
|
+
}) => (
|
|
44
|
+
<html lang='en' suppressHydrationWarning className='lux-dark-theme'>
|
|
45
|
+
<head >
|
|
46
|
+
{/* https://stackoverflow.com/a/75716588/11645689 */ }
|
|
47
|
+
<base target='_blank' />
|
|
48
|
+
<FacebookPixelHead/>
|
|
49
|
+
</head>
|
|
50
|
+
<body className={bodyClasses}>
|
|
51
|
+
<FacebookPixel />
|
|
52
|
+
<GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID ?? ''} />
|
|
53
|
+
{header && <Header siteDef={siteDef}/>}
|
|
54
|
+
{children}
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
RootLayout as default,
|
|
61
|
+
viewport
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.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/",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"clean": "rm -rf dist && rm -rf node_modules"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
+
"@hookform/resolvers": "^3.3.2",
|
|
32
33
|
"@next/third-parties": "^14.1.0",
|
|
33
34
|
"@radix-ui/react-accordion": "^1.1.2",
|
|
34
35
|
"@radix-ui/react-aspect-ratio": "^1.0.3",
|
|
@@ -53,28 +54,29 @@
|
|
|
53
54
|
"class-variance-authority": "^0.7.0",
|
|
54
55
|
"clsx": "^2.1.0",
|
|
55
56
|
"cmdk": "^0.2.0",
|
|
57
|
+
"embla-carousel-react": "8.0.0-rc15",
|
|
56
58
|
"input-otp": "^1.0.1",
|
|
57
59
|
"lodash.castarray": "^4.4.0",
|
|
58
60
|
"lodash.isplainobject": "^4.0.6",
|
|
59
61
|
"lodash.merge": "^4.6.2",
|
|
62
|
+
"lucide-react": "^0.344.0",
|
|
60
63
|
"markdown-to-jsx": "^7.3.2",
|
|
61
64
|
"postcss-selector-parser": "^6.0.13",
|
|
62
65
|
"react-day-picker": "^8.7.1",
|
|
66
|
+
"react-device-detect": "^2.2.3",
|
|
67
|
+
"react-hook-form": "^7.47.0",
|
|
63
68
|
"react-intersection-observer": "^9.7.0",
|
|
69
|
+
"react-social-icons": "^6.14.0",
|
|
64
70
|
"tailwind-merge": "^2.2.0",
|
|
65
|
-
"tailwindcss-
|
|
66
|
-
"
|
|
71
|
+
"tailwindcss-interaction-media": "^0.1.0",
|
|
72
|
+
"validator": "^13.11.0",
|
|
73
|
+
"zod": "3.21.4"
|
|
67
74
|
},
|
|
68
75
|
"peerDependencies": {
|
|
69
|
-
"@hookform/resolvers": "^3.3.2",
|
|
70
|
-
"lucide-react": "^0.344.0",
|
|
71
76
|
"next": "^14.1.0",
|
|
72
77
|
"next-themes": "^0.2.1",
|
|
73
78
|
"react": "^18.2.0",
|
|
74
|
-
"react-dom": "^18.2.0"
|
|
75
|
-
"react-hook-form": "^7.47.0",
|
|
76
|
-
"validator": "^13.11.0",
|
|
77
|
-
"zod": "3.21.4"
|
|
79
|
+
"react-dom": "^18.2.0"
|
|
78
80
|
},
|
|
79
81
|
"devDependencies": {
|
|
80
82
|
"@mdx-js/loader": "^3.0.0",
|
|
@@ -83,7 +85,7 @@
|
|
|
83
85
|
"@types/gtag.js": "^0.0.19",
|
|
84
86
|
"@types/lodash.merge": "^4.6.9",
|
|
85
87
|
"@types/mdx": "^2.0.9",
|
|
86
|
-
"@types/react": "^18.2.
|
|
88
|
+
"@types/react": "^18.2.48",
|
|
87
89
|
"@types/react-dom": "^18.2.18",
|
|
88
90
|
"tailwindcss": "^3.4.1",
|
|
89
91
|
"typescript": "5.3.3"
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import useEmblaCarousel, {
|
|
5
|
+
type UseEmblaCarouselType,
|
|
6
|
+
} from 'embla-carousel-react'
|
|
7
|
+
import { ArrowLeft, ArrowRight } from 'lucide-react'
|
|
8
|
+
|
|
9
|
+
import { cn } from '../util'
|
|
10
|
+
import { Button } from '.'
|
|
11
|
+
|
|
12
|
+
type CarouselApi = UseEmblaCarouselType[1]
|
|
13
|
+
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
|
14
|
+
type CarouselOptions = UseCarouselParameters[0]
|
|
15
|
+
type CarouselPlugins = UseCarouselParameters[1]
|
|
16
|
+
|
|
17
|
+
type CarouselProps = {
|
|
18
|
+
options?: CarouselOptions
|
|
19
|
+
plugins?: CarouselPlugins
|
|
20
|
+
orientation?: 'horizontal' | 'vertical'
|
|
21
|
+
setApi?: (api: CarouselApi) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type CarouselContextProps = {
|
|
25
|
+
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
|
|
26
|
+
api: ReturnType<typeof useEmblaCarousel>[1]
|
|
27
|
+
scrollPrev: () => void
|
|
28
|
+
scrollNext: () => void
|
|
29
|
+
canScrollPrev: boolean
|
|
30
|
+
canScrollNext: boolean
|
|
31
|
+
} & CarouselProps
|
|
32
|
+
|
|
33
|
+
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
|
|
34
|
+
|
|
35
|
+
function useCarousel(): CarouselContextProps {
|
|
36
|
+
const context = React.useContext(CarouselContext)
|
|
37
|
+
|
|
38
|
+
if (!context) {
|
|
39
|
+
throw new Error('useCarousel must be used within a <Carousel />')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return context
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const Carousel = React.forwardRef<
|
|
46
|
+
HTMLDivElement,
|
|
47
|
+
React.HTMLAttributes<HTMLDivElement> & CarouselProps
|
|
48
|
+
>(
|
|
49
|
+
(
|
|
50
|
+
{
|
|
51
|
+
orientation = 'horizontal',
|
|
52
|
+
options,
|
|
53
|
+
setApi,
|
|
54
|
+
plugins,
|
|
55
|
+
className,
|
|
56
|
+
children,
|
|
57
|
+
...props
|
|
58
|
+
},
|
|
59
|
+
ref
|
|
60
|
+
) => {
|
|
61
|
+
const [carouselRef, api] = useEmblaCarousel(
|
|
62
|
+
{
|
|
63
|
+
...options,
|
|
64
|
+
axis: orientation === 'horizontal' ? 'x' : 'y',
|
|
65
|
+
},
|
|
66
|
+
plugins
|
|
67
|
+
)
|
|
68
|
+
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
|
|
69
|
+
const [canScrollNext, setCanScrollNext] = React.useState(false)
|
|
70
|
+
|
|
71
|
+
const onSelect = React.useCallback((api: CarouselApi) => {
|
|
72
|
+
if (!api) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
setCanScrollPrev(api.canScrollPrev())
|
|
77
|
+
setCanScrollNext(api.canScrollNext())
|
|
78
|
+
}, [])
|
|
79
|
+
|
|
80
|
+
const scrollPrev = React.useCallback(() => {
|
|
81
|
+
api?.scrollPrev()
|
|
82
|
+
}, [api])
|
|
83
|
+
|
|
84
|
+
const scrollNext = React.useCallback(() => {
|
|
85
|
+
api?.scrollNext()
|
|
86
|
+
}, [api])
|
|
87
|
+
|
|
88
|
+
const handleKeyDown = React.useCallback(
|
|
89
|
+
(event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
90
|
+
if (event.key === 'ArrowLeft') {
|
|
91
|
+
event.preventDefault()
|
|
92
|
+
scrollPrev()
|
|
93
|
+
}
|
|
94
|
+
else if (event.key === 'ArrowRight') {
|
|
95
|
+
event.preventDefault()
|
|
96
|
+
scrollNext()
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
[scrollPrev, scrollNext]
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
React.useEffect(() => {
|
|
103
|
+
if (!api || !setApi) {
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
setApi(api)
|
|
108
|
+
}, [api, setApi])
|
|
109
|
+
|
|
110
|
+
React.useEffect(() => {
|
|
111
|
+
if (!api) {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
onSelect(api)
|
|
116
|
+
api.on('reInit', onSelect)
|
|
117
|
+
api.on('select', onSelect)
|
|
118
|
+
|
|
119
|
+
return () => {
|
|
120
|
+
api?.off('select', onSelect)
|
|
121
|
+
}
|
|
122
|
+
}, [api, onSelect])
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<CarouselContext.Provider
|
|
126
|
+
value={{
|
|
127
|
+
carouselRef,
|
|
128
|
+
api: api,
|
|
129
|
+
options,
|
|
130
|
+
orientation:
|
|
131
|
+
orientation || (options?.axis === 'y' ? 'vertical' : 'horizontal'),
|
|
132
|
+
scrollPrev,
|
|
133
|
+
scrollNext,
|
|
134
|
+
canScrollPrev,
|
|
135
|
+
canScrollNext,
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
<div
|
|
139
|
+
ref={ref}
|
|
140
|
+
onKeyDownCapture={handleKeyDown}
|
|
141
|
+
className={cn('relative', className)}
|
|
142
|
+
role='region'
|
|
143
|
+
aria-roledescription='carousel'
|
|
144
|
+
{...props}
|
|
145
|
+
>
|
|
146
|
+
{children}
|
|
147
|
+
</div>
|
|
148
|
+
</CarouselContext.Provider>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
Carousel.displayName = 'Carousel'
|
|
153
|
+
|
|
154
|
+
const CarouselContent = React.forwardRef<
|
|
155
|
+
HTMLDivElement,
|
|
156
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
157
|
+
>(({ className, ...props }, ref) => {
|
|
158
|
+
const { carouselRef, orientation } = useCarousel()
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<div ref={carouselRef} className='overflow-hidden'>
|
|
162
|
+
<div
|
|
163
|
+
ref={ref}
|
|
164
|
+
className={cn(
|
|
165
|
+
'flex',
|
|
166
|
+
orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',
|
|
167
|
+
className
|
|
168
|
+
)}
|
|
169
|
+
{...props}
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
)
|
|
173
|
+
})
|
|
174
|
+
CarouselContent.displayName = 'CarouselContent'
|
|
175
|
+
|
|
176
|
+
const CarouselItem = React.forwardRef<
|
|
177
|
+
HTMLDivElement,
|
|
178
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
179
|
+
>(({ className, ...props }, ref) => {
|
|
180
|
+
const { orientation } = useCarousel()
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<div
|
|
184
|
+
ref={ref}
|
|
185
|
+
role='group'
|
|
186
|
+
aria-roledescription='slide'
|
|
187
|
+
className={cn(
|
|
188
|
+
'min-w-0 shrink-0 grow-0 basis-full',
|
|
189
|
+
orientation === 'horizontal' ? 'pl-4' : 'pt-4',
|
|
190
|
+
className
|
|
191
|
+
)}
|
|
192
|
+
{...props}
|
|
193
|
+
/>
|
|
194
|
+
)
|
|
195
|
+
})
|
|
196
|
+
CarouselItem.displayName = 'CarouselItem'
|
|
197
|
+
|
|
198
|
+
const CarouselPrevious = React.forwardRef<
|
|
199
|
+
HTMLButtonElement,
|
|
200
|
+
React.ComponentProps<typeof Button>
|
|
201
|
+
>(({ className, variant = 'outline', size = 'icon', ...props }, ref) => {
|
|
202
|
+
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<Button
|
|
206
|
+
ref={ref}
|
|
207
|
+
variant={variant}
|
|
208
|
+
size={size}
|
|
209
|
+
className={cn(
|
|
210
|
+
'absolute h-8 w-8 rounded-full',
|
|
211
|
+
orientation === 'horizontal'
|
|
212
|
+
? '-left-12 top-1/2 -translate-y-1/2'
|
|
213
|
+
: '-top-12 left-1/2 -translate-x-1/2 rotate-90',
|
|
214
|
+
className
|
|
215
|
+
)}
|
|
216
|
+
disabled={!canScrollPrev}
|
|
217
|
+
onClick={scrollPrev}
|
|
218
|
+
{...props}
|
|
219
|
+
>
|
|
220
|
+
<ArrowLeft className='h-4 w-4' />
|
|
221
|
+
<span className='sr-only'>Previous slide</span>
|
|
222
|
+
</Button>
|
|
223
|
+
)
|
|
224
|
+
})
|
|
225
|
+
CarouselPrevious.displayName = 'CarouselPrevious'
|
|
226
|
+
|
|
227
|
+
const CarouselNext = React.forwardRef<
|
|
228
|
+
HTMLButtonElement,
|
|
229
|
+
React.ComponentProps<typeof Button>
|
|
230
|
+
>(({ className, variant = 'outline', size = 'icon', ...props }, ref) => {
|
|
231
|
+
const { orientation, scrollNext, canScrollNext } = useCarousel()
|
|
232
|
+
|
|
233
|
+
return (
|
|
234
|
+
<Button
|
|
235
|
+
ref={ref}
|
|
236
|
+
variant={variant}
|
|
237
|
+
size={size}
|
|
238
|
+
className={cn(
|
|
239
|
+
'absolute h-8 w-8 rounded-full',
|
|
240
|
+
orientation === 'horizontal'
|
|
241
|
+
? '-right-12 top-1/2 -translate-y-1/2'
|
|
242
|
+
: '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
|
|
243
|
+
className
|
|
244
|
+
)}
|
|
245
|
+
disabled={!canScrollNext}
|
|
246
|
+
onClick={scrollNext}
|
|
247
|
+
{...props}
|
|
248
|
+
>
|
|
249
|
+
<ArrowRight className='h-4 w-4' />
|
|
250
|
+
<span className='sr-only'>Next slide</span>
|
|
251
|
+
</Button>
|
|
252
|
+
)
|
|
253
|
+
})
|
|
254
|
+
CarouselNext.displayName = 'CarouselNext'
|
|
255
|
+
|
|
256
|
+
export {
|
|
257
|
+
type CarouselApi,
|
|
258
|
+
Carousel,
|
|
259
|
+
CarouselContent,
|
|
260
|
+
CarouselItem,
|
|
261
|
+
CarouselPrevious,
|
|
262
|
+
CarouselNext,
|
|
263
|
+
}
|
package/primitives/index.ts
CHANGED
|
@@ -131,6 +131,14 @@ export {
|
|
|
131
131
|
InputOTPSlot,
|
|
132
132
|
} from './input-otp'
|
|
133
133
|
|
|
134
|
+
export {
|
|
135
|
+
Carousel,
|
|
136
|
+
CarouselContent,
|
|
137
|
+
CarouselItem,
|
|
138
|
+
CarouselNext,
|
|
139
|
+
CarouselPrevious,
|
|
140
|
+
} from './carousel'
|
|
141
|
+
|
|
134
142
|
export { Toggle, toggleVariants } from './toggle'
|
|
135
143
|
export { ToggleGroup, ToggleGroupItem } from './toggle-group'
|
|
136
144
|
|
|
@@ -157,4 +165,3 @@ export { default as NavItems} from './nav-items'
|
|
|
157
165
|
export { default as Main } from './main'
|
|
158
166
|
export { default as ListBox } from './list-box'
|
|
159
167
|
|
|
160
|
-
export * as Icons from './icons'
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { LinkDef } from '../../types'
|
|
2
|
+
import { Icons } from '../../common'
|
|
3
|
+
|
|
4
|
+
// @ts-ignore (will build in project that has @svgr support)
|
|
5
|
+
import SVG_warp_logo from './svg/warpcast-logo.svg'
|
|
6
|
+
|
|
7
|
+
const SOC_ICON_SIZE = 18
|
|
8
|
+
|
|
9
|
+
export default [
|
|
10
|
+
{
|
|
11
|
+
title: 'Community',
|
|
12
|
+
href: '',
|
|
13
|
+
variant: 'linkFG',
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
{
|
|
17
|
+
title: 'Lux Channel',
|
|
18
|
+
href: 'https://warpcast.com/~/channel/lux',
|
|
19
|
+
icon: <SVG_warp_logo width={SOC_ICON_SIZE} height={SOC_ICON_SIZE} /> //<Icons.SocialIcon network='warpcast' size={SOC_ICON_SIZE} />
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: 'Lux Discussion',
|
|
23
|
+
href: 'https://github.com/orgs/luxdefi/discussions',
|
|
24
|
+
icon: <Icons.SocialIcon network='github' size={SOC_ICON_SIZE} />
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
{
|
|
29
|
+
title: 'Discord',
|
|
30
|
+
href: 'https://discord.gg/luxdefi',
|
|
31
|
+
external: true,
|
|
32
|
+
icon: <Icons.SocialIcon network='discord' size={SOC_ICON_SIZE} />
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
title: 'Telegram',
|
|
36
|
+
href: 'https://t.me/luxdefi',
|
|
37
|
+
external: true,
|
|
38
|
+
icon: <Icons.SocialIcon network='telegram' size={SOC_ICON_SIZE} />
|
|
39
|
+
},
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
title: '@luxdefi',
|
|
44
|
+
href: 'https://twitter.com/luxdefi',
|
|
45
|
+
icon: <Icons.SocialIcon network='x' size={SOC_ICON_SIZE} />
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
title: '@luxdefi',
|
|
49
|
+
href: 'https://facebook.com/luxdefi',
|
|
50
|
+
icon: <Icons.SocialIcon network='facebook' size={SOC_ICON_SIZE + 2} />
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
title: '@luxdefi',
|
|
54
|
+
href: 'https://www.instagram.com/luxdefi',
|
|
55
|
+
icon: <Icons.SocialIcon network='instagram' size={SOC_ICON_SIZE + 2} />
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: '@luxdefi',
|
|
59
|
+
href: 'https://linkedin.com/company/luxdefi',
|
|
60
|
+
icon: <Icons.SocialIcon network='linkedin' size={SOC_ICON_SIZE + 2} />
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
title: '@luxdefi',
|
|
64
|
+
href: 'https://www.youtube.com/@luxdefi',
|
|
65
|
+
icon: <Icons.SocialIcon network='youtube' size={SOC_ICON_SIZE + 2} />
|
|
66
|
+
},
|
|
67
|
+
] satisfies LinkDef[]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { LinkDef } from '../../types'
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
{
|
|
5
|
+
title: 'Company',
|
|
6
|
+
href: "https://lux.partners/",
|
|
7
|
+
variant: 'linkFG',
|
|
8
|
+
newTab: false,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
title: 'About',
|
|
12
|
+
href: 'https://lux.partners',
|
|
13
|
+
newTab: false,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: 'Brand',
|
|
17
|
+
href: 'https://drive.google.com/drive/folders/14OJtKLVakGY6883XO9yGbiHtlFxQUUm5?usp=share_link',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: 'Careers',
|
|
21
|
+
href: 'https://docs.google.com/document/d/1SCt0Hg7EIs06TootKCA1am1xo4mcXoKF/edit#heading=h.30j0zll',
|
|
22
|
+
newTab: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: 'Partnerships',
|
|
26
|
+
href: 'https://apply.lux.partners/',
|
|
27
|
+
newTab: false,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
title: 'Press',
|
|
31
|
+
href: 'mailto:ai@lux.partners?subject=%E2%96%BC%20Press',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
title: 'Help',
|
|
35
|
+
href: 'mailto:ai@lux.partners?subject=%E2%96%BC%20Help',
|
|
36
|
+
},
|
|
37
|
+
] satisfies LinkDef[]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { LinkDef } from '../../types'
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
{
|
|
5
|
+
title: 'Ecosystem',
|
|
6
|
+
href: '',
|
|
7
|
+
variant: 'linkFG'
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
title: 'Lux Silver',
|
|
11
|
+
href: 'https://lux.market/silver',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
title: 'Lux Gold',
|
|
15
|
+
href: 'https://lux.market/gold',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
title: 'Lux Credit Card',
|
|
19
|
+
href: 'https://lux.credit',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: 'Lux Exchange',
|
|
23
|
+
href: 'https://lux.exchange',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
title: 'Lux Finance',
|
|
27
|
+
href: 'https://lux.finance',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
title: 'Lux Market',
|
|
31
|
+
href: 'https://lux.market',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
title: 'Lux Network',
|
|
35
|
+
href: 'https://lux.network',
|
|
36
|
+
},
|
|
37
|
+
] satisfies LinkDef[]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { LinkDef } from '../../types'
|
|
2
|
+
|
|
3
|
+
import ecosystem from './ecosystem'
|
|
4
|
+
import network from './network'
|
|
5
|
+
import company from './company'
|
|
6
|
+
import community from './community'
|
|
7
|
+
import { legal, legalColumn } from './legal'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const common = [
|
|
11
|
+
ecosystem,
|
|
12
|
+
network,
|
|
13
|
+
company,
|
|
14
|
+
community,
|
|
15
|
+
] satisfies LinkDef[][]
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
ecosystem,
|
|
19
|
+
network,
|
|
20
|
+
company,
|
|
21
|
+
community,
|
|
22
|
+
legal,
|
|
23
|
+
legalColumn,
|
|
24
|
+
common as default
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LinkDef } from '../../types'
|
|
2
|
+
|
|
3
|
+
const legal: LinkDef[] = [
|
|
4
|
+
{
|
|
5
|
+
title: 'Terms and Conditions',
|
|
6
|
+
href: '/terms',
|
|
7
|
+
newTab: true,
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
title: 'Privacy Policy',
|
|
11
|
+
href: '/privacy',
|
|
12
|
+
newTab: true,
|
|
13
|
+
},
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
const title: LinkDef =
|
|
17
|
+
{
|
|
18
|
+
title: 'Legal',
|
|
19
|
+
href: '',
|
|
20
|
+
variant: 'linkFG',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const legalColumn: LinkDef[] = [title, ...legal]
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
legal,
|
|
27
|
+
legalColumn
|
|
28
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { LinkDef } from '../../types'
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
{
|
|
5
|
+
title: 'Network',
|
|
6
|
+
href: "https://lux.network/",
|
|
7
|
+
variant: 'linkFG'
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
title: 'Lux Bridge',
|
|
11
|
+
href: "https://bridge.lux.network/",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
title: 'Lux Explorer',
|
|
15
|
+
href: "https://explore.lux.network/",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
title: 'Lux Wallet',
|
|
19
|
+
href: "https://wallet.lux.network/",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: 'Lux Safe',
|
|
23
|
+
href: "https://safe.lux.network/",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
title: 'Lux Validator',
|
|
27
|
+
href: "https://lux.market/validator/",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
title: 'Open Source',
|
|
31
|
+
href: 'https://github.com/luxdefi',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
title: 'Launch Subnet',
|
|
35
|
+
href: 'https://docs.lux.network/build/subnet/hello-subnet',
|
|
36
|
+
},
|
|
37
|
+
] satisfies LinkDef[]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg viewBox="0 0 1260 1260" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<g clip-path="url(#clip0_1_2)">
|
|
3
|
+
<!-- path d="M947.747 1259.61H311.861C139.901 1259.61 0 1119.72 0 947.752V311.871C0 139.907 139.901 0.00541362 311.861 0.00541362H947.747C1119.71 0.00541362 1259.61 139.907 1259.61 311.871V947.752C1259.61 1119.72 1119.71 1259.61 947.747 1259.61Z" fill="#472A91"></path -->
|
|
4
|
+
<path d="M826.513 398.633L764.404 631.889L702.093 398.633H558.697L495.789 633.607L433.087 398.633H269.764L421.528 914.36H562.431L629.807 674.876L697.181 914.36H838.388L989.819 398.633H826.513Z" fill="currentColor">
|
|
5
|
+
</path>
|
|
6
|
+
</g>
|
|
7
|
+
<defs>
|
|
8
|
+
<clipPath id="clip0_1_2">
|
|
9
|
+
<rect width="1259.61" height="1259.61" fill="white"></rect>
|
|
10
|
+
</clipPath>
|
|
11
|
+
</defs>
|
|
12
|
+
</svg>
|