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

159 lines
3.9 KiB
TypeScript
Raw Normal View History

2020-05-20 14:21:08 +00:00
import {
defineComponent,
2020-05-24 15:33:25 +00:00
provide,
2020-12-27 21:32:43 +00:00
shallowReactive,
2022-12-29 23:33:04 +00:00
shallowRef,
2020-05-24 15:33:25 +00:00
ref,
2022-03-20 13:49:44 +00:00
watch,
2022-12-29 02:47:45 +00:00
computed,
Transition,
2020-05-24 15:33:25 +00:00
PropType,
2020-05-28 20:16:35 +00:00
Ref,
2020-12-27 21:32:43 +00:00
} from 'vue';
2020-05-24 15:33:25 +00:00
import {
IBlockData,
IBlockDefinition,
IBlockLibrary,
ITreeNode,
2022-03-17 17:59:51 +00:00
OnUpdateBlockCb,
IFormattingTool,
IFormattingToolLibrary,
2021-03-08 15:29:35 +00:00
} from '../types';
import { model } from '../block-helpers';
2022-03-15 23:38:33 +00:00
import { SymMode, SbMode } from '../mode';
2021-03-08 15:29:35 +00:00
import { SymBlockLibrary} from '../use-dynamic-blocks';
import {
SymBlockTree,
SymBlockTreeRegister,
SymBlockTreeUnregister,
} from '../use-block-tree';
import { SymEditorDimensions, useResizeObserver } from '../use-resize-observer';
import { SymActiveBlock } from '../use-activation';
2022-12-29 23:33:04 +00:00
import { SymRootElement } from '../use-root-element';
import {
SbFormattingToolbar,
SymFormattingToolLibrary,
SymFormattingToolbarClients,
SymFormattingToolbarActiveClient,
} from '../rich-text';
2020-05-24 15:33:25 +00:00
2021-02-22 18:13:37 +00:00
import { SbMainMenu } from './MainMenu';
2020-12-30 20:17:34 +00:00
import { SbBlock } from './Block';
2020-05-24 20:00:14 +00:00
2022-03-20 13:49:44 +00:00
export interface ISbMainProps {
availableBlocks: IBlockDefinition<any>[];
availableFormattingTools: IFormattingTool[];
2022-03-20 13:49:44 +00:00
block: IBlockData<any>;
2022-09-05 19:12:20 +00:00
eventUpdate: OnUpdateBlockCb;
2022-03-20 13:49:44 +00:00
mode: SbMode;
}
2022-03-17 17:59:51 +00:00
import './Main.scss';
2020-05-27 13:57:57 +00:00
2021-03-08 15:29:35 +00:00
export const SbMain = defineComponent({
name: 'sb-main',
2020-05-20 14:21:08 +00:00
model,
props: {
2022-03-12 16:42:42 +00:00
availableBlocks: {
type: Array as PropType<IBlockDefinition<any>[]>,
2021-03-08 15:29:35 +00:00
default: () => [],
},
availableFormattingTools: {
type: Array as PropType<IFormattingTool[]>,
2022-12-29 23:33:04 +00:00
default: () => [],
},
2021-03-08 15:29:35 +00:00
block: {
type: Object as PropType<IBlockData<any>>,
2021-03-08 15:29:35 +00:00
required: true,
},
2022-03-17 17:59:51 +00:00
/**
* Called when the block should be updated.
*/
2022-09-05 19:12:20 +00:00
eventUpdate: {
2022-03-17 17:59:51 +00:00
type: (null as unknown) as PropType<OnUpdateBlockCb>,
default: () => {},
},
2020-05-27 13:57:57 +00:00
mode: {
2020-12-30 01:32:46 +00:00
type: String as PropType<SbMode>,
validator(value: any) {
2020-12-27 21:32:43 +00:00
return Object.values(SbMode).includes(value);
2020-05-27 13:57:57 +00:00
},
2020-12-27 21:32:43 +00:00
default: SbMode.Edit,
2020-05-27 13:57:57 +00:00
},
2020-05-20 14:21:08 +00:00
},
2022-03-20 13:49:44 +00:00
setup(props: ISbMainProps) {
2020-05-28 20:16:35 +00:00
const el: Ref<null|HTMLElement> = ref(null);
2021-03-08 15:29:35 +00:00
useResizeObserver(el, SymEditorDimensions);
2022-12-29 23:33:04 +00:00
provide(SymRootElement, el);
const inlineClients = shallowRef([]);
provide(SymFormattingToolbarClients, inlineClients);
provide(SymFormattingToolbarActiveClient, ref(null));
2020-05-28 20:16:35 +00:00
2020-05-27 13:57:57 +00:00
const mode = ref(props.mode);
2022-03-15 23:38:33 +00:00
provide(SymMode, mode);
2020-05-27 13:57:57 +00:00
2022-03-20 13:49:44 +00:00
watch(() => props.mode, (newMode) => {
mode.value = newMode;
});
2022-12-29 02:47:45 +00:00
const classes = computed(() => ({
'sb-main': true,
[`sb-main_${mode.value}`]: true,
}));
2020-05-24 15:33:25 +00:00
const activeBlock = ref(null);
2021-03-08 15:29:35 +00:00
provide(SymActiveBlock, activeBlock);
2020-05-20 14:21:08 +00:00
const blockTree: Ref<ITreeNode|null> = ref(null);
2021-03-08 15:29:35 +00:00
provide(SymBlockTree, blockTree);
provide(SymBlockTreeRegister, (block: ITreeNode) => { blockTree.value = block; });
2021-03-08 15:29:35 +00:00
provide(SymBlockTreeUnregister, () => { blockTree.value = null; });
2021-03-07 17:47:28 +00:00
const blockLibrary: IBlockLibrary = shallowReactive({
2022-03-12 16:42:42 +00:00
...props.availableBlocks.reduce(
(blocks: IBlockLibrary, block: IBlockDefinition<any>) => ({ ...blocks, [block.name]: block }),
2020-05-24 15:33:25 +00:00
{},
),
});
2021-03-08 15:29:35 +00:00
provide(SymBlockLibrary, blockLibrary);
2020-05-20 14:21:08 +00:00
const inlineToolLibrary: IFormattingToolLibrary = shallowReactive({
...props.availableFormattingTools.reduce(
(tools: IFormattingToolLibrary, tool: IFormattingTool) => ({ ...tools, [tool.name]: tool }),
2022-12-29 23:33:04 +00:00
{},
),
});
provide(SymFormattingToolLibrary, inlineToolLibrary);
2022-12-29 23:33:04 +00:00
2020-05-25 21:10:21 +00:00
return () => (
2020-05-28 20:16:35 +00:00
<div
2022-12-29 02:47:45 +00:00
class={classes.value}
2020-05-28 20:16:35 +00:00
ref={el}
>
2022-12-29 02:47:45 +00:00
<Transition
name="sb-main--menu"
mode="out-in"
>
{mode.value === SbMode.Edit
? <SbMainMenu
block={props.block}
class="sb-main--menu"
/>
: null}
</Transition>
2020-05-27 13:57:57 +00:00
<SbBlock
2022-12-29 02:47:45 +00:00
class="sb-main--block"
2020-05-27 13:57:57 +00:00
block={props.block}
2022-09-05 19:12:20 +00:00
eventUpdate={props.eventUpdate}
2020-05-27 13:57:57 +00:00
/>
<SbFormattingToolbar />
2020-05-27 13:57:57 +00:00
</div>
2020-05-20 14:21:08 +00:00
);
},
});