Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/deep-moons-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"vaul-vue": patch
---

added programmatic close functionality to drawer from dialog root
27 changes: 27 additions & 0 deletions packages/vaul-vue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,33 @@ import { DrawerContent, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTrigger }
<DrawerOverlay />
<DrawerContent>
<p>Content</p>

<DrawerClose>
Close
</DrawerClose>
</DrawerContent>
</DrawerPortal>
</DrawerRoot>
</template>
```

#### Close programatically

```vue
<script setup lang="ts">
import { DrawerContent, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTrigger } from 'vaul-vue'
</script>

<template>
<DrawerRoot v-slot="{ close }">
<DrawerTrigger> Open </DrawerTrigger>
<DrawerPortal>
<DrawerOverlay />
<DrawerContent>
<p>Content</p>
<button @click="close">
close
</button>
</DrawerContent>
</DrawerPortal>
</DrawerRoot>
Expand Down
2 changes: 1 addition & 1 deletion packages/vaul-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
"dependencies": {
"@vueuse/core": "^10.8.0",
"reka-ui": "^2.0.0",
"reka-ui": "^2.3.0",
"vue": "^3.4.5"
},
"devDependencies": {
Expand Down
1 change: 0 additions & 1 deletion packages/vaul-vue/src/DrawerOverlay.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang="ts">
import { DialogOverlay } from 'reka-ui'
import { computed } from 'vue'
import { injectDrawerRootContext } from './context'
const { overlayRef, hasSnapPoints, isOpen, shouldFade } = injectDrawerRootContext()
Expand Down
4 changes: 3 additions & 1 deletion packages/vaul-vue/src/DrawerRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const emit = defineEmits<DrawerRootEmits>()
const slots = defineSlots<{
default: (props: {
open: typeof isOpen.value
close: () => void
}) => any
}>()

Expand Down Expand Up @@ -93,10 +94,11 @@ defineExpose({

<template>
<DialogRoot
v-slot="{ close }"
:open="isOpen"
:modal="modal"
@update:open="handleOpenChange"
>
<slot :open="isOpen" />
<slot :open="isOpen" :close="close" />
</DialogRoot>
</template>
8 changes: 7 additions & 1 deletion packages/vaul-vue/src/DrawerRootNested.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { injectDrawerRootContext } from './context'

const props = defineProps<DrawerRootProps>()
const emits = defineEmits<DrawerRootEmits>()
const slots = defineSlots<{
default: (props: {
close: () => void
}) => any
}>()

const { onNestedDrag, onNestedOpenChange, onNestedRelease } = injectDrawerRootContext()
function onClose() {
Expand All @@ -28,13 +33,14 @@ const forwarded = useForwardPropsEmits(props, emits)

<template>
<DrawerRoot
v-slot="{ close }"
v-bind="forwarded"
nested
@close="onClose"
@drag="onDrag"
@release="onNestedRelease"
@update:open="onOpenChange"
>
<slot />
<slot :close="close" />
</DrawerRoot>
</template>
2 changes: 1 addition & 1 deletion packages/vaul-vue/src/controls.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { computed, onUnmounted, ref, watch, watchEffect } from 'vue'
import { computed, ref, watch, watchEffect } from 'vue'
import type { ComponentPublicInstance, Ref } from 'vue'
import { isClient } from '@vueuse/core'
import { dampenValue, getTranslate, isVertical, reset, set } from './helpers'
Expand Down
2 changes: 1 addition & 1 deletion packages/vaul-vue/src/useScaleBackground.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ref, watchEffect } from 'vue'
import { injectDrawerRootContext } from './context'
import { assignStyle, chain, isVertical, reset } from './helpers'
import { assignStyle, chain, isVertical } from './helpers'
import { BORDER_RADIUS, TRANSITIONS, WINDOW_TOP_OFFSET } from './constants'

const noop = () => () => {}
Expand Down
18 changes: 10 additions & 8 deletions packages/vaul-vue/src/useSnapPoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ export function useSnapPoints({
const isLastSnapPoint = computed(
() =>
(snapPoints.value
&& activeSnapPoint.value === snapPoints.value[snapPoints.value.length - 1])
&& activeSnapPoint.value === snapPoints.value[snapPoints.value.length - 1])
?? null,
)

const shouldFade = computed(
() =>
(snapPoints.value
&& snapPoints.value.length > 0
&& (fadeFromIndex?.value || fadeFromIndex?.value === 0)
&& !Number.isNaN(fadeFromIndex?.value)
&& snapPoints.value[fadeFromIndex?.value ?? -1] === activeSnapPoint.value)
&& snapPoints.value.length > 0
&& (fadeFromIndex?.value || fadeFromIndex?.value === 0)
&& !Number.isNaN(fadeFromIndex?.value)
&& snapPoints.value[fadeFromIndex?.value ?? -1] === activeSnapPoint.value)
|| !snapPoints.value,
)

Expand Down Expand Up @@ -143,8 +143,9 @@ export function useSnapPoints({
snapPointsOffset.value
&& newIndex !== -1
&& typeof snapPointsOffset.value[newIndex] === 'number'
)
) {
snapToPoint(snapPointsOffset.value[newIndex])
}
}
},
{
Expand Down Expand Up @@ -249,8 +250,9 @@ export function useSnapPoints({
|| typeof activeSnapPointIndex.value !== 'number'
|| !snapPointsOffset.value
|| fadeFromIndex.value === undefined
)
) {
return null
}

// If this is true we are dragging to a snap point that is supposed to have an overlay
const isOverlaySnapPoint = activeSnapPointIndex.value === fadeFromIndex.value - 1
Expand All @@ -275,7 +277,7 @@ export function useSnapPoints({
? snapPointsOffset.value[targetSnapPointIndex]
- snapPointsOffset.value[targetSnapPointIndex - 1]
: snapPointsOffset.value[targetSnapPointIndex + 1]
- snapPointsOffset.value[targetSnapPointIndex]
- snapPointsOffset.value[targetSnapPointIndex]

const percentageDragged = absDraggedDistance / Math.abs(snapPointDistance)

Expand Down
2 changes: 1 addition & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test": "pnpm run test:e2e"
},
"dependencies": {
"reka-ui": "^2.0.0",
"reka-ui": "^2.3.0",
"vaul-vue": "workspace:*",
"vue": "^3.4.5",
"vue-router": "4"
Expand Down
5 changes: 4 additions & 1 deletion playground/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import Nav from './components/Nav.vue'
</script>

<template>
<Nav />
<RouterView />
</template>

Expand Down
73 changes: 73 additions & 0 deletions playground/src/components/Nav.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<script setup lang="ts">
import {
NavigationMenuContent,
NavigationMenuIndicator,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuRoot,
NavigationMenuTrigger,
NavigationMenuViewport,
} from 'reka-ui'
import { RouterLink, useRouter } from 'vue-router'
import { computed } from 'vue'

const router = useRouter()

const testPages = computed(() => {
const testRoute = router.getRoutes().filter(route => route.path.includes('/test'))
return testRoute?.map(child => ({
path: child.path,
name: child.name,
}))
})
</script>

<template>
<NavigationMenuRoot class="fixed top-0 left-0 right-0 z-10 flex max-w-max flex-1 items-center justify-center">
<NavigationMenuList class="group flex flex-1 list-none items-center justify-center space-x-1">
<!-- Home Link -->
<NavigationMenuItem>
<NavigationMenuLink as-child>
<RouterLink
to="/"
class="group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
>
Home
</RouterLink>
</NavigationMenuLink>
</NavigationMenuItem>

<!-- Test Pages Dropdown -->
<NavigationMenuItem>
<NavigationMenuTrigger class="group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50">
Demo Pages
</NavigationMenuTrigger>
<NavigationMenuContent>
<div class="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]">
<div v-for="page in testPages" :key="page.path" class="row-span-1">
<NavigationMenuLink as-child>
<RouterLink
:to="page.path"
class="block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
>
<div class="text-sm font-medium leading-none">
{{ page.name }}
</div>
</RouterLink>
</NavigationMenuLink>
</div>
</div>
</NavigationMenuContent>
</NavigationMenuItem>

<NavigationMenuIndicator class="top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in">
<div class="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
</NavigationMenuIndicator>
</NavigationMenuList>

<div class="absolute left-0 top-full flex justify-center">
<NavigationMenuViewport class="origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]" />
</div>
</NavigationMenuRoot>
</template>
16 changes: 16 additions & 0 deletions playground/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,62 @@ const router = createRouter({
children: [
{
path: 'controlled',
name: 'Controlled Drawer',
component: () => import('../views/tests/ControlledView.vue'),
},
{
path: 'no-drag-element',
name: 'No Drag Element',
component: () => import('../views/tests/NoDragElementView.vue'),
},
{
path: 'initial-snap',
name: 'Initial Snap Point',
component: () => import('../views/tests/InitialSnapView.vue'),
},
{
path: 'direction',
name: 'Drawer Direction',
component: () => import('../views/tests/DirectionView.vue'),
},
{
path: 'nested-drawer',
name: 'Nested Drawer',
component: () => import('../views/tests/NestedDrawerView.vue'),
},
{
path: 'nested-programmatic-close',
name: 'Nested Programmatic Close',
component: () => import('../views/tests/NestedProgrammaticClose.vue'),
},
{
path: 'non-dismissible',
name: 'Non-Dismissible Drawer',
component: () => import('../views/tests/NonDismissibleView.vue'),
},
{
path: 'scrollable-with-inputs',
name: 'Scrollable with Inputs',
component: () => import('../views/tests/ScrollableWithInputsView.vue'),
},
{
path: 'without-scaled-background',
name: 'Without Scaled Background',
component: () => import('../views/tests/WithoutScaledBackgroundView.vue'),
},
{
path: 'with-handle',
name: 'With Handle',
component: () => import('../views/tests/WithHandleView.vue'),
},
{
path: 'with-scaled-background',
name: 'With Scaled Background',
component: () => import('../views/tests/WithScaledBackgroundView.vue'),
},
{
path: 'with-snap-points',
name: 'With Snap Points',
component: () => import('../views/tests/WithSnapPointsView.vue'),
},

Expand Down
1 change: 0 additions & 1 deletion playground/src/views/tests/DirectionView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang="ts">
import {
DrawerClose,
type DrawerDirection,
DrawerOverlay,
DrawerPortal,
Expand Down
Loading