@hanzo/ui 3.6.4 → 3.7.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.
- package/blocks/components/cta-block.tsx +3 -3
- package/package.json +24 -18
- package/primitives/action-button.tsx +12 -11
- package/primitives/button.tsx +0 -7
- package/primitives/drawer.tsx +32 -18
- package/primitives/index.ts +1 -2
- package/primitives/link-element.tsx +16 -11
- package/tailwind/tailwind.config.hanzo-preset.js +0 -5
- package/types/image-def.ts +1 -2
- package/types/link-def.ts +3 -5
- package/util/index.ts +4 -1
- package/util/two-way-map.ts +19 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
|
|
3
3
|
import type { LinkDef, ButtonDef} from '../../types'
|
|
4
|
-
import {
|
|
4
|
+
import { buttonVariants, ActionButton, LinkElement } from '../../primitives'
|
|
5
5
|
import type { CTABlock } from '../def'
|
|
6
|
-
import { cn, containsToken } from '../../util'
|
|
6
|
+
import { cn, containsToken, type VariantProps } from '../../util'
|
|
7
7
|
|
|
8
8
|
import type BlockComponentProps from './block-component-props'
|
|
9
9
|
|
|
10
10
|
const CtaBlockComponent: React.FC<BlockComponentProps & {
|
|
11
11
|
itemClasses?: string
|
|
12
|
-
itemSize?:
|
|
12
|
+
itemSize?: VariantProps<typeof buttonVariants>['size'],
|
|
13
13
|
renderLink?: (def: LinkDef, key: any) => JSX.Element
|
|
14
14
|
renderButton?: (def: ButtonDef, key: any) => JSX.Element
|
|
15
15
|
}> = ({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.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/",
|
|
@@ -31,9 +31,15 @@
|
|
|
31
31
|
"scripts": {
|
|
32
32
|
"lat": "npm show @hanzo/ui version",
|
|
33
33
|
"pub": "npm publish",
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
"tc": "tsc"
|
|
35
|
+
},
|
|
36
|
+
"exports": {
|
|
37
|
+
"./blocks": "./blocks/index.ts",
|
|
38
|
+
"./primitives": "./primitives/index.ts",
|
|
39
|
+
"./style/": "./style/*",
|
|
40
|
+
"./tailwind": "./tailwind/index.ts",
|
|
41
|
+
"./types": "./types/index.ts",
|
|
42
|
+
"./util": "./util/index.ts"
|
|
37
43
|
},
|
|
38
44
|
"dependencies": {
|
|
39
45
|
"@next/third-parties": "^14.1.0",
|
|
@@ -63,30 +69,30 @@
|
|
|
63
69
|
"class-variance-authority": "^0.7.0",
|
|
64
70
|
"clsx": "^2.1.0",
|
|
65
71
|
"cmdk": "^0.2.0",
|
|
66
|
-
"embla-carousel-react": "8.0.
|
|
72
|
+
"embla-carousel-react": "8.0.2",
|
|
67
73
|
"input-otp": "^1.0.1",
|
|
68
74
|
"lodash.castarray": "^4.4.0",
|
|
69
75
|
"lodash.isplainobject": "^4.0.6",
|
|
70
76
|
"lodash.merge": "^4.6.2",
|
|
71
|
-
"markdown-to-jsx": "^7.
|
|
72
|
-
"postcss-selector-parser": "^6.0.
|
|
73
|
-
"react-day-picker": "^8.
|
|
74
|
-
"react-intersection-observer": "^9.
|
|
75
|
-
"sonner": "^1.
|
|
76
|
-
"tailwind-merge": "^2.
|
|
77
|
+
"markdown-to-jsx": "^7.4.7",
|
|
78
|
+
"postcss-selector-parser": "^6.0.16",
|
|
79
|
+
"react-day-picker": "^8.10.1",
|
|
80
|
+
"react-intersection-observer": "^9.8.2",
|
|
81
|
+
"sonner": "^1.4.41",
|
|
82
|
+
"tailwind-merge": "^2.3.0",
|
|
77
83
|
"tailwindcss-animate": "^1.0.7",
|
|
78
84
|
"tailwindcss-interaction-media": "^0.1.0",
|
|
79
85
|
"vaul": "^0.9.0"
|
|
80
86
|
},
|
|
81
87
|
"peerDependencies": {
|
|
82
88
|
"@hookform/resolvers": "^3.3.2",
|
|
83
|
-
"embla-carousel": "^8.0.
|
|
89
|
+
"embla-carousel": "^8.0.2",
|
|
84
90
|
"lucide-react": "^0.344.0",
|
|
85
91
|
"next": "14.1.3",
|
|
86
92
|
"next-themes": "^0.2.1",
|
|
87
93
|
"react": "^18.2.0",
|
|
88
94
|
"react-dom": "^18.2.0",
|
|
89
|
-
"react-hook-form": "^7.
|
|
95
|
+
"react-hook-form": "^7.51.3",
|
|
90
96
|
"validator": "^13.11.0",
|
|
91
97
|
"zod": "3.21.4"
|
|
92
98
|
},
|
|
@@ -96,11 +102,11 @@
|
|
|
96
102
|
"@types/facebook-pixel": "^0.0.30",
|
|
97
103
|
"@types/gtag.js": "^0.0.19",
|
|
98
104
|
"@types/lodash.merge": "^4.6.9",
|
|
99
|
-
"@types/mdx": "^2.0.
|
|
100
|
-
"@types/react": "^18.2.
|
|
101
|
-
"@types/react-dom": "^18.2.
|
|
102
|
-
"embla-carousel": "^8.0.
|
|
103
|
-
"tailwindcss": "^3.4.
|
|
105
|
+
"@types/mdx": "^2.0.13",
|
|
106
|
+
"@types/react": "^18.2.79",
|
|
107
|
+
"@types/react-dom": "^18.2.25",
|
|
108
|
+
"embla-carousel": "^8.0.2",
|
|
109
|
+
"tailwindcss": "^3.4.3",
|
|
104
110
|
"typescript": "5.3.3"
|
|
105
111
|
}
|
|
106
112
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import dynamic from 'next/dynamic'
|
|
3
3
|
|
|
4
|
-
import { cn } from '../util'
|
|
4
|
+
import { cn, type VariantProps } from '../util'
|
|
5
5
|
|
|
6
6
|
import type { ButtonDef, ButtonModalDef } from '../types'
|
|
7
|
-
import type {
|
|
7
|
+
import type { buttonVariants } from './button'
|
|
8
8
|
|
|
9
9
|
// The DVC must be rendered client-side since it accesses the DOM directly.
|
|
10
10
|
// There is no need for a loading UI since the dialog only opens
|
|
@@ -12,26 +12,27 @@ import type { ButtonSizes } from './button'
|
|
|
12
12
|
// https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading
|
|
13
13
|
const DynamicDVC = dynamic(() => (import('./dialog-video-controller')), {ssr: false})
|
|
14
14
|
|
|
15
|
-
const ActionButton: React.FC<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
const ActionButton: React.FC<
|
|
16
|
+
VariantProps<typeof buttonVariants> &
|
|
17
|
+
{
|
|
18
|
+
def: ButtonDef
|
|
19
|
+
className?: string
|
|
20
|
+
}
|
|
21
|
+
> = ({
|
|
20
22
|
def,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
className='',
|
|
24
|
+
...rest
|
|
23
25
|
}) => {
|
|
24
26
|
if (def.action.type === 'modal') {
|
|
25
27
|
const m = def.action.def as ButtonModalDef
|
|
26
28
|
const Modal = m.Comp
|
|
27
|
-
const sizeToSpread = size ? {size} : {}
|
|
28
29
|
return (
|
|
29
30
|
<DynamicDVC>
|
|
30
31
|
<Modal
|
|
31
32
|
title={m.title}
|
|
32
33
|
byline={m.byline}
|
|
33
34
|
buttonText={def.text}
|
|
34
|
-
buttonProps={{...def.props, ...
|
|
35
|
+
buttonProps={{...def.props, ...rest, className: cn((def.props?.className ?? ''), className)}}
|
|
35
36
|
action={m.action}
|
|
36
37
|
actionEnclosure={m.actionEnclosure}
|
|
37
38
|
{...m.props}
|
package/primitives/button.tsx
CHANGED
|
@@ -52,10 +52,6 @@ const buttonVariants = cva(
|
|
|
52
52
|
}
|
|
53
53
|
)
|
|
54
54
|
|
|
55
|
-
type ButtonVariants = keyof typeof variant
|
|
56
|
-
type ButtonSizes = keyof typeof size
|
|
57
|
-
type ButtonRoundedValue = keyof typeof rounded
|
|
58
|
-
|
|
59
55
|
interface ButtonProps extends
|
|
60
56
|
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
61
57
|
VariantProps<typeof buttonVariants>
|
|
@@ -81,8 +77,5 @@ Button.displayName = "Button"
|
|
|
81
77
|
export {
|
|
82
78
|
Button as default,
|
|
83
79
|
type ButtonProps,
|
|
84
|
-
type ButtonVariants,
|
|
85
|
-
type ButtonSizes,
|
|
86
|
-
type ButtonRoundedValue,
|
|
87
80
|
buttonVariants,
|
|
88
81
|
}
|
package/primitives/drawer.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { Drawer as DrawerPrimitive } from 'vaul'
|
|
|
6
6
|
import { cn } from '../util'
|
|
7
7
|
|
|
8
8
|
const Drawer = ({
|
|
9
|
-
shouldScaleBackground =
|
|
9
|
+
shouldScaleBackground = false,
|
|
10
10
|
...props
|
|
11
11
|
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
|
|
12
12
|
<DrawerPrimitive.Root
|
|
@@ -36,24 +36,35 @@ const DrawerContent = React.forwardRef<
|
|
|
36
36
|
React.ElementRef<typeof DrawerPrimitive.Content>,
|
|
37
37
|
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content> & {
|
|
38
38
|
overlayClx?: string
|
|
39
|
+
// Redundancy of 'modal' sent to Root, since we have no access to that.
|
|
40
|
+
// Hack that avoids forking their code.
|
|
41
|
+
modal?: boolean
|
|
39
42
|
}
|
|
40
|
-
>(({ className, children, overlayClx='', ...props }, ref) =>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
className
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
>(({ className, children, overlayClx='', modal=true, ...props }, ref) => {
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<DrawerPortal>
|
|
47
|
+
{/* If no or same z index, overlay should precede content */}
|
|
48
|
+
<DrawerOverlay className={cn('z-below-modal', overlayClx)}/>
|
|
49
|
+
<DrawerPrimitive.Content
|
|
50
|
+
ref={ref}
|
|
51
|
+
className={cn('fixed left-0 right-0 bottom-0 z-modal',
|
|
52
|
+
'mt-24 flex flex-col rounded-t-[10px] pt-6 border bg-background',
|
|
53
|
+
// 'h-[80%]'
|
|
54
|
+
className
|
|
55
|
+
)}
|
|
56
|
+
// A bug / omission in Vaul
|
|
57
|
+
onFocusOutside={(e) => { if (!modal) { e.preventDefault(); return } }}
|
|
58
|
+
onEscapeKeyDown={(e) => { if (!modal) { e.preventDefault(); return } }}
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
<div className='absolute left-0 right-0 mx-auto top-2 h-2 w-[100px] rounded-full bg-level-3 shrink-0' />
|
|
62
|
+
{children}
|
|
63
|
+
</DrawerPrimitive.Content>
|
|
64
|
+
</DrawerPortal>
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
|
|
57
68
|
DrawerContent.displayName = 'DrawerContent'
|
|
58
69
|
|
|
59
70
|
const DrawerHeader = ({
|
|
@@ -105,7 +116,10 @@ const DrawerDescription = React.forwardRef<
|
|
|
105
116
|
))
|
|
106
117
|
DrawerDescription.displayName = DrawerPrimitive.Description.displayName
|
|
107
118
|
|
|
119
|
+
type DrawerProps = React.ComponentProps<typeof DrawerPrimitive.Root>
|
|
120
|
+
|
|
108
121
|
export {
|
|
122
|
+
type DrawerProps,
|
|
109
123
|
Drawer,
|
|
110
124
|
DrawerPortal,
|
|
111
125
|
DrawerOverlay,
|
package/primitives/index.ts
CHANGED
|
@@ -24,8 +24,6 @@ export {
|
|
|
24
24
|
export {
|
|
25
25
|
default as Button,
|
|
26
26
|
type ButtonProps,
|
|
27
|
-
type ButtonVariants,
|
|
28
|
-
type ButtonSizes,
|
|
29
27
|
buttonVariants,
|
|
30
28
|
} from './button'
|
|
31
29
|
|
|
@@ -61,6 +59,7 @@ export {
|
|
|
61
59
|
} from './command'
|
|
62
60
|
|
|
63
61
|
export {
|
|
62
|
+
type DrawerProps,
|
|
64
63
|
Drawer,
|
|
65
64
|
DrawerPortal,
|
|
66
65
|
DrawerOverlay,
|
|
@@ -2,24 +2,26 @@ import React, { type PropsWithChildren } from 'react'
|
|
|
2
2
|
import Link from 'next/link'
|
|
3
3
|
|
|
4
4
|
import type { LinkDef, Icon } from '../types'
|
|
5
|
-
import { buttonVariants
|
|
6
|
-
import { cn } from '../util'
|
|
5
|
+
import { buttonVariants } from './button'
|
|
6
|
+
import { cn, type VariantProps } from '../util'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* If this is rendered directly (and not auto generated in a Block)
|
|
10
10
|
* and it has any children, title, icon, and iconAfter
|
|
11
11
|
* are ignore.
|
|
12
12
|
*/
|
|
13
|
-
const LinkElement: React.FC<
|
|
13
|
+
const LinkElement: React.FC<
|
|
14
|
+
PropsWithChildren &
|
|
15
|
+
VariantProps<typeof buttonVariants> &
|
|
16
|
+
{
|
|
14
17
|
def: LinkDef,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/** To trigger other events in addition to the
|
|
20
|
-
* link action itself. (eg, to also close a drawer menu)
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Use to trigger other events in addition to the
|
|
21
|
+
* link action itself. For example, to also close a drawer menu.
|
|
21
22
|
*/
|
|
22
23
|
onClick?: () => void
|
|
24
|
+
|
|
23
25
|
/** overrides def (eg, for title area)*/
|
|
24
26
|
icon?: Icon
|
|
25
27
|
/** overrides def */
|
|
@@ -28,9 +30,10 @@ const LinkElement: React.FC<PropsWithChildren & {
|
|
|
28
30
|
}> = ({
|
|
29
31
|
def,
|
|
30
32
|
// DO NOT provide a default to any of the props that also appear in def!
|
|
31
|
-
size,
|
|
32
33
|
onClick,
|
|
34
|
+
size,
|
|
33
35
|
variant,
|
|
36
|
+
rounded,
|
|
34
37
|
icon,
|
|
35
38
|
iconAfter,
|
|
36
39
|
className = '',
|
|
@@ -42,6 +45,7 @@ const LinkElement: React.FC<PropsWithChildren & {
|
|
|
42
45
|
newTab,
|
|
43
46
|
variant: defVariant,
|
|
44
47
|
size: defSize,
|
|
48
|
+
rounded: defRounded,
|
|
45
49
|
title
|
|
46
50
|
} = def
|
|
47
51
|
|
|
@@ -88,7 +92,8 @@ const LinkElement: React.FC<PropsWithChildren & {
|
|
|
88
92
|
size: (!defVariant || defVariant.includes('link') || variant?.includes('link')) ?
|
|
89
93
|
'link'
|
|
90
94
|
:
|
|
91
|
-
(size ? size : defSize)
|
|
95
|
+
(size ? size : defSize),
|
|
96
|
+
rounded: rounded ? rounded : (defRounded ? defRounded : 'md'),
|
|
92
97
|
}),
|
|
93
98
|
// This is a "label only" LinkDef. cf: footer"
|
|
94
99
|
((href.length > 0 || onClick) ? '' : 'pointer-events-none'),
|
|
@@ -107,11 +107,6 @@ export default {
|
|
|
107
107
|
}),
|
|
108
108
|
borderOpacity: ({ theme }) => theme('opacity'),
|
|
109
109
|
borderRadius: {
|
|
110
|
-
/* shadcn's:
|
|
111
|
-
lg: `var(--radius)`,
|
|
112
|
-
md: `calc(var(--radius) - 2px)`,
|
|
113
|
-
sm: "calc(var(--radius) - 4px)",
|
|
114
|
-
*/
|
|
115
110
|
none: '0px',
|
|
116
111
|
sm: '0.25rem',
|
|
117
112
|
DEFAULT: '0.5rem',
|
package/types/image-def.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ButtonRoundedValue } from '../primitives/button'
|
|
2
1
|
import type Dimensions from './dimensions'
|
|
3
2
|
|
|
4
3
|
/**
|
|
@@ -25,7 +24,7 @@ interface ImageDef {
|
|
|
25
24
|
*/
|
|
26
25
|
dim: Dimensions
|
|
27
26
|
|
|
28
|
-
rounded?:
|
|
27
|
+
rounded?: string // any key from tailwind.config.borderRadius
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
export {
|
package/types/link-def.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VariantProps } from 'class-variance-authority'
|
|
2
|
+
import type { buttonVariants } from '../primitives/button'
|
|
2
3
|
import type Icon from './icon'
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -6,7 +7,7 @@ import type Icon from './icon'
|
|
|
6
7
|
*
|
|
7
8
|
*
|
|
8
9
|
*/
|
|
9
|
-
interface LinkDef {
|
|
10
|
+
interface LinkDef extends VariantProps<typeof buttonVariants> {
|
|
10
11
|
/**
|
|
11
12
|
* If the LinkElement is rendered directly and has children,
|
|
12
13
|
* the title, icon, iconAfter fields in the supplied LinkDef
|
|
@@ -49,9 +50,6 @@ interface LinkDef {
|
|
|
49
50
|
* rendered as a disabled link, shows default cursor, and eats pointer events.
|
|
50
51
|
*/
|
|
51
52
|
disabled?: boolean
|
|
52
|
-
|
|
53
|
-
variant?: ButtonVariants
|
|
54
|
-
size?: ButtonSizes
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
export {
|
package/util/index.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { compiler as mdCompiler } from 'markdown-to-jsx'
|
|
|
2
2
|
|
|
3
3
|
import { clsx, type ClassValue } from 'clsx'
|
|
4
4
|
import { twMerge } from 'tailwind-merge'
|
|
5
|
+
export { cva, type VariantProps } from 'class-variance-authority'
|
|
6
|
+
|
|
5
7
|
import type { Dimensions } from '../types'
|
|
6
8
|
|
|
7
9
|
// @ts-ignore
|
|
@@ -71,4 +73,5 @@ export const capitalize = (str: string): string => (
|
|
|
71
73
|
str.charAt(0).toUpperCase() + str.slice(1)
|
|
72
74
|
)
|
|
73
75
|
|
|
74
|
-
export { default as spreadToTransform } from './spread-to-transform'
|
|
76
|
+
export { default as spreadToTransform } from './spread-to-transform'
|
|
77
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class TwoWayReadonlyMap<T, K> {
|
|
2
|
+
map: Map<T, K>;
|
|
3
|
+
reverseMap: Map<K, T>;
|
|
4
|
+
constructor(map: Map<T, K>) {
|
|
5
|
+
this.map = map;
|
|
6
|
+
this.reverseMap = new Map<K, T>();
|
|
7
|
+
map.forEach((value, key) => {
|
|
8
|
+
this.reverseMap.set(value, key);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
get(key: T) {
|
|
12
|
+
return this.map.get(key);
|
|
13
|
+
}
|
|
14
|
+
revGet(key: K) {
|
|
15
|
+
return this.reverseMap.get(key);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default TwoWayReadonlyMap
|