@mframework/ui 0.1.0-beta.0 → 0.1.0-beta.1
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.
- package/dist/adapters/adapter-directus/src/types/ui.d.ts +21 -0
- package/dist/adapters/adapter-directus/src/types/ui.js +1 -0
- package/dist/module.d.mts +9 -0
- package/dist/module.d.ts +6 -0
- package/dist/module.js +68 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +38 -0
- package/dist/modules/ui/src/module.d.ts +8 -0
- package/dist/modules/ui/src/module.js +75 -0
- package/dist/modules/ui/src/runtime/composables/useMToast.d.ts +5 -0
- package/dist/modules/ui/src/runtime/composables/useMToast.js +11 -0
- package/dist/modules/ui/src/runtime/design/tokens.d.ts +22 -0
- package/dist/modules/ui/src/runtime/design/tokens.js +22 -0
- package/dist/modules/ui/src/runtime/plugins/builder.d.ts +3 -0
- package/dist/modules/ui/src/runtime/plugins/builder.js +311 -0
- package/dist/modules/ui/src/runtime/plugins/fontawesome.d.ts +3 -0
- package/dist/modules/ui/src/runtime/plugins/fontawesome.js +9 -0
- package/dist/modules/ui/src/runtime/plugins/formkit.d.ts +3 -0
- package/dist/modules/ui/src/runtime/plugins/formkit.js +8 -0
- package/dist/modules/ui/src/runtime/plugins/motion.d.ts +2 -0
- package/dist/modules/ui/src/runtime/plugins/motion.js +5 -0
- package/dist/modules/ui/src/runtime/plugins/theme-switcher.d.ts +2 -0
- package/dist/modules/ui/src/runtime/plugins/theme-switcher.js +27 -0
- package/dist/modules/ui/src/runtime/plugins/theme.d.ts +2 -0
- package/dist/modules/ui/src/runtime/plugins/theme.js +44 -0
- package/dist/modules/ui/src/runtime/plugins/vuetify.d.ts +3 -0
- package/dist/modules/ui/src/runtime/plugins/vuetify.js +33 -0
- package/dist/modules/ui/src/runtime/search/client.d.ts +2 -0
- package/dist/modules/ui/src/runtime/search/client.js +21 -0
- package/dist/modules/ui/src/runtime/search/plugin.d.ts +2 -0
- package/dist/modules/ui/src/runtime/search/plugin.js +7 -0
- package/dist/modules/ui/src/utils/color.d.ts +2 -0
- package/dist/modules/ui/src/utils/color.js +11 -0
- package/dist/modules/ui/src/utils/fonts.d.ts +5 -0
- package/dist/modules/ui/src/utils/fonts.js +18 -0
- package/dist/modules/ui/src/utils/formkit.d.ts +12 -0
- package/dist/modules/ui/src/utils/formkit.js +59 -0
- package/dist/modules/ui/src/utils/icons.d.ts +4 -0
- package/dist/modules/ui/src/utils/icons.js +36 -0
- package/dist/runtime/assets/config/tailwind.conifg.d.ts +0 -0
- package/dist/runtime/assets/config/tailwind.conifg.js +11 -0
- package/dist/runtime/components/MButton.d.vue.ts +0 -0
- package/dist/runtime/components/MButton.vue +15 -0
- package/dist/runtime/components/MButton.vue.d.ts +0 -0
- package/dist/runtime/composables/useMToast.d.ts +5 -0
- package/dist/runtime/composables/useMToast.js +11 -0
- package/dist/runtime/plugins/builder.d.ts +3 -0
- package/dist/runtime/plugins/builder.js +311 -0
- package/dist/runtime/plugins/fontawesome.d.ts +3 -0
- package/dist/runtime/plugins/fontawesome.js +9 -0
- package/dist/runtime/plugins/formkit.d.ts +3 -0
- package/dist/runtime/plugins/formkit.js +8 -0
- package/dist/runtime/plugins/icon-switcher.d.ts +1 -1
- package/dist/runtime/plugins/icon-switcher.js +15 -9
- package/dist/runtime/plugins/lightgallery.d.ts +6 -0
- package/dist/runtime/plugins/lightgallery.js +15 -0
- package/dist/runtime/plugins/motion.d.ts +2 -0
- package/dist/runtime/plugins/motion.js +5 -0
- package/dist/runtime/plugins/theme-switcher.d.ts +2 -0
- package/dist/runtime/plugins/theme-switcher.js +27 -0
- package/dist/runtime/plugins/theme.d.ts +1 -1
- package/dist/runtime/plugins/theme.js +31 -25
- package/dist/runtime/plugins/vuetify.d.ts +1 -86
- package/dist/runtime/plugins/vuetify.js +28 -55
- package/dist/runtime/search/components/MSearch.d.vue.ts +0 -0
- package/dist/runtime/search/components/MSearch.vue +19 -0
- package/dist/runtime/search/components/MSearch.vue.d.ts +0 -0
- package/dist/runtime/styles/index.css +5 -0
- package/dist/runtime/styles/tailwind.css +1 -0
- package/dist/runtime/styles/vuetify.css +3 -0
- package/dist/types.d.mts +9 -0
- package/dist/utils/color.d.ts +2 -0
- package/dist/utils/color.js +11 -0
- package/dist/utils/fonts.d.ts +5 -0
- package/dist/utils/fonts.js +18 -0
- package/dist/utils/formkit.d.ts +12 -0
- package/dist/utils/formkit.js +59 -0
- package/dist/utils/icons.d.ts +4 -0
- package/dist/utils/icons.js +36 -0
- package/package.json +12 -10
- package/src/module.ts +105 -0
- package/src/runtime/assets/config/tailwind.conifg.js +42 -0
- package/src/runtime/components/Gallery.vue +66 -0
- package/src/runtime/components/MButton.vue +17 -0
- package/src/runtime/composables/useMToast.ts +14 -0
- package/src/runtime/design/tokens.ts +22 -0
- package/src/runtime/plugins/builder.ts +326 -0
- package/src/runtime/plugins/fontawesome.ts +11 -0
- package/src/runtime/plugins/formkit.ts +9 -0
- package/src/runtime/plugins/lightgallery.js +21 -0
- package/src/runtime/plugins/motion.ts +6 -0
- package/src/runtime/plugins/theme-switcher.ts +32 -0
- package/src/runtime/plugins/theme.ts +57 -0
- package/src/runtime/plugins/vuetify.ts +36 -0
- package/src/runtime/search/client.ts +25 -0
- package/src/runtime/search/components/MSearch.vue +19 -0
- package/src/runtime/search/plugin.ts +9 -0
- package/src/runtime/styles/index.scss +101 -0
- package/src/runtime/styles/tailwind.css +9 -0
- package/src/runtime/styles/vuetify.scss +5 -0
- package/src/types/runtime-config.d.ts +12 -0
- package/src/utils/color.js +11 -0
- package/src/utils/color.ts +14 -0
- package/src/utils/fonts.js +18 -0
- package/src/utils/fonts.ts +24 -0
- package/src/utils/formkit.js +59 -0
- package/src/utils/formkit.ts +75 -0
- package/src/utils/icons.js +36 -0
- package/src/utils/icons.ts +62 -0
- package/dist/runtime/plugins/icons.d.ts +0 -4
- package/dist/runtime/plugins/icons.js +0 -13
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineNuxtPlugin
|
|
3
|
+
} from 'nuxt/app'
|
|
4
|
+
import 'grapesjs/dist/css/grapes.min.css'
|
|
5
|
+
import grapesjs from 'grapesjs'
|
|
6
|
+
|
|
7
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
8
|
+
if (process.server) return
|
|
9
|
+
|
|
10
|
+
const mount = () => {
|
|
11
|
+
const el = document.querySelector('#gjs')
|
|
12
|
+
if (!el) return null
|
|
13
|
+
|
|
14
|
+
const editor = grapesjs.init({
|
|
15
|
+
container: `${el}`,
|
|
16
|
+
fromElement: true,
|
|
17
|
+
height: '100%',
|
|
18
|
+
width: 'auto',
|
|
19
|
+
storageManager: {
|
|
20
|
+
type: 'local',
|
|
21
|
+
autosave: true,
|
|
22
|
+
autoload: true,
|
|
23
|
+
stepsBeforeSave: 1,
|
|
24
|
+
options: {
|
|
25
|
+
local: {
|
|
26
|
+
key: 'gjsProject'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
// Avoid any default panel
|
|
32
|
+
layerManager: {
|
|
33
|
+
appendTo: '.layers-container',
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
mediaCondition: 'min-width', // default is `max-width`
|
|
37
|
+
deviceManager: {
|
|
38
|
+
devices: [{
|
|
39
|
+
name: 'Desktop',
|
|
40
|
+
width: '', // default size
|
|
41
|
+
widthMedia: '1024px', // this value will be used in CSS @media
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'Mobile',
|
|
45
|
+
width: '320px', // this value will be used on canvas width
|
|
46
|
+
widthMedia: '480px', // this value will be used in CSS @media
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
blockManager: {
|
|
52
|
+
appendTo: '#blocks',
|
|
53
|
+
blocks: [{
|
|
54
|
+
id: 'section', // id is mandatory
|
|
55
|
+
label: '<b>Section</b>', // You can use HTML/SVG inside labels
|
|
56
|
+
category: 'Basic',
|
|
57
|
+
attributes: {
|
|
58
|
+
class: 'gjs-block-section'
|
|
59
|
+
},
|
|
60
|
+
content: {
|
|
61
|
+
tagName: 'div',
|
|
62
|
+
draggable: false,
|
|
63
|
+
attributes: {
|
|
64
|
+
'some-attribute': 'some-value'
|
|
65
|
+
},
|
|
66
|
+
components: [{
|
|
67
|
+
tagName: 'span',
|
|
68
|
+
content: '<b>Some static content</b>',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
tagName: 'div',
|
|
72
|
+
// use `content` for static strings, `components` string will be parsed
|
|
73
|
+
// and transformed in Components
|
|
74
|
+
components: '<span>HTML at some point</span>',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'text',
|
|
81
|
+
label: 'Text',
|
|
82
|
+
content: '<div data-gjs-type="text">Insert your text here</div>',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'image',
|
|
86
|
+
label: 'Image',
|
|
87
|
+
// Select the component once it's dropped
|
|
88
|
+
select: true,
|
|
89
|
+
// You can pass components as a JSON instead of a simple HTML string,
|
|
90
|
+
// in this case we also use a defined component type `image`
|
|
91
|
+
content: {
|
|
92
|
+
type: 'image'
|
|
93
|
+
},
|
|
94
|
+
// This triggers `active` event on dropped components and the `image`
|
|
95
|
+
// reacts by opening the AssetManager
|
|
96
|
+
activate: true,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
panels: {
|
|
101
|
+
defaults: [{
|
|
102
|
+
id: 'layers',
|
|
103
|
+
el: '.panel__right',
|
|
104
|
+
// Make the panel resizable
|
|
105
|
+
resizable: {
|
|
106
|
+
maxDim: 350,
|
|
107
|
+
minDim: 200,
|
|
108
|
+
tc: false, // Top handler
|
|
109
|
+
cl: true, // Left handler
|
|
110
|
+
cr: false, // Right handler
|
|
111
|
+
bc: false, // Bottom handler
|
|
112
|
+
// Being a flex child we need to change `flex-basis` property
|
|
113
|
+
// instead of the `width` (default)
|
|
114
|
+
keyWidth: 'flex-basis',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 'panel-switcher',
|
|
119
|
+
el: '.panel__switcher',
|
|
120
|
+
buttons: [{
|
|
121
|
+
id: 'show-layers',
|
|
122
|
+
active: true,
|
|
123
|
+
label: 'Layers',
|
|
124
|
+
command: 'show-layers',
|
|
125
|
+
// Once activated disable the possibility to turn it off
|
|
126
|
+
togglable: false,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 'show-style',
|
|
130
|
+
active: true,
|
|
131
|
+
label: 'Styles',
|
|
132
|
+
command: 'show-styles',
|
|
133
|
+
togglable: false,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 'show-traits',
|
|
137
|
+
active: true,
|
|
138
|
+
label: 'Traits',
|
|
139
|
+
command: 'show-traits',
|
|
140
|
+
togglable: false,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: 'panel-devices',
|
|
146
|
+
el: '.panel__devices',
|
|
147
|
+
buttons: [{
|
|
148
|
+
id: 'device-desktop',
|
|
149
|
+
label: 'D',
|
|
150
|
+
command: 'set-device-desktop',
|
|
151
|
+
active: true,
|
|
152
|
+
togglable: false,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: 'device-mobile',
|
|
156
|
+
label: 'M',
|
|
157
|
+
command: 'set-device-mobile',
|
|
158
|
+
togglable: false,
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
// The Selector Manager allows to assign classes and
|
|
165
|
+
// different states (eg. :hover) on components.
|
|
166
|
+
// Generally, it's used in conjunction with Style Manager
|
|
167
|
+
// but it's not mandatory
|
|
168
|
+
selectorManager: {
|
|
169
|
+
appendTo: '.styles-container',
|
|
170
|
+
},
|
|
171
|
+
styleManager: {
|
|
172
|
+
appendTo: '.styles-container',
|
|
173
|
+
sectors: [{
|
|
174
|
+
name: 'Dimension',
|
|
175
|
+
open: false,
|
|
176
|
+
// Use built-in properties
|
|
177
|
+
buildProps: ['width', 'min-height', 'padding'],
|
|
178
|
+
// Use `properties` to define/override single property
|
|
179
|
+
properties: [{
|
|
180
|
+
// Type of the input,
|
|
181
|
+
// options: integer | radio | select | color | slider | file | composite | stack
|
|
182
|
+
type: 'integer',
|
|
183
|
+
name: 'The width', // Label for the property
|
|
184
|
+
property: 'width', // CSS property (if buildProps contains it will be extended)
|
|
185
|
+
units: ['px', '%'], // Units, available only for 'integer' types
|
|
186
|
+
defaults: 'auto', // Default value
|
|
187
|
+
min: 0, // Min value, available only for 'integer' types
|
|
188
|
+
}, ],
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: 'Extra',
|
|
192
|
+
open: false,
|
|
193
|
+
buildProps: ['background-color', 'box-shadow', 'custom-prop'],
|
|
194
|
+
properties: [{
|
|
195
|
+
id: 'custom-prop',
|
|
196
|
+
name: 'Custom Label',
|
|
197
|
+
property: 'font-size',
|
|
198
|
+
type: 'select',
|
|
199
|
+
defaults: '32px',
|
|
200
|
+
// List of options, available only for 'select' and 'radio' types
|
|
201
|
+
options: [{
|
|
202
|
+
id: 'tiny',
|
|
203
|
+
value: '12px',
|
|
204
|
+
name: 'Tiny'
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
id: 'medium',
|
|
208
|
+
value: '18px',
|
|
209
|
+
name: 'Medium'
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
id: 'big',
|
|
213
|
+
value: '32px',
|
|
214
|
+
name: 'Big'
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
}, ],
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Define commands
|
|
224
|
+
editor.Commands.add('show-layers', {
|
|
225
|
+
getRowEl(editor: any) {
|
|
226
|
+
return editor.getContainer().closest('.editor-row');
|
|
227
|
+
},
|
|
228
|
+
getLayersEl(row: any) {
|
|
229
|
+
return row.querySelector('.layers-container');
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
run(editor: any, sender: any) {
|
|
233
|
+
const lmEl = this.getLayersEl(this.getRowEl(editor));
|
|
234
|
+
lmEl.style.display = '';
|
|
235
|
+
},
|
|
236
|
+
stop(editor: any, sender: any) {
|
|
237
|
+
const lmEl = this.getLayersEl(this.getRowEl(editor));
|
|
238
|
+
lmEl.style.display = 'none';
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
editor.Commands.add('show-styles', {
|
|
242
|
+
getRowEl(editor: any) {
|
|
243
|
+
return editor.getContainer().closest('.editor-row');
|
|
244
|
+
},
|
|
245
|
+
getStyleEl(row: any) {
|
|
246
|
+
return row.querySelector('.styles-container');
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
run(editor: any, sender: any) {
|
|
250
|
+
const smEl = this.getStyleEl(this.getRowEl(editor));
|
|
251
|
+
smEl.style.display = '';
|
|
252
|
+
},
|
|
253
|
+
stop(editor: any, sender: any) {
|
|
254
|
+
const smEl = this.getStyleEl(this.getRowEl(editor));
|
|
255
|
+
smEl.style.display = 'none';
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
editor.Commands.add('show-traits', {
|
|
260
|
+
getTraitsEl(editor: any) {
|
|
261
|
+
const row = editor.getContainer().closest('.editor-row');
|
|
262
|
+
return row.querySelector('.traits-container');
|
|
263
|
+
},
|
|
264
|
+
run(editor: any, sender: any) {
|
|
265
|
+
this.getTraitsEl(editor).style.display = '';
|
|
266
|
+
},
|
|
267
|
+
stop(editor: any, sender: any) {
|
|
268
|
+
this.getTraitsEl(editor).style.display = 'none';
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
editor.Panels.addPanel({
|
|
273
|
+
id: 'panel-top',
|
|
274
|
+
el: '.panel__top',
|
|
275
|
+
});
|
|
276
|
+
editor.Panels.addPanel({
|
|
277
|
+
id: 'basic-actions',
|
|
278
|
+
el: '.panel__basic-actions',
|
|
279
|
+
buttons: [{
|
|
280
|
+
id: 'visibility',
|
|
281
|
+
active: true, // active by default
|
|
282
|
+
className: 'btn-toggle-borders',
|
|
283
|
+
label: '<u>B</u>',
|
|
284
|
+
command: 'sw-visibility', // Built-in command
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
id: 'export',
|
|
288
|
+
className: 'btn-open-export',
|
|
289
|
+
label: 'Exp',
|
|
290
|
+
command: 'export-template',
|
|
291
|
+
context: 'export-template', // For grouping context of buttons from the same panel
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
id: 'show-json',
|
|
295
|
+
className: 'btn-show-json',
|
|
296
|
+
label: 'JSON',
|
|
297
|
+
context: 'show-json',
|
|
298
|
+
command(editor: any) {
|
|
299
|
+
editor.Modal.setTitle('Components JSON')
|
|
300
|
+
.setContent(
|
|
301
|
+
`<textarea style="width:100%; height: 250px;">
|
|
302
|
+
${JSON.stringify(editor.getComponents())}
|
|
303
|
+
</textarea>`,
|
|
304
|
+
)
|
|
305
|
+
.open();
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
});
|
|
310
|
+
editor.Commands.add('set-device-desktop', {
|
|
311
|
+
run: (editor) => editor.setDevice('Desktop'),
|
|
312
|
+
});
|
|
313
|
+
editor.Commands.add('set-device-mobile', {
|
|
314
|
+
run: (editor) => editor.setDevice('Mobile'),
|
|
315
|
+
});
|
|
316
|
+
editor.on('change:device', () => console.log('Current device: ', editor.getDevice()));
|
|
317
|
+
// Set initial device as Mobile
|
|
318
|
+
editor.setDevice('Mobile');
|
|
319
|
+
|
|
320
|
+
nuxtApp.provide('grapesStudio', editor)
|
|
321
|
+
return editor
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Auto‑mount when page loads
|
|
325
|
+
window.addEventListener('DOMContentLoaded', mount)
|
|
326
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineNuxtPlugin } from 'nuxt/app'
|
|
2
|
+
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
3
|
+
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
|
4
|
+
import { fas } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
+
import '@fortawesome/fontawesome-free/css/all.min.css'
|
|
6
|
+
|
|
7
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
8
|
+
library.add(fas)
|
|
9
|
+
|
|
10
|
+
nuxtApp.vueApp.component('Fa', FontAwesomeIcon)
|
|
11
|
+
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { defineNuxtPlugin } from 'nuxt/app'
|
|
2
|
+
import { plugin as formKitPlugin, defaultConfig } from '@formkit/vue'
|
|
3
|
+
import '@formkit/themes/genesis'
|
|
4
|
+
|
|
5
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
6
|
+
nuxtApp.vueApp.use(formKitPlugin, defaultConfig({
|
|
7
|
+
// You can inject your own inputs, locales, etc. here
|
|
8
|
+
}))
|
|
9
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineNuxtPlugin } from 'nuxt/app'
|
|
2
|
+
import lightGallery from 'lightgallery'
|
|
3
|
+
import lgZoom from 'lg-zoom'
|
|
4
|
+
import lgVideo from 'lg-video'
|
|
5
|
+
import lgThumbnail from 'lg-thumbnail'
|
|
6
|
+
import 'lightgallery/css/lightgallery.css'
|
|
7
|
+
import 'lightgallery/css/lg-zoom.css'
|
|
8
|
+
import 'lightgallery/css/lg-thumbnail.css'
|
|
9
|
+
import 'lightgallery/css/lg-video.css'
|
|
10
|
+
|
|
11
|
+
export default defineNuxtPlugin(() => {
|
|
12
|
+
// You can expose a composable or directive later if you want.
|
|
13
|
+
// For now, this ensures CSS + plugins are bundled.
|
|
14
|
+
// Example directive could be added here if needed.
|
|
15
|
+
document.querySelectorAll('.lightgallery').forEach((element) => {
|
|
16
|
+
lightGallery(element as HTMLElement, {
|
|
17
|
+
plugins: [lgZoom, lgVideo, lgThumbnail],
|
|
18
|
+
speed: 500,
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { defineNuxtPlugin } from 'nuxt/app'
|
|
2
|
+
import { useTheme } from 'vuetify'
|
|
3
|
+
|
|
4
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
5
|
+
if (process.server) return
|
|
6
|
+
|
|
7
|
+
const theme = useTheme()
|
|
8
|
+
|
|
9
|
+
const setTheme = (mode: 'light' | 'dark') => {
|
|
10
|
+
theme.global.name.value = mode
|
|
11
|
+
document.documentElement.classList.toggle('dark', mode === 'dark')
|
|
12
|
+
localStorage.setItem('mframework-theme', mode)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const toggleTheme = () => {
|
|
16
|
+
const current = theme.global.name.value === 'light' ? 'dark' : 'light'
|
|
17
|
+
setTheme(current)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Load saved theme
|
|
21
|
+
const saved = localStorage.getItem('mframework-theme')
|
|
22
|
+
if (saved === 'light' || saved === 'dark') {
|
|
23
|
+
setTheme(saved)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Expose composable
|
|
27
|
+
nuxtApp.provide('mTheme', {
|
|
28
|
+
setTheme,
|
|
29
|
+
toggleTheme,
|
|
30
|
+
current: () => theme.global.name.value
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineNuxtPlugin,
|
|
3
|
+
useRuntimeConfig
|
|
4
|
+
} from 'nuxt/app'
|
|
5
|
+
import {
|
|
6
|
+
useTheme
|
|
7
|
+
} from 'vuetify'
|
|
8
|
+
|
|
9
|
+
export default defineNuxtPlugin(() => {
|
|
10
|
+
if (process.server) return
|
|
11
|
+
|
|
12
|
+
const theme = useTheme()
|
|
13
|
+
const config = useRuntimeConfig()
|
|
14
|
+
|
|
15
|
+
const baseColors = {
|
|
16
|
+
primary: 'var(--m-primary)',
|
|
17
|
+
secondary: 'var(--m-secondary)',
|
|
18
|
+
accent: 'var(--m-accent)',
|
|
19
|
+
surface: 'var(--m-surface)',
|
|
20
|
+
background: 'var(--m-muted)',
|
|
21
|
+
border: 'var(--m-border)',
|
|
22
|
+
|
|
23
|
+
// Required Vuetify system colors
|
|
24
|
+
success: '#22c55e',
|
|
25
|
+
warning: '#f59e0b',
|
|
26
|
+
error: '#ef4444',
|
|
27
|
+
info: '#3b82f6',
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// Vuetify internal required fields
|
|
31
|
+
'on-primary': '#ffffff',
|
|
32
|
+
'on-secondary': '#ffffff',
|
|
33
|
+
'on-surface': '#ffffff',
|
|
34
|
+
'on-background': '#ffffff',
|
|
35
|
+
'on-success': '#ffffff',
|
|
36
|
+
'on-warning': '#ffffff',
|
|
37
|
+
'on-error': '#ffffff',
|
|
38
|
+
'on-info': '#ffffff'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const defaultTheme = config.public.mframeworkUi?.theme || 'light'
|
|
42
|
+
|
|
43
|
+
theme.global.name.value = defaultTheme
|
|
44
|
+
|
|
45
|
+
theme.themes.value = {
|
|
46
|
+
light: {
|
|
47
|
+
dark: false,
|
|
48
|
+
colors: baseColors,
|
|
49
|
+
variables: {}
|
|
50
|
+
},
|
|
51
|
+
dark: {
|
|
52
|
+
dark: true,
|
|
53
|
+
colors: baseColors,
|
|
54
|
+
variables: {}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
})
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useRuntimeConfig } from 'nuxt/app'
|
|
2
|
+
import { createVuetify } from 'vuetify'
|
|
3
|
+
import * as components from 'vuetify/components'
|
|
4
|
+
import * as directives from 'vuetify/directives'
|
|
5
|
+
import 'vuetify/styles'
|
|
6
|
+
|
|
7
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
8
|
+
const config = useRuntimeConfig()
|
|
9
|
+
const theme = config.public.mframeworkUi?.theme || 'light'
|
|
10
|
+
|
|
11
|
+
const vuetify = createVuetify({
|
|
12
|
+
components,
|
|
13
|
+
directives,
|
|
14
|
+
theme: {
|
|
15
|
+
defaultTheme: theme,
|
|
16
|
+
themes: {
|
|
17
|
+
light: {
|
|
18
|
+
dark: false,
|
|
19
|
+
colors: {
|
|
20
|
+
primary: '#3b82f6',
|
|
21
|
+
secondary: '#64748b'
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
dark: {
|
|
25
|
+
dark: true,
|
|
26
|
+
colors: {
|
|
27
|
+
primary: '#3b82f6',
|
|
28
|
+
secondary: '#64748b'
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
nuxtApp.vueApp.use(vuetify)
|
|
36
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SearchClient } from 'instantsearch.js'
|
|
2
|
+
|
|
3
|
+
export function getSearchClient(): SearchClient | null {
|
|
4
|
+
let mod: any
|
|
5
|
+
try {
|
|
6
|
+
mod = require('@searchkit/instantsearch-client')
|
|
7
|
+
} catch {
|
|
8
|
+
console.warn('[mframework-ui] Searchkit client missing')
|
|
9
|
+
return null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const candidate =
|
|
13
|
+
mod?.default?.default ||
|
|
14
|
+
mod?.default?.createClient ||
|
|
15
|
+
mod?.default ||
|
|
16
|
+
mod?.createClient ||
|
|
17
|
+
mod
|
|
18
|
+
|
|
19
|
+
if (typeof candidate !== 'function') return null
|
|
20
|
+
|
|
21
|
+
const host = process.env.NUXT_PUBLIC_SEARCHKIT_HOST
|
|
22
|
+
if (!host) return null
|
|
23
|
+
|
|
24
|
+
return candidate({ host })
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ais-instant-search :search-client="client" :index-name="index">
|
|
3
|
+
<ais-search-box />
|
|
4
|
+
<ais-hits>
|
|
5
|
+
<template #item="{ item }">
|
|
6
|
+
<slot name="hit" :item="item">
|
|
7
|
+
<div class="p-2 border rounded">
|
|
8
|
+
<ais-highlight attribute="title" :hit="item" />
|
|
9
|
+
</div>
|
|
10
|
+
</slot>
|
|
11
|
+
</template>
|
|
12
|
+
</ais-hits>
|
|
13
|
+
</ais-instant-search>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script setup lang="ts">
|
|
17
|
+
const client = inject('mSearchClient')
|
|
18
|
+
const index = inject('mSearchIndex')
|
|
19
|
+
</script>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getSearchClient } from './client'
|
|
2
|
+
|
|
3
|
+
export default (nuxtApp: any) => {
|
|
4
|
+
const client = getSearchClient()
|
|
5
|
+
const indexName = process.env.NUXT_PUBLIC_SEARCH_INDEX || 'default'
|
|
6
|
+
|
|
7
|
+
nuxtApp.provide('mSearchClient', client)
|
|
8
|
+
nuxtApp.provide('mSearchIndex', indexName)
|
|
9
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
@import './tailwind.css';
|
|
2
|
+
|
|
3
|
+
// Your design tokens, utilities, etc.
|
|
4
|
+
:root {
|
|
5
|
+
--m-primary: #3b82f6;
|
|
6
|
+
--m-secondary: #64748b;
|
|
7
|
+
--m-accent: #10b981;
|
|
8
|
+
--m-muted: #f3f4f6;
|
|
9
|
+
--m-surface: #ffffff;
|
|
10
|
+
--m-border: #e5e7eb;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.dark {
|
|
14
|
+
--m-primary: #60a5fa;
|
|
15
|
+
--m-secondary: #94a3b8;
|
|
16
|
+
--m-accent: #34d399;
|
|
17
|
+
--m-muted: #1f2937;
|
|
18
|
+
--m-surface: #111827;
|
|
19
|
+
--m-border: #374151;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// GrapesJS canvas and editor styling
|
|
23
|
+
/* Let's highlight canvas boundaries */
|
|
24
|
+
#gjs {
|
|
25
|
+
border: 3px solid #444;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Theming */
|
|
29
|
+
|
|
30
|
+
/* Primary color for the background */
|
|
31
|
+
.gjs-one-bg {
|
|
32
|
+
background-color: #78366a;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Secondary color for the text color */
|
|
36
|
+
.gjs-two-color {
|
|
37
|
+
color: rgba(255, 255, 255, 0.7);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Tertiary color for the background */
|
|
41
|
+
.gjs-three-bg {
|
|
42
|
+
background-color: #ec5896;
|
|
43
|
+
color: white;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Quaternary color for the text color */
|
|
47
|
+
.gjs-four-color,
|
|
48
|
+
.gjs-four-color-h:hover {
|
|
49
|
+
color: #ec5896;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Reset some default styling */
|
|
53
|
+
.gjs-cv-canvas {
|
|
54
|
+
top: 0;
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 100%;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.gjs-block {
|
|
60
|
+
width: auto;
|
|
61
|
+
height: auto;
|
|
62
|
+
min-height: auto;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.panel__top {
|
|
66
|
+
padding: 0;
|
|
67
|
+
width: 100%;
|
|
68
|
+
display: flex;
|
|
69
|
+
position: initial;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
justify-content: space-between;
|
|
72
|
+
}
|
|
73
|
+
.panel__basic-actions {
|
|
74
|
+
position: initial;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.editor-row {
|
|
78
|
+
display: flex;
|
|
79
|
+
justify-content: flex-start;
|
|
80
|
+
align-items: stretch;
|
|
81
|
+
flex-wrap: nowrap;
|
|
82
|
+
height: 300px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.editor-canvas {
|
|
86
|
+
flex-grow: 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.panel__right {
|
|
90
|
+
flex-basis: 230px;
|
|
91
|
+
position: relative;
|
|
92
|
+
overflow-y: auto;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.panel__switcher {
|
|
96
|
+
position: initial;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.panel__devices {
|
|
100
|
+
position: initial;
|
|
101
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* @mframework/ui/runtime/assets/css/tailwind.css */
|
|
2
|
+
|
|
3
|
+
/* Tailwind base (if using Tailwind 3 style) */
|
|
4
|
+
@import "tailwindcss/preflight";
|
|
5
|
+
|
|
6
|
+
/* Vuetify + Tailwind coexistence tips:
|
|
7
|
+
- Avoid global resets that fight Vuetify
|
|
8
|
+
- Prefer utility classes for layout, spacing, etc.
|
|
9
|
+
*/
|