@hanzo/ui 1.0.15 → 2.0.0

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 (78) hide show
  1. package/blocks/components/card-block.tsx +1 -1
  2. package/package.json +1 -1
  3. package/primitives/icons/index.ts +18 -0
  4. package/primitives/index.ts +1 -0
  5. package/primitives/toggle-group.tsx +1 -1
  6. package/primitives/youtube-embed.tsx +1 -1
  7. package/style/hanzo-default-colors.css +2 -2
  8. package/{context-providers → style}/theme-provider.tsx +2 -2
  9. package/tailwind/fontFamily.tailwind.ts +7 -0
  10. package/tailwind/{fonts.tailwind.ts → fontSize.tailwind.ts} +1 -19
  11. package/tailwind/index.ts +8 -5
  12. package/tailwind/{tailwind.config.base.js → tailwind.config.hanzo-preset.js} +3 -2
  13. package/tailwind/typo-plugin/get-plugin-styles.js +42 -42
  14. package/tailwind/typography-test.mdx +1 -1
  15. package/types/index.ts +5 -15
  16. package/assets/lux-site-icons/android-chrome-192x192.png +0 -0
  17. package/assets/lux-site-icons/android-chrome-512x512.png +0 -0
  18. package/assets/lux-site-icons/apple-touch-icon.png +0 -0
  19. package/assets/lux-site-icons/favicon-16x16.png +0 -0
  20. package/assets/lux-site-icons/favicon-32x32.png +0 -0
  21. package/assets/lux-site-icons/favicon.ico +0 -0
  22. package/assets/standard-docs/LUX-NFT-Terms-and-Conditions.pdf +0 -0
  23. package/assets/standard-docs/LUX-Privacy-Policy.pdf +0 -0
  24. package/common/chat-widget.tsx +0 -75
  25. package/common/contact-dialog/contact-form.tsx +0 -111
  26. package/common/contact-dialog/disclaimer.tsx +0 -13
  27. package/common/contact-dialog/index.tsx +0 -48
  28. package/common/copyright.tsx +0 -21
  29. package/common/drawer-menu.tsx +0 -54
  30. package/common/footer.tsx +0 -77
  31. package/common/head-metadata/from-next/metadata-types.ts +0 -158
  32. package/common/head-metadata/from-next/opengraph-types.ts +0 -267
  33. package/common/head-metadata/from-next/twitter-types.ts +0 -92
  34. package/common/head-metadata/index.tsx +0 -208
  35. package/common/header/index.tsx +0 -66
  36. package/common/header/mobile-nav.tsx +0 -72
  37. package/common/header/theme-toggle.tsx +0 -26
  38. package/common/icons/index.tsx +0 -34
  39. package/common/icons/lux-logo.tsx +0 -10
  40. package/common/icons/secure-delivery.tsx +0 -13
  41. package/common/icons/social-icon.tsx +0 -35
  42. package/common/index.ts +0 -14
  43. package/common/logo.tsx +0 -71
  44. package/common/mini-chart/index.tsx +0 -8
  45. package/common/mini-chart/mini-chart-props.ts +0 -44
  46. package/common/mini-chart/mini-chart.tsx +0 -76
  47. package/common/mini-chart/wrapper.tsx +0 -23
  48. package/context-providers/index.ts +0 -1
  49. package/next/README.md +0 -11
  50. package/next/analytics/fpixel.ts +0 -18
  51. package/next/analytics/pixel-analytics.tsx +0 -55
  52. package/next/determine-device-middleware.ts +0 -16
  53. package/next/fonts/DrukTextWide-Bold-Trial.otf +0 -0
  54. package/next/fonts/DrukTextWide-Heavy-Trial.otf +0 -0
  55. package/next/fonts/DrukTextWide-Medium-Trial.otf +0 -0
  56. package/next/fonts/DrukWide-Bold-Trial.otf +0 -0
  57. package/next/fonts/DrukWide-Heavy-Trial.otf +0 -0
  58. package/next/fonts/DrukWide-Medium-Trial.otf +0 -0
  59. package/next/get-app-router-font-classes.ts +0 -12
  60. package/next/load-and-return-lux-next-fonts-on-import.ts +0 -94
  61. package/next/next-font-desc.ts +0 -28
  62. package/next/not-found-content.mdx +0 -5
  63. package/next/not-found.tsx +0 -23
  64. package/next/pages-router-font-vars.tsx +0 -18
  65. package/next/root-layout.tsx +0 -62
  66. package/siteDef/footer/community.tsx +0 -67
  67. package/siteDef/footer/company.ts +0 -37
  68. package/siteDef/footer/ecosystem.ts +0 -37
  69. package/siteDef/footer/index.tsx +0 -26
  70. package/siteDef/footer/legal.ts +0 -28
  71. package/siteDef/footer/network.ts +0 -37
  72. package/siteDef/footer/svg/warpcast-logo.svg +0 -12
  73. package/siteDef/main-nav.ts +0 -35
  74. package/style/social-svg.css +0 -3
  75. package/tailwind/lux-tw-fonts.ts +0 -37
  76. package/types/site-def.ts +0 -36
  77. /package/{common → primitives}/icons/github.tsx +0 -0
  78. /package/{common → primitives}/icons/youtube-logo.tsx +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  type TypographySize
