vue-wswg-editor 0.0.6 → 0.0.7
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/types/components/PageRenderer/blockModules.d.ts +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/dist/types/util/registry.d.ts +2 -3
- package/dist/types/vite-plugin.d.ts +9 -0
- package/dist/vite-plugin.js +43 -0
- package/package.json +9 -3
- package/src/components/WswgJsonEditor/WswgJsonEditor.vue +3 -5
- package/src/shims.d.ts +17 -0
- package/src/util/registry.ts +122 -41
- package/src/vite-plugin.ts +65 -0
- package/dist/style.css +0 -1
- package/dist/vue-wswg-editor.es.js +0 -3377
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const blockModules: Record<string, string> | Record<string, () => Promise<any
|
|
1
|
+
export declare const blockModules: Record<string, any> | Record<string, string> | Record<string, () => Promise<any>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../../src/index.ts","../../src/shims.d.ts","../../src/vite-plugin.ts","../../src/components/pagerenderer/blockmodules.ts","../../src/components/wswgjsoneditor/wswgjsoneditor.test.ts","../../src/types/block.d.ts","../../src/types/layout.d.ts","../../src/util/fieldconfig.ts","../../src/util/helpers.ts","../../src/util/registry.ts","../../src/util/validation.ts","../../src/components/addblockitem/addblockitem.vue","../../src/components/blockbrowser/blockbrowser.vue","../../src/components/blockcomponent/blockcomponent.vue","../../src/components/blockeditorfieldnode/blockeditorfieldnode.vue","../../src/components/blockeditorfields/blockeditorfields.vue","../../src/components/blockmarginfieldnode/blockmarginnode.vue","../../src/components/blockrepeaterfieldnode/blockrepeaternode.vue","../../src/components/browsernavigation/browsernavigation.vue","../../src/components/emptystate/emptystate.vue","../../src/components/pageblocklist/pageblocklist.vue","../../src/components/pagebuildersidebar/pagebuildersidebar.vue","../../src/components/pagebuildertoolbar/pagebuildertoolbar.vue","../../src/components/pagerenderer/pagerenderer.vue","../../src/components/pagesettings/pagesettings.vue","../../src/components/resizehandle/resizehandle.vue","../../src/components/wswgjsoneditor/wswgjsoneditor.vue"],"version":"5.8.3"}
|
|
@@ -3,8 +3,7 @@ import type { EditorFieldConfig } from "./fieldConfig";
|
|
|
3
3
|
import type { Block } from "../types/Block";
|
|
4
4
|
import type { Layout } from "../types/Layout";
|
|
5
5
|
/**
|
|
6
|
-
* Registry of all page builder blocks
|
|
7
|
-
* Automatically populated from the /page-builder/blocks directory of your app
|
|
6
|
+
* Registry of all page builder blocks, layouts & fields
|
|
8
7
|
*/
|
|
9
8
|
export declare const pageBuilderBlocks: Ref<Record<string, Block>>;
|
|
10
9
|
export declare const pageBuilderLayouts: Ref<Record<string, Layout>>;
|
|
@@ -18,4 +17,4 @@ export declare function getLayouts(): Record<string, Layout>;
|
|
|
18
17
|
export declare function getBlockThumbnailUrl(directory: string | undefined): string | undefined;
|
|
19
18
|
export declare function getBlockComponent(blockType: string): Block | undefined;
|
|
20
19
|
export declare function getLayoutFields(layoutName: string): Record<string, EditorFieldConfig>;
|
|
21
|
-
export declare function initialiseRegistry(): void
|
|
20
|
+
export declare function initialiseRegistry(): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
export interface VueWswgEditorPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Root directory in the host project.
|
|
5
|
+
* Example: "@/features/homepage"
|
|
6
|
+
*/
|
|
7
|
+
rootDir: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function vueWswgEditorPlugin(options: VueWswgEditorPluginOptions): Plugin;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function s(r) {
|
|
2
|
+
const e = {
|
|
3
|
+
blocks: "\0vue-wswg-editor:blocks",
|
|
4
|
+
fields: "\0vue-wswg-editor:fields",
|
|
5
|
+
layouts: "\0vue-wswg-editor:layouts",
|
|
6
|
+
thumbnails: "\0vue-wswg-editor:thumbnails"
|
|
7
|
+
};
|
|
8
|
+
return {
|
|
9
|
+
name: "vue-wswg-editor-glob-plugin",
|
|
10
|
+
enforce: "pre",
|
|
11
|
+
// Run before other plugins to ensure import.meta.glob is processed correctly
|
|
12
|
+
resolveId(t) {
|
|
13
|
+
if (t.startsWith("vue-wswg-editor:")) {
|
|
14
|
+
const u = t.replace("vue-wswg-editor:", "");
|
|
15
|
+
if (u in e)
|
|
16
|
+
return e[u];
|
|
17
|
+
}
|
|
18
|
+
if (Object.values(e).includes(t))
|
|
19
|
+
return t;
|
|
20
|
+
},
|
|
21
|
+
load(t) {
|
|
22
|
+
switch (t) {
|
|
23
|
+
case e.layouts:
|
|
24
|
+
return `export const modules = import.meta.glob("${r.rootDir}/layout/**/*.vue", { eager: true });`;
|
|
25
|
+
case e.blocks:
|
|
26
|
+
return `export const modules = import.meta.glob("${r.rootDir}/blocks/**/*.vue", { eager: true });`;
|
|
27
|
+
case e.fields:
|
|
28
|
+
return `export const modules = import.meta.glob("${r.rootDir}/blocks/**/fields.ts", { eager: true });`;
|
|
29
|
+
case e.thumbnails:
|
|
30
|
+
return `export const modules = import.meta.glob("${r.rootDir}/blocks/**/thumbnail.png", { eager: true });`;
|
|
31
|
+
default:
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
transform(t, o) {
|
|
36
|
+
if (Object.values(e).includes(o))
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
s as vueWswgEditorPlugin
|
|
43
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-wswg-editor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"import": "./src/components/PageRenderer/PageRenderer.vue",
|
|
16
16
|
"types": "./src/components/PageRenderer/PageRenderer.vue"
|
|
17
17
|
},
|
|
18
|
+
"./vite-plugin": {
|
|
19
|
+
"import": "./dist/vite-plugin.js",
|
|
20
|
+
"require": "./dist/vite-plugin.js",
|
|
21
|
+
"types": "./src/vite-plugin.ts"
|
|
22
|
+
},
|
|
18
23
|
"./style.css": "./dist/style.css"
|
|
19
24
|
},
|
|
20
25
|
"files": [
|
|
@@ -22,8 +27,8 @@
|
|
|
22
27
|
"src"
|
|
23
28
|
],
|
|
24
29
|
"scripts": {
|
|
25
|
-
"dev": "vite build --watch",
|
|
26
|
-
"build": "vite build && vue-tsc --declaration --emitDeclarationOnly",
|
|
30
|
+
"dev": "concurrently \"vite build --watch\" \"vite build --config vite-plugin.config.ts --watch\"",
|
|
31
|
+
"build": "vite build && vite build --config vite-plugin.config.ts && vue-tsc --declaration --emitDeclarationOnly",
|
|
27
32
|
"preview": "vite preview",
|
|
28
33
|
"test:unit": "vitest",
|
|
29
34
|
"test:unit:ui": "vitest --ui",
|
|
@@ -59,6 +64,7 @@
|
|
|
59
64
|
"@vue/test-utils": "^2.4.6",
|
|
60
65
|
"@vue/tsconfig": "^0.7.0",
|
|
61
66
|
"autoprefixer": "^10.4.21",
|
|
67
|
+
"concurrently": "^9.2.1",
|
|
62
68
|
"eslint": "^9.30.0",
|
|
63
69
|
"eslint-plugin-tailwindcss": "^3.18.2",
|
|
64
70
|
"eslint-plugin-vue": "^9.33.0",
|
|
@@ -138,12 +138,10 @@ function handleSidebarWidth(width: number) {
|
|
|
138
138
|
async function loadLayout(layoutName: string | undefined) {
|
|
139
139
|
// Use "default" layout if no layout is provided
|
|
140
140
|
const layout = layoutName || "default";
|
|
141
|
-
|
|
142
141
|
try {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
pageLayout.value = layoutModule.default;
|
|
142
|
+
const availableLayouts = getLayouts();
|
|
143
|
+
const layoutModule = availableLayouts[layout];
|
|
144
|
+
pageLayout.value = layoutModule;
|
|
147
145
|
await nextTick();
|
|
148
146
|
initSortable();
|
|
149
147
|
} catch (error) {
|
package/src/shims.d.ts
CHANGED
|
@@ -50,6 +50,23 @@ interface ImportMeta {
|
|
|
50
50
|
): Record<string, () => Promise<T>> | Record<string, T> | Record<string, string>;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// Virtual modules created by vue-wswg-editor vite plugin
|
|
54
|
+
declare module "vue-wswg-editor:layouts" {
|
|
55
|
+
export const modules: Record<string, () => Promise<any>>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare module "vue-wswg-editor:blocks" {
|
|
59
|
+
export const modules: Record<string, () => Promise<any>>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare module "vue-wswg-editor:fields" {
|
|
63
|
+
export const modules: Record<string, () => Promise<any>>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
declare module "vue-wswg-editor:thumbnails" {
|
|
67
|
+
export const modules: Record<string, () => Promise<any>>;
|
|
68
|
+
}
|
|
69
|
+
|
|
53
70
|
// SortableJS type declaration - reference @types/sortablejs and re-export as ESM default
|
|
54
71
|
/// <reference types="sortablejs" />
|
|
55
72
|
declare module "sortablejs" {
|
package/src/util/registry.ts
CHANGED
|
@@ -1,28 +1,85 @@
|
|
|
1
|
-
import { ref, shallowRef, type Ref } from "vue";
|
|
1
|
+
import { ref, shallowRef, markRaw, type Ref } from "vue";
|
|
2
2
|
import type { EditorFieldConfig } from "./fieldConfig";
|
|
3
3
|
import type { Block } from "../types/Block";
|
|
4
4
|
import type { Layout } from "../types/Layout";
|
|
5
|
-
import { generateNameVariations,
|
|
5
|
+
import { generateNameVariations, toCamelCase } from "./helpers";
|
|
6
6
|
// Dynamic imports for all page builder blocks and layouts
|
|
7
7
|
// IMPORTANT: These globs use the @page-builder alias which must be configured in the CONSUMING APP's vite.config.ts
|
|
8
8
|
// The globs are evaluated by the consuming app's Vite build, so they resolve relative to the consuming app's project root
|
|
9
9
|
// The consuming app should have: "@page-builder": fileURLToPath(new URL("../page-builder", import.meta.url))
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
import { modules as layoutModules } from "vue-wswg-editor:layouts";
|
|
11
|
+
import { modules as blockModules } from "vue-wswg-editor:blocks";
|
|
12
|
+
import { modules as fieldModules } from "vue-wswg-editor:fields";
|
|
13
|
+
import { modules as thumbnailModules } from "vue-wswg-editor:thumbnails";
|
|
14
|
+
|
|
14
15
|
// Load all thumbnail images - Vite will process these as assets and provide URLs
|
|
15
16
|
// For images, Vite returns the URL as the default export when using eager: true
|
|
16
|
-
const thumbnailModules = import.meta.glob("@page-builder/blocks/**/thumbnail.png", { eager: true });
|
|
17
|
+
// const thumbnailModules = import.meta.glob("@page-builder/blocks/**/thumbnail.png", { eager: true });
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
|
-
* Registry of all page builder blocks
|
|
20
|
-
* Automatically populated from the /page-builder/blocks directory of your app
|
|
20
|
+
* Registry of all page builder blocks, layouts & fields
|
|
21
21
|
*/
|
|
22
22
|
export const pageBuilderBlocks: Ref<Record<string, Block>> = shallowRef({});
|
|
23
23
|
export const pageBuilderLayouts: Ref<Record<string, Layout>> = shallowRef({});
|
|
24
24
|
const pageBuilderBlockFields: Ref<Record<string, any>> = ref({});
|
|
25
25
|
|
|
26
|
+
////////////////////////////////////////////////////////////
|
|
27
|
+
// Helper Functions
|
|
28
|
+
////////////////////////////////////////////////////////////
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Recursively mark Vue components as raw to prevent reactivity
|
|
32
|
+
* Components are identified by having __name, setup, or render properties
|
|
33
|
+
*/
|
|
34
|
+
function markComponentsAsRaw(obj: any): any {
|
|
35
|
+
if (!obj || typeof obj !== "object") return obj;
|
|
36
|
+
|
|
37
|
+
// Check if this is a Vue component
|
|
38
|
+
if (obj.__name || obj.setup || obj.render) {
|
|
39
|
+
return markRaw(obj);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Recursively process objects and arrays
|
|
43
|
+
if (Array.isArray(obj)) {
|
|
44
|
+
return obj.map((item) => markComponentsAsRaw(item));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const result: any = {};
|
|
48
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
49
|
+
result[key] = markComponentsAsRaw(value);
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Extract the default export from a module, handling different module formats
|
|
56
|
+
* Works with both eager and lazy-loaded modules from import.meta.glob
|
|
57
|
+
*/
|
|
58
|
+
function getModuleDefault(module: any): any {
|
|
59
|
+
if (!module) return undefined;
|
|
60
|
+
|
|
61
|
+
// If module is a function (lazy-loaded), we'd need to await it, but with eager: true it should be resolved
|
|
62
|
+
if (typeof module === "function") {
|
|
63
|
+
// This shouldn't happen with eager: true, but handle it just in case
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Try .default first (standard ES module format)
|
|
68
|
+
if (typeof module === "object") {
|
|
69
|
+
// Check if it has .default property
|
|
70
|
+
if ("default" in module && module.default !== undefined) {
|
|
71
|
+
return module.default;
|
|
72
|
+
}
|
|
73
|
+
// If no .default but module has component-like properties (__name, etc.), maybe module itself is the component
|
|
74
|
+
if ("__name" in module || "name" in module || "setup" in module || "render" in module) {
|
|
75
|
+
return module;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Fallback: return the module as-is
|
|
80
|
+
return module;
|
|
81
|
+
}
|
|
82
|
+
|
|
26
83
|
////////////////////////////////////////////////////////////
|
|
27
84
|
// Methods
|
|
28
85
|
////////////////////////////////////////////////////////////
|
|
@@ -66,20 +123,17 @@ export function getBlockComponent(blockType: string): Block | undefined {
|
|
|
66
123
|
return undefined;
|
|
67
124
|
}
|
|
68
125
|
|
|
69
|
-
function getBlockFields(
|
|
126
|
+
function getBlockFields(directory: string): any {
|
|
127
|
+
const fieldsPath = `${directory}/fields.ts`;
|
|
70
128
|
try {
|
|
71
|
-
// Generate path
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (path && blockFieldsModules[path]) {
|
|
76
|
-
// Get the block fields
|
|
77
|
-
const blockFields = (blockFieldsModules[path] as any).default;
|
|
78
|
-
return blockFields || {};
|
|
129
|
+
// Generate path for fields.ts file
|
|
130
|
+
const blockField = pageBuilderBlockFields.value[fieldsPath];
|
|
131
|
+
if (blockField) {
|
|
132
|
+
return blockField;
|
|
79
133
|
}
|
|
80
134
|
return {};
|
|
81
135
|
} catch (error) {
|
|
82
|
-
console.error("Error getting block fields for block: ",
|
|
136
|
+
console.error("Error getting block fields for block: ", fieldsPath, error);
|
|
83
137
|
return {};
|
|
84
138
|
}
|
|
85
139
|
}
|
|
@@ -92,29 +146,48 @@ export function getLayoutFields(layoutName: string): Record<string, EditorFieldC
|
|
|
92
146
|
return layout?.fields || {};
|
|
93
147
|
}
|
|
94
148
|
|
|
95
|
-
function initialiseBlockFieldsRegistry(): void {
|
|
149
|
+
async function initialiseBlockFieldsRegistry(): Promise<void> {
|
|
150
|
+
// Clear existing registry
|
|
96
151
|
Object.keys(pageBuilderBlockFields.value).forEach((key) => {
|
|
97
152
|
delete pageBuilderBlockFields.value[key];
|
|
98
153
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
154
|
+
|
|
155
|
+
for (const [path, module] of Object.entries(fieldModules)) {
|
|
156
|
+
let resolvedModule = module;
|
|
157
|
+
// If module is a function (lazy-loaded), call it to get the actual module
|
|
158
|
+
if (typeof module === "function") {
|
|
159
|
+
resolvedModule = await module();
|
|
160
|
+
}
|
|
161
|
+
const blockFieldModule = getModuleDefault(resolvedModule);
|
|
162
|
+
// Mark as raw to prevent Vue from making it reactive
|
|
163
|
+
pageBuilderBlockFields.value[path] = markRaw(blockFieldModule);
|
|
164
|
+
}
|
|
103
165
|
}
|
|
104
166
|
|
|
105
|
-
function initialiseLayoutRegistry(): void {
|
|
167
|
+
async function initialiseLayoutRegistry(): Promise<void> {
|
|
106
168
|
Object.keys(pageBuilderLayouts.value).forEach((key) => {
|
|
107
169
|
delete pageBuilderLayouts.value[key];
|
|
108
170
|
});
|
|
109
|
-
|
|
110
|
-
|
|
171
|
+
|
|
172
|
+
// Use layoutModules if available (from vite plugin), otherwise fall back to layoutModules
|
|
173
|
+
const modulesToUse = layoutModules;
|
|
174
|
+
|
|
175
|
+
// Handle both eager-loaded modules and lazy-loaded modules (functions)
|
|
176
|
+
for (const [, module] of Object.entries(modulesToUse)) {
|
|
177
|
+
let resolvedModule = module;
|
|
178
|
+
// If module is a function (lazy-loaded), call it to get the actual module
|
|
179
|
+
if (typeof module === "function") {
|
|
180
|
+
resolvedModule = await module();
|
|
181
|
+
}
|
|
182
|
+
const layout = getModuleDefault(resolvedModule);
|
|
111
183
|
// exclude modules without name
|
|
112
|
-
if (!layout.label) return;
|
|
113
|
-
|
|
114
|
-
|
|
184
|
+
if (!layout || !layout.label) return;
|
|
185
|
+
// Mark layout component as raw to prevent Vue from making it reactive
|
|
186
|
+
pageBuilderLayouts.value[layout.__name] = markRaw(layout);
|
|
187
|
+
}
|
|
115
188
|
}
|
|
116
189
|
|
|
117
|
-
function initialiseBlockRegistry(): void {
|
|
190
|
+
async function initialiseBlockRegistry(): Promise<void> {
|
|
118
191
|
// Clear existing registry
|
|
119
192
|
Object.keys(pageBuilderBlocks.value).forEach((key) => {
|
|
120
193
|
delete pageBuilderBlocks.value[key];
|
|
@@ -122,28 +195,36 @@ function initialiseBlockRegistry(): void {
|
|
|
122
195
|
|
|
123
196
|
// Load all blocks from the glob pattern
|
|
124
197
|
// With eager: true, module is the actual module object, not a loader function
|
|
125
|
-
|
|
126
|
-
|
|
198
|
+
for (const [path, module] of Object.entries(blockModules)) {
|
|
199
|
+
let resolvedModule = module;
|
|
200
|
+
// If module is a function (lazy-loaded), call it to get the actual module
|
|
201
|
+
if (typeof module === "function") {
|
|
202
|
+
resolvedModule = await module();
|
|
203
|
+
}
|
|
204
|
+
const component = getModuleDefault(resolvedModule);
|
|
127
205
|
if (component && component.__name) {
|
|
128
206
|
const blockType = toCamelCase(component.type || component.__name);
|
|
129
207
|
// Extract directory path from component path (e.g., "@page-builder/blocks/hero-section/hero-section.vue" -> "@page-builder/blocks/hero-section")
|
|
130
208
|
const directory = path.replace(/\/[^/]+\.vue$/, "");
|
|
209
|
+
// Mark the component itself as raw before spreading
|
|
210
|
+
const rawComponent = markRaw(component);
|
|
131
211
|
const block: Block = {
|
|
132
|
-
fields: getBlockFields(
|
|
133
|
-
...
|
|
212
|
+
fields: markComponentsAsRaw(getBlockFields(directory)), // Mark any components in fields as raw
|
|
213
|
+
...rawComponent, // Component can override fields
|
|
134
214
|
directory: directory, // directory path where the block component is located (e.g., "@page-builder/blocks/hero-section")
|
|
135
215
|
type: blockType,
|
|
136
216
|
};
|
|
137
217
|
pageBuilderBlocks.value[blockType] = block;
|
|
138
218
|
}
|
|
139
|
-
}
|
|
219
|
+
}
|
|
140
220
|
}
|
|
141
221
|
|
|
142
|
-
export function initialiseRegistry(): void {
|
|
143
|
-
initialiseLayoutRegistry();
|
|
144
|
-
initialiseBlockFieldsRegistry();
|
|
145
|
-
initialiseBlockRegistry();
|
|
222
|
+
export async function initialiseRegistry(): Promise<void> {
|
|
223
|
+
await initialiseLayoutRegistry();
|
|
224
|
+
await initialiseBlockFieldsRegistry();
|
|
225
|
+
await initialiseBlockRegistry();
|
|
146
226
|
}
|
|
147
227
|
|
|
148
228
|
// Initialise the registry when the module is loaded
|
|
149
|
-
|
|
229
|
+
// Use void to handle the promise without blocking
|
|
230
|
+
void initialiseRegistry();
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// my-lib/src/plugin.ts
|
|
2
|
+
import type { Plugin } from "vite";
|
|
3
|
+
|
|
4
|
+
export interface VueWswgEditorPluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Root directory in the host project.
|
|
7
|
+
* Example: "@/features/homepage"
|
|
8
|
+
*/
|
|
9
|
+
rootDir: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function vueWswgEditorPlugin(options: VueWswgEditorPluginOptions): Plugin {
|
|
13
|
+
const virtualModules = {
|
|
14
|
+
blocks: "\0vue-wswg-editor:blocks",
|
|
15
|
+
fields: "\0vue-wswg-editor:fields",
|
|
16
|
+
layouts: "\0vue-wswg-editor:layouts",
|
|
17
|
+
thumbnails: "\0vue-wswg-editor:thumbnails",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
name: "vue-wswg-editor-glob-plugin",
|
|
22
|
+
enforce: "pre", // Run before other plugins to ensure import.meta.glob is processed correctly
|
|
23
|
+
|
|
24
|
+
resolveId(id) {
|
|
25
|
+
// Handle virtual module imports like "vue-wswg-editor:layouts"
|
|
26
|
+
if (id.startsWith("vue-wswg-editor:")) {
|
|
27
|
+
const suffix = id.replace("vue-wswg-editor:", "");
|
|
28
|
+
if (suffix in virtualModules) {
|
|
29
|
+
return virtualModules[suffix as keyof typeof virtualModules];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Handle already resolved virtual module IDs (with \0 prefix)
|
|
33
|
+
const virtualModuleValues = Object.values(virtualModules);
|
|
34
|
+
if (virtualModuleValues.includes(id)) {
|
|
35
|
+
return id;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
load(id) {
|
|
40
|
+
// Generate code that Vite will process - ensure import.meta.glob is at top level
|
|
41
|
+
// Using a more explicit format to ensure Vite processes it correctly
|
|
42
|
+
switch (id) {
|
|
43
|
+
case virtualModules.layouts:
|
|
44
|
+
return `export const modules = import.meta.glob("${options.rootDir}/layout/**/*.vue", { eager: true });`;
|
|
45
|
+
case virtualModules.blocks:
|
|
46
|
+
return `export const modules = import.meta.glob("${options.rootDir}/blocks/**/*.vue", { eager: true });`;
|
|
47
|
+
case virtualModules.fields:
|
|
48
|
+
return `export const modules = import.meta.glob("${options.rootDir}/blocks/**/fields.ts", { eager: true });`;
|
|
49
|
+
case virtualModules.thumbnails:
|
|
50
|
+
return `export const modules = import.meta.glob("${options.rootDir}/blocks/**/thumbnail.png", { eager: true });`;
|
|
51
|
+
default:
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
transform(_code, id) {
|
|
57
|
+
// Ensure import.meta.glob in virtual modules is processed correctly by Vite
|
|
58
|
+
// This hook ensures the code goes through Vite's transform pipeline
|
|
59
|
+
if (Object.values(virtualModules).includes(id)) {
|
|
60
|
+
// Return null to let Vite process the code normally - this ensures import.meta.glob is transformed
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
package/dist/style.css
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.resize-handle[data-v-b9819ded]{position:relative;top:0;right:0;z-index:2;width:3px;height:100%;cursor:col-resize;background-color:var(--grey-20);transition:all .2s ease-in-out}.resize-handle[data-v-b9819ded]:hover{width:3px;background-color:var(--yellow-40)}.resize-handle[data-v-b9819ded]:active{width:3px;background-color:var(--yellow-50)}.resize-handle[data-v-b9819ded]:before{position:absolute;top:50%;left:-6px;z-index:20;width:14px;height:40px;content:"";background-color:var(--yellow-40);border-radius:var(--border-radius-16);opacity:0;transform:translateY(-50%);transition:opacity .2s ease-in-out,background-color .2s ease-in-out}.resize-handle[data-v-b9819ded]:hover:before{opacity:1}.resize-handle[data-v-b9819ded]:active:before{background-color:var(--yellow-50);opacity:1}.repeater-field[data-v-20cd0fde]{width:100%}.empty-state[data-v-20cd0fde]{border:2px dashed #e5e7eb;border-radius:.5rem}.repeater-item .repeater-item-fields[data-v-20cd0fde]{height:0;overflow:hidden}.repeater-item.is-open .repeater-item-fields[data-v-20cd0fde]{height:auto;border-top-width:1px;padding:.75rem}select.form-control[data-v-649db0fa]{padding-right:32px;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;background-size:20px}.editor-field-node[data-v-664a26d0] .form-control:is(input:not([type=checkbox],[type=radio]),textarea,select){width:100%;padding:8px;font-size:14px;color:#333;outline:none;background-color:#fff;border:1px solid #e0e0e0;border-radius:5px;box-shadow:none;transition:border-color .2s}.editor-field-node[data-v-664a26d0] .form-control label input[type=checkbox],.editor-field-node[data-v-664a26d0] .form-control label input[type=radio]{width:16px;height:16px;padding:8px;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;border:1px solid #e0e0e0;border-radius:5px}.editor-field-node[data-v-664a26d0] .form-control label input[type=checkbox]:checked,.editor-field-node[data-v-664a26d0] .form-control label input[type=radio]:checked{--tw-border-opacity: 1;border-color:rgb(29 78 216 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.editor-field-node[data-v-664a26d0] .form-control label:has(input[type=checkbox]:checked,input[type=radio]:checked){--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.editor-field-node[data-v-664a26d0] .form-control label:hover input[type=checkbox]:not(:checked),.editor-field-node[data-v-664a26d0] .form-control label:hover input[type=radio]:not(:checked){--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.editor-field-node[data-v-664a26d0] .form-control label:has(input[type=checkbox]:disabled,input[type=radio]:disabled){cursor:not-allowed;opacity:.75}.editor-field-node[data-v-664a26d0] .form-control label:has(input[type=checkbox]:disabled,input[type=radio]:disabled) input{cursor:not-allowed}.editor-field-node[data-v-664a26d0] .form-control:is(select){padding-right:32px;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;background-size:20px}.editor-field-node[data-v-664a26d0] .form-control:is(input[type=color]){width:auto;aspect-ratio:1/1;padding:3px;cursor:pointer;background-color:#fff;border:none;border:1px solid #e0e0e0;border-radius:5px}.editor-field-node[data-v-664a26d0] .form-control:hover{border-color:#555}.editor-field-node[data-v-664a26d0] .form-control:disabled{cursor:not-allowed;background-color:#fff;opacity:.75}.block-item.hovered-block[data-v-b8a8bb65]{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}select.form-control[data-v-fd08bd6a]{padding-right:32px;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;background-size:20px}.page-builder-sidebar[data-v-2212ac82]{height:100%;overflow-y:auto;background:#fff}.block-wrapper[data-v-9d8117d8]{position:relative;transition:all .3s ease}.block-wrapper[data-v-9d8117d8]:before,.block-wrapper[data-v-9d8117d8]:after{position:absolute;left:0;display:flex;align-items:center;justify-content:center;width:100%;height:0;font-size:14px;font-weight:500;color:#888017;content:"Spacing";background-color:#f7efac;border:2px dashed #d2c564;border-radius:7px;opacity:0;transform:scaleY(.9) scaleX(.98);transition:all .3s ease}.block-wrapper .block-component[data-v-9d8117d8]{position:relative;cursor:pointer}.block-wrapper .block-component[data-v-9d8117d8]:before{position:absolute;top:0;left:0;z-index:2;width:100%;height:100%;pointer-events:none;outline:2px dashed #638ef1;outline-offset:-2px;content:"";background-color:#9fd0f643;opacity:0}.block-wrapper.active-block .block-component[data-v-9d8117d8]:before{background-color:#9fd0f643;border-color:#638ef1;opacity:1}.block-wrapper.active-block[data-v-9d8117d8]:after,.block-wrapper.active-block[data-v-9d8117d8]:before{opacity:1}.block-wrapper.hovered-block .block-component[data-v-9d8117d8]:before{background-color:#9fd0f643;border-color:#638ef1;opacity:1}.block-wrapper.hovered-block[data-v-9d8117d8]:after,.block-wrapper.hovered-block[data-v-9d8117d8]:before{opacity:1}.block-wrapper.margin-top-sm[data-v-9d8117d8]{padding-top:2rem}.block-wrapper.margin-top-sm[data-v-9d8117d8]:before{top:0;height:2rem}.block-wrapper.margin-top-md[data-v-9d8117d8]{padding-top:4rem}.block-wrapper.margin-top-md[data-v-9d8117d8]:before{top:0;height:4rem}.block-wrapper.margin-top-lg[data-v-9d8117d8]{padding-top:6rem}.block-wrapper.margin-top-lg[data-v-9d8117d8]:before{top:0;height:6rem}.block-wrapper.margin-bottom-sm[data-v-9d8117d8]{padding-bottom:2rem}.block-wrapper.margin-bottom-sm[data-v-9d8117d8]:after{bottom:0;height:2rem}.block-wrapper.margin-bottom-md[data-v-9d8117d8]{padding-bottom:4rem}.block-wrapper.margin-bottom-md[data-v-9d8117d8]:after{bottom:0;height:4rem}.block-wrapper.margin-bottom-lg[data-v-9d8117d8]{padding-bottom:6rem}.block-wrapper.margin-bottom-lg[data-v-9d8117d8]:after{bottom:0;height:6rem}.block-wrapper.margin-top-none[data-v-9d8117d8]:before,.block-wrapper.margin-bottom-none[data-v-9d8117d8]:after{display:none;content:none}.wswg-json-editor{display:flex;flex-direction:column;width:100%;max-width:100%;height:100vh}.wswg-json-editor-header{position:sticky;top:0;z-index:20;background-color:#fff}.wswg-json-editor-loading{display:flex;align-items:center;justify-content:center}.wswg-json-editor-canvas{display:flex;flex:1;flex-grow:1;flex-shrink:0;height:100%;overflow-y:auto;background-color:#6a6a6a}.wswg-json-editor-canvas-preview{flex:1;flex-grow:1;flex-shrink:0;padding:2rem}.wswg-json-editor-canvas-sidebar{min-width:300px;padding:2rem;background:#fff}.block-wrapper.margin-top-sm[data-v-958830a9]{padding-top:2rem}.block-wrapper.margin-top-sm[data-v-958830a9]:before{top:0;height:2rem}.block-wrapper.margin-top-md[data-v-958830a9]{padding-top:4rem}.block-wrapper.margin-top-md[data-v-958830a9]:before{top:0;height:4rem}.block-wrapper.margin-top-lg[data-v-958830a9]{padding-top:6rem}.block-wrapper.margin-top-lg[data-v-958830a9]:before{top:0;height:6rem}.block-wrapper.margin-bottom-sm[data-v-958830a9]{padding-bottom:2rem}.block-wrapper.margin-bottom-sm[data-v-958830a9]:after{bottom:0;height:2rem}.block-wrapper.margin-bottom-md[data-v-958830a9]{padding-bottom:4rem}.block-wrapper.margin-bottom-md[data-v-958830a9]:after{bottom:0;height:4rem}.block-wrapper.margin-bottom-lg[data-v-958830a9]{padding-bottom:6rem}.block-wrapper.margin-bottom-lg[data-v-958830a9]:after{bottom:0;height:6rem}.block-wrapper.margin-top-none[data-v-958830a9]:before,.block-wrapper.margin-bottom-none[data-v-958830a9]:after{display:none;content:none}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.-top-3{top:-.75rem}.left-0{left:0}.right-4{right:1rem}.top-0{top:0}.z-10{z-index:10}.-mx-2\.5{margin-left:-.625rem;margin-right:-.625rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-9{margin-bottom:2.25rem}.ml-0{margin-left:0}.ml-1{margin-left:.25rem}.ml-auto{margin-left:auto}.mr-auto{margin-right:auto}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.size-10{width:2.5rem;height:2.5rem}.size-3{width:.75rem;height:.75rem}.size-4{width:1rem;height:1rem}.size-5{width:1.25rem;height:1.25rem}.size-6{width:1.5rem;height:1.5rem}.size-7{width:1.75rem;height:1.75rem}.h-28{height:7rem}.h-7{height:1.75rem}.h-auto{height:auto}.h-full{height:100%}.w-14{width:3.5rem}.w-96{width:24rem}.w-auto{width:auto}.w-full{width:100%}.max-w-5xl{max-width:64rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse: 0;border-right-width:calc(1px * var(--tw-divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-dashed{border-style:dashed}.\!border-none{border-style:none!important}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-500{--tw-border-opacity: 1;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))}.border-blue-800\/20{border-color:#1e40af33}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-zinc-200{--tw-border-opacity: 1;border-color:rgb(228 228 231 / var(--tw-border-opacity, 1))}.border-b-transparent{border-bottom-color:transparent}.\!bg-white{--tw-bg-opacity: 1 !important;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))!important}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-50\/80{background-color:#eff6ffcc}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-700{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.bg-emerald-700{--tw-bg-opacity: 1;background-color:rgb(4 120 87 / var(--tw-bg-opacity, 1))}.bg-neutral-100{--tw-bg-opacity: 1;background-color:rgb(245 245 245 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-zinc-100{--tw-bg-opacity: 1;background-color:rgb(244 244 245 / var(--tw-bg-opacity, 1))}.bg-zinc-200{--tw-bg-opacity: 1;background-color:rgb(228 228 231 / var(--tw-bg-opacity, 1))}.bg-zinc-300{--tw-bg-opacity: 1;background-color:rgb(212 212 216 / var(--tw-bg-opacity, 1))}.bg-zinc-50{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.bg-zinc-600{--tw-bg-opacity: 1;background-color:rgb(82 82 91 / var(--tw-bg-opacity, 1))}.bg-zinc-700{--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-5{padding:1.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pt-3{padding-top:.75rem}.text-center{text-align:center}.\!font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"!important}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-900{--tw-text-opacity: 1;color:rgb(23 23 23 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-zinc-300{--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.text-zinc-400{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.text-zinc-500{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.text-zinc-600{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.text-zinc-900{--tw-text-opacity: 1;color:rgb(24 24 27 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.opacity-50{opacity:.5}.\!outline-none{outline:2px solid transparent!important;outline-offset:2px!important}.outline{outline-style:solid}.\!ring-0{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)!important}.\!ring-offset-0{--tw-ring-offset-width: 0px !important}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.first-letter\:uppercase:first-letter{text-transform:uppercase}.checked\:ml-7:checked{margin-left:1.75rem}.hover\:border-red-200:hover{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.hover\:border-zinc-300:hover{--tw-border-opacity: 1;border-color:rgb(212 212 216 / var(--tw-border-opacity, 1))}.hover\:border-zinc-400:hover{--tw-border-opacity: 1;border-color:rgb(161 161 170 / var(--tw-border-opacity, 1))}.hover\:bg-blue-100:hover{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.hover\:bg-emerald-800:hover{--tw-bg-opacity: 1;background-color:rgb(6 95 70 / var(--tw-bg-opacity, 1))}.hover\:bg-red-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-100:hover{--tw-bg-opacity: 1;background-color:rgb(244 244 245 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-200:hover{--tw-bg-opacity: 1;background-color:rgb(228 228 231 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-300:hover{--tw-bg-opacity: 1;background-color:rgb(212 212 216 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-500:hover{--tw-bg-opacity: 1;background-color:rgb(113 113 122 / var(--tw-bg-opacity, 1))}.hover\:text-blue-700:hover{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.hover\:text-blue-800:hover{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.hover\:text-red-600:hover{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.hover\:text-red-700:hover{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:text-zinc-600:hover{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.hover\:text-zinc-700:hover{--tw-text-opacity: 1;color:rgb(63 63 70 / var(--tw-text-opacity, 1))}.hover\:text-zinc-900:hover{--tw-text-opacity: 1;color:rgb(24 24 27 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-sm:hover{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.active\:border-blue-600:active{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.active\:bg-blue-50:active{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.active\:text-blue-600:active{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}
|