soiz1's picture
Upload folder using huggingface_hub
4d70170 verified
raw
history blame
2.56 kB
<script lang="ts">
import {
computed,
defineComponent,
nextTick,
onMounted,
provide,
ref,
useSlots,
watch,
} from 'vue'
export default defineComponent({
props: {
indicator: {
type: Boolean,
default: false,
},
modelValue: {
type: [String, Object],
default: '',
},
},
emits: ['update:modelValue'],
setup(props, { emit }) {
const indicatorStyle = ref<null | {
top: number
left: number
width: number
height: number
}>(null)
const model = computed({
get: () => props.modelValue,
set: value => emit('update:modelValue', value),
})
provide('VueGroup', {
data: model,
setValue: value => (model.value = value),
})
const root = ref<null | HTMLElement>(null)
const updateIndicator = async () => {
await nextTick()
const el = root.value?.querySelector('.selected') as HTMLElement
if (!el) {
indicatorStyle.value = null
return
}
const offset = {
top: el.offsetTop,
left: el.offsetLeft,
width: el.offsetWidth,
height: el.offsetHeight,
}
let parent = el.offsetParent as HTMLElement
while (parent && parent !== root.value) {
offset.top += parent.offsetTop
offset.left += parent.offsetLeft
parent = parent.offsetParent as HTMLElement
}
indicatorStyle.value = offset
}
watch(
() => model.value,
(value, oldValue) => {
if (value !== oldValue) {
updateIndicator()
}
},
)
const slot = useSlots()
watch(
() => slot.length,
() => {
updateIndicator()
},
)
onMounted(() => {
updateIndicator()
})
return {
root,
indicatorStyle,
updateIndicator,
}
},
})
</script>
<template>
<div
ref="root"
class="vue-ui-group"
:class="{
'has-indicator': indicator,
}"
>
<div class="content-wrapper">
<div class="content">
<slot />
</div>
<resize-observer
v-if="indicator"
@notify="updateIndicator()"
/>
</div>
<div
v-if="indicator && indicatorStyle"
class="indicator"
:style="{
top: `${indicatorStyle.top}px`,
left: `${indicatorStyle.left}px`,
width: `${indicatorStyle.width}px`,
height: `${indicatorStyle.height}px`,
}"
>
<div class="content">
<slot name="indicator" />
</div>
</div>
</div>
</template>