@alpaca-editor/core 1.0.3974 → 1.0.3978

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 (139) hide show
  1. package/dist/components/ActionButton.js +1 -1
  2. package/dist/components/ActionButton.js.map +1 -1
  3. package/dist/components/FilterInput.d.ts +1 -0
  4. package/dist/components/FilterInput.js +2 -2
  5. package/dist/components/FilterInput.js.map +1 -1
  6. package/dist/components/ui/checkbox.d.ts +4 -0
  7. package/dist/components/ui/checkbox.js +10 -0
  8. package/dist/components/ui/checkbox.js.map +1 -0
  9. package/dist/components/ui/command.js +1 -1
  10. package/dist/components/ui/dialog.js +2 -2
  11. package/dist/components/ui/dialog.js.map +1 -1
  12. package/dist/components/ui/upload-button.d.ts +15 -0
  13. package/dist/components/ui/upload-button.js +56 -0
  14. package/dist/components/ui/upload-button.js.map +1 -0
  15. package/dist/config/config.js +7 -5
  16. package/dist/config/config.js.map +1 -1
  17. package/dist/editor/ContentTree.js +1 -1
  18. package/dist/editor/ContentTree.js.map +1 -1
  19. package/dist/editor/FieldActionsOverlay.js +1 -1
  20. package/dist/editor/FieldActionsOverlay.js.map +1 -1
  21. package/dist/editor/FieldList.js +3 -3
  22. package/dist/editor/FieldList.js.map +1 -1
  23. package/dist/editor/FieldListField.js +6 -8
  24. package/dist/editor/FieldListField.js.map +1 -1
  25. package/dist/editor/FieldListFieldWithFallbacks.js +2 -1
  26. package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
  27. package/dist/editor/ImageEditor.js +1 -1
  28. package/dist/editor/ImageEditor.js.map +1 -1
  29. package/dist/editor/ItemInfo.js +4 -4
  30. package/dist/editor/ItemInfo.js.map +1 -1
  31. package/dist/editor/commands/componentCommands.js +2 -2
  32. package/dist/editor/commands/componentCommands.js.map +1 -1
  33. package/dist/editor/context-menu/InsertMenu.js +1 -1
  34. package/dist/editor/context-menu/InsertMenu.js.map +1 -1
  35. package/dist/editor/field-types/CheckboxEditor.js +3 -3
  36. package/dist/editor/field-types/CheckboxEditor.js.map +1 -1
  37. package/dist/editor/field-types/ImageFieldEditor.js +1 -1
  38. package/dist/editor/field-types/InternalLinkFieldEditor.js +3 -2
  39. package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
  40. package/dist/editor/field-types/LinkFieldEditor.js +1 -1
  41. package/dist/editor/field-types/LinkFieldEditor.js.map +1 -1
  42. package/dist/editor/field-types/RawEditor.js +1 -1
  43. package/dist/editor/field-types/RawEditor.js.map +1 -1
  44. package/dist/editor/field-types/SingleLineText.js +1 -1
  45. package/dist/editor/fieldTypes.d.ts +1 -0
  46. package/dist/editor/media-selector/AiImageSearch.js.map +1 -1
  47. package/dist/editor/media-selector/AiImageSearchPrompt.js +3 -4
  48. package/dist/editor/media-selector/AiImageSearchPrompt.js.map +1 -1
  49. package/dist/editor/media-selector/MediaSelector.js +3 -3
  50. package/dist/editor/media-selector/MediaSelector.js.map +1 -1
  51. package/dist/editor/media-selector/Preview.d.ts +1 -1
  52. package/dist/editor/media-selector/Preview.js +14 -2
  53. package/dist/editor/media-selector/Preview.js.map +1 -1
  54. package/dist/editor/media-selector/Thumbnails.d.ts +1 -6
  55. package/dist/editor/media-selector/Thumbnails.js +3 -2
  56. package/dist/editor/media-selector/Thumbnails.js.map +1 -1
  57. package/dist/editor/media-selector/TreeSelector.js +22 -17
  58. package/dist/editor/media-selector/TreeSelector.js.map +1 -1
  59. package/dist/editor/media-selector/UploadZone.js +5 -3
  60. package/dist/editor/media-selector/UploadZone.js.map +1 -1
  61. package/dist/editor/media-selector/index.d.ts +1 -1
  62. package/dist/editor/media-selector/index.js.map +1 -1
  63. package/dist/editor/menubar/GenericToolbar.js +1 -1
  64. package/dist/editor/menubar/GenericToolbar.js.map +1 -1
  65. package/dist/editor/menubar/ToolbarFactory.js +2 -2
  66. package/dist/editor/menubar/ToolbarFactory.js.map +1 -1
  67. package/dist/editor/menubar/toolbar-sections/ReviewCommands.js +19 -19
  68. package/dist/editor/menubar/toolbar-sections/ReviewCommands.js.map +1 -1
  69. package/dist/editor/page-viewer/PageViewer.js +1 -1
  70. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  71. package/dist/editor/page-viewer/PageViewerFrame.js +1 -7
  72. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  73. package/dist/editor/reviews/Comment.js +14 -18
  74. package/dist/editor/reviews/Comment.js.map +1 -1
  75. package/dist/editor/reviews/SuggestedEdit.js +6 -5
  76. package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
  77. package/dist/editor/services/contentService.d.ts +12 -1
  78. package/dist/editor/services/contentService.js.map +1 -1
  79. package/dist/editor/sidebar/SidebarView.js +4 -2
  80. package/dist/editor/sidebar/SidebarView.js.map +1 -1
  81. package/dist/editor/ui/PerfectTree.d.ts +8 -3
  82. package/dist/editor/ui/PerfectTree.js +215 -8
  83. package/dist/editor/ui/PerfectTree.js.map +1 -1
  84. package/dist/editor/ui/Section.js +2 -1
  85. package/dist/editor/ui/Section.js.map +1 -1
  86. package/dist/page-wizard/PageWizard.d.ts +1 -1
  87. package/dist/page-wizard/steps/Components.d.ts +1 -1
  88. package/dist/page-wizard/steps/Components.js +2 -2
  89. package/dist/page-wizard/steps/Components.js.map +1 -1
  90. package/dist/revision.d.ts +2 -2
  91. package/dist/revision.js +2 -2
  92. package/dist/styles.css +81 -16
  93. package/package.json +2 -1
  94. package/src/components/ActionButton.tsx +2 -0
  95. package/src/components/FilterInput.tsx +7 -1
  96. package/src/components/ui/checkbox.tsx +32 -0
  97. package/src/components/ui/command.tsx +1 -1
  98. package/src/components/ui/dialog.tsx +5 -2
  99. package/src/components/ui/upload-button.tsx +117 -0
  100. package/src/config/config.tsx +11 -6
  101. package/src/editor/ContentTree.tsx +1 -0
  102. package/src/editor/FieldActionsOverlay.tsx +1 -1
  103. package/src/editor/FieldList.tsx +14 -10
  104. package/src/editor/FieldListField.tsx +20 -18
  105. package/src/editor/FieldListFieldWithFallbacks.tsx +14 -11
  106. package/src/editor/ImageEditor.tsx +1 -1
  107. package/src/editor/ItemInfo.tsx +10 -10
  108. package/src/editor/commands/componentCommands.tsx +2 -1
  109. package/src/editor/context-menu/InsertMenu.tsx +2 -1
  110. package/src/editor/field-types/CheckboxEditor.tsx +3 -3
  111. package/src/editor/field-types/ImageFieldEditor.tsx +1 -1
  112. package/src/editor/field-types/InternalLinkFieldEditor.tsx +8 -4
  113. package/src/editor/field-types/LinkFieldEditor.tsx +1 -1
  114. package/src/editor/field-types/RawEditor.tsx +1 -1
  115. package/src/editor/field-types/SingleLineText.tsx +1 -1
  116. package/src/editor/fieldTypes.ts +1 -0
  117. package/src/editor/media-selector/AiImageSearch.tsx +2 -1
  118. package/src/editor/media-selector/AiImageSearchPrompt.tsx +39 -20
  119. package/src/editor/media-selector/MediaFolderBrowser.tsx +1 -1
  120. package/src/editor/media-selector/MediaSelector.tsx +26 -17
  121. package/src/editor/media-selector/Preview.tsx +41 -3
  122. package/src/editor/media-selector/Thumbnails.tsx +13 -14
  123. package/src/editor/media-selector/TreeSelector.tsx +94 -40
  124. package/src/editor/media-selector/UploadZone.tsx +14 -12
  125. package/src/editor/media-selector/index.ts +1 -1
  126. package/src/editor/menubar/GenericToolbar.tsx +1 -3
  127. package/src/editor/menubar/ToolbarFactory.tsx +2 -2
  128. package/src/editor/menubar/toolbar-sections/ReviewCommands.tsx +7 -1
  129. package/src/editor/page-viewer/PageViewer.tsx +1 -1
  130. package/src/editor/page-viewer/PageViewerFrame.tsx +1 -10
  131. package/src/editor/reviews/Comment.tsx +51 -43
  132. package/src/editor/reviews/SuggestedEdit.tsx +30 -19
  133. package/src/editor/services/contentService.ts +13 -1
  134. package/src/editor/sidebar/SidebarView.tsx +8 -6
  135. package/src/editor/ui/PerfectTree.tsx +305 -9
  136. package/src/editor/ui/Section.tsx +16 -6
  137. package/src/page-wizard/PageWizard.tsx +1 -1
  138. package/src/page-wizard/steps/Components.tsx +8 -10
  139. package/src/revision.ts +2 -2
