Browse Source

refactor: standardize bottom sheet animations using CSS classes and consistent 200ms timing

master
mortezaei 20 hours ago
parent
commit
4496053d98
  1. 42
      src/app/globals.css
  2. 1
      src/app/questions-list/sections-request.tsx
  3. 12
      src/components/Componentes/call-result-sheet.tsx
  4. 11
      src/components/Componentes/currency-sheet.tsx
  5. 12
      src/components/Componentes/dismiss-reason-sheet.tsx
  6. 12
      src/components/Componentes/female-consent-sheet.tsx
  7. 12
      src/components/Componentes/female-outcome-sheet.tsx
  8. 12
      src/components/Componentes/help-modal.tsx
  9. 10
      src/components/Componentes/information-sheet.tsx
  10. 12
      src/components/Componentes/outcome-selection-sheet.tsx
  11. 10
      src/components/Componentes/question-birthplace.tsx
  12. 11
      src/components/Componentes/question-date-sheet.tsx
  13. 11
      src/components/Componentes/question-phone.tsx
  14. 11
      src/components/Componentes/question-sheet.tsx
  15. 14
      src/components/Componentes/report-actions-sheet.tsx
  16. 12
      src/components/Componentes/support-sheet.tsx

42
src/app/globals.css

@ -258,6 +258,48 @@ body.section-overlay-open .app-shell {
overflow-y: hidden;
}
/* ─── Flutter BottomSheet Exact Motion Match (Najm: 250ms in, 200ms out, easeOutCubic / easeIn) ─── */
@keyframes flutter-bottomsheet-enter {
0% {
transform: translate3d(0, 100%, 0);
}
100% {
transform: translate3d(0, 0, 0);
}
}
@keyframes flutter-scrim-enter {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.flutter-sheet-surface {
animation: flutter-bottomsheet-enter 250ms cubic-bezier(0, 0, 0.2, 1) forwards;
will-change: transform;
}
.flutter-sheet-surface-exit {
transform: translate3d(0, 100%, 0) !important;
transition: transform 200ms cubic-bezier(0.4, 0, 1, 1) !important;
will-change: transform;
}
.flutter-scrim {
background-color: rgba(0, 0, 0, 0.54);
animation: flutter-scrim-enter 250ms cubic-bezier(0, 0, 0.2, 1) forwards;
will-change: opacity;
}
.flutter-scrim-exit {
opacity: 0 !important;
transition: opacity 200ms cubic-bezier(0.4, 0, 1, 1) !important;
will-change: opacity;
}
/* ── Section Overlay Slide-in Panel (Exact Flutter Najm Matching: 350ms in, 200ms out, easeInOut) ── */
.section-overlay {
position: fixed;

1
src/app/questions-list/sections-request.tsx

@ -87,6 +87,7 @@ export default function SectionsRequest({
return (
<InformationSheet
icon={null}
showCloseButton={false}
title={({ close }) => (
<span className="flex w-full items-start justify-between gap-3 text-start">
<span className="text-[14px] leading-5 font-bold tracking-normal text-[#8B8B8B]">

12
src/components/Componentes/call-result-sheet.tsx

@ -4,7 +4,7 @@ import type { HTMLAttributes } from "react";
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
import { useI18n } from "@/translations/provider";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
export type CallResultSheetProps = Omit<
HTMLAttributes<HTMLDivElement>,
@ -89,10 +89,8 @@ export function CallResultSheet({
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms] animate-in fade-in",
isClosing
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -119,8 +117,8 @@ export function CallResultSheet({
<section
{...props}
className={[
"w-full sm:max-w-[375px] rounded-t-[34px] bg-[#F9F8F8] p-3.5 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"w-full sm:max-w-[375px] rounded-t-[22px] bg-white p-3.5 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
className,
]
.filter(Boolean)

11
src/components/Componentes/currency-sheet.tsx

@ -6,7 +6,7 @@ import { CURRENCIES, type CurrencyItem } from "@/data/currencies";
import { useI18n } from "@/translations/provider";
import { useSheetScrollLock } from "./use-sheet-scroll-lock";
const EXIT_ANIMATION_MS = 300;
const EXIT_ANIMATION_MS = 200;
export type CurrencySheetProps = {
isOpen: boolean;
@ -91,7 +91,10 @@ export function CurrencySheet({
return createPortal(
<div
className="fixed inset-0 z-50 flex items-end justify-center bg-black/40 backdrop-blur-[2px] transition-opacity duration-200"
className={[
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
].join(" ")}
role="dialog"
aria-label={sheetTitle}
onKeyDown={(e) => {
@ -104,8 +107,8 @@ export function CurrencySheet({
<section
ref={sheetRef}
className={[
"flex w-full flex-col overflow-hidden rounded-t-[24px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.16)] transition-transform duration-[300ms] ease-out sm:max-w-[420px] h-[82svh] min-h-[82svh] max-h-[82svh]",
isClosing ? "translate-y-full" : "translate-y-0",
"flex w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.16)] sm:max-w-[420px] h-[82svh] min-h-[82svh] max-h-[82svh]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
].join(" ")}
>
{/* Header */}

12
src/components/Componentes/dismiss-reason-sheet.tsx

@ -6,7 +6,7 @@ import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { useI18n } from "@/translations/provider";
import Button from "./button";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
export type DismissReasonSheetProps = Omit<
HTMLAttributes<HTMLDivElement>,
@ -104,10 +104,8 @@ export function DismissReasonSheet({
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms] animate-in fade-in",
isClosing
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -134,8 +132,8 @@ export function DismissReasonSheet({
<section
{...props}
className={[
"flex h-[80vh] w-full flex-col overflow-hidden rounded-t-[15px] bg-[#F9F8F8] p-3.5 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform sm:max-w-[375px] animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"flex h-[80vh] w-full flex-col overflow-hidden rounded-t-[22px] bg-white p-3.5 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] sm:max-w-[375px]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
className,
]
.filter(Boolean)

12
src/components/Componentes/female-consent-sheet.tsx

@ -6,7 +6,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { useI18n } from "@/translations/provider";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
export type FemaleConsentSheetProps = Omit<
HTMLAttributes<HTMLDivElement>,
@ -81,10 +81,8 @@ export function FemaleConsentSheet({
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms] animate-in fade-in",
isClosing
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -111,8 +109,8 @@ export function FemaleConsentSheet({
<section
{...props}
className={[
"w-full sm:max-w-[375px] rounded-t-[15px] bg-[#F9F8F8] py-5 px-4 text-left shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"w-full sm:max-w-[375px] rounded-t-[22px] bg-white py-5 px-4 text-left shadow-[0_20px_60px_rgba(15,23,42,0.08)]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
className,
]
.filter(Boolean)

12
src/components/Componentes/female-outcome-sheet.tsx

@ -5,7 +5,7 @@ import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { useI18n } from "@/translations/provider";
import SwipeButton from "./swipe-button";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
export type FemaleOutcomeSheetProps = {
closeOnOutside?: boolean;
@ -108,10 +108,8 @@ export function FemaleOutcomeSheet({
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms] animate-in fade-in",
isClosing
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -137,8 +135,8 @@ export function FemaleOutcomeSheet({
>
<section
className={[
"flex max-h-[85vh] w-full flex-col overflow-hidden rounded-t-[34px] bg-[#F9F8F8] p-4 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform sm:max-w-[375px] animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"flex max-h-[85vh] w-full flex-col overflow-hidden rounded-t-[22px] bg-white p-4 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] sm:max-w-[375px]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
]
.filter(Boolean)
.join(" ")}

12
src/components/Componentes/help-modal.tsx

@ -7,7 +7,7 @@ import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import Button from "./button";
import { useI18n } from "@/translations/provider";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
export type HelpModalProps = {
isOpen: boolean;
@ -84,10 +84,8 @@ export function HelpModal({
return createPortal(
<div
className={[
"fixed inset-0 z-[100] flex items-end justify-center transition-all duration-[220ms] animate-in fade-in",
isClosing
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-[100] flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
].join(" ")}
role="dialog"
aria-modal="true"
@ -108,8 +106,8 @@ export function HelpModal({
>
<section
className={[
"w-full sm:max-w-[375px] rounded-t-[15px] bg-[#F9F8F8] px-4 pb-5 pt-4 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"w-full sm:max-w-[375px] rounded-t-[22px] bg-white px-4 pb-5 pt-4 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
].join(" ")}
>
<div className="mx-auto flex flex-col items-center">

10
src/components/Componentes/information-sheet.tsx

@ -9,7 +9,7 @@ import { LoadingThreeDot } from "./loading-three-dot";
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { useI18n } from "@/translations/provider";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
type InformationSheetPresetIcon =
| "play"
@ -266,8 +266,8 @@ export function InformationSheet({
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center overflow-y-auto transition-all duration-[220ms] animate-in fade-in",
isClosing ? "bg-[#171717]/0 opacity-0" : "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center overflow-y-auto",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -295,8 +295,8 @@ export function InformationSheet({
<section
{...props}
className={[
"relative w-full sm:max-w-[375px] rounded-t-[22px] bg-[#F9F8F8] px-4 pt-4 pb-[max(24px,calc(24px+var(--safe-bottom)))] text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"relative w-full sm:max-w-[375px] rounded-t-[22px] bg-white px-4 pt-4 pb-[max(24px,calc(24px+var(--safe-bottom)))] text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
className,
]
.filter(Boolean)

12
src/components/Componentes/outcome-selection-sheet.tsx

@ -5,7 +5,7 @@ import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { useI18n } from "@/translations/provider";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
export type OutcomeSelectionSheetProps = Omit<
HTMLAttributes<HTMLDivElement>,
@ -83,10 +83,8 @@ export function OutcomeSelectionSheet({
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms] animate-in fade-in",
isClosing
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -113,8 +111,8 @@ export function OutcomeSelectionSheet({
<section
{...props}
className={[
"w-full sm:max-w-[375px] rounded-t-[34px] bg-[#F9F8F8] p-3.5 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"w-full sm:max-w-[375px] rounded-t-[22px] bg-white p-3.5 text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
className,
]
.filter(Boolean)

10
src/components/Componentes/question-birthplace.tsx

@ -25,7 +25,7 @@ import {
pickManualLocation,
} from "@/lib/webview-actions";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
type QuestionBirthplaceProps = {
question: QuestionField;
@ -678,8 +678,8 @@ export function QuestionBirthplace({
createPortal(
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms] animate-in fade-in",
isClosing ? "bg-black/0 opacity-0" : "bg-black/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
].join(" ")}
role="dialog"
aria-modal="true"
@ -696,8 +696,8 @@ export function QuestionBirthplace({
>
<section
className={[
"flex h-[82svh] min-h-[82svh] max-h-[82svh] w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] transition-transform duration-[220ms] ease-out will-change-transform sm:max-w-[375px] animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"flex h-[82svh] min-h-[82svh] max-h-[82svh] w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] sm:max-w-[375px]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
].join(" ")}
onClick={(e) => e.stopPropagation()}
>

11
src/components/Componentes/question-date-sheet.tsx

@ -14,7 +14,7 @@ import { useI18n } from "@/translations/provider";
import { Button } from "./button";
import { useSheetScrollLock } from "./use-sheet-scroll-lock";
const EXIT_ANIMATION_MS = 300;
const EXIT_ANIMATION_MS = 200;
const WHEEL_ITEM_HEIGHT = 48;
const WHEEL_EDGE_PADDING = 108;
const SCROLL_SETTLE_MS = 90;
@ -274,7 +274,10 @@ export function QuestionDateSheet({
return createPortal(
<div
className="fixed inset-0 z-50 flex items-end justify-center bg-transparent"
className={[
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
].join(" ")}
role="dialog"
aria-modal="true"
aria-label={question.title}
@ -287,8 +290,8 @@ export function QuestionDateSheet({
>
<section
className={[
"flex w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[calc(16px+env(safe-area-inset-bottom))] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] transition-transform duration-[300ms] ease-out sm:max-w-[375px] animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"flex w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[calc(16px+env(safe-area-inset-bottom))] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] sm:max-w-[375px]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
].join(" ")}
>
<div className="flex items-center justify-between border-b border-[#F2F4F7] px-5 pb-3 pt-2">

11
src/components/Componentes/question-phone.tsx

@ -15,7 +15,7 @@ import { useQuestionAnswers } from "./question-answer-storage";
import QuestionTitle from "./question-title";
import { useSheetScrollLock } from "./use-sheet-scroll-lock";
const EXIT_ANIMATION_MS = 300;
const EXIT_ANIMATION_MS = 200;
type QuestionPhoneProps = {
question: QuestionField;
@ -796,7 +796,10 @@ export function QuestionPhone({
{isOpen &&
createPortal(
<div
className="fixed inset-0 z-50 flex items-end justify-center bg-transparent"
className={[
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
].join(" ")}
role="dialog"
aria-label={selectCountryTitle}
onKeyDown={(event) => {
@ -808,8 +811,8 @@ export function QuestionPhone({
>
<section
className={[
"flex h-[82svh] min-h-[82svh] max-h-[82svh] w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] transition-transform duration-[300ms] ease-out sm:max-w-[375px] animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"flex h-[82svh] min-h-[82svh] max-h-[82svh] w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] sm:max-w-[375px]",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
].join(" ")}
>
{/* Header with Title and Close Button */}

11
src/components/Componentes/question-sheet.tsx

@ -13,7 +13,7 @@ import QuestionTitle from "./question-title";
import { registerCompactQuestionSheet } from "./question-viewport-coordinator";
import { useSheetScrollLock } from "./use-sheet-scroll-lock";
const EXIT_ANIMATION_MS = 300;
const EXIT_ANIMATION_MS = 200;
const EMPTY_ARRAY: string[] = [];
export type QuestionSheetProps = {
@ -413,7 +413,10 @@ export function QuestionSheet({ question, disabled }: QuestionSheetProps) {
{isOpen &&
createPortal(
<div
className="fixed inset-0 z-50 flex items-end justify-center bg-transparent"
className={[
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
].join(" ")}
role="dialog"
aria-label={question.title}
onKeyDown={(e) => {
@ -426,11 +429,11 @@ export function QuestionSheet({ question, disabled }: QuestionSheetProps) {
<section
ref={sheetRef}
className={[
"flex w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] transition-transform duration-[300ms] ease-out sm:max-w-[375px] animate-in slide-in-from-bottom",
"flex w-full flex-col overflow-hidden rounded-t-[22px] bg-white pb-[env(safe-area-inset-bottom)] shadow-[0_-10px_32px_rgba(0,0,0,0.12)] sm:max-w-[375px]",
!showSearch
? "h-auto max-h-[82svh]"
: "h-[82svh] min-h-[82svh] max-h-[82svh]",
isClosing ? "translate-y-full" : "translate-y-0",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
].join(" ")}
>
<div className="flex items-center justify-between px-5 pt-2 pb-3 border-b border-[#F2F4F7]">

14
src/components/Componentes/report-actions-sheet.tsx

@ -13,7 +13,7 @@ import {
pickManualLocation,
} from "@/lib/webview-actions";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
type ReportActionsSheetProps = {
onClose?: () => void;
@ -176,10 +176,8 @@ export function ReportActionsSheet({ onClose }: ReportActionsSheetProps) {
return (
<div
className={[
"fixed inset-0 z-50 flex items-end justify-center transition-all duration-[220ms]",
isClosing || isEntering
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-50 flex items-end justify-center",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -191,14 +189,14 @@ export function ReportActionsSheet({ onClose }: ReportActionsSheetProps) {
>
<section
className={[
"w-full sm:max-w-[375px] rounded-t-[15px] bg-[#F9F8F8] shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out max-h-[85vh] overflow-y-auto",
isClosing || isEntering ? "translate-y-full" : "translate-y-0",
"w-full sm:max-w-[375px] rounded-t-[22px] bg-white shadow-[0_20px_60px_rgba(15,23,42,0.08)] max-h-[85vh] overflow-y-auto",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
]
.filter(Boolean)
.join(" ")}
>
{/* Header */}
<div className="sticky top-0 bg-[#F9F8F8] p-3.5 border-b border-gray-200/50">
<div className="sticky top-0 bg-white p-3.5 border-b border-gray-200/50">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<h3 className="font-semibold text-gray-800">

12
src/components/Componentes/support-sheet.tsx

@ -7,7 +7,7 @@ import { FiHeadphones } from "react-icons/fi";
import { useHardwareBackHandler } from "@/hooks/use-hardware-back-handler";
import { useI18n } from "@/translations/provider";
const EXIT_ANIMATION_MS = 220;
const EXIT_ANIMATION_MS = 200;
export type SupportSheetProps = {
isOpen: boolean;
@ -89,10 +89,8 @@ export function SupportSheet({ isOpen, onClose }: SupportSheetProps) {
return createPortal(
<div
className={[
"fixed inset-0 z-[100] flex items-end justify-center transition-all duration-[220ms] select-none animate-in fade-in",
isClosing
? "bg-[#171717]/0 opacity-0"
: "bg-[#171717]/55 opacity-100",
"fixed inset-0 z-[100] flex items-end justify-center select-none",
isClosing ? "flutter-scrim-exit" : "flutter-scrim",
]
.filter(Boolean)
.join(" ")}
@ -106,8 +104,8 @@ export function SupportSheet({ isOpen, onClose }: SupportSheetProps) {
>
<section
className={[
"w-full sm:max-w-[375px] rounded-t-[15px] bg-[#EBEBEB] px-[14px] py-[14px] text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] transition-transform duration-[220ms] ease-out will-change-transform flex flex-col items-center animate-in slide-in-from-bottom",
isClosing ? "translate-y-full" : "translate-y-0",
"w-full sm:max-w-[375px] rounded-t-[22px] bg-white px-[14px] py-[14px] text-center shadow-[0_20px_60px_rgba(15,23,42,0.08)] flex flex-col items-center",
isClosing ? "flutter-sheet-surface-exit" : "flutter-sheet-surface",
]
.filter(Boolean)
.join(" ")}

Loading…
Cancel
Save