@kyro-cms/admin 0.9.8 → 0.9.9

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.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { createContext, lazy, useState, useContext, useRef, useEffect, useCallback, useMemo, Suspense } from 'react';
1
+ import React, { createContext, lazy, useState, useRef, useEffect, useCallback, useContext, useMemo, Suspense } from 'react';
2
2
  import { create, useStore } from 'zustand';
3
3
  import { persist, createJSONStorage } from 'zustand/middleware';
4
4
  import { GripVertical, Copy, X, Video, Mail, Clock, Database, Users, Tag, Image, Activity, CircleHelp, Sparkles, Blocks, Columns3, Link2, ListOrdered, Box, Heading1, Star, AlignLeft, ChevronDown, File, Code, List, Plus, ChevronRight, ChevronUp, Search, LoaderCircle, Check, RefreshCw, Undo, Redo, Bold, Italic, Underline, Strikethrough, Highlighter, Palette, CheckSquare, Quote, Terminal, Minus, AlignCenter, AlignRight, Link, Minimize2, Maximize2, Grid3X3, Filter, FolderPlus, FolderInput, Folder, Trash2, Film, Music, FileText, Archive, Download, Crop, Server, CodeXml, Pencil, Eye, EllipsisVertical, Send, Info, TriangleAlert, ShieldAlert, CircleCheck, History, CheckCircle2, User, GitCompare, Undo2, ExternalLink, Settings, Shield, Hexagon, Network, Sun, Moon, LogOut, ArrowRight, LayoutDashboard, ArrowUpRight, Webhook, Zap, Pause, Play, Key, Lock, EyeOff, CirclePlay, RefreshCcw, Save, UserPlus, LockOpen } from 'lucide-react';
