schlechtenburg/packages/core/lib/rich-text/RichText.tsx

70 lines
1.4 KiB
TypeScript

import {
ref,
Ref,
h,
defineComponent,
onMounted,
onBeforeUnmount,
PropType,
computed,
watchEffect,
} from 'vue';
import { useFormattingToolbar } from './use-formatting-toolbar';
export const SbRichText = defineComponent({
name: 'sb-rich-text',
props: {
inputRef: {
type: (null as unknown) as PropType<Ref<HTMLElement|null>>,
default: ref(null),
},
tag: { type: String, default: 'p' },
value: { type: String, default: '' },
onValueChange: {
type: (null as unknown) as PropType<(value: string) => void>,
default: (_:string) => {},
},
},
setup(props) {
const {
registerClient,
unregisterClient,
} = useFormattingToolbar();
const onKeydown = (event: KeyboardEvent) => {
if (['Delete', 'Backspace'].indexOf(event.key) < 0) {
return;
}
if (props.inputRef.value?.textContent === '') {
props.inputRef.value.innerHTML = '';
}
};
onMounted(() => {
registerClient(props.inputRef.value!);
});
onBeforeUnmount(() => {
unregisterClient(props.inputRef.value!);
});
return () => h(
props.tag,
{
class: 'sb-contenteditable',
contenteditable: 'true',
ref: props.inputRef,
onKeydown,
onInput: () => {
props.onValueChange(props.inputRef.value?.innerHTML || '');
},
},
);
},
});