@@ -0,0 +1,117 @@
1
+ import * as React from "react";
2
+ import { Button, buttonVariants } from "./button";
3
+ import { cn } from "../../lib/utils";
4
+ import { Upload } from "lucide-react";
5
+ import { type VariantProps } from "class-variance-authority";
6
+
7
+ interface UploadButtonProps
8
+ extends Omit<React.ComponentProps<"button">, "onChange">,
9
+ VariantProps<typeof buttonVariants> {
10
+ accept?: string;
11
+ multiple?: boolean;
12
+ onFileSelect?: (files: FileList) => void;
13
+ onUpload?: (response: any) => void;
14
+ uploadUrl?: string;
15
+ disabled?: boolean;
16
+ children?: React.ReactNode;
17
+ auto?: boolean;
18
+ }
19
+
20
+ function UploadButton({
21
+ className,
22
+ variant = "default",
23
+ size = "default",
24
+ accept = "*/*",
25
+ multiple = false,
26
+ onFileSelect,
27
+ onUpload,
28
+ uploadUrl,
29
+ disabled = false,
30
+ children,
31
+ auto = false,
32
+ ...props
33
+ }: UploadButtonProps) {
34
+ const fileInputRef = React.useRef<HTMLInputElement>(null);
35
+
36
+ const handleButtonClick = () => {
37
+ fileInputRef.current?.click();
38
+ };
39
+
40
+ const handleFileChange = async (
41
+ event: React.ChangeEvent<HTMLInputElement>,
42
+ ) => {
43
+ const files = event.target.files;
44
+ if (!files || files.length === 0) return;
45
+
46
+ onFileSelect?.(files);
47
+
48
+ if (auto && uploadUrl) {
49
+ await uploadFiles(files);
50
+ }
51
+
52
+ // Reset the input so the same file can be selected again
53
+ if (fileInputRef.current) {
54
+ fileInputRef.current.value = "";
55
+ }
56
+ };
57
+
58
+ const uploadFiles = async (files: FileList) => {
59
+ for (let i = 0; i < files.length; i++) {
60
+ const file = files[i];
61
+ if (!file) continue;
62
+
63
+ const formData = new FormData();
64
+ formData.append("file", file);
65
+
66
+ try {
67
+ const response = await fetch(uploadUrl!, {
68
+ method: "POST",
69
+ body: formData,
70
+ });
71
+
72
+ if (response.ok) {
73
+ const result = await response.text();
74
+ onUpload?.({
75
+ xhr: {
76
+ responseText: result,
77
+ },
78
+ });
79
+ } else {
80
+ console.error("Upload failed:", response.statusText);
81
+ }
82
+ } catch (error) {
83
+ console.error("Upload error:", error);
84
+ }
85
+ }
86
+ };
87
+
88
+ return (
89
+ <>
90
+ <input
91
+ ref={fileInputRef}
92
+ type="file"
93
+ accept={accept}
94
+ multiple={multiple}
95
+ onChange={handleFileChange}
96
+ style={{ display: "none" }}
97
+ />
98
+ <Button
99
+ className={cn(className)}
100
+ variant={variant}
101
+ size={size}
102
+ onClick={handleButtonClick}
103
+ disabled={disabled}
104
+ {...props}
105
+ >
106
+ {children || (
107
+ <>
108
+ <Upload />
109
+ Upload
110
+ </>
111
+ )}
112
+ </Button>
113
+ </>
114
+ );
115
+ }
116
+
117
+ export { UploadButton };
@@ -121,7 +121,10 @@ import { Command } from "../editor/commands/commands";
121
121
  import { NewPage } from "../splash-screen/NewPage";
