@kyro-cms/admin 0.3.1 → 0.3.4

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.
Files changed (242) hide show
  1. package/dist/EditorClient-XEUOVAAC.js +466 -0
  2. package/dist/EditorClient-XEUOVAAC.js.map +1 -0
  3. package/dist/EditorClient-YLCGVDXY.cjs +468 -0
  4. package/dist/EditorClient-YLCGVDXY.cjs.map +1 -0
  5. package/dist/chunk-7KPIUCGT.js +384 -0
  6. package/dist/chunk-7KPIUCGT.js.map +1 -0
  7. package/dist/chunk-GOACG6R7.cjs +473 -0
  8. package/dist/chunk-GOACG6R7.cjs.map +1 -0
  9. package/dist/index.cjs +14861 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.css +1661 -0
  12. package/dist/index.css.map +1 -0
  13. package/dist/index.d.ts +563 -0
  14. package/dist/index.js +14784 -0
  15. package/dist/index.js.map +1 -0
  16. package/package.json +19 -19
  17. package/src/components/ActionBar.tsx +7 -43
  18. package/src/components/Admin.tsx +138 -277
  19. package/src/components/ApiKeysManager.tsx +428 -419
  20. package/src/components/AuditLogsPage.tsx +35 -39
  21. package/src/components/AuthBridge.tsx +51 -0
  22. package/src/components/AutoForm.tsx +495 -1230
  23. package/src/components/BrandingHub.tsx +18 -19
  24. package/src/components/BulkActionsBar.tsx +1 -1
  25. package/src/components/CreateView.tsx +22 -36
  26. package/src/components/Dashboard.tsx +60 -84
  27. package/src/components/DetailView.tsx +113 -91
  28. package/src/components/DeveloperCenter.tsx +200 -198
  29. package/src/components/FieldRenderer.tsx +206 -0
  30. package/src/components/GraphQLPlayground.tsx +340 -480
  31. package/src/components/ListView.tsx +828 -254
  32. package/src/components/LoginPage.tsx +3 -4
  33. package/src/components/MarketplaceManager.tsx +254 -0
  34. package/src/components/MediaGallery.tsx +856 -1192
  35. package/src/components/PluginsManager.tsx +277 -0
  36. package/src/components/RestPlayground.tsx +398 -560
  37. package/src/components/SessionsManager.tsx +211 -0
  38. package/src/components/Sidebar.astro +179 -151
  39. package/src/components/ThemeProvider.tsx +7 -161
  40. package/src/components/UserManagement.tsx +162 -146
  41. package/src/components/UserMenu.tsx +110 -0
  42. package/src/components/WebhookManager.tsx +305 -367
  43. package/src/components/blocks/AccordionBlock.tsx +4 -4
  44. package/src/components/blocks/ArrayBlock.tsx +3 -3
  45. package/src/components/blocks/BlockEditModal.tsx +8 -8
  46. package/src/components/blocks/BlockWrapper.tsx +61 -0
  47. package/src/components/blocks/ButtonBlock.tsx +4 -4
  48. package/src/components/blocks/ChildBlocksTree.tsx +23 -25
  49. package/src/components/blocks/CodeBlock.tsx +15 -15
  50. package/src/components/blocks/ColumnsBlock.tsx +6 -44
  51. package/src/components/blocks/DividerBlock.tsx +3 -3
  52. package/src/components/blocks/FileBlock.tsx +4 -4
  53. package/src/components/blocks/HeadingBlock.tsx +6 -38
  54. package/src/components/blocks/HeroBlock.tsx +4 -4
  55. package/src/components/blocks/ImageBlock.tsx +4 -4
  56. package/src/components/blocks/LinkBlock.tsx +4 -4
  57. package/src/components/blocks/ListBlock.tsx +3 -3
  58. package/src/components/blocks/ParagraphBlock.tsx +12 -42
  59. package/src/components/blocks/RelationshipBlock.tsx +4 -4
  60. package/src/components/blocks/RichTextBlock.tsx +4 -4
  61. package/src/components/blocks/VStackBlock.tsx +5 -37
  62. package/src/components/blocks/VideoBlock.tsx +4 -4
  63. package/src/components/blocks/types.ts +11 -0
  64. package/src/components/fields/AccordionField.tsx +1 -1
  65. package/src/components/fields/ArrayField.tsx +2 -2
  66. package/src/components/fields/ArrayLayout.tsx +93 -0
  67. package/src/components/fields/BlocksField.tsx +122 -111
  68. package/src/components/fields/ButtonField.tsx +1 -1
  69. package/src/components/fields/CheckboxField.tsx +14 -15
  70. package/src/components/fields/ChildrenField.tsx +2 -2
  71. package/src/components/fields/CodeField.tsx +3 -3
  72. package/src/components/fields/ColumnsField.tsx +2 -2
  73. package/src/components/fields/DateField.tsx +13 -26
  74. package/src/components/fields/EditorClient.tsx +26 -28
  75. package/src/components/fields/FieldLayout.tsx +52 -0
  76. package/src/components/fields/GroupLayout.tsx +35 -0
  77. package/src/components/fields/JSONField.tsx +7 -7
  78. package/src/components/fields/LinkField.tsx +1 -1
  79. package/src/components/fields/MarkdownField.tsx +1 -1
  80. package/src/components/fields/NumberField.tsx +13 -26
  81. package/src/components/fields/PortableTextField.tsx +4 -4
  82. package/src/components/fields/PortableTextRenderer.tsx +1 -1
  83. package/src/components/fields/RelationshipBlockField.tsx +31 -23
  84. package/src/components/fields/RelationshipField.tsx +14 -14
  85. package/src/components/fields/SelectField.tsx +17 -26
  86. package/src/components/fields/TabsLayout.tsx +69 -0
  87. package/src/components/fields/TextField.tsx +85 -38
  88. package/src/components/fields/UploadField.tsx +71 -41
  89. package/src/components/fields/VideoField.tsx +1 -1
  90. package/src/components/fields/extensions/blockComponents.tsx +2 -2
  91. package/src/components/fields/extensions/blocksStore.ts +207 -193
  92. package/src/components/fields/types.ts +22 -0
  93. package/src/components/layout/Layout.tsx +1 -1
  94. package/src/components/ui/ActionMenu.tsx +63 -0
  95. package/src/components/ui/Badge.tsx +59 -5
  96. package/src/components/ui/BlockDrawer.tsx +4 -5
  97. package/src/components/ui/CommandPalette.tsx +58 -36
  98. package/src/components/ui/CommandPaletteWrapper.tsx +18 -17
  99. package/src/components/ui/Dropdown.tsx +18 -16
  100. package/src/components/ui/EmptyState.tsx +25 -0
  101. package/src/components/ui/GlobalModal.tsx +49 -0
  102. package/src/components/ui/IconButton.tsx +44 -0
  103. package/src/components/ui/Modal.tsx +19 -20
  104. package/src/components/ui/PageHeader.tsx +158 -0
  105. package/src/components/ui/Pagination.tsx +61 -0
  106. package/src/components/ui/PromptModal.tsx +1 -1
  107. package/src/components/ui/SearchInput.tsx +57 -0
  108. package/src/components/ui/SeoPreview.tsx +31 -0
  109. package/src/components/ui/SessionModal.tsx +0 -0
  110. package/src/components/ui/SlidePanel.tsx +2 -0
  111. package/src/components/ui/Toast.tsx +65 -122
  112. package/src/components/ui/Toaster.tsx +18 -0
  113. package/src/components/ui/icons.tsx +112 -0
  114. package/src/components/users/UserDetail.tsx +290 -0
  115. package/src/components/users/UserForm.tsx +242 -0
  116. package/src/components/users/UsersList.tsx +338 -0
  117. package/src/env.d.ts +13 -13
  118. package/src/fields/index.ts +2 -1
  119. package/src/global.d.ts +7 -0
  120. package/src/hooks/data.ts +2 -9
  121. package/src/hooks/useAsyncData.ts +36 -0
  122. package/src/hooks/useAutoFormState.ts +527 -0
  123. package/src/hooks/useSelection.ts +49 -0
  124. package/src/hooks/useSession.ts +0 -0
  125. package/src/index.ts +11 -1
  126. package/src/integration.ts +86 -11
  127. package/src/kyro-cms.d.ts +209 -0
  128. package/src/layouts/AdminLayout.astro +128 -11
  129. package/src/layouts/AuthLayout.astro +21 -5
  130. package/src/lib/api.ts +175 -55
  131. package/src/lib/autoform-store.ts +435 -0
  132. package/src/lib/config.ts +82 -34
  133. package/src/lib/createRegistry.ts +29 -0
  134. package/src/lib/default-kyro-config.ts +4 -0
  135. package/src/lib/globals.ts +50 -0
  136. package/src/lib/media-utils.ts +18 -0
  137. package/src/lib/object-utils.ts +77 -0
  138. package/src/lib/paths.ts +61 -0
  139. package/src/lib/stores/index.ts +370 -0
  140. package/src/lib/types.ts +43 -0
  141. package/src/lib/useResourceManager.ts +105 -0
  142. package/src/pages/403.astro +67 -0
  143. package/src/pages/[collection]/[id].astro +14 -180
  144. package/src/pages/[collection]/index.astro +11 -6
  145. package/src/pages/api-explorer.astro +173 -0
  146. package/src/pages/audit/index.astro +2 -0
  147. package/src/pages/auth/login.astro +122 -0
  148. package/src/pages/auth/register.astro +167 -0
  149. package/src/pages/graphql-explorer.astro +59 -0
  150. package/src/pages/{admin/graphql.astro → graphql.astro} +51 -17
  151. package/src/pages/index.astro +577 -0
  152. package/src/pages/index_ALT.astro +3 -0
  153. package/src/pages/keys.astro +11 -0
  154. package/src/pages/marketplace.astro +11 -0
  155. package/src/pages/media.astro +3 -0
  156. package/src/pages/plugins.astro +8 -0
  157. package/src/pages/preview/[collection]/[id].astro +188 -123
  158. package/src/pages/rest-playground.astro +62 -0
  159. package/src/pages/roles/index.astro +183 -76
  160. package/src/pages/sessions.astro +8 -0
  161. package/src/pages/settings/[slug].astro +92 -114
  162. package/src/pages/settings/index.astro +5 -3
  163. package/src/pages/users/[id].astro +25 -154
  164. package/src/pages/users/index.astro +19 -130
  165. package/src/pages/users/new.astro +9 -86
  166. package/src/pages/webhooks.astro +11 -0
  167. package/src/routes.ts +80 -0
  168. package/src/styles/main.css +119 -79
  169. package/src/theme/tokens.ts +1 -0
  170. package/src/vite-env.d.ts +14 -0
  171. package/src/collections/auth/index.ts +0 -155
  172. package/src/collections/portfolio/index.ts +0 -343
  173. package/src/components/ApiExplorer.tsx +0 -325
  174. package/src/components/EnhancedListView.tsx +0 -889
  175. package/src/components/GraphQLExplorer.tsx +0 -675
  176. package/src/components/Icons.tsx +0 -23
  177. package/src/components/StatusBadge.tsx +0 -76
  178. package/src/lib/MediaService.ts +0 -541
  179. package/src/lib/auth/sqlite-adapter.ts +0 -319
  180. package/src/lib/dataStore.ts +0 -226
  181. package/src/lib/db/adapter.ts +0 -54
  182. package/src/lib/db/drizzle-mysql-adapter.ts +0 -194
  183. package/src/lib/db/drizzle-mysql-auth-adapter.ts +0 -327
  184. package/src/lib/db/drizzle-postgres-adapter.ts +0 -202
  185. package/src/lib/db/drizzle-postgres-auth-adapter.ts +0 -304
  186. package/src/lib/db/drizzle-sqlite-adapter.ts +0 -227
  187. package/src/lib/db/drizzle-sqlite-auth-adapter.ts +0 -548
  188. package/src/lib/db/index.ts +0 -449
  189. package/src/lib/db/mongodb-adapter.ts +0 -207
  190. package/src/lib/db/mongodb-auth-adapter.ts +0 -305
  191. package/src/lib/db/schema/mysql-auth.ts +0 -113
  192. package/src/lib/db/schema/mysql-content.ts +0 -20
  193. package/src/lib/db/schema/postgres-auth.ts +0 -116
  194. package/src/lib/db/schema/postgres-content.ts +0 -35
  195. package/src/lib/db/schema/postgres-media.ts +0 -52
  196. package/src/lib/db/schema/postgres-settings.ts +0 -11
  197. package/src/lib/db/schema/sqlite-auth.ts +0 -112
  198. package/src/lib/db/schema/sqlite-content.ts +0 -20
  199. package/src/lib/db/version-adapter.ts +0 -248
  200. package/src/lib/graphql/index.ts +0 -1
  201. package/src/lib/graphql/schema.ts +0 -443
  202. package/src/lib/rate-limit.ts +0 -267
  203. package/src/lib/storage.ts +0 -374
  204. package/src/lib/store.ts +0 -85
  205. package/src/middleware.ts +0 -177
  206. package/src/pages/admin/api-explorer.astro +0 -98
  207. package/src/pages/admin/graphql-explorer.astro +0 -40
  208. package/src/pages/admin/index.astro +0 -286
  209. package/src/pages/admin/keys.astro +0 -8
  210. package/src/pages/admin/rest-playground.astro +0 -44
  211. package/src/pages/admin/webhooks.astro +0 -8
  212. package/src/pages/api/[collection]/[id]/publish.ts +0 -52
  213. package/src/pages/api/[collection]/[id]/unpublish.ts +0 -42
  214. package/src/pages/api/[collection]/[id]/versions.ts +0 -66
  215. package/src/pages/api/[collection]/[id].ts +0 -213
  216. package/src/pages/api/[collection]/index.ts +0 -209
  217. package/src/pages/api/auth/[id].ts +0 -121
  218. package/src/pages/api/auth/audit-logs.ts +0 -57
  219. package/src/pages/api/auth/login.ts +0 -211
  220. package/src/pages/api/auth/logout.ts +0 -66
  221. package/src/pages/api/auth/me.ts +0 -36
  222. package/src/pages/api/auth/refresh.ts +0 -119
  223. package/src/pages/api/auth/register.ts +0 -188
  224. package/src/pages/api/auth/users.ts +0 -97
  225. package/src/pages/api/collections.ts +0 -59
  226. package/src/pages/api/globals/[slug].ts +0 -42
  227. package/src/pages/api/graphql.ts +0 -90
  228. package/src/pages/api/health.ts +0 -426
  229. package/src/pages/api/keys/[id].ts +0 -26
  230. package/src/pages/api/keys/index.ts +0 -75
  231. package/src/pages/api/media/[id].ts +0 -309
  232. package/src/pages/api/media/folders.ts +0 -609
  233. package/src/pages/api/media/index.ts +0 -146
  234. package/src/pages/api/media/resize.ts +0 -267
  235. package/src/pages/api/search.ts +0 -82
  236. package/src/pages/api/slug-availability.ts +0 -70
  237. package/src/pages/api/storage-config.ts +0 -20
  238. package/src/pages/api/storage-status.ts +0 -206
  239. package/src/pages/api/upload.ts +0 -334
  240. package/src/pages/api/webhooks/index.ts +0 -71
  241. package/src/pages/login.astro +0 -82
  242. package/src/pages/register.astro +0 -102
