@luxfi/core 4.3.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. package/components/access-code-input.tsx +71 -0
  2. package/components/auth/login-panel.tsx +80 -0
  3. package/components/chat-widget.tsx +77 -0
  4. package/components/commerce/bag-button.tsx +67 -0
  5. package/components/commerce/checkout-panel/close-button.tsx +23 -0
  6. package/components/commerce/checkout-panel/dt-bag-carousel.tsx +36 -0
  7. package/components/commerce/checkout-panel/dt-checkout-panel.tsx +68 -0
  8. package/components/commerce/checkout-panel/index.tsx +124 -0
  9. package/components/commerce/checkout-panel/links-row.tsx +21 -0
  10. package/components/commerce/checkout-panel/mb-checkout-panel.tsx +51 -0
  11. package/components/commerce/checkout-panel/steps-indicator.tsx +39 -0
  12. package/components/commerce/checkout-panel/thank-you.tsx +18 -0
  13. package/components/commerce/desktop-bag-popup.tsx +78 -0
  14. package/components/commerce/mobile-bag-drawer.tsx +51 -0
  15. package/components/commerce/mobile-menu-toggle-button.tsx +35 -0
  16. package/components/commerce/mobile-nav-menu.tsx +64 -0
  17. package/components/contact-dialog/contact-form.tsx +112 -0
  18. package/components/contact-dialog/disclaimer.tsx +13 -0
  19. package/components/contact-dialog/index.tsx +64 -0
  20. package/components/copyright.tsx +21 -0
  21. package/components/footer.tsx +78 -0
  22. package/components/header/desktop.tsx +54 -0
  23. package/components/header/index.tsx +26 -0
  24. package/components/header/mobile.tsx +161 -0
  25. package/components/header/theme-toggle.tsx +26 -0
  26. package/components/icons/bag-icon.tsx +10 -0
  27. package/components/icons/github.tsx +14 -0
  28. package/components/icons/index.tsx +35 -0
  29. package/components/icons/lux-logo.tsx +10 -0
  30. package/components/icons/secure-delivery.tsx +13 -0
  31. package/components/icons/social-icon.tsx +35 -0
  32. package/components/icons/social-svg.css +3 -0
  33. package/components/icons/youtube-logo.tsx +59 -0
  34. package/components/index.ts +26 -0
  35. package/components/logo.tsx +81 -0
  36. package/components/mini-chart/index.tsx +8 -0
  37. package/components/mini-chart/mini-chart-props.ts +44 -0
  38. package/components/mini-chart/mini-chart.tsx +85 -0
  39. package/components/mini-chart/wrapper.tsx +23 -0
  40. package/components/not-found/index.tsx +27 -0
  41. package/components/not-found/not-found-content.mdx +5 -0
  42. package/components/root-layout.tsx +71 -0
  43. package/components/scripts.tsx +23 -0
  44. package/conf/index.ts +50 -0
  45. package/environment.d.ts +6 -0
  46. package/next/analytics/fpixel.ts +16 -0
  47. package/next/analytics/google-analytics.ts +14 -0
  48. package/next/analytics/index.ts +3 -0
  49. package/next/analytics/pixel-analytics.tsx +55 -0
  50. package/next/determine-device-mw.ts +16 -0
  51. package/next/font/get-app-router-font-classes.ts +12 -0
  52. package/next/font/load-and-return-lux-next-fonts-on-import.ts +67 -0
  53. package/next/font/local/Druk-Wide-Bold.ttf +0 -0
  54. package/next/font/local/Druk-Wide-Medium.ttf +0 -0
  55. package/next/font/next-font-desc.ts +28 -0
  56. package/next/font/pages-router-font-vars.tsx +18 -0
  57. package/next/head-metadata/from-next/metadata-types.ts +158 -0
  58. package/next/head-metadata/from-next/opengraph-types.ts +267 -0
  59. package/next/head-metadata/from-next/twitter-types.ts +92 -0
  60. package/next/head-metadata/index.tsx +208 -0
  61. package/next/index.ts +1 -0
  62. package/package.json +72 -0
  63. package/server-actions/firebase-app.ts +14 -0
  64. package/server-actions/index.ts +5 -0
  65. package/server-actions/store-contact.ts +51 -0
  66. package/site-def/footer/community.tsx +67 -0
  67. package/site-def/footer/company.ts +37 -0
  68. package/site-def/footer/ecosystem.ts +37 -0
  69. package/site-def/footer/index.tsx +26 -0
  70. package/site-def/footer/legal.ts +28 -0
  71. package/site-def/footer/network.ts +45 -0
  72. package/site-def/footer/svg/warpcast-logo.svg +12 -0
  73. package/site-def/index.ts +3 -0
  74. package/site-def/main-nav.ts +35 -0
  75. package/site-def/site-def.ts +37 -0
  76. package/style/lux-colors.css +85 -0
  77. package/style/lux-global.css +19 -0
  78. package/tailwind/fontFamily.tailwind.lux.ts +18 -0
  79. package/tailwind/index.ts +2 -0
  80. package/tailwind/lux-tw-fonts.ts +40 -0
  81. package/tailwind/tailwind.config.lux-preset.ts +10 -0
  82. package/tsconfig.json +10 -0
  83. package/types/contact-info.ts +11 -0
  84. package/types/index.ts +1 -0
