@silexlabs/silex 3.3.1-1 → 3.3.1-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Plugin options configuration for all GrapesJS plugins
3
+ */
4
+
5
+ import { EditorConfig } from 'grapesjs'
6
+ import { PluginDefinition } from './dynamic-plugins'
7
+ import { staticPlugins, cmdPromptAddSymbol, cmdTogglePages, cmdAddPage, cmdOpenSettings, PROJECT_BAR_PANEL_ID, cmdOpenNewPageDialog } from './static-plugins'
8
+ import { NotificationEditor } from '@silexlabs/grapesjs-notifications'
9
+ import { cmdKeymapsDialog } from '@silexlabs/grapesjs-keymaps-dialog'
10
+ // Commands will be imported from the main index file
11
+ export const cmdToggleLayers = 'open-layers'
12
+ export const cmdToggleBlocks = 'open-blocks'
13
+ export const cmdToggleSymbols = 'open-symbols'
14
+ export const cmdToggleNotifications = 'open-notifications'
15
+ import { ClientConfig } from '../config'
16
+ import { titleCase } from '../utils'
17
+ import { defaultKms } from './keymaps'
18
+
19
+ // Constants
20
+ const PRIMARY_COLOR = '#333333'
21
+ const SECONDARY_COLOR = '#ddd'
22
+ const TERTIARY_COLOR = '#8873FE'
23
+ const QUATERNARY_COLOR = '#A291FF'
24
+ const catBasic = 'Containers'
25
+ const catComponents = 'Components'
26
+
27
+ // Create notification container
28
+ const notificationContainer = document.createElement('div')
29
+
30
+ /**
31
+ * Get plugin options for static plugins
32
+ */
33
+ export function getStaticPluginOptions(config: ClientConfig) {
34
+ const { websiteId, storageId } = config
35
+
36
+ const projectBarPluginValue = staticPlugins.find(p => p.name === './project-bar')?.value
37
+ const imgPluginValue = staticPlugins.find(p => p.name === './img')?.value
38
+ const pagePanelPluginValue = staticPlugins.find(p => p.name === './page-panel')?.value
39
+ const internalLinksPluginValue = staticPlugins.find(p => p.name === './internal-links')?.value
40
+ const keymapsPluginValue = staticPlugins.find(p => p.name === './keymaps')?.value
41
+ const loginDialogPluginValue = staticPlugins.find(p => p.name === './LoginDialog')?.value
42
+
43
+ return {
44
+ [projectBarPluginValue?.toString()]: {
45
+ panels: [
46
+ {
47
+ id: 'dash',
48
+ className: 'logo',
49
+ attributes: { title: 'Dashboard' },
50
+ command: () => {
51
+ window.location.href = '/'
52
+ },
53
+ }, {
54
+ id: 'block-manager-btn',
55
+ className: 'block-manager-btn fa fa-fw fa-plus',
56
+ name: 'Blocks',
57
+ attributes: { title: `Blocks (${titleCase(defaultKms.kmBlocks.keys, '+')})`, containerClassName: 'block-manager-container', },
58
+ command: cmdToggleBlocks,
59
+ }, {
60
+ id: 'symbols-btn',
61
+ className: 'symbols-btn fa-regular fa-gem',
62
+ name: 'Symbols',
63
+ attributes: { title: `Symbols (${titleCase(defaultKms.kmSymbols.keys, '+')})`, containerClassName: 'symbols-list-container', },
64
+ command: cmdToggleSymbols,
65
+ buttons: [
66
+ {
67
+ id: 'symbol-create-button',
68
+ className: 'gjs-pn-btn',
69
+ command: cmdPromptAddSymbol,
70
+ text: '\u271A',
71
+ },
72
+ ],
73
+ }, {
74
+ id: 'page-panel-btn',
75
+ className: 'page-panel-btn fa fa-fw fa-file',
76
+ name: 'Pages',
77
+ attributes: { title: `Pages (${titleCase(defaultKms.kmPages.keys, '+')})`, containerClassName: 'page-panel-container', },
78
+ command: cmdTogglePages,
79
+ buttons: [{
80
+ className: 'gjs-pn-btn',
81
+ command: cmdAddPage,
82
+ text: '\u271A',
83
+ }],
84
+ }, {
85
+ id: 'layer-manager-btn',
86
+ className: 'layer-manager-btn fa-solid fa-layer-group',
87
+ name: 'Layers',
88
+ attributes: { title: `Layers (${titleCase(defaultKms.kmLayers.keys, '+')})`, containerClassName: 'layer-manager-container', },
89
+ command: cmdToggleLayers,
90
+ }, {
91
+ id: 'font-dialog-btn',
92
+ className: 'font-manager-btn fa-solid fa-font',
93
+ name: 'Fonts',
94
+ attributes: { title: `Fonts (${titleCase(defaultKms.kmOpenFonts.keys, '+')})` },
95
+ command: () => {
96
+ // @ts-ignore - editor will be available at runtime
97
+ editor.runCommand('open-fonts')
98
+ },
99
+ }, {
100
+ id: 'settings-dialog-btn',
101
+ className: 'page-panel-btn fa-solid fa-gears',
102
+ name: 'Settings',
103
+ attributes: { title: `Settings (${titleCase(defaultKms.kmOpenSettings.keys, '+')})` },
104
+ command: cmdOpenSettings,
105
+ }, {
106
+ id: 'spacer',
107
+ attributes: {},
108
+ className: 'project-bar-spacer',
109
+ }, {
110
+ id: 'keymaps-btn',
111
+ className: 'keymaps-btn fa-solid fa-keyboard',
112
+ name: 'Shortcuts',
113
+ attributes: { title: 'Keyboard Shortcuts (Shift+H)' },
114
+ command: cmdKeymapsDialog,
115
+ }, {
116
+ id: 'notifications-btn',
117
+ className: 'notifications-btn fa-regular fa-bell',
118
+ name: 'Notifications',
119
+ attributes: { title: `Notifications (${titleCase(defaultKms.kmNotifications.keys, '+')})`, containerClassName: 'notifications-container', },
120
+ command: cmdToggleNotifications,
121
+ }, {
122
+ id: 'logout-btn',
123
+ className: 'logout-btn fa fa-fw fa-power-off',
124
+ name: 'Logout',
125
+ attributes: { title: 'Logout' },
126
+ command: () => {
127
+ // @ts-ignore - editor will be available at runtime
128
+ editor.runCommand('logout')
129
+ },
130
+ }],
131
+ },
132
+ ...(pagePanelPluginValue && {
133
+ [pagePanelPluginValue.toString()]: {
134
+ cmdOpenNewPageDialog,
135
+ cmdOpenSettings,
136
+ appendTo: '.page-panel-container',
137
+ }
138
+ }),
139
+ ...(internalLinksPluginValue && {
140
+ [internalLinksPluginValue.toString()]: {
141
+ // FIXME: warn the user about links in error
142
+ onError: (errors: any) => console.warn('Links errors:', errors),
143
+ }
144
+ }),
145
+ ...(keymapsPluginValue && {
146
+ [keymapsPluginValue.toString()]: {
147
+ disableKeymaps: false,
148
+ }
149
+ }),
150
+ ...(loginDialogPluginValue && {
151
+ [loginDialogPluginValue.toString()]: {
152
+ id: websiteId,
153
+ }
154
+ }),
155
+ ...(imgPluginValue && {
156
+ [imgPluginValue.toString()]: {
157
+ replacedElements: config.replacedElements,
158
+ websiteId,
159
+ storageId,
160
+ }
161
+ }),
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Get plugin options for dynamic plugins
167
+ */
168
+ export function getDynamicPluginOptions(dynamicPlugins: PluginDefinition[], config: ClientConfig) {
169
+ const options: any = {}
170
+
171
+ dynamicPlugins.forEach(plugin => {
172
+ const pluginKey = plugin.value.toString()
173
+
174
+ switch (plugin.name) {
175
+ case 'grapesjs-blocks-basic':
176
+ options[pluginKey] = {
177
+ blocks: ['text', 'image', 'video', 'map'],
178
+ category: catBasic,
179
+ }
180
+ break
181
+
182
+ case '@silexlabs/grapesjs-fonts':
183
+ options[pluginKey] = {
184
+ api_key: (config as any).fontsApiKey || 'dummy-key-for-development',
185
+ server_url: (config as any).fontsServerUrl,
186
+ api_url: (config as any).fontsApiUrl,
187
+ }
188
+ break
189
+
190
+ case '@silexlabs/grapesjs-filter-styles':
191
+ options[pluginKey] = {
192
+ appendBefore: '.gjs-sm-sectors',
193
+ }
194
+ break
195
+
196
+ case 'grapesjs-custom-code':
197
+ options[pluginKey] = {
198
+ blockLabel: 'HTML',
199
+ blockCustomCode: {
200
+ category: catComponents,
201
+ },
202
+ codeViewOptions: {
203
+ autoFormat: false,
204
+ },
205
+ }
206
+ break
207
+
208
+ case '@silexlabs/grapesjs-symbols':
209
+ options[pluginKey] = {
210
+ appendTo: '.symbols-list-container',
211
+ emptyText: 'No symbol yet.',
212
+ primaryColor: PRIMARY_COLOR,
213
+ secondaryColor: SECONDARY_COLOR,
214
+ highlightColor: TERTIARY_COLOR,
215
+ }
216
+ break
217
+
218
+ case '@silexlabs/grapesjs-storage-rate-limit':
219
+ options[pluginKey] = {
220
+ time: 5000,
221
+ }
222
+ break
223
+
224
+ case '@silexlabs/grapesjs-notifications':
225
+ options[pluginKey] = {
226
+ container: notificationContainer,
227
+ reverse: true,
228
+ }
229
+ break
230
+
231
+ case '@silexlabs/grapesjs-keymaps-dialog':
232
+ options[pluginKey] = {
233
+ longPressDuration: null,
234
+ shortcut: 'shift+h',
235
+ }
236
+ break
237
+ }
238
+ })
239
+
240
+ return options
241
+ }
242
+
243
+ export { notificationContainer }
@@ -22,16 +22,17 @@ import { Component, Editor } from 'grapesjs'
22
22
  */
23
23
 
24
24
  export type SectorConfig = {
25
+ id: string
25
26
  name: string
26
27
  props: any[]
27
- shouldShow: (comp: Component) => boolean
28
+ shouldShow: (comp: Component) => boolean | Promise<boolean>
28
29
  }
29
30
 
30
31
  export function registerSector(editor: Editor, config: SectorConfig, at?: number) {
31
32
  const sm = editor.StyleManager
32
- let sector = sm.getSector(config.name)
33
+ let sector = sm.getSector(config.id)
33
34
  if (!sector) {
34
- sector = sm.addSector(config.name, { name: config.name, open: false, visible: false }, { at })
35
+ sector = sm.addSector(config.id, { name: config.name, open: false, visible: false }, { at })
35
36
  }
36
37
 
37
38
  // Add props if not already present
@@ -42,18 +43,15 @@ export function registerSector(editor: Editor, config: SectorConfig, at?: number
42
43
  }
43
44
  })
44
45
 
45
- // Keep sector in sync with internal visibility state
46
- sector.on('change:visible', () => {
47
- const shouldBeVisible = sector.get('visible')
48
- if (shouldBeVisible !== config.shouldShow(editor.getSelected() as Component)) {
49
- sector.set('visible', !shouldBeVisible)
50
- }
51
- })
52
-
53
- editor.on('component:selected', comp => {
54
- const shouldShow = config.shouldShow(comp)
46
+ async function applyVisibility(comp: Component = editor.getSelected()) {
47
+ const shouldShow = await config.shouldShow(comp)
55
48
  if (sector.get('visible') !== shouldShow) {
56
49
  sector.set('visible', shouldShow)
50
+ // sector.getProperties()
51
+ // .forEach(p => p.set('visible', shouldShow))
57
52
  }
58
- })
53
+ }
54
+
55
+ sector.on('change:visible', () => applyVisibility())
56
+ editor.on('component:selected', comp => applyVisibility(comp))
59
57
  }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Static plugin definitions for internal GrapesJS plugins
