@kyro-cms/admin 0.9.0 → 0.9.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.
Files changed (114) hide show
  1. package/dist/index.cjs +11715 -11292
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +67 -65
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.d.cts +564 -0
  6. package/dist/index.d.ts +11 -10
  7. package/dist/index.js +11326 -10912
  8. package/dist/index.js.map +1 -1
  9. package/package.json +16 -12
  10. package/src/components/ActionBar.tsx +25 -161
  11. package/src/components/Admin.tsx +2 -4
  12. package/src/components/ApiKeysManager.tsx +5 -5
  13. package/src/components/AuditLogsPage.tsx +2 -13
  14. package/src/components/AutoForm.tsx +572 -461
  15. package/src/components/BrandingHub.tsx +7 -4
  16. package/src/components/CreateView.tsx +2 -0
  17. package/src/components/DetailView.tsx +52 -65
  18. package/src/components/DeveloperCenter.tsx +8 -6
  19. package/src/components/FieldRenderer.tsx +94 -19
  20. package/src/components/ListView.tsx +57 -216
  21. package/src/components/MediaGallery.tsx +334 -367
  22. package/src/components/PluginsManager.tsx +197 -70
  23. package/src/components/RestPlayground.tsx +59 -52
  24. package/src/components/SessionsManager.tsx +1 -1
  25. package/src/components/SettingsPage.tsx +22 -0
  26. package/src/components/Sidebar.astro +13 -41
  27. package/src/components/UserManagement.tsx +153 -15
  28. package/src/components/UserMenu.tsx +30 -4
  29. package/src/components/VersionHistoryPanel.tsx +112 -119
  30. package/src/components/WebhookManager.tsx +6 -4
  31. package/src/components/blocks/ArrayBlock.tsx +6 -23
  32. package/src/components/blocks/BlockEditModal.tsx +82 -309
  33. package/src/components/blocks/CardBlock.tsx +35 -0
  34. package/src/components/blocks/ChildBlocksTree.tsx +57 -31
  35. package/src/components/blocks/GenericBlock.tsx +44 -0
  36. package/src/components/blocks/HeadingSubheadingBlock.tsx +32 -0
  37. package/src/components/blocks/HeroBlock.tsx +5 -14
  38. package/src/components/blocks/RichTextBlock.tsx +5 -5
  39. package/src/components/blocks/index.ts +5 -3
  40. package/src/components/fields/AccordionField.tsx +2 -2
  41. package/src/components/fields/ArrayField.tsx +1 -1
  42. package/src/components/fields/ArrayLayout.tsx +120 -29
  43. package/src/components/fields/BlocksField.tsx +433 -55
  44. package/src/components/fields/CardField.tsx +73 -0
  45. package/src/components/fields/CheckboxField.tsx +7 -3
  46. package/src/components/fields/DateField.tsx +4 -1
  47. package/src/components/fields/GroupLayout.tsx +2 -2
  48. package/src/components/fields/HeadingSubheadingField.tsx +43 -0
  49. package/src/components/fields/ListField.tsx +2 -2
  50. package/src/components/fields/NumberField.tsx +4 -1
  51. package/src/components/fields/RelationshipBlockField.tsx +2 -3
  52. package/src/components/fields/RelationshipField.tsx +155 -90
  53. package/src/components/fields/RichTextField.tsx +781 -0
  54. package/src/components/fields/SecretField.tsx +102 -0
  55. package/src/components/fields/SelectField.tsx +19 -6
  56. package/src/components/fields/TabsLayout.tsx +19 -9
  57. package/src/components/fields/TextField.tsx +4 -1
  58. package/src/components/fields/UploadField.tsx +122 -56
  59. package/src/components/fields/extensions/blockComponents.tsx +103 -174
  60. package/src/components/fields/extensions/blocksStore.ts +8 -1
  61. package/src/components/fields/index.ts +4 -2
  62. package/src/components/fix_imports.cjs +23 -0
  63. package/src/components/fix_imports2.cjs +19 -0
  64. package/src/components/replace_svgs.cjs +63 -0
  65. package/src/components/ui/Dropdown.tsx +7 -2
  66. package/src/components/ui/Modal.tsx +24 -27
  67. package/src/components/ui/PageHeader.tsx +5 -5
  68. package/src/components/ui/PromptModal.tsx +2 -10
  69. package/src/components/ui/SlidePanel.tsx +10 -13
  70. package/src/components/ui/SplitButton.tsx +107 -0
  71. package/src/components/ui/Toaster.tsx +0 -1
  72. package/src/components/ui/icons.tsx +110 -109
  73. package/src/components/users/UserDetail.tsx +79 -16
  74. package/src/components/users/UsersList.tsx +8 -85
  75. package/src/hooks/useAutoFormState.ts +187 -196
  76. package/src/hooks/useQueue.ts +60 -0
  77. package/src/integration.ts +148 -46
  78. package/src/kyro-cms.d.ts +7 -2
  79. package/src/layouts/AdminLayout.astro +22 -2
  80. package/src/layouts/AuthLayout.astro +67 -7
  81. package/src/lib/autoform-store.ts +90 -53
  82. package/src/lib/change-source.ts +9 -0
  83. package/src/lib/config.ts +104 -8
  84. package/src/lib/globals.ts +48 -11
  85. package/src/lib/normalize-upload-fields.ts +41 -0
  86. package/src/lib/paths.ts +2 -2
  87. package/src/lib/resolve-field-value.ts +110 -0
  88. package/src/lib/shim/use-sync-external-store-with-selector.js +30 -0
  89. package/src/lib/shim/use-sync-external-store.js +1 -0
  90. package/src/lib/stores/index.ts +1 -0
  91. package/src/lib/useResourceManager.ts +4 -4
  92. package/src/lib/vite-shim-plugin.ts +100 -0
  93. package/src/pages/[collection]/[id].astro +1 -1
  94. package/src/pages/auth/register.astro +5 -2
  95. package/src/pages/preview/[collection]/[id].astro +4 -4
  96. package/src/pages/settings/[slug].astro +2 -2
  97. package/src/styles/main.css +60 -54
  98. package/README.md +0 -46
  99. package/dist/EditorClient-Q23UXR37.cjs +0 -468
  100. package/dist/EditorClient-Q23UXR37.cjs.map +0 -1
  101. package/dist/EditorClient-T5PASFNR.js +0 -466
  102. package/dist/EditorClient-T5PASFNR.js.map +0 -1
  103. package/dist/chunk-3BGDYKTD.cjs +0 -348
  104. package/dist/chunk-3BGDYKTD.cjs.map +0 -1
  105. package/dist/chunk-EEFXLQVT.js +0 -3
  106. package/dist/chunk-EEFXLQVT.js.map +0 -1
  107. package/src/components/blocks/ButtonBlock.tsx +0 -64
  108. package/src/components/blocks/ColumnsBlock.tsx +0 -55
  109. package/src/components/blocks/DividerBlock.tsx +0 -43
  110. package/src/components/blocks/LinkBlock.tsx +0 -65
  111. package/src/components/blocks/VStackBlock.tsx +0 -29
  112. package/src/components/fields/EditorClient.tsx +0 -535
  113. package/src/components/fields/PortableTextField.tsx +0 -155
  114. package/src/components/fields/PortableTextRenderer.tsx +0 -68