@@ -0,0 +1,267 @@
1
+ import type { AbsoluteTemplateString, TemplateString } from './metadata-types'
2
+
3
+ export type OpenGraphType =
4
+ | 'article'
5
+ | 'book'
6
+ | 'music.song'
7
+ | 'music.album'
8
+ | 'music.playlist'
9
+ | 'music.radio_station'
10
+ | 'profile'
11
+ | 'website'
12
+ | 'video.tv_show'
13
+ | 'video.other'
14
+ | 'video.movie'
15
+ | 'video.episode'
16
+
17
+ export type OpenGraph =
18
+ | OpenGraphWebsite
19
+ | OpenGraphArticle
20
+ | OpenGraphBook
21
+ | OpenGraphProfile
22
+ | OpenGraphMusicSong
23
+ | OpenGraphMusicAlbum
24
+ | OpenGraphMusicPlaylist
25
+ | OpenGraphRadioStation
26
+ | OpenGraphVideoMovie
27
+ | OpenGraphVideoEpisode
28
+ | OpenGraphVideoTVShow
29
+ | OpenGraphVideoOther
30
+ | OpenGraphMetadata
31
+
32
+ // update this type to reflect actual locales
33
+ type Locale = string
34
+
35
+ type OpenGraphMetadata = {
36
+ determiner?: 'a' | 'an' | 'the' | 'auto' | ''
37
+ title?: string | TemplateString
38
+ description?: string
39
+ emails?: string | Array<string>
40
+ phoneNumbers?: string | Array<string>
41
+ faxNumbers?: string | Array<string>
42
+ siteName?: string
43
+ locale?: Locale
44
+ alternateLocale?: Locale | Array<Locale>
45
+ images?: OGImage | Array<OGImage>
46
+ audio?: OGAudio | Array<OGAudio>
47
+ videos?: OGVideo | Array<OGVideo>
48
+ url?: string | URL
49
+ countryName?: string
50
+ ttl?: number
51
+ }
52
+ export type OpenGraphWebsite = OpenGraphMetadata & {
53
+ type: 'website'
54
+ }
55
+ type OpenGraphArticle = OpenGraphMetadata & {
56
+ type: 'article'
57
+ publishedTime?: string // datetime
58
+ modifiedTime?: string // datetime
59
+ expirationTime?: string // datetime
60
+ authors?: null | string | URL | Array<string | URL>
61
+ section?: null | string
62
+ tags?: null | string | Array<string>
63
+ }
64
+ type OpenGraphBook = OpenGraphMetadata & {
65
+ type: 'book'
66
+ isbn?: null | string
67
+ releaseDate?: null | string // datetime
68
+ authors?: null | string | URL | Array<string | URL>
69
+ tags?: null | string | Array<string>
70
+ }
71
+ type OpenGraphProfile = OpenGraphMetadata & {
72
+ type: 'profile'
73
+ firstName?: null | string
74
+ lastName?: null | string
75
+ username?: null | string
76
+ gender?: null | string
77
+ }
78
+ type OpenGraphMusicSong = OpenGraphMetadata & {
79
+ type: 'music.song'
80
+ duration?: null | number
81
+ albums?: null | string | URL | OGAlbum | Array<string | URL | OGAlbum>
82
+ musicians?: null | string | URL | Array<string | URL>
83
+ }
84
+ type OpenGraphMusicAlbum = OpenGraphMetadata & {
85
+ type: 'music.album'
86
+ songs?: null | string | URL | OGSong | Array<string | URL | OGSong>
87
+ musicians?: null | string | URL | Array<string | URL>
88
+ releaseDate?: null | string // datetime
89
+ }
90
+ type OpenGraphMusicPlaylist = OpenGraphMetadata & {
91
+ type: 'music.playlist'
92
+ songs?: null | string | URL | OGSong | Array<string | URL | OGSong>
93
+ creators?: null | string | URL | Array<string | URL>
94
+ }
95
+ type OpenGraphRadioStation = OpenGraphMetadata & {
96
+ type: 'music.radio_station'
97
+ creators?: null | string | URL | Array<string | URL>
98
+ }
99
+ type OpenGraphVideoMovie = OpenGraphMetadata & {
100
+ type: 'video.movie'
101
+ actors?: null | string | URL | OGActor | Array<string | URL | OGActor>
102
+ directors?: null | string | URL | Array<string | URL>
103
+ writers?: null | string | URL | Array<string | URL>
104
+ duration?: null | number
105
+ releaseDate?: null | string // datetime
106
+ tags?: null | string | Array<string>
107
+ }
108
+ type OpenGraphVideoEpisode = OpenGraphMetadata & {
109
+ type: 'video.episode'
110
+ actors?: null | string | URL | OGActor | Array<string | URL | OGActor>
111
+ directors?: null | string | URL | Array<string | URL>
112
+ writers?: null | string | URL | Array<string | URL>
113
+ duration?: null | number
114
+ releaseDate?: null | string // datetime
115
+ tags?: null | string | Array<string>
116
+ series?: null | string | URL
117
+ }
118
+ type OpenGraphVideoTVShow = OpenGraphMetadata & {
119
+ type: 'video.tv_show'
120
+ }
121
+ type OpenGraphVideoOther = OpenGraphMetadata & {
122
+ type: 'video.other'
123
+ }
124
+
125
+ export type OGImage = string | OGImageDescriptor | URL
126
+ type OGImageDescriptor = {
127
+ url: string | URL
128
+ secureUrl?: string | URL
129
+ alt?: string
130
+ type?: string
131
+ width?: string | number
132
+ height?: string | number
133
+ }
134
+ type OGAudio = string | OGAudioDescriptor | URL
135
+ type OGAudioDescriptor = {
136
+ url: string | URL
137
+ secureUrl?: string | URL
138
+ type?: string
139
+ }
140
+ type OGVideo = string | OGVideoDescriptor | URL
141
+ type OGVideoDescriptor = {
142
+ url: string | URL
143
+ secureUrl?: string | URL
144
+ type?: string
145
+ width?: string | number
146
+ height?: string | number
147
+ }
148
+
149
+ export type ResolvedOpenGraph =
150
+ | ResolvedOpenGraphWebsite
151
+ | ResolvedOpenGraphArticle
152
+ | ResolvedOpenGraphBook
153
+ | ResolvedOpenGraphProfile
154
+ | ResolvedOpenGraphMusicSong
155
+ | ResolvedOpenGraphMusicAlbum
156
+ | ResolvedOpenGraphMusicPlaylist
157
+ | ResolvedOpenGraphRadioStation
158
+ | ResolvedOpenGraphVideoMovie
159
+ | ResolvedOpenGraphVideoEpisode
160
+ | ResolvedOpenGraphVideoTVShow
161
+ | ResolvedOpenGraphVideoOther
162
+ | ResolvedOpenGraphMetadata
163
+
164
+ type ResolvedOpenGraphMetadata = {
165
+ determiner?: 'a' | 'an' | 'the' | 'auto' | ''
166
+ title: AbsoluteTemplateString
167
+ description?: string
168
+ emails?: Array<string>
169
+ phoneNumbers?: Array<string>
170
+ faxNumbers?: Array<string>
171
+ siteName?: string
172
+ locale?: Locale
173
+ alternateLocale?: Array<Locale>
174
+ images?: Array<OGImage>
175
+ audio?: Array<OGAudio>
176
+ videos?: Array<OGVideo>
177
+ url: null | URL | string
178
+ countryName?: string
179
+ ttl?: number
180
+ }
181
+ type ResolvedOpenGraphWebsite = ResolvedOpenGraphMetadata & {
182
+ type: 'website'
183
+ }
184
+ type ResolvedOpenGraphArticle = ResolvedOpenGraphMetadata & {
185
+ type: 'article'
186
+ publishedTime?: string // datetime
187
+ modifiedTime?: string // datetime
188
+ expirationTime?: string // datetime
189
+ authors?: Array<string>
190
+ section?: string
191
+ tags?: Array<string>
192
+ }
193
+ type ResolvedOpenGraphBook = ResolvedOpenGraphMetadata & {
194
+ type: 'book'
195
+ isbn?: string
196
+ releaseDate?: string // datetime
197
+ authors?: Array<string>
198
+ tags?: Array<string>
199
+ }
200
+ type ResolvedOpenGraphProfile = ResolvedOpenGraphMetadata & {
201
+ type: 'profile'
202
+ firstName?: string
203
+ lastName?: string
204
+ username?: string
205
+ gender?: string
206
+ }
207
+ type ResolvedOpenGraphMusicSong = ResolvedOpenGraphMetadata & {
208
+ type: 'music.song'
209
+ duration?: number
210
+ albums?: Array<OGAlbum>
211
+ musicians?: Array<string | URL>
212
+ }
213
+ type ResolvedOpenGraphMusicAlbum = ResolvedOpenGraphMetadata & {
214
+ type: 'music.album'
215
+ songs?: Array<string | URL | OGSong>
216
+ musicians?: Array<string | URL>
217
+ releaseDate?: string // datetime
218
+ }
219
+ type ResolvedOpenGraphMusicPlaylist = ResolvedOpenGraphMetadata & {
220
+ type: 'music.playlist'
221
+ songs?: Array<string | URL | OGSong>
222
+ creators?: Array<string | URL>
223
+ }
224
+ type ResolvedOpenGraphRadioStation = ResolvedOpenGraphMetadata & {
225
+ type: 'music.radio_station'
226
+ creators?: Array<string | URL>
227
+ }
228
+ type ResolvedOpenGraphVideoMovie = ResolvedOpenGraphMetadata & {
229
+ type: 'video.movie'
230
+ actors?: Array<string | URL | OGActor>
231
+ directors?: Array<string | URL>
232
+ writers?: Array<string | URL>
233
+ duration?: number
234
+ releaseDate?: string // datetime
235
+ tags?: Array<string>
236
+ }
237
+ type ResolvedOpenGraphVideoEpisode = ResolvedOpenGraphMetadata & {
238
+ type: 'video.episode'
239
+ actors?: Array<string | URL | OGActor>
240
+ directors?: Array<string | URL>
241
+ writers?: Array<string | URL>
242
+ duration?: number
243
+ releaseDate?: string // datetime
244
+ tags?: Array<string>
245
+ series?: string | URL
246
+ }
247
+ type ResolvedOpenGraphVideoTVShow = ResolvedOpenGraphMetadata & {
248
+ type: 'video.tv_show'
249
+ }
250
+ type ResolvedOpenGraphVideoOther = ResolvedOpenGraphMetadata & {
251
+ type: 'video.other'
252
+ }
253
+
254
+ type OGSong = {
255
+ url: string | URL
256
+ disc?: number
257
+ track?: number
258
+ }
259
+ type OGAlbum = {
260
+ url: string | URL
261
+ disc?: number
262
+ track?: number
263
+ }
264
+ type OGActor = {
265
+ url: string | URL
266
+ role?: string
267
+ }
@@ -0,0 +1,92 @@
1
+ // Reference: https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup
2
+
3
+ import type { AbsoluteTemplateString, TemplateString } from './metadata-types'
4
+
5
+ export type Twitter =
6
+ | TwitterSummary
7
+ | TwitterSummaryLargeImage
8
+ | TwitterPlayer
9
+ | TwitterApp
10
+ | TwitterMetadata
11
+
12
+ type TwitterMetadata = {
13
+ // defaults to card="summary"
14
+ site?: string // username for account associated to the site itself
15
+ siteId?: string // id for account associated to the site itself
16
+ creator?: string // username for the account associated to the creator of the content on the site
17
+ creatorId?: string // id for the account associated to the creator of the content on the site
18
+ description?: string
19
+ title?: string | TemplateString
20
+ images?: TwitterImage | Array<TwitterImage>
21
+ }
22
+ type TwitterSummary = TwitterMetadata & {
23
+ card: 'summary'
24
+ }
25
+ type TwitterSummaryLargeImage = TwitterMetadata & {
26
+ card: 'summary_large_image'
27
+ }
28
+ type TwitterPlayer = TwitterMetadata & {
29
+ card: 'player'
30
+ players: TwitterPlayerDescriptor | Array<TwitterPlayerDescriptor>
31
+ }
32
+ type TwitterApp = TwitterMetadata & {
33
+ card: 'app'
34
+ app: TwitterAppDescriptor
35
+ }
36
+ export type TwitterAppDescriptor = {
37
+ id: {
38
+ iphone?: string | number
39
+ ipad?: string | number
40
+ googleplay?: string
41
+ }
42
+ url?: {
43
+ iphone?: string | URL
44
+ ipad?: string | URL
45
+ googleplay?: string | URL
46
+ }
47
+ name?: string
48
+ }
49
+
50
+ export type TwitterImage = string | TwitterImageDescriptor | URL
51
+ type TwitterImageDescriptor = {
52
+ url: string | URL
53
+ alt?: string
54
+ secureUrl?: string | URL
55
+ type?: string
56
+ width?: string | number
57
+ height?: string | number
58
+ }
59
+ type TwitterPlayerDescriptor = {
60
+ playerUrl: string | URL
61
+ streamUrl: string | URL
62
+ width: number
63
+ height: number
64
+ }
65
+
66
+ type ResolvedTwitterImage = {
67
+ url: string | URL
68
+ alt?: string
69
+ secureUrl?: string | URL
70
+ type?: string
71
+ width?: string | number
72
+ height?: string | number
73
+ }
74
+ type ResolvedTwitterSummary = {
75
+ site: string | null
76
+ siteId: string | null
77
+ creator: string | null
78
+ creatorId: string | null
79
+ description: string | null
80
+ title: AbsoluteTemplateString
81
+ images?: Array<ResolvedTwitterImage>
82
+ }
83
+ type ResolvedTwitterPlayer = ResolvedTwitterSummary & {
84
+ players: Array<TwitterPlayerDescriptor>
85
+ }
86
+ type ResolvedTwitterApp = ResolvedTwitterSummary & { app: TwitterAppDescriptor }
87
+
88
+ export type ResolvedTwitterMetadata =
89
+ | ({ card: 'summary' } & ResolvedTwitterSummary)
90
+ | ({ card: 'summary_large_image' } & ResolvedTwitterSummary)
91
+ | ({ card: 'player' } & ResolvedTwitterPlayer)
92
+ | ({ card: 'app' } & ResolvedTwitterApp)
@@ -0,0 +1,208 @@
1
+ import React from 'react'
2
+
3
+ import type { Metadata } from 'next'
4
+ import Head from "next/head"
5
+
6
+ import type {
7
+ IconDescriptor,
8
+ TemplateString,
9
+ Author,
10
+ ThemeColorDescriptor
11
+ } from './from-next/metadata-types'
12
+
13
+ import type { OpenGraph, OGImage } from './from-next/opengraph-types'
14
+ import type { Twitter, TwitterImage } from './from-next/twitter-types'
15
+
16
+ /*
17
+ NOTE: This is ONLY for sites that use the pages router in next.
18
+ The app router does this automatically
19
+ */
20
+
21
+ const getURLasString = (url: string | URL) => {
22
+ return (
23
+ (typeof url === 'string') ? (url as string) : (url.href)
24
+ )
25
+ }
26
+
27
+ // https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
28
+ const Icons: React.FC<{icons: IconDescriptor[]}> = ({
29
+ icons
30
+ }) => {
31
+ return <Head>
32
+ {icons.map(({url, ...rest}: IconDescriptor, index) => (
33
+ <link {...rest} href={getURLasString(url)} key={`icons-${index}`}/>
34
+ ))}
35
+ </Head>
36
+ }
37
+
38
+ export const getTitleFromTemplateString = (title: string | TemplateString | null | undefined): string | null => {
39
+
40
+ if (!title) {
41
+ return null
42
+ }
43
+ if (typeof title === 'object') {
44
+ if ('default' in title) {
45
+ return title.default
46
+ }
47
+ else if ('absolute' in title) {
48
+ return title.absolute
49
+ }
50
+ }
51
+ return title as string
52
+ }
53
+
54
+ const Authors: React.FC<{
55
+ authors: null | undefined | Author | Array<Author>
56
+ }> = ({
57
+ authors
58
+ }) => {
59
+
60
+ const Author: React.FC<{author: Author}> = ({author}) => (<>
61
+ {author.name && <meta name="author" content={author.name} />}
62
+ {author.url && <link rel="author" href={getURLasString(author.url)}/>}
63
+ </>)
64
+
65
+ if (!authors) {
66
+ return null
67
+ }
68
+
69
+ if (Array.isArray(authors)) {
70
+ return (<>
71
+ {authors.map((el: Author, index) => (
72
+ <Author author={el} key={`authors-${index}`} />
73
+ ))}
74
+ </>)
75
+ }
76
+ return (<Author author={authors as Author} />)
77
+ }
78
+
79
+ const Keywords: React.FC<{keywords: undefined | null | string | Array<string>}> = ({
80
+ keywords
81
+ }) => {
82
+ if (!keywords) return null
83
+ const content = (Array.isArray(keywords) ? keywords.join(', ') : keywords as string)
84
+ return (<meta name="keywords" content={content} />)
85
+ }
86
+
87
+ const ThemeColor: React.FC<{
88
+ thColors: null | undefined | string | ThemeColorDescriptor | ThemeColorDescriptor[]
89
+ }> = ({
90
+ thColors
91
+ }) => {
92
+
93
+ const ThColor: React.FC<{thColor: ThemeColorDescriptor}> = ({thColor}) => {
94
+ const toSpread: any = {
95
+ content: thColor.color
96
+ }
97
+
98
+ if ('media' in thColor) {
99
+ toSpread.media = thColor.media
100
+ }
101
+
102
+ return <meta name="theme-color" {...toSpread}/>
103
+ }
104
+
105
+ if (!thColors) {
106
+ return null
107
+ }
108
+
109
+ if (Array.isArray(thColors)) {
110
+ return (<>
111
+ {thColors.map((el: ThemeColorDescriptor, index) => (
112
+ <ThColor thColor={el} key={`theme-colors-${index}`} />
113
+ ))}
114
+ </>)
115
+ }
116
+ else if (typeof thColors === 'string') {
117
+ <meta name="theme-color" content={thColors as string}/>
118
+ }
119
+ return (<ThColor thColor={thColors as ThemeColorDescriptor} />)
120
+ }
121
+
122
+ const Manifest: React.FC<{
123
+ manifest: undefined | null | string | URL
124
+ }> = ({
125
+ manifest
126
+ }) => (
127
+ manifest && (<link rel="manifest" href={getURLasString(manifest)}/>)
128
+ )
129
+
130
+ const getOGImageURL = (img: OGImage | undefined): string | null => {
131
+
132
+ if (!img) {
133
+ return null
134
+ }
135
+ if (typeof img === 'object' && 'url' in img) { // this is a OGImageDescriptor
136
+ return getURLasString(img.url)
137
+ }
138
+ return getURLasString(img) // this is a URL or string
139
+ }
140
+
141
+ const getTwitterImageURL = (img: TwitterImage | undefined): string | null => {
142
+
143
+ if (!img) {
144
+ return null
145
+ }
146
+ if (typeof img === 'object' && 'url' in img) { // this is a TwitterImageDescriptor
147
+ return getURLasString(img.url)
148
+ }
149
+ return getURLasString(img) // this is a URL or string
150
+ }
151
+
152
+ // https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
153
+ const OpenGraphComponent: React.FC<{
154
+ og: OpenGraph | undefined | null
155
+ }> = ({
156
+ og
157
+ }) => (og && (<Head>
158
+ {og.url && (<meta property="og:url" content={(typeof og.url === 'string') ? (og.url as string) : (og.url.href)} />)}
159
+ {(og as any).type && (<meta property="og:type" content={(og as any).type} />)}
160
+ {og.title && (<meta property="og:title" content={getTitleFromTemplateString(og.title)!} />)}
161
+ {og.description && (<meta property="og:description" content={og.description} />)}
162
+ {og.images && (<meta property="og:image" content={getOGImageURL(Array.isArray(og.images) ? og.images[0] : og.images)!} />)}
163
+ </Head>))
164
+
165
+ // https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
166
+ export const TwitterComponent: React.FC<{
167
+ tw: Twitter | undefined | null
168
+ }> = ({
169
+ tw
170
+ }) => (tw && (<Head>
171
+ {(tw as any).card && (<meta name="twitter:card" content={(tw as any).card} />)}
172
+ {tw.title && (<meta name="twitter:title" content={getTitleFromTemplateString(tw.title)!} />)}
173
+ {tw.description && (<meta name="twitter:description" content={tw.description} />)}
174
+ {tw.images && (<meta name="twitter:image" content={getTwitterImageURL(Array.isArray(tw.images) ? tw.images[0] : tw.images)!} />)}
175
+ {tw.site && (<meta name="twitter:site" content={tw.site} />)}
176
+ </Head>))
177
+
178
+ /* See NOTE at top of file! */
179
+ // https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
180
+ const HeadMetadataComponent: React.FC<{
181
+ metadata: Metadata
182
+ }> = ({
183
+ metadata
184
+ }) => {
185
+ const mainTitle = getTitleFromTemplateString(metadata.title)
186
+
187
+ return (<>
188
+ <Head>
189
+ {mainTitle && (<title>{mainTitle}</title>) /* must be here, directly under Head component */}
190
+ {metadata.description && (
191
+ <meta name="description" content={metadata.description} />
192
+ )}
193
+ {metadata.applicationName && (
194
+ <meta name="application-name" content={metadata.applicationName} />
195
+ )}
196
+ <Authors authors={metadata.authors} />
197
+ <Keywords keywords={metadata.keywords} />
198
+ <ThemeColor thColors={metadata.themeColor} />
199
+ <Manifest manifest={metadata.manifest} />
200
+ </Head>
201
+ {/* Icons: We only support this format for now */}
202
+ <Icons icons={metadata.icons as IconDescriptor[]} />
203
+ <OpenGraphComponent og={metadata.openGraph} />
204
+ <TwitterComponent tw={metadata.twitter} />
205
+ </>)
206
+ }
207
+
208
+ export default HeadMetadataComponent
package/next/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default as determineDeviceMW } from './determine-device-mw'
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@luxfi/core",
3
+ "version": "4.3.11",
4
+ "description": "Library that contains shared UI primitives, support for a common design system, and other boilerplate support.",
5
+ "publishConfig": {
6
+ "registry": "https://registry.npmjs.org/",
7
+ "access": "public",
8
+ "scope": "@luxfi"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/luxfi/web.git",
13
+ "directory": "packages/common"
14
+ },
15
+ "keywords": [
16
+ "components",
17
+ "radix-ui",
18
+ "hanzo",
19
+ "luxdefi"
20
+ ],
21
+ "scripts": {
22
+ "lat": "npm show @luxfi/common version",
23
+ "pub": "npm publish",
24
+ "build": "tsc",
25
+ "tc": "tsc",
26
+ "ln:ui": "pnpm link -g @hanzo/ui",
27
+ "ln:auth": "pnpm link -g @hanzo/auth",
28
+ "ln:cmmc": "pnpm link -g @hanzo/commerce",
29
+ "ul:all": "rm node_modules/@hanzo/*",
30
+ "clean": "rm -rf node_modules"
31
+ },
32
+ "exports": {
33
+ ".": "./components/index.ts",
34
+ "./server-actions": "./server-actions/index.ts",
35
+ "./next": "./next/index.ts",
36
+ "./style/": "./style/",
37
+ "./site-def": "./site-def/index.ts",
38
+ "./tailwind": "./tailwind/index.ts",
39
+ "./conf": "./conf/index.ts"
40
+ },
41
+ "dependencies": {
42
+ "@hanzo/auth": "2.3.5",
43
+ "@hanzo/commerce": "6.3.2",
44
+ "@hanzo/ui": "3.6.3",
45
+ "@next/third-parties": "^14.1.0",
46
+ "embla-carousel-autoplay": "^8.0.1",
47
+ "react-device-detect": "^2.2.3",
48
+ "react-social-icons": "^6.4.0"
49
+ },
50
+ "peerDependencies": {
51
+ "@hookform/resolvers": "^3.3.2",
52
+ "lucide-react": "^0.344.0",
53
+ "next": "14.1.3",
54
+ "next-themes": "^0.2.1",
55
+ "react": "^18.2.0",
56
+ "react-dom": "^18.2.0",
57
+ "react-hook-form": "^7.47.0",
58
+ "validator": "^13.11.0",
59
+ "zod": "3.21.4"
60
+ },
61
+ "devDependencies": {
62
+ "@mdx-js/loader": "^3.0.0",
63
+ "@mdx-js/react": "^3.0.0",
64
+ "@types/facebook-pixel": "^0.0.30",
65
+ "@types/gtag.js": "^0.0.19",
66
+ "@types/mdx": "^2.0.9",
67
+ "@types/react": "^18.2.64",
68
+ "@types/react-dom": "^18.2.18",
69
+ "tailwindcss": "^3.4.2",
70
+ "typescript": "5.3.3"
71
+ }
72
+ }
@@ -0,0 +1,14 @@
1
+ import { initializeApp, getApps } from 'firebase/app'
2
+
3
+ const firebaseConfig = {
4
+ apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
5
+ authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
6
+ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
7
+ storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
8
+ messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
9
+ appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
10
+ measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
11
+ }
12
+
13
+ // Initialize Firebase instance if there isn't one already
14
+ export default getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]
@@ -0,0 +1,5 @@
1
+ import storeContact from './store-contact'
2
+
3
+ export {
4
+ storeContact as default
5
+ }