Saner activation strategy

This commit is contained in:
Benjamin Bädorf 2020-05-24 22:39:14 +02:00
parent 50a9606e86
commit 6ef1a3b172
No known key found for this signature in database
GPG key ID: 4406E80E13CD656C
7 changed files with 50 additions and 17 deletions

View file

@ -54,9 +54,17 @@ export function useActivation(currentBlockId: string|number) {
const activate = (blockId?: string|number|null) => { const activate = (blockId?: string|number|null) => {
activeBlockId.value = blockId !== undefined ? blockId : currentBlockId; activeBlockId.value = blockId !== undefined ? blockId : currentBlockId;
}; };
const requestActivation = () => {
if (activeBlockId.value) {
return;
}
activate();
};
return { return {
isActive, isActive,
activate, activate,
requestActivation,
}; };
} }

View file

@ -10,12 +10,9 @@
pointer-events: none; pointer-events: none;
} }
&:focus, &_active {
&:hover {
outline: 1px solid var(--grey-2); outline: 1px solid var(--grey-2);
}
&:focus {
> .sb-toolbar { > .sb-toolbar {
opacity: 1; opacity: 1;
pointer-events: all; pointer-events: all;

View file

@ -20,11 +20,11 @@ export default defineComponent({
}, },
setup(props, context) { setup(props, context) {
const { isActive, activate } = useActivation(props.block.blockId); const { isActive, activate, requestActivation } = useActivation(props.block.blockId);
const { getBlock } = useDynamicBlocks(); const { getBlock } = useDynamicBlocks();
const classes = computed(() => ({ const classes = computed(() => ({
'sb-block': true, 'sb-block': true,
'sb-block_active': isActive, 'sb-block_active': isActive.value,
})); }));
const onChildUpdate = (updated: {[key: string]: any}) => { const onChildUpdate = (updated: {[key: string]: any}) => {
@ -41,8 +41,8 @@ export default defineComponent({
return { return {
getBlock, getBlock,
classes, classes,
activate,
onChildUpdate, onChildUpdate,
activate,
}; };
}, },
@ -50,6 +50,7 @@ export default defineComponent({
console.log('render block', this.block); console.log('render block', this.block);
const Block = this.getBlock(this.block.name).edit; const Block = this.getBlock(this.block.name).edit;
return <Block return <Block
class={this.classes}
data={this.block.data} data={this.block.data}
block-id={this.block.blockId} block-id={this.block.blockId}
{...{ {...{
@ -60,6 +61,12 @@ export default defineComponent({
'insert-block': (block: BlockDefinition) => this.$emit('insert-block', block), 'insert-block': (block: BlockDefinition) => this.$emit('insert-block', block),
'append-block': (block: BlockDefinition) => this.$emit('append-block', block), 'append-block': (block: BlockDefinition) => this.$emit('append-block', block),
}, },
nativeOn: {
click: ($event) => {
$event.stopPropagation();
this.activate();
},
},
}} }}
/>; />;
}, },

View file

@ -55,7 +55,6 @@ export default defineComponent({
const classes = computed(() => ({ const classes = computed(() => ({
'sb-layout': true, 'sb-layout': true,
'sb-layout_active': isActive,
[`sb-layout_${localData.orientation}`]: true, [`sb-layout_${localData.orientation}`]: true,
})); }));
@ -80,17 +79,16 @@ export default defineComponent({
}; };
const appendBlock = (block: BlockData) => { const appendBlock = (block: BlockData) => {
console.log('append block', block);
context.emit('update', { context.emit('update', {
children: [ children: [
...localData.children, ...localData.children,
block, block,
], ],
}); });
activate(block.blockId);
}; };
const insertBlock = (index: number, block: BlockData) => { const insertBlock = (index: number, block: BlockData) => {
console.log('insert block', index, block);
context.emit('update', { context.emit('update', {
children: [ children: [
...localData.children.slice(0, index + 1), ...localData.children.slice(0, index + 1),
@ -98,6 +96,7 @@ export default defineComponent({
...localData.children.slice(index + 1), ...localData.children.slice(index + 1),
], ],
}); });
activate(block.blockId);
}; };
return { return {

View file

@ -1,6 +1,7 @@
import { import {
defineComponent, defineComponent,
reactive, reactive,
computed,
ref, ref,
Ref, Ref,
onMounted, onMounted,
@ -17,7 +18,7 @@ import {
getDefaultData, getDefaultData,
ParagraphData, ParagraphData,
ParagraphProps, ParagraphProps,
} from './util.ts'; } from './util';
import SbToolbar from '@internal/Toolbar'; import SbToolbar from '@internal/Toolbar';
@ -39,9 +40,12 @@ export default defineComponent({
setup(props: ParagraphProps, context) { setup(props: ParagraphProps, context) {
const localData = reactive({ const localData = reactive({
value: props.data.value, value: props.data.value,
align: props.data.align,
focused: false, focused: false,
}); });
console.log(localData);
const inputEl: Ref<null|HTMLElement> = ref(null); const inputEl: Ref<null|HTMLElement> = ref(null);
const { isActive, activate } = useActivation(props.blockId); const { isActive, activate } = useActivation(props.blockId);
@ -50,14 +54,16 @@ export default defineComponent({
if (inputEl.value) { if (inputEl.value) {
inputEl.value.innerHTML = localData.value; inputEl.value.innerHTML = localData.value;
if (isActive) { if (isActive.value) {
inputEl.value.focus(); inputEl.value.focus();
} }
} }
}); });
watch(() => props.data, () => { watch(() => props.data, () => {
console.log('props update paragraph');
localData.value = props.data.value; localData.value = props.data.value;
localData.align = props.data.align;
if (inputEl.value) { if (inputEl.value) {
inputEl.value.innerHTML = localData.value; inputEl.value.innerHTML = localData.value;
} }
@ -67,10 +73,11 @@ export default defineComponent({
localData.value = $event.target.innerHTML; localData.value = $event.target.innerHTML;
}; };
const classes = reactive({ const classes = computed(() => ({
'sb-paragraph': true, 'sb-paragraph': true,
'sb-paragraph_focused': localData.focused, 'sb-paragraph_focused': localData.focused,
}); [`sb-paragraph_align-${localData.align}`]: true,
}));
const onFocus = () => { const onFocus = () => {
localData.focused = true; localData.focused = true;
@ -111,10 +118,15 @@ export default defineComponent({
}, },
render() { render() {
console.log('render paragraph');
return ( return (
<div class="sb-paragraph"> <div class="sb-paragraph">
<SbToolbar>Paragraph editing</SbToolbar> <SbToolbar>
<select vModel={this.localData.align}>
<option>left</option>
<option>center</option>
<option>right</option>
</select>
</SbToolbar>
<p <p
class={this.classes} class={this.classes}
ref="inputEl" ref="inputEl"

View file

@ -1,4 +1,10 @@
.sb-paragraph { .sb-paragraph {
display: block; display: block;
width: 100%; width: 100%;
&_align {
&-left { text-align: left; }
&-right { text-align: right; }
&-center { text-align: center; }
}
} }

View file

@ -2,10 +2,14 @@ import { BlockProps } from '@components/TreeElement';
export interface ParagraphData { export interface ParagraphData {
value: string; value: string;
align: string;
} }
export interface ParagraphProps extends BlockProps { export interface ParagraphProps extends BlockProps {
data: ParagraphData; data: ParagraphData;
} }
export const getDefaultData: () => ParagraphData = () => ({ value: '' }); export const getDefaultData: () => ParagraphData = () => ({
value: '',
align: 'left',
});