15
15
  } from '../../primitives'
16
16
 
17
- import { Icons } from '../../common'
17
+ import { Icons } from '../../primitives'
18
18
 
19
19
  import {
20
20
  getSpecifierData,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/ui",
3
- "version": "1.0.15",
3
+ "version": "2.0.0",
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/",
@@ -0,0 +1,18 @@
1
+ import {
2
+ Moon as moon,
3
+ SunMedium as sun,
4
+ Menu as burger,
5
+ ArrowUpRight as linkOut,
6
+ } from 'lucide-react'
7
+
8
+ import youtube from './youtube-logo'
9
+ import gitHub from './github'
10
+
11
+ export {
12
+ sun,
13
+ moon,
14
+ burger,
15
+ gitHub,
16
+ linkOut,
17
+ youtube,
18
+ }
@@ -157,3 +157,4 @@ export { default as NavItems} from './nav-items'
157
157
  export { default as Main } from './main'
158
158
  export { default as ListBox } from './list-box'
159
159
 
160
+ export * as Icons from './icons'
@@ -26,7 +26,7 @@ const ToggleGroup = React.forwardRef<
26
26
  {...props}
27
27
  >
28
28
  <ToggleGroupContext.Provider value={{ variant, size, rounded }}>
29
- {children}
29
+ {children as React.ReactNode}
30
30
  </ToggleGroupContext.Provider>
31
31
  </ToggleGroupPrimitive.Root>
32
32
  ))
@@ -3,7 +3,7 @@
3
3
  import { useState } from 'react'
4
4
  import Image from 'next/image'
5
5
 
6
- import * as Icons from '../common/icons'
6
+ import * as Icons from './icons'
7
7
 
8
8
  // Concept based on https://www.youtube.com/watch?v=lLqRchtjN00
9
9
  // (https://github.com/a-trost/fableton)
@@ -3,7 +3,7 @@
3
3
 
