1
+ import { IconDefinition } from '@fortawesome/free-solid-svg-icons'
2
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
1
3
import * as RadixDropdown from '@radix-ui/react-dropdown-menu'
2
4
import React from 'react'
3
5
import { twMerge } from 'tailwind-merge'
@@ -20,12 +22,11 @@ interface DropdownProps {
20
22
test ?: string
21
23
}
22
24
trigger : string | React . ReactNode
25
+ triggerIcon ?: IconDefinition
23
26
items ?: Item [ ]
24
27
activeItems ?: string [ ]
25
28
groups ?: Item [ ] [ ]
26
29
className ?: {
27
- triggerOverride ?: string
28
- viewportOverride ?: string
29
30
trigger ?: string
30
31
triggerDisabled ?: string
31
32
viewport ?: string
@@ -52,6 +53,7 @@ export interface DropdownWithGroupsProps extends DropdownProps {
52
53
* @param id - The id of the dropdown.
53
54
* @param data - The object of data attributes that can be used for testing (e.g. data-test or data-cy)
54
55
* @param trigger - The content of the trigger button or a custom trigger component to replace the default button.
56
+ * @param triggerIcon - The icon that is displayed next to the trigger content.
55
57
* @param items - The items that are displayed in the dropdown menu. This attribute should not be set, if groups are used.
56
58
* @param activeItems - List of labels that should be considered active. This attribute has a similar function as the "select" attribute on the item props and should not be used at the same time.
57
59
* @param groups - The groups of items that are displayed in the dropdown menu. This attribute should not be set, if items are used.
@@ -63,77 +65,13 @@ export function Dropdown({
63
65
id,
64
66
data,
65
67
trigger,
68
+ triggerIcon,
66
69
items,
67
70
activeItems,
68
71
groups,
69
72
className,
70
73
disabled = false ,
71
74
} : DropdownWithItemsProps | DropdownWithGroupsProps ) {
72
- const DropdownItem = ( {
73
- id,
74
- data,
75
- label,
76
- active = false ,
77
- onClick,
78
- shorting,
79
- selected,
80
- className,
81
- } : {
82
- id ?: string
83
- data ?: {
84
- cy ?: string
85
- test ?: string
86
- }
87
- label : string | React . ReactNode
88
- active ?: boolean
89
- onClick : ( ) => void
90
- shorting ?: string
91
- selected ?: boolean
92
- className ?: {
93
- override ?: string
94
- root ?: string
95
- active ?: string
96
- }
97
- } ) => {
98
- if ( typeof label === 'string' ) {
99
- return (
100
- < RadixDropdown . Item
101
- id = { id }
102
- data-cy = { data ?. cy }
103
- data-test = { data ?. test }
104
- className = { twMerge (
105
- className ?. override ,
106
- `flex flex-row rounded px-2 py-0.5 hover:cursor-pointer hover:bg-primary-60 sm:hover:!text-white` ,
107
- active && twMerge ( 'font-bold' , className ?. active ) ,
108
- className ?. root
109
- ) }
110
- onClick = { onClick }
111
- >
112
- < div
113
- className = { twMerge (
114
- 'flex-1' ,
115
- selected && twMerge ( 'font-bold' , className ?. active )
116
- ) }
117
- >
118
- { label }
119
- </ div >
120
- { shorting && < div className = "ml-6" > { shorting } </ div > }
121
- </ RadixDropdown . Item >
122
- )
123
- }
124
- return (
125
- < RadixDropdown . Item
126
- id = { id }
127
- data-cy = { data ?. cy }
128
- data-test = { data ?. test }
129
- onClick = { onClick }
130
- className = { twMerge ( 'rounded-md' , className ?. root ) }
131
- >
132
- { label }
133
- </ RadixDropdown . Item >
134
- )
135
- }
136
-
137
75
return (
138
76
< RadixDropdown . Root >
139
77
{ typeof trigger === 'string' ? (
@@ -142,15 +80,18 @@ export function Dropdown({
142
80
data-cy = { data ?. cy }
143
81
data-test = { data ?. test }
144
82
className = { twMerge (
145
- className ?. triggerOverride ,
146
- `rounded-md border border-solid border-uzh-grey-60 px -2 py-1 hover:bg-primary-20` ,
147
- disabled && 'cursor-not-allowed text-gray-500 hover:bg-white' ,
148
- className ?. trigger ,
149
- className ?. triggerDisabled
83
+ 'inline-flex h-7 items-center justify-between gap-3 rounded-md border' ,
84
+ 'bg-white py-1.5 pl-2 pr -2 shadow-sm hover:bg-primary-20 sm:hover:text-primary' ,
85
+ disabled &&
86
+ 'hover:bg-none, sm:hover:text-none cursor-not-allowed bg-uzh-grey-20 opacity-70 shadow-sm' ,
87
+ className ?. trigger
150
88
) }
151
89
disabled = { disabled }
152
90
>
153
- { trigger }
91
+ < div > { trigger } </ div >
92
+ { triggerIcon && (
93
+ < FontAwesomeIcon icon = { triggerIcon } size = "sm" className = "mb-0.5" />
94
+ ) }
154
95
</ RadixDropdown . Trigger >
155
96
) : (
156
97
< RadixDropdown . Trigger
@@ -159,7 +100,6 @@ export function Dropdown({
159
100
data-test = { data ?. test }
160
101
disabled = { disabled }
161
102
className = { twMerge (
162
- className ?. triggerOverride ,
163
103
disabled && 'cursor-not-allowed text-gray-500 hover:bg-white' ,
164
104
className ?. trigger
165
105
) }
@@ -170,17 +110,16 @@ export function Dropdown({
170
110
171
111
< RadixDropdown . Content
172
112
className = { twMerge (
173
- className ?. viewportOverride ,
174
- 'rounded-md bg-primary-20 p-1.5' ,
113
+ 'rounded-lg border border-solid p-1 shadow-md' ,
175
114
className ?. viewport
176
115
) }
177
116
>
178
117
< RadixDropdown . Arrow
179
- className = { twMerge ( 'fill-primary-80 opacity-25' , className ?. arrow ) }
118
+ className = { twMerge ( 'fill-gray-500 opacity-25' , className ?. arrow ) }
180
119
/>
181
120
182
121
{ items && (
183
- < div className = "border-b border-solid border-uzh-grey-100 pb-1 pt-1 first:pt-0 last:border-b-0 last:pb-0" >
122
+ < div className = "border-b border-solid border-uzh-grey-100 pb-1 first:pt-0 last:border-b-0 last:pb-0" >
184
123
{ items . map ( ( item , index ) => (
185
124
< DropdownItem
186
125
key = { index }
@@ -228,4 +167,71 @@ export function Dropdown({
228
167
)
229
168
}
230
169
170
+ const DropdownItem = ( {
171
+ id,
172
+ data,
173
+ label,
174
+ active = false ,
175
+ onClick,
176
+ shorting,
177
+ selected,
178
+ className,
179
+ } : {
180
+ id ?: string
181
+ data ?: {
182
+ cy ?: string
183
+ test ?: string
184
+ }
185
+ label : string | React . ReactNode
186
+ active ?: boolean
187
+ onClick : ( ) => void
188
+ shorting ?: string
189
+ selected ?: boolean
190
+ className ?: {
191
+ override ?: string
192
+ root ?: string
193
+ active ?: string
194
+ }
195
+ } ) => {
196
+ if ( typeof label === 'string' ) {
197
+ return (
198
+ < RadixDropdown . Item
199
+ id = { id }
200
+ data-cy = { data ?. cy }
201
+ data-test = { data ?. test }
202
+ className = { twMerge (
203
+ className ?. override ,
204
+ `flex flex-row rounded px-2 py-0.5 hover:cursor-pointer hover:bg-primary-20 sm:hover:text-primary` ,
205
+ active && twMerge ( 'font-bold' , className ?. active ) ,
206
+ className ?. root
207
+ ) }
208
+ onClick = { onClick }
209
+ >
210
+ < div
211
+ className = { twMerge (
212
+ 'flex-1' ,
213
+ selected && twMerge ( 'font-bold' , className ?. active )
214
+ ) }
215
+ >
216
+ { label }
217
+ </ div >
218
+
219
+ { shorting && < div className = "ml-6" > { shorting } </ div > }
220
+ </ RadixDropdown . Item >
221
+ )
222
+ }
223
+
224
+ return (
225
+ < RadixDropdown . Item
226
+ id = { id }
227
+ data-cy = { data ?. cy }
228
+ data-test = { data ?. test }
229
+ onClick = { onClick }
230
+ className = { twMerge ( 'rounded-md' , className ?. root ) }
231
+ >
232
+ { label }
233
+ </ RadixDropdown . Item >
234
+ )
235
+ }
236
+
231
237
export default Dropdown
0 commit comments