@kyro-cms/admin 0.12.19 → 0.12.20
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 +13 -13
- package/dist/index.js +13 -13
- package/package.json +1 -1
- package/src/components/AutoForm.tsx +1 -0
- package/src/components/fields/ArrayLayout.tsx +8 -8
- package/src/components/fields/CodeField.tsx +0 -1
- package/src/components/fields/TabsLayout.tsx +5 -2
- package/src/components/ui/SeoPreview.tsx +25 -21
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import { CSS } from "@dnd-kit/utilities";
|
|
20
20
|
import { useTranslation } from "react-i18next";
|
|
21
21
|
|
|
22
|
-
const SIMPLE_TYPES = new Set(["text", "number", "checkbox", "select", "radio", "color", "email", "password"]);
|
|
22
|
+
const SIMPLE_TYPES = new Set(["text", "number", "checkbox", "select", "radio", "color", "email", "password", "url", "id"]);
|
|
23
23
|
|
|
24
24
|
function extractLabelFromObj(obj: unknown): string | null {
|
|
25
25
|
if (!obj || typeof obj !== "object") return null;
|
|
@@ -120,7 +120,7 @@ function SortableArrayItem({
|
|
|
120
120
|
<div
|
|
121
121
|
ref={setNodeRef}
|
|
122
122
|
style={style}
|
|
123
|
-
className="flex items-start gap-
|
|
123
|
+
className="flex items-start gap-3 p-3.5 mb-2 border border-[var(--kyro-border)] rounded-[var(--kyro-radius-md)] bg-[var(--kyro-surface-accent)]/15 hover:border-[var(--kyro-border-accent)] transition-all group/item shadow-xs"
|
|
124
124
|
>
|
|
125
125
|
<div
|
|
126
126
|
{...attributes}
|
|
@@ -132,9 +132,9 @@ function SortableArrayItem({
|
|
|
132
132
|
<span className="text-[10px] font-bold text-[var(--kyro-text-muted)] pt-2.5 min-w-[18px] text-center">
|
|
133
133
|
{index + 1}
|
|
134
134
|
</span>
|
|
135
|
-
<div className={`flex-1 min-w-0 ${fields.length >= 3 ? "flex flex-col gap-
|
|
135
|
+
<div className={`flex-1 min-w-0 ${fields.length >= 3 ? "flex flex-col gap-2" : "grid grid-cols-1 sm:grid-cols-2 gap-3"}`}>
|
|
136
136
|
{fields.map((f: Field) => (
|
|
137
|
-
<div key={f.name} className="
|
|
137
|
+
<div key={f.name} className="min-w-0">
|
|
138
138
|
{renderField(f, item, onChangeItem)}
|
|
139
139
|
</div>
|
|
140
140
|
))}
|
|
@@ -143,10 +143,10 @@ function SortableArrayItem({
|
|
|
143
143
|
type="button"
|
|
144
144
|
disabled={disabled}
|
|
145
145
|
onClick={onRemove}
|
|
146
|
-
className="text-[var(--kyro-text-muted)] hover:text-[var(--kyro-error)] transition-colors disabled:opacity-30 p-
|
|
146
|
+
className="text-[var(--kyro-text-muted)] hover:text-[var(--kyro-error)] transition-colors disabled:opacity-30 p-1 mt-1.5 flex-shrink-0 rounded hover:bg-[var(--kyro-surface-accent)]"
|
|
147
147
|
title={t("tooltips.remove", { defaultValue: "Remove" })}
|
|
148
148
|
>
|
|
149
|
-
<svg width="
|
|
149
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
150
150
|
<line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
|
|
151
151
|
</svg>
|
|
152
152
|
</button>
|
|
@@ -437,7 +437,7 @@ export function ArrayLayout({
|
|
|
437
437
|
onDragEnd={handleDragEnd}
|
|
438
438
|
>
|
|
439
439
|
{compact ? (
|
|
440
|
-
<div className="kyro-form-array kyro-form-array--compact border border-[var(--kyro-border)] bg-[var(--kyro-surface-accent)]/
|
|
440
|
+
<div className="kyro-form-array kyro-form-array--compact border border-[var(--kyro-border)] bg-[var(--kyro-surface-accent)]/10 rounded-lg p-3">
|
|
441
441
|
<SortableContext
|
|
442
442
|
items={itemIds}
|
|
443
443
|
strategy={verticalListSortingStrategy}
|
|
@@ -466,7 +466,7 @@ export function ArrayLayout({
|
|
|
466
466
|
</SortableContext>
|
|
467
467
|
<button
|
|
468
468
|
type="button"
|
|
469
|
-
className="w-full py-2 border
|
|
469
|
+
className="w-full py-2.5 border border-dashed border-[var(--kyro-border)] rounded-md text-xs font-bold text-[var(--kyro-text-secondary)] hover:text-[var(--kyro-primary)] hover:border-[var(--kyro-primary)] bg-[var(--kyro-surface)]/50 transition-all disabled:opacity-50 mt-1"
|
|
470
470
|
disabled={disabled}
|
|
471
471
|
onClick={() => onChange([...items, { id: Math.random().toString(36).substr(2, 9) }])}
|
|
472
472
|
>
|
|
@@ -5,6 +5,7 @@ import { SeoPreview } from "../ui/SeoPreview";
|
|
|
5
5
|
interface TabsLayoutProps {
|
|
6
6
|
field: Field;
|
|
7
7
|
formData: Record<string, unknown>;
|
|
8
|
+
collectionSlug?: string;
|
|
8
9
|
onTabDataChange: (value: unknown) => void;
|
|
9
10
|
renderField: (
|
|
10
11
|
field: Field,
|
|
@@ -16,6 +17,7 @@ interface TabsLayoutProps {
|
|
|
16
17
|
export function TabsLayout({
|
|
17
18
|
field,
|
|
18
19
|
formData,
|
|
20
|
+
collectionSlug,
|
|
19
21
|
onTabDataChange,
|
|
20
22
|
renderField,
|
|
21
23
|
}: TabsLayoutProps) {
|
|
@@ -39,7 +41,7 @@ export function TabsLayout({
|
|
|
39
41
|
<button
|
|
40
42
|
key={index}
|
|
41
43
|
type="button"
|
|
42
|
-
className={`px-6 py-3 text-sm
|
|
44
|
+
className={`px-6 py-3 text-sm tracking-widest font-medium transition-all border-b-2 -mb-[1px] whitespace-nowrap ${
|
|
43
45
|
activeTab === index
|
|
44
46
|
? "border-[var(--kyro-primary)] text-[var(--kyro-primary)]"
|
|
45
47
|
: "border-transparent text-[var(--kyro-text-secondary)] hover:text-[var(--kyro-text-primary)] opacity-60 hover:opacity-100"
|
|
@@ -63,7 +65,7 @@ export function TabsLayout({
|
|
|
63
65
|
|
|
64
66
|
{currentTab?.label === "SEO Settings" && (
|
|
65
67
|
<div className="mt-12 pt-8 border-t border-[var(--kyro-border)]">
|
|
66
|
-
<h4 className="text-[10px] font-bold text-[var(--kyro-text-secondary)]
|
|
68
|
+
<h4 className="text-[10px] font-bold text-[var(--kyro-text-secondary)] tracking-[0.2em] mb-6 opacity-50">
|
|
67
69
|
Live Google Preview
|
|
68
70
|
</h4>
|
|
69
71
|
<SeoPreview
|
|
@@ -80,6 +82,7 @@ export function TabsLayout({
|
|
|
80
82
|
(typeof formData.slug === "object" ? "" : formData.slug) ||
|
|
81
83
|
"your-slug"
|
|
82
84
|
)}
|
|
85
|
+
collectionSlug={collectionSlug}
|
|
83
86
|
/>
|
|
84
87
|
</div>
|
|
85
88
|
)}
|
|
@@ -4,28 +4,32 @@ interface SeoPreviewProps {
|
|
|
4
4
|
title: string;
|
|
5
5
|
description: string;
|
|
6
6
|
slug: string;
|
|
7
|
+
collectionSlug?: string;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
export const SeoPreview = ({ title, description, slug }: SeoPreviewProps) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
export const SeoPreview = ({ title, description, slug, collectionSlug }: SeoPreviewProps) => {
|
|
11
|
+
const collectionName = collectionSlug || "posts";
|
|
12
|
+
return (
|
|
13
|
+
<div className="bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-lg p-6 max-w-2xl shadow-sm transition-colors duration-300">
|
|
14
|
+
<div className="flex items-center gap-2 mb-2">
|
|
15
|
+
<div className="w-7 h-7 bg-[var(--kyro-bg-secondary)] rounded-full flex items-center justify-center text-[10px] text-[var(--kyro-text-primary)] font-medium border border-[var(--kyro-border)]">
|
|
16
|
+
K
|
|
17
|
+
</div>
|
|
18
|
+
<div className="flex flex-col">
|
|
19
|
+
<span className="text-sm font-medium text-[var(--kyro-text-primary)] leading-tight">
|
|
20
|
+
kyro-cms.com
|
|
21
|
+
</span>
|
|
22
|
+
<span className="text-[12px] text-[var(--kyro-text-secondary)] leading-tight opacity-80">
|
|
23
|
+
https://kyro-cms.com › {collectionName} › {slug}
|
|
24
|
+
</span>
|
|
25
|
+
</div>
|
|
22
26
|
</div>
|
|
27
|
+
<h3 className="text-[20px] text-[#2563eb] dark:text-[#60a5fa] font-medium hover:underline cursor-pointer mb-1 leading-tight transition-colors">
|
|
28
|
+
{title}
|
|
29
|
+
</h3>
|
|
30
|
+
<p className="text-[14px] text-[var(--kyro-text-secondary)] leading-relaxed line-clamp-2">
|
|
31
|
+
{description}
|
|
32
|
+
</p>
|
|
23
33
|
</div>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
</h3>
|
|
27
|
-
<p className="text-[14px] text-[var(--kyro-text-secondary)] leading-relaxed line-clamp-2">
|
|
28
|
-
{description}
|
|
29
|
-
</p>
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
34
|
+
);
|
|
35
|
+
};
|