4
4
  @layer base {
5
5
 
6
- :root, .lux-light-theme {
6
+ :root, .hanzo-ui-light-theme {
7
7
  --hz-ui-fg-0: hsl(0 0% 0%);
8
8
  --hz-ui-fg-body: hsl(0 0% 10%);
9
9
  --hz-ui-fg-1: hsl(0 0% 20%);
@@ -49,7 +49,7 @@
49
49
  --hz-ui-radius: 0.5rem;
50
50
  }
51
51
 
52
- .lux-dark-theme {
52
+ .hanzo-ui-dark-theme {
53
53
 
54
54
  --hz-ui-fg-0: hsl(0 0% 100%);
55
55
  --hz-ui-fg-body: hsl(0, 0%, 97%);
@@ -9,8 +9,8 @@ const ThemeProvider: React.FC<ThemeProviderProps> = ({ children, ...props }) =>
9
9
  attribute="class"
10
10
  {...props}
11
11
  value={{
12
- light: 'lux-light-theme',
13
- dark: 'lux-dark-theme'
12
+ light: 'hanzo-ui-light-theme',
13
+ dark: 'hanzo-ui-dark-theme'
14
14
  }}
15
15
  >
16
16
  {children}
@@ -0,0 +1,7 @@
1
+ export default {
2
+ sans: ['sans-serif'],
3
+ heading: ['serif'],
4
+ nav: ['serif'],
5
+ serif: ['serif'],
6
+ mono: ['monospace']
7
+ }
@@ -1,22 +1,4 @@
1
- import luxTwFonts from './lux-tw-fonts'
2
- import type TwFontDesc from './tw-font-desc'
3
-
4
- export const fontFamily = (ignoreTheme: any): {
5
- [key: string]: string[]
6
- } => {
7
-
8
- let result: any = {}
9
- luxTwFonts.forEach((font: TwFontDesc) => {
10
- result[font.twName] = font.fontFamily
11
- // eg: heading: ['var(--font-druk-text-wide)']
12
- })
13
-
14
- return result as {
15
- [key: string]: string[]
16
- }
17
- }
18
-
19
- export const fontSize = {
1
+ export default {
20
2
  xxs: ['0.65rem', { lineHeight: '0.8rem' }], // very fine print
21
3
  xs: ['0.8rem', { lineHeight: '1rem' }], // fine print
22
4
  sm: ['0.9rem', { lineHeight: '1.2rem' }], // 'standard' some news article cards (set manually when using typography-sm)
package/tailwind/index.ts CHANGED
@@ -1,18 +1,21 @@
1
1
  import colors from './colors.tailwind'
2
- import { fontFamily, fontSize } from './fonts.tailwind'
2
+ import fontSize from './fontSize.tailwind'
3
+ import fontFamily from './fontFamily.tailwind'
3
4
  import safelist from './safelist.tailwind'
4
5
  import screens from './screens.tailwind'
5
6
  import spacing from './spacing.tailwind'
6
7
  import typographyPlugin from './typo-plugin'
7
- import config from './tailwind.config.base'
8
+ import preset from './tailwind.config.hanzo-preset'
9
+ import type TwFontDesc from './tw-font-desc'
8
10
 
9
11
  export {
10
12
  colors,
11
- config,
12
- fontFamily,
13
+ preset,
13
14
  fontSize,
15
+ fontFamily,
14
16
  safelist,
15
17
  screens,
16
18
  spacing,
17
- typographyPlugin
19
+ typographyPlugin,
20
+ type TwFontDesc
18
21
  }
@@ -6,7 +6,8 @@ import colors from './colors.tailwind'
6
6
  import safelist from './safelist.tailwind'
7
7
  import screens from './screens.tailwind'
8
8
  import spacing from './spacing.tailwind'
9
- import { fontFamily, fontSize} from './fonts.tailwind'
9
+ import fontSize from './fontSize.tailwind'
10
+ import fontFamily from './fontFamily.tailwind'
10
11
  import typographyPlugin from './typo-plugin'
11
12
 
12
13
  export default {
@@ -296,7 +297,7 @@ export default {
296
297
  0: '0',
297
298
  DEFAULT: '1',
298
299
  },
299
- fontFamily,
300
+ fontFamily,
300
301
  fontSize,
301
302
  fontWeight: {
302
303
  thin: '100',
@@ -7,29 +7,29 @@ import {
7
7
  const typographyColorTheme = {
8
8
  // vars are defined in global.css
9
9
  // and dark mode is handled at that level.
10
- '--tw-prose-body': "var(--hz-ui-fg-body)",
11
- '--tw-prose-headings': "var(--hz-ui-fg-0)",
12
- '--tw-prose-links': "var(--hz-ui-fg-0)",
13
- '--tw-prose-links-hover': "var(--hz-ui-fg-2)",
14
- '--tw-prose-bold': "var(--hz-ui-fg-0)",
15
- '--tw-prose-counters': "var(--hz-ui-fg-4)",
16
- '--tw-prose-bullets': "var(--hz-ui-fg-2)",
17
- '--tw-prose-hr': "var(--hz-ui-fg-2)",
18
- '--tw-prose-quotes': "var(--hz-ui-fg-body)",
19
- '--tw-prose-quote-borders': "var(--hz-ui-fg-3)",
20
- '--tw-prose-captions': "var(--hz-ui-fg-2)",
21
- '--tw-prose-kbd': "var(--hz-ui-fg-0)",
22
- '--tw-prose-kbd-shadows': "var(--hz-ui-fg-1)",
23
- '--tw-prose-code': "var(--hz-ui-fg-0)",
24
- '--tw-prose-pre-code': "var(--hz-ui-fg-1)",
25
- '--tw-prose-pre-bg': "var(--hz-ui-bg-1)",
26
- '--tw-prose-th-borders': "var(--hz-ui-fg-2)",
27
- '--tw-prose-td-borders': "var(--hz-ui-fg-3)",
10
+ '--tw-typo-plugin-body': "var(--hz-ui-fg-body)",
11
+ '--tw-typo-plugin-headings': "var(--hz-ui-fg-0)",
12
+ '--tw-typo-plugin-links': "var(--hz-ui-fg-0)",
13
+ '--tw-typo-plugin-links-hover': "var(--hz-ui-fg-2)",
14
+ '--tw-typo-plugin-bold': "var(--hz-ui-fg-0)",
15
+ '--tw-typo-plugin-counters': "var(--hz-ui-fg-4)",
16
+ '--tw-typo-plugin-bullets': "var(--hz-ui-fg-2)",
17
+ '--tw-typo-plugin-hr': "var(--hz-ui-fg-2)",
18
+ '--tw-typo-plugin-quotes': "var(--hz-ui-fg-body)",
19
+ '--tw-typo-plugin-quote-borders': "var(--hz-ui-fg-3)",
20
+ '--tw-typo-plugin-captions': "var(--hz-ui-fg-2)",
21
+ '--tw-typo-plugin-kbd': "var(--hz-ui-fg-0)",
22
+ '--tw-typo-plugin-kbd-shadows': "var(--hz-ui-fg-1)",
23
+ '--tw-typo-plugin-code': "var(--hz-ui-fg-0)",
24
+ '--tw-typo-plugin-pre-code': "var(--hz-ui-fg-1)",
25
+ '--tw-typo-plugin-pre-bg': "var(--hz-ui-bg-1)",
26
+ '--tw-typo-plugin-th-borders': "var(--hz-ui-fg-2)",
27
+ '--tw-typo-plugin-td-borders': "var(--hz-ui-fg-3)",
28
28
  }
29
29
 
30
30
  const defaultCSS = {
31
31
 
32
- color: 'var(--tw-prose-body)',
32
+ color: 'var(--tw-typo-plugin-body)',
33
33
  // YUCK maxWidth: '65ch',
34
34
  p: {
35
35
  textAlign: 'inherit'
@@ -37,17 +37,17 @@ const defaultCSS = {
37
37
  'p:first-child': {},
38
38
  'p:last-child': {},
39
39
  a: {
40
- color: 'var(--tw-prose-links)',
40
+ color: 'var(--tw-typo-plugin-links)',
41
41
  textDecoration: 'underline',
42
42
  fontWeight: '400',
43
43
  },
44
44
  'a:hover': {
45
- color: 'var(--tw-prose-links-hover)',
45
+ color: 'var(--tw-typo-plugin-links-hover)',
46
46
  },
47
47
  blockquote: {
48
48
  fontWeight: '400',
49
49
  fontStyle: 'italic',
50
- color: 'var(--tw-prose-quotes)',
50
+ color: 'var(--tw-typo-plugin-quotes)',
51
51
  quotes: '"\\201C""\\201D""\\2018""\\2019"',
52
52
  },
53
53
  //'blockquote::before': {},
@@ -65,7 +65,7 @@ const defaultCSS = {
65
65
  display: 'block',
66
66
  fontStyle: 'normal',
67
67
  textAlign: 'right',
68
- color: 'var(--tw-prose-quotes)',
68
+ color: 'var(--tw-typo-plugin-quotes)',
69
69
  },
70
70
  ol: {
71
71
  listStyleType: 'decimal',
@@ -75,44 +75,44 @@ const defaultCSS = {
75
75
  },
76
76
  'ol > li::marker': {
77
77
  fontWeight: '400',
78
- color: 'var(--tw-prose-counters)',
78
+ color: 'var(--tw-typo-plugin-counters)',
79
79
  },
80
80
  'ul > li::marker': {
81
- color: 'var(--tw-prose-bullets)',
81
+ color: 'var(--tw-typo-plugin-bullets)',
82
82
  },
83
83
  'ul > li::before': {
84
84
  },
85
85
  hr: {
86
- borderColor: 'var(--tw-prose-hr)',
86
+ borderColor: 'var(--tw-typo-plugin-hr)',
87
87
  borderTopWidth: 1,
88
88
  },
89
89
  h1: {
90
- color: 'var(--tw-prose-headings)',
90
+ color: 'var(--tw-typo-plugin-headings)',
91
91
  fontWeight: '800',
92
92
  textAlign: 'inherit'
93
93
  },
94
94
  h2: {
95
- color: 'var(--tw-prose-headings)',
95
+ color: 'var(--tw-typo-plugin-headings)',
96
96
  fontWeight: '700',
97
97
  textAlign: 'inherit'
98
98
  },
99
99
  h3: {
100
- color: 'var(--tw-prose-headings)',
100
+ color: 'var(--tw-typo-plugin-headings)',
101
101
  fontWeight: '600',
102
102
  textAlign: 'inherit'
103
103
  },
104
104
  h4: {
105
- color: 'var(--tw-prose-headings)',
105
+ color: 'var(--tw-typo-plugin-headings)',
106
106
  fontWeight: '600',
107
107
  textAlign: 'inherit'
108
108
  },
109
109
  h5: {
110
- color: 'var(--tw-prose-headings)',
110
+ color: 'var(--tw-typo-plugin-headings)',
111
111
  fontWeight: '600',
112
112
  textAlign: 'inherit'
113
113
  },
114
114
  h6: {
115
- color: 'var(--tw-prose-headings)',
115
+ color: 'var(--tw-typo-plugin-headings)',
116
116
  textAlign: 'inherit'
117
117
  },
118
118
  img: {},
@@ -124,19 +124,19 @@ const defaultCSS = {
124
124
  display: 'block',
125
125
  },
126
126
  strong: {
127
- color: 'var(--tw-prose-bold)',
127
+ color: 'var(--tw-typo-plugin-bold)',
128
128
  fontWeight: '600',
129
129
  },
130
130
  video: {},
131
131
  kbd: {
132
132
  fontWeight: '500',
133
133
  fontFamily: 'inherit',
134
- color: 'var(--tw-prose-kbd)',
134
+ color: 'var(--tw-typo-plugin-kbd)',
135
135
  boxShadow:
136
- '0 0 0 1px rgb(var(--tw-prose-kbd-shadows) / 10%), 0 3px 0 rgb(var(--tw-prose-kbd-shadows) / 10%)',
136
+ '0 0 0 1px rgb(var(--tw-typo-plugin-kbd-shadows) / 10%), 0 3px 0 rgb(var(--tw-typo-plugin-kbd-shadows) / 10%)',
137
137
  },
138
138
  code: {
139
- color: 'var(--tw-prose-code)',
139
+ color: 'var(--tw-typo-plugin-code)',
140
140
  fontWeight: '500',
141
141
  },
142
142
  'code::before': {
@@ -173,8 +173,8 @@ const defaultCSS = {
173
173
  color: 'inherit',
174
174
  },
175
175
  pre: {
176
- color: 'var(--tw-prose-pre-code)',
177
- backgroundColor: 'var(--tw-prose-pre-bg)',
176
+ color: 'var(--tw-typo-plugin-pre-code)',
177
+ backgroundColor: 'var(--tw-typo-plugin-pre-bg)',
178
178
  overflowX: 'auto',
179
179
  fontWeight: '400',
180
180
  },
@@ -202,10 +202,10 @@ const defaultCSS = {
202
202
  },
203
203
  thead: {
204
204
  borderBottomWidth: '1px',
205
- borderBottomColor: 'var(--tw-prose-th-borders)',
205
+ borderBottomColor: 'var(--tw-typo-plugin-th-borders)',
206
206
  },
207
207
  'thead th': {
208
- color: 'var(--tw-prose-headings)',
208
+ color: 'var(--tw-typo-plugin-headings)',
209
209
  fontWeight: '600',
210
210
  verticalAlign: 'bottom',
211
211
  },
@@ -218,7 +218,7 @@ const defaultCSS = {
218
218
  },
219
219
  tfoot: {
220
220
  borderTopWidth: '1px',
221
- borderTopColor: 'var(--tw-prose-th-borders)',
221
+ borderTopColor: 'var(--tw-typo-plugin-th-borders)',
222
222
  },
223
223
  'tfoot td': {
224
224
  verticalAlign: 'top',
@@ -244,7 +244,7 @@ const defaultModifiers = (base) => ({
244
244
  a: {},
245
245
  'a:hover': {},
246
246
  blockquote: {
247
- //color: 'blue', //var(--tw-prose-quotes)',
247
+ //color: 'blue', //var(--tw-typo-plugin-quotes)',
248
248
  //marginTop: pxToEm(32, 20),
249
249
  //marginBottom: pxToEm(32, 20),
250
250
  //paddingLeft: pxToEm(20, 20),
@@ -1,4 +1,4 @@
1
- import Link from '@hanzo/ui/common/link-element'
1
+ import Link from '@hanzo/ui/primitives/link-element'
2
2
 
3
3
  ###### In a galaxy far, far away
4
4
  ##### Join the global rush to own silver
package/types/index.ts CHANGED
@@ -11,19 +11,9 @@ export type {default as GridDef, GridColumnSpec} from './grid-def'
11
11
  export type { TShirtDimensions, Dimensions } from './dimensions'
12
12
  export type { ContactInfo, ContactInfoFields } from './contact-info'
13
13
 
14
- import type BulletItem from './bullet-item'
15
- import type Icon from './icon'
16
- import type ImageDef from './image-def'
17
- import type LinkDef from './link-def'
18
- import type SiteDef from './site-def'
19
- import type TShirtSize from './t-shirt-size'
20
-
21
- export {
22
- type BulletItem,
23
- type Icon,
24
- type ImageDef,
25
- type LinkDef,
26
- type SiteDef,
27
- type TShirtSize,
28
- }
14
+ export type { default as BulletItem } from './bullet-item'
15
+ export type { default as Icon } from './icon'
16
+ export type { default as ImageDef } from './image-def'
17
+ export type { default as LinkDef } from './link-def'
18
+ export type { default as TShirtSize } from './t-shirt-size'
29
19
 
Binary file
@@ -1,75 +0,0 @@
1
- 'use client'
2
- import React from 'react'
3
-
4
- import { X } from 'lucide-react'
5
-
6
- import LuxLogo from './icons/lux-logo'
7
- import { Button, Card } from '../primitives'
8
-
9
- const ChatWidget: React.FC<{
10
- title: string,
11
- chatbotUrl: string,
12
- subtitle?: string,
13
- question?: string,
14
- /*
15
- Currently supports these icons from remix icons (https://remixicon.com/):
16
- GlobalLineIcon,
17
- ShieldFlashLineIcon,
18
- BankCardLineIcon,
19
- GroupLineIcon,
20
- QuestionnaireLineIcon
21
- */
22
- suggestedQuestions?: { heading: string, message: string, icon?: string }[]
23
- }> = ({
24
- title,
25
- chatbotUrl,
26
- subtitle,
27
- question,
28
- suggestedQuestions
29
- }) => {
30
-
31
- const [showChatbot, setShowChatbot] = React.useState<boolean>(false)
32
-
33
- const onClick = () => { setShowChatbot(!showChatbot) }
34
-
35
- const searchParams = new URLSearchParams()
36
- if (question) {
37
- searchParams.append('question', question)
38
- }
39
- if (suggestedQuestions) {
40
- searchParams.append('sQuestions', suggestedQuestions.map(({ message }) => message).join(','))
41
- searchParams.append('sHeadings', suggestedQuestions.map(({ heading }) => heading).join(','))
42
- searchParams.append('sIcons', suggestedQuestions.map(({ icon }) => icon).join(','))
43
- }
44
-
45
- const iframeSrc = `${chatbotUrl}?${searchParams.toString()}`
46
-
47
- return (<>
48
- <div className={
49
- 'fixed bottom-0 sm:bottom-20 right-0 w-full h-full ' +
50
- 'sm:max-w-[400px] sm:max-h-[550px] sm:px-4 z-[1002] ' +
51
- (showChatbot ? 'flex' : 'hidden')
52
- }>
53
- <Card className='flex flex-col h-full w-full'>
54
- <div className='flex px-4 py-2 h-12 bg-level-0 items-center justify-between'>
55
- <h3 className='font-semibold font-heading'>{title} <span className='opacity-60'>{subtitle}</span></h3>
56
- <Button onClick={onClick} variant='link' size='icon' className='w-fit sm:hidden'>
57
- <X />
58
- </Button>
59
- </div>
60
- <iframe src={iframeSrc} className='h-full' />
61
- </Card>
62
- </div>
63
-
64
- <Button
65
- variant='outline'
66
- size='link'
67
- onClick={onClick}
68
- className='fixed bottom-4 right-0 h-12 w-12 mx-4 rounded-full z-[1001]'
69
- >
70
- {showChatbot ? <X /> : <LuxLogo width={24} height={24} className='mt-2' />}
71
- </Button>
72
- </>)
73
- }
74
-
75
- export default ChatWidget
@@ -1,111 +0,0 @@
1
- 'use client'
2
-
3
- import React, { useTransition } from 'react'
4
-
5
- import { zodResolver } from '@hookform/resolvers/zod'
6
- import { useForm, type SubmitHandler, type ControllerRenderProps } from 'react-hook-form'
7
- import * as z from 'zod'
8
- // @ts-ignore
9
- import validator from 'validator'
10
-
11
- import { Loader2 } from 'lucide-react'
12
-
13
- import {
14
- Button,
15
- Input,
16
- Form,
17
- FormControl,
18
- FormField,
19
- FormItem,
20
- FormMessage,
21
- } from '../../primitives'
22
-
23
- import type { ContactInfo, SubmitServerAction } from '../../types'
24
-
25
- const ValidationSchema = z.object({
26
- email: z
27
- .string()
28
- .min(1, { message: "Email must be provided." })
29
- .email("Invalid email."),
30
- phone: z
31
- .string()
32
- .min(1, { message: "Telephone must be provided." })
33
- .refine(validator.isMobilePhone, { message: "Invalid format." })
34
- })
35
-
36
- const ContactForm: React.FC<{
37
- onSubmit: SubmitServerAction
38
- enclosure: any
39
- }> = ({
40
- onSubmit,
41
- enclosure
42
- }) => {
43
-
44
- const form = useForm<ContactInfo>({
45
- // @ts-ignore (pnpm linking / tsc bug )
46
- resolver: zodResolver(ValidationSchema),
47
- defaultValues: {
48
- email: '',
49
- phone: '',
50
- },
51
- })
52
-
53
- const [isPending, startTransition] = useTransition()
54
-
55
- const onFormSubmit: SubmitHandler<ContactInfo> = (data) => {
56
- // https://github.com/orgs/react-hook-form/discussions/10757#discussioncomment-6672403
57
- // @ts-ignore
58
- startTransition(async () => {
59
- await onSubmit(data, enclosure)
60
- })
61
- }
62
-
63
- const MyFormItem: React.FC<{
64
- field: ControllerRenderProps<ContactInfo, 'email'> | ControllerRenderProps<ContactInfo, 'phone'>
65
- placeholder: string
66
- }> = ({
67
- field,
68
- placeholder
69
- }) => (
70
- <FormItem className="space-y-0" >
71
- <FormControl>
72
- <Input placeholder={placeholder} {...field} className="mt-0 text-foreground"/>
73
- </FormControl>
74
- <div className="flex flex-row justify-start items-stretch gap-2">
75
- <FormMessage />
76
- </div>
77
- </FormItem>
78
- )
79
-
80
- return (
81
- <Form {...form}>
82
- <form onSubmit={form.handleSubmit(onFormSubmit)} className="w-3/4">
83
- <div className='flex flex-col justify-start items-stretch mt-4'>
84
- <FormField
85
- control={form.control}
86
- name='email'
87
- // @ts-ignore
88
- render={({ field }) => ( <MyFormItem field={field} placeholder='email'/> )}
89
- />
90
- <FormField
91
- control={form.control}
92
- name='phone'
93
- // @ts-ignore
94
- render={({ field }) => ( <MyFormItem field={field} placeholder='phone'/> )}
95
- />
96
- <Button disabled={isPending} type='submit' className='bg-primary text-primary-fg hover:bg-primary-hover'>
97
- {isPending ? (<>
98
- <Loader2 className="mr-2 h-4 w-4 animate-spin" />
99
- Please wait
100
- </>
101
- ) : (
102
- <>Submit</>
103
- )}
104
- </Button>
105
- </div>
106
- </form>
107
- </Form>
108
- )
109
- }
110
-
111
- export default ContactForm
@@ -1,13 +0,0 @@
1
- import React from 'react'
2
-
3
- const Disclaimer: React.FC = () => (
4
- <div>
5
- By entering your mobile number and submitting, you consent to receive text messages from Lux at the number provided.
6
- Message and data rates may apply. Message frequency varies.
7
- You can unsubscribe at any time by replying STOP.
8
- View our <a href='/privacy'>Privacy Policy</a> and <a href='/terms'>Terms & conditions</a>.
9
- </div>
10
- )
11
-
12
- export default Disclaimer
13
-