diff --git a/app/app.vue b/app/app.vue index e29ccb5..f66156c 100644 --- a/app/app.vue +++ b/app/app.vue @@ -9,9 +9,7 @@ // 15px, which shifted the entire page content 15px to the left. This prop prevents // that unwanted padding injection and layout shift. import { ConfigProvider } from 'reka-ui' - -// Import cart UI components -const { isMobile } = useCartUI() +import CartResponsive from '~/components/Cart/CartResponsive.vue' @@ -19,10 +17,8 @@ const { isMobile } = useCartUI() - - - - + + diff --git a/app/components/Cart/CartSidebar.vue b/app/components/Cart/CartResponsive.vue similarity index 80% rename from app/components/Cart/CartSidebar.vue rename to app/components/Cart/CartResponsive.vue index 2d28fea..cecc168 100644 --- a/app/components/Cart/CartSidebar.vue +++ b/app/components/Cart/CartResponsive.vue @@ -1,4 +1,5 @@ - - - !open && close()"> - - - - - Warenkorb ({{ itemCount }}) - - - - - - - - - - - - - - handleUpdateQuantity(item.id, qty)" @remove="handleRemoveItem(item.id)" /> - - - - - - - - - - - diff --git a/app/components/Cart/index.ts b/app/components/Cart/index.ts index f5bb864..05bbf8a 100644 --- a/app/components/Cart/index.ts +++ b/app/components/Cart/index.ts @@ -2,5 +2,4 @@ export { default as CartItem } from './CartItem.vue' export { default as CartSummary } from './CartSummary.vue' export { default as CartEmpty } from './CartEmpty.vue' export { default as CartFAB } from './CartFAB.vue' -export { default as CartSidebar } from './CartSidebar.vue' -export { default as CartSheet } from './CartSheet.vue' +export { default as CartResponsive } from './CartResponsive.vue' diff --git a/app/layouts/default.vue b/app/layouts/default.vue index 007cf53..e4f524f 100644 --- a/app/layouts/default.vue +++ b/app/layouts/default.vue @@ -2,12 +2,8 @@ import AppHeader from '~/components/navigation/AppHeader.vue' import BottomNav from '~/components/navigation/BottomNav.vue' import CartFAB from '~/components/Cart/CartFAB.vue' -import CartSidebar from '~/components/Cart/CartSidebar.vue' -import CartSheet from '~/components/Cart/CartSheet.vue' +import CartResponsive from '~/components/Cart/CartResponsive.vue' import { Toaster } from '~/components/ui/sonner' - -// Determine which cart UI to show based on screen size -const { isMobile } = useCartUI() @@ -29,11 +25,8 @@ const { isMobile } = useCartUI() - - - - - + + diff --git a/assets/css/tailwind.css b/assets/css/tailwind.css index 6ac8162..56c9135 100644 --- a/assets/css/tailwind.css +++ b/assets/css/tailwind.css @@ -836,6 +836,170 @@ ======================================== */ @layer utilities { + /* Animation utilities for Sheet/Dialog components */ + @keyframes slideInFromRight { + from { + transform: translateX(100%); + } + to { + transform: translateX(0); + } + } + + @keyframes slideOutToRight { + from { + transform: translateX(0); + } + to { + transform: translateX(100%); + } + } + + @keyframes slideInFromBottom { + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } + } + + @keyframes slideOutToBottom { + from { + transform: translateY(0); + } + to { + transform: translateY(100%); + } + } + + @keyframes slideInFromLeft { + from { + transform: translateX(-100%); + } + to { + transform: translateX(0); + } + } + + @keyframes slideOutToLeft { + from { + transform: translateX(0); + } + to { + transform: translateX(-100%); + } + } + + @keyframes slideInFromTop { + from { + transform: translateY(-100%); + } + to { + transform: translateY(0); + } + } + + @keyframes slideOutToTop { + from { + transform: translateY(0); + } + to { + transform: translateY(-100%); + } + } + + @keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + + @keyframes fadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } + } + + /* Animation classes with data-state support */ + [data-state="open"].animate-in, + .data-\[state\=open\]\:animate-in[data-state="open"] { + animation-duration: 0.3s; + animation-fill-mode: both; + } + + [data-state="closed"].animate-out, + .data-\[state\=closed\]\:animate-out[data-state="closed"] { + animation-duration: 0.2s; + animation-fill-mode: both; + } + + [data-state="open"].fade-in-0, + .data-\[state\=open\]\:fade-in-0[data-state="open"] { + animation-name: fadeIn; + } + + [data-state="closed"].fade-out-0, + .data-\[state\=closed\]\:fade-out-0[data-state="closed"] { + animation-name: fadeOut; + } + + [data-state="open"].slide-in-from-right, + .data-\[state\=open\]\:slide-in-from-right[data-state="open"] { + animation-name: slideInFromRight; + } + + [data-state="closed"].slide-out-to-right, + .data-\[state\=closed\]\:slide-out-to-right[data-state="closed"] { + animation-name: slideOutToRight; + } + + [data-state="open"].slide-in-from-bottom, + .data-\[state\=open\]\:slide-in-from-bottom[data-state="open"] { + animation-name: slideInFromBottom; + } + + [data-state="closed"].slide-out-to-bottom, + .data-\[state\=closed\]\:slide-out-to-bottom[data-state="closed"] { + animation-name: slideOutToBottom; + } + + [data-state="open"].slide-in-from-left, + .data-\[state\=open\]\:slide-in-from-left[data-state="open"] { + animation-name: slideInFromLeft; + } + + [data-state="closed"].slide-out-to-left, + .data-\[state\=closed\]\:slide-out-to-left[data-state="closed"] { + animation-name: slideOutToLeft; + } + + [data-state="open"].slide-in-from-top, + .data-\[state\=open\]\:slide-in-from-top[data-state="open"] { + animation-name: slideInFromTop; + } + + [data-state="closed"].slide-out-to-top, + .data-\[state\=closed\]\:slide-out-to-top[data-state="closed"] { + animation-name: slideOutToTop; + } + + [data-state="open"].duration-500, + .data-\[state\=open\]\:duration-500[data-state="open"] { + animation-duration: 500ms; + } + + [data-state="closed"].duration-300, + .data-\[state\=closed\]\:duration-300[data-state="closed"] { + animation-duration: 300ms; + } + /* Container utilities */ .container-main { @apply max-w-container-main mx-auto;