@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.
Files changed (111) hide show
  1. package/dist/adapters/adapter-directus/src/types/ui.d.ts +21 -0
  2. package/dist/adapters/adapter-directus/src/types/ui.js +1 -0
  3. package/dist/module.d.mts +9 -0
  4. package/dist/module.d.ts +6 -0
  5. package/dist/module.js +68 -0
  6. package/dist/module.json +9 -0
  7. package/dist/module.mjs +38 -0
  8. package/dist/modules/ui/src/module.d.ts +8 -0
  9. package/dist/modules/ui/src/module.js +75 -0
  10. package/dist/modules/ui/src/runtime/composables/useMToast.d.ts +5 -0
  11. package/dist/modules/ui/src/runtime/composables/useMToast.js +11 -0
  12. package/dist/modules/ui/src/runtime/design/tokens.d.ts +22 -0
  13. package/dist/modules/ui/src/runtime/design/tokens.js +22 -0
  14. package/dist/modules/ui/src/runtime/plugins/builder.d.ts +3 -0
  15. package/dist/modules/ui/src/runtime/plugins/builder.js +311 -0
  16. package/dist/modules/ui/src/runtime/plugins/fontawesome.d.ts +3 -0
  17. package/dist/modules/ui/src/runtime/plugins/fontawesome.js +9 -0
  18. package/dist/modules/ui/src/runtime/plugins/formkit.d.ts +3 -0
  19. package/dist/modules/ui/src/runtime/plugins/formkit.js +8 -0
  20. package/dist/modules/ui/src/runtime/plugins/motion.d.ts +2 -0
  21. package/dist/modules/ui/src/runtime/plugins/motion.js +5 -0
  22. package/dist/modules/ui/src/runtime/plugins/theme-switcher.d.ts +2 -0
  23. package/dist/modules/ui/src/runtime/plugins/theme-switcher.js +27 -0
  24. package/dist/modules/ui/src/runtime/plugins/theme.d.ts +2 -0
  25. package/dist/modules/ui/src/runtime/plugins/theme.js +44 -0
  26. package/dist/modules/ui/src/runtime/plugins/vuetify.d.ts +3 -0
  27. package/dist/modules/ui/src/runtime/plugins/vuetify.js +33 -0
  28. package/dist/modules/ui/src/runtime/search/client.d.ts +2 -0
  29. package/dist/modules/ui/src/runtime/search/client.js +21 -0
  30. package/dist/modules/ui/src/runtime/search/plugin.d.ts +2 -0
  31. package/dist/modules/ui/src/runtime/search/plugin.js +7 -0
  32. package/dist/modules/ui/src/utils/color.d.ts +2 -0
  33. package/dist/modules/ui/src/utils/color.js +11 -0
  34. package/dist/modules/ui/src/utils/fonts.d.ts +5 -0
  35. package/dist/modules/ui/src/utils/fonts.js +18 -0
  36. package/dist/modules/ui/src/utils/formkit.d.ts +12 -0
  37. package/dist/modules/ui/src/utils/formkit.js +59 -0
  38. package/dist/modules/ui/src/utils/icons.d.ts +4 -0
  39. package/dist/modules/ui/src/utils/icons.js +36 -0
  40. package/dist/runtime/assets/config/tailwind.conifg.d.ts +0 -0
  41. package/dist/runtime/assets/config/tailwind.conifg.js +11 -0
  42. package/dist/runtime/components/MButton.d.vue.ts +0 -0
  43. package/dist/runtime/components/MButton.vue +15 -0
  44. package/dist/runtime/components/MButton.vue.d.ts +0 -0
  45. package/dist/runtime/composables/useMToast.d.ts +5 -0
  46. package/dist/runtime/composables/useMToast.js +11 -0
  47. package/dist/runtime/plugins/builder.d.ts +3 -0
  48. package/dist/runtime/plugins/builder.js +311 -0
  49. package/dist/runtime/plugins/fontawesome.d.ts +3 -0
  50. package/dist/runtime/plugins/fontawesome.js +9 -0
  51. package/dist/runtime/plugins/formkit.d.ts +3 -0
  52. package/dist/runtime/plugins/formkit.js +8 -0
  53. package/dist/runtime/plugins/icon-switcher.d.ts +1 -1
  54. package/dist/runtime/plugins/icon-switcher.js +15 -9
  55. package/dist/runtime/plugins/lightgallery.d.ts +6 -0
  56. package/dist/runtime/plugins/lightgallery.js +15 -0
  57. package/dist/runtime/plugins/motion.d.ts +2 -0
  58. package/dist/runtime/plugins/motion.js +5 -0
  59. package/dist/runtime/plugins/theme-switcher.d.ts +2 -0
  60. package/dist/runtime/plugins/theme-switcher.js +27 -0
  61. package/dist/runtime/plugins/theme.d.ts +1 -1
  62. package/dist/runtime/plugins/theme.js +31 -25
  63. package/dist/runtime/plugins/vuetify.d.ts +1 -86
  64. package/dist/runtime/plugins/vuetify.js +28 -55
  65. package/dist/runtime/search/components/MSearch.d.vue.ts +0 -0
  66. package/dist/runtime/search/components/MSearch.vue +19 -0
  67. package/dist/runtime/search/components/MSearch.vue.d.ts +0 -0
  68. package/dist/runtime/styles/index.css +5 -0
  69. package/dist/runtime/styles/tailwind.css +1 -0
  70. package/dist/runtime/styles/vuetify.css +3 -0
  71. package/dist/types.d.mts +9 -0
  72. package/dist/utils/color.d.ts +2 -0
  73. package/dist/utils/color.js +11 -0
  74. package/dist/utils/fonts.d.ts +5 -0
  75. package/dist/utils/fonts.js +18 -0
  76. package/dist/utils/formkit.d.ts +12 -0
  77. package/dist/utils/formkit.js +59 -0
  78. package/dist/utils/icons.d.ts +4 -0
  79. package/dist/utils/icons.js +36 -0
  80. package/package.json +12 -10
  81. package/src/module.ts +105 -0
  82. package/src/runtime/assets/config/tailwind.conifg.js +42 -0
  83. package/src/runtime/components/Gallery.vue +66 -0
  84. package/src/runtime/components/MButton.vue +17 -0
  85. package/src/runtime/composables/useMToast.ts +14 -0
  86. package/src/runtime/design/tokens.ts +22 -0
  87. package/src/runtime/plugins/builder.ts +326 -0
  88. package/src/runtime/plugins/fontawesome.ts +11 -0
  89. package/src/runtime/plugins/formkit.ts +9 -0
  90. package/src/runtime/plugins/lightgallery.js +21 -0
  91. package/src/runtime/plugins/motion.ts +6 -0
  92. package/src/runtime/plugins/theme-switcher.ts +32 -0
  93. package/src/runtime/plugins/theme.ts +57 -0
  94. package/src/runtime/plugins/vuetify.ts +36 -0
  95. package/src/runtime/search/client.ts +25 -0
  96. package/src/runtime/search/components/MSearch.vue +19 -0
  97. package/src/runtime/search/plugin.ts +9 -0
  98. package/src/runtime/styles/index.scss +101 -0
  99. package/src/runtime/styles/tailwind.css +9 -0
  100. package/src/runtime/styles/vuetify.scss +5 -0
  101. package/src/types/runtime-config.d.ts +12 -0
  102. package/src/utils/color.js +11 -0
  103. package/src/utils/color.ts +14 -0
  104. package/src/utils/fonts.js +18 -0
  105. package/src/utils/fonts.ts +24 -0
  106. package/src/utils/formkit.js +59 -0
  107. package/src/utils/formkit.ts +75 -0
  108. package/src/utils/icons.js +36 -0
  109. package/src/utils/icons.ts +62 -0
  110. package/dist/runtime/plugins/icons.d.ts +0 -4
  111. 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,6 @@
1
+ import { defineNuxtPlugin } from 'nuxt/app'
2
+ import { MotionPlugin } from '@vueuse/motion'
3
+
4
+ export default defineNuxtPlugin((nuxtApp) => {
5
+ nuxtApp.vueApp.use(MotionPlugin)
6
+ })
@@ -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
+ */
@@ -0,0 +1,5 @@
1
+ // Override Vuetify variables or add global Vuetify-related styles here.
2
+
3
+ body {
4
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
5
+ }
@@ -0,0 +1,12 @@
1
+ declare module 'nuxt/schema' {
2
+ interface PublicRuntimeConfig {
3
+ mframeworkUi?: {
4
+ theme?: 'light' | 'dark'
5
+ builder?: {
6
+ enabled?: boolean
7
+ }
8
+ }
9
+ }
10
+ }
11
+
12
+ export {}