Improve Interface naming, fix deactivate on document click

This commit is contained in:
Benjamin Bädorf 2022-03-11 17:50:50 +01:00
parent 9289083a59
commit 01c2644a36
No known key found for this signature in database
GPG key ID: 4406E80E13CD656C
19 changed files with 93 additions and 71 deletions

View file

@ -6,7 +6,7 @@ import {
ref, ref,
Ref, Ref,
} from 'vue'; } from 'vue';
import { BlockData } from '../types'; import { IBlockData } from '../types';
import { SbMode } from '../mode'; import { SbMode } from '../mode';
import { useResizeObserver, SymBlockDimensions } from '../use-resize-observer'; import { useResizeObserver, SymBlockDimensions } from '../use-resize-observer';
import { useActivation } from '../use-activation'; import { useActivation } from '../use-activation';
@ -22,7 +22,7 @@ export const SbBlock = defineComponent({
props: { props: {
block: { block: {
type: (null as unknown) as PropType<BlockData<any>>, type: (null as unknown) as PropType<IBlockData<any>>,
required: true, required: true,
}, },
sortable: { sortable: {

View file

@ -4,7 +4,7 @@ import {
defineComponent, defineComponent,
} from 'vue'; } from 'vue';
import { useDynamicBlocks } from '../use-dynamic-blocks'; import { useDynamicBlocks } from '../use-dynamic-blocks';
import { BlockDefinition } from '../types'; import { IBlockDefinition } from '../types';
import { SbButton } from './Button'; import { SbButton } from './Button';
import { SbContextMenu } from './ContextMenu'; import { SbContextMenu } from './ContextMenu';
@ -19,11 +19,13 @@ export const SbBlockPicker = defineComponent({
}, },
setup(props, context) { setup(props, context) {
const open = ref(false);
const { customBlocks } = useDynamicBlocks(); const { customBlocks } = useDynamicBlocks();
const blockList = computed(() => Object.keys(customBlocks).map((key) => customBlocks[key])); const blockList = computed(() => Object.keys(customBlocks).map((key) => customBlocks[key]));
const selectBlock = (block: BlockDefinition<any>) => () => { const selectBlock = (block: IBlockDefinition<any>) => () => {
open.value = false; open.value = false;
props.onPickedBlock({ props.onPickedBlock({
name: block.name, name: block.name,
@ -40,7 +42,7 @@ export const SbBlockPicker = defineComponent({
context: (slotContext) => context.slots.context context: (slotContext) => context.slots.context
? context.slots.context(slotContext) ? context.slots.context(slotContext)
: <SbButton {...{ onClick: slotContext.toggle }}>Insert a block</SbButton>, : <SbButton {...{ onClick: slotContext.toggle }}>Insert a block</SbButton>,
default: ({ close }: { close: Function }) => blockList.value.map((block: BlockDefinition<any>) => ( default: ({ close }: { close: Function }) => blockList.value.map((block: IBlockDefinition<any>) => (
<SbButton <SbButton
{...{ {...{
type: 'button', type: 'button',

View file

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { BlockData } from '../types'; import { IBlockData } from '../types';
import { SbBlockPicker } from './BlockPicker'; import { SbBlockPicker } from './BlockPicker';
@ -16,7 +16,7 @@ export const SbBlockPlaceholder = defineComponent({
return () => ( return () => (
<div class="sb-block-placeholder"> <div class="sb-block-placeholder">
<SbBlockPicker <SbBlockPicker
onPickedBlock={(block: BlockData<any>) => props.onInsertBlock(block)} onPickedBlock={(block: IBlockData<any>) => props.onInsertBlock(block)}
/> />
</div> </div>
); );

View file

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { TreeNode } from '../types'; import { ITreeNode } from '../types';
import { useBlockTree } from '../use-block-tree'; import { useBlockTree } from '../use-block-tree';
import { useActivation } from '../use-activation'; import { useActivation } from '../use-activation';

View file

@ -2,7 +2,7 @@ import {
defineComponent, defineComponent,
PropType, PropType,
} from 'vue'; } from 'vue';
import { BlockData } from '../types'; import { IBlockData } from '../types';
import { SbTreeBlockSelect } from './TreeBlockSelect'; import { SbTreeBlockSelect } from './TreeBlockSelect';
import { SbGlobalInsert } from './GlobalInsert'; import { SbGlobalInsert } from './GlobalInsert';
@ -13,7 +13,7 @@ export const SbMainMenu = defineComponent({
props: { props: {
block: { block: {
type: (null as unknown) as PropType<BlockData<any>>, type: (null as unknown) as PropType<IBlockData<any>>,
required: true, required: true,
}, },
}, },

View file

@ -7,10 +7,10 @@ import {
Ref, Ref,
} from 'vue'; } from 'vue';
import { import {
BlockData, IBlockData,
BlockDefinition, IBlockDefinition,
BlockLibrary, IBlockLibrary,
TreeNode, ITreeNode,
} from '../types'; } from '../types';
import { model } from '../block-helpers'; import { model } from '../block-helpers';
import { Mode, SbMode } from '../mode'; import { Mode, SbMode } from '../mode';
@ -36,11 +36,11 @@ export const SbMain = defineComponent({
props: { props: {
customBlocks: { customBlocks: {
type: Array as PropType<BlockDefinition<any>[]>, type: Array as PropType<IBlockDefinition<any>[]>,
default: () => [], default: () => [],
}, },
block: { block: {
type: Object as PropType<BlockData<any>>, type: Object as PropType<IBlockData<any>>,
required: true, required: true,
}, },
onUpdate: { type: Function, default: () => {} }, onUpdate: { type: Function, default: () => {} },
@ -63,14 +63,14 @@ export const SbMain = defineComponent({
const activeBlock = ref(null); const activeBlock = ref(null);
provide(SymActiveBlock, activeBlock); provide(SymActiveBlock, activeBlock);
const blockTree: Ref<TreeNode|null> = ref(null); const blockTree: Ref<ITreeNode|null> = ref(null);
provide(SymBlockTree, blockTree); provide(SymBlockTree, blockTree);
provide(SymBlockTreeRegister, (block: TreeNode) => { blockTree.value = block; }); provide(SymBlockTreeRegister, (block: ITreeNode) => { blockTree.value = block; });
provide(SymBlockTreeUnregister, () => { blockTree.value = null; }); provide(SymBlockTreeUnregister, () => { blockTree.value = null; });
const blockLibrary: BlockLibrary = shallowReactive({ const blockLibrary: IBlockLibrary = shallowReactive({
...props.customBlocks.reduce( ...props.customBlocks.reduce(
(blocks: BlockLibrary, block: BlockDefinition<any>) => ({ ...blocks, [block.name]: block }), (blocks: IBlockLibrary, block: IBlockDefinition<any>) => ({ ...blocks, [block.name]: block }),
{}, {},
), ),
}); });

View file

@ -1,5 +1,5 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { TreeNode } from '../types'; import { ITreeNode } from '../types';
import { useBlockTree } from '../use-block-tree'; import { useBlockTree } from '../use-block-tree';
import { useActivation } from '../use-activation'; import { useActivation } from '../use-activation';
@ -18,7 +18,7 @@ export const SbTreeBlockSelect = defineComponent({
activeBlockId, activeBlockId,
} = useActivation(); } = useActivation();
const treeToHtml = (tree: TreeNode, close: Function) => <li const treeToHtml = (tree: ITreeNode, close: Function) => <li
class={{ class={{
'sb-tree-block-select__block': true, 'sb-tree-block-select__block': true,
'sb-tree-block-select__block_active': activeBlockId.value === tree.id, 'sb-tree-block-select__block_active': activeBlockId.value === tree.id,
@ -34,7 +34,7 @@ export const SbTreeBlockSelect = defineComponent({
>{tree.name}</button> >{tree.name}</button>
{tree.children?.length {tree.children?.length
? <ul class="sb-tree-block-select__list"> ? <ul class="sb-tree-block-select__list">
{tree.children?.map((child: TreeNode) => treeToHtml(child, close))} {tree.children?.map((child: ITreeNode) => treeToHtml(child, close))}
</ul> </ul>
: null : null
} }
@ -48,7 +48,7 @@ export const SbTreeBlockSelect = defineComponent({
context: ({ toggle }: { toggle: Function }) => <SbButton {...{ onClick: toggle }}>Tree</SbButton>, context: ({ toggle }: { toggle: Function }) => <SbButton {...{ onClick: toggle }}>Tree</SbButton>,
default: ({ close }: { close: Function }) => <ul default: ({ close }: { close: Function }) => <ul
class="sb-tree-block-select__list sb-tree-block-select__list_base" class="sb-tree-block-select__list sb-tree-block-select__list_base"
>{treeToHtml(blockTree.value as TreeNode, close)}</ul>, >{treeToHtml(blockTree.value as ITreeNode, close)}</ul>,
}} }}
/> />
: '' : ''

View file

@ -1,37 +1,37 @@
import { Component } from 'vue'; import { Component } from 'vue';
export interface TreeNode { export interface ITreeNode {
id: string; id: string;
name: string; name: string;
icon?: string; icon?: string;
children: TreeNode[]; children: ITreeNode[];
} }
export interface BlockData<T> { export interface IBlockData<T> {
id: string; id: string;
name: string; name: string;
data: T; data: T;
} }
export interface BlockProps<T> { export interface IBlockProps<T> {
blockId: string; blockId: string;
data?: T, data?: T,
onUpdate?: (b?: BlockData<T>) => void; onUpdate?: (b?: IBlockData<T>) => void;
onPrependBlock?: (b?: BlockData<T>) => void; onPrependBlock?: (b?: IBlockData<T>) => void;
onAppendBlock?: (b?: BlockData<T>) => void; onAppendBlock?: (b?: IBlockData<T>) => void;
onRemoveSelf?: () => void; onRemoveSelf?: () => void;
onActivateNext?: () => void; onActivateNext?: () => void;
onActivatePrevious?: () => void; onActivatePrevious?: () => void;
} }
export interface BlockDefinition<T> { export interface IBlockDefinition<T> {
name: string; name: string;
icon?: string; icon?: string;
getDefaultData: T; getDefaultData: T;
edit: Component<BlockProps<T>>; edit: Component<IBlockProps<T>>;
display: Component<BlockProps<T>>; display: Component<IBlockProps<T>>;
} }
export interface BlockLibrary { export interface IBlockLibrary {
[name: string]: BlockDefinition<any>; [name: string]: IBlockDefinition<any>;
} }

View file

@ -3,15 +3,34 @@ import {
ref, ref,
inject, inject,
computed, computed,
onBeforeUnmount,
} from 'vue'; } from 'vue';
export const SymActiveBlock = Symbol('Schlechtenburg active block'); export const SymActiveBlock = Symbol('Schlechtenburg active block');
export function useActivation(currentBlockId: string|null = null) { export function useActivation(currentBlockId: string|null = null) {
const activeBlockId: Ref<string|null> = inject(SymActiveBlock, ref(null)); const activeBlockId: Ref<string|null> = inject(SymActiveBlock, ref(null));
const isActive = computed(() => activeBlockId.value === currentBlockId); const isActive = computed(() => activeBlockId.value === currentBlockId);
const activate = (id?: string|null) => {
activeBlockId.value = id !== undefined ? id : currentBlockId; const deactivate = (id: string|null = currentBlockId) => {
if (activeBlockId.value !== id) {
return;
}
activeBlockId.value = null;
}; };
const deactivateCb = (_:Event) => deactivate();
onBeforeUnmount(() => {
document.removeEventListener('click', deactivateCb);
})
const activate = (id: string|null = currentBlockId) => {
document.addEventListener('click', deactivateCb, { once: true });
activeBlockId.value = id;
};
const requestActivation = () => { const requestActivation = () => {
if (activeBlockId.value) { if (activeBlockId.value) {
return; return;
@ -24,6 +43,7 @@ export function useActivation(currentBlockId: string|null = null) {
activeBlockId, activeBlockId,
isActive, isActive,
activate, activate,
deactivate,
requestActivation, requestActivation,
}; };
} }

View file

@ -7,8 +7,8 @@ import {
onUnmounted, onUnmounted,
} from 'vue'; } from 'vue';
import { import {
TreeNode, ITreeNode,
BlockData, IBlockData,
} from './types'; } from './types';
export const SymBlockTree= Symbol('Schlechtenburg block tree'); export const SymBlockTree= Symbol('Schlechtenburg block tree');
@ -16,11 +16,11 @@ export const SymBlockTreeRegister = Symbol('Schlechtenburg block tree register')
export const SymBlockTreeUnregister = Symbol('Schlechtenburg block tree unregister'); export const SymBlockTreeUnregister = Symbol('Schlechtenburg block tree unregister');
export function useBlockTree() { export function useBlockTree() {
const blockTree: Ref<TreeNode|null> = inject(SymBlockTree, ref(null)); const blockTree: Ref<ITreeNode|null> = inject(SymBlockTree, ref(null));
const registerWithParent = inject(SymBlockTreeRegister, (_: TreeNode) => {}); const registerWithParent = inject(SymBlockTreeRegister, (_: ITreeNode) => {});
const unregisterWithParent = inject(SymBlockTreeUnregister, (_: TreeNode) => {}); const unregisterWithParent = inject(SymBlockTreeUnregister, (_: ITreeNode) => {});
const self: TreeNode = reactive({ const self: ITreeNode = reactive({
id: '', id: '',
name: '', name: '',
icon: '', icon: '',
@ -28,8 +28,8 @@ export function useBlockTree() {
}); });
// Provide a registration function to child blocks // Provide a registration function to child blocks
provide(SymBlockTreeRegister, (block: TreeNode) => { provide(SymBlockTreeRegister, (block: ITreeNode) => {
if (self.children.find((child: TreeNode) => child.id === block.id)) { if (self.children.find((child: ITreeNode) => child.id === block.id)) {
return; return;
} }
@ -40,11 +40,11 @@ export function useBlockTree() {
}); });
// Provide an unregistration function to child blocks // Provide an unregistration function to child blocks
provide(SymBlockTreeUnregister, ({ id }: TreeNode) => { provide(SymBlockTreeUnregister, ({ id }: ITreeNode) => {
self.children = self.children.filter((child: TreeNode) => child.id !== id); self.children = self.children.filter((child: ITreeNode) => child.id !== id);
}); });
const register = (block: BlockData<any>) => { const register = (block: IBlockData<any>) => {
if (!block.id) { if (!block.id) {
throw new Error(`Cannot register a block without an id: ${JSON.stringify(block)}`); throw new Error(`Cannot register a block without an id: ${JSON.stringify(block)}`);
} }

View file

@ -3,13 +3,13 @@ import {
inject, inject,
reactive, reactive,
} from 'vue'; } from 'vue';
import { BlockLibrary } from './types'; import { IBlockLibrary } from './types';
import { Mode, SbMode } from './mode'; import { Mode, SbMode } from './mode';
export const SymBlockLibrary = Symbol('Schlechtenburg block library'); export const SymBlockLibrary = Symbol('Schlechtenburg block library');
export function useDynamicBlocks() { export function useDynamicBlocks() {
const mode = inject(Mode, ref(SbMode.Edit)); const mode = inject(Mode, ref(SbMode.Edit));
const customBlocks: BlockLibrary = inject(SymBlockLibrary, reactive({})); const customBlocks: IBlockLibrary = inject(SymBlockLibrary, reactive({}));
const getBlock = (name: string) => customBlocks[name]; const getBlock = (name: string) => customBlocks[name];
return { return {

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"file":"edit.a95f3ab1.js","sources":["../../../image/lib/edit.tsx"],"sourcesContent":["import {\n defineComponent,\n reactive,\n ref,\n Ref,\n watch,\n PropType,\n} from 'vue';\nimport {\n model,\n SbToolbar,\n SbButton,\n SbBlock,\n BlockData,\n} from '@schlechtenburg/core';\nimport { ParagraphData } from '@schlechtenburg/paragraph';\nimport {\n getDefaultData,\n ImageData,\n} from './util';\n\nimport './style.scss';\n\nexport default defineComponent({\n name: 'sb-image-edit',\n\n model,\n\n props: {\n onUpdate: { type: Function, default: () => {} },\n data: {\n type: (null as unknown) as PropType<ImageData>,\n default: getDefaultData,\n },\n },\n\n setup(props) {\n const localData = reactive({\n src: props.data.src,\n alt: props.data.alt,\n description: props.data.description,\n });\n\n const fileInput: Ref<null|HTMLInputElement> = ref(null);\n\n watch(() => props.data, () => {\n localData.src = props.data.src;\n localData.alt = props.data.alt;\n localData.description = props.data.description;\n });\n\n const selectImage = () => {\n if (fileInput.value) {\n fileInput.value.click();\n }\n };\n\n const onImageSelect = () => {\n if (fileInput.value && fileInput.value.files && fileInput.value.files.length) {\n const reader = new FileReader();\n reader.addEventListener('load', () => {\n const src = reader?.result?.toString();\n if (!src) {\n throw new Error('Couldn\\'t load image src');\n }\n\n props.onUpdate({\n src,\n alt: props.data.alt,\n description: props.data.description,\n });\n });\n\n reader.readAsDataURL(fileInput.value.files[0]);\n }\n };\n\n const onDescriptionUpdate = (description: BlockData<ParagraphData>) => {\n props.onUpdate({\n ...props.data,\n description,\n });\n };\n\n return () => (\n <figure class=\"sb-image\">\n <SbToolbar>\n {localData.src\n ? <SbButton {...{ onClick: selectImage }}>Select Image</SbButton>\n : null}\n <input\n type=\"file\"\n ref={fileInput}\n style=\"display: none;\"\n onInput={onImageSelect}\n />\n </SbToolbar>\n {localData.src\n ? <>\n <img\n src={localData.src}\n alt={localData.alt}\n class=\"sb-image__content\"\n />\n <SbBlock\n block={localData.description}\n onUpdate={(updated: BlockData<ParagraphData>) => onDescriptionUpdate(updated)}\n />\n </>\n : <SbButton {...{ onClick: selectImage }}>Select Image</SbButton>\n }\n </figure>\n );\n },\n});\n"],"names":["defineComponent","name","model","props","onUpdate","type","Function","default","data","getDefaultData","setup","localData","reactive","src","alt","description","fileInput","ref","selectImage","value","click","onImageSelect","files","length","reader","FileReader","addEventListener","result","toString","Error","readAsDataURL","onClick","onDescriptionUpdate","updated","__assign"],"mappings":"8dAuBA,MAAeA,EAAgB,CAC7BC,KAAM,gBAENC,MAAAA,EAEAC,MAAO,CACLC,SAAU,CAAEC,KAAMC,SAAUC,QAAS,QACrCC,KAAM,CACJH,KAAO,KACPE,QAASE,IAIbC,MAAMP,SACEQ,EAAYC,EAAS,CACzBC,IAAKV,EAAMK,KAAKK,IAChBC,IAAKX,EAAMK,KAAKM,IAChBC,YAAaZ,EAAMK,KAAKO,cAGpBC,EAAwCC,EAAI,SAE5C,IAAMd,EAAMK,OAAM,OACZK,IAAMV,EAAMK,KAAKK,MACjBC,IAAMX,EAAMK,KAAKM,MACjBC,YAAcZ,EAAMK,KAAKO,qBAG/BG,EAAc,KACdF,EAAUG,SACFA,MAAMC,SAIdC,EAAgB,QAChBL,EAAUG,OAASH,EAAUG,MAAMG,OAASN,EAAUG,MAAMG,MAAMC,OAAQ,OACtEC,EAAS,IAAIC,aACZC,iBAAiB,QAAQ,iBACxBb,EAAMW,0BAAQG,iBAAQC,eACvBf,QACG,IAAIgB,MAAM,6BAGZzB,SAAS,CACbS,IAAAA,EACAC,IAAKX,EAAMK,KAAKM,IAChBC,YAAaZ,EAAMK,KAAKO,mBAIrBe,cAAcd,EAAUG,MAAMG,MAAM,YAWxC,sBACS,oCAETX,EAAUE,SACSkB,QAASb,sCACzB,qBAEG,WACAF,QACC,yBACGK,YAGZV,EAAUE,2BAGEF,EAAUE,QACVF,EAAUG,UACT,sCAGCH,EAAUI,yBACgCiB,SAAoBC,SA5BzE7B,SAAS8B,OACV/B,EAAMK,MADI,CAEbO,YAAAA,KAHyBA,qBAgCLgB,QAASb"} {"version":3,"file":"edit.a95f3ab1.js","sources":["../../../image/lib/edit.tsx"],"sourcesContent":["import {\n defineComponent,\n reactive,\n ref,\n Ref,\n watch,\n PropType,\n} from 'vue';\nimport {\n model,\n SbToolbar,\n SbButton,\n SbBlock,\n IBlockData,\n} from '@schlechtenburg/core';\nimport { ParagraphData } from '@schlechtenburg/paragraph';\nimport {\n getDefaultData,\n ImageData,\n} from './util';\n\nimport './style.scss';\n\nexport default defineComponent({\n name: 'sb-image-edit',\n\n model,\n\n props: {\n onUpdate: { type: Function, default: () => {} },\n data: {\n type: (null as unknown) as PropType<ImageData>,\n default: getDefaultData,\n },\n },\n\n setup(props) {\n const localData = reactive({\n src: props.data.src,\n alt: props.data.alt,\n description: props.data.description,\n });\n\n const fileInput: Ref<null|HTMLInputElement> = ref(null);\n\n watch(() => props.data, () => {\n localData.src = props.data.src;\n localData.alt = props.data.alt;\n localData.description = props.data.description;\n });\n\n const selectImage = () => {\n if (fileInput.value) {\n fileInput.value.click();\n }\n };\n\n const onImageSelect = () => {\n if (fileInput.value && fileInput.value.files && fileInput.value.files.length) {\n const reader = new FileReader();\n reader.addEventListener('load', () => {\n const src = reader?.result?.toString();\n if (!src) {\n throw new Error('Couldn\\'t load image src');\n }\n\n props.onUpdate({\n src,\n alt: props.data.alt,\n description: props.data.description,\n });\n });\n\n reader.readAsDataURL(fileInput.value.files[0]);\n }\n };\n\n const onDescriptionUpdate = (description: IBlockData<ParagraphData>) => {\n props.onUpdate({\n ...props.data,\n description,\n });\n };\n\n return () => (\n <figure class=\"sb-image\">\n <SbToolbar>\n {localData.src\n ? <SbButton {...{ onClick: selectImage }}>Select Image</SbButton>\n : null}\n <input\n type=\"file\"\n ref={fileInput}\n style=\"display: none;\"\n onInput={onImageSelect}\n />\n </SbToolbar>\n {localData.src\n ? <>\n <img\n src={localData.src}\n alt={localData.alt}\n class=\"sb-image__content\"\n />\n <SbBlock\n block={localData.description}\n onUpdate={(updated: IBlockData<ParagraphData>) => onDescriptionUpdate(updated)}\n />\n </>\n : <SbButton {...{ onClick: selectImage }}>Select Image</SbButton>\n }\n </figure>\n );\n },\n});\n"],"names":["defineComponent","name","model","props","onUpdate","type","Function","default","data","getDefaultData","setup","localData","reactive","src","alt","description","fileInput","ref","selectImage","value","click","onImageSelect","files","length","reader","FileReader","addEventListener","result","toString","Error","readAsDataURL","onClick","onDescriptionUpdate","updated","__assign"],"mappings":"8dAuBA,MAAeA,EAAgB,CAC7BC,KAAM,gBAENC,MAAAA,EAEAC,MAAO,CACLC,SAAU,CAAEC,KAAMC,SAAUC,QAAS,QACrCC,KAAM,CACJH,KAAO,KACPE,QAASE,IAIbC,MAAMP,SACEQ,EAAYC,EAAS,CACzBC,IAAKV,EAAMK,KAAKK,IAChBC,IAAKX,EAAMK,KAAKM,IAChBC,YAAaZ,EAAMK,KAAKO,cAGpBC,EAAwCC,EAAI,SAE5C,IAAMd,EAAMK,OAAM,OACZK,IAAMV,EAAMK,KAAKK,MACjBC,IAAMX,EAAMK,KAAKM,MACjBC,YAAcZ,EAAMK,KAAKO,qBAG/BG,EAAc,KACdF,EAAUG,SACFA,MAAMC,SAIdC,EAAgB,QAChBL,EAAUG,OAASH,EAAUG,MAAMG,OAASN,EAAUG,MAAMG,MAAMC,OAAQ,OACtEC,EAAS,IAAIC,aACZC,iBAAiB,QAAQ,iBACxBb,EAAMW,0BAAQG,iBAAQC,eACvBf,QACG,IAAIgB,MAAM,6BAGZzB,SAAS,CACbS,IAAAA,EACAC,IAAKX,EAAMK,KAAKM,IAChBC,YAAaZ,EAAMK,KAAKO,mBAIrBe,cAAcd,EAAUG,MAAMG,MAAM,YAWxC,sBACS,oCAETX,EAAUE,SACSkB,QAASb,sCACzB,qBAEG,WACAF,QACC,yBACGK,YAGZV,EAAUE,2BAGEF,EAAUE,QACVF,EAAUG,UACT,sCAGCH,EAAUI,yBACgCiB,SAAoBC,SA5BzE7B,SAAS8B,OACV/B,EAAMK,MADI,CAEbO,YAAAA,KAHyBA,qBAgCLgB,QAASb"}

File diff suppressed because one or more lines are too long

View file

@ -6,7 +6,7 @@ import {
ref, ref,
} from 'vue'; } from 'vue';
import { SbMain, BlockData, SbMode } from '@schlechtenburg/core'; import { SbMain, IBlockData, SbMode } from '@schlechtenburg/core';
import SbLayout from '@schlechtenburg/layout'; import SbLayout from '@schlechtenburg/layout';
import SbHeading from '@schlechtenburg/heading'; import SbHeading from '@schlechtenburg/heading';
@ -20,7 +20,7 @@ export default defineComponent({
setup() { setup() {
const activeTab = ref('edit'); const activeTab = ref('edit');
const block: BlockData<any> = reactive({ const block: IBlockData<any> = reactive({
name: 'none', name: 'none',
id: '0', id: '0',
data: null, data: null,
@ -39,7 +39,7 @@ export default defineComponent({
case SbMode.Edit: case SbMode.Edit:
return <SbMain return <SbMain
block={block} block={block}
onUpdate={(newBlock: BlockData<any>) => { onUpdate={(newBlock: IBlockData<any>) => {
block.data = newBlock.data; block.data = newBlock.data;
}} }}
customBlocks={[ customBlocks={[

View file

@ -11,7 +11,7 @@ import {
SbToolbar, SbToolbar,
SbButton, SbButton,
SbBlock, SbBlock,
BlockData, IBlockData,
} from '@schlechtenburg/core'; } from '@schlechtenburg/core';
import { ParagraphData } from '@schlechtenburg/paragraph'; import { ParagraphData } from '@schlechtenburg/paragraph';
import { import {
@ -75,7 +75,7 @@ export default defineComponent({
} }
}; };
const onDescriptionUpdate = (description: BlockData<ParagraphData>) => { const onDescriptionUpdate = (description: IBlockData<ParagraphData>) => {
props.onUpdate({ props.onUpdate({
...props.data, ...props.data,
description, description,
@ -104,7 +104,7 @@ export default defineComponent({
/> />
<SbBlock <SbBlock
block={localData.description} block={localData.description}
onUpdate={(updated: BlockData<ParagraphData>) => onDescriptionUpdate(updated)} onUpdate={(updated: IBlockData<ParagraphData>) => onDescriptionUpdate(updated)}
/> />
</> </>
: <SbButton {...{ onClick: selectImage }}>Select Image</SbButton> : <SbButton {...{ onClick: selectImage }}>Select Image</SbButton>

View file

@ -1,5 +1,5 @@
import { import {
BlockData, IBlockData,
generateBlockId, generateBlockId,
} from '@schlechtenburg/core'; } from '@schlechtenburg/core';
import { import {
@ -11,7 +11,7 @@ import {
export interface ImageData { export interface ImageData {
src: string; src: string;
alt: string; alt: string;
description: BlockData<ParagraphData>; description: IBlockData<ParagraphData>;
} }
export const getDefaultData: () => ImageData = () => ({ export const getDefaultData: () => ImageData = () => ({

View file

@ -7,7 +7,7 @@ import {
} from 'vue'; } from 'vue';
import { import {
model, model,
BlockData, IBlockData,
useActivation, useActivation,
SbBlock, SbBlock,
@ -61,7 +61,7 @@ export default defineComponent({
}); });
}; };
const onChildUpdate = (child: BlockData<any>, updated: BlockData<any>) => { const onChildUpdate = (child: IBlockData<any>, updated: IBlockData<any>) => {
const index = localData.children.indexOf(child); const index = localData.children.indexOf(child);
if (index === -1) { if (index === -1) {
return; return;
@ -78,7 +78,7 @@ export default defineComponent({
}); });
}; };
const appendBlock = (block: BlockData<any>) => { const appendBlock = (block: IBlockData<any>) => {
localData.children = [ localData.children = [
...localData.children, ...localData.children,
block, block,
@ -87,7 +87,7 @@ export default defineComponent({
activate(block.id); activate(block.id);
}; };
const insertBlock = (index: number, block: BlockData<any>) => { const insertBlock = (index: number, block: IBlockData<any>) => {
localData.children = [ localData.children = [
...localData.children.slice(0, index + 1), ...localData.children.slice(0, index + 1),
block, block,
@ -170,10 +170,10 @@ export default defineComponent({
{...{ key: child.id }} {...{ key: child.id }}
data-order={index} data-order={index}
block={child} block={child}
onUpdate={(updated: BlockData<any>) => onChildUpdate(child, updated)} onUpdate={(updated: IBlockData<any>) => onChildUpdate(child, updated)}
onRemoveSelf={() => removeBlock(index)} onRemoveSelf={() => removeBlock(index)}
onPrependBlock={(block: BlockData<any>) => insertBlock(index - 1, block)} onPrependBlock={(block: IBlockData<any>) => insertBlock(index - 1, block)}
onAppendBlock={(block: BlockData<any>) => insertBlock(index, block)} onAppendBlock={(block: IBlockData<any>) => insertBlock(index, block)}
onActivatePrevious={() => activateBlock(index - 1,)} onActivatePrevious={() => activateBlock(index - 1,)}
onActivateNext={() => activateBlock(index + 1,)} onActivateNext={() => activateBlock(index + 1,)}
> >

View file

@ -1,8 +1,8 @@
import { BlockData } from '@schlechtenburg/core'; import { IBlockData } from '@schlechtenburg/core';
export interface LayoutData { export interface LayoutData {
orientation: string; orientation: string;
children: BlockData<any>[]; children: IBlockData<any>[];
} }
export const getDefaultData: () => LayoutData = () => ({ export const getDefaultData: () => LayoutData = () => ({