diff --git a/playground/pages/slideover.vue b/playground/pages/slideover.vue index 24b1820f..1d9610b5 100644 --- a/playground/pages/slideover.vue +++ b/playground/pages/slideover.vue @@ -14,24 +14,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + - + @@ -39,7 +55,7 @@ - + @@ -47,7 +63,7 @@ - + @@ -55,7 +71,7 @@ - + diff --git a/src/runtime/components/Slideover.vue b/src/runtime/components/Slideover.vue index d149206f..98e8792d 100644 --- a/src/runtime/components/Slideover.vue +++ b/src/runtime/components/Slideover.vue @@ -16,7 +16,7 @@ export interface SlideoverProps extends DialogRootProps { content?: Omit overlay?: boolean transition?: boolean - side?: 'left' | 'right' + side?: 'left' | 'right' | 'top' | 'bottom' preventClose?: boolean portal?: boolean close?: ButtonProps | null @@ -173,4 +173,36 @@ const ui = computed(() => tv({ extend: slideover, slots: props.ui })({ transform: translateX(-100%); } } +@keyframes slideover-content-top-open { + from { + transform: translateY(-100%); + } + to { + transform: translateY(0); + } +} +@keyframes slideover-content-top-closed { + from { + transform: translateY(0); + } + to { + transform: translateY(-100%); + } +} +@keyframes slideover-content-bottom-open { + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } +} +@keyframes slideover-content-bottom-closed { + from { + transform: translateY(0); + } + to { + transform: translateY(100%); + } +} diff --git a/src/theme/slideover.ts b/src/theme/slideover.ts index a55c1e7b..6d71d064 100644 --- a/src/theme/slideover.ts +++ b/src/theme/slideover.ts @@ -1,7 +1,7 @@ export default { slots: { overlay: 'fixed inset-0 z-30 bg-gray-200/75 dark:bg-gray-800/75', - content: 'fixed inset-y-0 z-50 sm:shadow-lg w-full max-w-md bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-800 sm:ring ring-gray-200 dark:ring-gray-800 flex flex-col focus:outline-none', + content: 'fixed z-50 bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-800 sm:ring ring-gray-200 dark:ring-gray-800 sm:shadow-lg flex flex-col focus:outline-none', header: 'px-4 py-5 sm:px-6', body: 'flex-1 overflow-y-auto p-4 sm:p-6', footer: 'flex items-center gap-x-1.5 p-4 sm:px-6', @@ -12,16 +12,22 @@ export default { variants: { side: { left: { - content: 'left-0' + content: 'left-0 inset-y-0 w-full max-w-md' }, right: { - content: 'right-0' + content: 'right-0 inset-y-0 w-full max-w-md' + }, + top: { + content: 'inset-x-0 top-0' + }, + bottom: { + content: 'inset-x-0 bottom-0' } }, transition: { true: { overlay: 'data-[state=open]:animate-[slideover-overlay-open_200ms_ease-out] data-[state=closed]:animate-[slideover-overlay-closed_200ms_ease-in]', - content: 'data-[state=open]:data-[side=left]:animate-[slideover-content-left-open_200ms_ease-in-out] data-[state=open]:data-[side=right]:animate-[slideover-content-right-open_200ms_ease-in-out] data-[state=closed]:data-[side=left]:animate-[slideover-content-left-closed_200ms_ease-in-out] data-[state=closed]:data-[side=right]:animate-[slideover-content-right-closed_200ms_ease-in-out]' + content: 'data-[state=open]:data-[side=left]:animate-[slideover-content-left-open_200ms_ease-in-out] data-[state=open]:data-[side=right]:animate-[slideover-content-right-open_200ms_ease-in-out] data-[state=closed]:data-[side=left]:animate-[slideover-content-left-closed_200ms_ease-in-out] data-[state=closed]:data-[side=right]:animate-[slideover-content-right-closed_200ms_ease-in-out] data-[state=open]:data-[side=top]:animate-[slideover-content-top-open_200ms_ease-in-out] data-[state=open]:data-[side=bottom]:animate-[slideover-content-bottom-open_200ms_ease-in-out] data-[state=closed]:data-[side=top]:animate-[slideover-content-top-closed_200ms_ease-in-out] data-[state=closed]:data-[side=bottom]:animate-[slideover-content-bottom-closed_200ms_ease-in-out]' } } } diff --git a/test/components/Slideover.spec.ts b/test/components/Slideover.spec.ts index 409fa033..17272441 100644 --- a/test/components/Slideover.spec.ts +++ b/test/components/Slideover.spec.ts @@ -8,6 +8,8 @@ describe('Slideover', () => { ['with title', { props: { open: true, portal: false, title: 'Title' } }], ['with description', { props: { open: true, portal: false, title: 'Title', description: 'Description' } }], ['with left side', { props: { open: true, portal: false, side: 'left' as const, title: 'Title', description: 'Description' } }], + ['with top side', { props: { open: true, portal: false, side: 'top' as const, title: 'Title', description: 'Description' } }], + ['with bottom side', { props: { open: true, portal: false, side: 'bottom' as const, title: 'Title', description: 'Description' } }], ['without overlay', { props: { open: true, portal: false, overlay: false, title: 'Title', description: 'Description' } }], ['without transition', { props: { open: true, portal: false, transition: false, title: 'Title', description: 'Description' } }], ['with class', { props: { open: true, portal: false, class: 'bg-gray-50 dark:bg-gray-800' } }], diff --git a/test/components/__snapshots__/Slideover.spec.ts.snap b/test/components/__snapshots__/Slideover.spec.ts.snap index 02454aa0..d6415580 100644 --- a/test/components/__snapshots__/Slideover.spec.ts.snap +++ b/test/components/__snapshots__/Slideover.spec.ts.snap @@ -6,7 +6,7 @@ exports[`Slideover > renders basic case correctly 1`] = ` - + @@ -29,7 +29,7 @@ exports[`Slideover > renders with body slot correctly 1`] = ` - + @@ -43,6 +43,29 @@ exports[`Slideover > renders with body slot correctly 1`] = ` +" +`; + +exports[`Slideover > renders with bottom side correctly 1`] = ` +" + + + + + + + Title + Description + + + + + + + + + + " `; @@ -52,7 +75,7 @@ exports[`Slideover > renders with class correctly 1`] = ` - + @@ -75,7 +98,7 @@ exports[`Slideover > renders with close slot correctly 1`] = ` - + Close slot @@ -94,7 +117,7 @@ exports[`Slideover > renders with content slot correctly 1`] = ` -Content slot +Content slot " @@ -106,7 +129,7 @@ exports[`Slideover > renders with default slot correctly 1`] = ` - + @@ -129,7 +152,7 @@ exports[`Slideover > renders with description correctly 1`] = ` - + Title Description @@ -152,10 +175,10 @@ exports[`Slideover > renders with description slot correctly 1`] = ` - + - Description slot + Description slot @@ -175,7 +198,7 @@ exports[`Slideover > renders with footer slot correctly 1`] = ` - + @@ -198,7 +221,7 @@ exports[`Slideover > renders with header slot correctly 1`] = ` - + Header slot @@ -214,7 +237,7 @@ exports[`Slideover > renders with left side correctly 1`] = ` - + Title Description @@ -237,7 +260,7 @@ exports[`Slideover > renders with title correctly 1`] = ` - + Title @@ -260,9 +283,9 @@ exports[`Slideover > renders with title slot correctly 1`] = ` - + - Title slot + Title slot @@ -274,6 +297,29 @@ exports[`Slideover > renders with title slot correctly 1`] = ` +" +`; + +exports[`Slideover > renders with top side correctly 1`] = ` +" + + + + + + + Title + Description + + + + + + + + + + " `; @@ -283,7 +329,7 @@ exports[`Slideover > renders with ui correctly 1`] = ` - + @@ -306,10 +352,10 @@ exports[`Slideover > renders without overlay correctly 1`] = ` - + - Title - Description + Title + Description @@ -329,10 +375,10 @@ exports[`Slideover > renders without transition correctly 1`] = ` - + - Title - Description + Title + Description
Description
Description slot