@alpaca-editor/core 1.0.3942 → 1.0.3944

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 (308) hide show
  1. package/.prettierrc +3 -0
  2. package/build.css +3 -0
  3. package/components.json +21 -0
  4. package/dist/editor/ContentTree.d.ts +2 -1
  5. package/dist/editor/ContentTree.js +23 -21
  6. package/dist/editor/ContentTree.js.map +1 -1
  7. package/dist/editor/FieldActionsOverlay.js +0 -2
  8. package/dist/editor/FieldActionsOverlay.js.map +1 -1
  9. package/dist/editor/ScrollingContentTree.js +1 -1
  10. package/dist/editor/ScrollingContentTree.js.map +1 -1
  11. package/dist/editor/Titlebar.js +1 -1
  12. package/dist/editor/Titlebar.js.map +1 -1
  13. package/dist/editor/ai/GhostWriter.js +24 -3
  14. package/dist/editor/ai/GhostWriter.js.map +1 -1
  15. package/dist/editor/client/EditorClient.js +7 -7
  16. package/dist/editor/client/EditorClient.js.map +1 -1
  17. package/dist/editor/field-types/InternalLinkFieldEditor.js +60 -10
  18. package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
  19. package/dist/editor/media-selector/MediaFolderBrowser.js +48 -1
  20. package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
  21. package/dist/editor/menubar/PageSelector.js +116 -65
  22. package/dist/editor/menubar/PageSelector.js.map +1 -1
  23. package/dist/editor/page-viewer/EditorForm.js +5 -2
  24. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  25. package/dist/editor/ui/ItemSearch.js +14 -8
  26. package/dist/editor/ui/ItemSearch.js.map +1 -1
  27. package/dist/editor/ui/PerfectTree.d.ts +4 -2
  28. package/dist/editor/ui/PerfectTree.js +78 -4
  29. package/dist/editor/ui/PerfectTree.js.map +1 -1
  30. package/dist/editor/ui/Splitter.js +1 -1
  31. package/dist/revision.d.ts +2 -2
  32. package/dist/revision.js +2 -2
  33. package/dist/styles.css +8 -2
  34. package/eslint.config.mjs +4 -0
  35. package/images/bg-shape-black.webp +0 -0
  36. package/images/wizard-bg.png +0 -0
  37. package/images/wizard-tour.png +0 -0
  38. package/images/wizard.png +0 -0
  39. package/package.json +2 -8
  40. package/src/client-components/api.ts +6 -0
  41. package/src/client-components/index.ts +19 -0
  42. package/src/components/ActionButton.tsx +50 -0
  43. package/src/components/Error.tsx +57 -0
  44. package/src/components/ui/CardConnector.tsx +56 -0
  45. package/src/components/ui/button.tsx +62 -0
  46. package/src/components/ui/card.tsx +372 -0
  47. package/src/components/ui/context-menu.tsx +250 -0
  48. package/src/config/config.tsx +917 -0
  49. package/src/config/types.ts +286 -0
  50. package/src/editor/ComponentInfo.tsx +90 -0
  51. package/src/editor/ConfirmationDialog.tsx +103 -0
  52. package/src/editor/ContentTree.tsx +733 -0
  53. package/src/editor/ContextMenu.tsx +230 -0
  54. package/src/editor/Editor.tsx +90 -0
  55. package/src/editor/EditorWarning.tsx +34 -0
  56. package/src/editor/EditorWarnings.tsx +33 -0
  57. package/src/editor/FieldActionsOverlay.tsx +296 -0
  58. package/src/editor/FieldEditorPopup.tsx +65 -0
  59. package/src/editor/FieldHistory.tsx +75 -0
  60. package/src/editor/FieldList.tsx +190 -0
  61. package/src/editor/FieldListField.tsx +391 -0
  62. package/src/editor/FieldListFieldWithFallbacks.tsx +217 -0
  63. package/src/editor/FloatingToolbar.tsx +163 -0
  64. package/src/editor/ImageEditor.tsx +128 -0
  65. package/src/editor/ItemInfo.tsx +90 -0
  66. package/src/editor/LinkEditorDialog.tsx +196 -0
  67. package/src/editor/MainLayout.tsx +95 -0
  68. package/src/editor/MobileLayout.tsx +68 -0
  69. package/src/editor/NewEditorClient.tsx +11 -0
  70. package/src/editor/PictureCropper.tsx +568 -0
  71. package/src/editor/PictureEditor.tsx +301 -0
  72. package/src/editor/PictureEditorDialog.tsx +381 -0
  73. package/src/editor/PublishDialog.ignore +74 -0
  74. package/src/editor/ScrollingContentTree.tsx +68 -0
  75. package/src/editor/Terminal.tsx +227 -0
  76. package/src/editor/Titlebar.tsx +104 -0
  77. package/src/editor/ai/AiPopup.tsx +59 -0
  78. package/src/editor/ai/AiResponseMessage.tsx +106 -0
  79. package/src/editor/ai/AiTerminal.tsx +503 -0
  80. package/src/editor/ai/AiToolCall.tsx +61 -0
  81. package/src/editor/ai/EditorAiTerminal.tsx +20 -0
  82. package/src/editor/ai/GhostWriter.tsx +480 -0
  83. package/src/editor/ai/aiPageModel.ts +108 -0
  84. package/src/editor/ai/editorAiContext.ts +18 -0
  85. package/src/editor/client/AboutDialog.tsx +44 -0
  86. package/src/editor/client/EditorClient.tsx +2241 -0
  87. package/src/editor/client/GenericDialog.tsx +50 -0
  88. package/src/editor/client/editContext.ts +416 -0
  89. package/src/editor/client/helpers.ts +44 -0
  90. package/src/editor/client/itemsRepository.ts +574 -0
  91. package/src/editor/client/operations.ts +768 -0
  92. package/src/editor/client/pageModelBuilder.ts +219 -0
  93. package/src/editor/commands/commands.ts +22 -0
  94. package/src/editor/commands/componentCommands.tsx +431 -0
  95. package/src/editor/commands/createVersionCommand.ts +33 -0
  96. package/src/editor/commands/deleteVersionCommand.ts +71 -0
  97. package/src/editor/commands/itemCommands.tsx +351 -0
  98. package/src/editor/commands/localizeItem/LocalizeItemDialog.tsx +201 -0
  99. package/src/editor/commands/localizeItem/LocalizeItemUtils.ts +27 -0
  100. package/src/editor/commands/undo.ts +39 -0
  101. package/src/editor/component-designer/ComponentDesigner.tsx +70 -0
  102. package/src/editor/component-designer/ComponentDesignerAiTerminal.tsx +11 -0
  103. package/src/editor/component-designer/ComponentDesignerMenu.tsx +91 -0
  104. package/src/editor/component-designer/ComponentEditor.tsx +97 -0
  105. package/src/editor/component-designer/ComponentRenderingCodeEditor.tsx +31 -0
  106. package/src/editor/component-designer/ComponentRenderingEditor.tsx +104 -0
  107. package/src/editor/component-designer/ComponentsDropdown.tsx +39 -0
  108. package/src/editor/component-designer/PlaceholdersEditor.tsx +179 -0
  109. package/src/editor/component-designer/RenderingsDropdown.tsx +36 -0
  110. package/src/editor/component-designer/TemplateEditor.tsx +236 -0
  111. package/src/editor/component-designer/aiContext.ts +23 -0
  112. package/src/editor/componentTreeHelper.tsx +116 -0
  113. package/src/editor/context-menu/CopyMoveMenu.tsx +103 -0
  114. package/src/editor/context-menu/InsertMenu.tsx +347 -0
  115. package/src/editor/control-center/About.tsx +342 -0
  116. package/src/editor/control-center/ControlCenterMenu.tsx +76 -0
  117. package/src/editor/control-center/IndexOverview.tsx +50 -0
  118. package/src/editor/control-center/IndexSettings.tsx +266 -0
  119. package/src/editor/control-center/Info.tsx +104 -0
  120. package/src/editor/control-center/QuotaInfo.tsx +301 -0
  121. package/src/editor/control-center/Status.tsx +113 -0
  122. package/src/editor/control-center/WebSocketMessages.tsx +155 -0
  123. package/src/editor/editor-warnings/ItemLocked.tsx +63 -0
  124. package/src/editor/editor-warnings/NoLanguageWriteAccess.tsx +22 -0
  125. package/src/editor/editor-warnings/NoWorkflowWriteAccess.tsx +23 -0
  126. package/src/editor/editor-warnings/NoWriteAccess.tsx +16 -0
  127. package/src/editor/editor-warnings/ValidationErrors.tsx +54 -0
  128. package/src/editor/field-types/AttachmentEditor.tsx +9 -0
  129. package/src/editor/field-types/CheckboxEditor.tsx +47 -0
  130. package/src/editor/field-types/DropLinkEditor.tsx +80 -0
  131. package/src/editor/field-types/DropListEditor.tsx +84 -0
  132. package/src/editor/field-types/ImageFieldEditor.tsx +65 -0
  133. package/src/editor/field-types/InternalLinkFieldEditor.tsx +188 -0
  134. package/src/editor/field-types/LinkFieldEditor.tsx +85 -0
  135. package/src/editor/field-types/MultiLineText.tsx +82 -0
  136. package/src/editor/field-types/PictureFieldEditor.tsx +121 -0
  137. package/src/editor/field-types/RawEditor.tsx +53 -0
  138. package/src/editor/field-types/ReactQuill.tsx +580 -0
  139. package/src/editor/field-types/RichTextEditor.tsx +22 -0
  140. package/src/editor/field-types/RichTextEditorComponent.tsx +127 -0
  141. package/src/editor/field-types/SingleLineText.tsx +174 -0
  142. package/src/editor/field-types/TreeListEditor.tsx +261 -0
  143. package/src/editor/fieldTypes.ts +140 -0
  144. package/src/editor/media-selector/AiImageSearch.tsx +185 -0
  145. package/src/editor/media-selector/AiImageSearchPrompt.tsx +94 -0
  146. package/src/editor/media-selector/MediaFolderBrowser.tsx +321 -0
  147. package/src/editor/media-selector/MediaSelector.tsx +42 -0
  148. package/src/editor/media-selector/Preview.tsx +14 -0
  149. package/src/editor/media-selector/Thumbnails.tsx +48 -0
  150. package/src/editor/media-selector/TreeSelector.tsx +292 -0
  151. package/src/editor/media-selector/UploadZone.tsx +137 -0
  152. package/src/editor/media-selector/index.ts +8 -0
  153. package/src/editor/menubar/ActionsMenu.tsx +94 -0
  154. package/src/editor/menubar/ActiveUsers.tsx +17 -0
  155. package/src/editor/menubar/ApproveAndPublish.tsx +18 -0
  156. package/src/editor/menubar/BrowseHistory.tsx +28 -0
  157. package/src/editor/menubar/ItemLanguageVersion.tsx +76 -0
  158. package/src/editor/menubar/LanguageSelector.tsx +226 -0
  159. package/src/editor/menubar/Menu.tsx +83 -0
  160. package/src/editor/menubar/NavButtons.tsx +74 -0
  161. package/src/editor/menubar/PageSelector.tsx +278 -0
  162. package/src/editor/menubar/PageViewerControls.tsx +120 -0
  163. package/src/editor/menubar/PreviewSecondaryControls.tsx +18 -0
  164. package/src/editor/menubar/SecondaryControls.tsx +45 -0
  165. package/src/editor/menubar/Separator.tsx +12 -0
  166. package/src/editor/menubar/SiteInfo.tsx +53 -0
  167. package/src/editor/menubar/User.tsx +27 -0
  168. package/src/editor/menubar/VersionSelector.tsx +142 -0
  169. package/src/editor/page-editor-chrome/CommentHighlighting.tsx +307 -0
  170. package/src/editor/page-editor-chrome/CommentHighlightings.tsx +35 -0
  171. package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +59 -0
  172. package/src/editor/page-editor-chrome/FieldActionIndicators.tsx +23 -0
  173. package/src/editor/page-editor-chrome/FieldEditedIndicator.tsx +64 -0
  174. package/src/editor/page-editor-chrome/FieldEditedIndicators.tsx +35 -0
  175. package/src/editor/page-editor-chrome/FrameMenu.tsx +338 -0
  176. package/src/editor/page-editor-chrome/FrameMenus.tsx +48 -0
  177. package/src/editor/page-editor-chrome/InlineEditor.tsx +765 -0
  178. package/src/editor/page-editor-chrome/LockedFieldIndicator.tsx +61 -0
  179. package/src/editor/page-editor-chrome/NoLayout.tsx +36 -0
  180. package/src/editor/page-editor-chrome/PageEditorChrome.tsx +122 -0
  181. package/src/editor/page-editor-chrome/PictureEditorOverlay.tsx +161 -0
  182. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +169 -0
  183. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +315 -0
  184. package/src/editor/page-editor-chrome/SuggestionHighlighting.tsx +300 -0
  185. package/src/editor/page-editor-chrome/SuggestionHighlightings.tsx +40 -0
  186. package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +828 -0
  187. package/src/editor/page-viewer/DeviceToolbar.tsx +70 -0
  188. package/src/editor/page-viewer/EditorForm.tsx +262 -0
  189. package/src/editor/page-viewer/MiniMap.tsx +362 -0
  190. package/src/editor/page-viewer/PageViewer.tsx +169 -0
  191. package/src/editor/page-viewer/PageViewerFrame.tsx +1022 -0
  192. package/src/editor/page-viewer/pageModelSkeletonBuilder.ts +412 -0
  193. package/src/editor/page-viewer/pageViewContext.ts +186 -0
  194. package/src/editor/pageModel.ts +220 -0
  195. package/src/editor/picture-shared.tsx +53 -0
  196. package/src/editor/reviews/Comment.tsx +308 -0
  197. package/src/editor/reviews/Comments.tsx +125 -0
  198. package/src/editor/reviews/DiffView.tsx +109 -0
  199. package/src/editor/reviews/PreviewInfo.tsx +35 -0
  200. package/src/editor/reviews/Reviews.tsx +280 -0
  201. package/src/editor/reviews/SuggestedEdit.tsx +316 -0
  202. package/src/editor/reviews/reviewCommands.tsx +47 -0
  203. package/src/editor/reviews/useReviews.tsx +70 -0
  204. package/src/editor/services/aiService.ts +173 -0
  205. package/src/editor/services/componentDesignerService.ts +151 -0
  206. package/src/editor/services/contentService.ts +180 -0
  207. package/src/editor/services/editService.ts +488 -0
  208. package/src/editor/services/indexService.ts +24 -0
  209. package/src/editor/services/reviewsService.ts +53 -0
  210. package/src/editor/services/serviceHelper.ts +95 -0
  211. package/src/editor/services/suggestedEditsService.ts +39 -0
  212. package/src/editor/services/systemService.ts +5 -0
  213. package/src/editor/services/translationService.ts +21 -0
  214. package/src/editor/services-server/api.ts +150 -0
  215. package/src/editor/services-server/graphQL.ts +106 -0
  216. package/src/editor/sidebar/ComponentPalette.tsx +161 -0
  217. package/src/editor/sidebar/ComponentTree.tsx +549 -0
  218. package/src/editor/sidebar/Debug.tsx +111 -0
  219. package/src/editor/sidebar/DictionaryEditor.tsx +261 -0
  220. package/src/editor/sidebar/EditHistory.tsx +134 -0
  221. package/src/editor/sidebar/GraphQL.tsx +164 -0
  222. package/src/editor/sidebar/Insert.tsx +35 -0
  223. package/src/editor/sidebar/MainContentTree.tsx +102 -0
  224. package/src/editor/sidebar/Performance.tsx +53 -0
  225. package/src/editor/sidebar/Sessions.tsx +35 -0
  226. package/src/editor/sidebar/Sidebar.tsx +20 -0
  227. package/src/editor/sidebar/SidebarView.tsx +152 -0
  228. package/src/editor/sidebar/Translations.tsx +295 -0
  229. package/src/editor/sidebar/Validation.tsx +102 -0
  230. package/src/editor/sidebar/ViewSelector.tsx +60 -0
  231. package/src/editor/sidebar/Workbox.tsx +209 -0
  232. package/src/editor/ui/CenteredMessage.tsx +7 -0
  233. package/src/editor/ui/CopyMoveTargetSelectorDialog.tsx +81 -0
  234. package/src/editor/ui/CopyToClipboardButton.tsx +24 -0
  235. package/src/editor/ui/DialogButtons.tsx +11 -0
  236. package/src/editor/ui/Icons.tsx +709 -0
  237. package/src/editor/ui/ItemList.tsx +76 -0
  238. package/src/editor/ui/ItemNameDialogNew.tsx +118 -0
  239. package/src/editor/ui/ItemSearch.tsx +159 -0
  240. package/src/editor/ui/PerfectTree.tsx +676 -0
  241. package/src/editor/ui/Section.tsx +35 -0
  242. package/src/editor/ui/SimpleIconButton.tsx +54 -0
  243. package/src/editor/ui/SimpleMenu.tsx +40 -0
  244. package/src/editor/ui/SimpleTable.tsx +60 -0
  245. package/src/editor/ui/SimpleTabs.tsx +60 -0
  246. package/src/editor/ui/SimpleToolbar.tsx +7 -0
  247. package/src/editor/ui/Spinner.tsx +9 -0
  248. package/src/editor/ui/Splitter.tsx +420 -0
  249. package/src/editor/ui/StackedPanels.tsx +134 -0
  250. package/src/editor/ui/Toolbar.tsx +7 -0
  251. package/src/editor/utils/id-helper.ts +3 -0
  252. package/src/editor/utils/insertOptions.ts +69 -0
  253. package/src/editor/utils/itemutils.ts +29 -0
  254. package/src/editor/utils/useMemoDebug.ts +28 -0
  255. package/src/editor/utils.ts +486 -0
  256. package/src/editor/views/CompareView.tsx +245 -0
  257. package/src/editor/views/EditView.tsx +27 -0
  258. package/src/editor/views/ItemEditor.tsx +58 -0
  259. package/src/editor/views/MediaFolderEditView.tsx +66 -0
  260. package/src/editor/views/SingleEditView.tsx +57 -0
  261. package/src/fonts/Geist-Black.woff2 +0 -0
  262. package/src/fonts/Geist-Bold.woff2 +0 -0
  263. package/src/fonts/Geist-ExtraBold.woff2 +0 -0
  264. package/src/fonts/Geist-ExtraLight.woff2 +0 -0
  265. package/src/fonts/Geist-Light.woff2 +0 -0
  266. package/src/fonts/Geist-Medium.woff2 +0 -0
  267. package/src/fonts/Geist-Regular.woff2 +0 -0
  268. package/src/fonts/Geist-SemiBold.woff2 +0 -0
  269. package/src/fonts/Geist-Thin.woff2 +0 -0
  270. package/src/fonts/Geist[wght].woff2 +0 -0
  271. package/src/fonts/index.ts +10 -0
  272. package/src/index.ts +23 -0
  273. package/src/lib/safelist.tsx +16 -0
  274. package/src/lib/utils.ts +6 -0
  275. package/src/page-wizard/PageWizard.tsx +139 -0
  276. package/src/page-wizard/WizardBox.tsx +4 -0
  277. package/src/page-wizard/WizardBoxConnector.tsx +56 -0
  278. package/src/page-wizard/WizardSteps.tsx +458 -0
  279. package/src/page-wizard/service.ts +35 -0
  280. package/src/page-wizard/startPageWizardCommand.ts +26 -0
  281. package/src/page-wizard/steps/BuildPageStep.tsx +259 -0
  282. package/src/page-wizard/steps/CollectStep.tsx +296 -0
  283. package/src/page-wizard/steps/ComponentTypesSelector.tsx +454 -0
  284. package/src/page-wizard/steps/Components.tsx +193 -0
  285. package/src/page-wizard/steps/ContentStep.tsx +890 -0
  286. package/src/page-wizard/steps/EditButton.tsx +34 -0
  287. package/src/page-wizard/steps/FieldEditor.tsx +102 -0
  288. package/src/page-wizard/steps/Generate.tsx +60 -0
  289. package/src/page-wizard/steps/ImagesStep.tsx +382 -0
  290. package/src/page-wizard/steps/LayoutStep.tsx +227 -0
  291. package/src/page-wizard/steps/MetaDataStep.tsx +173 -0
  292. package/src/page-wizard/steps/SelectStep.tsx +281 -0
  293. package/src/page-wizard/steps/schema.ts +180 -0
  294. package/src/page-wizard/steps/usePageCreator.ts +325 -0
  295. package/src/page-wizard/usePageWizard.ts +79 -0
  296. package/src/revision.ts +2 -0
  297. package/src/splash-screen/NewPage.tsx +294 -0
  298. package/src/splash-screen/OpenPage.tsx +113 -0
  299. package/src/splash-screen/RecentPages.tsx +123 -0
  300. package/src/splash-screen/SectionHeadline.tsx +21 -0
  301. package/src/splash-screen/SplashScreen.tsx +195 -0
  302. package/src/tour/Tour.tsx +566 -0
  303. package/src/tour/default-tour.tsx +301 -0
  304. package/src/tour/preview-tour.tsx +128 -0
  305. package/src/types.ts +335 -0
  306. package/styles.css +765 -0
  307. package/tsconfig.build.json +31 -0
  308. package/tsconfig.json +14 -0
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,20 +1,14 @@
1
1
  {
2
2
  "name": "@alpaca-editor/core",
3
- "version": "1.0.3942",
3
+ "version": "1.0.3944",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "exports": {
8
- ".": "./dist/index.js",
8
+ ".": "./src/index.ts",
9
9
  "./styles.css": "./dist/styles.css",
10
10
  "./dev-styles.css": "./dev.css"
11
11
  },
12
- "main": "./dist/index.js",
13
- "types": "./dist/index.d.ts",
14
- "files": [
15
- "dist/**/*",
16
- "dev.css"
17
- ],
18
12
  "type": "module",
19
13
  "scripts": {
20
14
  "build": "npx @tailwindcss/cli -i ./build.css -o ./dist/styles.css && copyfiles -u 0 \"images/**/*\" dist && tsc -p tsconfig.build.json",
@@ -0,0 +1,6 @@
1
+ export function selectComponents(componentIds: string[]) {
2
+ window.top?.window.postMessage(
3
+ { componentIds, type: "componentsSelected" },
4
+ "*"
5
+ );
6
+ }
@@ -0,0 +1,19 @@
1
+ export { useEditContext } from "../editor/client/editContext";
2
+ export { selectComponents } from "./api";
3
+ export { getDefaultTourSteps } from "../tour/default-tour";
4
+ export * from "../editor/field-types/DropLinkEditor";
5
+ export * from "../editor/field-types/TreeListEditor";
6
+ export * from "../editor/field-types/DropListEditor";
7
+ export * from "../editor/field-types/AttachmentEditor";
8
+ export * from "../editor/field-types/CheckboxEditor";
9
+ export * from "../editor/field-types/LinkFieldEditor";
10
+ export * from "../editor/field-types/PictureFieldEditor";
11
+ export * from "../editor/field-types/RichTextEditor";
12
+ export * from "../editor/field-types/SingleLineText";
13
+ export * from "../editor/field-types/MultiLineText";
14
+ export * from "../editor/field-types/RawEditor";
15
+ export * from "../editor/field-types/RichTextEditor";
16
+ export * from "../editor/field-types/InternalLinkFieldEditor";
17
+
18
+
19
+
@@ -0,0 +1,50 @@
1
+ import { classNames } from "primereact/utils";
2
+ import React from "react";
3
+ import { Button } from "./ui/button";
4
+
5
+ interface ActionButtonProps {
6
+ isLoading?: boolean;
7
+ onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
8
+ disabled?: boolean;
9
+ loadingText?: string;
10
+ children: React.ReactNode;
11
+ type?: "button" | "submit" | "reset";
12
+ className?: string;
13
+ variant?:
14
+ | "default"
15
+ | "secondary"
16
+ | "destructive"
17
+ | "outline"
18
+ | "ghost"
19
+ | "link";
20
+ }
21
+
22
+ export const ActionButton: React.FC<ActionButtonProps> = ({
23
+ isLoading,
24
+ onClick,
25
+ disabled = false,
26
+ loadingText = "Loading...",
27
+ children,
28
+ type = "button",
29
+ className = "",
30
+ variant = "default",
31
+ }) => {
32
+ return (
33
+ <Button
34
+ type={type}
35
+ onClick={onClick}
36
+ disabled={disabled || isLoading}
37
+ className={className}
38
+ variant={variant}
39
+ >
40
+ {isLoading ? (
41
+ <div className="flex items-center justify-center gap-2">
42
+ <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent"></div>
43
+ <div>{loadingText}</div>
44
+ </div>
45
+ ) : (
46
+ children
47
+ )}
48
+ </Button>
49
+ );
50
+ };
@@ -0,0 +1,57 @@
1
+ "use client";
2
+
3
+ import { EditContextType } from "../editor/client/editContext";
4
+ import { Component } from "../editor/pageModel";
5
+
6
+ export function ErrorFallback() {
7
+ // Call resetErrorBoundary() to reset the error boundary and retry the render.
8
+
9
+ return (
10
+ <div role="alert">
11
+ <p>Something went wrong.</p>
12
+ </div>
13
+ );
14
+ }
15
+
16
+ export function ErrorFallbackWithDetails({
17
+ error,
18
+ component,
19
+ editContext,
20
+ }: {
21
+ error: Error;
22
+ component: Component;
23
+ editContext?: EditContextType;
24
+ }) {
25
+ // Call resetErrorBoundary() to reset the error boundary and retry the render.
26
+
27
+ return (
28
+ <div
29
+ role="alert"
30
+ className="cursor-pointer"
31
+ onClick={(ev) => {
32
+ if (!editContext) return;
33
+ ev.stopPropagation();
34
+ ev.preventDefault();
35
+ editContext.select([component.id]);
36
+ if (!editContext.configuration.editor.views) return;
37
+ if (component.rendering) editContext.switchView("component-designer");
38
+ }}
39
+ >
40
+ <div className="text-xs bg-gray-100 p-3">
41
+ <div className="font-bold mb-1">Something went wrong</div>
42
+ <div>Component id: {component.id}</div>
43
+ <div>Component type: {component.type}</div>
44
+ {component.rendering && (
45
+ <div>Rendering id: {component.rendering.id}</div>
46
+ )}
47
+ <pre className="overflow-x-auto text-red-500 py-2">
48
+ {error.message} {error.stack}
49
+ </pre>
50
+ </div>
51
+ </div>
52
+ );
53
+ }
54
+
55
+ export async function AsyncComponent() {
56
+ return <ErrorFallback />;
57
+ }
@@ -0,0 +1,56 @@
1
+ import { cn } from "../../lib/utils";
2
+
3
+ export function CardConnector({
4
+ className,
5
+ direction,
6
+ }: {
7
+ className?: string;
8
+ direction?: "horizontal" | "vertical";
9
+ }) {
10
+ return (
11
+ <>
12
+ <div
13
+ className={cn(
14
+ "mt-[-3px] mb-[-3px] flex items-center justify-center",
15
+ className,
16
+ (!direction || direction === "horizontal") && "md:hidden",
17
+ )}
18
+ >
19
+ <svg
20
+ width="40"
21
+ height="31"
22
+ viewBox="0 0 40 31"
23
+ fill="none"
24
+ xmlns="http://www.w3.org/2000/svg"
25
+ >
26
+ <path
27
+ d="M40 3.04199C33.8405 3.55018 29 8.70936 29 15C29 21.2906 33.8405 26.4498 40 26.958L40 31L-1.35505e-06 31L-1.18021e-06 27C6.62741 27 12 21.6274 12 15C12 8.37258 6.62741 3 -1.31134e-07 3L0 -1.74846e-06L40 0L40 3.04199Z"
28
+ fill="white"
29
+ />
30
+ </svg>
31
+ </div>
32
+
33
+ <div
34
+ className={cn(
35
+ "mt-6 mr-[-3px] ml-[-3px] hidden",
36
+ className,
37
+ (!direction || direction === "horizontal") && "md:block",
38
+ )}
39
+ >
40
+ <svg
41
+ className={className}
42
+ width="31"
43
+ height="40"
44
+ viewBox="0 0 31 40"
45
+ fill="none"
46
+ xmlns="http://www.w3.org/2000/svg"
47
+ >
48
+ <path
49
+ d="M3.04199 0C3.55018 6.15949 8.70936 11 15 11C21.2906 11 26.4498 6.1595 26.958 0H31V40H27C27 33.3726 21.6274 28 15 28C8.37258 28 3 33.3726 3 40H0V0H3.04199Z"
50
+ fill="white"
51
+ />
52
+ </svg>
53
+ </div>
54
+ </>
55
+ );
56
+ }
@@ -0,0 +1,62 @@
1
+ import * as React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+
5
+ import { cn } from "../../lib/utils";
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ "bg-theme-secondary text-primary-foreground shadow-xs hover:bg-theme-secondary/80",
14
+ destructive:
15
+ "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
16
+ outline:
17
+ "border bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
18
+ secondary:
19
+ "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
20
+ ghost:
21
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
22
+ link: "text-primary underline-offset-4 hover:underline",
23
+ },
24
+ size: {
25
+ default: "h-8 px-7 py-5 has-[>svg]:px-3 md:text-sm text-xs",
26
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
27
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28
+ icon: "size-9",
29
+ },
30
+ },
31
+ defaultVariants: {
32
+ variant: "default",
33
+ size: "default",
34
+ },
35
+ },
36
+ );
37
+
38
+ function Button({
39
+ className,
40
+ variant,
41
+ size,
42
+ asChild = false,
43
+ ...props
44
+ }: React.ComponentProps<"button"> &
45
+ VariantProps<typeof buttonVariants> & {
46
+ asChild?: boolean;
47
+ }) {
48
+ const Comp = asChild ? Slot : "button";
49
+
50
+ return (
51
+ <Comp
52
+ data-slot="button"
53
+ className={cn(
54
+ "cursor-pointer",
55
+ buttonVariants({ variant, size, className }),
56
+ )}
57
+ {...props}
58
+ />
59
+ );
60
+ }
61
+
62
+ export { Button, buttonVariants };
@@ -0,0 +1,372 @@
1
+ import { cn } from "../../lib/utils";
2
+ import { useState, useEffect } from "react";
3
+ import { Expand, Shrink } from "lucide-react";
4
+
5
+ /**
6
+ * A reusable card component with header (icon, title, description) and content area.
7
+ * Originally created for the page wizard but now available as a generic UI component.
8
+ */
9
+ export function Card({
10
+ children,
11
+ icon,
12
+ title,
13
+ description,
14
+ className,
15
+ noPadding,
16
+ collapsible = "no",
17
+ defaultCollapsed = "no",
18
+ summary,
19
+ footer,
20
+ showFullscreenButton = false,
21
+ onFullscreen,
22
+ }: {
23
+ children: React.ReactNode;
24
+ icon: React.ReactNode;
25
+ title: string;
26
+ description: string;
27
+ className?: string;
28
+ noPadding?: boolean;
29
+ collapsible?: "yes" | "no" | "mobileOnly";
30
+ defaultCollapsed?: "yes" | "no" | "mobileOnly";
31
+ summary?: React.ReactNode;
32
+ footer?: React.ReactNode;
33
+ showFullscreenButton?: boolean;
34
+ onFullscreen?: () => void;
35
+ }) {
36
+ const [isExpanded, setIsExpanded] = useState(() => {
37
+ if (defaultCollapsed === "yes") return false; // Starts collapsed
38
+ if (defaultCollapsed === "no") return true; // Starts expanded
39
+ if (defaultCollapsed === "mobileOnly") return false; // Starts collapsed on mobile, but we'll handle desktop separately
40
+ return true; // Default
41
+ });
42
+
43
+ const [isFullscreen, setIsFullscreen] = useState(false);
44
+
45
+ const isCollapsibleEnabled = collapsible !== "no";
46
+
47
+ // Prevent body scroll when fullscreen is active
48
+ useEffect(() => {
49
+ if (isFullscreen) {
50
+ document.body.style.overflow = "hidden";
51
+ return () => {
52
+ document.body.style.overflow = "";
53
+ };
54
+ }
55
+ }, [isFullscreen]);
56
+
57
+ // Check if collapsible behavior should be active (considering mobile-only options)
58
+ const isCollapsibleActive = () => {
59
+ if (collapsible === "no") return false;
60
+ if (collapsible === "mobileOnly") {
61
+ // Only collapsible on mobile - we'll handle this with CSS classes
62
+ return true;
63
+ }
64
+ return true; // For "yes"
65
+ };
66
+
67
+ // Determine what content to show based on collapsible state
68
+ const getContentToShow = () => {
69
+ if (!isCollapsibleEnabled) return children;
70
+
71
+ return isExpanded ? children : summary;
72
+ };
73
+
74
+ const shouldShowContent = () => {
75
+ if (!isCollapsibleEnabled) return true;
76
+
77
+ // Always show content area if we have either main content or summary
78
+ if (!isExpanded && summary) return true;
79
+ if (isExpanded) return true;
80
+
81
+ return false;
82
+ };
83
+
84
+ const toggleExpanded = () => {
85
+ if (isCollapsibleActive()) {
86
+ setIsExpanded(!isExpanded);
87
+ }
88
+ };
89
+
90
+ const handleFullscreen = () => {
91
+ setIsFullscreen(true);
92
+ onFullscreen?.();
93
+ };
94
+
95
+ const handleExitFullscreen = () => {
96
+ setIsFullscreen(false);
97
+ };
98
+
99
+ return (
100
+ <>
101
+ {/* Blurred background overlay - only visible in fullscreen */}
102
+ {isFullscreen && (
103
+ <div
104
+ className="fixed inset-0 z-40 bg-black/20 backdrop-blur-sm md:hidden"
105
+ onClick={handleExitFullscreen}
106
+ />
107
+ )}
108
+
109
+ <div
110
+ className={cn(
111
+ "flex flex-col rounded-lg bg-white transition-all duration-300 ease-in-out",
112
+ className,
113
+ isFullscreen && [
114
+ // Fullscreen styles - only on mobile
115
+ "fixed inset-0 z-50 mx-0 mt-[30px] h-[calc(100vh-60px)] shadow-xl md:relative md:inset-auto md:mx-auto md:mt-0 md:h-auto md:shadow-none",
116
+ ],
117
+ )}
118
+ >
119
+ <div
120
+ className={cn(
121
+ "flex flex-col justify-between gap-1 p-4 pb-2 md:p-6 md:pb-4",
122
+ isCollapsibleEnabled && "cursor-pointer",
123
+ )}
124
+ onClick={isCollapsibleEnabled ? toggleExpanded : undefined}
125
+ >
126
+ <div className="flex items-center justify-between gap-2">
127
+ <div className="flex items-center gap-2">
128
+ <div className="text-theme-secondary flex h-4 w-4 items-center justify-center rounded-full">
129
+ {icon}
130
+ </div>
131
+ <div className="text-base font-bold text-neutral-800">
132
+ {title}
133
+ </div>
134
+ </div>
135
+ <div className="flex items-center gap-2">
136
+ {/* Fullscreen button - only on mobile */}
137
+ {showFullscreenButton && (
138
+ <button
139
+ onClick={handleFullscreen}
140
+ className={cn(
141
+ "flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden",
142
+ isFullscreen && "hidden",
143
+ )}
144
+ aria-label="Open fullscreen"
145
+ >
146
+ <Expand className="h-4 w-4" />
147
+ </button>
148
+ )}
149
+
150
+ {/* Exit fullscreen button - only visible in fullscreen */}
151
+ {showFullscreenButton && isFullscreen && (
152
+ <button
153
+ onClick={handleExitFullscreen}
154
+ className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
155
+ aria-label="Exit fullscreen"
156
+ >
157
+ <Shrink className="h-4 w-4" />
158
+ </button>
159
+ )}
160
+
161
+ {/* Show toggle in header when no summary is provided */}
162
+ {isCollapsibleEnabled && !summary && (
163
+ <>
164
+ {collapsible === "yes" && (
165
+ <button
166
+ onClick={toggleExpanded}
167
+ className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700"
168
+ aria-label={isExpanded ? "Collapse" : "Expand"}
169
+ >
170
+ <svg
171
+ className={cn(
172
+ "h-4 w-4 transition-transform duration-200",
173
+ isExpanded ? "rotate-180" : "rotate-0",
174
+ )}
175
+ fill="none"
176
+ stroke="currentColor"
177
+ viewBox="0 0 24 24"
178
+ >
179
+ <path
180
+ strokeLinecap="round"
181
+ strokeLinejoin="round"
182
+ strokeWidth={2}
183
+ d="M19 9l-7 7-7-7"
184
+ />
185
+ </svg>
186
+ </button>
187
+ )}
188
+ {collapsible === "mobileOnly" && (
189
+ <button
190
+ onClick={toggleExpanded}
191
+ className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
192
+ aria-label={isExpanded ? "Collapse" : "Expand"}
193
+ >
194
+ <svg
195
+ className={cn(
196
+ "h-4 w-4 transition-transform duration-200",
197
+ isExpanded ? "rotate-180" : "rotate-0",
198
+ )}
199
+ fill="none"
200
+ stroke="currentColor"
201
+ viewBox="0 0 24 24"
202
+ >
203
+ <path
204
+ strokeLinecap="round"
205
+ strokeLinejoin="round"
206
+ strokeWidth={2}
207
+ d="M19 9l-7 7-7-7"
208
+ />
209
+ </svg>
210
+ </button>
211
+ )}
212
+ </>
213
+ )}
214
+ </div>
215
+ </div>
216
+ <div className="mb-1 text-xs text-neutral-500">{description}</div>
217
+ </div>
218
+
219
+ {shouldShowContent() && (
220
+ <div
221
+ className={cn(
222
+ "flex-1 transition-all duration-300 ease-in-out",
223
+ noPadding ? "" : "p-4 pt-0 md:p-6 md:pt-0",
224
+ isFullscreen && "overflow-hidden",
225
+ // Handle responsive behavior for mobile-only collapsible options
226
+ collapsible === "mobileOnly" &&
227
+ !isExpanded &&
228
+ summary &&
229
+ "block md:hidden",
230
+ collapsible === "mobileOnly" && isExpanded && "block",
231
+ className,
232
+ )}
233
+ >
234
+ {!isExpanded && summary && isCollapsibleEnabled ? (
235
+ <div className="flex items-start justify-between gap-2">
236
+ <div className="flex-1 cursor-pointer" onClick={toggleExpanded}>
237
+ {summary}
238
+ </div>
239
+ {/* Show toggle button next to summary when summary exists */}
240
+ {collapsible === "yes" && (
241
+ <button
242
+ onClick={toggleExpanded}
243
+ className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700"
244
+ aria-label="Expand"
245
+ >
246
+ <svg
247
+ className="h-4 w-4 rotate-0 transition-transform duration-200"
248
+ fill="none"
249
+ stroke="currentColor"
250
+ viewBox="0 0 24 24"
251
+ >
252
+ <path
253
+ strokeLinecap="round"
254
+ strokeLinejoin="round"
255
+ strokeWidth={2}
256
+ d="M19 9l-7 7-7-7"
257
+ />
258
+ </svg>
259
+ </button>
260
+ )}
261
+ {collapsible === "mobileOnly" && (
262
+ <button
263
+ onClick={toggleExpanded}
264
+ className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
265
+ aria-label="Expand"
266
+ >
267
+ <svg
268
+ className="h-4 w-4 rotate-0 transition-transform duration-200"
269
+ fill="none"
270
+ stroke="currentColor"
271
+ viewBox="0 0 24 24"
272
+ >
273
+ <path
274
+ strokeLinecap="round"
275
+ strokeLinejoin="round"
276
+ strokeWidth={2}
277
+ d="M19 9l-7 7-7-7"
278
+ />
279
+ </svg>
280
+ </button>
281
+ )}
282
+ </div>
283
+ ) : (
284
+ <>
285
+ {isExpanded && isCollapsibleEnabled && summary ? (
286
+ <>
287
+ {/* Show summary with toggle button */}
288
+ <div className="mb-4 flex items-start justify-between gap-2">
289
+ <div
290
+ className="flex-1 cursor-pointer"
291
+ onClick={toggleExpanded}
292
+ >
293
+ {summary}
294
+ </div>
295
+ {/* Show toggle button next to summary */}
296
+ {collapsible === "yes" && (
297
+ <button
298
+ onClick={toggleExpanded}
299
+ className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700"
300
+ aria-label="Collapse"
301
+ >
302
+ <svg
303
+ className="h-4 w-4 rotate-180 transition-transform duration-200"
304
+ fill="none"
305
+ stroke="currentColor"
306
+ viewBox="0 0 24 24"
307
+ >
308
+ <path
309
+ strokeLinecap="round"
310
+ strokeLinejoin="round"
311
+ strokeWidth={2}
312
+ d="M19 9l-7 7-7-7"
313
+ />
314
+ </svg>
315
+ </button>
316
+ )}
317
+ {collapsible === "mobileOnly" && (
318
+ <button
319
+ onClick={toggleExpanded}
320
+ className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
321
+ aria-label="Collapse"
322
+ >
323
+ <svg
324
+ className="h-4 w-4 rotate-180 transition-transform duration-200"
325
+ fill="none"
326
+ stroke="currentColor"
327
+ viewBox="0 0 24 24"
328
+ >
329
+ <path
330
+ strokeLinecap="round"
331
+ strokeLinejoin="round"
332
+ strokeWidth={2}
333
+ d="M19 9l-7 7-7-7"
334
+ />
335
+ </svg>
336
+ </button>
337
+ )}
338
+ </div>
339
+ {/* Show full content below summary */}
340
+ <div>{children}</div>
341
+ </>
342
+ ) : (
343
+ getContentToShow()
344
+ )}
345
+ </>
346
+ )}
347
+ </div>
348
+ )}
349
+
350
+ {/* Show full content on desktop when using mobile-only collapsible options */}
351
+ {collapsible === "mobileOnly" && (
352
+ <div
353
+ className={cn(
354
+ "hidden flex-1 transition-all duration-300 ease-in-out md:block",
355
+ noPadding ? "" : "p-4 pt-0 md:p-6",
356
+ className,
357
+ )}
358
+ >
359
+ {children}
360
+ </div>
361
+ )}
362
+
363
+ {/* Footer - always displayed regardless of collapsed state */}
364
+ {footer && (
365
+ <div className="border-t border-gray-100 p-4 pt-0 md:p-6 md:pt-0">
366
+ {footer}
367
+ </div>
368
+ )}
369
+ </div>
370
+ </>
371
+ );
372
+ }