import { useNamespace } from '@ibiz-template/vue-util'; import { defineComponent, onUnmounted, ref, watch } from 'vue'; import type { PropType } from 'vue'; import '@ibiz-template/theme/style/components/common/skeleton/skeleton-card/skeleton-card.scss'; export default defineComponent({ props: { active: { type: Boolean, default: false, }, round: { type: Boolean, default: false, }, loading: { type: Boolean, default: true, }, title: { type: Boolean, default: true, }, paragraph: { type: [Boolean, Object] as PropType<boolean | { rows: number }>, default: true, }, }, setup(props, { slots }) { const ns = useNamespace('skeleton-card'); const content = ref<HTMLElement | null>(null); const rows = ref<number>(2); watch( () => props.paragraph, value => { if (!(typeof value === 'boolean')) { rows.value = Math.floor(value.rows > 2 ? value.rows : 2); } }, ); const childHeight = 16; const childMarginBottom = 12; let observer: ResizeObserver | null = null; watch( content, () => { if (content.value && !observer && ResizeObserver) { observer = new ResizeObserver(entries => { if (typeof props.paragraph === 'boolean') { rows.value = Math.floor( (entries[0].contentRect.height + childMarginBottom) / (childHeight + childMarginBottom), ); } }); observer.observe(content.value); } else if (!content.value && observer) { observer.disconnect(); observer = null; } }, { immediate: true }, ); onUnmounted(() => { if (observer) { observer.disconnect(); observer = null; } }); return () => ( <div class={`${props.loading ? ns.b() : ''} ${ props.loading && props.active ? ns.m('active') : '' } ${props.loading && props.round ? ns.m('round') : ''}`.trim()} > {props.loading && props.title ? ( <header class={ns.b('header')}> <h3 class={ns.be('header', 'title')}></h3> </header> ) : null} {props.loading && props.paragraph ? ( <main class={ns.b('content')} ref={content as unknown as string}> {Array.from({ length: rows.value }).map((_value, i) => ( <div class={ns.be('content', 'item')} key={i}></div> ))} </main> ) : null} {typeof slots.default === 'function' && !props.loading ? slots.default() : null} </div> ); }, });