pref: use hooks instead of directive (#108)
- remove v-resize - add useContainerResize - remove v-container - add useContainerQueries - add useContainerScroll
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex h-full flex-col gap-4">
|
<div class="flex h-full flex-col gap-4">
|
||||||
<div class="whitespace-nowrap px-4" v-container="container">
|
<div ref="container" class="whitespace-nowrap px-4">
|
||||||
<div :class="['flex gap-4', $sm('justify-end')]">
|
<div :class="['flex gap-4', $sm('justify-end')]">
|
||||||
<Button
|
<Button
|
||||||
:class="[$sm('w-auto', 'w-full')]"
|
:class="[$sm('w-auto', 'w-full')]"
|
||||||
@@ -77,6 +77,7 @@ import { useContainerQueries } from 'hooks/container'
|
|||||||
import { useDialog } from 'hooks/dialog'
|
import { useDialog } from 'hooks/dialog'
|
||||||
import { useDownload } from 'hooks/download'
|
import { useDownload } from 'hooks/download'
|
||||||
import Button from 'primevue/button'
|
import Button from 'primevue/button'
|
||||||
|
import { ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
const { data } = useDownload()
|
const { data } = useDownload()
|
||||||
@@ -92,6 +93,6 @@ const openCreateTask = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = Symbol('container')
|
const container = ref<HTMLElement | null>(null)
|
||||||
const { $sm } = useContainerQueries(container)
|
const { $sm } = useContainerQueries(container)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
ref="contentContainer"
|
||||||
class="flex h-full flex-col gap-4 overflow-hidden"
|
class="flex h-full flex-col gap-4 overflow-hidden"
|
||||||
v-resize="onContainerResize"
|
|
||||||
v-container="contentContainer"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-1 justify-center gap-4 px-8"
|
class="grid grid-cols-1 justify-center gap-4 px-8"
|
||||||
:style="$content_lg(contentStyle)"
|
:style="$content_lg(contentStyle)"
|
||||||
>
|
>
|
||||||
<div class="col-span-full" v-container="toolbarContainer">
|
<div ref="toolbarContainer" class="col-span-full">
|
||||||
<div class="flex flex-col gap-4" :style="$toolbar_2xl(toolbarStyle)">
|
<div class="flex flex-col gap-4" :style="$toolbar_2xl(toolbarStyle)">
|
||||||
<ResponseInput
|
<ResponseInput
|
||||||
v-model="searchContent"
|
v-model="searchContent"
|
||||||
@@ -71,7 +70,7 @@ import ResponseSelect from 'components/ResponseSelect.vue'
|
|||||||
import { configSetting, useConfig } from 'hooks/config'
|
import { configSetting, useConfig } from 'hooks/config'
|
||||||
import { useContainerQueries } from 'hooks/container'
|
import { useContainerQueries } from 'hooks/container'
|
||||||
import { useModels } from 'hooks/model'
|
import { useModels } from 'hooks/model'
|
||||||
import { defineResizeCallback } from 'hooks/resize'
|
import { useContainerResize } from 'hooks/resize'
|
||||||
import { chunk } from 'lodash'
|
import { chunk } from 'lodash'
|
||||||
import { app } from 'scripts/comfyAPI'
|
import { app } from 'scripts/comfyAPI'
|
||||||
import { Model } from 'types/typings'
|
import { Model } from 'types/typings'
|
||||||
@@ -84,6 +83,12 @@ const { isMobile, cardWidth, gutter, aspect } = useConfig()
|
|||||||
const { data, folders } = useModels()
|
const { data, folders } = useModels()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const toolbarContainer = ref<HTMLElement | null>(null)
|
||||||
|
const { $2xl: $toolbar_2xl } = useContainerQueries(toolbarContainer)
|
||||||
|
|
||||||
|
const contentContainer = ref<HTMLElement | null>(null)
|
||||||
|
const { $lg: $content_lg } = useContainerQueries(contentContainer)
|
||||||
|
|
||||||
const responseScroll = ref()
|
const responseScroll = ref()
|
||||||
|
|
||||||
const searchContent = ref<string>()
|
const searchContent = ref<string>()
|
||||||
@@ -143,8 +148,16 @@ const itemSize = computed(() => {
|
|||||||
return itemWidth / aspect + itemGutter
|
return itemWidth / aspect + itemGutter
|
||||||
})
|
})
|
||||||
|
|
||||||
const colSpan = ref(1)
|
const { width } = useContainerResize(contentContainer)
|
||||||
const colSpanWidth = ref(cardWidth)
|
|
||||||
|
const cols = computed(() => {
|
||||||
|
if (isMobile.value) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerWidth = width.value
|
||||||
|
return Math.floor((containerWidth - gutter) / (cardWidth + gutter))
|
||||||
|
})
|
||||||
|
|
||||||
const list = computed(() => {
|
const list = computed(() => {
|
||||||
const mergedList = Object.values(data.value).flat()
|
const mergedList = Object.values(data.value).flat()
|
||||||
@@ -180,33 +193,17 @@ const list = computed(() => {
|
|||||||
|
|
||||||
const sortedList = filterList.sort(sortStrategy)
|
const sortedList = filterList.sort(sortStrategy)
|
||||||
|
|
||||||
return chunk(sortedList, colSpan.value)
|
return chunk(sortedList, cols.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
const toolbarContainer = Symbol('toolbar')
|
const contentStyle = computed(() => ({
|
||||||
const { $2xl: $toolbar_2xl } = useContainerQueries(toolbarContainer)
|
|
||||||
|
|
||||||
const contentContainer = Symbol('content')
|
|
||||||
const { $lg: $content_lg } = useContainerQueries(contentContainer)
|
|
||||||
|
|
||||||
const contentStyle = {
|
|
||||||
gridTemplateColumns: `repeat(auto-fit, ${cardWidth}px)`,
|
gridTemplateColumns: `repeat(auto-fit, ${cardWidth}px)`,
|
||||||
gap: `${gutter}px`,
|
gap: `${gutter}px`,
|
||||||
paddingLeft: `1rem`,
|
paddingLeft: `1rem`,
|
||||||
paddingRight: `1rem`,
|
paddingRight: `1rem`,
|
||||||
}
|
}))
|
||||||
const toolbarStyle = {
|
|
||||||
flexDirection: 'row',
|
|
||||||
}
|
|
||||||
|
|
||||||
const onContainerResize = defineResizeCallback((entries) => {
|
const toolbarStyle = computed(() => ({
|
||||||
const entry = entries[0]
|
flexDirection: 'row',
|
||||||
if (isMobile.value) {
|
}))
|
||||||
colSpan.value = 1
|
|
||||||
} else {
|
|
||||||
const containerWidth = entry.contentRect.width
|
|
||||||
colSpan.value = Math.floor((containerWidth - gutter) / (cardWidth + gutter))
|
|
||||||
colSpanWidth.value = colSpan.value * (cardWidth + gutter) - gutter
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<form
|
<form
|
||||||
|
ref="container"
|
||||||
@submit.prevent="handleSubmit"
|
@submit.prevent="handleSubmit"
|
||||||
@reset.prevent="handleReset"
|
@reset.prevent="handleReset"
|
||||||
v-container="container"
|
|
||||||
>
|
>
|
||||||
<div class="mx-auto w-full max-w-[50rem]">
|
<div class="mx-auto w-full max-w-[50rem]">
|
||||||
<div
|
<div
|
||||||
@@ -63,7 +63,7 @@ import TabPanel from 'primevue/tabpanel'
|
|||||||
import TabPanels from 'primevue/tabpanels'
|
import TabPanels from 'primevue/tabpanels'
|
||||||
import Tabs from 'primevue/tabs'
|
import Tabs from 'primevue/tabs'
|
||||||
import { BaseModel, WithResolved } from 'types/typings'
|
import { BaseModel, WithResolved } from 'types/typings'
|
||||||
import { toRaw, watch } from 'vue'
|
import { ref, toRaw, watch } from 'vue'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
model: BaseModel
|
model: BaseModel
|
||||||
@@ -101,6 +101,6 @@ watch(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const container = Symbol('container')
|
const container = ref<HTMLElement | null>(null)
|
||||||
const { $xl } = useContainerQueries(container)
|
const { $xl } = useContainerQueries(container)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
data-scroll-viewport
|
data-scroll-viewport
|
||||||
class="h-full w-full overflow-auto scrollbar-none"
|
class="h-full w-full overflow-auto scrollbar-none"
|
||||||
:style="{ contain: items ? 'strict' : undefined }"
|
:style="{ contain: items ? 'strict' : undefined }"
|
||||||
@scroll="onContentScroll"
|
|
||||||
v-resize="onContainerResize"
|
|
||||||
>
|
>
|
||||||
<div data-scroll-content class="relative min-w-full">
|
<div data-scroll-content class="relative min-w-full">
|
||||||
<slot name="default">
|
<slot name="default">
|
||||||
@@ -60,7 +58,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" generic="T">
|
<script setup lang="ts" generic="T">
|
||||||
import { defineResizeCallback } from 'hooks/resize'
|
import { useContainerResize } from 'hooks/resize'
|
||||||
|
import { useContainerScroll } from 'hooks/scroll'
|
||||||
import { clamp, throttle } from 'lodash'
|
import { clamp, throttle } from 'lodash'
|
||||||
import { nextTick, onUnmounted, ref, watch } from 'vue'
|
import { nextTick, onUnmounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
@@ -74,7 +73,6 @@ interface ScrollAreaProps {
|
|||||||
const props = withDefaults(defineProps<ScrollAreaProps>(), {
|
const props = withDefaults(defineProps<ScrollAreaProps>(), {
|
||||||
scrollbar: true,
|
scrollbar: true,
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['scroll', 'resize'])
|
|
||||||
|
|
||||||
type ScrollbarDirection = 'horizontal' | 'vertical'
|
type ScrollbarDirection = 'horizontal' | 'vertical'
|
||||||
|
|
||||||
@@ -207,37 +205,40 @@ const calculateScrollThumbSize = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const onContainerResize = defineResizeCallback((entries) => {
|
const viewport = ref<HTMLElement | null>(null)
|
||||||
emit('resize', entries)
|
|
||||||
|
const { width, height } = useContainerResize(viewport)
|
||||||
|
|
||||||
|
watch([width, height], () => {
|
||||||
if (isDragging.value) return
|
if (isDragging.value) return
|
||||||
|
|
||||||
calculateScrollThumbSize()
|
calculateScrollThumbSize()
|
||||||
})
|
})
|
||||||
|
|
||||||
const onContentScroll = throttle((event: Event) => {
|
useContainerScroll(viewport, {
|
||||||
emit('scroll', event)
|
onScroll: (event) => {
|
||||||
if (isDragging.value) return
|
if (isDragging.value) return
|
||||||
|
|
||||||
const container = event.target as HTMLDivElement
|
const container = event.target as HTMLDivElement
|
||||||
const content = getContainerContent()
|
const content = getContainerContent()
|
||||||
|
|
||||||
const resolveOffset = (item: Scrollbar, attr: ScrollbarAttribute) => {
|
const resolveOffset = (item: Scrollbar, attr: ScrollbarAttribute) => {
|
||||||
const containerSize = container[attr.clientSize]
|
const containerSize = container[attr.clientSize]
|
||||||
const contentSize = content[attr.clientSize]
|
const contentSize = content[attr.clientSize]
|
||||||
const scrollOffset = container[attr.scrollOffset]
|
const scrollOffset = container[attr.scrollOffset]
|
||||||
|
|
||||||
item.offset =
|
item.offset =
|
||||||
(scrollOffset / (contentSize - containerSize)) *
|
(scrollOffset / (contentSize - containerSize)) *
|
||||||
(containerSize - item.size)
|
(containerSize - item.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveOffset(scrollbars.value.horizontal, scrollbarAttrs.horizontal)
|
resolveOffset(scrollbars.value.horizontal, scrollbarAttrs.horizontal)
|
||||||
resolveOffset(scrollbars.value.vertical, scrollbarAttrs.vertical)
|
resolveOffset(scrollbars.value.vertical, scrollbarAttrs.vertical)
|
||||||
|
|
||||||
calculateLoadItems()
|
calculateLoadItems()
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const viewport = ref<HTMLElement>()
|
|
||||||
const draggingDirection = ref<ScrollbarDirection>()
|
const draggingDirection = ref<ScrollbarDirection>()
|
||||||
const prevDraggingEvent = ref<MouseEvent>()
|
const prevDraggingEvent = ref<MouseEvent>()
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,7 @@
|
|||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
<div v-else class="relative flex-1 overflow-hidden">
|
<div v-else class="relative flex-1 overflow-hidden">
|
||||||
<div
|
<div ref="scrollArea" class="h-full w-full overflow-auto scrollbar-none">
|
||||||
ref="scrollArea"
|
|
||||||
class="h-full w-full overflow-auto scrollbar-none"
|
|
||||||
v-resize="checkScrollPosition"
|
|
||||||
@scroll="checkScrollPosition"
|
|
||||||
>
|
|
||||||
<div ref="contentArea" class="table max-w-full">
|
<div ref="contentArea" class="table max-w-full">
|
||||||
<div
|
<div
|
||||||
v-show="showControlButton && scrollPosition !== 'left'"
|
v-show="showControlButton && scrollPosition !== 'left'"
|
||||||
@@ -157,11 +152,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useConfig } from 'hooks/config'
|
import { useConfig } from 'hooks/config'
|
||||||
|
import { useContainerResize } from 'hooks/resize'
|
||||||
|
import { useContainerScroll } from 'hooks/scroll'
|
||||||
import Button, { ButtonProps } from 'primevue/button'
|
import Button, { ButtonProps } from 'primevue/button'
|
||||||
import Drawer from 'primevue/drawer'
|
import Drawer from 'primevue/drawer'
|
||||||
import Menu from 'primevue/menu'
|
import Menu from 'primevue/menu'
|
||||||
import { SelectOptions } from 'types/typings'
|
import { SelectOptions } from 'types/typings'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
const current = defineModel()
|
const current = defineModel()
|
||||||
|
|
||||||
@@ -202,7 +199,7 @@ const toggle = (event: MouseEvent) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select Button Type
|
// Select Button Type
|
||||||
const scrollArea = ref()
|
const scrollArea = ref<HTMLElement | null>(null)
|
||||||
const contentArea = ref()
|
const contentArea = ref()
|
||||||
|
|
||||||
type ScrollPosition = 'left' | 'right'
|
type ScrollPosition = 'left' | 'right'
|
||||||
@@ -242,4 +239,16 @@ const checkScrollPosition = () => {
|
|||||||
scrollPosition.value = position
|
scrollPosition.value = position
|
||||||
showControlButton.value = contentWidth > containerWidth
|
showControlButton.value = contentWidth > containerWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { width, height } = useContainerResize(scrollArea)
|
||||||
|
|
||||||
|
watch([width, height], () => {
|
||||||
|
checkScrollPosition()
|
||||||
|
})
|
||||||
|
|
||||||
|
useContainerScroll(scrollArea, {
|
||||||
|
onScroll: () => {
|
||||||
|
checkScrollPosition()
|
||||||
|
},
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,46 +1,27 @@
|
|||||||
import { defineResizeCallback } from 'hooks/resize'
|
import { useContainerResize } from 'hooks/resize'
|
||||||
import { computed, Directive, inject, InjectionKey, provide, ref } from 'vue'
|
import { type InjectionKey, type Ref, inject, provide, toRef } from 'vue'
|
||||||
|
|
||||||
const globalContainerSize = ref<Record<symbol, number>>({})
|
|
||||||
|
|
||||||
const containerNameKey = Symbol('containerName') as InjectionKey<symbol>
|
|
||||||
|
|
||||||
export const containerDirective: Directive<HTMLElement, symbol> = {
|
|
||||||
mounted: (el, binding) => {
|
|
||||||
const containerName = binding.value || Symbol('container')
|
|
||||||
const resizeCallback = defineResizeCallback((entries) => {
|
|
||||||
const entry = entries[0]
|
|
||||||
globalContainerSize.value[containerName] = entry.contentRect.width
|
|
||||||
})
|
|
||||||
const observer = new ResizeObserver(resizeCallback)
|
|
||||||
observer.observe(el)
|
|
||||||
el['_containerObserver'] = observer
|
|
||||||
},
|
|
||||||
unmounted: (el) => {
|
|
||||||
const observer = el['_containerObserver']
|
|
||||||
observer.disconnect()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const rem = parseFloat(getComputedStyle(document.documentElement).fontSize)
|
const rem = parseFloat(getComputedStyle(document.documentElement).fontSize)
|
||||||
|
|
||||||
export const useContainerQueries = (containerName?: symbol) => {
|
const containerKey = Symbol('container') as InjectionKey<
|
||||||
const parentContainer = inject(containerNameKey, Symbol('unknown'))
|
Ref<HTMLElement | null>
|
||||||
|
>
|
||||||
|
|
||||||
const name = containerName ?? parentContainer
|
export const useContainerQueries = (
|
||||||
|
el?: HTMLElement | null | Ref<HTMLElement | null>,
|
||||||
|
) => {
|
||||||
|
const container = inject(containerKey, el ? toRef(el) : toRef(document.body))
|
||||||
|
|
||||||
provide(containerNameKey, name)
|
provide(containerKey, container)
|
||||||
|
|
||||||
const currentContainerSize = computed(() => {
|
const { width } = useContainerResize(container)
|
||||||
return globalContainerSize.value[name] ?? 0
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param size unit rem
|
* @param size unit rem
|
||||||
*/
|
*/
|
||||||
const generator = (size: number) => {
|
const generator = (size: number) => {
|
||||||
return (content: any, defaultContent: any = undefined) => {
|
return (content: any, defaultContent: any = undefined) => {
|
||||||
return currentContainerSize.value > size * rem ? content : defaultContent
|
return width.value > size * rem ? content : defaultContent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,5 @@
|
|||||||
import { throttle } from 'lodash'
|
import { throttle } from 'lodash'
|
||||||
import { Directive } from 'vue'
|
import { type Ref, onUnmounted, ref, toRef, watch } from 'vue'
|
||||||
|
|
||||||
export const resizeDirective: Directive<HTMLElement, ResizeObserverCallback> = {
|
|
||||||
mounted: (el, binding) => {
|
|
||||||
const callback = binding.value ?? (() => {})
|
|
||||||
const observer = new ResizeObserver(callback)
|
|
||||||
observer.observe(el)
|
|
||||||
el['observer'] = observer
|
|
||||||
},
|
|
||||||
unmounted: (el) => {
|
|
||||||
const observer = el['observer']
|
|
||||||
observer.disconnect()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export const defineResizeCallback = (
|
export const defineResizeCallback = (
|
||||||
callback: ResizeObserverCallback,
|
callback: ResizeObserverCallback,
|
||||||
@@ -20,3 +7,45 @@ export const defineResizeCallback = (
|
|||||||
) => {
|
) => {
|
||||||
return throttle(callback, wait ?? 100)
|
return throttle(callback, wait ?? 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useContainerResize = (
|
||||||
|
el: HTMLElement | null | Ref<HTMLElement | null>,
|
||||||
|
) => {
|
||||||
|
const observer = ref<ResizeObserver | null>(null)
|
||||||
|
|
||||||
|
const width = ref(0)
|
||||||
|
const height = ref(0)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
toRef(el),
|
||||||
|
(el) => {
|
||||||
|
if (el) {
|
||||||
|
const onResize = defineResizeCallback((entries) => {
|
||||||
|
const entry = entries[0]
|
||||||
|
width.value = entry.contentRect.width
|
||||||
|
height.value = entry.contentRect.height
|
||||||
|
})
|
||||||
|
|
||||||
|
observer.value = new ResizeObserver(onResize)
|
||||||
|
observer.value.observe(el)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
const stop = () => {
|
||||||
|
if (observer.value) {
|
||||||
|
observer.value.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
stop()
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
stop,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
58
src/hooks/scroll.ts
Normal file
58
src/hooks/scroll.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { throttle } from 'lodash'
|
||||||
|
import { computed, onUnmounted, ref, toRef, watch, type Ref } from 'vue'
|
||||||
|
|
||||||
|
export interface UseScrollOption {
|
||||||
|
throttle?: number
|
||||||
|
onScroll?: (e: Event) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useContainerScroll = (
|
||||||
|
el: HTMLElement | null | Ref<HTMLElement | null>,
|
||||||
|
options?: UseScrollOption,
|
||||||
|
) => {
|
||||||
|
const scrollLeft = ref(0)
|
||||||
|
const scrollTop = ref(0)
|
||||||
|
|
||||||
|
const container = toRef(el)
|
||||||
|
|
||||||
|
const onScroll = throttle((e: Event) => {
|
||||||
|
options?.onScroll?.(e)
|
||||||
|
|
||||||
|
if (container.value) {
|
||||||
|
scrollLeft.value = container.value.scrollLeft
|
||||||
|
scrollTop.value = container.value.scrollTop
|
||||||
|
}
|
||||||
|
}, options?.throttle || 100)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
container,
|
||||||
|
(el) => {
|
||||||
|
if (el) {
|
||||||
|
el.addEventListener('scroll', onScroll)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
const x = computed({
|
||||||
|
get: () => scrollLeft,
|
||||||
|
set: (val) => {
|
||||||
|
container.value?.scrollTo({ left: val.value })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const y = computed({
|
||||||
|
get: () => scrollTop,
|
||||||
|
set: (val) => {
|
||||||
|
container.value?.scrollTo({ top: val.value })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (container.value) {
|
||||||
|
container.value.removeEventListener('scroll', onScroll)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return { x, y }
|
||||||
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import { definePreset } from '@primevue/themes'
|
import { definePreset } from '@primevue/themes'
|
||||||
import Aura from '@primevue/themes/aura'
|
import Aura from '@primevue/themes/aura'
|
||||||
import { containerDirective } from 'hooks/container'
|
|
||||||
import { resizeDirective } from 'hooks/resize'
|
|
||||||
import PrimeVue from 'primevue/config'
|
import PrimeVue from 'primevue/config'
|
||||||
import ConfirmationService from 'primevue/confirmationservice'
|
import ConfirmationService from 'primevue/confirmationservice'
|
||||||
import ToastService from 'primevue/toastservice'
|
import ToastService from 'primevue/toastservice'
|
||||||
@@ -21,8 +19,6 @@ const ComfyUIPreset = definePreset(Aura, {
|
|||||||
function createVueApp(rootContainer: string | HTMLElement) {
|
function createVueApp(rootContainer: string | HTMLElement) {
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.directive('tooltip', Tooltip)
|
app.directive('tooltip', Tooltip)
|
||||||
app.directive('resize', resizeDirective)
|
|
||||||
app.directive('container', containerDirective)
|
|
||||||
app
|
app
|
||||||
.use(PrimeVue, {
|
.use(PrimeVue, {
|
||||||
theme: {
|
theme: {
|
||||||
|
|||||||
7
src/types/shims.d.ts
vendored
7
src/types/shims.d.ts
vendored
@@ -1,12 +1,5 @@
|
|||||||
export {}
|
export {}
|
||||||
|
|
||||||
declare module 'vue' {
|
|
||||||
interface ComponentCustomProperties {
|
|
||||||
vResize: (typeof import('hooks/resize'))['resizeDirective']
|
|
||||||
vContainer: (typeof import('hooks/container'))['containerDirective']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'hooks/store' {
|
declare module 'hooks/store' {
|
||||||
interface StoreProvider {}
|
interface StoreProvider {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user