schlechtenburg/packages/core/lib/components/Block.tsx

120 lines
3.2 KiB
TypeScript
Raw Normal View History

2020-05-24 15:33:25 +00:00
import {
defineComponent,
2020-12-27 21:32:43 +00:00
computed,
2020-05-28 20:16:35 +00:00
watch,
2020-05-24 15:33:25 +00:00
PropType,
2020-05-28 20:16:35 +00:00
ref,
Ref,
2020-12-27 21:32:43 +00:00
} from 'vue';
2020-12-30 13:34:23 +00:00
import { Block } from '../blocks';
import { SbMode } from '../mode';
import { useResizeObserver, BlockDimensions } from '../use-resize-observer';
import { useActivation } from '../use-activation';
import { useDynamicBlocks } from '../use-dynamic-blocks';
2020-05-20 14:21:08 +00:00
2020-12-30 13:34:23 +00:00
import { SbBlockOrdering } from './BlockOrdering';
2020-12-30 20:17:34 +00:00
import SbMissingBlock from './BlockMissing/index';
2020-05-27 18:59:20 +00:00
2020-05-20 14:21:08 +00:00
import './Block.scss';
2020-05-27 15:06:14 +00:00
interface BlockProps {
block: Block;
2021-02-22 18:13:37 +00:00
onUpdate: (b?: Block) => void;
onPrependBlock: (b?: Block) => void;
onAppendBlock: (b?: Block) => void;
onRemoveSelf: () => void;
onMoveBackward: () => void;
onMoveForward: () => void;
onActivateNext: () => void;
onActivatePrevious: () => void;
2020-05-28 20:16:35 +00:00
sortable: string;
2020-05-27 15:06:14 +00:00
}
2020-12-30 13:34:23 +00:00
export const SbBlock = defineComponent({
2020-05-20 14:21:08 +00:00
name: 'sb-block',
props: {
2020-05-27 15:06:14 +00:00
block: {
type: (null as unknown) as PropType<Block>,
required: true,
2020-05-27 13:57:57 +00:00
},
2020-05-28 20:16:35 +00:00
sortable: {
type: String,
default: null,
},
2021-02-22 18:13:37 +00:00
onUpdate: { type: Function, default: () => {} },
onPrependBlock: { type: Function, default: () => {} },
onAppendBlock: { type: Function, default: () => {} },
onRemoveSelf: { type: Function, default: () => {} },
onMoveBackward: { type: Function, default: () => {} },
onMoveForward: { type: Function, default: () => {} },
2020-05-20 14:21:08 +00:00
},
2020-05-27 15:06:14 +00:00
setup(props: BlockProps, context) {
2020-05-28 20:16:35 +00:00
const el: Ref<null|HTMLElement> = ref(null);
2020-05-27 15:32:35 +00:00
const { mode, getBlock } = useDynamicBlocks();
2020-05-28 20:16:35 +00:00
const { isActive, activate } = useActivation(props.block.blockId);
2020-05-20 14:21:08 +00:00
const classes = computed(() => ({
'sb-block': true,
2020-05-24 20:39:14 +00:00
'sb-block_active': isActive.value,
2020-05-20 14:21:08 +00:00
}));
2020-05-28 20:16:35 +00:00
const { triggerSizeCalculation } = useResizeObserver(el, BlockDimensions);
watch(() => props.block.data, triggerSizeCalculation);
const onChildUpdate = (updated: {[key: string]: any}) => {
2021-02-22 18:13:37 +00:00
props.onUpdate({
2020-05-28 20:16:35 +00:00
...props.block,
data: {
...props.block.data,
...updated,
},
});
};
2020-12-30 20:17:34 +00:00
return () => {
const BlockComponent = getBlock(props.block.name) as any;
if (!BlockComponent) {
const MissingBlock = SbMissingBlock[mode.value];
return <MissingBlock
name={props.block.name}
blockId={props.block.blockId}
/>;
}
if (mode.value === SbMode.Display) {
return () => (
<BlockComponent
data={props.block.data}
blockId={props.block.blockId}
/>
);
}
return <div
ref={el}
class={classes.value}
>
<div class="sb-block__edit-cover"></div>
{context.slots['context-toolbar'] ? context.slots['context-toolbar']() : null}
<BlockComponent
data={props.block.data}
blockId={props.block.blockId}
2021-02-22 18:13:37 +00:00
onUpdate={onChildUpdate}
onPrependBlock={props.onPrependBlock}
onAppendBlock={props.onAppendBlock}
onRemoveSelf={props.onRemoveSelf}
onActivatePrevious={props.onActivatePrevious}
onActivateNext={props.onActivateNext}
2020-12-30 20:17:34 +00:00
onClick={($event: MouseEvent) => {
$event.stopPropagation();
activate();
}}
{...context.attrs}
/>
</div>;
};
2020-05-20 14:21:08 +00:00
},
});