@@ -5867,6 +5867,7 @@ function createNewBlock(type) {
5867
5867
  return {
5868
5868
  id: Math.random().toString(36).substr(2, 9),
5869
5869
  type,
5870
+ name: "",
5870
5871
  data,
5871
5872
  options,
5872
5873
  children,
@@ -7504,6 +7505,18 @@ var BlockEditModal = ({
7504
7505
  accentClass: theme.border,
7505
7506
  children: [
7506
7507
  /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
7508
+ /* @__PURE__ */ jsxs("div", { children: [
7509
+ /* @__PURE__ */ jsx("label", { className: "text-[10px] font-medium text-[var(--kyro-text-muted)] mb-1 block", children: "Block Name" }),
7510
+ /* @__PURE__ */ jsx(
7511
+ "input",
7512
+ {
7513
+ value: blockData?.name || "",
7514
+ onChange: (e) => updateBlock(block3.id, { name: e.target.value }),
7515
+ placeholder: blockSchema?.label || block3.type,
7516
+ className: "w-full bg-[var(--kyro-bg-primary)] border border-[var(--kyro-border)] rounded-lg px-3 py-2 text-sm text-[var(--kyro-text-primary)] outline-none focus:border-[var(--kyro-primary)] transition-colors"
7517
+ }
7518
+ )
7519
+ ] }),
7507
7520
  renderFields(),
7508
7521
  children.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t border-[var(--kyro-border)]", children: [
7509
7522
  /* @__PURE__ */ jsxs("label", { className: "text-[10px] font-medium text-[var(--kyro-text-muted)] mb-1.5 block", children: [
@@ -7615,7 +7628,7 @@ var ChildBlocksTree = ({
7615
7628
  blockIcons[child.type] && /* @__PURE__ */ jsx("div", { className: "w-8 h-8 rounded bg-[var(--kyro-surface-accent)] flex items-center justify-center text-[var(--kyro-text-secondary)]", children: blockIcons[child.type] }),
7616
7629
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
7617
7630
  /* @__PURE__ */ jsxs("div", { className: "text-xs font-medium text-[var(--kyro-text-secondary)] truncate", children: [
7618
- getBlockLabel(child.type),
7631
+ getBlockDisplayLabel(child),
7619
7632
  child.data?.text ? ` - ${child.data.text.slice(0, 30)}` : "",
7620
7633
  child.data?.heading ? ` - ${child.data.heading.slice(0, 30)}` : ""
7621
7634
  ] }),
@@ -7836,7 +7849,7 @@ var NestedChildBlocks = ({
7836
7849
  blockIcons[child.type] && /* @__PURE__ */ jsx("div", { className: "w-8 h-8 rounded bg-[var(--kyro-surface-accent)] flex items-center justify-center text-[var(--kyro-text-secondary)]", children: blockIcons[child.type] }),
7837
7850
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
7838
7851
  /* @__PURE__ */ jsxs("div", { className: "text-xs font-medium text-[var(--kyro-text-secondary)] truncate", children: [
7839
- getBlockLabel(child.type),
7852
+ getBlockDisplayLabel(child),
7840
7853
  child.data?.text ? ` - ${child.data.text.slice(0, 30)}` : "",
7841
7854
  child.data?.heading ? ` - ${child.data.heading.slice(0, 30)}` : ""
7842
7855
  ] }),
@@ -8550,7 +8563,7 @@ var blockIcons = {
8550
8563
  function getBlockComponent(type) {
8551
8564
  return BLOCK_COMPONENTS[type] || null;
8552
8565
  }
8553
- function getBlockLabel(type) {
8566
+ function getBlockLabel2(type) {
8554
8567
  const labelMap = {
8555
8568
  // Primitives
8556
8569
  paragraph: "Paragraph",
@@ -8593,6 +8606,11 @@ function getBlockLabel(type) {
8593
8606
  };
8594
8607
  return labelMap[type] || type;
8595
8608
  }
8609
+ function getBlockDisplayLabel(block3) {
8610
+ const name = block3.name;
8611
+ if (name && name.trim()) return name.trim();
8612
+ return getBlockLabel2(block3.type);
8613
+ }
8596
8614
  function getBlockPreviewSnippet(data, blockSchema) {
8597
8615
  if (blockSchema?.fields) {
8598
8616
  for (const field3 of blockSchema.fields) {
@@ -8621,16 +8639,32 @@ var SortableBlockComponent = ({
8621
8639
  transition,
8622
8640
  isDragging
8623
8641
  } = useSortable({ id: block3.id });
8624
- const { removeBlock } = useBlockActions();
8642
+ const { removeBlock, updateBlock } = useBlockActions();
8625
8643
  const isEditing = editingBlockId === block3.id;
8626
8644
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
8645
+ const [editingName, setEditingName] = useState(false);
8646
+ const [nameDraft, setNameDraft] = useState(block3.name || "");
8647
+ const nameInputRef = useRef(null);
8648
+ useEffect(() => {
8649
+ if (editingName && nameInputRef.current) {
8650
+ nameInputRef.current.focus();
8651
+ nameInputRef.current.select();
8652
+ }
8653
+ }, [editingName]);
8654
+ const commitName = useCallback(() => {
8655
+ setEditingName(false);
8656
+ const trimmed = nameDraft.trim();
8657
+ if (trimmed !== (block3.name || "").trim()) {
8658
+ updateBlock(block3.id, { name: trimmed || "" });
8659
+ }
8660
+ }, [nameDraft, block3.name, block3.id, updateBlock]);
8627
8661
  const style = {
8628
8662
  transform: CSS.Transform.toString(transform),
8629
8663
  transition,
8630
8664
  zIndex: isDragging ? 10 : 1,
8631
8665
  opacity: isDragging ? 0.8 : 1
8632
8666
  };
8633
- const itemLabel = getBlockLabel(block3.type);
8667
+ const itemLabel = getBlockDisplayLabel(block3);
8634
8668
  const data = block3.data || {};
8635
8669
  const previewSnippet = getBlockPreviewSnippet(data, blockSchema);
8636
8670
  if (compact) {
@@ -8652,7 +8686,36 @@ var SortableBlockComponent = ({
8652
8686
  }
8653
8687
  ),
8654
8688
  blockIcons[block3.type] && /* @__PURE__ */ jsx("span", { className: "text-[var(--kyro-text-secondary)] flex-shrink-0", children: blockIcons[block3.type] }),
8655
- /* @__PURE__ */ jsx("span", { className: "font-medium text-[var(--kyro-text-secondary)] truncate max-w-[120px]", children: itemLabel }),
8689
+ editingName ? /* @__PURE__ */ jsx(
8690
+ "input",
8691
+ {
8692
+ ref: nameInputRef,
8693
+ value: nameDraft,
8694
+ onChange: (e) => setNameDraft(e.target.value),
8695
+ onBlur: commitName,
8696
+ onKeyDown: (e) => {
8697
+ if (e.key === "Enter") commitName();
8698
+ if (e.key === "Escape") {
8699
+ setNameDraft(block3.name || "");
8700
+ setEditingName(false);
8701
+ }
8702
+ },
8703
+ onClick: (e) => e.stopPropagation(),
8704
+ className: "flex-1 min-w-0 bg-[var(--kyro-surface-accent)] border border-[var(--kyro-primary)] rounded px-1.5 py-0.5 text-[10px] font-medium text-[var(--kyro-text-primary)] outline-none"
8705
+ }
8706
+ ) : /* @__PURE__ */ jsx(
8707
+ "span",
8708
+ {
8709
+ onClick: (e) => {
8710
+ e.stopPropagation();
8711
+ setNameDraft(block3.name || "");
8712
+ setEditingName(true);
8713
+ },
8714
+ className: "font-medium text-[var(--kyro-text-secondary)] truncate max-w-[120px] cursor-text hover:text-[var(--kyro-text-primary)] transition-colors",
8715
+ title: "Click to rename",
8716
+ children: itemLabel
8717
+ }
8718
+ ),
8656
8719
  showDeleteConfirm ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", onClick: (e) => e.stopPropagation(), children: [
8657
8720
  /* @__PURE__ */ jsx(
8658
8721
  "button",
@@ -8734,13 +8797,43 @@ var SortableBlockComponent = ({
8734
8797
  children: [
8735
8798
  blockIcons[block3.type] && /* @__PURE__ */ jsx("span", { className: "text-[var(--kyro-text-secondary)]", children: blockIcons[block3.type] }),
8736
8799
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
8737
- /* @__PURE__ */ jsxs("div", { className: "text-xs font-semibold text-[var(--kyro-text-secondary)] truncate", children: [
8738
- itemLabel,
8739
- previewSnippet && typeof previewSnippet === "string" && /* @__PURE__ */ jsxs("span", { className: "text-[var(--kyro-text-muted)] font-normal ml-1.5", children: [
8740
- "- ",
8741
- previewSnippet.length > 40 ? `${previewSnippet.slice(0, 40)}...` : previewSnippet
8742
- ] })
8743
- ] }),
8800
+ editingName ? /* @__PURE__ */ jsx(
8801
+ "input",
8802
+ {
8803
+ ref: nameInputRef,
8804
+ value: nameDraft,
8805
+ onChange: (e) => setNameDraft(e.target.value),
8806
+ onBlur: commitName,
8807
+ onKeyDown: (e) => {
8808
+ if (e.key === "Enter") commitName();
8809
+ if (e.key === "Escape") {
8810
+ setNameDraft(block3.name || "");
8811
+ setEditingName(false);
8812
+ }
8813
+ },
8814
+ onClick: (e) => e.stopPropagation(),
8815
+ placeholder: getBlockLabel2(block3.type),
8816
+ className: "w-full bg-[var(--kyro-surface-accent)] border border-[var(--kyro-primary)] rounded px-2 py-0.5 text-xs font-semibold text-[var(--kyro-text-primary)] outline-none"
8817
+ }
8818
+ ) : /* @__PURE__ */ jsxs(
8819
+ "div",
8820
+ {
8821
+ onClick: (e) => {
8822
+ e.stopPropagation();
8823
+ setNameDraft(block3.name || "");
8824
+ setEditingName(true);
8825
+ },
8826
+ className: "text-xs font-semibold text-[var(--kyro-text-secondary)] truncate cursor-text hover:text-[var(--kyro-text-primary)] transition-colors",
8827
+ title: "Click to rename",
8828
+ children: [
8829
+ itemLabel,
8830
+ previewSnippet && typeof previewSnippet === "string" && /* @__PURE__ */ jsxs("span", { className: "text-[var(--kyro-text-muted)] font-normal ml-1.5", children: [
8831
+ "- ",
8832
+ previewSnippet.length > 40 ? `${previewSnippet.slice(0, 40)}...` : previewSnippet
8833
+ ] })
8834
+ ]
8835
+ }
8836
+ ),
8744
8837
  blockSchema?.admin?.description && /* @__PURE__ */ jsx("div", { className: "text-[10px] text-[var(--kyro-text-muted)] mt-0.5 truncate opacity-80", children: blockSchema.admin.description })
8745
8838
  ] }),
8746
8839
  block3.children && Array.isArray(block3.children) && block3.children.length > 0 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] bg-[var(--kyro-surface-accent)] px-2 py-0.5 rounded text-[var(--kyro-text-muted)] font-medium", children: [