@hanzo/ui 4.1.0 → 4.1.2
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/package.json +12 -12
- package/primitives/combobox.tsx +72 -57
- package/primitives/index-common.ts +2 -1
- package/primitives/list-adaptor.ts +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/ui",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.2",
|
|
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/",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"./util-client": "./util/index-client.ts"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@hanzo/react-drawer": "0.1.
|
|
47
|
+
"@hanzo/react-drawer": "^0.1.8",
|
|
48
48
|
"@next/third-parties": "^15.0.1",
|
|
49
49
|
"@radix-ui/react-accordion": "^1.1.2",
|
|
50
50
|
"@radix-ui/react-aspect-ratio": "^1.0.3",
|
|
@@ -92,13 +92,13 @@
|
|
|
92
92
|
"peerDependencies": {
|
|
93
93
|
"@hookform/resolvers": "^3.3.2",
|
|
94
94
|
"embla-carousel": "^8.1.6",
|
|
95
|
-
"lucide-react": "
|
|
95
|
+
"lucide-react": "catalog:",
|
|
96
96
|
"mobx": "^6.12.3",
|
|
97
|
-
"next": "
|
|
97
|
+
"next": "catalog:",
|
|
98
98
|
"next-themes": "^0.2.1",
|
|
99
|
-
"react": "
|
|
100
|
-
"react-dom": "
|
|
101
|
-
"react-hook-form": "
|
|
99
|
+
"react": "catalog:",
|
|
100
|
+
"react-dom": "catalog:",
|
|
101
|
+
"react-hook-form": "catalog:",
|
|
102
102
|
"validator": "^13.11.0",
|
|
103
103
|
"zod": "3.23.8"
|
|
104
104
|
},
|
|
@@ -109,10 +109,10 @@
|
|
|
109
109
|
"@types/gtag.js": "^0.0.19",
|
|
110
110
|
"@types/lodash.merge": "^4.6.9",
|
|
111
111
|
"@types/mdx": "^2.0.13",
|
|
112
|
-
"@types/node": "
|
|
113
|
-
"@types/react": "
|
|
114
|
-
"@types/react-dom": "
|
|
115
|
-
"tailwindcss": "
|
|
116
|
-
"typescript": "
|
|
112
|
+
"@types/node": "catalog:",
|
|
113
|
+
"@types/react": "catalog:",
|
|
114
|
+
"@types/react-dom": "catalog:",
|
|
115
|
+
"tailwindcss": "catalog:",
|
|
116
|
+
"typescript": "catalog:"
|
|
117
117
|
}
|
|
118
118
|
}
|
package/primitives/combobox.tsx
CHANGED
|
@@ -19,64 +19,68 @@ import {
|
|
|
19
19
|
PopoverTrigger,
|
|
20
20
|
} from './popover'
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
value: string,
|
|
24
|
-
label?: string,
|
|
25
|
-
imageUrl?: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const IMAGE_SIZE = 32
|
|
22
|
+
import type ListAdaptor from './list-adaptor'
|
|
29
23
|
|
|
30
24
|
const ElementImage: React.FC<{
|
|
31
25
|
url: string | undefined
|
|
32
26
|
alt?: string
|
|
33
27
|
w: number
|
|
34
28
|
h: number
|
|
29
|
+
className?: string
|
|
35
30
|
}> = ({
|
|
36
31
|
url,
|
|
37
32
|
alt,
|
|
38
33
|
w,
|
|
39
|
-
h
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
h,
|
|
35
|
+
className=''
|
|
36
|
+
}) => (url ? (
|
|
37
|
+
<img
|
|
38
|
+
src={url}
|
|
39
|
+
alt={alt ?? 'image'}
|
|
40
|
+
height={h}
|
|
41
|
+
width={w}
|
|
42
|
+
loading="eager"
|
|
43
|
+
className={className}
|
|
44
|
+
/>
|
|
45
|
+
) : null
|
|
49
46
|
)
|
|
47
|
+
// "rounded-sm object-contain"
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
49
|
+
const Combobox = <T,>(
|
|
50
|
+
{
|
|
51
|
+
elements,
|
|
52
|
+
adaptor,
|
|
53
|
+
buttonClx='',
|
|
54
|
+
popoverClx='',
|
|
55
|
+
imageClx='',
|
|
56
|
+
initial,
|
|
57
|
+
searchPlaceholder='Search...',
|
|
58
|
+
buttonPlaceholder='Select...',
|
|
59
|
+
noneFoundMessage='None found.',
|
|
60
|
+
elementSelected,
|
|
61
|
+
disabled=false,
|
|
62
|
+
imageSize=32
|
|
63
|
+
}: {
|
|
64
|
+
elements: T[]
|
|
65
|
+
adaptor: ListAdaptor<T>
|
|
66
|
+
elementSelected: (e: T) => void
|
|
67
|
+
buttonClx?: string
|
|
68
|
+
popoverClx?: string
|
|
69
|
+
imageClx?: string
|
|
70
|
+
buttonPlaceholder?: string
|
|
71
|
+
searchPlaceholder?: string
|
|
72
|
+
noneFoundMessage?: string
|
|
73
|
+
initial?: T,
|
|
74
|
+
disabled?: boolean
|
|
75
|
+
imageSize?: number
|
|
70
76
|
}) => {
|
|
71
77
|
|
|
72
78
|
const [open, setOpen] = useState<boolean>(false)
|
|
73
|
-
const [current, setCurrent] = useState<
|
|
79
|
+
const [current, setCurrent] = useState<T | null>(initial ?? null)
|
|
74
80
|
|
|
75
|
-
const handleSelect = (
|
|
76
|
-
|
|
77
|
-
// some issue w case... I know, right??
|
|
78
|
-
const found = elements.find((el: SelectElement) => (el.value.toUpperCase() === selectedValue.toUpperCase()) )
|
|
81
|
+
const handleSelect = (selString: string) => {
|
|
79
82
|
|
|
83
|
+
const found = elements.find((el: T) => (adaptor.valueEquals(el, selString)))
|
|
80
84
|
if (found) {
|
|
81
85
|
setCurrent(found)
|
|
82
86
|
elementSelected(found)
|
|
@@ -84,9 +88,17 @@ const Combobox: React.FC<{
|
|
|
84
88
|
setOpen(false)
|
|
85
89
|
}
|
|
86
90
|
|
|
87
|
-
const isCurrent = (el:
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
const isCurrent = (el: T): boolean => (!!current && (adaptor.equals(el, current)))
|
|
92
|
+
|
|
93
|
+
let currentValue: string | undefined
|
|
94
|
+
let currentLabel: string | undefined
|
|
95
|
+
let currentImageUrl: string | undefined
|
|
96
|
+
|
|
97
|
+
if (current) {
|
|
98
|
+
currentValue = adaptor.getValue(current)
|
|
99
|
+
currentLabel = adaptor.getLabel ? adaptor.getLabel(current) : undefined
|
|
100
|
+
currentImageUrl = adaptor.getImageUrl ? adaptor.getImageUrl(current) : undefined
|
|
101
|
+
}
|
|
90
102
|
|
|
91
103
|
return (
|
|
92
104
|
<Popover open={open} onOpenChange={setOpen}>
|
|
@@ -100,9 +112,9 @@ const Combobox: React.FC<{
|
|
|
100
112
|
>
|
|
101
113
|
<div className='flex justify-start items-center gap-2'>
|
|
102
114
|
{current && (
|
|
103
|
-
<ElementImage url={
|
|
115
|
+
<ElementImage url={currentImageUrl} w={imageSize} h={imageSize} className={imageClx} alt={currentValue + ' image'}/>
|
|
104
116
|
)}
|
|
105
|
-
<span>{ current ? (
|
|
117
|
+
<span>{ current ? (currentLabel ?? currentValue) : buttonPlaceholder }</span>
|
|
106
118
|
</div>
|
|
107
119
|
<ChevronDown className={open ? '' : 'opacity-50'} />
|
|
108
120
|
</Button>
|
|
@@ -111,21 +123,27 @@ const Combobox: React.FC<{
|
|
|
111
123
|
<Command>
|
|
112
124
|
<CommandInput placeholder={searchPlaceholder} />
|
|
113
125
|
<CommandList>
|
|
114
|
-
<CommandEmpty>
|
|
126
|
+
<CommandEmpty>{noneFoundMessage}</CommandEmpty>
|
|
115
127
|
<CommandGroup>
|
|
116
|
-
{elements.map((
|
|
128
|
+
{elements.map((el) => (
|
|
117
129
|
<CommandItem
|
|
118
|
-
key={
|
|
119
|
-
value={
|
|
130
|
+
key={adaptor.getValue(el)}
|
|
131
|
+
value={adaptor.getValue(el)}
|
|
120
132
|
onSelect={handleSelect}
|
|
121
133
|
className='flex justify-between'
|
|
122
134
|
>
|
|
123
135
|
<div className='flex justify-start items-center gap-2'>
|
|
124
|
-
<ElementImage
|
|
125
|
-
|
|
136
|
+
<ElementImage
|
|
137
|
+
url={adaptor.getImageUrl ? adaptor.getImageUrl(el) : undefined}
|
|
138
|
+
w={imageSize}
|
|
139
|
+
h={imageSize}
|
|
140
|
+
className={imageClx}
|
|
141
|
+
alt={adaptor.getValue(el) + ' image'}
|
|
142
|
+
/>
|
|
143
|
+
<span>{ adaptor.getLabel ? adaptor.getLabel(el) : adaptor.getValue(el) }</span>
|
|
126
144
|
</div>
|
|
127
145
|
<div>
|
|
128
|
-
<Check className={cn('ml-auto', (isCurrent(
|
|
146
|
+
<Check className={cn('ml-auto', (isCurrent(el)) ? '' : 'invisible' )} />
|
|
129
147
|
</div>
|
|
130
148
|
</CommandItem>
|
|
131
149
|
))}
|
|
@@ -137,7 +155,4 @@ const Combobox: React.FC<{
|
|
|
137
155
|
)
|
|
138
156
|
}
|
|
139
157
|
|
|
140
|
-
export
|
|
141
|
-
type SelectElement,
|
|
142
|
-
Combobox as default
|
|
143
|
-
}
|
|
158
|
+
export default Combobox
|
|
@@ -198,10 +198,11 @@ export { default as Badge } from './badge'
|
|
|
198
198
|
export { default as BreakpointIndicator } from './breakpoint-indicator'
|
|
199
199
|
export { default as Calendar } from './calendar'
|
|
200
200
|
export { default as Checkbox } from './checkbox'
|
|
201
|
-
export { default as Combobox
|
|
201
|
+
export { default as Combobox } from './combobox'
|
|
202
202
|
export { default as DialogVideoController } from './dialog-video-controller'
|
|
203
203
|
export { default as Input } from './input'
|
|
204
204
|
export { default as Label } from './label'
|
|
205
|
+
export type { default as ListAdaptor } from './list-adaptor'
|
|
205
206
|
export { default as ListBox } from './list-box'
|
|
206
207
|
export { default as Progress } from './progress'
|
|
207
208
|
export { RadioGroup, RadioGroupItem } from './radio-group'
|