122
122
  import { OpenPage } from "../splash-screen/OpenPage";
123
123
  import { GenericToolbar } from "../editor/menubar/GenericToolbar";
124
- import { EditControls } from "../editor/menubar/toolbar-sections";
124
+ import {
125
+ EditControls,
126
+ UtilityControls,
127
+ } from "../editor/menubar/toolbar-sections";
125
128
 
126
129
  const defaultRichTextEditorProfile: RichTextEditorProfile = {
127
130
  toolbar: {
@@ -929,12 +932,14 @@ export function configureForUser(
929
932
  if (user.isLimitedPreviewUser) {
930
933
  const previewToolbar = (editContext: EditContextType) => (
931
934
  <GenericToolbar
932
- left={[
933
- { key: "review-commands", component: <ReviewCommands /> },
934
- { key: "edit-mode", component: <EditControls /> },
935
+ left={[{ key: "review-commands", component: <ReviewCommands /> }]}
936
+ center={[{ key: "edit-mode", component: <EditControls /> }]}
937
+ right={[
938
+ {
939
+ key: "utility-controls",
940
+ component: <UtilityControls />,
941
+ },
935
942
  ]}
936
- right={[]}
937
- center={[]}
938
943
  />
939
944
  );
940
945
 
@@ -714,6 +714,7 @@ export default function ContentTree({
714
714
  ref={treeContainerRef}
715
715
  >
716
716
  <MemoizedPerfectTree
717
+ enableKeyboardSearch={true}
717
718
  nodes={memoizedTreeNodes}
718
719
  expandedKeys={expandedKeys}
719
720
  onToggleExpand={handleToggleExpand}
@@ -271,7 +271,7 @@ const FieldActionsOverlay = React.forwardRef<
271
271
  {generatorButtons?.map((x) => (
272
272
  <button
273
273
  key={x.id}
274
- className="block p-1 text-xs hover:text-gray-400"
274
+ className="block cursor-pointer p-1 text-xs hover:text-gray-400"
275
275
  onClick={() => handleActionClick(x)}
276
276
  >
277
277
  {x.icon && <i className={x.icon + " mr-2 text-xs"} />}
@@ -7,9 +7,9 @@ import { SingleValidatorResult } from "../types";
7
7
  import { Field } from "./pageModel";
8
8
  import { FilterInput } from "../components/FilterInput";
9
9
  import { Fragment, useState } from "react";
10
- import { Checkbox } from "primereact/checkbox";
10
+
11
11
  import uuid from "react-uuid";
12
- import { SimpleIconButton } from "./ui/SimpleIconButton";
12
+ import { Checkbox } from "../components/ui/checkbox";
13
13
  import { ChevronRight } from "lucide-react";
14
14
  import {
15
15
  Tooltip,
@@ -64,14 +64,18 @@ export function FieldList({
64
64
  />
65
65
  {showStandardFieldsEnabled && (
66
66
  <>
67
- <Checkbox
68
- inputId={uniqueId}
69
- checked={showStandardFields}
70
- onChange={(e: any) => setShowStandardFields(e.checked)}
71
- />{" "}
72
- <label htmlFor={uniqueId} className="cursor-pointer text-xs">
73
- Show standard fields
74
- </label>
67
+ <div className="flex items-center gap-1">
68
+ <Checkbox
69
+ id={uniqueId}
70
+ checked={showStandardFields}
71
+ onCheckedChange={(checked: boolean) =>
72
+ setShowStandardFields(checked)
73
+ }
74
+ />{" "}
75
+ <label htmlFor={uniqueId} className="cursor-pointer text-xs">
76
+ Show standard fields
77
+ </label>
78
+ </div>
75
79
  </>
76
80
  )}
77
81
  </div>
@@ -20,6 +20,7 @@ import { useThrottledCallback } from "use-debounce";
20
20
  import { SimpleIconButton } from "./ui/SimpleIconButton";
21
21
  import { FieldHistory } from "./FieldHistory";
22
22
  import { Copy, History, MessageCircle, WandSparkles } from "lucide-react";
23
+ import { Checkbox } from "../components/ui/checkbox";
23
24
 
24
25
  export default function FieldListField({
25
26
  field,
@@ -166,7 +167,7 @@ export default function FieldListField({
166
167
  <>
167
168
  {(!executingAction || executingAction.state !== "running") && (
168
169
  <SimpleIconButton
169
- icon={<WandSparkles strokeWidth={1} className="h-4 w-4" />}
170
+ icon={<WandSparkles strokeWidth={1} className="h-3.5 w-3.5" />}
170
171
  label="Generate"
171
172
  onClick={(e: any) => {
172
173
  generatorsOverlay.current?.show(e);
@@ -277,27 +278,26 @@ export default function FieldListField({
277
278
  );
278
279
  })}
279
280
  {!simplified && (
280
- <button
281
- className="text-gray-1 cursor-pointer p-0 text-xs"
282
- onClick={() => {
283
- setShowRawValue(!showRawValue);
284
- }}
285
- >
286
- <i
287
- className={
288
- "pi text-xs " +
289
- (showRawValue ? "pi-check-square" : "pi-stop")
290
- }
291
- />{" "}
292
- Raw
293
- </button>
281
+ <div className="flex items-center gap-1.5 text-xs">
282
+ <Checkbox
283
+ className="size-3.5"
284
+ checked={showRawValue}
285
+ onCheckedChange={(checked) => setShowRawValue(!!checked)}
286
+ />
287
+ <label
288
+ className="cursor-pointer"
289
+ onClick={() => setShowRawValue(!showRawValue)}
290
+ >
291
+ Raw
292
+ </label>
293
+ </div>
294
294
  )}
295
295
  {field.rawValue && (
296
296
  <div className="relative">
297
297
  <button
298
298
  className="text-gray-1 flex cursor-pointer items-center gap-1 p-0 text-xs"
299
299
  onClick={() => {
300
- navigator.clipboard.writeText(field.rawValue!);
300
+ navigator.clipboard.writeText(field.rawValue || "");
301
301
  setShowCopiedHint(true);
302
302
  setTimeout(() => setShowCopiedHint(false), 2000);
303
303
  }}
@@ -319,7 +319,9 @@ export default function FieldListField({
319
319
  )}
320
320
  <div className="ml-auto flex items-center gap-1">
321
321
  <SimpleIconButton
322
- icon={<MessageCircle strokeWidth={1} className="h-4 w-4" />}
322
+ icon={
323
+ <MessageCircle strokeWidth={1} className="h-3.5 w-3.5" />
324
+ }
323
325
  onClick={() => {
324
326
  editContext.switchView("reviews");
325
327
  editContext.addComment();
@@ -328,7 +330,7 @@ export default function FieldListField({
328
330
  />
329
331
  {!readonly && renderGeneratorButtons()}
330
332
  <SimpleIconButton
331
- icon={<History strokeWidth={1} className="h-4 w-4" />}
333
+ icon={<History strokeWidth={1} className="h-3.5 w-3.5" />}
332
334
  onClick={(ev) => {
333
335
  fieldHistoryOverlay.current?.toggle(ev);
334
336
  ev.preventDefault();
@@ -2,6 +2,7 @@ import { useEffect, useRef, useState } from "react";
2
2
 
3
3
  import FieldListField from "./FieldListField";
4
4
  import { useEditContext, useOperationsContext } from "./client/editContext";
5
+ import { Checkbox } from "../components/ui/checkbox";
5
6
 
6
7
  import { SingleValidatorResult } from "../types";
7
8
 
@@ -147,17 +148,19 @@ export function FieldListFieldWithFallbacks({
147
148
  ]);
148
149
 
149
150
  const showFallbackButton = field?.isFallback && (
150
- <button
151
- className="p-0 text-xs"
152
- onClick={() => setShowFallback(!showFallback)}
153
- >
154
- <i
155
- className={
156
- "pi text-xs " + (showFallback ? "pi-check-square" : "pi-stop")
157
- }
158
- />{" "}
159
- Fallback
160
- </button>
151
+ <div className="flex items-center gap-1.5 text-xs">
152
+ <Checkbox
153
+ className="size-3.5"
154
+ checked={showFallback}
155
+ onCheckedChange={(checked) => setShowFallback(!!checked)}
156
+ />
157
+ <label
158
+ className="cursor-pointer"
159
+ onClick={() => setShowFallback(!showFallback)}
160
+ >
161
+ Fallback
162
+ </label>
163
+ </div>
161
164
  );
162
165
 
163
166
  if (!field) {
@@ -30,7 +30,7 @@ export function ImageEditor({
30
30
 
31
31
  async function selectMedia() {
32
32
  const selectedImageId = await editContext?.selectMedia({
33
- selectedIdPath: field.value?.src || "",
33
+ selectedIdPath: field.value?.idPath || "",
34
34
  mode: "images",
35
35
  });
36
36
  if (selectedImageId) imageSelected(selectedImageId);
@@ -14,7 +14,7 @@ export function ItemInfo({ item }: { item: FullItem | null }) {
14
14
  function formatRow(label: string, value: string) {
15
15
  return (
16
16
  <>
17
- <div className="font-bold">{label}</div>
17
+ <div className="font-medium">{label}</div>
18
18
  <div>{value}</div>
19
19
  </>
20
20
  );
@@ -29,7 +29,7 @@ export function ItemInfo({ item }: { item: FullItem | null }) {
29
29
  className="mr-2"
30
30
  style={{ height: "32px", width: "32px" }}
31
31
  />
32
- <h2 className="text-l flex items-center gap-1 font-bold">
32
+ <h2 className="text-l flex items-center gap-1 font-medium">
33
33
  {item.name}
34
34
  <SimpleIconButton
35
35
  onClick={() => {
@@ -38,26 +38,26 @@ export function ItemInfo({ item }: { item: FullItem | null }) {
38
38
  data: { items: [item] },
39
39
  });
40
40
  }}
41
- icon={<Pencil size={14} />}
41
+ icon={<Pencil size={14} strokeWidth={1} />}
42
42
  label="Rename"
43
43
  ></SimpleIconButton>
44
44
  </h2>
45
45
  </div>
46
46
  <Section title="Info">
47
- <div className="grid grid-cols-[min-content_1fr] gap-3 text-xs">
48
- <div className="font-bold">ID:</div>
47
+ <div className="grid grid-cols-[min-content_1fr] gap-3 text-xs font-light">
48
+ <div className="font-medium">ID:</div>
49
49
  <div className="flex items-center gap-1">
50
50
  {item.id} <CopyToClipboardButton text={item.id} />
51
51
  </div>
52
- <div className="font-bold">Path:</div>
52
+ <div className="font-medium">Path:</div>
53
53
  <div className="flex items-center gap-1">
54
54
  {item.path} <CopyToClipboardButton text={item.path} />
55
55
  </div>
56
- <div className="font-bold">Language:</div>
56
+ <div className="font-medium">Language:</div>
57
57
  <div>{item.language}</div>
58
- <div className="font-bold">Version:</div>
58
+ <div className="font-medium">Version:</div>
59
59
  <div>{item.versions > 0 ? item.version : "No versions"}</div>
60
- <div className="font-bold">Template:</div>
60
+ <div className="font-medium">Template:</div>
61
61
  <div className="flex items-center gap-1">
62
62
  <span
63
63
  className="cursor-pointer hover:underline"
@@ -80,7 +80,7 @@ export function ItemInfo({ item }: { item: FullItem | null }) {
80
80
  formatRow("Master languages", item.masterLanguages.join(", "))}
81
81
  {item.translations && (
82
82
  <>
83
- <div className="font-bold">Languages</div>
83
+ <div className="font-medium">Languages</div>
84
84
  <div>{item.translations?.join(", ")}</div>
85
85
  </>
86
86
  )}
@@ -14,6 +14,7 @@ import {
14
14
  Check,
15
15
  Copy,
16
16
  MessageCircleMore,
17
+ MessageCirclePlus,
17
18
  Palette,
18
19
  Plus,
19
20
  RefreshCcw,
@@ -407,7 +408,7 @@ function getCreateCommentCommand(
407
408
  return {
408
409
  id: "addComment",
409
410
  label: "Add Comment",
410
- icon: <MessageCircleMore size={14} />,
411
+ icon: <MessageCirclePlus size={14} />,
411
412
  disabled: () => false,
412
413
  visibilityScopes: ["contextMenu"],
413
414
  execute: async (context: CommandContext<any>) => {
@@ -325,8 +325,9 @@ export const InsertMenuTemplate = ({
325
325
  border: "1px solid #ddd",
326
326
  }}
327
327
  >
328
- <div className="absolute inset-4 flex flex-col">
328
+ <div className="absolute inset-4 flex flex-col text-xs">
329
329
  <SimpleTabs
330
+ className="border-gray-3 mb-2 border-b"
330
331
  tabs={tabs}
331
332
  setActiveTab={setActiveTab}
332
333
  activeTab={activeTab}
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useEditContext } from "../client/editContext";
4
4
 
5
- import { Checkbox } from "primereact/checkbox";
5
+ import { Checkbox } from "../../components/ui/checkbox";
6
6
  import { useEffect, useState } from "react";
7
7
  import { ProgressSpinner } from "primereact/progressspinner";
8
8
  import { CheckboxField } from "../fieldTypes";
@@ -34,11 +34,11 @@ export function CheckboxEditor({
34
34
  key={fieldItem.id + field.id + fieldItem.language + fieldItem.version}
35
35
  checked={field.value}
36
36
  disabled={readOnly}
37
- onClick={() => {
37
+ onCheckedChange={(checked) => {
38
38
  setIsUpdating(true);
39
39
  editContext.operations.editField({
40
40
  field: field.descriptor,
41
- rawValue: field.value ? "0" : "1",
41
+ rawValue: checked ? "1" : "0",
42
42
  refresh: "immediate",
43
43
  });
44
44
  }}
@@ -47,7 +47,7 @@ export function ImageFieldEditor({
47
47
  key={item!.id + field.id + item!.language + item!.version}
48
48
  value={altText}
49
49
  disabled={readOnly}
50
- className="focus-shadow bg-gray-5 p-1.5 text-sm"
50
+ className="focus-shadow bg-gray-5 p-1.5 text-xs"
51
51
  style={{ width: "100%" }}
52
52
  onChange={(e) => {
53
53
  setAltText(e.target.value);
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useEffect, useRef, useState } from "react";
4
+ import { ChevronDown } from "lucide-react";
4
5
 
5
6
  import { Link } from "../LinkEditorDialog";
6
7
  import { useEditContext } from "../client/editContext";
@@ -121,7 +122,7 @@ export function InternalLinkFieldEditor({
121
122
  <div
122
123
  ref={texboxRef}
123
124
  className={classNames(
124
- "justiy-between focus-shadow flex cursor-pointer justify-between border p-1.5 text-sm",
125
+ "justiy-between focus-shadow flex cursor-pointer justify-between border p-1.5 text-xs",
125
126
  readOnly ? "bg-gray-50" : "bg-white",
126
127
  )}
127
128
  onClick={(e) => {
@@ -137,9 +138,12 @@ export function InternalLinkFieldEditor({
137
138
  <span>&nbsp;</span>
138
139
  )}
139
140
  {!readOnly && (
140
- <i
141
- className={`pi ${showTree ? "pi-angle-up" : "pi-angle-down"} `}
142
- ></i>
141
+ <ChevronDown
142
+ strokeWidth={1}
143
+ className={`h-4 w-4 transition-transform duration-200 ${
144
+ showTree ? "rotate-180" : "rotate-0"
145
+ }`}
146
+ />
143
147
  )}
144
148
  </div>
145
149
  <div ref={dropdownRef} className="w-0"></div>
@@ -34,7 +34,7 @@ export function LinkFieldEditor({
34
34
  <>
35
35
  <div
36
36
  className={classNames(
37
- "focus-shadow flex justify-between border border-gray-300 p-2",
37
+ "focus-shadow border-gray-3 bg-gray-5 flex justify-between border p-2",
38
38
  readOnly ? "bg-gray-100" : "cursor-pointer bg-white",
39
39
  )}
40
40
  onClick={(e) => {
@@ -40,7 +40,7 @@ export function RawEditor({
40
40
  key={fieldItem.id + field.id + fieldItem.language + fieldItem.version}
41
41
  value={value || ""}
42
42
  disabled={readOnly}
43
- className="p-2 focus-shadow text-sm"
43
+ className="focus-shadow bg-gray-5 p-2 text-xs"
44
44
  style={{ width: "100%" }}
45
45
  rows={12}
46
46
  onChange={(e) => {
@@ -164,7 +164,7 @@ export function SingleLineText({
164
164
  key={fieldItem.id + field.id + fieldItem.language + fieldItem.version}
165
165
  value={value || ""}
166
166
  disabled={readOnly}
167
- className="focus-shadow bg-gray-5 p-1.5 text-sm"
167
+ className="focus-shadow bg-gray-5 p-1.5 text-xs"
168
168
  style={{ width: "100%" }}
169
169
  onChange={handleChange}
170
170
  onSelect={handleSelect}
@@ -77,6 +77,7 @@ export type ImageField = Field & {
77
77
  export type ImageValue = {
78
78
  alt: string;
79
79
  src: string;
80
+ idPath?: string;
80
81
  };
81
82
 
82
83
  export type LinkValue = {
@@ -6,7 +6,8 @@ import { executePrompt, executeSearch } from "../services/aiService";
6
6
  import { useEditContext } from "../client/editContext";
7
7
  import { ProgressSpinner } from "primereact/progressspinner";
8
8
  import { InputText } from "primereact/inputtext";
9
- import { Thumbnail, Thumbnails } from "./Thumbnails";
9
+ import { Thumbnail } from "../services/contentService";
10
+ import { Thumbnails } from "./Thumbnails";
10
11
  import { Splitter, SplitterPanel } from "primereact/splitter";
11
12
  import { Preview } from "./Preview";
12
13
  import DialogButtons from "../ui/DialogButtons";
@@ -1,10 +1,9 @@
1
- import { Button } from "primereact/button";
2
- import { InputText } from "primereact/inputtext";
3
1
  import { useEffect, useRef, useState } from "react";
4
2
  import { useEditContext } from "../client/editContext";
5
3
  import { executePrompt } from "../services/aiService";
6
4
  import { createEditorAiContext } from "../ai/editorAiContext";
7
- import { ProgressSpinner } from "primereact/progressspinner";
5
+ import { FilterInput } from "../../components/FilterInput";
6
+ import { ActionButton } from "../../components/ActionButton";
8
7
 
9
8
  export function AiImageSearchPrompt({
10
9
  onSearchPromptChange,
@@ -69,26 +68,46 @@ export function AiImageSearchPrompt({
69
68
 
70
69
  return (
71
70
  <div className="m-2 flex items-center gap-2">
72
- <i className="pi pi-search text-gray-500" />
73
- <InputText
74
- ref={inputRef} // Add ref to InputText
71
+ <FilterInput
72
+ ref={inputRef}
75
73
  value={prompt}
76
- onChange={(e) => setPrompt(e.target.value)}
74
+ onChange={setPrompt}
77
75
  className="flex-1"
76
+ placeholder="Enter search terms for image..."
77
+ loading={loadingPrompt}
78
+ showSearchIcon={true}
79
+ showClearIcon={true}
80
+ size="md"
78
81
  />
79
- {loadingPrompt && (
80
- <div className="flex h-10 items-center">
81
- <ProgressSpinner style={{ width: "24px", height: "24px" }} />
82
- </div>
83
- )}
84
- {!loadingPrompt && (
85
- <Button
86
- icon="pi pi-sparkles"
87
- onClick={() => suggestPrompt()}
88
- label="Suggest"
89
- size="small"
90
- />
91
- )}
82
+ <ActionButton
83
+ onClick={() => suggestPrompt()}
84
+ isLoading={loadingPrompt}
85
+ loadingText="Suggesting..."
86
+ disabled={loadingPrompt}
87
+ variant="outline"
88
+ >
89
+ <svg
90
+ width="22"
91
+ height="20"
92
+ viewBox="0 0 22 20"
93
+ fill="none"
94
+ xmlns="http://www.w3.org/2000/svg"
95
+ >
96
+ <path
97
+ d="M14.0062 3.46766C14.2345 3.41253 14.4444 3.35739 14.6542 3.30225C14.9073 3.23485 15.1665 3.17971 15.4134 3.09394C16.37 2.7386 16.9748 2.06467 17.2341 1.09054C17.3266 0.735194 17.4192 0.37985 17.5118 0.0306331C17.5118 0.0183798 17.5118 0.0122532 17.5303 0C17.5488 0.0612662 17.5612 0.122532 17.5797 0.183799C17.6784 0.557522 17.7587 0.931246 17.8821 1.29884C18.2154 2.2791 18.9005 2.91014 19.9065 3.18584C20.2644 3.28387 20.6286 3.36964 20.9865 3.46766C21.0051 3.46766 21.0174 3.47379 21.0483 3.48604C20.9125 3.5228 20.7891 3.55344 20.6594 3.58407C20.3262 3.67597 19.9867 3.74336 19.6596 3.85364C18.7091 4.19061 18.0981 4.85841 17.8266 5.82641C17.7216 6.20014 17.6291 6.57386 17.518 6.95371C17.518 6.93533 17.5056 6.91695 17.4994 6.89857C17.4007 6.51872 17.3143 6.13887 17.197 5.76515C16.8823 4.72975 16.191 4.06195 15.1356 3.774C14.7777 3.67597 14.4197 3.5902 14.0617 3.4983C14.0432 3.4983 14.0309 3.49217 14 3.47992L14.0062 3.46766Z"
98
+ fill="#9650FB"
99
+ />
100
+ <path
101
+ d="M0.5 9.29394C1.04312 9.15303 1.54922 9.02437 2.05531 8.88958C2.66632 8.72416 3.28968 8.60163 3.88218 8.3872C6.17811 7.54173 7.63467 5.91817 8.2642 3.57168C8.49256 2.72008 8.71475 1.86848 8.93694 1.01688C8.94311 0.992372 8.94928 0.967866 8.98014 0.943359C9.01717 1.0904 9.06037 1.23744 9.09741 1.37835C9.33194 2.27284 9.52326 3.17957 9.81951 4.05568C10.6219 6.42055 12.2636 7.9277 14.6829 8.58938C15.547 8.82219 16.4172 9.03662 17.2813 9.2633C17.3183 9.27556 17.3554 9.28168 17.4232 9.30619C17.09 9.39196 16.7937 9.46548 16.4913 9.54513C15.689 9.75956 14.8681 9.91885 14.0904 10.2007C11.8007 11.0155 10.3379 12.6207 9.6899 14.9488C9.43686 15.8494 9.21467 16.75 8.95545 17.6629C8.94311 17.62 8.93077 17.5771 8.91842 17.5281C8.67772 16.6152 8.47405 15.6963 8.19631 14.7956C7.43717 12.3021 5.77077 10.7031 3.24031 10.0108C2.38242 9.77794 1.51836 9.56351 0.654297 9.34295C0.617265 9.3307 0.580234 9.32457 0.5 9.30006L0.5 9.29394Z"
102
+ fill="#9650FB"
103
+ />
104
+ <path
105
+ d="M14.0062 15.7881C14.2345 15.733 14.4444 15.6778 14.6542 15.6227C14.9073 15.5553 15.1665 15.5001 15.4134 15.4144C16.37 15.059 16.9748 14.3851 17.2341 13.411C17.3266 13.0556 17.4192 12.7003 17.5118 12.3511C17.5118 12.3388 17.5118 12.3327 17.5303 12.3204C17.5488 12.3817 17.5612 12.443 17.5797 12.5042C17.6784 12.878 17.7587 13.2517 17.8821 13.6193C18.2154 14.5995 18.9005 15.2306 19.9065 15.5063C20.2644 15.6043 20.6286 15.6901 20.9865 15.7881C21.0051 15.7881 21.0174 15.7942 21.0483 15.8065C20.9125 15.8432 20.7891 15.8739 20.6594 15.9045C20.3262 15.9964 19.9867 16.0638 19.6596 16.1741C18.7091 16.511 18.0981 17.1788 17.8266 18.1468C17.7216 18.5206 17.6291 18.8943 17.518 19.2741C17.518 19.2558 17.5056 19.2374 17.4994 19.219C17.4007 18.8392 17.3143 18.4593 17.197 18.0856C16.8823 17.0502 16.191 16.3824 15.1356 16.0944C14.7777 15.9964 14.4197 15.9106 14.0617 15.8187C14.0432 15.8187 14.0309 15.8126 14 15.8004L14.0062 15.7881Z"
106
+ fill="#9650FB"
107
+ />
108
+ </svg>
109
+ Suggest search terms
110
+ </ActionButton>
92
111
  </div>
93
112
  );
94
113
  }
@@ -4,7 +4,7 @@ import { Button } from "primereact/button";
4
4
  import { ProgressSpinner } from "primereact/progressspinner";
5
5
  import { useEditContext } from "../client/editContext";
6
6
  import { getChildren } from "../services/contentService";
7
- import { Thumbnail } from "./Thumbnails";
7
+ import { Thumbnail } from "../services/contentService";
8
8
 
9
9
  type ViewMode = "grid" | "list" | "large-grid";
10
10