1 line
6.3 KiB
Plaintext
1 line
6.3 KiB
Plaintext
|
{"version":3,"file":"edit.b0a76e09.js","sources":["../../packages/paragraph/lib/edit.tsx"],"sourcesContent":["import {\n defineComponent,\n reactive,\n computed,\n ref,\n Ref,\n onMounted,\n watch,\n PropType,\n} from 'vue';\nimport {\n model,\n useActivation,\n SbToolbar,\n SbSelect,\n} from '@schlechtenburg/core';\nimport {\n getDefaultData,\n ParagraphData,\n} from './util';\n\nimport './style.scss';\n\nexport default defineComponent({\n name: 'sb-paragraph-edit',\n\n model,\n\n props: {\n blockId: { type: String, required: true },\n data: {\n type: (null as unknown) as PropType<ParagraphData>,\n default: getDefaultData,\n },\n onUpdate: { type: Function, default: () => {} },\n onAppendBlock: { type: Function, default: () => {} },\n onRemoveSelf: { type: Function, default: () => {} },\n onActivateNext: { type: Function, default: () => {} },\n onActivatePrevious: { type: Function, default: () => {} },\n },\n\n setup(props) {\n const localData = (reactive({\n value: props.data.value,\n align: props.data.align,\n focused: false,\n }) as unknown) as {\n value: string;\n align: string;\n focused: boolean;\n };\n\n const inputEl: Ref<null|HTMLElement> = ref(null);\n\n const { isActive, activate } = useActivation(props.blockId);\n\n const focusInput = () => {\n if (inputEl.value && isActive.value) {\n inputEl.value.focus();\n }\n };\n\n onMounted(() => {\n focusInput();\n if (inputEl.value) {\n inputEl.value.innerHTML = localData.value;\n }\n });\n\n watch(isActive, focusInput);\n\n watch(() => props.data, () => {\n localData.value = props.data.value;\n localData.align = props.data.align;\n if (inputEl.value) {\n inputEl.value.innerHTML = localData.value;\n }\n });\n\n const onTextUpdate = ($event: Event) => {\n localData.value = ($event.target as HTMLElement).innerHTML;\n };\n\n const classes = computed(() => ({\n 'sb-paragraph': true,\n 'sb-paragraph_focused': localData.focused,\n [`sb-paragraph_align-${localData.align}`]: true,\n }));\n\n const setAlignment = ($event: Event) => {\n props.onUpdate({\n value: localData.value,\n align: ($event.target as HTMLSelectElement).value,\n });\n };\n\n const onFocus = () => {\n localData.focused = true;\n activate();\n };\n\n const onBlur = () => {\n localData.focused = false;\n props.onUpdate({\n value: localData.value,\n align: localData.align,\n });\n };\n\n const onKeydown = ($event: KeyboardEvent) => {\n if ($event.key === 'Enter' && !$event.shiftKey) {\n const id = `${+(new Date())}`;\n props.onAppendBlock({\n id,\n name: 'sb-paragraph',\n data: getDefaultData(),\n });\n\n activate(id);\n\n $event.preventDefault();\n }\n };\n\n const onKeyup = ($event: KeyboardEvent) => {\n if ($event.key === 'Backspace' && localData.value === '') {\n props.onRemoveSelf();\n }\n\n const selection = window.getSelection();\n const node = selection?.focusNode;\n const childNodes = Array.from(inputEl?.value?.childNodes || []);\n const index = node ? childNodes.indexOf(node as ChildNode) : -1;\n if (node === inputEl.value || index === 0 || index === childNodes.length -1) {\n switch ($event.key) {\n case 'ArrowDown':\n props.onActivateNext();\n break;\n case 'ArrowUp':\n props.onActivatePrevious();\n break;\n }\n }\n };\n\n return () => (\n <div class={classes.value}>\n <SbToolbar>\n <SbSelect\n {...{\n value: localData.align,\n onChange: setAlignment,\n }}\n >\n <option>left</option>\n <option>center</option>\n <option>right</option>\n </SbSelect>\n </SbToolbar>\n <p\n
|