feat(Slideover): open programmatically (#1465)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Eugen Istoc
2024-03-21 12:48:35 -04:00
committed by GitHub
parent b0ecac563c
commit e7697595c8
10 changed files with 173 additions and 1 deletions

View File

@@ -0,0 +1,17 @@
<template>
<component
:is="slideoverState.component"
v-if="slideoverState"
v-bind="slideoverState.props"
v-model="isOpen"
/>
</template>
<script lang="ts" setup>
import { inject } from 'vue'
import { useSlideover, slidOverInjectionKey } from '../../composables/useSlideover'
const slideoverState = inject(slidOverInjectionKey)
const { isOpen } = useSlideover()
</script>

View File

@@ -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<ShallowRef<SlideoverState>> =
Symbol('nuxt-ui.slideover')
function _useSlideover () {
const slideoverState = inject(slidOverInjectionKey)
const isOpen = ref(false)
function open<T extends Component> (component: T, props?: Slideover & ComponentProps<T>) {
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<T extends Component = {}> (props: Partial<Slideover & ComponentProps<T>>) {
if (!slideoverState) return
slideoverState.value = {
...slideoverState.value,
props: {
...slideoverState.value.props,
...props
}
}
}
return {
open,
close,
patch,
isOpen
}
}
export const useSlideover = createSharedComposable(_useSlideover)

View File

@@ -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<SlideoverState>({
component: 'div',
props: {}
})
nuxtApp.vueApp.provide(slidOverInjectionKey, slideoverState)
})

View File

@@ -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'

17
src/runtime/types/slideover.d.ts vendored Normal file
View File

@@ -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;
}