Skip to canvas
Proton Design System
/
Introduction
Changelog
Colors
Icons
Layers Management
Responsive
Sass Css Variables
Typography
Alert
Autocomplete
Badge
ButtonGroup
Checkbox
Collapsible
Copy
CountrySelect
DateInput
Details
DropdownSkip to canvas
Dropzone
EllipsisLoader
Errors
Icon
InputButton
InputField
InputFieldStacked
LabelStack
Logo
Meter
MiddleEllipsis
Modal
Notification
Price
Progress
Promotion Button
QuickSettings
Radio
Scale
Select
Spotlight
Table
Tabs
Toggle
TopBanner
TotpInput
VideoInstructions
Avatar
Banner
Button
Card
CircleLoader
DashboardCard
Donut
Href
InlineLinkButton
Input
Kbd
NotificationDot
Pill
ProtonLoader
Scroll
Slider
Stepper
UserAvatar
VerticalSteps
Vr
Border
Border Radius
Colors
Columns
Cursor
Divide
ExpandClickArea
Gap
HidingDisablingContent
InteractiveFocusHelper
Lists
Margin
Opacity
OpacityOnHover
Padding
Position
Print
Ratio Container
Responsive
Scroll
Shadow
Sizing
Transforms
Typography
  1. Recently opened
  2. Dropdowncomponents
  3. Back to componentsESC
  4. Clear history
Skip to sidebar
1import { useState } from 'react'; 2 3import { Button } from '@proton/atoms'; 4import type { DropdownProps } from '@proton/components'; 5import { 6 Collapsible, 7 CollapsibleContent, 8 CollapsibleHeader, 9 CollapsibleHeaderIconButton, 10 Dropdown, 11 DropdownButton, 12 DropdownMenu, 13 DropdownMenuButton, 14 DropdownSizeUnit, 15 Icon, 16 Option, 17 SelectTwo, 18 usePopperAnchor, 19} from '@proton/components'; 20 21import { getTitle } from '../../helpers/title'; 22import mdx from './Dropdown.mdx'; 23 24export default { 25 component: Dropdown, 26 title: getTitle(__filename, false), 27 parameters: { 28 docs: { 29 page: mdx, 30 }, 31 }, 32}; 33
34export const Basic = () => { 35 const { anchorRef, isOpen, toggle, close } = usePopperAnchor<HTMLButtonElement>(); 36 37 return ( 38 <> 39 <DropdownButton ref={anchorRef} isOpen={isOpen} onClick={toggle} hasCaret> 40 Click me 41 </DropdownButton> 42 <Dropdown isOpen={isOpen} anchorRef={anchorRef} onClose={close}> 43 <DropdownMenu> 44 {['Foo', 'Bar'].map((i) => { 45 return ( 46 <DropdownMenuButton className="text-left" key={i}> 47 {i} 48 </DropdownMenuButton> 49 ); 50 })} 51 </DropdownMenu> 52 <div className="p-4"> 53 <Button className="w-full" color="norm"> 54 Action 55 </Button> 56 </div> 57 </Dropdown> 58 </> 59 ); 60};
61 62export const Size = () => { 63 const [size, setSize] = useState<NonNullable<DropdownProps['size']>>({ 64 width: DropdownSizeUnit.Static, 65 height: DropdownSizeUnit.Dynamic, 66 maxHeight: '50em', 67 maxWidth: '20em', 68 }); 69 const { anchorRef, isOpen, toggle, close } = usePopperAnchor<HTMLButtonElement>(); 70 71 const Editor = ({ 72 sizeKey, 73 options, 74 }: Readonly<{ 75 sizeKey: keyof typeof size; 76 options: { title: string; value: DropdownSizeUnit }[]; 77 }>) => { 78 const value = size?.[sizeKey]; 79 const exists = options.find((option) => option.value === (value as any)); 80 return ( 81 <SelectTwo 82 value={exists ? value : 'custom'} 83 onChange={(change) => { 84 setSize((size) => ({ 85 ...size, 86 [sizeKey]: change.value === 'custom' ? '10em' : change.value, 87 })); 88 }} 89 > 90 {[...options, { title: `custom${!exists ? ` (${value})` : ''}`, value: 'custom' }].map((option) => { 91 return <Option key={option.value} title={option.title} value={option.value} />; 92 })} 93 </SelectTwo> 94 ); 95 }; 96 97 const getOption = (unit: DropdownSizeUnit) => { 98 return { title: `${unit}`, value: unit }; 99 }; 100 101 return ( 102 <> 103 <div> 104 {[ 105 { 106 sizeKey: 'width' as const, 107 options: [DropdownSizeUnit.Static, DropdownSizeUnit.Dynamic, DropdownSizeUnit.Anchor], 108 }, 109 { 110 sizeKey: 'height' as const, 111 options: [DropdownSizeUnit.Static, DropdownSizeUnit.Dynamic], 112 }, 113 { 114 sizeKey: 'maxWidth' as const, 115 options: [DropdownSizeUnit.Viewport], 116 }, 117 { 118 sizeKey: 'maxHeight' as const, 119 options: [DropdownSizeUnit.Viewport], 120 }, 121 ].map((row) => { 122 return ( 123 <div className="flex items-center"> 124 <pre className="w-custom" style={{ '--w-custom': '20em' }}> 125 {row.sizeKey}: 126 </pre> 127 <div className="flex-auto"> 128 <Editor sizeKey={row.sizeKey} options={row.options.map(getOption)} /> 129 </div> 130 </div> 131 ); 132 })} 133 </div> 134 <DropdownButton ref={anchorRef} isOpen={isOpen} onClick={toggle} hasCaret> 135 Click me to open 136 </DropdownButton> 137 <Dropdown 138 isOpen={isOpen} 139 anchorRef={anchorRef} 140 onClose={close} 141 size={size} 142 autoClose={false} 143 autoCloseOutside={false} 144 > 145 <Collapsible className="p-4"> 146 <CollapsibleHeader 147 suffix={ 148 <CollapsibleHeaderIconButton> 149 <Icon name="chevron-down" /> 150 </CollapsibleHeaderIconButton> 151 } 152 > 153 Collapsible header 154 </CollapsibleHeader> 155 <CollapsibleContent> 156 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut 157 labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco 158 laboris nisi ut aliquip ex ea commodo consequat. 159 </CollapsibleContent> 160 </Collapsible> 161 </Dropdown> 162 </> 163 ); 164};