diff --git a/.eslintrc.js b/.eslintrc.js
index 7b7963a..896f753 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -14,6 +14,7 @@ module.exports = {
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+ '@typescript-eslint/no-empty-function': 0,
},
overrides: [
{
diff --git a/src/App.tsx b/src/App.tsx
index 6819529..7dcc62c 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -4,7 +4,7 @@ import {
ref,
} from '@vue/composition-api';
import Schlechtenburg from '@components/Schlechtenburg';
-import { BlockData } from './components/TreeElement';
+import { Block } from './components/TreeElement';
import './App.scss';
@@ -20,7 +20,7 @@ export default defineComponent({
orientation: 'vertical',
children: [],
},
- }) as BlockData;
+ }) as Block;
return () => (
@@ -41,7 +41,7 @@ export default defineComponent({
{
+ eventUpdate={(newBlock: Block) => {
block.name = newBlock.name;
block.blockId = newBlock.blockId;
block.data = newBlock.data;
diff --git a/src/components/Schlechtenburg.tsx b/src/components/Schlechtenburg.tsx
index f61d9e9..1601a06 100644
--- a/src/components/Schlechtenburg.tsx
+++ b/src/components/Schlechtenburg.tsx
@@ -8,7 +8,7 @@ import {
import {
model,
ActiveBlock,
- BlockData,
+ Block,
SbMode,
Mode,
BlockDefinition,
@@ -27,8 +27,8 @@ import './Schlechtenburg.scss';
export interface SchlechtenburgProps {
customBlocks: BlockDefinition[];
- eventUpdate: (b?: BlockData) => void;
- block: BlockData;
+ eventUpdate: (b: Block) => void;
+ block: Block;
mode: SbMode;
}
@@ -39,11 +39,8 @@ export default defineComponent({
props: {
customBlocks: { type: Array as PropType, default: () => [] },
- block: { type: Object as PropType, required: true },
- eventUpdate: {
- type: (Function as unknown) as (b?: BlockData) => void,
- default: () => () => undefined,
- },
+ block: { type: Object as PropType, required: true },
+ eventUpdate: { type: Function, default: () => {} },
mode: {
type: String,
validator(value: string) {
@@ -53,7 +50,7 @@ export default defineComponent({
},
},
- setup(props: SchlechtenburgProps, context) {
+ setup(props: SchlechtenburgProps) {
const mode = ref(props.mode);
provide(Mode, mode);
diff --git a/src/components/TreeElement.ts b/src/components/TreeElement.ts
index c782da8..52ab007 100644
--- a/src/components/TreeElement.ts
+++ b/src/components/TreeElement.ts
@@ -17,10 +17,12 @@ export interface BlockLibraryDefinition {
[name: string]: BlockDefinition;
}
-export interface BlockData {
+export interface BlockData { [name: string]: any }
+
+export interface Block {
name: string;
blockId: string;
- data: { [name: string]: any };
+ data: BlockData;
}
export interface BlockProps {
@@ -35,10 +37,6 @@ export const model = {
export const blockProps = {
blockId: { type: String, required: true },
- eventUpdate: {
- type: (Function as unknown) as (b: any) => void,
- default: () => () => undefined,
- },
data: { type: Object, default: () => ({}) },
};
diff --git a/src/components/internal/Block.tsx b/src/components/internal/Block.tsx
index b7d9833..6ca4804 100644
--- a/src/components/internal/Block.tsx
+++ b/src/components/internal/Block.tsx
@@ -4,33 +4,34 @@ import {
PropType,
} from '@vue/composition-api';
import {
- BlockData,
+ Block,
useDynamicBlocks,
useActivation,
} from '@components/TreeElement';
import './Block.scss';
+interface BlockProps {
+ block: Block;
+ eventUpdate: (b?: Block) => void;
+ eventInsertBlock: (b?: Block) => void;
+ eventAppendBlock: (b?: Block) => void;
+}
+
export default defineComponent({
name: 'sb-block',
props: {
- block: { type: (null as unknown) as PropType, required: true },
- eventUpdate: {
- type: (Function as unknown) as (b?: BlockData) => void,
- default: () => () => undefined,
- },
- eventInsertBlock: {
- type: (Function as unknown) as (b?: BlockData) => void,
- default: () => () => undefined,
- },
- eventAppendBlock: {
- type: (Function as unknown) as (b?: BlockData) => void,
- default: () => () => undefined,
+ block: {
+ type: (null as unknown) as PropType,
+ required: true,
},
+ eventUpdate: { type: Function, default: () => {} },
+ eventInsertBlock: { type: Function, default: () => {} },
+ eventAppendBlock: { type: Function, default: () => {} },
},
- setup(props, context) {
+ setup(props: BlockProps, context) {
const { isActive, activate } = useActivation(props.block.blockId);
const { getBlock } = useDynamicBlocks();
const classes = computed(() => ({
@@ -48,31 +49,26 @@ export default defineComponent({
});
};
- const Block = getBlock(props.block.name) as any;
+ const BlockComponent = getBlock(props.block.name) as any;
- return () =>
+ return () => (
-
{
+ $event.stopPropagation();
+ activate();
+ }}
{...{
attrs: context.attrs,
- on: {
- ...context.listeners,
- update: onChildUpdate,
- },
- nativeOn: {
- click: ($event: MouseEvent) => {
- $event.stopPropagation();
- activate();
- },
- },
+ on: context.listeners,
}}
/>
- ;
+
);
},
});
diff --git a/src/components/internal/BlockPicker.tsx b/src/components/internal/BlockPicker.tsx
index e2e749d..b69380c 100644
--- a/src/components/internal/BlockPicker.tsx
+++ b/src/components/internal/BlockPicker.tsx
@@ -36,17 +36,17 @@ export default defineComponent({
return () => (
$event.stopPropagation()}
>
{
+ onClick={($event: MouseEvent) => {
open.value = true;
- console.log(open);
+ $event.stopPropagation();
}}
>Add a block
$event.stopPropagation()}
eventClose={() => {
open.value = false;
}}
diff --git a/src/components/internal/Modal.tsx b/src/components/internal/Modal.tsx
index 75298ef..2f73559 100644
--- a/src/components/internal/Modal.tsx
+++ b/src/components/internal/Modal.tsx
@@ -1,11 +1,15 @@
import {
defineComponent,
computed,
- ref,
} from '@vue/composition-api';
import './Modal.scss';
+interface ModalProps {
+ open: boolean;
+ eventClose: () => void;
+}
+
export default defineComponent({
name: 'sb-modal',
@@ -14,13 +18,10 @@ export default defineComponent({
type: Boolean,
default: false,
},
- eventClose: {
- type: (Function as unknown) as () => void,
- default: () => () => undefined,
- },
+ eventClose: { type: Function, default: () => {} },
},
- setup(props, context) {
+ setup(props: ModalProps, context) {
const classes = computed(() => ({
'sb-modal': true,
'sb-modal_open': props.open,
diff --git a/src/components/user/Image/display.tsx b/src/components/user/Image/display.tsx
new file mode 100644
index 0000000..29af999
--- /dev/null
+++ b/src/components/user/Image/display.tsx
@@ -0,0 +1,93 @@
+import {
+ defineComponent,
+ reactive,
+ ref,
+ Ref,
+ watch,
+ PropType,
+} from '@vue/composition-api';
+import {
+ model,
+ blockProps,
+} from '@components/TreeElement';
+
+import SbToolbar from '@internal/Toolbar';
+
+import {
+ getDefaultData,
+ ImageData,
+ ImageProps,
+} from './util';
+
+import './style.scss';
+
+export default defineComponent({
+ name: 'sb-image-display',
+
+ model,
+
+ props: {
+ ...blockProps,
+ data: {
+ type: (null as unknown) as PropType,
+ default: getDefaultData,
+ },
+ },
+
+ setup(props: ImageProps, context) {
+ const localData = reactive({
+ src: props.data.src,
+ alt: props.data.alt,
+ });
+
+
+ const fileInput: Ref = ref(null);
+
+ watch(() => props.data, () => {
+ localData.src = props.data.src;
+ localData.alt = props.data.alt;
+ });
+
+ const selectImage = () => {
+ if (fileInput.value) {
+ fileInput.value.click();
+ }
+ };
+
+ const onImageSelect = () => {
+ if (fileInput.value && fileInput.value.files && fileInput.value.files.length) {
+ context.emit('update', {
+ src: window.URL.createObjectURL(fileInput.value.files[0]),
+ });
+ }
+ };
+
+ return () => (
+
+
+ Image Edit
+
+
+ {localData.src
+ ?
+ :
+ }
+
+ );
+ },
+});
diff --git a/src/components/user/Layout/edit.tsx b/src/components/user/Layout/edit.tsx
index c94cf0d..74e64e8 100644
--- a/src/components/user/Layout/edit.tsx
+++ b/src/components/user/Layout/edit.tsx
@@ -8,7 +8,7 @@ import {
import {
model,
useActivation,
- BlockData,
+ Block,
blockProps,
} from '@components/TreeElement';
@@ -32,17 +32,14 @@ export default defineComponent({
props: {
...blockProps,
- eventUpdate: {
- type: (Function as unknown) as (b?: LayoutData) => void,
- default: () => () => undefined,
- },
+ eventUpdate: { type: Function, default: () => {} },
data: {
type: (null as unknown) as PropType,
default: getDefaultData,
},
},
- setup(props: LayoutProps, context) {
+ setup(props: LayoutProps) {
const { activate } = useActivation(props.blockId);
const localData: LayoutData = reactive({
@@ -66,7 +63,7 @@ export default defineComponent({
});
};
- const onChildUpdate = (child: BlockData, updated: BlockData) => {
+ const onChildUpdate = (child: Block, updated: Block) => {
const index = localData.children.indexOf(child);
props.eventUpdate({
children: [
@@ -80,7 +77,7 @@ export default defineComponent({
});
};
- const appendBlock = (block: BlockData) => {
+ const appendBlock = (block: Block) => {
props.eventUpdate({
children: [
...localData.children,
@@ -90,8 +87,8 @@ export default defineComponent({
activate(block.blockId);
};
- const insertBlock = (index: number, block: BlockData) => {
- context.emit('update', {
+ const insertBlock = (index: number, block: Block) => {
+ props.eventUpdate({
children: [
...localData.children.slice(0, index + 1),
block,
@@ -118,13 +115,9 @@ export default defineComponent({
onChildUpdate(child, updated),
- 'insert-block': (block: BlockData) => insertBlock(index, block),
- 'append-block': appendBlock,
- },
- }}
+ eventUpdate={(updated: Block) => onChildUpdate(child, updated)}
+ eventInsertBlock={(block: Block) => insertBlock(index, block)}
+ eventAppendBlock={appendBlock}
/>
))}
diff --git a/src/components/user/Layout/index.ts b/src/components/user/Layout/index.ts
index a8cfd47..99b9952 100644
--- a/src/components/user/Layout/index.ts
+++ b/src/components/user/Layout/index.ts
@@ -3,6 +3,6 @@ import { getDefaultData } from './util';
export default {
name: 'sb-layout',
getDefaultData,
- edit: () => import('./edit.tsx'),
- display: () => import('./display.tsx'),
+ edit: () => import('./edit'),
+ display: () => import('./display'),
};
diff --git a/src/components/user/Layout/util.ts b/src/components/user/Layout/util.ts
index 642dece..13b22fd 100644
--- a/src/components/user/Layout/util.ts
+++ b/src/components/user/Layout/util.ts
@@ -1,11 +1,12 @@
import {
BlockProps,
+ Block,
BlockData,
} from '@components/TreeElement';
export interface LayoutData {
orientation: string;
- children: BlockData[];
+ children: Block[];
}
export interface LayoutProps extends BlockProps {
diff --git a/src/components/user/Paragraph/display.tsx b/src/components/user/Paragraph/display.tsx
index 3389083..6efeb79 100644
--- a/src/components/user/Paragraph/display.tsx
+++ b/src/components/user/Paragraph/display.tsx
@@ -1,48 +1,36 @@
import {
defineComponent,
- reactive,
computed,
- ref,
- Ref,
- onMounted,
- watch,
PropType,
} from '@vue/composition-api';
import {
model,
blockProps,
- useActivation,
+ BlockProps,
} from '@components/TreeElement';
-import SbToolbar from '@internal/Toolbar';
-
import {
getDefaultData,
ParagraphData,
- ParagraphProps,
} from './util';
import './style.scss';
+interface ParagraphProps extends BlockProps {
+ data: ParagraphData;
+}
+
export default defineComponent({
- name: 'sb-paragraph-edit',
+ name: 'sb-paragraph-display',
model,
props: {
...blockProps,
data: {
- type: (null as unknown) as PropType,
+ type: Object as PropType,
default: getDefaultData,
},
- eventUpdate: {
- type: (Function as unknown) as (b?: ParagraphData) => void,
- default: () => () => undefined,
- },
- eventInsertBlock: {
- type: (Function as unknown) as (b?: ParagraphData) => void,
- default: () => () => undefined,
- },
},
setup(props: ParagraphProps, context) {
@@ -51,8 +39,6 @@ export default defineComponent({
[`sb-paragraph_align-${props.data.align}`]: true,
}));
- return () => (
- {props.data.value}
- );
+ return () => {props.data.value}
;
},
});
diff --git a/src/components/user/Paragraph/edit.tsx b/src/components/user/Paragraph/edit.tsx
index d54f639..7a0a0f8 100644
--- a/src/components/user/Paragraph/edit.tsx
+++ b/src/components/user/Paragraph/edit.tsx
@@ -11,6 +11,8 @@ import {
import {
model,
blockProps,
+ BlockProps,
+ BlockData,
useActivation,
} from '@components/TreeElement';
@@ -19,11 +21,16 @@ import SbToolbar from '@internal/Toolbar';
import {
getDefaultData,
ParagraphData,
- ParagraphProps,
} from './util';
import './style.scss';
+interface ParagraphProps extends BlockProps {
+ data: ParagraphData;
+ eventUpdate: (b?: ParagraphData) => void;
+ eventInsertBlock: (b?: BlockData) => void;
+}
+
export default defineComponent({
name: 'sb-paragraph-edit',
@@ -35,22 +42,16 @@ export default defineComponent({
type: (null as unknown) as PropType,
default: getDefaultData,
},
- eventUpdate: {
- type: (Function as unknown) as (b?: ParagraphData) => void,
- default: () => () => undefined,
- },
- eventInsertBlock: {
- type: (Function as unknown) as (b?: ParagraphData) => void,
- default: () => () => undefined,
- },
+ eventUpdate: { type: Function, default: () => {} },
+ eventInsertBlock: { type: Function, default: () => {} },
},
- setup(props: ParagraphProps, context) {
+ setup(props: ParagraphProps) {
const localData = (reactive({
value: props.data.value,
align: props.data.align,
focused: false,
- }) as any) as {
+ }) as unknown) as {
value: string;
align: string;
focused: boolean;
@@ -89,7 +90,10 @@ export default defineComponent({
}));
const setAlignment = ($event: Event) => {
- props.eventUpdate({ align: ($event.target as HTMLSelectElement).value });
+ props.eventUpdate({
+ value: localData.value,
+ align: ($event.target as HTMLSelectElement).value,
+ });
};
const onFocus = () => {
@@ -100,6 +104,7 @@ export default defineComponent({
localData.focused = false;
props.eventUpdate({
value: localData.value,
+ align: localData.align,
});
activate(null);
};
@@ -124,11 +129,7 @@ export default defineComponent({
);
diff --git a/src/components/user/Paragraph/util.ts b/src/components/user/Paragraph/util.ts
index 5cd0719..33e7eaf 100644
--- a/src/components/user/Paragraph/util.ts
+++ b/src/components/user/Paragraph/util.ts
@@ -1,14 +1,8 @@
-import { BlockProps } from '@components/TreeElement';
-
export interface ParagraphData {
value: string;
align: string;
}
-export interface ParagraphProps extends BlockProps {
- data: ParagraphData;
-}
-
export const getDefaultData: () => ParagraphData = () => ({
value: '',
align: 'left',