schlechtenburg/src/components/user/Paragraph/edit.tsx

147 lines
2.9 KiB
TypeScript
Raw Normal View History

2020-05-20 14:21:08 +00:00
import {
defineComponent,
reactive,
2020-05-24 20:39:14 +00:00
computed,
2020-05-20 14:21:08 +00:00
ref,
2020-05-24 15:33:25 +00:00
Ref,
2020-05-20 14:21:08 +00:00
onMounted,
2020-05-24 15:33:25 +00:00
watch,
2020-05-24 20:00:14 +00:00
PropType,
2020-05-20 14:21:08 +00:00
} from '@vue/composition-api';
import {
model,
2020-05-24 15:33:25 +00:00
blockProps,
useActivation,
2020-05-20 14:21:08 +00:00
} from '@components/TreeElement';
2020-05-25 18:07:34 +00:00
import SbToolbar from '@internal/Toolbar';
2020-05-24 20:00:14 +00:00
import {
getDefaultData,
ParagraphData,
ParagraphProps,
2020-05-24 20:39:14 +00:00
} from './util';
2020-05-24 20:00:14 +00:00
import './style.scss';
2020-05-20 14:21:08 +00:00
export default defineComponent({
2020-05-24 20:00:14 +00:00
name: 'sb-paragraph-edit',
2020-05-20 14:21:08 +00:00
model,
props: {
2020-05-24 15:33:25 +00:00
...blockProps,
2020-05-24 20:00:14 +00:00
data: {
type: (null as unknown) as PropType<ParagraphData>,
default: getDefaultData,
},
2020-05-20 14:21:08 +00:00
},
2020-05-24 20:00:14 +00:00
setup(props: ParagraphProps, context) {
2020-05-24 15:33:25 +00:00
const localData = reactive({
value: props.data.value,
2020-05-24 20:39:14 +00:00
align: props.data.align,
2020-05-24 15:33:25 +00:00
focused: false,
});
2020-05-24 20:39:14 +00:00
console.log(localData);
2020-05-24 15:33:25 +00:00
const inputEl: Ref<null|HTMLElement> = ref(null);
const { isActive, activate } = useActivation(props.blockId);
onMounted(() => {
if (inputEl.value) {
inputEl.value.innerHTML = localData.value;
2020-05-24 20:39:14 +00:00
if (isActive.value) {
2020-05-24 15:33:25 +00:00
inputEl.value.focus();
}
}
});
watch(() => props.data, () => {
2020-05-24 20:39:14 +00:00
console.log('props update paragraph');
2020-05-24 15:33:25 +00:00
localData.value = props.data.value;
2020-05-24 20:39:14 +00:00
localData.align = props.data.align;
2020-05-24 15:33:25 +00:00
if (inputEl.value) {
inputEl.value.innerHTML = localData.value;
}
});
2020-05-20 14:21:08 +00:00
const onTextUpdate = ($event: InputEvent) => {
2020-05-24 15:33:25 +00:00
localData.value = $event.target.innerHTML;
2020-05-20 14:21:08 +00:00
};
2020-05-24 20:39:14 +00:00
const classes = computed(() => ({
2020-05-20 14:21:08 +00:00
'sb-paragraph': true,
2020-05-24 15:33:25 +00:00
'sb-paragraph_focused': localData.focused,
2020-05-24 20:39:14 +00:00
[`sb-paragraph_align-${localData.align}`]: true,
}));
2020-05-20 14:21:08 +00:00
const onFocus = () => {
2020-05-24 15:33:25 +00:00
localData.focused = true;
2020-05-20 14:21:08 +00:00
};
2020-05-24 15:33:25 +00:00
2020-05-20 14:21:08 +00:00
const onBlur = () => {
2020-05-24 15:33:25 +00:00
localData.focused = false;
context.emit('update', {
value: localData.value,
2020-05-20 14:21:08 +00:00
});
2020-05-24 15:33:25 +00:00
activate(null);
2020-05-20 14:21:08 +00:00
};
2020-05-24 15:33:25 +00:00
const onKeypress = ($event: KeyboardEvent) => {
if ($event.key === 'Enter') {
const blockId = +(new Date());
context.emit('insert-block', {
blockId,
name: 'sb-paragraph',
2020-05-24 20:00:14 +00:00
data: getDefaultData(),
2020-05-24 15:33:25 +00:00
});
2020-05-20 14:21:08 +00:00
2020-05-24 15:33:25 +00:00
activate(blockId);
$event.preventDefault();
}
};
2020-05-20 14:21:08 +00:00
return {
classes,
2020-05-24 15:33:25 +00:00
localData,
2020-05-20 14:21:08 +00:00
onTextUpdate,
onFocus,
onBlur,
2020-05-24 15:33:25 +00:00
onKeypress,
2020-05-20 14:21:08 +00:00
inputEl,
};
},
render() {
return (
2020-05-24 15:33:25 +00:00
<div class="sb-paragraph">
2020-05-24 20:39:14 +00:00
<SbToolbar>
<select vModel={this.localData.align}>
<option>left</option>
<option>center</option>
<option>right</option>
</select>
</SbToolbar>
2020-05-20 14:21:08 +00:00
<p
class={this.classes}
ref="inputEl"
contenteditable
{...{
on: {
input: this.onTextUpdate,
focus: this.onFocus,
blur: this.onBlur,
2020-05-24 15:33:25 +00:00
keypress: this.onKeypress,
2020-05-20 14:21:08 +00:00
},
}}
></p>
2020-05-24 15:33:25 +00:00
</div>
2020-05-20 14:21:08 +00:00
);
},
});