@luxfi/ui 5.5.5 → 5.5.6
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/commerce/ui/context.tsx +13 -16
- package/components/access-code-input.tsx +3 -4
- package/components/analytics.tsx +8 -17
- package/components/auth/login-panel.tsx +7 -6
- package/components/auth/login.tsx +1 -1
- package/components/auth/widget.tsx +1 -1
- package/components/back-button.tsx +4 -7
- package/components/chat-widget.tsx +5 -6
- package/components/commerce/bag-button.tsx +8 -7
- package/components/commerce/buy-button.tsx +2 -3
- package/components/commerce/checkout-button.tsx +12 -10
- package/components/commerce/checkout-panel/cart-accordian.tsx +3 -4
- package/components/commerce/checkout-panel/desktop-cp.tsx +5 -6
- package/components/commerce/checkout-panel/index.tsx +1 -1
- package/components/commerce/checkout-panel/mobile-cp.tsx +4 -4
- package/components/commerce/checkout-panel/policy-links.tsx +7 -12
- package/components/commerce/checkout-panel/steps-indicator.tsx +1 -1
- package/components/commerce/desktop-bag-popup.tsx +1 -1
- package/components/commerce/drawer/micro.tsx +30 -30
- package/components/commerce/drawer/shell.tsx +3 -5
- package/components/contact-dialog/contact-form.tsx +6 -13
- package/components/contact-dialog/index.tsx +2 -2
- package/components/copyright.tsx +3 -2
- package/components/drawer-margin.tsx +2 -2
- package/components/footer.tsx +6 -7
- package/components/header/desktop-nav-menu.tsx +6 -6
- package/components/header/desktop.tsx +5 -5
- package/components/header/index.tsx +1 -1
- package/components/header/mobile-bag-drawer.tsx +1 -1
- package/components/header/mobile-menu-toggle-button.tsx +5 -6
- package/components/header/mobile-nav-menu-ai.tsx +13 -12
- package/components/header/mobile-nav-menu-item.tsx +12 -11
- package/components/header/mobile-nav-menu.tsx +17 -16
- package/components/header/mobile.tsx +7 -8
- package/components/icons/social-icon.tsx +1 -1
- package/components/logo.tsx +3 -2
- package/components/main.tsx +3 -4
- package/components/mini-chart/mini-chart.tsx +2 -1
- package/next/font/font-desc.ts +18 -0
- package/next/font/fonts.ts +40 -0
- package/next/font/get-app-router-font-classes.ts +14 -12
- package/next/font/load-and-return-lux-next-fonts-on-import.ts +16 -24
- package/next/font/local/Zen-Variable.woff2 +0 -0
- package/next/font/next-font-desc.ts +18 -17
- package/next/head-metadata/index.tsx +7 -6
- package/next/head-metadata/next-metadata.ts +49 -0
- package/package.json +9 -10
- package/root-layout/index.tsx +39 -19
- package/style/fonts/Zen-Variable.woff2 +0 -0
- package/style/lux-colors.css +0 -1
- package/style/lux-fonts.css +5 -11
- package/style/lux-global-non-next.css +9 -9
- package/style/lux-global.css +56 -21
- package/tsconfig.json +8 -0
- package/next/font/local/Druk-Wide-Bold.ttf +0 -0
- package/next/font/local/Druk-Wide-Medium.ttf +0 -0
- package/next/head-metadata/from-next/metadata-types.ts +0 -158
- package/next/head-metadata/from-next/opengraph-types.ts +0 -267
- package/next/head-metadata/from-next/twitter-types.ts +0 -92
- package/style/fonts/Druk-Wide-Bold.ttf +0 -0
- package/style/fonts/Druk-Wide-Medium.ttf +0 -0
- package/tailwind/fontFamily.tailwind.lux.ts +0 -18
- package/tailwind/index.ts +0 -2
- package/tailwind/lux-tw-fonts.ts +0 -40
- package/tailwind/tailwind.config.lux-preset.ts +0 -10
|
@@ -3,8 +3,7 @@ import React, { useState, useEffect } from 'react'
|
|
|
3
3
|
import { useRouter } from 'next/navigation'
|
|
4
4
|
|
|
5
5
|
import type { LinkDef } from '@hanzo/ui/types'
|
|
6
|
-
import { cn } from '@hanzo/ui
|
|
7
|
-
|
|
6
|
+
import { Box, cn } from '@hanzo/ui'
|
|
8
7
|
import { CartPanel, useCommerce } from '@hanzo/commerce'
|
|
9
8
|
import Login from '../auth/login'
|
|
10
9
|
import sendGAEvent from '../../next/analytics/google-analytics'
|
|
@@ -89,7 +88,7 @@ const MobileHeader: React.FC<{
|
|
|
89
88
|
}
|
|
90
89
|
// header element MUST be fixed, and NOT sticky. Or else drawer breaks on mobile browsers
|
|
91
90
|
return (<>
|
|
92
|
-
<header id='MOBILE_HEADER' className={cn(
|
|
91
|
+
<Box tag="header" id='MOBILE_HEADER' className={cn(
|
|
93
92
|
`bg-background fixed z-header top-0 left-0 w-full ${menuOpen() ? 'hidden' : 'block'}`,
|
|
94
93
|
className
|
|
95
94
|
)}>
|
|
@@ -99,12 +98,12 @@ const MobileHeader: React.FC<{
|
|
|
99
98
|
{/* Not that key to the cross-fade effect
|
|
100
99
|
is that this is **on top of** the logo. */}
|
|
101
100
|
{menuOpen() && (
|
|
102
|
-
<
|
|
101
|
+
<Box className={'absolute left-0 top-0 bottom-0 right-0 pl-8 ' +
|
|
103
102
|
'flex flex-row ' +
|
|
104
103
|
'bg-background animate-mobile-menu-open'
|
|
105
104
|
}>
|
|
106
105
|
<Avatar className='self-center ' />
|
|
107
|
-
</
|
|
106
|
+
</Box>
|
|
108
107
|
)}
|
|
109
108
|
<div className='flex gap-0 flex-row'>
|
|
110
109
|
<BagButton className='text-primary -mr-[3px]' onClick={openBag} />
|
|
@@ -112,7 +111,7 @@ const MobileHeader: React.FC<{
|
|
|
112
111
|
</div>
|
|
113
112
|
|
|
114
113
|
</div>
|
|
115
|
-
</
|
|
114
|
+
</Box>
|
|
116
115
|
{!noCommerce && (
|
|
117
116
|
<MobileBagDrawer
|
|
118
117
|
className=''
|
|
@@ -123,7 +122,7 @@ const MobileHeader: React.FC<{
|
|
|
123
122
|
)}
|
|
124
123
|
|
|
125
124
|
{menuOpen() && (
|
|
126
|
-
<
|
|
125
|
+
<Box className={
|
|
127
126
|
'fixed top-0 left-0 w-full h-full ' +
|
|
128
127
|
// z must below header itself
|
|
129
128
|
'flex flex-column bg-background z-below-header animate-mobile-menu-open'
|
|
@@ -162,7 +161,7 @@ const MobileHeader: React.FC<{
|
|
|
162
161
|
/>
|
|
163
162
|
)
|
|
164
163
|
)}
|
|
165
|
-
</
|
|
164
|
+
</Box>
|
|
166
165
|
) /* menuOpen */}
|
|
167
166
|
</>)
|
|
168
167
|
}
|
package/components/logo.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
+
import { Box, css } from '@hanzo/ui'
|
|
2
3
|
import Link from 'next/link'
|
|
3
4
|
|
|
4
5
|
import { type TShirtSize } from '@hanzo/ui/types'
|
|
@@ -52,9 +53,9 @@ const Logo: React.FC<{
|
|
|
52
53
|
</>)
|
|
53
54
|
|
|
54
55
|
return href ? (
|
|
55
|
-
<Link href={href}
|
|
56
|
+
<Link href={href} style={css(clx)} onClick={onClick}>{art}</Link>
|
|
56
57
|
) : (
|
|
57
|
-
<span className={clx} onClick={onClick}>{art}</
|
|
58
|
+
<Box tag="span" className={clx} onClick={onClick}>{art}</Box>
|
|
58
59
|
)
|
|
59
60
|
}
|
|
60
61
|
|
package/components/main.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { type PropsWithChildren } from 'react'
|
|
2
|
-
import { cn } from '@hanzo/ui
|
|
3
|
-
|
|
2
|
+
import { Box, cn } from '@hanzo/ui'
|
|
4
3
|
const Main: React.FC<PropsWithChildren & {
|
|
5
4
|
id?: string
|
|
6
5
|
className?: string
|
|
@@ -13,7 +12,7 @@ const Main: React.FC<PropsWithChildren & {
|
|
|
13
12
|
standardWidth=true,
|
|
14
13
|
id
|
|
15
14
|
}) => (
|
|
16
|
-
<main id={id ?? 'LUX_UI_MAIN'} className={cn(
|
|
15
|
+
<Box tag="main" id={id ?? 'LUX_UI_MAIN'} className={cn(
|
|
17
16
|
'flex flex-col justify-start items-center',
|
|
18
17
|
'px-4 md:px-6 lg:px-8',
|
|
19
18
|
standardWidth ? 'max-w-screen-2xl w-full lg:mx-auto' : '',
|
|
@@ -21,7 +20,7 @@ const Main: React.FC<PropsWithChildren & {
|
|
|
21
20
|
className
|
|
22
21
|
)}>
|
|
23
22
|
{children}
|
|
24
|
-
</
|
|
23
|
+
</Box>
|
|
25
24
|
)
|
|
26
25
|
|
|
27
26
|
export default Main
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import React, { useEffect, useRef } from 'react'
|
|
4
|
+
import { Box } from '@hanzo/ui'
|
|
4
5
|
import { type MiniChartProps } from './mini-chart-props'
|
|
5
6
|
|
|
6
7
|
const MiniChart: React.FC<MiniChartProps> = ({
|
|
@@ -77,7 +78,7 @@ const MiniChart: React.FC<MiniChartProps> = ({
|
|
|
77
78
|
<div style={containerStyles} className='tradingview-widget-container h-[150px]' ref={containerRef} />
|
|
78
79
|
<div className='tradingview-widget-copyright border-t w-full invisible'>
|
|
79
80
|
<a href={`https://www.tradingview.com/symbols/${symbol}${exchange ? `/?exchange=${exchange}` : '' }`} rel="noopener" target="_blank">
|
|
80
|
-
<span className="text-[--hz-ui-primary]">{symbol} quotes</
|
|
81
|
+
<Box tag="span" className="text-[--hz-ui-primary]">{symbol} quotes</Box></a> by TradingView
|
|
81
82
|
</div>
|
|
82
83
|
</>)
|
|
83
84
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A font in this site's vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* `name` is the ROLE the font plays — `sans`, `nav`, `heading`, `serif`, `mono`
|
|
5
|
+
* — not a file and not a family. The stack is what the browser resolves, and
|
|
6
|
+
* `cssVar` is the custom property the next/font loader publishes the loaded
|
|
7
|
+
* face under, so the stack can point at it.
|
|
8
|
+
*
|
|
9
|
+
* It lived in a Tailwind preset and was called `TwFontDesc`, which named the
|
|
10
|
+
* engine that happened to read it rather than what it is. The engine is gone;
|
|
11
|
+
* the fonts are not.
|
|
12
|
+
*/
|
|
13
|
+
export type FontDesc = {
|
|
14
|
+
/** The role: `sans`, `nav`, `heading`, `serif`, `mono`. */
|
|
15
|
+
name: string
|
|
16
|
+
fontFamily: string[]
|
|
17
|
+
cssVar?: string
|
|
18
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { FontDesc } from './font-desc'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/* Read by ./load-and-return-lux-next-fonts-on-import.ts */
|
|
5
|
+
|
|
6
|
+
export default [
|
|
7
|
+
{
|
|
8
|
+
fontFamily: ['var(--font-inter)'], // do not provide fall-backs due to next bug
|
|
9
|
+
cssVar: '--font-inter',
|
|
10
|
+
name: 'sans'
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
fontFamily: ['var(--font-inter)'], // do not provide fall-backs due to next bug
|
|
14
|
+
cssVar: '--font-inter',
|
|
15
|
+
name: 'nav'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
fontFamily: ['var(--font-zen-sans)'], // do not provide fall-backs due to next bug
|
|
19
|
+
cssVar: '--font-zen-sans',
|
|
20
|
+
name: 'heading'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'serif',
|
|
24
|
+
fontFamily: ['ui-serif', 'Georgia', 'Cambria', '"Times New Roman"', 'Times']
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'mono',
|
|
28
|
+
fontFamily: [
|
|
29
|
+
'ui-monospace',
|
|
30
|
+
'SFMono-Regular',
|
|
31
|
+
'Menlo',
|
|
32
|
+
'Monaco',
|
|
33
|
+
'Consolas',
|
|
34
|
+
'"Liberation Mono"',
|
|
35
|
+
'"Courier New"',
|
|
36
|
+
'monospace',
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
] as FontDesc[]
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import nextFonts from './load-and-return-lux-next-fonts-on-import'
|
|
2
2
|
import type NextFontDesc from './next-font-desc'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/**
|
|
5
|
+
* next/font's own generated class names, for <body> in an app-router app using
|
|
6
|
+
* our RootLayout.
|
|
7
|
+
*
|
|
8
|
+
* Each one DEFINES a custom property holding the face it loaded, so they have
|
|
9
|
+
* to land on an element before anything can name `var(--font-inter)`.
|
|
10
|
+
*
|
|
11
|
+
* It used to append `font-<role>` for the default face as well. That was a
|
|
12
|
+
* utility class, and with no engine generating it the body had a name no sheet
|
|
13
|
+
* served — the family is set on `body` in lux-global.css instead, where it can
|
|
14
|
+
* point at the property these classes define.
|
|
15
|
+
*/
|
|
8
16
|
export default () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
nf = nf.filter(
|
|
12
|
-
(str, i, arr) => (
|
|
13
|
-
arr.indexOf(str) === i
|
|
14
|
-
)
|
|
15
|
-
)
|
|
16
|
-
return nf.join(' ') + ` font-${nextFonts[0].twName}`
|
|
17
|
+
const named = nextFonts.map((desc: NextFontDesc) => desc.nextFont!.variable)
|
|
18
|
+
return [...new Set(named)].join(' ')
|
|
17
19
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// import { Inter } from 'next/font/google'
|
|
2
2
|
import localFont from 'next/font/local'
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type { FontDesc } from './font-desc'
|
|
5
5
|
import type NextFontDesc from './next-font-desc'
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import fonts from './fonts'
|
|
8
8
|
|
|
9
9
|
/*
|
|
10
|
-
Creating NextFontDesc's and
|
|
10
|
+
Creating NextFontDesc's and FontDesc's has to be seperated because they are needed
|
|
11
11
|
at different times during the next compile / build. Otherwise a nasty
|
|
12
12
|
race condition happens!
|
|
13
13
|
|
|
@@ -15,21 +15,11 @@ import twFonts from '../../tailwind/lux-tw-fonts'
|
|
|
15
15
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
src:
|
|
20
|
-
|
|
21
|
-
path: './local/Druk-Wide-Bold.ttf',
|
|
22
|
-
weight: '700',
|
|
23
|
-
style: 'normal'
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
path: './local/Druk-Wide-Medium.ttf',
|
|
27
|
-
weight: '500',
|
|
28
|
-
style: 'normal',
|
|
29
|
-
},
|
|
30
|
-
],
|
|
18
|
+
const zen = localFont({
|
|
19
|
+
src: './local/Zen-Variable.woff2',
|
|
20
|
+
weight: '100 900',
|
|
31
21
|
display: 'swap',
|
|
32
|
-
variable: '--font-
|
|
22
|
+
variable: '--font-zen-sans',
|
|
33
23
|
})
|
|
34
24
|
|
|
35
25
|
const inter = localFont({
|
|
@@ -41,25 +31,27 @@ const inter = localFont({
|
|
|
41
31
|
export default [
|
|
42
32
|
{
|
|
43
33
|
font: inter,
|
|
44
|
-
|
|
34
|
+
name: 'sans'
|
|
45
35
|
},
|
|
46
36
|
{
|
|
47
37
|
font: inter,
|
|
48
|
-
|
|
38
|
+
name: 'nav'
|
|
49
39
|
},
|
|
50
40
|
{
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
// Zen is one variable face over 100-900, so the display cut is weight and
|
|
42
|
+
// tracking in CSS rather than a second file: '.font-heading' in style/lux-global.css.
|
|
43
|
+
font: zen,
|
|
44
|
+
name: 'heading'
|
|
53
45
|
}
|
|
54
46
|
].map (
|
|
55
47
|
(el) => {
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
48
|
+
const font: FontDesc | undefined = fonts.find((f: FontDesc) => (el.name === f.name))
|
|
49
|
+
if (!font) {
|
|
58
50
|
throw new Error('lux-next-fonts: Next font is not paired to a TW font!')
|
|
59
51
|
}
|
|
60
52
|
|
|
61
53
|
return ({
|
|
62
|
-
...
|
|
54
|
+
...font,
|
|
63
55
|
nextFont: el.font,
|
|
64
56
|
})
|
|
65
57
|
}
|
|
Binary file
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type localFont from 'next/font/local'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
type NextFont = {
|
|
5
|
-
className: string
|
|
6
|
-
style: { fontFamily: string; fontWeight?: number; fontStyle?: string }
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// from next repo
|
|
10
|
-
type NextFontWithVariable = NextFont & {
|
|
11
|
-
variable: string
|
|
12
|
-
}
|
|
3
|
+
import type { FontDesc } from './font-desc'
|
|
13
4
|
|
|
5
|
+
/**
|
|
6
|
+
* What a next/font loader hands back, DERIVED from the loader.
|
|
7
|
+
*
|
|
8
|
+
* These were two hand-copied declarations marked "from next repo" — a copy of a
|
|
9
|
+
* type that keeps moving, which is how the OpenGraph types in ../head-metadata
|
|
10
|
+
* went stale and failed as "two different types with this name exist, but they
|
|
11
|
+
* are unrelated". `ReturnType` names the position and lets Next say what lives
|
|
12
|
+
* there. The loader answers with a union — a font is only given a variable
|
|
13
|
+
* when it was asked for one — so `Extract` picks the half that has it.
|
|
14
|
+
*/
|
|
15
|
+
export type NextFontWithVariable = Extract<ReturnType<typeof localFont>, { variable: string }>
|
|
14
16
|
|
|
15
17
|
/*
|
|
16
|
-
NextFontDesc and
|
|
17
|
-
at different times during the next compile / build. Otherwise a nasty
|
|
18
|
+
NextFontDesc and FontDesc have to be seperate because they are needed
|
|
19
|
+
at different times during the next compile / build. Otherwise a nasty
|
|
18
20
|
race condition happens! That's why they are in different files.
|
|
19
21
|
*/
|
|
20
22
|
|
|
21
|
-
interface NextFontDesc extends
|
|
22
|
-
nextFont: NextFontWithVariable
|
|
23
|
+
interface NextFontDesc extends FontDesc {
|
|
24
|
+
nextFont: NextFontWithVariable
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export {
|
|
26
28
|
type NextFontDesc as default,
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
+
}
|
|
@@ -4,14 +4,15 @@ import type { Metadata } from 'next'
|
|
|
4
4
|
import Head from "next/head"
|
|
5
5
|
|
|
6
6
|
import type {
|
|
7
|
+
Author,
|
|
7
8
|
IconDescriptor,
|
|
9
|
+
OGImage,
|
|
10
|
+
OpenGraph,
|
|
8
11
|
TemplateString,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import type { OpenGraph, OGImage } from './from-next/opengraph-types'
|
|
14
|
-
import type { Twitter, TwitterImage } from './from-next/twitter-types'
|
|
12
|
+
ThemeColorDescriptor,
|
|
13
|
+
Twitter,
|
|
14
|
+
TwitterImage,
|
|
15
|
+
} from './next-metadata'
|
|
15
16
|
|
|
16
17
|
/*
|
|
17
18
|
NOTE: This is ONLY for sites that use the pages router in next.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next's metadata vocabulary, DERIVED from Next's own `Metadata` type.
|
|
3
|
+
*
|
|
4
|
+
* These were three files of hand-copied declarations under `from-next/`, which
|
|
5
|
+
* is a copy of a type that keeps moving: Next 16 changed `OpenGraph` and the
|
|
6
|
+
* copy stayed where it was, so passing `metadata.openGraph` into a component
|
|
7
|
+
* typed against the copy failed with
|
|
8
|
+
*
|
|
9
|
+
* Two different types with this name exist, but they are unrelated.
|
|
10
|
+
*
|
|
11
|
+
* — a message that reads like a duplicate package rather than a stale copy.
|
|
12
|
+
*
|
|
13
|
+
* Derivation cannot drift. Nothing here restates a shape; each line names a
|
|
14
|
+
* position inside `Metadata` and lets Next say what lives there.
|
|
15
|
+
*/
|
|
16
|
+
import type { Metadata } from 'next'
|
|
17
|
+
|
|
18
|
+
/** The element type of an array, or the type itself when it is not one. */
|
|
19
|
+
type Item<T> = T extends readonly (infer E)[] ? E : T
|
|
20
|
+
|
|
21
|
+
/** Metadata fields are nullable by convention; this is the value half. */
|
|
22
|
+
type Set<T> = Exclude<T, null | undefined>
|
|
23
|
+
|
|
24
|
+
export type OpenGraph = Set<Metadata['openGraph']>
|
|
25
|
+
export type OGImage = Item<Set<OpenGraph['images']>>
|
|
26
|
+
|
|
27
|
+
export type Twitter = Set<Metadata['twitter']>
|
|
28
|
+
export type TwitterImage = Item<Set<Twitter['images']>>
|
|
29
|
+
|
|
30
|
+
export type Author = Item<Set<Metadata['authors']>>
|
|
31
|
+
/**
|
|
32
|
+
* A theme colour with its media query. `Metadata['themeColor']` also admits a
|
|
33
|
+
* bare colour string; this is the form with fields, picked out by the one it
|
|
34
|
+
* always has.
|
|
35
|
+
*/
|
|
36
|
+
export type ThemeColorDescriptor = Extract<Item<Set<Metadata['themeColor']>>, { color: unknown }>
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The title's object form. `Metadata['title']` is that OR a plain string, and
|
|
40
|
+
* the string is the case with nothing to read.
|
|
41
|
+
*/
|
|
42
|
+
export type TemplateString = Exclude<Set<Metadata['title']>, string>
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* One icon, in its descriptor form. `Metadata['icons']` also admits a bare url
|
|
46
|
+
* and a grouping object (`{ icon, shortcut, apple }`); this is the one that
|
|
47
|
+
* describes a single icon, picked out by the field only it has.
|
|
48
|
+
*/
|
|
49
|
+
export type IconDescriptor = Extract<Item<Set<Metadata['icons']>>, { url: unknown }>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luxfi/ui",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.6",
|
|
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/",
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"./next": "./next/index.ts",
|
|
28
28
|
"./style/": "./style/",
|
|
29
29
|
"./site-def": "./site-def/index.ts",
|
|
30
|
-
"./tailwind": "./tailwind/index.ts",
|
|
31
30
|
"./util": "./util/index.ts"
|
|
32
31
|
},
|
|
33
32
|
"dependencies": {
|
|
@@ -41,21 +40,22 @@
|
|
|
41
40
|
"react-social-icons": "^6.4.0",
|
|
42
41
|
"react-tooltip": "^5.26.4",
|
|
43
42
|
"request": "^2.88.2",
|
|
44
|
-
"usehooks-ts": "^3.1.0"
|
|
43
|
+
"usehooks-ts": "^3.1.0",
|
|
44
|
+
"react-native-web": "^0.21.2"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@hanzo/iam": "0.21.9",
|
|
48
|
-
"@hanzo/commerce": "7.
|
|
49
|
-
"@hanzo/ui": "
|
|
48
|
+
"@hanzo/commerce": "7.7.0",
|
|
49
|
+
"@hanzo/ui": "8.23.2",
|
|
50
50
|
"@luxfi/menu-icons": "^1.0.2",
|
|
51
51
|
"@hookform/resolvers": "^3.3.2",
|
|
52
52
|
"lucide-react": "0.470.0",
|
|
53
53
|
"mobx": "^6.12.3",
|
|
54
54
|
"mobx-react-lite": "^4.0.7",
|
|
55
|
-
"next": "16.
|
|
55
|
+
"next": "16.3.3",
|
|
56
56
|
"next-themes": "^0.4.0",
|
|
57
|
-
"react": "19.2.
|
|
58
|
-
"react-dom": "19.2.
|
|
57
|
+
"react": "19.2.8",
|
|
58
|
+
"react-dom": "19.2.8",
|
|
59
59
|
"react-hook-form": "7.54.2",
|
|
60
60
|
"validator": "^13.11.0",
|
|
61
61
|
"zod": "3.23.8"
|
|
@@ -71,8 +71,7 @@
|
|
|
71
71
|
"@types/react": "19.0.2",
|
|
72
72
|
"@types/react-dom": "19.0.2",
|
|
73
73
|
"@types/validator": "^13.12.1",
|
|
74
|
-
"
|
|
75
|
-
"typescript": "5.7.3"
|
|
74
|
+
"typescript": "7.0.2"
|
|
76
75
|
},
|
|
77
76
|
"scripts": {
|
|
78
77
|
"lat": "npm show @luxfi/ui version",
|
package/root-layout/index.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import React, { type PropsWithChildren } from 'react'
|
|
|
2
2
|
import type { Viewport } from 'next'
|
|
3
3
|
|
|
4
4
|
import { Toaster } from '@hanzo/ui/primitives'
|
|
5
|
+
import { Hanzo } from '@hanzo/ui'
|
|
5
6
|
import { CommerceProvider } from '@hanzo/commerce'
|
|
6
7
|
|
|
7
8
|
import getAppRouterBodyFontClasses from '../next/font/get-app-router-font-classes'
|
|
@@ -14,6 +15,13 @@ import CommerceDrawer from '../components/commerce/drawer'
|
|
|
14
15
|
|
|
15
16
|
import type SiteDef from '../types/site-def'
|
|
16
17
|
|
|
18
|
+
// BY NAME, and before the Lux sheets so those can override. Next does not
|
|
19
|
+
// follow a CSS import out of node_modules on a consumer's behalf, so naming
|
|
20
|
+
// these here is what actually puts the reset and the token scale on the page —
|
|
21
|
+
// a site that omits them renders with browser defaults and no palette.
|
|
22
|
+
import '@hanzo/ui/theme.css'
|
|
23
|
+
import '@hanzo/ui/styles.css'
|
|
24
|
+
|
|
17
25
|
import '../style/lux-global.css'
|
|
18
26
|
import '../style/cart-animation.css'
|
|
19
27
|
import '../style/checkout-animation.css'
|
|
@@ -28,21 +36,20 @@ const viewport = {
|
|
|
28
36
|
} satisfies Viewport
|
|
29
37
|
|
|
30
38
|
/*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
The only classes left on <body> are next/font's own generated ones. Each
|
|
40
|
+
DEFINES a custom property (`--font-inter`, `--font-zen-sans`) holding the face
|
|
41
|
+
it loaded, and they have to be on an element for the rest of the sheet to
|
|
42
|
+
resolve those names — which is why they are classes and not a stylesheet.
|
|
43
|
+
|
|
44
|
+
The ground, the ink and the family that used to sit here as utility classes
|
|
45
|
+
are in lux-global.css, on `body` itself. They were `bg-background
|
|
46
|
+
text-foreground flex flex-col min-h-full`, and with no engine generating them
|
|
47
|
+
they were four names no sheet served.
|
|
48
|
+
|
|
49
|
+
re body: not overflow-hidden and not h-full — scroll-snap does not work on iOS
|
|
50
|
+
with those on the body tag.
|
|
42
51
|
*/
|
|
43
|
-
const bodyClasses =
|
|
44
|
-
'bg-background text-foreground flex flex-col min-h-full ' +
|
|
45
|
-
getAppRouterBodyFontClasses()
|
|
52
|
+
const bodyClasses = getAppRouterBodyFontClasses()
|
|
46
53
|
|
|
47
54
|
function RootLayout({
|
|
48
55
|
showHeader = false,
|
|
@@ -75,11 +82,23 @@ function RootLayout({
|
|
|
75
82
|
<FacebookPixelHead/>
|
|
76
83
|
</head>
|
|
77
84
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
{/* No inline style. The body's layout is stated once, in lux-global.css,
|
|
86
|
+
where it applies whether or not any script runs.
|
|
87
|
+
|
|
88
|
+
It used to render `display: none` here and a mount effect in
|
|
89
|
+
analytics.tsx set it back — hiding the page until React had hydrated.
|
|
90
|
+
That trades a flash for a site that is blank to anything without
|
|
91
|
+
JavaScript, and it silently outranked the sheet: the effect wrote
|
|
92
|
+
`flex`, so the `display: grid` the sheet asks for never once applied
|
|
93
|
+
on any of these sites.
|
|
94
|
+
|
|
95
|
+
Note the other half of that comment, still true: `overflow: hidden` on
|
|
96
|
+
<body> breaks scroll-snap on iOS, so it does not go here either. */}
|
|
97
|
+
<body suppressHydrationWarning className={bodyClasses}>
|
|
98
|
+
{/* The root every @hanzo/ui component reads its config from. Without it
|
|
99
|
+
a prerender throws `Err0` from inside gui — a message that names
|
|
100
|
+
neither the component nor the missing provider. */}
|
|
101
|
+
<Hanzo theme='dark'>
|
|
83
102
|
<Analytics/>
|
|
84
103
|
<Auth app={siteDef.app}>
|
|
85
104
|
{siteDef?.commerce ? (
|
|
@@ -94,6 +113,7 @@ function RootLayout({
|
|
|
94
113
|
)}
|
|
95
114
|
</Auth>
|
|
96
115
|
<Toaster position='top-center' duration={3000}/>
|
|
116
|
+
</Hanzo>
|
|
97
117
|
</body>
|
|
98
118
|
</html>
|
|
99
119
|
)
|
|
Binary file
|
package/style/lux-colors.css
CHANGED
package/style/lux-fonts.css
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/* Both faces are served from the app's own /fonts. The Next path (../next/font)
|
|
2
|
+
emits the same two through next/font instead. */
|
|
3
3
|
@layer base {
|
|
4
4
|
@font-face {
|
|
5
|
-
font-family: "
|
|
6
|
-
src: url("/fonts/
|
|
7
|
-
font-weight:
|
|
8
|
-
font-style: normal;
|
|
9
|
-
}
|
|
10
|
-
@font-face {
|
|
11
|
-
font-family: "DrukWide";
|
|
12
|
-
src: url("/fonts/Druk-Wide-Bold.ttf");
|
|
13
|
-
font-weight: 700;
|
|
5
|
+
font-family: "Zen";
|
|
6
|
+
src: url("/fonts/Zen-Variable.woff2") format("woff2");
|
|
7
|
+
font-weight: 100 900;
|
|
14
8
|
font-style: normal;
|
|
15
9
|
}
|
|
16
10
|
@font-face {
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/* Note, preflight is applied first:
|
|
2
2
|
https://unpkg.com/tailwindcss@3.3.5/src/css/preflight.css
|
|
3
3
|
*/
|
|
4
|
-
@import "tailwindcss/base";
|
|
5
|
-
|
|
6
4
|
/* see https://stackoverflow.com/questions/69746121/using-nextjs-how-can-you-import-in-css-using-tailwind-css */
|
|
7
5
|
/* @import "@hanzo/ui/style/hanzo-common"; */
|
|
8
|
-
@import "lux-colors";
|
|
9
|
-
@import "lux-fonts";
|
|
10
|
-
|
|
11
|
-
@import "tailwindcss/components";
|
|
12
|
-
@import "tailwindcss/utilities";
|
|
13
|
-
|
|
6
|
+
@import "./lux-colors.css";
|
|
7
|
+
@import "./lux-fonts.css";
|
|
14
8
|
div.nextjs-toast-errors-parent[data-nextjs-toast="true"] {
|
|
15
9
|
display: none;
|
|
16
10
|
}
|
|
17
11
|
|
|
12
|
+
/* Headings are Zen cut wide: the '.zen-wide' preset from @hanzo/font, fitted
|
|
13
|
+
against Druk Wide Bold. The preset's scaleX(1.56) is left out on purpose -- a
|
|
14
|
+
transform does not reflow, and these land on block h1-h4 that would overrun
|
|
15
|
+
their container. Use the class itself where a word has room to be monumental. */
|
|
18
16
|
.font-heading {
|
|
19
|
-
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
font-variation-settings: 'wght' 845;
|
|
19
|
+
letter-spacing: -0.04em;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/* Specific style fixes for react-square-web-payments-sdk -
|