/* ------------------------------------------------------------------------------------------------- * Drawer Component Styles * Block: drawer * -----------------------------------------------------------------------------------------------*/ /** * Element: trigger - the element that opens the drawer */ .drawer__trigger { @apply inline-block cursor-(--cursor-interactive); /** * Transitions * CRITICAL: motion-reduce must be AFTER transition for correct override specificity */ transition: transform 250ms var(--ease-out-quart), background-color 150ms var(--ease-smooth), box-shadow 150ms var(--ease-out); @apply motion-reduce:transition-none; /* Focus state */ &:focus-visible:not(:focus), &[data-focus-visible="true"] { @apply status-focused; } /* Disabled state */ &:disabled, &[aria-disabled="true"] { @apply status-disabled; } /* Active/pressed state */ &:active, &[data-pressed="true"] { transform: scale(0.97); } } /** * Element: backdrop - the overlay behind the drawer */ .drawer__backdrop { @apply fixed inset-0 z-50; @apply h-(--visual-viewport-height) w-full; opacity: 1; transition: opacity 250ms cubic-bezier(0.32, 0.72, 0, 1); &[data-entering="true"] { opacity: 0; } &[data-exiting="true"] { opacity: 0; transition-duration: 200ms; transition-timing-function: cubic-bezier(0.32, 0.72, 0, 1); } &[data-exiting="true"], &[data-entering="true"] { will-change: opacity; } @media (prefers-reduced-motion: reduce) { transition: none; } } /** * Modifier: backdrop--transparent */ .drawer__backdrop--transparent { @apply bg-transparent; } /** * Modifier: backdrop--opaque */ .drawer__backdrop--opaque { @apply bg-backdrop; } /** * Modifier: backdrop--blur */ .drawer__backdrop--blur { @apply bg-backdrop backdrop-blur-md; } /** * Element: content - the positioning wrapper for the drawer panel */ .drawer__content { @apply pointer-events-none; @apply fixed inset-0 z-50 flex; @apply h-(--visual-viewport-height) w-full min-w-0; } /** * Modifier: content--bottom (default) * Slides up from the bottom edge */ .drawer__content--bottom { @apply items-end; } /** * Modifier: content--top * Slides down from the top edge */ .drawer__content--top { @apply items-start; } /** * Modifier: content--left * Slides in from the left edge */ .drawer__content--left { @apply justify-start; } /** * Modifier: content--right * Slides in from the right edge */ .drawer__content--right { @apply justify-end; } /** * Element: dialog - the drawer panel itself */ .drawer__dialog { @apply relative; @apply flex flex-col; @apply bg-overlay shadow-overlay outline-none; @apply p-6; @apply pointer-events-auto; --drawer-enter-duration: 250ms; --drawer-exit-duration: 200ms; --drawer-enter-ease: cubic-bezier(0.32, 0.72, 0, 1); --drawer-exit-ease: cubic-bezier(0.32, 0.72, 0, 1); will-change: translate; transition: translate var(--drawer-enter-duration) var(--drawer-enter-ease); @media (prefers-reduced-motion: reduce) { transition: none; } /* Bottom/top placement: full width, auto height */ &[data-placement="bottom"] { @apply w-full; @apply max-h-[85vh]; border-top-left-radius: min(32px, var(--radius-2xl)); border-top-right-radius: min(32px, var(--radius-2xl)); } &[data-placement="top"] { @apply w-full; @apply max-h-[85vh]; border-bottom-left-radius: min(32px, var(--radius-2xl)); border-bottom-right-radius: min(32px, var(--radius-2xl)); } /* Left/right placement: auto width, full height */ &[data-placement="left"] { @apply h-full rounded-none; @apply w-80 max-w-[85vw] sm:w-96; } &[data-placement="right"] { @apply h-full rounded-none; @apply w-80 max-w-[85vw] sm:w-96; } } [data-exiting="true"] .drawer__dialog { transition-duration: var(--drawer-exit-duration); transition-timing-function: var(--drawer-exit-ease); } .drawer__content--left .drawer__dialog, .drawer__content--right .drawer__dialog, .drawer__content--top .drawer__dialog, .drawer__content--bottom .drawer__dialog { translate: 0 0; } .drawer__content--left[data-entering="true"] .drawer__dialog, .drawer__content--left[data-exiting="true"] .drawer__dialog { translate: -100% 0; } .drawer__content--right[data-entering="true"] .drawer__dialog, .drawer__content--right[data-exiting="true"] .drawer__dialog { translate: 100% 0; } .drawer__content--top[data-entering="true"] .drawer__dialog, .drawer__content--top[data-exiting="true"] .drawer__dialog { translate: 0 -100%; } .drawer__content--bottom[data-entering="true"] .drawer__dialog, .drawer__content--bottom[data-exiting="true"] .drawer__dialog { translate: 0 100%; } .drawer__dialog--top { @apply pb-2; .drawer__handle { @apply pb-0; } } /** * Element: header - the top section with the title */ .drawer__header { @apply flex flex-col gap-3; @apply mb-0; } /** * Element: heading - the main title text */ .drawer__heading { @apply align-middle; @apply text-base font-medium text-foreground; } /** * Element: body - the main content area * touch-action: pan-y allows vertical scrolling while the dialog captures drag gestures */ .drawer__body { @apply min-h-0 flex-1 scrollbar; @apply text-sm leading-[1.43] text-muted; @apply -m-[3px] my-0 p-[3px]; @apply overflow-y-auto overscroll-contain; -webkit-overflow-scrolling: touch; } /** * Element: footer - the bottom action section */ .drawer__footer { @apply flex flex-row items-center justify-end gap-2; @apply mt-0; } /** * Element: handle - visual drag handle indicator */ .drawer__handle { @apply flex items-center justify-center; @apply pb-2; /* The handle bar */ & > [data-slot="drawer-handle-bar"] { @apply h-1 w-9 rounded-xs; @apply bg-separator; } } /** * Element: close-trigger - the close button */ .drawer__close-trigger { @apply absolute top-4 right-4; } /** * Elements Spacing */ .drawer__header + .drawer__body { @apply mt-2; } .drawer__header + .drawer__footer { @apply mt-5; } .drawer__body + .drawer__footer { @apply mt-5; } .drawer__handle + .drawer__header { @apply mt-0; } .drawer__handle + .drawer__body { @apply mt-0; }