@wikex/admin-kit 0.2.0 → 0.2.2
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/CHANGELOG.md +4 -0
- package/dist/admin/before-login.d.ts +5 -0
- package/dist/admin/before-login.js +27 -0
- package/dist/admin/brand.d.ts +19 -0
- package/dist/admin/brand.js +16 -0
- package/dist/admin/header.d.ts +5 -0
- package/dist/admin/header.js +96 -0
- package/dist/admin/logout-button.d.ts +8 -0
- package/dist/admin/logout-button.js +8 -0
- package/dist/admin/nav-client.d.ts +16 -0
- package/dist/admin/nav-client.js +258 -0
- package/dist/admin/nav.d.ts +16 -0
- package/dist/admin/nav.js +31 -0
- package/dist/admin/theme-toggle.d.ts +5 -0
- package/dist/admin/theme-toggle.js +8 -0
- package/dist/admin/view-site.d.ts +5 -0
- package/dist/admin/view-site.js +11 -0
- package/dist/chunk-7FEACJUN.js +151 -0
- package/dist/chunk-BUD6BMFV.js +117 -0
- package/dist/chunk-GMPR6LHH.js +2063 -0
- package/dist/chunk-GZ2B5BTH.js +39 -0
- package/dist/chunk-JJLHSZ3T.js +40 -0
- package/dist/chunk-LC2CP5SR.js +13 -0
- package/dist/chunk-SAI5SWZA.js +29 -0
- package/dist/chunk-SM6CCKQQ.js +62 -0
- package/dist/chunk-VK4EFLWH.js +119 -0
- package/dist/chunk-X7VETFVD.js +52 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +104 -0
- package/dist/live-preview.d.ts +118 -0
- package/dist/live-preview.js +20 -0
- package/dist/project-ClCmpyeX.d.ts +54 -0
- package/dist/project.d.ts +1 -0
- package/dist/project.js +8 -0
- package/dist/rich-text-client.d.ts +5 -0
- package/dist/rich-text-client.js +166 -0
- package/dist/rich-text.d.ts +5 -0
- package/dist/rich-text.js +6 -0
- package/dist/runtimeConfig-BwjQepcW.d.ts +30 -0
- package/dist/starter-client.d.ts +56 -0
- package/dist/starter-client.js +26 -0
- package/dist/starter.d.ts +39 -0
- package/dist/starter.js +62 -0
- package/dist/text-style-runtime.d.ts +5 -0
- package/dist/text-style-runtime.js +74 -0
- package/dist/text-styles.d.ts +86 -0
- package/dist/text-styles.js +22 -0
- package/package.json +24 -19
- package/src/TextStyleRuntime.tsx +0 -90
- package/src/admin/BeforeLogin.tsx +0 -19
- package/src/admin/Brand.tsx +0 -74
- package/src/admin/Header.tsx +0 -87
- package/src/admin/LogoutButton.tsx +0 -41
- package/src/admin/Nav.tsx +0 -35
- package/src/admin/NavClient.tsx +0 -288
- package/src/admin/ThemeToggle.tsx +0 -31
- package/src/admin/ViewSite.tsx +0 -11
- package/src/admin/useAdminBrand.ts +0 -81
- package/src/adminExperience.ts +0 -117
- package/src/index.ts +0 -11
- package/src/live-preview/GlobalInlineInspector.tsx +0 -334
- package/src/live-preview/LivePreviewEditor.tsx +0 -2088
- package/src/live-preview/TextStyleInspector.tsx +0 -289
- package/src/live-preview/index.ts +0 -23
- package/src/live-preview/runtimeConfig.ts +0 -52
- package/src/plugin.ts +0 -70
- package/src/project.ts +0 -82
- package/src/rich-text/client.tsx +0 -202
- package/src/rich-text/index.ts +0 -10
- package/src/starter/client.tsx +0 -22
- package/src/starter.ts +0 -95
- package/src/textStyles.ts +0 -161
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { V as VisualEditorRouteRegistry, W as WikexProjectDefinition, c as createVisualEditorRouteResolver, d as defineWikexProject } from './project-ClCmpyeX.js';
|
package/dist/project.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
"use client";
|
|
3
|
+
import {
|
|
4
|
+
TEXT_FONT_OPTIONS,
|
|
5
|
+
TEXT_LINE_HEIGHT_OPTIONS,
|
|
6
|
+
getTextStyleCSS,
|
|
7
|
+
normalizeTextStyleValue
|
|
8
|
+
} from "./chunk-VK4EFLWH.js";
|
|
9
|
+
|
|
10
|
+
// src/rich-text/client.tsx
|
|
11
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
12
|
+
import { $forEachSelectedTextNode } from "@lexical/selection";
|
|
13
|
+
import { createClientFeature } from "@payloadcms/richtext-lexical/client";
|
|
14
|
+
import {
|
|
15
|
+
$getNodeByKey,
|
|
16
|
+
$getSelection,
|
|
17
|
+
$getState,
|
|
18
|
+
$isRangeSelection,
|
|
19
|
+
$isTextNode,
|
|
20
|
+
$setSelection,
|
|
21
|
+
$setState,
|
|
22
|
+
createState,
|
|
23
|
+
TextNode
|
|
24
|
+
} from "lexical";
|
|
25
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
26
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
27
|
+
var fontFamilyState = createState("fontFamily", {
|
|
28
|
+
parse: (value) => normalizeTextStyleValue({ fontFamily: value }).fontFamily
|
|
29
|
+
});
|
|
30
|
+
var lineHeightState = createState("lineHeight", {
|
|
31
|
+
parse: (value) => normalizeTextStyleValue({ lineHeight: value }).lineHeight
|
|
32
|
+
});
|
|
33
|
+
var DEFAULT_TYPOGRAPHY = {
|
|
34
|
+
fontFamily: "default",
|
|
35
|
+
lineHeight: "default"
|
|
36
|
+
};
|
|
37
|
+
var readSelectedTypography = (editor) => editor.getEditorState().read(() => {
|
|
38
|
+
const selection = $getSelection();
|
|
39
|
+
if (!$isRangeSelection(selection)) return DEFAULT_TYPOGRAPHY;
|
|
40
|
+
const textNode = selection.getNodes().find($isTextNode);
|
|
41
|
+
if (!textNode) return DEFAULT_TYPOGRAPHY;
|
|
42
|
+
return {
|
|
43
|
+
fontFamily: $getState(textNode, fontFamilyState) ?? "default",
|
|
44
|
+
lineHeight: $getState(textNode, lineHeightState) ?? "default"
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
var updateSelectedTypography = (editor, property, value, savedSelection) => {
|
|
48
|
+
editor.update(() => {
|
|
49
|
+
if (!$isRangeSelection($getSelection()) && savedSelection) {
|
|
50
|
+
$setSelection(savedSelection.clone());
|
|
51
|
+
}
|
|
52
|
+
$forEachSelectedTextNode((textNode) => {
|
|
53
|
+
if (property === "fontFamily") {
|
|
54
|
+
const fontFamily = value;
|
|
55
|
+
$setState(textNode, fontFamilyState, fontFamily === "default" ? void 0 : fontFamily);
|
|
56
|
+
} else {
|
|
57
|
+
const lineHeight = value;
|
|
58
|
+
$setState(textNode, lineHeightState, lineHeight === "default" ? void 0 : lineHeight);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
var TypographyToolbarItem = ({ editor }) => {
|
|
64
|
+
const [value, setValue] = useState(DEFAULT_TYPOGRAPHY);
|
|
65
|
+
const savedSelection = useRef(null);
|
|
66
|
+
const captureSelection = useCallback(() => {
|
|
67
|
+
editor.getEditorState().read(() => {
|
|
68
|
+
const selection = $getSelection();
|
|
69
|
+
if ($isRangeSelection(selection)) savedSelection.current = selection.clone();
|
|
70
|
+
});
|
|
71
|
+
}, [editor]);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
const syncValue = () => {
|
|
74
|
+
captureSelection();
|
|
75
|
+
setValue(readSelectedTypography(editor));
|
|
76
|
+
};
|
|
77
|
+
syncValue();
|
|
78
|
+
return editor.registerUpdateListener(syncValue);
|
|
79
|
+
}, [captureSelection, editor]);
|
|
80
|
+
return /* @__PURE__ */ jsxs(
|
|
81
|
+
"div",
|
|
82
|
+
{
|
|
83
|
+
"aria-label": "Ki\u1EC3u ch\u1EEF",
|
|
84
|
+
className: "wikex-typography-selects",
|
|
85
|
+
onMouseDown: (event) => {
|
|
86
|
+
event.stopPropagation();
|
|
87
|
+
captureSelection();
|
|
88
|
+
},
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ jsx(
|
|
91
|
+
"select",
|
|
92
|
+
{
|
|
93
|
+
"aria-label": "Ph\xF4ng ch\u1EEF",
|
|
94
|
+
className: "wikex-minimal-select wikex-minimal-select--font",
|
|
95
|
+
onChange: (event) => {
|
|
96
|
+
const fontFamily = event.target.value;
|
|
97
|
+
setValue((current) => ({ ...current, fontFamily }));
|
|
98
|
+
updateSelectedTypography(editor, "fontFamily", fontFamily, savedSelection.current);
|
|
99
|
+
},
|
|
100
|
+
title: "Ph\xF4ng ch\u1EEF",
|
|
101
|
+
value: value.fontFamily,
|
|
102
|
+
children: TEXT_FONT_OPTIONS.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
/* @__PURE__ */ jsx(
|
|
106
|
+
"select",
|
|
107
|
+
{
|
|
108
|
+
"aria-label": "Chi\u1EC1u cao d\xF2ng",
|
|
109
|
+
className: "wikex-minimal-select wikex-minimal-select--line-height",
|
|
110
|
+
onChange: (event) => {
|
|
111
|
+
const lineHeight = event.target.value;
|
|
112
|
+
setValue((current) => ({ ...current, lineHeight }));
|
|
113
|
+
updateSelectedTypography(editor, "lineHeight", lineHeight, savedSelection.current);
|
|
114
|
+
},
|
|
115
|
+
title: "Chi\u1EC1u cao d\xF2ng",
|
|
116
|
+
value: value.lineHeight,
|
|
117
|
+
children: TEXT_LINE_HEIGHT_OPTIONS.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
|
+
var TypographyStatePlugin = () => {
|
|
125
|
+
const [editor] = useLexicalComposerContext();
|
|
126
|
+
useEffect(
|
|
127
|
+
() => editor.registerMutationListener(TextNode, (mutatedNodes) => {
|
|
128
|
+
editor.getEditorState().read(() => {
|
|
129
|
+
for (const [nodeKey, mutation] of mutatedNodes) {
|
|
130
|
+
if (mutation === "destroyed") continue;
|
|
131
|
+
const node = $getNodeByKey(nodeKey);
|
|
132
|
+
const element = editor.getElementByKey(nodeKey);
|
|
133
|
+
if (!$isTextNode(node) || !element) continue;
|
|
134
|
+
const style = getTextStyleCSS({
|
|
135
|
+
fontFamily: $getState(node, fontFamilyState),
|
|
136
|
+
lineHeight: $getState(node, lineHeightState)
|
|
137
|
+
});
|
|
138
|
+
if (style.fontFamily) element.style.fontFamily = style.fontFamily;
|
|
139
|
+
else element.style.removeProperty("font-family");
|
|
140
|
+
if (style.lineHeight) element.style.lineHeight = style.lineHeight;
|
|
141
|
+
else element.style.removeProperty("line-height");
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}),
|
|
145
|
+
[editor]
|
|
146
|
+
);
|
|
147
|
+
return null;
|
|
148
|
+
};
|
|
149
|
+
var toolbarItem = {
|
|
150
|
+
Component: TypographyToolbarItem,
|
|
151
|
+
key: "wikex-typography-controls"
|
|
152
|
+
};
|
|
153
|
+
var typographyToolbarGroup = {
|
|
154
|
+
items: [toolbarItem],
|
|
155
|
+
key: "wikexTypography",
|
|
156
|
+
order: 34,
|
|
157
|
+
type: "buttons"
|
|
158
|
+
};
|
|
159
|
+
var RichTextTypographyFeatureClient = createClientFeature({
|
|
160
|
+
plugins: [{ Component: TypographyStatePlugin, position: "normal" }],
|
|
161
|
+
toolbarFixed: { groups: [typographyToolbarGroup] },
|
|
162
|
+
toolbarInline: { groups: [typographyToolbarGroup] }
|
|
163
|
+
});
|
|
164
|
+
export {
|
|
165
|
+
RichTextTypographyFeatureClient
|
|
166
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type BlockPickerScope = 'page' | 'post';
|
|
2
|
+
type BlockPickerOption = {
|
|
3
|
+
description: string;
|
|
4
|
+
image?: string;
|
|
5
|
+
label: string;
|
|
6
|
+
payloadLabel?: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
};
|
|
9
|
+
type VisualEditorDocumentTarget = {
|
|
10
|
+
collection: string;
|
|
11
|
+
documentID: string;
|
|
12
|
+
kind: 'collection';
|
|
13
|
+
} | {
|
|
14
|
+
global: string;
|
|
15
|
+
kind: 'global';
|
|
16
|
+
};
|
|
17
|
+
type VisualEditorScope = 'content' | 'footer' | 'header';
|
|
18
|
+
type VisualEditorRoute = {
|
|
19
|
+
documentTarget: VisualEditorDocumentTarget | null;
|
|
20
|
+
scope: VisualEditorScope;
|
|
21
|
+
type: 'collection' | 'global';
|
|
22
|
+
};
|
|
23
|
+
type LivePreviewRuntimeConfig = {
|
|
24
|
+
getVisualEditorRoute: (pathname: string) => VisualEditorRoute | null;
|
|
25
|
+
pageBlocks: readonly BlockPickerOption[];
|
|
26
|
+
postBlocks: readonly BlockPickerOption[];
|
|
27
|
+
};
|
|
28
|
+
declare const configureLivePreview: (config: LivePreviewRuntimeConfig) => void;
|
|
29
|
+
|
|
30
|
+
export { type BlockPickerOption as B, type LivePreviewRuntimeConfig as L, type VisualEditorDocumentTarget as V, type BlockPickerScope as a, type VisualEditorRoute as b, type VisualEditorScope as c, configureLivePreview as d };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { createContentModule } from '@wikex/content-kit';
|
|
3
|
+
import { b as VisualEditorRoute, B as BlockPickerOption } from './runtimeConfig-BwjQepcW.js';
|
|
4
|
+
|
|
5
|
+
type WikexProjectDefinition<TModuleID extends string = string> = {
|
|
6
|
+
admin?: {
|
|
7
|
+
collectionOrder?: readonly string[];
|
|
8
|
+
globalOrder?: readonly string[];
|
|
9
|
+
};
|
|
10
|
+
brand: {
|
|
11
|
+
description: string;
|
|
12
|
+
logo: {
|
|
13
|
+
height: number;
|
|
14
|
+
url: string;
|
|
15
|
+
width: number;
|
|
16
|
+
};
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
19
|
+
homepage?: {
|
|
20
|
+
defaultMode: 'builder' | 'preset';
|
|
21
|
+
};
|
|
22
|
+
id: string;
|
|
23
|
+
modules: readonly TModuleID[];
|
|
24
|
+
};
|
|
25
|
+
declare const defineWikexProject: <const TModuleID extends string, const TProject extends WikexProjectDefinition<TModuleID>>(project: TProject) => TProject;
|
|
26
|
+
|
|
27
|
+
type WikexStarterBrand = {
|
|
28
|
+
description: string;
|
|
29
|
+
logo: {
|
|
30
|
+
height: number;
|
|
31
|
+
url: string;
|
|
32
|
+
width: number;
|
|
33
|
+
};
|
|
34
|
+
name: string;
|
|
35
|
+
};
|
|
36
|
+
type WikexStarter = {
|
|
37
|
+
collections: ReturnType<typeof createContentModule>['collections'];
|
|
38
|
+
getVisualEditorRoute: (pathname: string) => VisualEditorRoute | null;
|
|
39
|
+
livePreview: {
|
|
40
|
+
brand: WikexStarterBrand;
|
|
41
|
+
pageBlocks: readonly BlockPickerOption[];
|
|
42
|
+
postBlocks: readonly BlockPickerOption[];
|
|
43
|
+
};
|
|
44
|
+
plugins: ReturnType<typeof createContentModule>['plugins'];
|
|
45
|
+
project: ReturnType<typeof defineWikexProject>;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
type LivePreviewConfig = WikexStarter['livePreview'] & {
|
|
49
|
+
getVisualEditorRoute: WikexStarter['getVisualEditorRoute'];
|
|
50
|
+
};
|
|
51
|
+
/** Configure and return the shared client-side Live Preview provider for a Wikex starter. */
|
|
52
|
+
declare const createWikexLivePreviewAdapter: ({ brand, getVisualEditorRoute, pageBlocks, postBlocks, }: LivePreviewConfig) => ({ children }: {
|
|
53
|
+
children?: React.ReactNode;
|
|
54
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
55
|
+
|
|
56
|
+
export { createWikexLivePreviewAdapter };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
"use client";
|
|
3
|
+
import "./chunk-SM6CCKQQ.js";
|
|
4
|
+
import {
|
|
5
|
+
configureAdminBrand
|
|
6
|
+
} from "./chunk-X7VETFVD.js";
|
|
7
|
+
import {
|
|
8
|
+
LivePreviewEditor_default,
|
|
9
|
+
configureLivePreview
|
|
10
|
+
} from "./chunk-GMPR6LHH.js";
|
|
11
|
+
import "./chunk-VK4EFLWH.js";
|
|
12
|
+
|
|
13
|
+
// src/starter/client.tsx
|
|
14
|
+
var createWikexLivePreviewAdapter = ({
|
|
15
|
+
brand,
|
|
16
|
+
getVisualEditorRoute,
|
|
17
|
+
pageBlocks,
|
|
18
|
+
postBlocks
|
|
19
|
+
}) => {
|
|
20
|
+
configureAdminBrand({ logo: { alt: brand.name, ...brand.logo }, siteName: brand.name });
|
|
21
|
+
configureLivePreview({ getVisualEditorRoute, pageBlocks, postBlocks });
|
|
22
|
+
return LivePreviewEditor_default;
|
|
23
|
+
};
|
|
24
|
+
export {
|
|
25
|
+
createWikexLivePreviewAdapter
|
|
26
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createContentModule, ContentModuleOptions } from '@wikex/content-kit';
|
|
2
|
+
import { a as VisualEditorRoute, B as BlockPickerOption, d as defineWikexProject } from './project-ClCmpyeX.js';
|
|
3
|
+
|
|
4
|
+
type WikexStarterBrand = {
|
|
5
|
+
description: string;
|
|
6
|
+
logo: {
|
|
7
|
+
height: number;
|
|
8
|
+
url: string;
|
|
9
|
+
width: number;
|
|
10
|
+
};
|
|
11
|
+
name: string;
|
|
12
|
+
};
|
|
13
|
+
type WikexStarterOptions = {
|
|
14
|
+
brand: WikexStarterBrand;
|
|
15
|
+
content: ContentModuleOptions;
|
|
16
|
+
globals?: Readonly<Record<string, 'content' | 'footer' | 'header'>>;
|
|
17
|
+
id: string;
|
|
18
|
+
modules?: readonly string[];
|
|
19
|
+
provider: string;
|
|
20
|
+
};
|
|
21
|
+
type WikexStarter = {
|
|
22
|
+
collections: ReturnType<typeof createContentModule>['collections'];
|
|
23
|
+
getVisualEditorRoute: (pathname: string) => VisualEditorRoute | null;
|
|
24
|
+
livePreview: {
|
|
25
|
+
brand: WikexStarterBrand;
|
|
26
|
+
pageBlocks: readonly BlockPickerOption[];
|
|
27
|
+
postBlocks: readonly BlockPickerOption[];
|
|
28
|
+
};
|
|
29
|
+
plugins: ReturnType<typeof createContentModule>['plugins'];
|
|
30
|
+
project: ReturnType<typeof defineWikexProject>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* One factory for the conventional Wikex Payload setup. The consuming project still owns
|
|
34
|
+
* its visual block components and frontend renderer, but no longer has to wire plugins,
|
|
35
|
+
* content schema, branding and preview routing independently.
|
|
36
|
+
*/
|
|
37
|
+
declare const createWikexStarter: (options: WikexStarterOptions) => WikexStarter;
|
|
38
|
+
|
|
39
|
+
export { type WikexStarter, type WikexStarterBrand, type WikexStarterOptions, createWikexStarter };
|
package/dist/starter.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
adminExperiencePlugin,
|
|
3
|
+
wikexAdminPlugin
|
|
4
|
+
} from "./chunk-7FEACJUN.js";
|
|
5
|
+
import {
|
|
6
|
+
createVisualEditorRouteResolver,
|
|
7
|
+
defineWikexProject
|
|
8
|
+
} from "./chunk-JJLHSZ3T.js";
|
|
9
|
+
|
|
10
|
+
// src/starter.ts
|
|
11
|
+
import { createContentModule } from "@wikex/content-kit";
|
|
12
|
+
var getLabel = (block) => {
|
|
13
|
+
if (typeof block.labels === "object" && block.labels && "singular" in block.labels) {
|
|
14
|
+
const singular = block.labels.singular;
|
|
15
|
+
if (typeof singular === "string") return singular;
|
|
16
|
+
}
|
|
17
|
+
return block.slug;
|
|
18
|
+
};
|
|
19
|
+
var isStarterBlock = (block) => typeof block === "object" && block !== null && "slug" in block && typeof block.slug === "string";
|
|
20
|
+
var toBlockPickerOptions = (blocks) => {
|
|
21
|
+
if (!Array.isArray(blocks)) return [];
|
|
22
|
+
return blocks.filter(isStarterBlock).map((block) => {
|
|
23
|
+
const label = getLabel(block);
|
|
24
|
+
return { description: label, label, payloadLabel: label, slug: block.slug };
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
var createWikexStarter = (options) => {
|
|
28
|
+
const seo = options.content.seo === void 0 ? { siteName: options.brand.name } : options.content.seo;
|
|
29
|
+
const content = createContentModule({ ...options.content, seo });
|
|
30
|
+
const collections = [content.pageSlug, content.postSlug].filter(
|
|
31
|
+
(slug) => Boolean(slug)
|
|
32
|
+
);
|
|
33
|
+
const getVisualEditorRoute = createVisualEditorRouteResolver({
|
|
34
|
+
collections,
|
|
35
|
+
globals: options.globals
|
|
36
|
+
});
|
|
37
|
+
const project = defineWikexProject({
|
|
38
|
+
brand: options.brand,
|
|
39
|
+
id: options.id,
|
|
40
|
+
modules: options.modules ?? ["website", "blog"]
|
|
41
|
+
});
|
|
42
|
+
const pageBlocks = toBlockPickerOptions(
|
|
43
|
+
options.content.page === false ? void 0 : options.content.page?.blocks
|
|
44
|
+
);
|
|
45
|
+
const postBlocks = toBlockPickerOptions(
|
|
46
|
+
options.content.post === false ? void 0 : options.content.post?.blocks
|
|
47
|
+
);
|
|
48
|
+
return {
|
|
49
|
+
collections: content.collections,
|
|
50
|
+
getVisualEditorRoute,
|
|
51
|
+
livePreview: { brand: options.brand, pageBlocks, postBlocks },
|
|
52
|
+
plugins: [
|
|
53
|
+
adminExperiencePlugin,
|
|
54
|
+
...content.plugins,
|
|
55
|
+
wikexAdminPlugin({ components: { provider: options.provider } })
|
|
56
|
+
],
|
|
57
|
+
project
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
export {
|
|
61
|
+
createWikexStarter
|
|
62
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
"use client";
|
|
3
|
+
import {
|
|
4
|
+
EDITABLE_PREVIEW_SELECTOR,
|
|
5
|
+
getEditableElementStyleKey,
|
|
6
|
+
getTextStyleCSS,
|
|
7
|
+
normalizeTextStyleMap
|
|
8
|
+
} from "./chunk-VK4EFLWH.js";
|
|
9
|
+
|
|
10
|
+
// src/TextStyleRuntime.tsx
|
|
11
|
+
import { useEffect } from "react";
|
|
12
|
+
var TextStyleRuntime = ({ styles }) => {
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const normalizedStyles = normalizeTextStyleMap(styles);
|
|
15
|
+
const originals = /* @__PURE__ */ new Map();
|
|
16
|
+
let applyFrame = 0;
|
|
17
|
+
const applyStyles = () => {
|
|
18
|
+
const fields = new Set(
|
|
19
|
+
document.querySelectorAll(`[data-wikex-field],${EDITABLE_PREVIEW_SELECTOR}`)
|
|
20
|
+
);
|
|
21
|
+
for (const element of fields) {
|
|
22
|
+
const fieldPath = element.dataset.wikexField || getEditableElementStyleKey(element);
|
|
23
|
+
if (!fieldPath || !normalizedStyles[fieldPath]) continue;
|
|
24
|
+
if (!originals.has(element)) {
|
|
25
|
+
originals.set(element, {
|
|
26
|
+
boxSizing: element.style.boxSizing,
|
|
27
|
+
fontFamily: element.style.fontFamily,
|
|
28
|
+
lineHeight: element.style.lineHeight,
|
|
29
|
+
marginLeft: element.style.marginLeft,
|
|
30
|
+
marginRight: element.style.marginRight,
|
|
31
|
+
maxWidth: element.style.maxWidth,
|
|
32
|
+
width: element.style.width
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const style = getTextStyleCSS(normalizedStyles[fieldPath]);
|
|
36
|
+
element.style.boxSizing = style.boxSizing || "";
|
|
37
|
+
element.style.fontFamily = style.fontFamily || "";
|
|
38
|
+
element.style.lineHeight = style.lineHeight || "";
|
|
39
|
+
element.style.marginLeft = style.marginLeft || "";
|
|
40
|
+
element.style.marginRight = style.marginRight || "";
|
|
41
|
+
element.style.maxWidth = style.maxWidth || "";
|
|
42
|
+
element.style.width = style.width || "";
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const scheduleApplyStyles = () => {
|
|
46
|
+
if (applyFrame) return;
|
|
47
|
+
applyFrame = window.requestAnimationFrame(() => {
|
|
48
|
+
applyFrame = 0;
|
|
49
|
+
applyStyles();
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
applyStyles();
|
|
53
|
+
const observer = new MutationObserver(scheduleApplyStyles);
|
|
54
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
55
|
+
return () => {
|
|
56
|
+
observer.disconnect();
|
|
57
|
+
window.cancelAnimationFrame(applyFrame);
|
|
58
|
+
for (const [element, original] of originals) {
|
|
59
|
+
if (!element.isConnected) continue;
|
|
60
|
+
element.style.boxSizing = original.boxSizing;
|
|
61
|
+
element.style.fontFamily = original.fontFamily;
|
|
62
|
+
element.style.lineHeight = original.lineHeight;
|
|
63
|
+
element.style.marginLeft = original.marginLeft;
|
|
64
|
+
element.style.marginRight = original.marginRight;
|
|
65
|
+
element.style.maxWidth = original.maxWidth;
|
|
66
|
+
element.style.width = original.width;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}, [styles]);
|
|
70
|
+
return null;
|
|
71
|
+
};
|
|
72
|
+
export {
|
|
73
|
+
TextStyleRuntime
|
|
74
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
declare const TEXT_FONT_OPTIONS: readonly [{
|
|
2
|
+
readonly css: "";
|
|
3
|
+
readonly label: "Mặc định";
|
|
4
|
+
readonly value: "default";
|
|
5
|
+
}, {
|
|
6
|
+
readonly css: "var(--font-manrope), sans-serif";
|
|
7
|
+
readonly label: "Manrope";
|
|
8
|
+
readonly value: "manrope";
|
|
9
|
+
}, {
|
|
10
|
+
readonly css: "var(--font-inter), sans-serif";
|
|
11
|
+
readonly label: "Inter";
|
|
12
|
+
readonly value: "inter";
|
|
13
|
+
}, {
|
|
14
|
+
readonly css: "var(--font-roboto), sans-serif";
|
|
15
|
+
readonly label: "Roboto";
|
|
16
|
+
readonly value: "roboto";
|
|
17
|
+
}, {
|
|
18
|
+
readonly css: "var(--font-montserrat), sans-serif";
|
|
19
|
+
readonly label: "Montserrat";
|
|
20
|
+
readonly value: "montserrat";
|
|
21
|
+
}, {
|
|
22
|
+
readonly css: "var(--font-lora), serif";
|
|
23
|
+
readonly label: "Lora";
|
|
24
|
+
readonly value: "lora";
|
|
25
|
+
}, {
|
|
26
|
+
readonly css: "var(--font-playfair-display), serif";
|
|
27
|
+
readonly label: "Playfair Display";
|
|
28
|
+
readonly value: "playfair-display";
|
|
29
|
+
}];
|
|
30
|
+
declare const TEXT_LINE_HEIGHT_OPTIONS: readonly [{
|
|
31
|
+
readonly css: "";
|
|
32
|
+
readonly label: "Mặc định";
|
|
33
|
+
readonly value: "default";
|
|
34
|
+
}, {
|
|
35
|
+
readonly css: "0.9";
|
|
36
|
+
readonly label: "Rất chặt · 0.9";
|
|
37
|
+
readonly value: "0.9";
|
|
38
|
+
}, {
|
|
39
|
+
readonly css: "1";
|
|
40
|
+
readonly label: "Chặt · 1.0";
|
|
41
|
+
readonly value: "1";
|
|
42
|
+
}, {
|
|
43
|
+
readonly css: "1.15";
|
|
44
|
+
readonly label: "Gọn · 1.15";
|
|
45
|
+
readonly value: "1.15";
|
|
46
|
+
}, {
|
|
47
|
+
readonly css: "1.35";
|
|
48
|
+
readonly label: "Tiêu chuẩn · 1.35";
|
|
49
|
+
readonly value: "1.35";
|
|
50
|
+
}, {
|
|
51
|
+
readonly css: "1.5";
|
|
52
|
+
readonly label: "Thoáng · 1.5";
|
|
53
|
+
readonly value: "1.5";
|
|
54
|
+
}, {
|
|
55
|
+
readonly css: "1.7";
|
|
56
|
+
readonly label: "Rộng · 1.7";
|
|
57
|
+
readonly value: "1.7";
|
|
58
|
+
}];
|
|
59
|
+
type TextFontFamily = (typeof TEXT_FONT_OPTIONS)[number]['value'];
|
|
60
|
+
type TextLineHeight = (typeof TEXT_LINE_HEIGHT_OPTIONS)[number]['value'];
|
|
61
|
+
type TextStyleValue = {
|
|
62
|
+
fontFamily?: TextFontFamily;
|
|
63
|
+
lineHeight?: TextLineHeight;
|
|
64
|
+
/** Percentage of the containing block, written by the canvas resize handles. */
|
|
65
|
+
width?: number;
|
|
66
|
+
/** Percentage offset from the containing block's left content edge. */
|
|
67
|
+
widthOffset?: number;
|
|
68
|
+
};
|
|
69
|
+
type TextStyleMap = Record<string, TextStyleValue>;
|
|
70
|
+
declare const EDITABLE_INTERACTIVE_SELECTOR: string;
|
|
71
|
+
declare const EDITABLE_PREVIEW_SELECTOR: string;
|
|
72
|
+
declare const isSyntheticElementStyleKey: (value: string) => boolean;
|
|
73
|
+
declare const getEditableElementStyleKey: (element: HTMLElement) => string;
|
|
74
|
+
declare const normalizeTextStyleValue: (value: unknown) => TextStyleValue;
|
|
75
|
+
declare const normalizeTextStyleMap: (value: unknown) => TextStyleMap;
|
|
76
|
+
declare const getTextStyleCSS: (value: TextStyleValue) => {
|
|
77
|
+
boxSizing?: "border-box";
|
|
78
|
+
fontFamily?: string;
|
|
79
|
+
lineHeight?: string;
|
|
80
|
+
marginLeft?: string;
|
|
81
|
+
marginRight?: string;
|
|
82
|
+
maxWidth?: string;
|
|
83
|
+
width?: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export { EDITABLE_INTERACTIVE_SELECTOR, EDITABLE_PREVIEW_SELECTOR, TEXT_FONT_OPTIONS, TEXT_LINE_HEIGHT_OPTIONS, type TextFontFamily, type TextLineHeight, type TextStyleMap, type TextStyleValue, getEditableElementStyleKey, getTextStyleCSS, isSyntheticElementStyleKey, normalizeTextStyleMap, normalizeTextStyleValue };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EDITABLE_INTERACTIVE_SELECTOR,
|
|
3
|
+
EDITABLE_PREVIEW_SELECTOR,
|
|
4
|
+
TEXT_FONT_OPTIONS,
|
|
5
|
+
TEXT_LINE_HEIGHT_OPTIONS,
|
|
6
|
+
getEditableElementStyleKey,
|
|
7
|
+
getTextStyleCSS,
|
|
8
|
+
isSyntheticElementStyleKey,
|
|
9
|
+
normalizeTextStyleMap,
|
|
10
|
+
normalizeTextStyleValue
|
|
11
|
+
} from "./chunk-BUD6BMFV.js";
|
|
12
|
+
export {
|
|
13
|
+
EDITABLE_INTERACTIVE_SELECTOR,
|
|
14
|
+
EDITABLE_PREVIEW_SELECTOR,
|
|
15
|
+
TEXT_FONT_OPTIONS,
|
|
16
|
+
TEXT_LINE_HEIGHT_OPTIONS,
|
|
17
|
+
getEditableElementStyleKey,
|
|
18
|
+
getTextStyleCSS,
|
|
19
|
+
isSyntheticElementStyleKey,
|
|
20
|
+
normalizeTextStyleMap,
|
|
21
|
+
normalizeTextStyleValue
|
|
22
|
+
};
|