1import { useState } from 'react'; 2 3import { 4 Checkbox, 5 Label, 6 Option, 7 SelectTwo, 8 Table, 9 TableBody, 10 TableCell, 11 TableHeader, 12 TableRow, 13} from '@proton/components'; 14 15import { getTitle } from '../../helpers/title'; 16import mdx from './Padding.mdx'; 17 18export default { 19 title: getTitle(__filename, false), 20 parameters: { 21 docs: { 22 page: mdx, 23 }, 24 }, 25}; 26 27const paddingSizes = [ 28 { 29 class: '0', 30 rem: '0', 31 px: '0', 32 }, 33 { 34 class: 'px', 35 rem: '0.0625rem', 36 px: '1', 37 }, 38 { 39 class: '0.5', 40 rem: '0.125rem', 41 px: '2px', 42 }, 43 { 44 class: '1', 45 rem: '0.25rem', 46 px: '4px', 47 }, 48 { 49 class: '2', 50 rem: '0.5rem', 51 px: '8px', 52 }, 53 { 54 class: '3', 55 rem: '0.75rem', 56 px: '12px', 57 }, 58 { 59 class: '4', 60 rem: '1rem', 61 px: '16px', 62 }, 63 { 64 class: '5', 65 rem: '1.25rem', 66 px: '20px', 67 }, 68 { 69 class: '6', 70 rem: '1.5rem', 71 px: '24px', 72 }, 73 { 74 class: '8', 75 rem: '2rem', 76 px: '32px', 77 }, 78 { 79 class: '10', 80 rem: '2.5rem', 81 px: '40px', 82 }, 83 { 84 class: '11', 85 rem: '2.75rem', 86 px: '44px', 87 }, 88 { 89 class: '12', 90 rem: '3rem', 91 px: '48px', 92 }, 93 { 94 class: '14', 95 rem: '3.5rem', 96 px: '56px', 97 }, 98]; 99 100export const PaddingsTable = () => { 101 return ( 102 <Table className="color-norm"> 103 <TableHeader> 104 <TableRow> 105 <TableCell type="header">Name</TableCell> 106 <TableCell type="header">REM value</TableCell> 107 <TableCell type="header">PX value</TableCell> 108 </TableRow> 109 </TableHeader> 110 <TableBody> 111 {paddingSizes.map((item) => ( 112 <TableRow key={item.class}> 113 <TableCell> 114 <code>p-{item.class}</code> 115 </TableCell> 116 <TableCell>{item.rem}</TableCell> 117 <TableCell>{item.px}</TableCell> 118 </TableRow> 119 ))} 120 </TableBody> 121 </Table> 122 ); 123}; 124 125const demoItemClasses = 'flex items-center justify-center bg-primary user-select'; 126 127export const Padding = () => { 128 return ( 129 <div className="border rounded w-full relative flex gap-2 flex-nowrap overflow-auto items-center justify-space-between"> 130 {paddingSizes.map((size) => ( 131 <div key={size.class} className="bg-primary shrink-0 rounded-sm overflow-hidden"> 132 <div className={`p-${size.class}`} style={{ backgroundColor: 'rgba(0,0,0,.2)' }}> 133 <div className={demoItemClasses} style={{ width: '3rem', height: '2rem' }}> 134 <span className="text-2xs">p-{size.class}</span> 135 </div> 136 </div> 137 </div> 138 ))} 139 </div> 140 ); 141}; 142 143export const PaddingTop = () => { 144 return ( 145 <div className="border rounded w-full relative flex gap-2 flex-nowrap overflow-auto items-start justify-space-between text-2xs"> 146 {paddingSizes.map((size) => ( 147 <div key={size.class} className="bg-primary shrink-0 rounded-sm overflow-hidden"> 148 <div className={`pt-${size.class}`} style={{ width: '3rem', backgroundColor: 'rgba(0,0,0,.2)' }}> 149 <div className={demoItemClasses} style={{ height: '2rem' }}> 150 pt-{size.class} 151 </div> 152 </div> 153 </div> 154 ))} 155 </div> 156 ); 157}; 158 159export const PaddingBottom = () => { 160 return ( 161 <div className="border rounded w-full relative flex gap-2 flex-nowrap overflow-auto items-end justify-space-between text-2xs"> 162 {paddingSizes.map((size) => ( 163 <div key={size.class} className="bg-primary shrink-0 rounded-sm overflow-hidden"> 164 <div className={`pb-${size.class}`} style={{ width: '3rem', backgroundColor: 'rgba(0,0,0,.2)' }}> 165 <div className={demoItemClasses} style={{ height: '2rem' }}> 166 pb-{size.class} 167 </div> 168 </div> 169 </div> 170 ))} 171 </div> 172 ); 173}; 174 175export const PaddingY = () => { 176 return ( 177 <div className="border rounded w-full relative flex gap-2 flex-nowrap overflow-auto items-center justify-space-between text-2xs"> 178 {paddingSizes.map((size) => ( 179 <div key={size.class} className="bg-primary shrink-0 rounded-sm overflow-hidden"> 180 <div className={`py-${size.class}`} style={{ width: '3rem', backgroundColor: 'rgba(0,0,0,.2)' }}> 181 <div className={demoItemClasses} style={{ height: '2rem' }}> 182 py-{size.class} 183 </div> 184 </div> 185 </div> 186 ))} 187 </div> 188 ); 189}; 190 191export const PaddingLeft = () => { 192 return ( 193 <div className="border rounded w-full relative flex flex-column flex-nowrap items-start gap-2 text-2xs"> 194 {paddingSizes.map((size) => ( 195 <div key={size.class} className="bg-primary grow-0 rounded-sm overflow-hidden"> 196 <div className={`pl-${size.class}`} style={{ height: '2rem', backgroundColor: 'rgba(0,0,0,.2)' }}> 197 <div className={demoItemClasses} style={{ width: '3rem', height: '2rem' }}> 198 pl-{size.class} 199 </div> 200 </div> 201 </div> 202 ))} 203 </div> 204 ); 205}; 206 207export const PaddingRight = () => { 208 return ( 209 <div className="border rounded w-full relative flex flex-column flex-nowrap items-end gap-2 text-2xs"> 210 {paddingSizes.map((size) => ( 211 <div key={size.class} className="bg-primary grow-0 rounded-sm overflow-hidden"> 212 <div className={`pr-${size.class}`} style={{ height: '2rem', backgroundColor: 'rgba(0,0,0,.2)' }}> 213 <div className={demoItemClasses} style={{ width: '3rem', height: '2rem' }}> 214 pr-{size.class} 215 </div> 216 </div> 217 </div> 218 ))} 219 </div> 220 ); 221}; 222
223export const PaddingX = () => { 224 return ( 225 <div className="border rounded w-full relative flex flex-column flex-nowrap items-center gap-2 text-2xs"> 226 {paddingSizes.map((size) => ( 227 <div key={size.class} className="bg-primary grow-0 rounded-sm overflow-hidden"> 228 <div className={`px-${size.class}`} style={{ height: '2rem', backgroundColor: 'rgba(0,0,0,.2)' }}> 229 <div className={demoItemClasses} style={{ width: '3rem', height: '2rem' }}> 230 px-{size.class} 231 </div> 232 </div> 233 </div> 234 ))} 235 </div> 236 ); 237};
238 239export const Responsive = () => { 240 return ( 241 <div className="border rounded overflow-hidden w-full relative flex text-2xs"> 242 <div className="bg-primary rounded-sm"> 243 <div 244 className={`${demoItemClasses} pl-4 sm:pl-8 md:pl-10 lg:pl-12 xl:pl-14`} 245 style={{ backgroundColor: 'rgba(0,0,0,.2)' }} 246 > 247 <div 248 className="flex items-center justify-center bg-primary" 249 style={{ height: '3rem', width: '3rem' }} 250 ></div> 251 </div> 252 </div> 253 </div> 254 ); 255}; 256 257Responsive.parameters = { 258 docs: { 259 iframeHeight: '100px', 260 inlineStories: false, 261 }, 262 layout: 'fullscreen', 263}; 264 265const paddings = [ 266 { 267 id: 'p', 268 checked: false, 269 value: '0', 270 }, 271 { 272 id: 'pt', 273 checked: true, 274 value: '4', 275 }, 276 { 277 id: 'pr', 278 checked: true, 279 value: '8', 280 }, 281 { 282 id: 'pb', 283 checked: true, 284 value: '4', 285 }, 286 { 287 id: 'pl', 288 checked: true, 289 value: '0-5', 290 }, 291 { 292 id: 'px', 293 checked: false, 294 value: '0', 295 }, 296 { 297 id: 'py', 298 checked: false, 299 value: '0', 300 }, 301]; 302 303export const Sandbox = () => { 304 const [selectedPadding, setSelectedPadding] = useState(paddings); 305 306 function handleCheckboxChange(id: string, checked: boolean) { 307 const updatedPaddings = selectedPadding.map((item) => { 308 if (id === item.id) { 309 return { ...item, checked: checked }; 310 } 311 return item; 312 }); 313 setSelectedPadding(updatedPaddings); 314 } 315 316 function handleSelectChange(id: string, value: string) { 317 const updatedPaddings = selectedPadding.map((item) => { 318 if (id === item.id) { 319 return { ...item, value: value }; 320 } 321 return item; 322 }); 323 setSelectedPadding(updatedPaddings); 324 } 325 326 function assembleClasses(items: any[]) { 327 const classes: string[] = []; 328 329 items.forEach((item) => { 330 if (item.checked) { 331 classes.push(`${item.id}-${item.value}`); 332 } 333 }); 334 335 return classes.join(' '); 336 } 337 338 return ( 339 <> 340 <div className="flex justify-space-between"> 341 <div className="w-1/4"> 342 {selectedPadding.map(({ id, checked, value }) => ( 343 <Label htmlFor={id} key={id} className="flex flex-nowrap items-center gap-4 mb-4"> 344 <Checkbox 345 id={id} 346 checked={checked} 347 onChange={({ target }) => { 348 handleCheckboxChange(id, target.checked); 349 }} 350 /> 351 352 <span className="text-semibold w-1/10">{id}</span> 353 354 <span className="w-1/10 flex shrink-0 justify-center"> 355 <span className="bg-primary rounded-sm shrink-0 grow-0"> 356 <span className={`${id}0-25 block rounded-sm bg-primary`}> 357 <span 358 className="flex items-center justify-center bg-norm opacity-65" 359 style={{ width: '1em', height: '1em' }} 360 ></span> 361 </span> 362 </span> 363 </span> 364 365 <SelectTwo value={value} onValue={(newValue) => handleSelectChange(id, newValue)}> 366 {paddingSizes.map((size) => ( 367 <Option key={size.class} title={size.class} value={size.class} /> 368 ))} 369 </SelectTwo> 370 </Label> 371 ))} 372 </div> 373 <div className="border rounded w-4/6 relative flex justify-center items-center p-14"> 374 <div className="bg-primary grow-0 rounded-sm overflow-hidden"> 375 <div 376 className={assembleClasses(selectedPadding)} 377 style={{ backgroundColor: 'rgba(0,0,0,.4)', transition: 'all .25s ease' }} 378 > 379 <div className={demoItemClasses} style={{ height: '2rem', width: '2rem' }}></div> 380 </div> 381 </div> 382 </div> 383 </div> 384 <strong>Classes:</strong>{' '} 385 <code className="inline-block user-select rounded-sm py-1 px-2 border bg-weak text-norm text-sm empty:hidden"> 386 {assembleClasses(selectedPadding)} 387 </code> 388 </> 389 ); 390};