-
Notifications
You must be signed in to change notification settings - Fork 3
/
example.ts
147 lines (121 loc) · 4.33 KB
/
example.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// This file is only used by Vite during development.
// It is ignored when the files are built.
// It is an example, a demonstration.
import 'grapesjs/dist/css/grapes.min.css'
import grapesjs, { usePlugin } from 'grapesjs'
import grapesjsBlocks from 'grapesjs-blocks-basic'
import grapesjsClick, { getMouseListener, hideGrabbedInfo, showGrabbedInfo } from './plugin'
import { grabBlockCommand, dropBlockCommand, grabComponentCommand, dropComponentCommand } from './utils/constant'
import type { Editor, Block, Component } from 'grapesjs'
import type { CommandOptions } from './types'
const grabIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path fill="currentColor" d="M188 76a31.85 31.85 0 0 0-11.21 2A32 32 0 0 0 128 67a32 32 0 0 0-52 25v16h-8a32 32 0 0 0-32 32v12a92 92 0 0 0 184 0v-44a32 32 0 0 0-32-32m8 76a68 68 0 0 1-136 0v-12a8 8 0 0 1 8-8h8v20a12 12 0 0 0 24 0V92a8 8 0 0 1 16 0v28a12 12 0 0 0 24 0V92a8 8 0 0 1 16 0v28a12 12 0 0 0 24 0v-12a8 8 0 0 1 16 0Z"/></svg>'
function updateBlocks (editor: Editor) {
const blockManager = editor.Blocks
const blocks = blockManager.getAll()
for (const block of blocks) {
block.set('onClick', () => {
const blockId = block.attributes.id
const commandOptions: CommandOptions = {
id: blockId,
isDebugging: true
}
editor.runCommand(grabBlockCommand, commandOptions)
})
}
}
function resetGrabbedInfo (element: HTMLElement) {
element.textContent = ''
element.style.top = '0'
element.style.left = '0'
}
function capitalizeValue (value?: string) {
if (typeof value !== 'string') {
return ''
}
return (
value.charAt(0).toUpperCase() +
value.replace(/[_-]+/, ' ').slice(1)
)
}
function runExample () {
const protectedCss: string = `
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body, [data-gjs-type="wrapper"] {
width: 100%;
height: 100%;
}
`
const editor = grapesjs.init({
container: '#editor', // same as id in the "index.html" file
height: '100vh',
canvas: {
infiniteCanvas: true
},
fromElement: true,
storageManager: false,
protectedCss,
plugins: [
usePlugin(grapesjsBlocks, {
flexGrid: true
}),
usePlugin(grapesjsClick)
]
})
const grabbedInfoEl = document.getElementById('grabbed-info')!
const mouseListener = getMouseListener(editor, grabbedInfoEl)
// For demonstration purposes, set the click event for all blocks.
editor.once('load', () => {
console.log('Editor loaded', editor)
updateBlocks(editor)
})
// Update the toolbar of the selected component to add the grab action.
editor.on('component:selected', (selectedComponent: Component) => {
const { type: componentType } = selectedComponent.props()
const toolbar = selectedComponent.toolbar
const isWrapperComponent = componentType === 'wrapper'
const hasGrabbedAction = toolbar.some(({ command }) => command === grabComponentCommand)
if (
isWrapperComponent ||
hasGrabbedAction
) {
return
}
toolbar.unshift({
label: grabIcon,
command: grabComponentCommand,
attributes: {
title: 'Grab this component'
}
})
selectedComponent.set({ toolbar })
})
// Show information on the currently grabbed block and follow the mouse cursor.
editor.on(grabBlockCommand, (block: Block) => {
const label = block.getLabel()
const category = block.getCategoryLabel()
grabbedInfoEl.textContent = `${label} (${category})`
showGrabbedInfo(grabbedInfoEl, mouseListener)
})
// Hide information on the currently grabbed block, because it has been dropped.
editor.on(dropBlockCommand, () => {
resetGrabbedInfo(grabbedInfoEl)
hideGrabbedInfo(grabbedInfoEl, mouseListener)
})
// Show information on the currently grabbed component and follow the mouse cursor.
editor.on(grabComponentCommand, (component: Component) => {
const { name, type } = component.props()
const label = name || capitalizeValue(type)
grabbedInfoEl.textContent = label
showGrabbedInfo(grabbedInfoEl, mouseListener)
})
// Hide information on the currently grabbed component, because it has been dropped.
editor.on(dropComponentCommand, () => {
resetGrabbedInfo(grabbedInfoEl)
hideGrabbedInfo(grabbedInfoEl, mouseListener)
})
}
runExample()