import { ref, Ref, h, defineComponent, onMounted, onBeforeUnmount, PropType, watchEffect, } from 'vue'; import { useInline } from '../inline'; export const SbContenteditable = defineComponent({ name: 'sb-contenteditable', props: { inputRef: { type: (null as unknown) as PropType>, default: ref(null), }, tag: { type: String, default: 'div' }, value: { type: String, default: '' }, onValueChange: { type: (null as unknown) as PropType<(value: string) => void>, default: (_:string) => {}, }, }, setup(props) { const { registerClient, unregisterClient, } = useInline(); const onKeyup = (event: KeyboardEvent) => { if (event.code !== 'Backspace' && event.code !== 'Delete') { return; } if (!props.inputRef.value) { return; } const textContent = props.inputRef.value.textContent; if (textContent === '') { props.inputRef.value.innerHTML = ''; } }; onMounted(() => { props.inputRef.value?.focus(); registerClient(props.inputRef.value!); }); watchEffect(() => { if (props.inputRef.value && props.inputRef.value.innerHTML != props.value) { props.inputRef.value.innerHTML = props.value; } }); onBeforeUnmount(() => { unregisterClient(props.inputRef.value!); }); return () => h(props.tag, { class: 'sb-contenteditable', contenteditable: 'true', ref: props.inputRef, onKeyup, onInput: () => { props.onValueChange(props.inputRef.value?.innerHTML || ''); }, }); }, });