+ Opened programmatically: {{ props.count }} times
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/components/content/examples/SlideoverExampleComposable.vue b/docs/components/content/examples/SlideoverExampleComposable.vue
new file mode 100644
index 0000000000..6eeabaed07
--- /dev/null
+++ b/docs/components/content/examples/SlideoverExampleComposable.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/content/2.components/slideover.md b/docs/content/2.components/slideover.md
index ab6528fa6d..0d7660c102 100644
--- a/docs/content/2.components/slideover.md
+++ b/docs/content/2.components/slideover.md
@@ -33,7 +33,7 @@ Set the `transition` prop to `false` to disable it.
### Prevent close
-Use the `prevent-close` prop to disable the outside click alongside the `esc` keyboard shortcut. A `close-prevented` event will be emitted when the user tries to close the modal.
+Use the `prevent-close` prop to disable the outside click alongside the `esc` keyboard shortcut. A `close-prevented` event will be emitted when the user tries to close the slideover.
:component-example{component="slideover-example-prevent-close"}
@@ -53,6 +53,24 @@ defineShortcuts({
```
+### Control programmatically
+
+First of all, add the `USlideovers` component to your app, preferably inside `app.vue`.
+
+```vue [app.vue]
+
+
+
+
+
+
+
+
+```
+
+Then, you can use the `useSlideover` composable to control your slideovers within your app.
+
+:component-example{component="slideover-example-composable"}
## Props
:component-props
diff --git a/src/module.ts b/src/module.ts
index 5beb7c1348..4b41d2596a 100644
--- a/src/module.ts
+++ b/src/module.ts
@@ -200,6 +200,10 @@ export default defineNuxtModule({
src: resolve(runtimeDir, 'plugins', 'modals')
})
+ addPlugin({
+ src: resolve(runtimeDir, 'plugins', 'slideovers')
+ })
+
// Components
addComponentsDir({
diff --git a/src/runtime/components/overlays/Slideovers.client.vue b/src/runtime/components/overlays/Slideovers.client.vue
new file mode 100644
index 0000000000..933c8e616b
--- /dev/null
+++ b/src/runtime/components/overlays/Slideovers.client.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/src/runtime/composables/useSlideover.ts b/src/runtime/composables/useSlideover.ts
new file mode 100644
index 0000000000..3f221e2ca6
--- /dev/null
+++ b/src/runtime/composables/useSlideover.ts
@@ -0,0 +1,55 @@
+import { ref, inject } from 'vue'
+import { createSharedComposable } from '@vueuse/core'
+import type { ShallowRef, Component, InjectionKey } from 'vue'
+import type { ComponentProps } from '../types/component'
+import type { Slideover, SlideoverState } from '../types/slideover'
+
+export const slidOverInjectionKey: InjectionKey> =
+ Symbol('nuxt-ui.slideover')
+
+function _useSlideover () {
+ const slideoverState = inject(slidOverInjectionKey)
+ const isOpen = ref(false)
+
+ function open (component: T, props?: Slideover & ComponentProps) {
+ if (!slideoverState) {
+ throw new Error('useSlideover() is called without provider')
+ }
+
+ slideoverState.value = {
+ component,
+ props: props ?? {}
+ }
+
+ isOpen.value = true
+ }
+
+ function close () {
+ if (!slideoverState) return
+
+ isOpen.value = false
+ }
+
+ /**
+ * Allows updating the slideover props
+ */
+ function patch (props: Partial>) {
+ if (!slideoverState) return
+
+ slideoverState.value = {
+ ...slideoverState.value,
+ props: {
+ ...slideoverState.value.props,
+ ...props
+ }
+ }
+ }
+ return {
+ open,
+ close,
+ patch,
+ isOpen
+ }
+}
+
+export const useSlideover = createSharedComposable(_useSlideover)
diff --git a/src/runtime/plugins/slideovers.ts b/src/runtime/plugins/slideovers.ts
new file mode 100644
index 0000000000..950d4fbb7d
--- /dev/null
+++ b/src/runtime/plugins/slideovers.ts
@@ -0,0 +1,13 @@
+import { defineNuxtPlugin } from '#imports'
+import { shallowRef } from 'vue'
+import { slidOverInjectionKey } from '../composables/useSlideover'
+import type { SlideoverState } from '../types/slideover'
+
+export default defineNuxtPlugin((nuxtApp) => {
+ const slideoverState = shallowRef({
+ component: 'div',
+ props: {}
+ })
+
+ nuxtApp.vueApp.provide(slidOverInjectionKey, slideoverState)
+})
diff --git a/src/runtime/types/index.d.ts b/src/runtime/types/index.d.ts
index 21188a9ee1..3b90d85399 100644
--- a/src/runtime/types/index.d.ts
+++ b/src/runtime/types/index.d.ts
@@ -17,6 +17,7 @@ export * from './kbd'
export * from './link'
export * from './meter'
export * from './modal'
+export * from './slideover'
export * from './notification'
export * from './popper'
export * from './progress'
diff --git a/src/runtime/types/slideover.d.ts b/src/runtime/types/slideover.d.ts
new file mode 100644
index 0000000000..291d20feca
--- /dev/null
+++ b/src/runtime/types/slideover.d.ts
@@ -0,0 +1,17 @@
+import type { Component } from 'vue'
+
+interface Slideover {
+ ui?: any;
+ side?: 'right' | 'left';
+ transition?: boolean;
+ appear?: boolean;
+ overlay?: boolean;
+ preventClose?: boolean;
+ modelValue?: boolean;
+}
+
+interface SlideoverState {
+ component: Component | string;
+ props: Slideover;
+}
+