Skip to content

Commit 5d473c7

Browse files
neSpeccgohabereg
andauthored
chore(ui): ui package bootstrapped (#96)
* ui package * enum added * on demand plugins init * lint * Update packages/core/src/entities/Ui.ts Co-authored-by: George Berezhnoy <[email protected]> * Update App.vue * fluent interface * Delete .eslintrc.cjs * upd clear --------- Co-authored-by: George Berezhnoy <[email protected]>
1 parent dcfde59 commit 5d473c7

24 files changed

+1605
-97
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { EventBus } from '../components/EventBus/index.js';
2+
import type { CoreConfigValidated } from './Config.js';
3+
import type { EditorAPI } from '../api/index.js';
4+
5+
/**
6+
* Parameters for EditorjsPlugin constructor
7+
*/
8+
export interface EditorjsPluginParams {
9+
/**
10+
* EditorJS config
11+
*/
12+
config: CoreConfigValidated;
13+
14+
/**
15+
* EditorAPI instance
16+
*/
17+
api: EditorAPI;
18+
19+
/**
20+
* EventBus instance
21+
*/
22+
eventBus: EventBus;
23+
}
24+
25+
/**
26+
* Base interface for UI plugins
27+
*/
28+
export interface EditorjsPlugin {
29+
/**
30+
* Destroy plugin instance
31+
*/
32+
destroy?(): void;
33+
}
34+
35+
/**
36+
* Constructor type for EditorjsPlugin
37+
*/
38+
export interface EditorjsPluginConstructor {
39+
/**
40+
* Create new EditorjsPlugin instance
41+
*/
42+
new (params: EditorjsPluginParams): EditorjsPlugin;
43+
44+
/**
45+
* Plugin type
46+
*/
47+
type: string;
48+
}

packages/core/src/entities/Ui.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* List of reserved UI component names
3+
*/
4+
export enum UiComponentType {
5+
/**
6+
* Main wrapper UI element
7+
*/
8+
Shell = 'shell',
9+
10+
/**
11+
* Blocks wrapper
12+
*/
13+
Blocks = 'blocks',
14+
15+
/**
16+
* Inline toolbar wrapper
17+
*/
18+
InlineToolbar = 'inline-toolbar',
19+
20+
/**
21+
* Toolbox wrapper
22+
*/
23+
Toolbox = 'toolbox'
24+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
export * from './Config.js';
22
export * from './UnifiedToolConfig.js';
3+
export * from './EditorjsPlugin.js';
4+
export * from './Ui.js';

packages/core/src/index.ts

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import { CaretAdapter, FormattingAdapter } from '@editorjs/dom-adapters';
77
import type { CoreConfigValidated } from './entities/Config.js';
88
import type { CoreConfig } from '@editorjs/sdk';
99
import { BlocksManager } from './components/BlockManager.js';
10-
import { EditorUI } from './ui/Editor/index.js';
11-
import { ToolboxUI } from './ui/Toolbox/index.js';
12-
import { InlineToolbarUI } from './ui/InlineToolbar/index.js';
1310
import { SelectionManager } from './components/SelectionManager.js';
11+
import { EventBus } from './components/EventBus/index.js';
12+
import type { EditorjsPluginConstructor } from './entities/EditorjsPlugin.js';
13+
import { EditorAPI } from './api/index.js';
14+
import { UiComponentType } from './entities/Ui.js';
1415

1516
/**
1617
* If no holder is provided via config, the editor will be appended to the element with this id
@@ -23,7 +24,6 @@ const DEFAULT_HOLDER_ID = 'editorjs';
2324
* - subscribes to model updates
2425
* - creates Adapters for Tools
2526
* - creates Tools
26-
* - adds Blocks accodring to model updates
2727
*/
2828
export default class Core {
2929
/**
@@ -71,10 +71,7 @@ export default class Core {
7171

7272
this.#iocContainer.set('EditorConfig', this.#config);
7373

74-
const { blocks } = composeDataFromVersion2(config.data ?? { blocks: [] });
75-
7674
this.#model = new EditorJSModel();
77-
7875
this.#iocContainer.set(EditorJSModel, this.#model);
7976

8077
this.#toolsManager = this.#iocContainer.get(ToolsManager);
@@ -92,8 +89,27 @@ export default class Core {
9289
config.onModelUpdate?.(this.#model);
9390
});
9491
}
92+
}
93+
94+
/**
95+
* Initialize and injects Plugin into the container
96+
* @param plugin - allows to pass any implementation of editor plugins
97+
*/
98+
public use(plugin: EditorjsPluginConstructor): Core {
99+
const pluginType = plugin.type;
100+
101+
this.#iocContainer.set(pluginType, plugin);
102+
103+
return this;
104+
}
105+
106+
/**
107+
* Initializes the core
108+
*/
109+
public initialize(): void {
110+
const { blocks } = composeDataFromVersion2(this.#config.data ?? { blocks: [] });
95111

96-
this.#prepareUI();
112+
this.initializePlugins();
97113

98114
this.#toolsManager.prepareTools()
99115
.then(() => {
@@ -105,15 +121,36 @@ export default class Core {
105121
}
106122

107123
/**
108-
* Renders Editor`s UI
124+
* Initialize all registered UI plugins
109125
*/
110-
#prepareUI(): void {
111-
const editorUI = this.#iocContainer.get(EditorUI);
126+
private initializePlugins(): void {
127+
/**
128+
* Get all registered plugin types from the container
129+
*/
130+
const pluginTypes = Object.values(UiComponentType) as string[];
131+
132+
for (const pluginType of pluginTypes) {
133+
const plugin = this.#iocContainer.get<EditorjsPluginConstructor>(pluginType);
112134

113-
this.#iocContainer.get(ToolboxUI);
114-
this.#iocContainer.get(InlineToolbarUI);
135+
if (plugin !== undefined && typeof plugin === 'function') {
136+
this.initializePlugin(plugin);
137+
}
138+
}
139+
}
115140

116-
editorUI.render();
141+
/**
142+
* Create instance of plugin
143+
* @param plugin - Plugin constructor to initialize
144+
*/
145+
private initializePlugin(plugin: EditorjsPluginConstructor): void {
146+
const eventBus = this.#iocContainer.get(EventBus);
147+
const api = this.#iocContainer.get(EditorAPI);
148+
149+
new plugin({
150+
config: this.#config,
151+
api,
152+
eventBus,
153+
});
117154
}
118155

119156
/**
@@ -147,4 +184,10 @@ export default class Core {
147184
}
148185
}
149186

187+
/**
188+
* @todo move to "sdk" package
189+
*/
150190
export * from './entities/index.js';
191+
export * from './components/EventBus/index.js';
192+
export * from './api/index.js';
193+
export * from './tools/facades/index.js';

packages/core/tsconfig.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"composite": true,
44
"target": "esnext",
55
"module": "esnext",
6-
"moduleResolution": "Node",
6+
"moduleResolution": "bundler",
77
"esModuleInterop": true,
88
"forceConsistentCasingInFileNames": true,
99
"strict": true,
@@ -12,7 +12,10 @@
1212
"emitDecoratorMetadata": true,
1313
"types": ["jest"],
1414
"rootDir": "src",
15-
"outDir": "dist"
15+
"outDir": "dist",
16+
"declaration": true,
17+
"declarationMap": true,
18+
"sourceMap": true
1619
},
1720
"include": ["src/**/*"],
1821
"exclude": [

packages/playground/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
"lint:fix": "yarn lint --fix"
1515
},
1616
"dependencies": {
17-
"@editorjs/core": "workspace:^",
17+
"@editorjs/core": "workspace:*",
1818
"@editorjs/dom-adapters": "workspace:^",
1919
"@editorjs/model": "workspace:^",
20+
"@editorjs/ui": "workspace:*",
2021
"vue": "^3.3.4"
2122
},
2223
"devDependencies": {

packages/playground/src/App.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { EditorDocument, EditorJSModel } from '@editorjs/model';
33
import Core from '@editorjs/core';
44
import { ref, onMounted } from 'vue';
55
import { Node } from './components';
6-
6+
import { EditorjsUI, BlocksUI, InlineToolbarUI, ToolboxUI } from '@editorjs/ui';
77
/**
88
* Editor document for visualizing
99
*/
@@ -20,7 +20,7 @@ const serialized = ref<EditorDocument['serialized'] | null>(null);
2020
*/
2121
2222
onMounted(() => {
23-
new Core({
23+
const core = new Core({
2424
holder: document.getElementById('editorjs') as HTMLElement,
2525
data: {
2626
blocks: [ {
@@ -35,6 +35,13 @@ onMounted(() => {
3535
editorDocument.value = model.devModeGetDocument();
3636
},
3737
});
38+
39+
core
40+
.use(EditorjsUI)
41+
.use(BlocksUI)
42+
.use(InlineToolbarUI)
43+
.use(ToolboxUI)
44+
.initialize();
3845
});
3946
4047
</script>

packages/playground/tsconfig.eslint.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,10 @@
22
"extends": "./tsconfig.json",
33
"include": [
44
".eslintrc.cjs"
5+
],
6+
"references": [
7+
{
8+
"path": "../ui/tsconfig.json"
9+
}
510
]
611
}

packages/playground/tsconfig.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
"references": [
2929
{
3030
"path": "./tsconfig.node.json"
31+
},
32+
{
33+
"path": "../ui/tsconfig.json"
34+
},
35+
{
36+
"path": "../core/tsconfig.json"
3137
}
3238
]
3339
}

packages/ui/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.yarn/*
2+
!.yarn/patches
3+
!.yarn/plugins
4+
!.yarn/releases
5+
!.yarn/sdks
6+
!.yarn/versions
7+
8+
# Swap the comments on the following lines if you don't wish to use zero-installs
9+
# Documentation here: https://yarnpkg.com/features/zero-installs
10+
#!.yarn/cache
11+
#.pnp.*
12+
13+
# IDE
14+
.idea/*
15+
16+
node_modules/*
17+
dist/*
18+
19+
# tests
20+
coverage/
21+
reports/
22+
23+
# stryker temp files
24+
.stryker-tmp

0 commit comments

Comments
 (0)