@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.
@@ -1,15 +1,15 @@
1
1
  import React from 'react'
2
2
 
3
3
  import type { LinkDef, ButtonDef} from '../../types'
4
- import { type ButtonSizes, ActionButton, LinkElement } from '../../primitives'
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?: ButtonSizes,
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.6.4",
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
- "build": "tsc",
35
- "tc": "tsc",
36
- "clean": "rm -rf dist && rm -rf node_modules"
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.1",
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.3.2",
72
- "postcss-selector-parser": "^6.0.13",
73
- "react-day-picker": "^8.7.1",
74
- "react-intersection-observer": "^9.7.0",
75
- "sonner": "^1.2.3",
76
- "tailwind-merge": "^2.2.0",
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.1",
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.47.0",
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.9",
100
- "@types/react": "^18.2.64",
101
- "@types/react-dom": "^18.2.18",
102
- "embla-carousel": "^8.0.1",
103
- "tailwindcss": "^3.4.1",
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 { ButtonSizes } from './button'
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
- def: ButtonDef
17
- size?: ButtonSizes
18
- className?: string
19
- }> = ({
15
+ const ActionButton: React.FC<
16
+ VariantProps<typeof buttonVariants> &
17
+ {
18
+ def: ButtonDef
19
+ className?: string
20
+ }
21
+ > = ({
20
22
  def,
21
- size, // no default. overrides!
22
- className=''
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, ...sizeToSpread, className: cn((def.props?.className ?? ''), className)}}
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}
@@ -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
  }
@@ -6,7 +6,7 @@ import { Drawer as DrawerPrimitive } from 'vaul'
6
6
  import { cn } from '../util'
7
7
 
8
8
  const Drawer = ({
9
- shouldScaleBackground = true,
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
- <DrawerPortal>
42
- {/* If no or same z index, overlay should precede content */}
43
- <DrawerOverlay className={cn('z-below-modal', overlayClx)}/>
44
- <DrawerPrimitive.Content
45
- ref={ref}
46
- className={cn('fixed left-0 right-0 bottom-0 z-modal',
47
- 'mt-24 flex flex-col h-[80%] rounded-t-[10px] pt-6 border bg-background',
48
- className
49
- )}
50
- {...props}
51
- >
52
- <div className='absolute left-0 right-0 mx-auto top-2 h-2 w-[100px] rounded-full bg-level-3 shrink-0' />
53
- {children}
54
- </DrawerPrimitive.Content>
55
- </DrawerPortal>
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,
@@ -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, type ButtonSizes, type ButtonVariants } from './button'
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<PropsWithChildren & {
13
+ const LinkElement: React.FC<
14
+ PropsWithChildren &
15
+ VariantProps<typeof buttonVariants> &
16
+ {
14
17
  def: LinkDef,
15
- /** overrides def */
16
- variant? : ButtonVariants
17
- /** overrides def */
18
- size?: ButtonSizes
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',
@@ -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?: ButtonRoundedValue
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 { ButtonVariants, ButtonSizes } from '../primitives/button'
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