@kyro-cms/admin 0.9.9 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +95 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +96 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/fields/RichTextField.tsx +45 -27
- package/src/hooks/examples/sample-hook-2.ts +0 -2
- package/src/integration.ts +28 -2
- package/src/plugins/examples/sample-plugin-2.ts +0 -1
- package/src/plugins/examples/sample-plugin.ts +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kyro-cms/admin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22"
|
|
6
6
|
},
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"vitest": "^4.1.4"
|
|
121
121
|
},
|
|
122
122
|
"peerDependencies": {
|
|
123
|
-
"@kyro-cms/core": "^0.
|
|
123
|
+
"@kyro-cms/core": "^0.10.0",
|
|
124
124
|
"react": "^19.0.0",
|
|
125
125
|
"react-dom": "^19.0.0"
|
|
126
126
|
},
|
|
@@ -521,23 +521,58 @@ export default function RichTextField({
|
|
|
521
521
|
error,
|
|
522
522
|
disabled,
|
|
523
523
|
}: RichTextFieldProps) {
|
|
524
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
525
|
-
const [panelWidth, setPanelWidth] = useState(0);
|
|
526
|
-
const [isMediaPickerOpen, setIsMediaPickerOpen] = useState(false);
|
|
527
524
|
const [isMounted, setIsMounted] = useState(false);
|
|
528
525
|
|
|
529
526
|
useEffect(() => {
|
|
530
527
|
setIsMounted(true);
|
|
531
528
|
}, []);
|
|
532
529
|
|
|
530
|
+
if (!isMounted) {
|
|
531
|
+
return (
|
|
532
|
+
<FieldLayout field={field} error={error}>
|
|
533
|
+
<div
|
|
534
|
+
className={`border rounded-lg bg-[var(--kyro-bg)] overflow-hidden border-[var(--kyro-border)] flex flex-col shadow-sm transition-all duration-200
|
|
535
|
+
${error ? "border-[var(--kyro-error)] shadow-[0_0_0_1px_var(--kyro-error)]" : "border-[var(--kyro-border)]"}
|
|
536
|
+
${disabled ? "opacity-60 cursor-not-allowed" : ""}`}
|
|
537
|
+
>
|
|
538
|
+
<div className="flex flex-wrap items-center gap-1.5 p-1.5 border-b border-[var(--kyro-border)] bg-[var(--kyro-bg-secondary)] rounded-t-lg h-[40px]"></div>
|
|
539
|
+
<div className="overflow-y-auto min-h-[160px] max-h-[400px] p-4"></div>
|
|
540
|
+
</div>
|
|
541
|
+
</FieldLayout>
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return (
|
|
546
|
+
<RichTextEditor
|
|
547
|
+
field={field}
|
|
548
|
+
value={value}
|
|
549
|
+
onChange={onChange}
|
|
550
|
+
error={error}
|
|
551
|
+
disabled={disabled}
|
|
552
|
+
/>
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function RichTextEditor({
|
|
557
|
+
field,
|
|
558
|
+
value,
|
|
559
|
+
onChange,
|
|
560
|
+
error,
|
|
561
|
+
disabled,
|
|
562
|
+
}: RichTextFieldProps) {
|
|
563
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
564
|
+
const [panelWidth, setPanelWidth] = useState(0);
|
|
565
|
+
const [isMediaPickerOpen, setIsMediaPickerOpen] = useState(false);
|
|
566
|
+
|
|
533
567
|
useEffect(() => {
|
|
534
568
|
if (!isExpanded) {
|
|
535
569
|
setPanelWidth(0);
|
|
536
570
|
return;
|
|
537
571
|
}
|
|
538
572
|
|
|
573
|
+
const panel = document.querySelector('[data-kyro-slide-panel="true"]');
|
|
574
|
+
|
|
539
575
|
const updateWidth = () => {
|
|
540
|
-
const panel = document.querySelector('[data-kyro-slide-panel="true"]');
|
|
541
576
|
if (panel) {
|
|
542
577
|
setPanelWidth(panel.getBoundingClientRect().width);
|
|
543
578
|
} else {
|
|
@@ -547,12 +582,10 @@ export default function RichTextField({
|
|
|
547
582
|
|
|
548
583
|
updateWidth();
|
|
549
584
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
updateWidth();
|
|
555
|
-
});
|
|
585
|
+
const observer = new MutationObserver(() => {
|
|
586
|
+
updateWidth();
|
|
587
|
+
});
|
|
588
|
+
if (panel) {
|
|
556
589
|
observer.observe(panel);
|
|
557
590
|
}
|
|
558
591
|
|
|
@@ -593,7 +626,7 @@ export default function RichTextField({
|
|
|
593
626
|
TextStyle,
|
|
594
627
|
Color,
|
|
595
628
|
],
|
|
596
|
-
content: value || { type: "doc", content: [] },
|
|
629
|
+
content: Array.isArray(value) ? { type: "doc", content: value } : (value || { type: "doc", content: [] }),
|
|
597
630
|
editable: !disabled,
|
|
598
631
|
onUpdate: ({ editor }: { editor: any }) => {
|
|
599
632
|
onChange(editor.getJSON());
|
|
@@ -608,25 +641,10 @@ export default function RichTextField({
|
|
|
608
641
|
|
|
609
642
|
useEffect(() => {
|
|
610
643
|
if (editor && value && JSON.stringify(value) !== JSON.stringify(editor.getJSON())) {
|
|
611
|
-
editor.commands.setContent(value);
|
|
644
|
+
editor.commands.setContent(Array.isArray(value) ? { type: "doc", content: value } : value);
|
|
612
645
|
}
|
|
613
646
|
}, [value, editor]);
|
|
614
647
|
|
|
615
|
-
if (!isMounted) {
|
|
616
|
-
return (
|
|
617
|
-
<FieldLayout field={field} error={error}>
|
|
618
|
-
<div
|
|
619
|
-
className={`border rounded-lg bg-[var(--kyro-bg)] overflow-hidden border-[var(--kyro-border)] flex flex-col shadow-sm transition-all duration-200
|
|
620
|
-
${error ? "border-[var(--kyro-error)] shadow-[0_0_0_1px_var(--kyro-error)]" : "border-[var(--kyro-border)]"}
|
|
621
|
-
${disabled ? "opacity-60 cursor-not-allowed" : ""}`}
|
|
622
|
-
>
|
|
623
|
-
<div className="flex flex-wrap items-center gap-1.5 p-1.5 border-b border-[var(--kyro-border)] bg-[var(--kyro-bg-secondary)] rounded-t-lg h-[40px]"></div>
|
|
624
|
-
<div className="overflow-y-auto min-h-[160px] max-h-[400px] p-4"></div>
|
|
625
|
-
</div>
|
|
626
|
-
</FieldLayout>
|
|
627
|
-
);
|
|
628
|
-
}
|
|
629
|
-
|
|
630
648
|
return (
|
|
631
649
|
<FieldLayout field={field} error={error}>
|
|
632
650
|
{isExpanded ? (
|
|
@@ -6,8 +6,6 @@ export default function registerSampleHook2() {
|
|
|
6
6
|
onAdminReady((ctx: AdminContext) => {
|
|
7
7
|
// Minimal side-effect demonstration
|
|
8
8
|
void ctx;
|
|
9
|
-
// eslint-disable-next-line no-console
|
|
10
|
-
console.log("[KyroAdmin] sample-hook-2 ready");
|
|
11
9
|
return { success: true } as HookResult;
|
|
12
10
|
});
|
|
13
11
|
}
|
package/src/integration.ts
CHANGED
|
@@ -176,7 +176,6 @@ export function c(size) {
|
|
|
176
176
|
function debug(namespace) {
|
|
177
177
|
function d(...args) {
|
|
178
178
|
if (typeof localStorage !== "undefined" && localStorage.getItem("DEBUG")) {
|
|
179
|
-
console.log(namespace, ...args);
|
|
180
179
|
}
|
|
181
180
|
}
|
|
182
181
|
d.enabled = false;
|
|
@@ -196,9 +195,26 @@ export default debug;
|
|
|
196
195
|
"kyro:config": resolvedConfig,
|
|
197
196
|
},
|
|
198
197
|
},
|
|
198
|
+
build: {
|
|
199
|
+
rollupOptions: {
|
|
200
|
+
output: {
|
|
201
|
+
manualChunks(id: string) {
|
|
202
|
+
if (id.includes("@tiptap") || id.includes("prosemirror")) {
|
|
203
|
+
return "vendor-tiptap";
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
},
|
|
199
209
|
optimizeDeps: {
|
|
200
210
|
include: [
|
|
211
|
+
'@kyro-cms/admin',
|
|
201
212
|
'use-sync-external-store',
|
|
213
|
+
'@tiptap/core', '@tiptap/react', '@tiptap/pm', '@tiptap/starter-kit',
|
|
214
|
+
'@tiptap/extension-link', '@tiptap/extension-image', '@tiptap/extension-text-align',
|
|
215
|
+
'@tiptap/extension-underline', '@tiptap/extension-highlight',
|
|
216
|
+
'@tiptap/extension-task-list', '@tiptap/extension-task-item',
|
|
217
|
+
'@tiptap/extension-text-style', '@tiptap/extension-color',
|
|
202
218
|
],
|
|
203
219
|
exclude: ['debug', 'react/compiler-runtime'],
|
|
204
220
|
},
|
|
@@ -208,7 +224,17 @@ export default debug;
|
|
|
208
224
|
__KYRO_ADMIN_CONFIG_FILE__: JSON.stringify(configFile),
|
|
209
225
|
},
|
|
210
226
|
ssr: {
|
|
211
|
-
noExternal: [
|
|
227
|
+
noExternal: [
|
|
228
|
+
'@kyro-cms/admin', '@kyro-cms/core',
|
|
229
|
+
'@tiptap/core', '@tiptap/react', '@tiptap/pm', '@tiptap/starter-kit',
|
|
230
|
+
'@tiptap/extension-link', '@tiptap/extension-image', '@tiptap/extension-text-align',
|
|
231
|
+
'@tiptap/extension-underline', '@tiptap/extension-highlight',
|
|
232
|
+
'@tiptap/extension-task-list', '@tiptap/extension-task-item',
|
|
233
|
+
'@tiptap/extension-text-style', '@tiptap/extension-color',
|
|
234
|
+
'prosemirror-model', 'prosemirror-state', 'prosemirror-view',
|
|
235
|
+
'prosemirror-schema-list', 'prosemirror-commands', 'prosemirror-keymap',
|
|
236
|
+
'prosemirror-transform', 'prosemirror-inputrules',
|
|
237
|
+
],
|
|
212
238
|
},
|
|
213
239
|
},
|
|
214
240
|
});
|
|
@@ -10,7 +10,6 @@ const samplePlugin2: KyroPlugin = {
|
|
|
10
10
|
beforeDeploy: (ctx) => {
|
|
11
11
|
// Lightweight side-effect; in real plugins, you could validate config, migrations, etc.
|
|
12
12
|
void ctx;
|
|
13
|
-
console.log("[Kyro Admin] sample-plugin-2 beforeDeploy");
|
|
14
13
|
return { success: true };
|
|
15
14
|
},
|
|
16
15
|
},
|
|
@@ -9,8 +9,6 @@ const samplePlugin: KyroPlugin = {
|
|
|
9
9
|
hooks: {
|
|
10
10
|
onAdminReady: () => {
|
|
11
11
|
// Lightweight side-effect; in real plugins this could mount UI or register editors
|
|
12
|
-
// eslint-disable-next-line no-console
|
|
13
|
-
console.log("[ Kyro Admin ] sample-plugin: onAdminReady executed");
|
|
14
12
|
return;
|
|
15
13
|
},
|
|
16
14
|
},
|