@hanzo/ui 0.5.23 → 1.0.8
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/common/drawer-menu.tsx +8 -5
- package/common/header/index.tsx +28 -19
- package/next/analytics/fpixel.ts +2 -0
- package/next/not-found-content.mdx +2 -1
- package/next/not-found.tsx +1 -1
- package/next/root-layout.tsx +4 -2
- package/package.json +7 -10
- package/primitives/aspect-ratio.tsx +5 -0
- package/primitives/button.tsx +20 -7
- package/primitives/dialog.tsx +4 -4
- package/primitives/index.ts +8 -0
- package/primitives/list-box.tsx +74 -0
- package/primitives/main.tsx +6 -2
- package/primitives/radio-group.tsx +44 -0
- package/primitives/sheet.tsx +1 -1
- package/primitives/skeleton.tsx +1 -1
- package/primitives/toggle-group.tsx +63 -0
- package/primitives/toggle.tsx +72 -0
- package/tailwind/fonts.tailwind.ts +1 -1
- package/tailwind/tailwind.config.base.js +9 -3
- package/types/site-def.ts +3 -1
package/common/drawer-menu.tsx
CHANGED
|
@@ -9,12 +9,16 @@ import { Sheet, SheetContent, SheetTrigger } from '../primitives/sheet'
|
|
|
9
9
|
const DrawerMenu: React.FC<PropsWithChildren & {
|
|
10
10
|
trigger: ReactNode
|
|
11
11
|
className?: string
|
|
12
|
-
showLogo?: boolean
|
|
12
|
+
showLogo?: boolean,
|
|
13
|
+
propogate?: boolean
|
|
14
|
+
asChild?: boolean
|
|
13
15
|
}> = ({
|
|
14
16
|
trigger,
|
|
15
17
|
children,
|
|
16
18
|
className='',
|
|
17
|
-
showLogo=true
|
|
19
|
+
showLogo=true,
|
|
20
|
+
propogate=true,
|
|
21
|
+
asChild=false
|
|
18
22
|
}) => {
|
|
19
23
|
|
|
20
24
|
const [open, setOpen] = React.useState(false)
|
|
@@ -31,14 +35,13 @@ const DrawerMenu: React.FC<PropsWithChildren & {
|
|
|
31
35
|
|
|
32
36
|
return (
|
|
33
37
|
<Sheet open={open} onOpenChange={setOpen} >
|
|
34
|
-
<SheetTrigger>
|
|
38
|
+
<SheetTrigger className={className} asChild={asChild}>
|
|
35
39
|
{trigger}
|
|
36
40
|
</SheetTrigger>
|
|
37
41
|
<SheetContent
|
|
38
42
|
side="right"
|
|
39
|
-
className={className}
|
|
40
43
|
closeButtonClass='text-inherit opacity-90'
|
|
41
|
-
onClick={onAction}
|
|
44
|
+
onClick={propogate ? onAction : () => {}}
|
|
42
45
|
closeElement={<LucideX className='h-6 w-6 text-inherit'/>}
|
|
43
46
|
centerElement={showLogo ? <Logo size='xs' className='' /> : null}
|
|
44
47
|
>
|
package/common/header/index.tsx
CHANGED
|
@@ -19,36 +19,45 @@ const Header: React.FC<{
|
|
|
19
19
|
const allElements = (featured) ? [...common, ...featured] : common
|
|
20
20
|
// TODO move 13px into a size class and configure twMerge to recognize say, 'text-size-nav'
|
|
21
21
|
// (vs be beat out by 'text-color-nav')
|
|
22
|
-
const navItemClx = 'font-nav h-8
|
|
22
|
+
const navItemClx = 'font-nav h-8 !text-[13px]/[13px]'
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<header className={cn('bg-background sticky z-10 top-0 ', className)} >
|
|
26
26
|
{/* md or larger */}
|
|
27
|
-
<div className=
|
|
27
|
+
<div className={
|
|
28
|
+
'hidden md:flex flex-row md:h-[80px] items-center justify-between ' +
|
|
29
|
+
'px-[32px] 2xl:mx-auto max-w-screen-2xl'
|
|
30
|
+
}>
|
|
28
31
|
<Logo size='md' className='hidden lg:flex' key='two'/>
|
|
29
32
|
<Logo size='sm' className='hidden md:flex lg:hidden' key='one'/>
|
|
30
33
|
{/* md or larger */}
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
<div className='flex gap-7 items-center'>
|
|
35
|
+
<NavItems
|
|
36
|
+
currentAs={siteDef.currentAs}
|
|
37
|
+
items={allElements}
|
|
38
|
+
className='hidden md:flex md:gap-4 lg:justify-between lg:gap-7 '
|
|
39
|
+
itemClx={navItemClx}
|
|
40
|
+
key='three'
|
|
41
|
+
/>
|
|
42
|
+
{siteDef.nav.cart}
|
|
43
|
+
</div>
|
|
38
44
|
</div>
|
|
39
45
|
{/* smaller than md: mobile style drawer menu */}
|
|
40
46
|
<div className="flex md:hidden h-[44px] items-center justify-between px-2">
|
|
41
47
|
<Logo size='sm' />
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
<div className='flex gap-4'>
|
|
49
|
+
{siteDef.nav.cart}
|
|
50
|
+
<DrawerMenu
|
|
51
|
+
className='p-0 text-primary' // ui has 'text-inherit', so need this for close buttons to appear.
|
|
52
|
+
trigger={<Icons.burger className='h-7 w-7'/>}
|
|
53
|
+
>
|
|
54
|
+
<MobileNav
|
|
55
|
+
siteDef={siteDef}
|
|
56
|
+
className='pt-12'
|
|
57
|
+
commonItemClx='px-10 text-l h-10 justify-start border-b rounded-none'
|
|
58
|
+
/>
|
|
59
|
+
</DrawerMenu>
|
|
60
|
+
</div>
|
|
52
61
|
</div>
|
|
53
62
|
</header>
|
|
54
63
|
)
|
package/next/analytics/fpixel.ts
CHANGED
|
@@ -7,10 +7,12 @@ declare global {
|
|
|
7
7
|
export const FB_PIXEL_ID = process.env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID
|
|
8
8
|
|
|
9
9
|
export const pageview = () => {
|
|
10
|
+
// @ts-ignore
|
|
10
11
|
window.fbq('track', 'PageView')
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
// https://developers.facebook.com/docs/facebook-pixel/advanced/
|
|
14
15
|
export const event = (name: string, options = {}) => {
|
|
16
|
+
// @ts-ignore
|
|
15
17
|
window.fbq('track', name, options)
|
|
16
18
|
}
|
package/next/not-found.tsx
CHANGED
|
@@ -12,7 +12,7 @@ const NotFound: React.FC<{
|
|
|
12
12
|
}> = ({
|
|
13
13
|
siteDef
|
|
14
14
|
}) => (<>
|
|
15
|
-
<Main className='h-[700px]'>
|
|
15
|
+
<Main className='xs:h-[100svh] xs:px-8 sm:px-10 sm:h-[700px]'>
|
|
16
16
|
<ApplyTypography className='mt-[200px] flex flex-col md:gap-8 '>
|
|
17
17
|
<NotFoundMDX />
|
|
18
18
|
</ApplyTypography>
|
package/next/root-layout.tsx
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import React, { type PropsWithChildren } from 'react'
|
|
2
2
|
|
|
3
|
+
import type { Viewport } from 'next'
|
|
4
|
+
|
|
3
5
|
import Header from '../common/header'
|
|
4
6
|
import type { SiteDef } from '../types'
|
|
5
7
|
import getAppRouterBodyFontClasses from './get-app-router-font-classes'
|
|
6
8
|
import { FacebookPixelHead, FacebookPixel } from './analytics/pixel-analytics'
|
|
7
9
|
import { GoogleAnalytics } from '@next/third-parties/google'
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
// Next 14: https://nextjs.org/docs/app/building-your-application/upgrading/codemods#use-viewport-export
|
|
10
12
|
const viewport = {
|
|
11
13
|
themeColor: [
|
|
12
14
|
{ media: '(prefers-color-scheme: light)', color: 'white' },
|
|
13
15
|
{ media: '(prefers-color-scheme: dark)', color: 'black' },
|
|
14
16
|
],
|
|
15
|
-
}
|
|
17
|
+
} satisfies Viewport
|
|
16
18
|
|
|
17
19
|
/*
|
|
18
20
|
These '.variable' fields are actually autogenerate css classnames that *define* the actual
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.8",
|
|
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/",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"license": "BSD-3-Clause",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "git+https://github.com/hanzoai/
|
|
14
|
+
"url": "git+https://github.com/hanzoai/react-sdk.git",
|
|
15
15
|
"directory": "pkgs/hanzo-ui"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"@hookform/resolvers": "^3.3.2",
|
|
47
47
|
"@next/third-parties": "^14.1.0",
|
|
48
48
|
"@radix-ui/react-accordion": "^1.1.2",
|
|
49
|
+
"@radix-ui/react-aspect-ratio": "^1.0.3",
|
|
49
50
|
"@radix-ui/react-avatar": "^1.0.3",
|
|
50
51
|
"@radix-ui/react-checkbox": "^1.0.4",
|
|
51
52
|
"@radix-ui/react-dialog": "^1.0.5",
|
|
@@ -53,6 +54,7 @@
|
|
|
53
54
|
"@radix-ui/react-label": "^2.0.2",
|
|
54
55
|
"@radix-ui/react-popover": "^1.0.6",
|
|
55
56
|
"@radix-ui/react-progress": "^1.0.3",
|
|
57
|
+
"@radix-ui/react-radio-group": "^1.1.3",
|
|
56
58
|
"@radix-ui/react-scroll-area": "^1.0.5",
|
|
57
59
|
"@radix-ui/react-select": "^2.0.0",
|
|
58
60
|
"@radix-ui/react-separator": "^1.0.3",
|
|
@@ -60,6 +62,8 @@
|
|
|
60
62
|
"@radix-ui/react-switch": "^1.0.3",
|
|
61
63
|
"@radix-ui/react-tabs": "^1.0.4",
|
|
62
64
|
"@radix-ui/react-toast": "^1.1.5",
|
|
65
|
+
"@radix-ui/react-toggle": "^1.0.3",
|
|
66
|
+
"@radix-ui/react-toggle-group": "^1.0.4",
|
|
63
67
|
"@tailwindcss/container-queries": "^0.1.1",
|
|
64
68
|
"class-variance-authority": "^0.7.0",
|
|
65
69
|
"clsx": "^2.1.0",
|
|
@@ -76,20 +80,17 @@
|
|
|
76
80
|
"react-intersection-observer": "^9.7.0",
|
|
77
81
|
"react-social-icons": "^6.4.0",
|
|
78
82
|
"tailwind-merge": "^2.2.0",
|
|
79
|
-
"tailwindcss-animate": "^1.0.6",
|
|
80
83
|
"tailwindcss-interaction-media": "^0.1.0",
|
|
81
84
|
"validator": "^13.11.0",
|
|
82
85
|
"zod": "3.21.4"
|
|
83
86
|
},
|
|
84
87
|
"peerDependencies": {
|
|
85
|
-
"@next/mdx": "^14.1.0",
|
|
86
88
|
"next": "^14.1.0",
|
|
87
89
|
"next-themes": "^0.2.1",
|
|
88
90
|
"react": "^18.2.0",
|
|
89
91
|
"react-dom": "^18.2.0"
|
|
90
92
|
},
|
|
91
93
|
"devDependencies": {
|
|
92
|
-
"@mdx-js/esbuild": "^3.0.0",
|
|
93
94
|
"@mdx-js/loader": "^3.0.0",
|
|
94
95
|
"@mdx-js/react": "^3.0.0",
|
|
95
96
|
"@types/facebook-pixel": "^0.0.30",
|
|
@@ -98,11 +99,7 @@
|
|
|
98
99
|
"@types/mdx": "^2.0.9",
|
|
99
100
|
"@types/react": "^18.2.48",
|
|
100
101
|
"@types/react-dom": "^18.2.18",
|
|
101
|
-
"autoprefixer": "^10.4.16",
|
|
102
|
-
"path": "^0.12.7",
|
|
103
|
-
"postcss": "^8.4.33",
|
|
104
|
-
"postcss-import": "^16.0.0",
|
|
105
102
|
"tailwindcss": "^3.4.1",
|
|
106
|
-
"typescript": "
|
|
103
|
+
"typescript": "5.3.3"
|
|
107
104
|
}
|
|
108
105
|
}
|
package/primitives/button.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { cn } from "../util"
|
|
|
6
6
|
|
|
7
7
|
const variant = {
|
|
8
8
|
primary: "bg-primary text-primary-fg hover:bg-primary-hover font-nav whitespace-nowrap not-typography",
|
|
9
|
-
secondary: "bg-secondary text-secondary-fg hover:bg-secondary
|
|
9
|
+
secondary: "bg-secondary text-secondary-fg hover:bg-secondary-hover font-nav whitespace-nowrap not-typography",
|
|
10
10
|
outline: "text-foreground bg-background border border-muted-4 hover:bg-level-1 hover:text-accent hover:border-accent font-nav whitespace-nowrap not-typography",
|
|
11
11
|
destructive: "bg-destructive text-destructive-fg font-sans whitespace-nowrap hover:bg-destructive-hover",
|
|
12
12
|
ghost: "text-foreground hover:bg-level-1 hover:text-accent whitespace-nowrap font-sans ",
|
|
@@ -16,25 +16,38 @@ const variant = {
|
|
|
16
16
|
|
|
17
17
|
const size = {
|
|
18
18
|
link: '',
|
|
19
|
-
|
|
19
|
+
xs: "h-8 px-2 text-xs",
|
|
20
|
+
sm: "h-9 px-3 text-xs",
|
|
20
21
|
square: 'h-10 py-2 px-2 text-sm aspect-square',
|
|
21
22
|
default: "h-10 py-2 px-4 text-sm lg:min-w-[220px]",
|
|
22
|
-
lg: "h-10 px-8
|
|
23
|
+
lg: "h-10 px-8 text-sm md:text-base min-w-0 md:min-w-[260px] lg:min-w-[300px]",
|
|
23
24
|
icon: "h-10 w-10",
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
const rounded = {
|
|
28
|
+
full: 'rounded-full',
|
|
29
|
+
sm: 'rounded-sm',
|
|
30
|
+
md: 'rounded-md',
|
|
31
|
+
lg: 'rounded-lg',
|
|
32
|
+
xl: 'rounded-xl',
|
|
33
|
+
none: ''
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
26
37
|
const buttonVariants = cva(
|
|
27
|
-
"flex items-center justify-center
|
|
38
|
+
"flex items-center justify-center font-medium transition-colors " +
|
|
28
39
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 " +
|
|
29
40
|
"disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
|
|
30
41
|
{
|
|
31
42
|
variants: {
|
|
32
43
|
variant,
|
|
33
|
-
size
|
|
44
|
+
size,
|
|
45
|
+
rounded
|
|
34
46
|
},
|
|
35
47
|
defaultVariants: {
|
|
36
48
|
variant: "primary",
|
|
37
49
|
size: "default",
|
|
50
|
+
rounded: 'md'
|
|
38
51
|
},
|
|
39
52
|
}
|
|
40
53
|
)
|
|
@@ -50,11 +63,11 @@ interface ButtonProps extends
|
|
|
50
63
|
}
|
|
51
64
|
|
|
52
65
|
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
53
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
66
|
+
({ className, variant, size, rounded, asChild = false, ...props }, ref) => {
|
|
54
67
|
const Comp = asChild ? Slot : "button"
|
|
55
68
|
return (
|
|
56
69
|
<Comp
|
|
57
|
-
className={cn(buttonVariants({ variant, size,
|
|
70
|
+
className={cn(buttonVariants({ variant, size, rounded }), className )}
|
|
58
71
|
ref={ref}
|
|
59
72
|
{...props}
|
|
60
73
|
/>
|
package/primitives/dialog.tsx
CHANGED
|
@@ -50,7 +50,7 @@ const DialogClose = React.forwardRef<
|
|
|
50
50
|
<DialogPrimitive.Close
|
|
51
51
|
ref={ref}
|
|
52
52
|
className={cn(
|
|
53
|
-
"absolute right-4 top-3 p-1 justify-self-start hover:brightness-105 hover:scale-110 duration-100 ring-1 ring-muted transition
|
|
53
|
+
"absolute right-4 top-3 p-1 justify-self-start hover:brightness-105 hover:scale-110 duration-100 ring-1 ring-muted transition hover:text- focus:outline-none rounded-full items-center",
|
|
54
54
|
className
|
|
55
55
|
)}
|
|
56
56
|
{...props}
|
|
@@ -71,7 +71,7 @@ const DialogContent = React.forwardRef<
|
|
|
71
71
|
<DialogPrimitive.Content
|
|
72
72
|
ref={ref}
|
|
73
73
|
className={cn(
|
|
74
|
-
"fixed z-50 grid w-full gap-4 rounded-t-lg bg-
|
|
74
|
+
"fixed z-50 grid w-full gap-4 rounded-t-lg bg-level-1 p-4 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-sm sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
|
|
75
75
|
className
|
|
76
76
|
)}
|
|
77
77
|
{...props}
|
|
@@ -118,7 +118,7 @@ const DialogTitle = React.forwardRef<
|
|
|
118
118
|
<DialogPrimitive.Title
|
|
119
119
|
ref={ref}
|
|
120
120
|
className={cn(
|
|
121
|
-
"text-lg font-semibold leading-none tracking-tight text-
|
|
121
|
+
"text-lg font-semibold leading-none tracking-tight text-foreground",
|
|
122
122
|
className
|
|
123
123
|
)}
|
|
124
124
|
{...props}
|
|
@@ -132,7 +132,7 @@ const DialogDescription = React.forwardRef<
|
|
|
132
132
|
>(({ className, ...props }, ref) => (
|
|
133
133
|
<DialogPrimitive.Description
|
|
134
134
|
ref={ref}
|
|
135
|
-
className={cn("text-sm text-
|
|
135
|
+
className={cn("text-sm text-muted", className)}
|
|
136
136
|
{...props}
|
|
137
137
|
/>
|
|
138
138
|
))
|
package/primitives/index.ts
CHANGED
|
@@ -124,11 +124,18 @@ export {
|
|
|
124
124
|
AvatarFallback
|
|
125
125
|
} from './avatar'
|
|
126
126
|
|
|
127
|
+
export { Toggle, toggleVariants } from './toggle'
|
|
128
|
+
export { ToggleGroup, ToggleGroupItem } from './toggle-group'
|
|
129
|
+
|
|
130
|
+
|
|
127
131
|
export { ScrollArea, ScrollBar } from './scroll-area'
|
|
128
132
|
|
|
129
133
|
export { Toaster } from './toaster'
|
|
130
134
|
export { useToast, toast } from './use-toast'
|
|
135
|
+
export { RadioGroup, RadioGroupItem } from './radio-group'
|
|
131
136
|
|
|
137
|
+
export { default as AspectRatio } from './aspect-ratio'
|
|
138
|
+
export { default as Badge } from './badge'
|
|
132
139
|
export { default as VideoPlayer } from './video-player'
|
|
133
140
|
export { default as YouTubeEmbed } from './youtube-embed'
|
|
134
141
|
export { default as Switch } from './switch'
|
|
@@ -141,4 +148,5 @@ export { default as Skeleton } from './skeleton'
|
|
|
141
148
|
export { default as InlineIcon } from './inline-icon'
|
|
142
149
|
export { default as NavItems} from './nav-items'
|
|
143
150
|
export { default as Main } from './main'
|
|
151
|
+
export { default as ListBox } from './list-box'
|
|
144
152
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { cn } from '../util'
|
|
4
|
+
|
|
5
|
+
function Item<T>({
|
|
6
|
+
value,
|
|
7
|
+
label,
|
|
8
|
+
className,
|
|
9
|
+
onClick,
|
|
10
|
+
first=false,
|
|
11
|
+
last=false,
|
|
12
|
+
selected=false
|
|
13
|
+
}:{
|
|
14
|
+
value: T
|
|
15
|
+
label: string
|
|
16
|
+
className: string
|
|
17
|
+
onClick: (val: T) => void
|
|
18
|
+
first?: boolean
|
|
19
|
+
last?: boolean
|
|
20
|
+
selected?: boolean
|
|
21
|
+
}) {
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div
|
|
25
|
+
className={cn(
|
|
26
|
+
'font-normal text-muted-1 px-3 py-1 cursor-pointer hover:text-foreground ',
|
|
27
|
+
last ? '' : 'border-b',
|
|
28
|
+
selected ? 'font-semibold text-accent hover:text-accent' : '',
|
|
29
|
+
className
|
|
30
|
+
)}
|
|
31
|
+
onClick={() => {onClick(value)}}
|
|
32
|
+
>
|
|
33
|
+
<span>{label}</span>
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function ListBox<T>({
|
|
39
|
+
values,
|
|
40
|
+
labels,
|
|
41
|
+
onValueChange,
|
|
42
|
+
value,
|
|
43
|
+
isEqual,
|
|
44
|
+
outClx = '',
|
|
45
|
+
itemClx = ''
|
|
46
|
+
}:{
|
|
47
|
+
values: T[]
|
|
48
|
+
labels: string[]
|
|
49
|
+
onValueChange: (val: T) => void
|
|
50
|
+
value: T | undefined
|
|
51
|
+
isEqual: (v1: T, v2: T) => boolean
|
|
52
|
+
outClx?: string
|
|
53
|
+
itemClx?: string
|
|
54
|
+
}): JSX.Element {
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div className={cn('border rounded-md select-none', outClx)} >
|
|
58
|
+
{values.map((val, i) => (
|
|
59
|
+
<Item<T>
|
|
60
|
+
value={val}
|
|
61
|
+
label={labels[i]}
|
|
62
|
+
onClick={onValueChange}
|
|
63
|
+
className={itemClx}
|
|
64
|
+
first={i === 0}
|
|
65
|
+
last={i === values.length - 1}
|
|
66
|
+
selected={value && isEqual(val, value)}
|
|
67
|
+
key={labels[i]}
|
|
68
|
+
/>
|
|
69
|
+
))}
|
|
70
|
+
</div>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default ListBox
|
package/primitives/main.tsx
CHANGED
|
@@ -5,11 +5,15 @@ const c = 'max-w-screen-2xl 2xl:w-[1500px] lg:mx-auto ' +
|
|
|
5
5
|
'flex flex-col justify-start items-stretch ' +
|
|
6
6
|
'p-4 md:px-6 lg:px-8 '
|
|
7
7
|
|
|
8
|
-
const Main: React.FC<PropsWithChildren & {
|
|
8
|
+
const Main: React.FC<PropsWithChildren & {
|
|
9
|
+
id?: string
|
|
10
|
+
className?: string
|
|
11
|
+
}> = ({
|
|
9
12
|
children,
|
|
10
13
|
className='',
|
|
14
|
+
id
|
|
11
15
|
}) => (
|
|
12
|
-
<main className={cn(c, className)}>
|
|
16
|
+
<main id={id ?? 'HZO_UI_MAIN'} className={cn(c, className)}>
|
|
13
17
|
{children}
|
|
14
18
|
</main>
|
|
15
19
|
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
|
|
5
|
+
import { Circle } from "lucide-react"
|
|
6
|
+
|
|
7
|
+
import { cn } from "../util"
|
|
8
|
+
|
|
9
|
+
const RadioGroup = React.forwardRef<
|
|
10
|
+
React.ElementRef<typeof RadioGroupPrimitive.Root>,
|
|
11
|
+
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
|
|
12
|
+
>(({ className, ...props }, ref) => {
|
|
13
|
+
return (
|
|
14
|
+
<RadioGroupPrimitive.Root
|
|
15
|
+
className={cn("grid gap-2", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
ref={ref}
|
|
18
|
+
/>
|
|
19
|
+
)
|
|
20
|
+
})
|
|
21
|
+
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
|
|
22
|
+
|
|
23
|
+
const RadioGroupItem = React.forwardRef<
|
|
24
|
+
React.ElementRef<typeof RadioGroupPrimitive.Item>,
|
|
25
|
+
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
|
|
26
|
+
>(({ className, ...props }, ref) => {
|
|
27
|
+
return (
|
|
28
|
+
<RadioGroupPrimitive.Item
|
|
29
|
+
ref={ref}
|
|
30
|
+
className={cn(
|
|
31
|
+
"aspect-square h-4 w-4 rounded-full border border-muted text-foreground ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
32
|
+
className
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
|
37
|
+
<Circle className="h-2.5 w-2.5 fill-current text-current" />
|
|
38
|
+
</RadioGroupPrimitive.Indicator>
|
|
39
|
+
</RadioGroupPrimitive.Item>
|
|
40
|
+
)
|
|
41
|
+
})
|
|
42
|
+
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
|
|
43
|
+
|
|
44
|
+
export { RadioGroup, RadioGroupItem }
|
package/primitives/sheet.tsx
CHANGED
|
@@ -32,7 +32,7 @@ const SheetOverlay = React.forwardRef<
|
|
|
32
32
|
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
|
|
33
33
|
|
|
34
34
|
const sheetVariants = cva(
|
|
35
|
-
'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-300',
|
|
35
|
+
'fixed z-50 gap-4 bg-background p-3 sm:p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-300',
|
|
36
36
|
{
|
|
37
37
|
variants: {
|
|
38
38
|
side: {
|
package/primitives/skeleton.tsx
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'
|
|
5
|
+
import type { VariantProps } from 'class-variance-authority'
|
|
6
|
+
|
|
7
|
+
import { cn } from '../util'
|
|
8
|
+
import { toggleVariants } from './toggle'
|
|
9
|
+
|
|
10
|
+
const ToggleGroupContext = React.createContext<
|
|
11
|
+
VariantProps<typeof toggleVariants>
|
|
12
|
+
>({
|
|
13
|
+
size: 'default',
|
|
14
|
+
variant: 'default',
|
|
15
|
+
rounded: 'md'
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const ToggleGroup = React.forwardRef<
|
|
19
|
+
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
|
|
20
|
+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
|
|
21
|
+
VariantProps<typeof toggleVariants>
|
|
22
|
+
>(({ className, variant, size, rounded, children, ...props }, ref) => (
|
|
23
|
+
<ToggleGroupPrimitive.Root
|
|
24
|
+
ref={ref}
|
|
25
|
+
className={cn('flex items-center justify-center gap-1', className)}
|
|
26
|
+
{...props}
|
|
27
|
+
>
|
|
28
|
+
<ToggleGroupContext.Provider value={{ variant, size, rounded }}>
|
|
29
|
+
{children}
|
|
30
|
+
</ToggleGroupContext.Provider>
|
|
31
|
+
</ToggleGroupPrimitive.Root>
|
|
32
|
+
))
|
|
33
|
+
|
|
34
|
+
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
|
|
35
|
+
|
|
36
|
+
const ToggleGroupItem = React.forwardRef<
|
|
37
|
+
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
|
|
38
|
+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
|
|
39
|
+
VariantProps<typeof toggleVariants>
|
|
40
|
+
>(({ className, children, variant, size, rounded, ...props }, ref) => {
|
|
41
|
+
const context = React.useContext(ToggleGroupContext)
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<ToggleGroupPrimitive.Item
|
|
45
|
+
ref={ref}
|
|
46
|
+
className={cn(
|
|
47
|
+
toggleVariants({
|
|
48
|
+
variant: context.variant || variant,
|
|
49
|
+
size: context.size || size,
|
|
50
|
+
rounded: context.rounded || rounded,
|
|
51
|
+
}),
|
|
52
|
+
className
|
|
53
|
+
)}
|
|
54
|
+
{...props}
|
|
55
|
+
>
|
|
56
|
+
{children}
|
|
57
|
+
</ToggleGroupPrimitive.Item>
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
|
|
62
|
+
|
|
63
|
+
export { ToggleGroup, ToggleGroupItem }
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import * as TogglePrimitive from '@radix-ui/react-toggle'
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
6
|
+
|
|
7
|
+
import { cn } from '../util'
|
|
8
|
+
|
|
9
|
+
const toggleVariants = cva(
|
|
10
|
+
'inline-flex items-center justify-center text-sm font-medium ' +
|
|
11
|
+
'ring-offset-background ' +
|
|
12
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ' +
|
|
13
|
+
'focus-visible:ring-offset-2 disabled:pointer-events-none ' +
|
|
14
|
+
'active:bg-level-3 active:text-accent ',
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
default: 'text-muted-1 hover:text-accent ' +
|
|
19
|
+
'data-[state=off]:bg-level-1 hover:data-[state=off]:text-foreground ' +
|
|
20
|
+
'data-[state=on]:text-foreground data-[state=on]:bg-level-3 ' +
|
|
21
|
+
'data-[state=on]:hover:bg-level-3 ',
|
|
22
|
+
|
|
23
|
+
outline: 'border border-muted-3 text-muted-1 ' +
|
|
24
|
+
'data-[state=off]:bg-level-1 hover:data-[state=off]:text-foreground ' +
|
|
25
|
+
'data-[state=on]:bg-level-3 data-[state=on]:border-muted data-[state=on]:text-foreground',
|
|
26
|
+
},
|
|
27
|
+
size: {
|
|
28
|
+
default: 'h-10 px-3',
|
|
29
|
+
sm: 'h-9 px-2',
|
|
30
|
+
lg: 'h-11 px-5',
|
|
31
|
+
},
|
|
32
|
+
rounded: {
|
|
33
|
+
full: 'rounded-full',
|
|
34
|
+
sm: 'rounded-sm',
|
|
35
|
+
lsm: 'rounded-l-sm',
|
|
36
|
+
rsm: 'rounded-r-sm',
|
|
37
|
+
md: 'rounded-md',
|
|
38
|
+
lmd: 'rounded-l-md',
|
|
39
|
+
rmd: 'rounded-r-md',
|
|
40
|
+
lg: 'rounded-lg',
|
|
41
|
+
llg: 'rounded-l-lg',
|
|
42
|
+
rlg: 'rounded-r-lg',
|
|
43
|
+
xl: 'rounded-xl',
|
|
44
|
+
lxl: 'rounded-l-xl',
|
|
45
|
+
rxl: 'rounded-r-xl',
|
|
46
|
+
none: 'rounded-none'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
},
|
|
50
|
+
defaultVariants: {
|
|
51
|
+
variant: 'default',
|
|
52
|
+
size: 'default',
|
|
53
|
+
rounded: 'md'
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
const Toggle = React.forwardRef<
|
|
59
|
+
React.ElementRef<typeof TogglePrimitive.Root>,
|
|
60
|
+
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
|
|
61
|
+
VariantProps<typeof toggleVariants>
|
|
62
|
+
>(({ className, variant, size, rounded, ...props }, ref) => (
|
|
63
|
+
<TogglePrimitive.Root
|
|
64
|
+
ref={ref}
|
|
65
|
+
className={cn(toggleVariants({ variant, size, rounded} ), className )}
|
|
66
|
+
{...props}
|
|
67
|
+
/>
|
|
68
|
+
))
|
|
69
|
+
|
|
70
|
+
Toggle.displayName = TogglePrimitive.Root.displayName
|
|
71
|
+
|
|
72
|
+
export { Toggle, toggleVariants }
|
|
@@ -17,7 +17,7 @@ export const fontFamily = (ignoreTheme: any): {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const fontSize = {
|
|
20
|
-
xxs: ['0.
|
|
20
|
+
xxs: ['0.65rem', { lineHeight: '0.8rem' }], // very fine print
|
|
21
21
|
xs: ['0.8rem', { lineHeight: '1rem' }], // fine print
|
|
22
22
|
sm: ['0.9rem', { lineHeight: '1.2rem' }], // 'standard' some news article cards (set manually when using typography-sm)
|
|
23
23
|
base: ['1rem', { lineHeight: 1.4 }],
|
|
@@ -611,6 +611,7 @@ export default {
|
|
|
611
611
|
...breakpoints(theme('screens')),
|
|
612
612
|
}),
|
|
613
613
|
minHeight: {
|
|
614
|
+
...spacing,
|
|
614
615
|
0: '0px',
|
|
615
616
|
full: '100%',
|
|
616
617
|
screen: '100vh',
|
|
@@ -618,13 +619,15 @@ export default {
|
|
|
618
619
|
max: 'max-content',
|
|
619
620
|
fit: 'fit-content',
|
|
620
621
|
},
|
|
621
|
-
minWidth: {
|
|
622
|
+
minWidth: ({ theme, breakpoints }) => ({
|
|
623
|
+
...spacing,
|
|
622
624
|
0: '0px',
|
|
623
625
|
full: '100%',
|
|
624
626
|
min: 'min-content',
|
|
625
627
|
max: 'max-content',
|
|
626
628
|
fit: 'fit-content',
|
|
627
|
-
|
|
629
|
+
...breakpoints(theme('screens')),
|
|
630
|
+
}),
|
|
628
631
|
objectPosition: {
|
|
629
632
|
bottom: 'bottom',
|
|
630
633
|
center: 'center',
|
|
@@ -769,7 +772,10 @@ export default {
|
|
|
769
772
|
2: '2',
|
|
770
773
|
},
|
|
771
774
|
supports: {},
|
|
772
|
-
data: {
|
|
775
|
+
data: {
|
|
776
|
+
on: 'state~="on"',
|
|
777
|
+
off: 'state~="off"',
|
|
778
|
+
},
|
|
773
779
|
textColor: ({ theme }) => theme('colors'),
|
|
774
780
|
textDecorationColor: ({ theme }) => theme('colors'),
|
|
775
781
|
textDecorationThickness: {
|
package/types/site-def.ts
CHANGED
|
@@ -7,7 +7,9 @@ interface SiteDef {
|
|
|
7
7
|
/** common elements (will auto-select currentAs if it's provide) */
|
|
8
8
|
/** optional feature element. right-most after 'elements' (any min-w is ignored) */
|
|
9
9
|
common: LinkDef[]
|
|
10
|
-
featured?: LinkDef[]
|
|
10
|
+
featured?: LinkDef[]
|
|
11
|
+
auth?: boolean
|
|
12
|
+
cart?: React.ReactNode
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
/**
|