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
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
PaddingSkip to canvas
Position
Print
Ratio Container
Responsive
Scroll
Shadow
Sizing
Transforms
Typography
  1. Recently opened
  2. PaddingCss Utilities
  3. Back to componentsESC
  4. Clear history
Skip to sidebar
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};