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
Dropdown
DropzoneSkip to canvas
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. Dropzonecomponents
  3. Back to componentsESC
  4. Clear history
Skip to sidebar
1import type { SetStateAction } from 'react'; 2import { useState } from 'react'; 3 4import { Checkbox, Dropzone, InputFieldTwo, RadioGroup } from '@proton/components'; 5import type { DropzoneShape, DropzoneSize } from '@proton/components/components/dropzone/Dropzone'; 6 7import { getTitle } from '../../helpers/title'; 8import mdx from './Dropzone.mdx'; 9 10export default { 11 component: Dropzone, 12 title: getTitle(__filename, false), 13 parameters: { 14 docs: { 15 page: mdx, 16 }, 17 }, 18}; 19 20const sizes: DropzoneSize[] = ['small', 'medium', 'large']; 21const shapes: DropzoneShape[] = ['norm', 'transparent', 'flashy', 'invisible']; 22const toggles = ['showDragOverState', 'border', 'rounded', 'disabled'] as const; 23 24// Hook only used in the demo 25const useAddFiles = () => { 26 const [uploadedFiles, setUploadedFiles] = useState<string[]>([]); 27 28 const handleAddFile = (files: File[]) => { 29 const filenames = files.map((file) => file.name); 30 setUploadedFiles([...uploadedFiles, ...filenames]); 31 }; 32 33 return { uploadedFiles, setUploadedFiles, handleAddFile }; 34}; 35
36export const Custom = () => { 37 const [content, setContent] = useState(''); 38 const [contentTitle, setContentTitle] = useState(''); 39 const [contentSubtext, setContentSubtext] = useState(''); 40 41 const [isCustomContent, setIsCustomContent] = useState(false); 42 43 const [selectedSize, setSelectedSize] = useState<DropzoneSize>('medium'); 44 const [selectedShape, setSelectedShape] = useState<DropzoneShape>('norm'); 45 const [selectedToggles, setSelectedToggles] = useState([false, true, true, false]); 46 const { uploadedFiles, handleAddFile } = useAddFiles(); 47 48 return ( 49 <div className="p-7"> 50 <div className="flex items-stretch"> 51 <div className="mr-7"> 52 <strong className="block mb-4">Size</strong> 53 <RadioGroup 54 name="selected-size" 55 onChange={(v) => setSelectedSize(v)} 56 value={selectedSize} 57 options={sizes.map((size) => ({ value: size, label: size }))} 58 /> 59 </div> 60 <div className="mr-7"> 61 <strong className="block mb-4">Shape</strong> 62 <RadioGroup 63 name="selected-shape" 64 onChange={(v) => setSelectedShape(v)} 65 value={selectedShape} 66 options={shapes.map((shape) => ({ value: shape, label: shape }))} 67 /> 68 </div> 69 <div className="mr-7"> 70 <strong className="block mb-4">Toggles</strong> 71 {toggles.map((prop, i) => { 72 return ( 73 <div className="mb-2"> 74 <Checkbox 75 checked={selectedToggles[i]} 76 onChange={({ target: { checked } }) => { 77 setSelectedToggles( 78 selectedToggles.map((oldValue, otherIndex) => 79 otherIndex === i ? checked : oldValue 80 ) 81 ); 82 }} 83 > 84 {prop} 85 </Checkbox> 86 </div> 87 ); 88 })} 89 </div> 90 <div className="mr-7"> 91 <strong className="block mb-4">Content</strong> 92 <Checkbox 93 checked={isCustomContent} 94 onChange={({ target: { checked } }) => { 95 setIsCustomContent(checked); 96 if (!checked) { 97 setContent(''); 98 } 99 }} 100 className="mb-2" 101 > 102 Custom content 103 </Checkbox> 104 {isCustomContent ? ( 105 <InputFieldTwo 106 name="content" 107 id="content" 108 label="Content" 109 value={content} 110 onChange={(e: { target: { value: SetStateAction<string> } }) => setContent(e.target.value)} 111 placeholder="Set a custom content" 112 /> 113 ) : ( 114 <> 115 {selectedSize === 'large' && ( 116 <InputFieldTwo 117 name="content-title" 118 id="content-title" 119 label="Content title" 120 value={contentTitle} 121 onChange={(e: { target: { value: SetStateAction<string> } }) => 122 setContentTitle(e.target.value) 123 } 124 placeholder="Set a custom content title" 125 /> 126 )} 127 <InputFieldTwo 128 name="content-subtext" 129 id="content-subtext" 130 label="Content subtext" 131 value={contentSubtext} 132 onChange={(e: { target: { value: SetStateAction<string> } }) => 133 setContentSubtext(e.target.value) 134 } 135 placeholder="Set a custom content" 136 /> 137 </> 138 )} 139 </div> 140 </div> 141 <div className="mt-4 flex items-center"> 142 <Dropzone 143 onDrop={handleAddFile} 144 size={selectedSize} 145 shape={selectedShape} 146 customContent={content} 147 contentTitle={contentTitle} 148 contentSubText={contentSubtext} 149 {...selectedToggles.reduce<{ [key: string]: boolean }>((acc, value, i) => { 150 acc[toggles[i]] = value; 151 return acc; 152 }, {})} 153 > 154 <div className="flex items-center w-full border p-4" style={{ minHeight: '300px' }}> 155 <div className="flex flex-column text-center h-full w-full"> 156 <span>Hover with a file to see the dropzone (or select showDragOverState toggle)</span> 157 <br /> 158 <span>This is the children content</span> 159 <span>You uploaded these files [{uploadedFiles.join(',')}]</span> 160 </div> 161 </div> 162 </Dropzone> 163 </div> 164 </div> 165 ); 166};
167export const Invisible = () => { 168 const { uploadedFiles, handleAddFile } = useAddFiles(); 169 170 return ( 171 <div className="p-7"> 172 <div className="mt-4 flex items-center"> 173 <Dropzone onDrop={handleAddFile} shape="invisible"> 174 <div className="flex items-center w-full border p-4" style={{ minHeight: '300px' }}> 175 <div className="flex flex-column text-center h-full w-full"> 176 <span>Hover with a file to see the dropzone (or select showDragOverState toggle)</span> 177 <br /> 178 <span>This is the children content</span> 179 <span>You uploaded these files [{uploadedFiles.join(',')}]</span> 180 </div> 181 </div> 182 </Dropzone> 183 </div> 184 </div> 185 ); 186};