Rename events, added mainmenu
This commit is contained in:
parent
d64d9e4af7
commit
d76f40cf7d
|
@ -11,12 +11,12 @@ export interface BlockLibraryDefinition {
|
||||||
[name: string]: BlockDefinition;
|
[name: string]: BlockDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlockProps<T> {
|
export interface BlockProps {
|
||||||
blockId: string;
|
blockId: string;
|
||||||
data: T;
|
data: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Block<T> extends BlockProps<T> {
|
export interface Block extends BlockProps {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,14 @@ import './Block.scss';
|
||||||
|
|
||||||
interface BlockProps {
|
interface BlockProps {
|
||||||
block: Block;
|
block: Block;
|
||||||
eventUpdate: (b?: Block) => void;
|
onUpdate: (b?: Block) => void;
|
||||||
eventPrependBlock: (b?: Block) => void;
|
onPrependBlock: (b?: Block) => void;
|
||||||
eventAppendBlock: (b?: Block) => void;
|
onAppendBlock: (b?: Block) => void;
|
||||||
eventRemoveBlock: () => void;
|
onRemoveSelf: () => void;
|
||||||
eventMoveUp: () => void;
|
onMoveBackward: () => void;
|
||||||
eventMoveDown: () => void;
|
onMoveForward: () => void;
|
||||||
|
onActivateNext: () => void;
|
||||||
|
onActivatePrevious: () => void;
|
||||||
sortable: string;
|
sortable: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +42,12 @@ export const SbBlock = defineComponent({
|
||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
eventUpdate: { type: Function, default: () => {} },
|
onUpdate: { type: Function, default: () => {} },
|
||||||
eventPrependBlock: { type: Function, default: () => {} },
|
onPrependBlock: { type: Function, default: () => {} },
|
||||||
eventAppendBlock: { type: Function, default: () => {} },
|
onAppendBlock: { type: Function, default: () => {} },
|
||||||
eventRemoveBlock: { type: Function, default: () => {} },
|
onRemoveSelf: { type: Function, default: () => {} },
|
||||||
eventMoveUp: { type: Function, default: () => {} },
|
onMoveBackward: { type: Function, default: () => {} },
|
||||||
eventMoveDown: { type: Function, default: () => {} },
|
onMoveForward: { type: Function, default: () => {} },
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props: BlockProps, context) {
|
setup(props: BlockProps, context) {
|
||||||
|
@ -61,7 +63,7 @@ export const SbBlock = defineComponent({
|
||||||
watch(() => props.block.data, triggerSizeCalculation);
|
watch(() => props.block.data, triggerSizeCalculation);
|
||||||
|
|
||||||
const onChildUpdate = (updated: {[key: string]: any}) => {
|
const onChildUpdate = (updated: {[key: string]: any}) => {
|
||||||
props.eventUpdate({
|
props.onUpdate({
|
||||||
...props.block,
|
...props.block,
|
||||||
data: {
|
data: {
|
||||||
...props.block.data,
|
...props.block.data,
|
||||||
|
@ -99,10 +101,12 @@ export const SbBlock = defineComponent({
|
||||||
<BlockComponent
|
<BlockComponent
|
||||||
data={props.block.data}
|
data={props.block.data}
|
||||||
blockId={props.block.blockId}
|
blockId={props.block.blockId}
|
||||||
eventUpdate={onChildUpdate}
|
onUpdate={onChildUpdate}
|
||||||
eventPrependBlock={props.eventPrependBlock}
|
onPrependBlock={props.onPrependBlock}
|
||||||
eventAppendBlock={props.eventAppendBlock}
|
onAppendBlock={props.onAppendBlock}
|
||||||
eventRemoveBlock={props.eventRemoveBlock}
|
onRemoveSelf={props.onRemoveSelf}
|
||||||
|
onActivatePrevious={props.onActivatePrevious}
|
||||||
|
onActivateNext={props.onActivateNext}
|
||||||
onClick={($event: MouseEvent) => {
|
onClick={($event: MouseEvent) => {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
activate();
|
activate();
|
||||||
|
|
|
@ -19,9 +19,9 @@ export const SbBlockOrdering = defineComponent({
|
||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
eventRemoveBlock: { type: Function, default: () => {} },
|
onRemove: { type: Function, default: () => {} },
|
||||||
eventMoveUp: { type: Function, default: () => {} },
|
onMoveUp: { type: Function, default: () => {} },
|
||||||
eventMoveDown: { type: Function, default: () => {} },
|
onMoveDown: { type: Function, default: () => {} },
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
@ -55,9 +55,9 @@ export const SbBlockOrdering = defineComponent({
|
||||||
style={styles}
|
style={styles}
|
||||||
onClick={($event: MouseEvent) => $event.stopPropagation()}
|
onClick={($event: MouseEvent) => $event.stopPropagation()}
|
||||||
>
|
>
|
||||||
<SbButton onClick={props.eventMoveUp}>{props.sortable === 'vertical' ? '↑' : '←'}</SbButton>
|
<SbButton onClick={props.onMoveUp}>{props.sortable === 'vertical' ? '↑' : '←'}</SbButton>
|
||||||
<SbButton onClick={props.eventRemoveBlock}>x</SbButton>
|
<SbButton onClick={props.onRemove}>x</SbButton>
|
||||||
<SbButton onClick={props.eventMoveDown}>{props.sortable === 'vertical' ? '↓' : '→'}</SbButton>
|
<SbButton onClick={props.onMoveDown}>{props.sortable === 'vertical' ? '↓' : '→'}</SbButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -46,7 +46,7 @@ export const SbBlockPicker = defineComponent({
|
||||||
<SbModal
|
<SbModal
|
||||||
open={open.value}
|
open={open.value}
|
||||||
onClick={($event: MouseEvent) => $event.stopPropagation()}
|
onClick={($event: MouseEvent) => $event.stopPropagation()}
|
||||||
eventClose={() => {
|
onClose={() => {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
0
packages/core/lib/components/ContextMenu.scss
Normal file
0
packages/core/lib/components/ContextMenu.scss
Normal file
74
packages/core/lib/components/ContextMenu.tsx
Normal file
74
packages/core/lib/components/ContextMenu.tsx
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import {
|
||||||
|
watch,
|
||||||
|
defineComponent,
|
||||||
|
ref,
|
||||||
|
} from 'vue';
|
||||||
|
|
||||||
|
import { SbButton } from './Button';
|
||||||
|
|
||||||
|
import './ContextMenu.scss';
|
||||||
|
|
||||||
|
interface ContextMenuProps {
|
||||||
|
onClose: () => void;
|
||||||
|
onOpen: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SbContextMenu = defineComponent({
|
||||||
|
name: 'sb-context-menu',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
onClose: { type: Function, default: () => {} },
|
||||||
|
onOpen: { type: Function, default: () => {} },
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props: ContextMenuProps, context) {
|
||||||
|
const opened = ref(false);
|
||||||
|
const close = () => { opened.value = false; }
|
||||||
|
const closeOnEscape = ($event: KeyboardEvent) => {
|
||||||
|
if ($event.key === 'Escape') {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const open = () => {
|
||||||
|
opened.value = true;
|
||||||
|
document.addEventListener('click', close);
|
||||||
|
document.addEventListener('keypress', closeOnEscape);
|
||||||
|
}
|
||||||
|
const toggle = () => { opened.value = !opened.value; }
|
||||||
|
|
||||||
|
watch(opened, () => {
|
||||||
|
if (!opened.value) {
|
||||||
|
document.removeEventListener('click', close);
|
||||||
|
document.removeEventListener('keypress', closeOnEscape);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<div class="sb-context-menu">
|
||||||
|
{
|
||||||
|
context.slots.context({
|
||||||
|
opened,
|
||||||
|
toggle,
|
||||||
|
close,
|
||||||
|
open,
|
||||||
|
}) ||
|
||||||
|
<SbButton onClick={toggle}>Menu</SbButton>
|
||||||
|
}
|
||||||
|
<dialog
|
||||||
|
open={opened.value}
|
||||||
|
onClose={close}
|
||||||
|
onClick={($event: Event) => {
|
||||||
|
// Make sure clicks inside do not autoclose this
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{context.slots.default({
|
||||||
|
opened,
|
||||||
|
toggle,
|
||||||
|
close,
|
||||||
|
open,
|
||||||
|
}) || null}
|
||||||
|
</dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
2
packages/core/lib/components/MainMenu.scss
Normal file
2
packages/core/lib/components/MainMenu.scss
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.sb-main-menu {
|
||||||
|
}
|
34
packages/core/lib/components/MainMenu.tsx
Normal file
34
packages/core/lib/components/MainMenu.tsx
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
PropType,
|
||||||
|
} from 'vue';
|
||||||
|
import { Block } from '../blocks';
|
||||||
|
|
||||||
|
import { TreeBlockSelect } from './TreeBlockSelect';
|
||||||
|
|
||||||
|
import './MainMenu.scss';
|
||||||
|
|
||||||
|
interface MainMenuProps {
|
||||||
|
block: Block;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SbMainMenu = defineComponent({
|
||||||
|
name: 'sb-main-menu',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
block: {
|
||||||
|
type: (null as unknown) as PropType<Block>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props: MainMenuProps, context) {
|
||||||
|
return () => (
|
||||||
|
<div class="sb-main-menu">
|
||||||
|
<TreeBlockSelect
|
||||||
|
block={block}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
|
@ -7,7 +7,7 @@ import './Modal.scss';
|
||||||
|
|
||||||
interface ModalProps {
|
interface ModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
eventClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SbModal = defineComponent({
|
export const SbModal = defineComponent({
|
||||||
|
@ -18,7 +18,7 @@ export const SbModal = defineComponent({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
eventClose: { type: Function, default: () => {} },
|
onClose: { type: Function, default: () => {} },
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props: ModalProps, context) {
|
setup(props: ModalProps, context) {
|
||||||
|
@ -33,7 +33,7 @@ export const SbModal = defineComponent({
|
||||||
class="sb-modal__overlay"
|
class="sb-modal__overlay"
|
||||||
onClick={($event: MouseEvent) => {
|
onClick={($event: MouseEvent) => {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
props.eventClose();
|
props.onClose();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="sb-modal__content">
|
<div class="sb-modal__content">
|
||||||
|
|
|
@ -18,13 +18,14 @@ import { BlockLibrary } from '../use-dynamic-blocks';
|
||||||
import { EditorDimensions, useResizeObserver } from '../use-resize-observer';
|
import { EditorDimensions, useResizeObserver } from '../use-resize-observer';
|
||||||
import { ActiveBlock } from '../use-activation';
|
import { ActiveBlock } from '../use-activation';
|
||||||
|
|
||||||
|
import { SbMainMenu } from './MainMenu';
|
||||||
import { SbBlock } from './Block';
|
import { SbBlock } from './Block';
|
||||||
|
|
||||||
import './Schlechtenburg.scss';
|
import './Schlechtenburg.scss';
|
||||||
|
|
||||||
export interface SchlechtenburgProps {
|
export interface SchlechtenburgProps {
|
||||||
customBlocks: BlockDefinition[];
|
customBlocks: BlockDefinition[];
|
||||||
eventUpdate: (b: Block<any>) => void;
|
onUpdate: (b: Block<any>) => void;
|
||||||
block: Block<any>;
|
block: Block<any>;
|
||||||
mode: SbMode;
|
mode: SbMode;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +38,7 @@ export const Schlechtenburg = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
customBlocks: { type: Array as PropType<BlockDefinition[]>, default: () => [] },
|
customBlocks: { type: Array as PropType<BlockDefinition[]>, default: () => [] },
|
||||||
block: { type: Object as PropType<Block<any>>, required: true },
|
block: { type: Object as PropType<Block<any>>, required: true },
|
||||||
eventUpdate: { type: Function, default: () => {} },
|
onUpdate: { type: Function, default: () => {} },
|
||||||
mode: {
|
mode: {
|
||||||
type: String as PropType<SbMode>,
|
type: String as PropType<SbMode>,
|
||||||
validator(value: any) {
|
validator(value: any) {
|
||||||
|
@ -75,9 +76,12 @@ export const Schlechtenburg = defineComponent({
|
||||||
class="sb-main"
|
class="sb-main"
|
||||||
ref={el}
|
ref={el}
|
||||||
>
|
>
|
||||||
|
<SbMainMenu
|
||||||
|
block={props.block}
|
||||||
|
/>
|
||||||
<SbBlock
|
<SbBlock
|
||||||
block={props.block}
|
block={props.block}
|
||||||
eventUpdate={props.eventUpdate}
|
onUpdate={props.onUpdate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
2
packages/core/lib/components/TreeBlockSelect.scss
Normal file
2
packages/core/lib/components/TreeBlockSelect.scss
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.sb-tree-block-select {
|
||||||
|
}
|
38
packages/core/lib/components/TreeBlockSelect.tsx
Normal file
38
packages/core/lib/components/TreeBlockSelect.tsx
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
PropType,
|
||||||
|
} from 'vue';
|
||||||
|
import { Block } from '../blocks';
|
||||||
|
import { SbContextMenu } from './ContextMenu';
|
||||||
|
import { SbButton } from './Button';
|
||||||
|
|
||||||
|
import './TreeBlockSelect.scss';
|
||||||
|
|
||||||
|
interface TreeBlockSelectProps {
|
||||||
|
block: Block;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SbTreeBlockSelect = defineComponent({
|
||||||
|
name: 'sb-main-menu',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
block: {
|
||||||
|
type: (null as unknown) as PropType<Block>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props: TreeBlockSelectProps, context) {
|
||||||
|
return () => (
|
||||||
|
<SbContextMenu
|
||||||
|
class="sb-tree-block-select"
|
||||||
|
v-slots={{
|
||||||
|
context: ({ toggle }) => <SbButton onClick={toggle}>Tree</SbButton>,
|
||||||
|
default: () => <ul>
|
||||||
|
<li>Test</li>
|
||||||
|
</ul>,
|
||||||
|
}}
|
||||||
|
></SbContextMenu>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
|
@ -29,7 +29,7 @@ export default defineComponent({
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
...blockProps,
|
...blockProps,
|
||||||
eventUpdate: { type: Function, default: () => {} },
|
onUpdate: { type: Function, default: () => {} },
|
||||||
data: {
|
data: {
|
||||||
type: (null as unknown) as PropType<ImageData>,
|
type: (null as unknown) as PropType<ImageData>,
|
||||||
default: getDefaultData,
|
default: getDefaultData,
|
||||||
|
@ -61,7 +61,7 @@ export default defineComponent({
|
||||||
if (fileInput.value && fileInput.value.files && fileInput.value.files.length) {
|
if (fileInput.value && fileInput.value.files && fileInput.value.files.length) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.addEventListener('load', () => {
|
reader.addEventListener('load', () => {
|
||||||
props.eventUpdate({
|
props.onUpdate({
|
||||||
src: reader.result,
|
src: reader.result,
|
||||||
alt: props.data.alt,
|
alt: props.data.alt,
|
||||||
description: props.data.description,
|
description: props.data.description,
|
||||||
|
@ -73,7 +73,7 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDescriptionUpdate = (description) => {
|
const onDescriptionUpdate = (description) => {
|
||||||
props.eventUpdate({
|
props.onUpdate({
|
||||||
...props.data,
|
...props.data,
|
||||||
description,
|
description,
|
||||||
});
|
});
|
||||||
|
@ -101,7 +101,7 @@ export default defineComponent({
|
||||||
/>
|
/>
|
||||||
<SbBlock
|
<SbBlock
|
||||||
block={localData.description}
|
block={localData.description}
|
||||||
eventUpdate={(updated: Block) => onDescriptionUpdate(updated)}
|
onUpdate={(updated: Block) => onDescriptionUpdate(updated)}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
: <SbButton onClick={selectImage}>Select Image</SbButton>}
|
: <SbButton onClick={selectImage}>Select Image</SbButton>}
|
||||||
|
|
|
@ -33,7 +33,7 @@ export default defineComponent({
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
...blockProps,
|
...blockProps,
|
||||||
eventUpdate: { type: Function, default: () => {} },
|
onUpdate: { type: Function, default: () => {} },
|
||||||
data: {
|
data: {
|
||||||
type: (null as unknown) as PropType<LayoutData>,
|
type: (null as unknown) as PropType<LayoutData>,
|
||||||
default: getDefaultData,
|
default: getDefaultData,
|
||||||
|
@ -60,7 +60,7 @@ export default defineComponent({
|
||||||
|
|
||||||
const toggleOrientation = () => {
|
const toggleOrientation = () => {
|
||||||
console.log('toggle');
|
console.log('toggle');
|
||||||
props.eventUpdate({
|
props.onUpdate({
|
||||||
orientation: localData.orientation === 'vertical' ? 'horizontal' : 'vertical',
|
orientation: localData.orientation === 'vertical' ? 'horizontal' : 'vertical',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,7 @@ export default defineComponent({
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
props.eventUpdate({
|
props.onUpdate({
|
||||||
children: [
|
children: [
|
||||||
...localData.children.slice(0, index),
|
...localData.children.slice(0, index),
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ export default defineComponent({
|
||||||
...localData.children,
|
...localData.children,
|
||||||
block,
|
block,
|
||||||
];
|
];
|
||||||
props.eventUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
activate(block.blockId);
|
activate(block.blockId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ export default defineComponent({
|
||||||
block,
|
block,
|
||||||
...localData.children.slice(index + 1),
|
...localData.children.slice(index + 1),
|
||||||
];
|
];
|
||||||
props.eventUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
activate(block.blockId);
|
activate(block.blockId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,13 +106,25 @@ export default defineComponent({
|
||||||
...localData.children.slice(0, index),
|
...localData.children.slice(0, index),
|
||||||
...localData.children.slice(index + 1),
|
...localData.children.slice(index + 1),
|
||||||
];
|
];
|
||||||
props.eventUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
|
|
||||||
const newActiveIndex = Math.max(index - 1, 0);
|
const newActiveIndex = Math.max(index - 1, 0);
|
||||||
activate(localData.children[newActiveIndex].blockId);
|
activate(localData.children[newActiveIndex].blockId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveUp = (index: number) => {
|
const activateBlock = (index: number) => {
|
||||||
|
const safeIndex =
|
||||||
|
Math.max(
|
||||||
|
Math.min(
|
||||||
|
localData.children.length - 1,
|
||||||
|
index,
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
activate(localData.children[safeIndex].blockId);
|
||||||
|
};
|
||||||
|
|
||||||
|
const moveBackward = (index: number) => {
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,10 +138,10 @@ export default defineComponent({
|
||||||
...localData.children.slice(index + 1),
|
...localData.children.slice(index + 1),
|
||||||
];
|
];
|
||||||
|
|
||||||
props.eventUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveDown = (index: number) => {
|
const moveForward = (index: number) => {
|
||||||
if (index === localData.children.length - 1) {
|
if (index === localData.children.length - 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +155,7 @@ export default defineComponent({
|
||||||
...localData.children.slice(index + 2),
|
...localData.children.slice(index + 2),
|
||||||
];
|
];
|
||||||
|
|
||||||
props.eventUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
};
|
};
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
|
@ -160,17 +172,19 @@ export default defineComponent({
|
||||||
{...{ key: child.blockId }}
|
{...{ key: child.blockId }}
|
||||||
data-order={index}
|
data-order={index}
|
||||||
block={child}
|
block={child}
|
||||||
eventUpdate={(updated: Block) => onChildUpdate(child, updated)}
|
onUpdate={(updated: Block) => onChildUpdate(child, updated)}
|
||||||
eventPrependBlock={(block: Block) => insertBlock(index - 1, block)}
|
onRemoveSelf={() => removeBlock(index)}
|
||||||
eventAppendBlock={(block: Block) => insertBlock(index, block)}
|
onPrependBlock={(block: Block) => insertBlock(index - 1, block)}
|
||||||
removable
|
onAppendBlock={(block: Block) => insertBlock(index, block)}
|
||||||
|
onActivatePrevious={(block: Block) => activateBlock(index - 1,)}
|
||||||
|
onActivateNext={(block: Block) => activateBlock(index + 1,)}
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
'context-toolbar': () =>
|
'context-toolbar': () =>
|
||||||
<SbBlockOrdering
|
<SbBlockOrdering
|
||||||
eventMoveUp={() => moveUp(index)}
|
onMoveBackward={() => moveBackward(index)}
|
||||||
eventMoveDown={() => moveDown(index)}
|
onMoveForward={() => moveForward(index)}
|
||||||
eventRemoveBlock={() => removeBlock(index)}
|
onRemove={() => removeBlock(index)}
|
||||||
sortable={props.sortable}
|
sortable={props.sortable}
|
||||||
/>,
|
/>,
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -28,9 +28,11 @@ import './style.scss';
|
||||||
|
|
||||||
interface ParagraphProps extends BlockProps {
|
interface ParagraphProps extends BlockProps {
|
||||||
data: ParagraphData;
|
data: ParagraphData;
|
||||||
eventUpdate: (b?: ParagraphData) => void;
|
onUpdate: (b?: ParagraphData) => void;
|
||||||
eventAppendBlock: (b?: BlockData) => void;
|
onAppendBlock: (b?: BlockData) => void;
|
||||||
eventRemoveBlock: () => void;
|
onRemoveSelf: () => void;
|
||||||
|
onActivateNext: () => void;
|
||||||
|
onActivatePrevious: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -44,9 +46,11 @@ export default defineComponent({
|
||||||
type: (null as unknown) as PropType<ParagraphData>,
|
type: (null as unknown) as PropType<ParagraphData>,
|
||||||
default: getDefaultData,
|
default: getDefaultData,
|
||||||
},
|
},
|
||||||
eventUpdate: { type: Function, default: () => {} },
|
onUpdate: { type: Function, default: () => {} },
|
||||||
eventAppendBlock: { type: Function, default: () => {} },
|
onAppendBlock: { type: Function, default: () => {} },
|
||||||
eventRemoveBlock: { type: Function, default: () => {} },
|
onRemoveSelf: { type: Function, default: () => {} },
|
||||||
|
onActivateNext: { type: Function, default: () => {} },
|
||||||
|
onActivatePrevious: { type: Function, default: () => {} },
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props: ParagraphProps) {
|
setup(props: ParagraphProps) {
|
||||||
|
@ -98,7 +102,7 @@ export default defineComponent({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const setAlignment = ($event: Event) => {
|
const setAlignment = ($event: Event) => {
|
||||||
props.eventUpdate({
|
props.onUpdate({
|
||||||
value: localData.value,
|
value: localData.value,
|
||||||
align: ($event.target as HTMLSelectElement).value,
|
align: ($event.target as HTMLSelectElement).value,
|
||||||
});
|
});
|
||||||
|
@ -111,16 +115,16 @@ export default defineComponent({
|
||||||
|
|
||||||
const onBlur = () => {
|
const onBlur = () => {
|
||||||
localData.focused = false;
|
localData.focused = false;
|
||||||
props.eventUpdate({
|
props.onUpdate({
|
||||||
value: localData.value,
|
value: localData.value,
|
||||||
align: localData.align,
|
align: localData.align,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onKeydown = ($event: KeyboardEvent) => {
|
const onKeydown = ($event: KeyboardEvent) => {
|
||||||
if (props.eventAppendBlock && $event.key === 'Enter' && !$event.shiftKey) {
|
if ($event.key === 'Enter' && !$event.shiftKey) {
|
||||||
const blockId = `${+(new Date())}`;
|
const blockId = `${+(new Date())}`;
|
||||||
props.eventAppendBlock({
|
props.onAppendBlock({
|
||||||
blockId,
|
blockId,
|
||||||
name: 'sb-paragraph',
|
name: 'sb-paragraph',
|
||||||
data: getDefaultData(),
|
data: getDefaultData(),
|
||||||
|
@ -133,8 +137,23 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onKeyup = ($event: KeyboardEvent) => {
|
const onKeyup = ($event: KeyboardEvent) => {
|
||||||
if (props.eventRemoveBlock && $event.key === 'Backspace' && localData.value === '') {
|
if ($event.key === 'Backspace' && localData.value === '') {
|
||||||
props.eventRemoveBlock();
|
props.onRemoveSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
const selection = window.getSelection();
|
||||||
|
const node = selection.focusNode;
|
||||||
|
const childNodes = Array.from(inputEl.value.childNodes);
|
||||||
|
const index = childNodes.indexOf(node);
|
||||||
|
if (node === inputEl.value || index === 0 || index === childNodes.length -1) {
|
||||||
|
switch ($event.key) {
|
||||||
|
case 'ArrowDown':
|
||||||
|
props.onActivateNext();
|
||||||
|
break;
|
||||||
|
case 'ArrowUp':
|
||||||
|
props.onActivatePrevious();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,10 @@ import {
|
||||||
|
|
||||||
import { Schlechtenburg, Block, SbMode } from '../packages/core/lib';
|
import { Schlechtenburg, Block, SbMode } from '../packages/core/lib';
|
||||||
|
|
||||||
/*
|
import SbLayout from '../packages/layout/lib';
|
||||||
import SbHeading from '../packages/heading/lib';
|
import SbHeading from '../packages/heading/lib';
|
||||||
import SbParagraph from '../packages/paragraph/lib';
|
import SbParagraph from '../packages/paragraph/lib';
|
||||||
import SbImage from '../packages/image/lib';
|
import SbImage from '../packages/image/lib';
|
||||||
*/
|
|
||||||
import SbLayout from '../packages/layout/lib';
|
|
||||||
|
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
|
|
||||||
|
@ -41,16 +39,14 @@ export default defineComponent({
|
||||||
case SbMode.Edit:
|
case SbMode.Edit:
|
||||||
return <Schlechtenburg
|
return <Schlechtenburg
|
||||||
block={block}
|
block={block}
|
||||||
eventUpdate={(newBlock: Block<any>) => {
|
onUpdate={(newBlock: Block<any>) => {
|
||||||
block.data = newBlock.data;
|
block.data = newBlock.data;
|
||||||
}}
|
}}
|
||||||
customBlocks={[
|
customBlocks={[
|
||||||
SbLayout,
|
SbLayout,
|
||||||
/*
|
|
||||||
SbHeading,
|
SbHeading,
|
||||||
SbImage,
|
SbImage,
|
||||||
SbParagraph,
|
SbParagraph,
|
||||||
*/
|
|
||||||
]}
|
]}
|
||||||
key="edit"
|
key="edit"
|
||||||
mode="edit"
|
mode="edit"
|
||||||
|
@ -67,7 +63,6 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
console.log('render App');
|
|
||||||
return <div id="app">
|
return <div id="app">
|
||||||
<select
|
<select
|
||||||
value={activeTab.value}
|
value={activeTab.value}
|
||||||
|
|
Loading…
Reference in a new issue