@@ -1,466 +0,0 @@
1
- import { LuUndo, LuRedo, LuLink, LuX, LuExternalLink, LuChevronDown, LuList, LuListOrdered, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuCode } from './chunk-EEFXLQVT.js';
2
- import { useState, useRef, useEffect, useCallback } from 'react';
3
- import { EditorProvider, PortableTextEditable, useEditor } from '@portabletext/editor';
4
- import { defineSchema } from '@portabletext/schema';
5
- import { EventListenerPlugin } from '@portabletext/editor/plugins';
6
- import { useHistoryButtons, useToolbarSchema, useDecoratorButton, useListButton, useAnnotationButton, useAnnotationPopover, useStyleSelector } from '@portabletext/toolbar';
7
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
-
9
- function sanitizeInitialValue(value) {
10
- if (!value || !Array.isArray(value))
11
- return [];
12
- return value.filter((block) => {
13
- if (!block || typeof block !== "object")
14
- return false;
15
- if (!("_type" in block))
16
- return false;
17
- if (block._type === "block" && Array.isArray(block.children)) {
18
- block.children = block.children.map((child) => ({
19
- ...child,
20
- _type: child._type || "span",
21
- text: typeof child.text === "string" ? child.text : ""
22
- }));
23
- }
24
- return true;
25
- });
26
- }
27
- var schemaDefinition = defineSchema({
28
- decorators: [
29
- { name: "strong", title: "Bold" },
30
- { name: "em", title: "Italic" },
31
- { name: "underline", title: "Underline" },
32
- { name: "strikeThrough", title: "Strikethrough" },
33
- { name: "code", title: "Code" }
34
- ],
35
- styles: [
36
- { name: "normal", title: "Normal" },
37
- { name: "h1", title: "H1" },
38
- { name: "h2", title: "H2" },
39
- { name: "h3", title: "H3" },
40
- { name: "blockquote", title: "Quote" }
41
- ],
42
- lists: [
43
- { name: "bullet", title: "Bullet" },
44
- { name: "number", title: "Number" }
45
- ],
46
- annotations: [
47
- {
48
- name: "link",
49
- title: "Link",
50
- fields: [{ name: "href", type: "string", title: "URL" }]
51
- }
52
- ],
53
- inlineObjects: [],
54
- blockObjects: []
55
- });
56
- var renderStyle = (props) => {
57
- if (props.schemaType.value === "h1") {
58
- return /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold mb-2", children: props.children });
59
- }
60
- if (props.schemaType.value === "h2") {
61
- return /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold mb-2", children: props.children });
62
- }
63
- if (props.schemaType.value === "h3") {
64
- return /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-1", children: props.children });
65
- }
66
- if (props.schemaType.value === "blockquote") {
67
- return /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-[var(--kyro-primary)] pl-4 italic text-[var(--kyro-text-muted)] my-2", children: props.children });
68
- }
69
- return /* @__PURE__ */ jsx(Fragment, { children: props.children });
70
- };
71
- var renderDecorator = (props) => {
72
- if (props.value === "strong") {
73
- return /* @__PURE__ */ jsx("strong", { children: props.children });
74
- }
75
- if (props.value === "em") {
76
- return /* @__PURE__ */ jsx("em", { children: props.children });
77
- }
78
- if (props.value === "underline") {
79
- return /* @__PURE__ */ jsx("u", { children: props.children });
80
- }
81
- if (props.value === "strikeThrough") {
82
- return /* @__PURE__ */ jsx("s", { children: props.children });
83
- }
84
- if (props.value === "code") {
85
- return /* @__PURE__ */ jsx("code", { className: "px-1 py-0.5 rounded bg-[var(--kyro-surface-accent)] text-[var(--kyro-primary)] text-sm font-mono", children: props.children });
86
- }
87
- return /* @__PURE__ */ jsx(Fragment, { children: props.children });
88
- };
89
- var renderBlock = (props) => {
90
- return /* @__PURE__ */ jsx("div", { children: props.children });
91
- };
92
- var renderListItem = (props) => {
93
- if (props.schemaType.value === "bullet") {
94
- return /* @__PURE__ */ jsx("li", { className: "list-disc ml-4", children: props.children });
95
- }
96
- if (props.schemaType.value === "number") {
97
- return /* @__PURE__ */ jsx("li", { className: "list-decimal ml-4", children: props.children });
98
- }
99
- return /* @__PURE__ */ jsx("li", { children: props.children });
100
- };
101
- var renderAnnotation = (props) => {
102
- if (props.schemaType.name === "link") {
103
- return /* @__PURE__ */ jsx(
104
- "a",
105
- {
106
- href: props.value.href,
107
- className: "text-[var(--kyro-primary)] underline hover:opacity-80",
108
- target: "_blank",
109
- rel: "noopener noreferrer",
110
- children: props.children
111
- }
112
- );
113
- }
114
- return /* @__PURE__ */ jsx(Fragment, { children: props.children });
115
- };
116
- function FocusRestoringButton({
117
- onClick,
118
- children,
119
- ...props
120
- }) {
121
- const editor = useEditor();
122
- return /* @__PURE__ */ jsx(
123
- "button",
124
- {
125
- type: "button",
126
- onClick: (e) => {
127
- onClick?.(e);
128
- editor.send({ type: "focus" });
129
- },
130
- ...props,
131
- children
132
- }
133
- );
134
- }
135
- var decoratorIcons = {
136
- strong: LuBold,
137
- em: LuItalic,
138
- underline: LuUnderline,
139
- strikeThrough: LuStrikethrough,
140
- code: LuCode
141
- };
142
- var DecoratorButton = ({
143
- name,
144
- title
145
- }) => {
146
- const schema = useToolbarSchema({});
147
- const decoratorSchema = schema.decorators?.find((d) => d.name === name);
148
- if (!decoratorSchema)
149
- return null;
150
- const { snapshot, send } = useDecoratorButton({
151
- schemaType: decoratorSchema
152
- });
153
- const Icon = decoratorIcons[name];
154
- const isActive = snapshot.matches({ enabled: "active" }) || snapshot.matches({ disabled: "active" });
155
- const isEnabled = snapshot.matches("enabled");
156
- return /* @__PURE__ */ jsx(
157
- FocusRestoringButton,
158
- {
159
- disabled: !isEnabled,
160
- "data-state": isActive ? "on" : "off",
161
- onClick: () => send({ type: "toggle" }),
162
- title,
163
- className: "p-1.5 rounded transition-colors disabled:opacity-30 hover:bg-[var(--kyro-surface-accent)] data-[state=on]:bg-[var(--kyro-primary)] data-[state=on]:text-[var(--kyro-sidebar-text-active)]",
164
- children: Icon && /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4" })
165
- }
166
- );
167
- };
168
- var ListButton = ({
169
- name,
170
- title
171
- }) => {
172
- const schema = useToolbarSchema({});
173
- const listSchema = schema.lists?.find((l) => l.name === name);
174
- if (!listSchema)
175
- return null;
176
- const { snapshot, send } = useListButton({ schemaType: listSchema });
177
- const Icon = name === "bullet" ? LuList : LuListOrdered;
178
- const isActive = snapshot.matches({ enabled: "active" }) || snapshot.matches({ disabled: "active" });
179
- const isEnabled = snapshot.matches("enabled");
180
- return /* @__PURE__ */ jsx(
181
- FocusRestoringButton,
182
- {
183
- disabled: !isEnabled,
184
- "data-state": isActive ? "on" : "off",
185
- onClick: () => send({ type: "toggle" }),
186
- title,
187
- className: "p-1.5 rounded transition-colors disabled:opacity-30 hover:bg-[var(--kyro-surface-accent)] data-[state=on]:bg-[var(--kyro-primary)] data-[state=on]:text-[var(--kyro-sidebar-text-active)]",
188
- children: Icon && /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4" })
189
- }
190
- );
191
- };
192
- var AnnotationButton = ({
193
- name,
194
- title
195
- }) => {
196
- const schema = useToolbarSchema({});
197
- const annotationSchema = schema.annotations?.find((a) => a.name === name);
198
- if (!annotationSchema)
199
- return null;
200
- const { snapshot, send } = useAnnotationButton({
201
- schemaType: annotationSchema
202
- });
203
- const isActive = snapshot.matches({ enabled: "active" }) || snapshot.matches({ disabled: "active" });
204
- const isEnabled = snapshot.matches("enabled");
205
- const isShowingDialog = snapshot.matches({
206
- enabled: { inactive: "showing dialog" }
207
- });
208
- return /* @__PURE__ */ jsx(
209
- FocusRestoringButton,
210
- {
211
- disabled: !isEnabled,
212
- "data-state": isActive ? "on" : "off",
213
- onClick: () => send({
214
- type: isShowingDialog ? "close dialog" : "open dialog"
215
- }),
216
- title,
217
- className: "p-1.5 rounded transition-colors disabled:opacity-30 hover:bg-[var(--kyro-surface-accent)] data-[state=on]:bg-[var(--kyro-primary)] data-[state=on]:text-[var(--kyro-sidebar-text-active)]",
218
- children: name === "link" && /* @__PURE__ */ jsx(LuLink, { className: "w-4 h-4" })
219
- }
220
- );
221
- };
222
- var LinkDialog = () => {
223
- const schema = useToolbarSchema({});
224
- const popover = useAnnotationPopover({
225
- schemaTypes: schema.annotations || []
226
- });
227
- const dialogRef = useRef(null);
228
- const inputRef = useRef(null);
229
- useEffect(() => {
230
- if (popover.snapshot.matches({ enabled: "active" }) && inputRef.current) {
231
- inputRef.current.focus();
232
- }
233
- }, [popover.snapshot]);
234
- if (!popover.snapshot.matches({ enabled: "active" }))
235
- return null;
236
- const activeAnnotations = popover.snapshot.context.annotations || [];
237
- const activeLink = activeAnnotations.find(
238
- (a) => a.schemaType.name === "link"
239
- );
240
- const currentHref = activeLink?.value?.href;
241
- const handleSubmit = (e) => {
242
- e.preventDefault();
243
- const formData = new FormData(e.target);
244
- const href = formData.get("href");
245
- if (activeLink) {
246
- if (href.trim()) {
247
- popover.send({
248
- type: "edit",
249
- at: activeLink.at,
250
- props: { href: href.trim() }
251
- });
252
- } else {
253
- popover.send({
254
- type: "remove",
255
- schemaType: activeLink.schemaType
256
- });
257
- }
258
- } else {
259
- if (href.trim()) {
260
- popover.send({
261
- type: "edit",
262
- at: [],
263
- props: { href: href.trim() }
264
- });
265
- }
266
- }
267
- popover.send({ type: "close" });
268
- };
269
- const handleRemove = () => {
270
- if (activeLink) {
271
- popover.send({
272
- type: "remove",
273
- schemaType: activeLink.schemaType
274
- });
275
- }
276
- popover.send({ type: "close" });
277
- };
278
- return /* @__PURE__ */ jsxs(
279
- "div",
280
- {
281
- ref: dialogRef,
282
- className: "absolute top-full left-0 z-50 mt-1 w-72 p-3 rounded-lg border border-[var(--kyro-border)] bg-[var(--kyro-bg-primary)] shadow-lg",
283
- children: [
284
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
285
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--kyro-text-primary)]", children: "Link" }),
286
- /* @__PURE__ */ jsx(
287
- "button",
288
- {
289
- type: "button",
290
- onClick: () => popover.send({ type: "close" }),
291
- className: "p-1 rounded hover:bg-[var(--kyro-surface-accent)]",
292
- children: /* @__PURE__ */ jsx(LuX, { className: "w-3.5 h-3.5 text-[var(--kyro-text-muted)]" })
293
- }
294
- )
295
- ] }),
296
- /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-2", children: [
297
- /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
298
- /* @__PURE__ */ jsx(
299
- "input",
300
- {
301
- ref: inputRef,
302
- name: "href",
303
- type: "url",
304
- defaultValue: currentHref || "https://",
305
- placeholder: "Enter URL...",
306
- className: "flex-1 px-2.5 py-1.5 text-sm rounded border border-[var(--kyro-border)] bg-transparent text-[var(--kyro-text-primary)] placeholder:text-[var(--kyro-text-muted)] focus:outline-none focus:ring-1 focus:ring-[var(--kyro-primary)]"
307
- }
308
- ),
309
- /* @__PURE__ */ jsx(
310
- "button",
311
- {
312
- type: "submit",
313
- className: "px-2.5 py-1.5 text-sm rounded bg-[var(--kyro-primary)] text-[var(--kyro-sidebar-text-active)] hover:opacity-90",
314
- children: activeLink ? "Update" : "Add"
315
- }
316
- )
317
- ] }),
318
- activeLink && /* @__PURE__ */ jsxs(
319
- "button",
320
- {
321
- type: "button",
322
- onClick: handleRemove,
323
- className: "w-full text-xs text-[var(--kyro-error)] hover:opacity-80 flex items-center justify-center gap-1 py-1",
324
- children: [
325
- /* @__PURE__ */ jsx(LuExternalLink, { className: "w-3 h-3" }),
326
- "Remove link"
327
- ]
328
- }
329
- )
330
- ] })
331
- ]
332
- }
333
- );
334
- };
335
- var StyleSelector = () => {
336
- const schema = useToolbarSchema({});
337
- const editor = useEditor();
338
- const { snapshot, send } = useStyleSelector({
339
- schemaTypes: schema.styles || []
340
- });
341
- if (!snapshot.matches("enabled"))
342
- return null;
343
- const activeStyle = snapshot.context.activeStyle || "normal";
344
- return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
345
- /* @__PURE__ */ jsx(
346
- "select",
347
- {
348
- value: activeStyle,
349
- onChange: (e) => {
350
- send({ type: "toggle", style: e.target.value });
351
- editor.send({ type: "focus" });
352
- },
353
- className: "appearance-none bg-transparent text-sm pr-6 pl-2 py-1 rounded hover:bg-[var(--kyro-surface-accent)] cursor-pointer focus:outline-none focus:ring-1 focus:ring-[var(--kyro-primary)]",
354
- children: schema.styles?.map((s) => /* @__PURE__ */ jsx("option", { value: s.name, children: s.title }, s.name))
355
- }
356
- ),
357
- /* @__PURE__ */ jsx(LuChevronDown, { className: "w-3 h-3 absolute right-1.5 top-1/2 -translate-y-1/2 pointer-events-none text-[var(--kyro-text-muted)]" })
358
- ] });
359
- };
360
- var Toolbar = () => {
361
- const { snapshot: historySnapshot, send: historySend } = useHistoryButtons();
362
- return /* @__PURE__ */ jsxs("div", { className: "relative flex items-center gap-0.5 p-1.5 border-b border-[var(--kyro-border)]", children: [
363
- /* @__PURE__ */ jsx(
364
- FocusRestoringButton,
365
- {
366
- disabled: !historySnapshot.matches("enabled"),
367
- onClick: () => historySend({ type: "history.undo" }),
368
- title: "Undo",
369
- className: "p-1.5 rounded transition-colors hover:bg-[var(--kyro-surface-accent)] disabled:opacity-30",
370
- children: /* @__PURE__ */ jsx(LuUndo, { className: "w-4 h-4 text-[var(--kyro-text-secondary)]" })
371
- }
372
- ),
373
- /* @__PURE__ */ jsx(
374
- FocusRestoringButton,
375
- {
376
- disabled: !historySnapshot.matches("enabled"),
377
- onClick: () => historySend({ type: "history.redo" }),
378
- title: "Redo",
379
- className: "p-1.5 rounded transition-colors hover:bg-[var(--kyro-surface-accent)] disabled:opacity-30",
380
- children: /* @__PURE__ */ jsx(LuRedo, { className: "w-4 h-4 text-[var(--kyro-text-secondary)]" })
381
- }
382
- ),
383
- /* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-[var(--kyro-border)] mx-1" }),
384
- /* @__PURE__ */ jsx(StyleSelector, {}),
385
- /* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-[var(--kyro-border)] mx-1" }),
386
- /* @__PURE__ */ jsx(DecoratorButton, { name: "strong", title: "Bold" }),
387
- /* @__PURE__ */ jsx(DecoratorButton, { name: "em", title: "Italic" }),
388
- /* @__PURE__ */ jsx(DecoratorButton, { name: "underline", title: "Underline" }),
389
- /* @__PURE__ */ jsx(DecoratorButton, { name: "strikeThrough", title: "Strikethrough" }),
390
- /* @__PURE__ */ jsx(DecoratorButton, { name: "code", title: "Code" }),
391
- /* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-[var(--kyro-border)] mx-1" }),
392
- /* @__PURE__ */ jsx(AnnotationButton, { name: "link", title: "Link" }),
393
- /* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-[var(--kyro-border)] mx-1" }),
394
- /* @__PURE__ */ jsx(ListButton, { name: "bullet", title: "Bullet List" }),
395
- /* @__PURE__ */ jsx(ListButton, { name: "number", title: "Numbered List" }),
396
- /* @__PURE__ */ jsx(LinkDialog, {})
397
- ] });
398
- };
399
- var EditorInner = ({ onChange, disabled }) => {
400
- return /* @__PURE__ */ jsxs(Fragment, { children: [
401
- /* @__PURE__ */ jsx(Toolbar, {}),
402
- /* @__PURE__ */ jsx(
403
- PortableTextEditable,
404
- {
405
- className: "min-h-[200px] p-4 focus:outline-none text-[var(--kyro-text-primary)]",
406
- placeholder: "Start typing...",
407
- readOnly: disabled,
408
- renderStyle,
409
- renderDecorator,
410
- renderBlock,
411
- renderListItem,
412
- renderAnnotation
413
- }
414
- )
415
- ] });
416
- };
417
- var EditorClient = ({
418
- initialValue,
419
- onChange,
420
- disabled
421
- }) => {
422
- const [value, setValue] = useState(() => sanitizeInitialValue(initialValue));
423
- const prevInitialValueRef = useRef(initialValue);
424
- useEffect(() => {
425
- const sanitized = sanitizeInitialValue(initialValue);
426
- const prevSanitized = sanitizeInitialValue(prevInitialValueRef.current);
427
- if (JSON.stringify(sanitized) !== JSON.stringify(prevSanitized)) {
428
- setValue(sanitized);
429
- prevInitialValueRef.current = initialValue;
430
- }
431
- }, [initialValue]);
432
- const handleChange = useCallback(
433
- (newValue) => {
434
- setValue(newValue);
435
- onChange(newValue);
436
- },
437
- [onChange]
438
- );
439
- return /* @__PURE__ */ jsxs(
440
- EditorProvider,
441
- {
442
- initialConfig: {
443
- schemaDefinition,
444
- initialValue: value
445
- },
446
- children: [
447
- /* @__PURE__ */ jsx(
448
- EventListenerPlugin,
449
- {
450
- on: (event) => {
451
- if (event.type === "mutation" && event.value) {
452
- handleChange(event.value);
453
- }
454
- }
455
- }
456
- ),
457
- /* @__PURE__ */ jsx(EditorInner, { onChange: handleChange, disabled })
458
- ]
459
- },
460
- JSON.stringify(value)
461
- );
462
- };
463
-
464
- export { EditorClient };
465
- //# sourceMappingURL=out.js.map
466
- //# sourceMappingURL=EditorClient-T5PASFNR.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/fields/EditorClient.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n useState,\n useCallback,\n useRef,\n useEffect,\n useMemo,\n} from \"react\";\nimport {\n EditorProvider,\n PortableTextEditable,\n useEditor,\n type RenderStyleFunction,\n type RenderDecoratorFunction,\n type RenderBlockFunction,\n type RenderListItemFunction,\n type RenderAnnotationFunction,\n} from \"@portabletext/editor\";\nimport { defineSchema } from \"@portabletext/schema\";\nimport { EventListenerPlugin } from \"@portabletext/editor/plugins\";\nimport {\n useToolbarSchema,\n useDecoratorButton,\n useListButton,\n useStyleSelector,\n useHistoryButtons,\n useAnnotationButton,\n useAnnotationPopover,\n} from \"@portabletext/toolbar\";\nimport {\n Bold,\n Italic,\n Underline,\n Strikethrough,\n Code,\n Link,\n List,\n ListOrdered,\n Undo,\n Redo,\n ChevronDown,\n X,\n ExternalLink,\n} from \"../ui/icons\";\n\ninterface EditorClientProps {\n initialValue: Record<string, unknown>[];\n onChange: (blocks: Record<string, unknown>[]) => void;\n disabled?: boolean;\n}\n\nfunction sanitizeInitialValue(value: unknown): Record<string, unknown>[] {\n if (!value || !Array.isArray(value)) return [];\n return (value as Record<string, unknown>[]).filter((block) => {\n if (!block || typeof block !== \"object\") return false;\n if (!(\"_type\" in block)) return false;\n if ((block as { _type?: string })._type === \"block\" && Array.isArray((block as { children?: unknown[] }).children)) {\n (block as { children: Record<string, unknown>[] }).children = (block.children as Record<string, unknown>[]).map((child) => ({\n ...child,\n _type: (child as { _type?: string })._type || \"span\",\n text: typeof (child as { text?: unknown }).text === \"string\" ? child.text : \"\",\n }));\n }\n return true;\n });\n}\n\nconst schemaDefinition = defineSchema({\n decorators: [\n { name: \"strong\", title: \"Bold\" },\n { name: \"em\", title: \"Italic\" },\n { name: \"underline\", title: \"Underline\" },\n { name: \"strikeThrough\", title: \"Strikethrough\" },\n { name: \"code\", title: \"Code\" },\n ],\n styles: [\n { name: \"normal\", title: \"Normal\" },\n { name: \"h1\", title: \"H1\" },\n { name: \"h2\", title: \"H2\" },\n { name: \"h3\", title: \"H3\" },\n { name: \"blockquote\", title: \"Quote\" },\n ],\n lists: [\n { name: \"bullet\", title: \"Bullet\" },\n { name: \"number\", title: \"Number\" },\n ],\n annotations: [\n {\n name: \"link\",\n title: \"Link\",\n fields: [{ name: \"href\", type: \"string\", title: \"URL\" }],\n },\n ],\n inlineObjects: [],\n blockObjects: [],\n});\n\nconst renderStyle: RenderStyleFunction = (props) => {\n if (props.schemaType.value === \"h1\") {\n return <h1 className=\"text-2xl font-bold mb-2\">{props.children}</h1>;\n }\n if (props.schemaType.value === \"h2\") {\n return <h2 className=\"text-xl font-bold mb-2\">{props.children}</h2>;\n }\n if (props.schemaType.value === \"h3\") {\n return <h3 className=\"text-lg font-semibold mb-1\">{props.children}</h3>;\n }\n if (props.schemaType.value === \"blockquote\") {\n return (\n <blockquote className=\"border-l-2 border-[var(--kyro-primary)] pl-4 italic text-[var(--kyro-text-muted)] my-2\">\n {props.children}\n </blockquote>\n );\n }\n return <>{props.children}</>;\n};\n\nconst renderDecorator: RenderDecoratorFunction = (props) => {\n if (props.value === \"strong\") {\n return <strong>{props.children}</strong>;\n }\n if (props.value === \"em\") {\n return <em>{props.children}</em>;\n }\n if (props.value === \"underline\") {\n return <u>{props.children}</u>;\n }\n if (props.value === \"strikeThrough\") {\n return <s>{props.children}</s>;\n }\n if (props.value === \"code\") {\n return (\n <code className=\"px-1 py-0.5 rounded bg-[var(--kyro-surface-accent)] text-[var(--kyro-primary)] text-sm font-mono\">\n {props.children}\n </code>\n );\n }\n return <>{props.children}</>;\n};\n\nconst renderBlock: RenderBlockFunction = (props) => {\n return <div>{props.children}</div>;\n};\n\nconst renderListItem: RenderListItemFunction = (props) => {\n if (props.schemaType.value === \"bullet\") {\n return <li className=\"list-disc ml-4\">{props.children}</li>;\n }\n if (props.schemaType.value === \"number\") {\n return <li className=\"list-decimal ml-4\">{props.children}</li>;\n }\n return <li>{props.children}</li>;\n};\n\nconst renderAnnotation: RenderAnnotationFunction = (props) => {\n if (props.schemaType.name === \"link\") {\n return (\n <a\n href={props.value.href as string}\n className=\"text-[var(--kyro-primary)] underline hover:opacity-80\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {props.children}\n </a>\n );\n }\n return <>{props.children}</>;\n};\n\nfunction FocusRestoringButton({\n onClick,\n children,\n ...props\n}: React.ButtonHTMLAttributes<HTMLButtonElement>) {\n const editor = useEditor();\n return (\n <button\n type=\"button\"\n onClick={(e) => {\n onClick?.(e);\n editor.send({ type: \"focus\" });\n }}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nconst decoratorIcons: Record<\n string,\n React.ComponentType<{ className?: string }>\n> = {\n strong: Bold,\n em: Italic,\n underline: Underline,\n strikeThrough: Strikethrough,\n code: Code,\n};\n\nconst DecoratorButton: React.FC<{ name: string; title: string }> = ({\n name,\n title,\n}) => {\n const schema = useToolbarSchema({});\n const decoratorSchema = schema.decorators?.find((d) => d.name === name);\n if (!decoratorSchema) return null;\n const { snapshot, send } = useDecoratorButton({\n schemaType: decoratorSchema,\n });\n const Icon = decoratorIcons[name];\n const isActive =\n snapshot.matches({ enabled: \"active\" }) ||\n snapshot.matches({ disabled: \"active\" });\n const isEnabled = snapshot.matches(\"enabled\");\n\n return (\n <FocusRestoringButton\n disabled={!isEnabled}\n data-state={isActive ? \"on\" : \"off\"}\n onClick={() => send({ type: \"toggle\" })}\n title={title}\n className=\"p-1.5 rounded transition-colors disabled:opacity-30 hover:bg-[var(--kyro-surface-accent)] data-[state=on]:bg-[var(--kyro-primary)] data-[state=on]:text-[var(--kyro-sidebar-text-active)]\"\n >\n {Icon && <Icon className=\"w-4 h-4\" />}\n </FocusRestoringButton>\n );\n};\n\nconst ListButton: React.FC<{ name: string; title: string }> = ({\n name,\n title,\n}) => {\n const schema = useToolbarSchema({});\n const listSchema = schema.lists?.find((l) => l.name === name);\n if (!listSchema) return null;\n const { snapshot, send } = useListButton({ schemaType: listSchema });\n const Icon = name === \"bullet\" ? List : ListOrdered;\n const isActive =\n snapshot.matches({ enabled: \"active\" }) ||\n snapshot.matches({ disabled: \"active\" });\n const isEnabled = snapshot.matches(\"enabled\");\n\n return (\n <FocusRestoringButton\n disabled={!isEnabled}\n data-state={isActive ? \"on\" : \"off\"}\n onClick={() => send({ type: \"toggle\" })}\n title={title}\n className=\"p-1.5 rounded transition-colors disabled:opacity-30 hover:bg-[var(--kyro-surface-accent)] data-[state=on]:bg-[var(--kyro-primary)] data-[state=on]:text-[var(--kyro-sidebar-text-active)]\"\n >\n {Icon && <Icon className=\"w-4 h-4\" />}\n </FocusRestoringButton>\n );\n};\n\nconst AnnotationButton: React.FC<{ name: string; title: string }> = ({\n name,\n title,\n}) => {\n const schema = useToolbarSchema({});\n const annotationSchema = schema.annotations?.find((a) => a.name === name);\n if (!annotationSchema) return null;\n const { snapshot, send } = useAnnotationButton({\n schemaType: annotationSchema,\n });\n const isActive =\n snapshot.matches({ enabled: \"active\" }) ||\n snapshot.matches({ disabled: \"active\" });\n const isEnabled = snapshot.matches(\"enabled\");\n const isShowingDialog = snapshot.matches({\n enabled: { inactive: \"showing dialog\" },\n });\n\n return (\n <FocusRestoringButton\n disabled={!isEnabled}\n data-state={isActive ? \"on\" : \"off\"}\n onClick={() =>\n send({\n type: isShowingDialog ? \"close dialog\" : \"open dialog\",\n })\n }\n title={title}\n className=\"p-1.5 rounded transition-colors disabled:opacity-30 hover:bg-[var(--kyro-surface-accent)] data-[state=on]:bg-[var(--kyro-primary)] data-[state=on]:text-[var(--kyro-sidebar-text-active)]\"\n >\n {name === \"link\" && <Link className=\"w-4 h-4\" />}\n </FocusRestoringButton>\n );\n};\n\nconst LinkDialog: React.FC = () => {\n const schema = useToolbarSchema({});\n const popover = useAnnotationPopover({\n schemaTypes: schema.annotations || [],\n });\n const dialogRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (popover.snapshot.matches({ enabled: \"active\" }) && inputRef.current) {\n inputRef.current.focus();\n }\n }, [popover.snapshot]);\n\n if (!popover.snapshot.matches({ enabled: \"active\" })) return null;\n\n const activeAnnotations = popover.snapshot.context.annotations || [];\n const activeLink = activeAnnotations.find(\n (a) => a.schemaType.name === \"link\",\n );\n const currentHref = activeLink?.value?.href as string | undefined;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n const formData = new FormData(e.target as HTMLFormElement);\n const href = formData.get(\"href\") as string;\n\n if (activeLink) {\n if (href.trim()) {\n popover.send({\n type: \"edit\",\n at: activeLink.at,\n props: { href: href.trim() },\n });\n } else {\n popover.send({\n type: \"remove\",\n schemaType: activeLink.schemaType,\n });\n }\n } else {\n if (href.trim()) {\n popover.send({\n type: \"edit\",\n at: [] as string[],\n props: { href: href.trim() },\n });\n }\n }\n popover.send({ type: \"close\" });\n };\n\n const handleRemove = () => {\n if (activeLink) {\n popover.send({\n type: \"remove\",\n schemaType: activeLink.schemaType,\n });\n }\n popover.send({ type: \"close\" });\n };\n\n return (\n <div\n ref={dialogRef}\n className=\"absolute top-full left-0 z-50 mt-1 w-72 p-3 rounded-lg border border-[var(--kyro-border)] bg-[var(--kyro-bg-primary)] shadow-lg\"\n >\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-medium text-[var(--kyro-text-primary)]\">\n Link\n </span>\n <button\n type=\"button\"\n onClick={() => popover.send({ type: \"close\" })}\n className=\"p-1 rounded hover:bg-[var(--kyro-surface-accent)]\"\n >\n <X className=\"w-3.5 h-3.5 text-[var(--kyro-text-muted)]\" />\n </button>\n </div>\n <form onSubmit={handleSubmit} className=\"space-y-2\">\n <div className=\"flex gap-1.5\">\n <input\n ref={inputRef}\n name=\"href\"\n type=\"url\"\n defaultValue={currentHref || \"https://\"}\n placeholder=\"Enter URL...\"\n className=\"flex-1 px-2.5 py-1.5 text-sm rounded border border-[var(--kyro-border)] bg-transparent text-[var(--kyro-text-primary)] placeholder:text-[var(--kyro-text-muted)] focus:outline-none focus:ring-1 focus:ring-[var(--kyro-primary)]\"\n />\n <button\n type=\"submit\"\n className=\"px-2.5 py-1.5 text-sm rounded bg-[var(--kyro-primary)] text-[var(--kyro-sidebar-text-active)] hover:opacity-90\"\n >\n {activeLink ? \"Update\" : \"Add\"}\n </button>\n </div>\n {activeLink && (\n <button\n type=\"button\"\n onClick={handleRemove}\n className=\"w-full text-xs text-[var(--kyro-error)] hover:opacity-80 flex items-center justify-center gap-1 py-1\"\n >\n <ExternalLink className=\"w-3 h-3\" />\n Remove link\n </button>\n )}\n </form>\n </div>\n );\n};\n\nconst StyleSelector: React.FC = () => {\n const schema = useToolbarSchema({});\n const editor = useEditor();\n const { snapshot, send } = useStyleSelector({\n schemaTypes: schema.styles || [],\n });\n if (!snapshot.matches(\"enabled\")) return null;\n const activeStyle = snapshot.context.activeStyle || \"normal\";\n\n return (\n <div className=\"relative\">\n <select\n value={activeStyle}\n onChange={(e) => {\n send({ type: \"toggle\", style: e.target.value as string });\n editor.send({ type: \"focus\" });\n }}\n className=\"appearance-none bg-transparent text-sm pr-6 pl-2 py-1 rounded hover:bg-[var(--kyro-surface-accent)] cursor-pointer focus:outline-none focus:ring-1 focus:ring-[var(--kyro-primary)]\"\n >\n {schema.styles?.map((s) => (\n <option key={s.name} value={s.name}>\n {s.title}\n </option>\n ))}\n </select>\n <ChevronDown className=\"w-3 h-3 absolute right-1.5 top-1/2 -translate-y-1/2 pointer-events-none text-[var(--kyro-text-muted)]\" />\n </div>\n );\n};\n\nconst Toolbar: React.FC = () => {\n const { snapshot: historySnapshot, send: historySend } = useHistoryButtons();\n return (\n <div className=\"relative flex items-center gap-0.5 p-1.5 border-b border-[var(--kyro-border)]\">\n <FocusRestoringButton\n disabled={!historySnapshot.matches(\"enabled\")}\n onClick={() => historySend({ type: \"history.undo\" })}\n title=\"Undo\"\n className=\"p-1.5 rounded transition-colors hover:bg-[var(--kyro-surface-accent)] disabled:opacity-30\"\n >\n <Undo className=\"w-4 h-4 text-[var(--kyro-text-secondary)]\" />\n </FocusRestoringButton>\n <FocusRestoringButton\n disabled={!historySnapshot.matches(\"enabled\")}\n onClick={() => historySend({ type: \"history.redo\" })}\n title=\"Redo\"\n className=\"p-1.5 rounded transition-colors hover:bg-[var(--kyro-surface-accent)] disabled:opacity-30\"\n >\n <Redo className=\"w-4 h-4 text-[var(--kyro-text-secondary)]\" />\n </FocusRestoringButton>\n <div className=\"w-px h-5 bg-[var(--kyro-border)] mx-1\" />\n <StyleSelector />\n <div className=\"w-px h-5 bg-[var(--kyro-border)] mx-1\" />\n <DecoratorButton name=\"strong\" title=\"Bold\" />\n <DecoratorButton name=\"em\" title=\"Italic\" />\n <DecoratorButton name=\"underline\" title=\"Underline\" />\n <DecoratorButton name=\"strikeThrough\" title=\"Strikethrough\" />\n <DecoratorButton name=\"code\" title=\"Code\" />\n <div className=\"w-px h-5 bg-[var(--kyro-border)] mx-1\" />\n <AnnotationButton name=\"link\" title=\"Link\" />\n <div className=\"w-px h-5 bg-[var(--kyro-border)] mx-1\" />\n <ListButton name=\"bullet\" title=\"Bullet List\" />\n <ListButton name=\"number\" title=\"Numbered List\" />\n <LinkDialog />\n </div>\n );\n};\n\nconst EditorInner: React.FC<{\n onChange: (blocks: Record<string, unknown>[]) => void;\n disabled?: boolean;\n}> = ({ onChange, disabled }) => {\n return (\n <>\n <Toolbar />\n <PortableTextEditable\n className=\"min-h-[200px] p-4 focus:outline-none text-[var(--kyro-text-primary)]\"\n placeholder=\"Start typing...\"\n readOnly={disabled}\n renderStyle={renderStyle}\n renderDecorator={renderDecorator}\n renderBlock={renderBlock}\n renderListItem={renderListItem}\n renderAnnotation={renderAnnotation}\n />\n </>\n );\n};\n\nexport const EditorClient: React.FC<EditorClientProps> = ({\n initialValue,\n onChange,\n disabled,\n}) => {\n const [value, setValue] = useState(() => sanitizeInitialValue(initialValue));\n const prevInitialValueRef = useRef(initialValue);\n\n useEffect(() => {\n const sanitized = sanitizeInitialValue(initialValue);\n const prevSanitized = sanitizeInitialValue(prevInitialValueRef.current);\n if (JSON.stringify(sanitized) !== JSON.stringify(prevSanitized)) {\n setValue(sanitized);\n prevInitialValueRef.current = initialValue;\n }\n }, [initialValue]);\n\nconst handleChange = useCallback(\n (newValue: Record<string, unknown>[]) => {\n setValue(newValue);\n onChange(newValue);\n },\n [onChange],\n );\n\n return (\n <EditorProvider\n key={JSON.stringify(value)}\n initialConfig={{\n schemaDefinition: schemaDefinition as Record<string, unknown>,\n initialValue: value,\n }}\n >\n <EventListenerPlugin\n on={(event: Record<string, unknown>) => {\n if (event.type === \"mutation\" && event.value) {\n handleChange(event.value as Record<string, unknown>);\n }\n }}\n />\n<EditorInner onChange={handleChange} disabled={disabled} />\n </EditorProvider>\n);\n};\n"]}