3
+ * These are bundled with the main application
4
+ */
5
+
6
+ import symbolDialogsPlugin, { cmdPromptAddSymbol } from './symbolDialogs'
7
+ import loginDialogPlugin, { LoginDialogOptions, cmdLogout } from './LoginDialog'
8
+ import footerPlugin from './footer'
9
+ import breadcrumbsPlugin from './breadcrumbs'
10
+ import imgPlugin from './img'
11
+ import liPlugin from './li'
12
+ import flexPlugin from './flex'
13
+ import cssPropsPlugin from './css-props'
14
+ import resizePanelPlugin from './resize-panel'
15
+ import { pagePanelPlugin, cmdTogglePages, cmdAddPage } from './page-panel'
16
+ import { newPageDialog, cmdOpenNewPageDialog } from './new-page-dialog'
17
+ import { PROJECT_BAR_PANEL_ID, projectBarPlugin } from './project-bar'
18
+ import { settingsDialog, cmdOpenSettings } from './settings'
19
+ import { blocksPlugin } from './blocks'
20
+ import ViewButtons from './view-buttons'
21
+ import { semanticPlugin } from './semantic'
22
+ import { richTextPlugin } from './rich-text'
23
+ import { internalLinksPlugin } from './internal-links'
24
+ import { keymapsPlugin } from './keymaps'
25
+ import publicationManagerPlugin from './PublicationManager'
26
+ import { storagePlugin } from './storage'
27
+ import uploadProgress from './upload-progress'
28
+
29
+ export interface PluginDefinition {
30
+ name: string
31
+ value: any
32
+ }
33
+
34
+ export const staticPlugins: PluginDefinition[] = [
35
+ { name: './symbolDialogs', value: symbolDialogsPlugin },
36
+ { name: './LoginDialog', value: loginDialogPlugin },
37
+ { name: './footer', value: footerPlugin },
38
+ { name: './breadcrumbs', value: breadcrumbsPlugin },
39
+ { name: './img', value: imgPlugin },
40
+ { name: './li', value: liPlugin },
41
+ { name: './flex', value: flexPlugin },
42
+ { name: './css-props', value: cssPropsPlugin },
43
+ { name: './resize-panel', value: resizePanelPlugin },
44
+ { name: './page-panel', value: pagePanelPlugin },
45
+ { name: './new-page-dialog', value: newPageDialog },
46
+ { name: './project-bar', value: projectBarPlugin },
47
+ { name: './settings', value: settingsDialog },
48
+ { name: './blocks', value: blocksPlugin },
49
+ { name: './view-buttons', value: ViewButtons },
50
+ { name: './semantic', value: semanticPlugin },
51
+ { name: './rich-text', value: richTextPlugin },
52
+ { name: './internal-links', value: internalLinksPlugin },
53
+ { name: './keymaps', value: keymapsPlugin },
54
+ { name: './PublicationManager', value: publicationManagerPlugin },
55
+ { name: './storage', value: storagePlugin },
56
+ { name: './upload-progress', value: uploadProgress },
57
+ ]
58
+
59
+ // Validate all static plugins are loaded correctly
60
+ staticPlugins
61
+ .filter(p => typeof p.value !== 'function')
62
+ .forEach(p => {
63
+ throw new Error(`Plugin ${p.name} could not be loaded correctly (${p.value})`)
64
+ })
65
+
66
+ // Export named functions for use in plugin options
67
+ export {
68
+ cmdPromptAddSymbol,
69
+ cmdLogout,
70
+ cmdTogglePages,
71
+ cmdAddPage,
72
+ cmdOpenNewPageDialog,
73
+ PROJECT_BAR_PANEL_ID,
74
+ cmdOpenSettings,
75
+ }