@@ -3,10 +3,10 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X } from "lucide-react";
6
+ import { ChevronRight, X } from "../ui/icons";
7
7
  import { AccordionField } from "../fields/AccordionField";
8
8
 
9
- export const AccordionBlock: React.FC<{ block: any; index: number }> = ({
9
+ export const AccordionBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
10
10
  block,
11
11
  index,
12
12
  }) => {
@@ -16,7 +16,7 @@ export const AccordionBlock: React.FC<{ block: any; index: number }> = ({
16
16
  const data = blockData?.data ?? block.data ?? {};
17
17
  const items = Array.isArray(data.items) ? data.items : [];
18
18
 
19
- const handleChange = (items: any[]) => {
19
+ const handleChange = (items: Record<string, unknown>[]) => {
20
20
  updateBlock(block.id, { data: { ...data, items } });
21
21
  };
22
22
 
@@ -24,7 +24,7 @@ export const AccordionBlock: React.FC<{ block: any; index: number }> = ({
24
24
  <div className="block-accordion border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
25
25
  <div className="flex items-center justify-between mb-2">
26
26
  <div className="flex items-center gap-2">
27
- <span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
27
+ <span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
28
28
  Accordion
29
29
  </span>
30
30
  <span className="text-[10px] text-[var(--kyro-text-muted)]">
@@ -3,11 +3,11 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X } from "lucide-react";
6
+ import { ChevronRight, X } from "../ui/icons";
7
7
  import { ArrayField } from "../fields/ArrayField";
8
8
  import { ChildBlocksTree } from "./ChildBlocksTree";
9
9
 
10
- export const ArrayBlock: React.FC<{ block: any; index: number }> = ({
10
+ export const ArrayBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
11
11
  block,
12
12
  index,
13
13
  }) => {
@@ -22,7 +22,7 @@ export const ArrayBlock: React.FC<{ block: any; index: number }> = ({
22
22
  <div className="block-array border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
23
23
  <div className="flex items-center justify-between mb-2">
24
24
  <div className="flex items-center gap-2">
25
- <span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
25
+ <span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
26
26
  Repeater
27
27
  </span>
28
28
  <span className="text-[10px] text-[var(--kyro-text-muted)]">
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { ChevronRight } from "lucide-react";
2
+ import { ChevronRight } from "../ui/icons";
3
3
  import {
4
4
  useBlockById,
5
5
  useBlockActions,
@@ -24,7 +24,7 @@ import {
24
24
  } from "../fields";
25
25
 
26
26
  interface BlockEditModalProps {
27
- block: any;
27
+ block: Record<string, unknown>;
28
28
  onClose: () => void;
29
29
  }
30
30
 
@@ -40,17 +40,17 @@ export const BlockEditModal: React.FC<BlockEditModalProps> = ({
40
40
  const data = blockData?.data || block.data || {};
41
41
  const children = blockData?.children || block.children || [];
42
42
 
43
- const handleChange = (field: string, value: any) => {
43
+ const handleChange = (field: string, value: unknown) => {
44
44
  updateBlock(block.id, { data: { ...data, [field]: value } });
45
45
  };
46
46
 
47
- const handleUpdateChildren = (newChildren: any[]) => {
47
+ const handleUpdateChildren = (newChildren: Record<string, unknown>[]) => {
48
48
  updateBlock(block.id, { children: newChildren });
49
49
  };
50
50
 
51
51
  const handleUpdateColumnChildren = (
52
52
  columnIndex: number,
53
- newChildren: any[],
53
+ newChildren: Record<string, unknown>[],
54
54
  ) => {
55
55
  const columnData = data.columnData || [];
56
56
  const newColumnData = [...columnData];
@@ -90,7 +90,7 @@ export const BlockEditModal: React.FC<BlockEditModalProps> = ({
90
90
  <PortableTextField
91
91
  field={{ name: "richtext", label: "Content" }}
92
92
  value={data.content}
93
- onChange={(value: any) => handleChange("content", value)}
93
+ onChange={(value: unknown) => handleChange("content", value)}
94
94
  />
95
95
  </div>
96
96
  );
@@ -184,14 +184,14 @@ export const BlockEditModal: React.FC<BlockEditModalProps> = ({
184
184
 
185
185
  <div className="grid grid-cols-2 gap-3">
186
186
  <div>
187
- <label className="text-[10px] font-bold uppercase tracking-widest text-[var(--kyro-text-muted)] mb-1.5 block">
187
+ <label className="text-[10px] font-bold tracking-widest text-[var(--kyro-text-muted)] mb-1.5 block">
188
188
  Language
189
189
  </label>
190
190
  <div className="relative">
191
191
  <select
192
192
  value={data.language || "javascript"}
193
193
  onChange={(e) => handleChange("language", e.target.value)}
194
- className="w-full pl-3 pr-10 py-2.5 bg-[var(--kyro-bg-secondary)] border border-[var(--kyro-border)] rounded-xl text-xs font-bold text-[var(--kyro-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--kyro-primary)]/20 transition-all appearance-none cursor-pointer"
194
+ className="w-full pl-3 pr-10 py-2.5 bg-[var(--kyro-bg-secondary)] border border-[var(--kyro-border)] rounded-xl text-xs font-medium text-[var(--kyro-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--kyro-primary)]/20 transition-all appearance-none cursor-pointer"
195
195
  >
196
196
  <option value="plaintext">Plain Text</option>
197
197
  <option value="javascript">JS</option>
@@ -0,0 +1,61 @@
1
+ import React from "react";
2
+ import { ChevronRight, X } from "../ui/icons";
3
+ import { useBlockActions } from "../fields/extensions/blocksStore";
4
+
5
+ interface BlockWrapperProps {
6
+ id: string;
7
+ type: string;
8
+ label?: string;
9
+ children: React.ReactNode;
10
+ className?: string;
11
+ }
12
+
13
+ export const BlockWrapper: React.FC<BlockWrapperProps> = ({
14
+ id,
15
+ type,
16
+ label,
17
+ children,
18
+ className = "",
19
+ }) => {
20
+ const { moveBlock, removeBlock } = useBlockActions();
21
+
22
+ return (
23
+ <div className={`block-${type} border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group bg-[var(--kyro-surface)] transition-all hover:border-[var(--kyro-primary)]/30 ${className}`}>
24
+ <div className="flex items-center justify-between mb-2">
25
+ <span className="text-[10px] font-bold text-[var(--kyro-text-muted)] tracking-wider">
26
+ {label || type}
27
+ </span>
28
+ <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
29
+ <button
30
+ type="button"
31
+ onClick={() => moveBlock(id, "up")}
32
+ className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded text-[var(--kyro-text-muted)] hover:text-[var(--kyro-primary)]"
33
+ title="Move up"
34
+ >
35
+ <ChevronRight className="w-3 h-3 rotate-90" />
36
+ </button>
37
+ <button
38
+ type="button"
39
+ onClick={() => moveBlock(id, "down")}
40
+ className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded text-[var(--kyro-text-muted)] hover:text-[var(--kyro-primary)]"
41
+ title="Move down"
42
+ >
43
+ <ChevronRight className="w-3 h-3" />
44
+ </button>
45
+ <button
46
+ type="button"
47
+ onClick={() => removeBlock(id)}
48
+ className="p-1 hover:bg-[var(--kyro-error)]/10 rounded text-[var(--kyro-error)]"
49
+ title="Remove"
50
+ >
51
+ <X className="w-3 h-3" />
52
+ </button>
53
+ </div>
54
+ </div>
55
+
56
+ <div className="block-content">
57
+ {children}
58
+ </div>
59
+ </div>
60
+ );
61
+ };
@@ -3,10 +3,10 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X } from "lucide-react";
6
+ import { ChevronRight, X } from "../ui/icons";
7
7
  import { ButtonField } from "../fields/ButtonField";
8
8
 
9
- export const ButtonBlock: React.FC<{ block: any; index: number }> = ({
9
+ export const ButtonBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
10
10
  block,
11
11
  index,
12
12
  }) => {
@@ -15,14 +15,14 @@ export const ButtonBlock: React.FC<{ block: any; index: number }> = ({
15
15
 
16
16
  const data = blockData?.data ?? block.data ?? {};
17
17
 
18
- const handleChange = (field: string, value: any) => {
18
+ const handleChange = (field: string, value: unknown) => {
19
19
  updateBlock(block.id, { data: { ...data, [field]: value } });
20
20
  };
21
21
 
22
22
  return (
23
23
  <div className="block-button border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
24
24
  <div className="flex items-center justify-between mb-2">
25
- <span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
25
+ <span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
26
26
  Button
27
27
  </span>
28
28
  <div className="flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from "react";
2
- import { Plus, X, ChevronRight, ChevronDown } from "lucide-react";
2
+ import { Plus, X, ChevronRight, ChevronDown } from "../ui/icons";
3
3
  import {
4
4
  blockCategories,
5
5
  blockIcons,
@@ -12,8 +12,8 @@ import { BlockEditModal } from "./BlockEditModal";
12
12
 
13
13
  interface ChildBlocksTreeProps {
14
14
  blockId: string;
15
- children: any[];
16
- onUpdateChildren: (children: any[]) => void;
15
+ children: Record<string, unknown>[];
16
+ onUpdateChildren: (children: Record<string, unknown>[]) => void;
17
17
  depth?: number;
18
18
  maxDepth?: number;
19
19
  }
@@ -47,7 +47,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
47
47
  onUpdateChildren(filtered);
48
48
  };
49
49
 
50
- const handleUpdateChildData = (childId: string, newData: any) => {
50
+ const handleUpdateChildData = (childId: string, newData: Record<string, unknown>) => {
51
51
  const updated = children.map((child) => {
52
52
  if (child.id === childId) {
53
53
  return { ...child, data: newData };
@@ -59,7 +59,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
59
59
 
60
60
  const handleUpdateChildChildren = (
61
61
  childId: string,
62
- newGrandchildren: any[],
62
+ newGrandchildren: Record<string, unknown>[],
63
63
  ) => {
64
64
  const updated = children.map((child) => {
65
65
  if (child.id === childId) {
@@ -82,7 +82,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
82
82
  });
83
83
  };
84
84
 
85
- const renderBlock = (child: any) => {
85
+ const renderBlock = (child: Record<string, unknown>) => {
86
86
  const hasChildren = child.children && child.children.length > 0;
87
87
  const isExpanded = expandedIds.has(child.id);
88
88
  const BlockComponent = getBlockComponent(child.type);
@@ -92,11 +92,10 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
92
92
  return (
93
93
  <div key={child.id} className="relative group">
94
94
  <div
95
- className={`flex items-center group/column gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${
96
- isEditing
97
- ? "bg-[var(--kyro-primary)]/10 border-[var(--kyro-primary)]"
98
- : "border-[var(--kyro-border)] hover:border-[var(--kyro-primary)]/50 hover:bg-[var(--kyro-primary)]/5"
99
- } ${canAddChildren ? "cursor-pointer" : ""}`}
95
+ className={`flex items-center group/column gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${isEditing
96
+ ? "bg-[var(--kyro-primary)]/10 border-[var(--kyro-primary)]"
97
+ : "border-[var(--kyro-border)] hover:border-[var(--kyro-primary)]/50 hover:bg-[var(--kyro-primary)]/5"
98
+ } ${canAddChildren ? "cursor-pointer" : ""}`}
100
99
  style={{ marginLeft: depth * indentWidth }}
101
100
  onClick={() => {
102
101
  if (canAddChildren) {
@@ -226,7 +225,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
226
225
  >
227
226
  {blockCategories.map((category) => (
228
227
  <div key={category.title} className="mb-4">
229
- <h3 className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase tracking-wide mb-2">
228
+ <h3 className="text-xs font-semibold text-[var(--kyro-text-muted)] tracking-wide mb-2">
230
229
  {category.title}
231
230
  </h3>
232
231
  <div className="grid grid-cols-3 gap-2">
@@ -244,7 +243,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
244
243
  {blockIcons[block.icon]}
245
244
  </div>
246
245
  <div className="flex-1 min-w-0">
247
- <div className="text-xs font-medium uppercase tracking-tight text-[var(--kyro-text-primary)]">
246
+ <div className="text-xs font-medium tracking-tight text-[var(--kyro-text-primary)]">
248
247
  {block.label}
249
248
  </div>
250
249
  <div className="text-[10px] text-[var(--kyro-text-muted)] mt-0.5">
@@ -283,8 +282,8 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
283
282
 
284
283
  interface NestedChildBlocksProps {
285
284
  parentId: string;
286
- children: any[];
287
- onUpdateChildren: (children: any[]) => void;
285
+ children: Record<string, unknown>[];
286
+ onUpdateChildren: (children: Record<string, unknown>[]) => void;
288
287
  depth: number;
289
288
  maxDepth: number;
290
289
  }
@@ -316,7 +315,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
316
315
  onUpdateChildren(filtered);
317
316
  };
318
317
 
319
- const handleUpdateChildData = (childId: string, newData: any) => {
318
+ const handleUpdateChildData = (childId: string, newData: Record<string, unknown>) => {
320
319
  const updated = children.map((child) => {
321
320
  if (child.id === childId) {
322
321
  return { ...child, data: newData };
@@ -328,7 +327,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
328
327
 
329
328
  const handleUpdateChildChildren = (
330
329
  childId: string,
331
- newGrandchildren: any[],
330
+ newGrandchildren: Record<string, unknown>[],
332
331
  ) => {
333
332
  const updated = children.map((child) => {
334
333
  if (child.id === childId) {
@@ -351,7 +350,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
351
350
  });
352
351
  };
353
352
 
354
- const renderBlock = (child: any) => {
353
+ const renderBlock = (child: Record<string, unknown>) => {
355
354
  const hasChildren = child.children && child.children.length > 0;
356
355
  const isExpanded = expandedIds.has(child.id);
357
356
  const BlockComponent = getBlockComponent(child.type);
@@ -361,11 +360,10 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
361
360
  return (
362
361
  <div key={child.id} className="relative group">
363
362
  <div
364
- className={`flex items-center gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${
365
- isEditing
366
- ? "bg-[var(--kyro-primary)]/10 border-[var(--kyro-primary)]"
367
- : "border-[var(--kyro-border)] hover:border-[var(--kyro-primary)]/50 hover:bg-[var(--kyro-primary)]/5"
368
- } ${canAddChildren ? "cursor-pointer" : ""}`}
363
+ className={`flex items-center gap-2 p-2 bg-[var(--kyro-bg-secondary)] rounded border transition-colors ${isEditing
364
+ ? "bg-[var(--kyro-primary)]/10 border-[var(--kyro-primary)]"
365
+ : "border-[var(--kyro-border)] hover:border-[var(--kyro-primary)]/50 hover:bg-[var(--kyro-primary)]/5"
366
+ } ${canAddChildren ? "cursor-pointer" : ""}`}
369
367
  style={{ marginLeft: depth * indentWidth }}
370
368
  onClick={() => {
371
369
  if (canAddChildren) {
@@ -495,7 +493,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
495
493
  >
496
494
  {blockCategories.map((category) => (
497
495
  <div key={category.title} className="mb-4">
498
- <h3 className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase tracking-wide mb-2">
496
+ <h3 className="text-xs font-semibold text-[var(--kyro-text-muted)] tracking-wide mb-2">
499
497
  {category.title}
500
498
  </h3>
501
499
  <div className="grid grid-cols-3 gap-2">
@@ -513,7 +511,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
513
511
  {blockIcons[block.icon]}
514
512
  </div>
515
513
  <div className="flex-1 min-w-0">
516
- <div className="text-xs font-medium uppercase tracking-tight text-[var(--kyro-text-primary)]">
514
+ <div className="text-xs font-medium tracking-tight text-[var(--kyro-text-primary)]">
517
515
  {block.label}
518
516
  </div>
519
517
  <div className="text-[10px] text-[var(--kyro-text-muted)] mt-0.5">
@@ -3,10 +3,10 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X, Code2 } from "lucide-react";
6
+ import { ChevronRight, X, Code2 } from "../ui/icons";
7
7
  import { CodeField } from "../fields/CodeField";
8
8
 
9
- export const CodeBlock: React.FC<{ block: any; index: number }> = ({
9
+ export const CodeBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
10
10
  block,
11
11
  index,
12
12
  }) => {
@@ -14,7 +14,7 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
14
14
  const { updateBlock, removeBlock, moveBlock } = useBlockActions();
15
15
  const data = blockData?.data ?? block.data ?? {};
16
16
 
17
- const handleChange = (field: string, value: any) => {
17
+ const handleChange = (field: string, value: unknown) => {
18
18
  updateBlock(block.id, { data: { ...data, [field]: value } });
19
19
  };
20
20
 
@@ -27,15 +27,15 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
27
27
  </div>
28
28
  <div>
29
29
  <h4 className="text-sm font-bold tracking-tight text-[var(--kyro-text-primary)]">Code Snippet</h4>
30
- <p className="text-[10px] font-medium text-[var(--kyro-text-muted)] uppercase tracking-widest">
30
+ <p className="text-[10px] font-medium text-[var(--kyro-text-muted)] tracking-widest">
31
31
  Block Editor • {data.language || "javascript"}
32
32
  </p>
33
33
  </div>
34
34
  </div>
35
-
35
+
36
36
  <div className="flex items-center gap-1.5 opacity-0 group-hover/block:opacity-100 transition-all translate-x-2 group-hover/block:translate-x-0">
37
37
  <div className="flex bg-[var(--kyro-surface-accent)]/50 p-1 rounded-xl border border-[var(--kyro-border)]">
38
- <button
38
+ <button
39
39
  type="button"
40
40
  onClick={() => moveBlock(block.id, "up")}
41
41
  className="p-1.5 hover:bg-[var(--kyro-surface)] rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-[var(--kyro-primary)]"
@@ -44,7 +44,7 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
44
44
  <ChevronRight className="w-4 h-4 rotate-[-90deg]" />
45
45
  </button>
46
46
  <div className="w-px h-4 bg-[var(--kyro-border)] mx-1 self-center" />
47
- <button
47
+ <button
48
48
  type="button"
49
49
  onClick={() => removeBlock(block.id)}
50
50
  className="p-1.5 hover:bg-red-500/10 rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-red-500"
@@ -55,7 +55,7 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
55
55
  </div>
56
56
  </div>
57
57
  </div>
58
-
58
+
59
59
  <div className="space-y-6">
60
60
  <CodeField
61
61
  field={{
@@ -67,17 +67,17 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
67
67
  value={data.code || ""}
68
68
  onChange={(val) => handleChange("code", val)}
69
69
  />
70
-
70
+
71
71
  <div className="flex items-center gap-4 bg-[var(--kyro-surface-accent)]/20 p-4 rounded-xl border border-[var(--kyro-border)]/50">
72
72
  <div className="flex-1">
73
- <label className="text-[10px] font-black uppercase tracking-widest text-[var(--kyro-text-muted)] mb-2 block">
73
+ <label className="text-[10px] font-bold tracking-widest text-[var(--kyro-text-muted)] mb-2 block">
74
74
  Syntax Highlighting
75
75
  </label>
76
76
  <div className="relative">
77
77
  <select
78
78
  value={data.language || "javascript"}
79
79
  onChange={(e) => handleChange("language", e.target.value)}
80
- className="w-full pl-4 pr-10 py-2.5 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-xl text-xs font-bold text-[var(--kyro-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--kyro-primary)]/20 focus:border-[var(--kyro-primary)] transition-all appearance-none cursor-pointer"
80
+ className="w-full pl-4 pr-10 py-2.5 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-xl text-xs font-medium text-[var(--kyro-text-primary)] focus:outline-none focus:ring-2 focus:ring-[var(--kyro-primary)]/20 focus:border-[var(--kyro-primary)] transition-all appearance-none cursor-pointer"
81
81
  >
82
82
  <option value="plaintext">Plain Text</option>
83
83
  <option value="javascript">JavaScript</option>
@@ -95,16 +95,16 @@ export const CodeBlock: React.FC<{ block: any; index: number }> = ({
95
95
  </div>
96
96
  </div>
97
97
  </div>
98
-
98
+
99
99
  <div className="hidden sm:block w-px h-10 bg-[var(--kyro-border)]" />
100
-
100
+
101
101
  <div className="hidden sm:flex flex-col justify-center">
102
- <span className="text-[10px] font-black uppercase tracking-widest text-[var(--kyro-text-muted)] mb-2">
102
+ <span className="text-[10px] font-bold tracking-widest text-[var(--kyro-text-muted)] mb-2">
103
103
  Status
104
104
  </span>
105
105
  <div className="flex items-center gap-2 px-3 py-2 bg-[var(--kyro-surface)] border border-[var(--kyro-border)] rounded-xl">
106
106
  <div className="w-2 h-2 rounded-full bg-blue-500 animate-pulse" />
107
- <span className="text-[10px] font-bold text-[var(--kyro-text-primary)] tracking-wide">EDITING</span>
107
+ <span className="text-[10px] font-medium text-[var(--kyro-text-primary)] tracking-wide">EDITING</span>
108
108
  </div>
109
109
  </div>
110
110
  </div>
@@ -3,15 +3,15 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X, Columns3 } from "lucide-react";
7
6
  import { ColumnsField } from "../fields/ColumnsField";
7
+ import { BlockWrapper } from "./BlockWrapper";
8
8
 
9
- export const ColumnsBlock: React.FC<{ block: any; index: number }> = ({
9
+ export const ColumnsBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
10
10
  block,
11
11
  index,
12
12
  }) => {
13
13
  const blockData = useBlockById(block.id);
14
- const { updateBlock, removeBlock, moveBlock } = useBlockActions();
14
+ const { updateBlock } = useBlockActions();
15
15
 
16
16
  const data = blockData?.data ?? block.data ?? {};
17
17
  const columns = data.columns || 2;
@@ -30,7 +30,7 @@ export const ColumnsBlock: React.FC<{ block: any; index: number }> = ({
30
30
 
31
31
  const handleUpdateColumnChildren = (
32
32
  columnIndex: number,
33
- newChildren: any[],
33
+ newChildren: Record<string, unknown>[],
34
34
  ) => {
35
35
  const newColumnData = [...columnData];
36
36
  newColumnData[columnIndex] = {
@@ -43,51 +43,13 @@ export const ColumnsBlock: React.FC<{ block: any; index: number }> = ({
43
43
  };
44
44
 
45
45
  return (
46
- <div className="block-columns border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
47
- <div className="flex items-center justify-between mb-2">
48
- <div className="flex items-center gap-2">
49
- <Columns3 className="w-3.5 h-3.5 text-[var(--kyro-primary)]" />
50
- <span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
51
- Columns
52
- </span>
53
- <span className="text-[10px] text-[var(--kyro-text-muted)]">
54
- ({columns})
55
- </span>
56
- </div>
57
- <div className="flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
58
- <button
59
- type="button"
60
- onClick={() => moveBlock(block.id, "up")}
61
- className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
62
- title="Move up"
63
- >
64
- <ChevronRight className="w-3 h-3 rotate-90" />
65
- </button>
66
- <button
67
- type="button"
68
- onClick={() => moveBlock(block.id, "down")}
69
- className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
70
- title="Move down"
71
- >
72
- <ChevronRight className="w-3 h-3" />
73
- </button>
74
- <button
75
- type="button"
76
- onClick={() => removeBlock(block.id)}
77
- className="p-1 hover:bg-red-50 rounded text-red-500"
78
- title="Remove"
79
- >
80
- <X className="w-3 h-3" />
81
- </button>
82
- </div>
83
- </div>
84
-
46
+ <BlockWrapper id={block.id} type="columns" label="Columns">
85
47
  <ColumnsField
86
48
  columns={columns}
87
49
  columnData={columnData}
88
50
  onColumnsChange={handleColumnsChange}
89
51
  onUpdateColumnChildren={handleUpdateColumnChildren}
90
52
  />
91
- </div>
53
+ </BlockWrapper>
92
54
  );
93
55
  };
@@ -3,16 +3,16 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X } from "lucide-react";
6
+ import { ChevronRight, X } from "../ui/icons";
7
7
 
8
- export const DividerBlock: React.FC<{ block: any; index: number }> = ({
8
+ export const DividerBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
9
9
  block,
10
10
  index,
11
11
  }) => {
12
12
  const blockData = useBlockById(block.id);
13
13
  const { updateBlock, removeBlock, moveBlock } = useBlockActions();
14
14
  const data = blockData?.data ?? block.data ?? {};
15
- const handleChange = (field: string, value: any) => {
15
+ const handleChange = (field: string, value: unknown) => {
16
16
  updateBlock(block.id, { data: { ...data, [field]: value } });
17
17
  };
18
18
 
@@ -3,10 +3,10 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X } from "lucide-react";
6
+ import { ChevronRight, X } from "../ui/icons";
7
7
  import { UploadField } from "../fields/UploadField";
8
8
 
9
- export const FileBlock: React.FC<{ block: any; index: number }> = ({
9
+ export const FileBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
10
10
  block,
11
11
  index,
12
12
  }) => {
@@ -15,14 +15,14 @@ export const FileBlock: React.FC<{ block: any; index: number }> = ({
15
15
 
16
16
  const data = blockData?.data ?? block.data ?? {};
17
17
 
18
- const handleChange = (field: string, value: any) => {
18
+ const handleChange = (field: string, value: unknown) => {
19
19
  updateBlock(block.id, { data: { ...data, [field]: value } });
20
20
  };
21
21
 
22
22
  return (
23
23
  <div className="block-file border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
24
24
  <div className="flex items-center justify-between mb-1">
25
- <span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
25
+ <span className="text-xs font-semibold text-[var(--kyro-text-muted)] ">
26
26
  File
27
27
  </span>
28
28
  <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
@@ -3,57 +3,25 @@ import {
3
3
  useBlockById,
4
4
  useBlockActions,
5
5
  } from "../fields/extensions/blocksStore";
6
- import { ChevronRight, X } from "lucide-react";
7
6
  import { HeadingField } from "../fields/HeadingField";
7
+ import { BlockWrapper } from "./BlockWrapper";
8
8
 
9
- export const HeadingBlock: React.FC<{ block: any; index: number }> = ({
9
+ export const HeadingBlock: React.FC<{ block: Record<string, unknown>; index: number }> = ({
10
10
  block,
11
11
  index,
12
12
  }) => {
13
13
  const blockData = useBlockById(block.id);
14
- const { updateBlock, removeBlock, moveBlock } = useBlockActions();
14
+ const { updateBlock } = useBlockActions();
15
15
 
16
16
  const data = blockData?.data || block.data || {};
17
17
 
18
- const handleChange = (field: string, value: any) => {
18
+ const handleChange = (field: string, value: unknown) => {
19
19
  updateBlock(block.id, { data: { ...data, [field]: value } });
20
20
  };
21
21
 
22
22
  return (
23
- <div className="block-heading border border-[var(--kyro-border)] rounded-md p-3 mb-2 relative group">
24
- <div className="flex items-center justify-between mb-1">
25
- <span className="text-xs font-semibold text-[var(--kyro-text-muted)] uppercase">
26
- Heading
27
- </span>
28
- <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
29
- <button
30
- type="button"
31
- onClick={() => moveBlock(block.id, "up")}
32
- className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
33
- title="Move up"
34
- >
35
- <ChevronRight className="w-3 h-3 rotate-90" />
36
- </button>
37
- <button
38
- type="button"
39
- onClick={() => moveBlock(block.id, "down")}
40
- className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
41
- title="Move down"
42
- >
43
- <ChevronRight className="w-3 h-3" />
44
- </button>
45
- <button
46
- type="button"
47
- onClick={() => removeBlock(block.id)}
48
- className="p-1 hover:bg-[var(--kyro-surface-accent)] rounded"
49
- title="Remove"
50
- >
51
- <X className="w-3 h-3" />
52
- </button>
53
- </div>
54
- </div>
55
-
23
+ <BlockWrapper id={block.id} type="heading" label="Heading">
56
24
  <HeadingField text={data.text || ""} onChange={handleChange} compact />
57
- </div>
25
+ </BlockWrapper>
58
26
  );
59
27
  };