@alpaca-editor/core 1.0.3898 → 1.0.3899

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 (43) hide show
  1. package/dist/components/ui/CardConnector.d.ts +3 -0
  2. package/dist/components/ui/CardConnector.js +6 -0
  3. package/dist/components/ui/CardConnector.js.map +1 -0
  4. package/dist/components/ui/card.d.ts +12 -0
  5. package/dist/components/ui/card.js +10 -0
  6. package/dist/components/ui/card.js.map +1 -0
  7. package/dist/editor/MobileLayout.js +15 -4
  8. package/dist/editor/MobileLayout.js.map +1 -1
  9. package/dist/editor/sidebar/SidebarView.js +14 -14
  10. package/dist/editor/sidebar/SidebarView.js.map +1 -1
  11. package/dist/editor/ui/SimpleTabs.js +1 -1
  12. package/dist/editor/ui/SimpleTabs.js.map +1 -1
  13. package/dist/editor/ui/Splitter.d.ts +1 -0
  14. package/dist/editor/ui/Splitter.js +119 -58
  15. package/dist/editor/ui/Splitter.js.map +1 -1
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +1 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/page-wizard/WizardBox.d.ts +2 -8
  20. package/dist/page-wizard/WizardBox.js +3 -5
  21. package/dist/page-wizard/WizardBox.js.map +1 -1
  22. package/dist/page-wizard/steps/CollectStep.js +9 -9
  23. package/dist/page-wizard/steps/CollectStep.js.map +1 -1
  24. package/dist/revision.d.ts +2 -2
  25. package/dist/revision.js +2 -2
  26. package/dist/splash-screen/NewPage.js +12 -11
  27. package/dist/splash-screen/NewPage.js.map +1 -1
  28. package/dist/splash-screen/SplashScreen.js +8 -7
  29. package/dist/splash-screen/SplashScreen.js.map +1 -1
  30. package/dist/styles.css +72 -18
  31. package/package.json +1 -1
  32. package/src/components/ui/CardConnector.tsx +21 -0
  33. package/src/components/ui/card.tsx +44 -0
  34. package/src/editor/MobileLayout.tsx +20 -7
  35. package/src/editor/sidebar/SidebarView.tsx +46 -44
  36. package/src/editor/ui/SimpleTabs.tsx +1 -1
  37. package/src/editor/ui/Splitter.tsx +152 -80
  38. package/src/index.ts +2 -0
  39. package/src/page-wizard/WizardBox.tsx +3 -39
  40. package/src/page-wizard/steps/CollectStep.tsx +8 -9
  41. package/src/revision.ts +2 -2
  42. package/src/splash-screen/NewPage.tsx +107 -80
  43. package/src/splash-screen/SplashScreen.tsx +49 -33
@@ -1,5 +1,6 @@
1
1
  import React, { useState, useRef, useEffect, useCallback } from "react";
2
2
  import { flushSync } from "react-dom";
3
+
3
4
  export type SplitterPanel = {
4
5
  defaultSize: number | "auto";
5
6
  name: string;
@@ -13,6 +14,7 @@ interface SplitterProps {
13
14
  localStorageKey?: string;
14
15
  expandLabel?: React.ReactNode;
15
16
  growablePanelIndex?: number; // Index of the panel that grows/shrinks
17
+ direction?: "horizontal" | "vertical"; // New prop for direction
16
18
  }
17
19
 
18
20
  type StoredSizes = { panels: PanelSizes; lastCollapsed: boolean };
@@ -22,6 +24,7 @@ export const Splitter: React.FC<SplitterProps> = ({
22
24
  panels,
23
25
  localStorageKey = "splitter-sizes",
24
26
  expandLabel = "Expand",
27
+ direction = "horizontal", // Default to horizontal for backward compatibility
25
28
  }) => {
26
29
  const totalPanels = panels.length;
27
30
 
@@ -86,79 +89,6 @@ export const Splitter: React.FC<SplitterProps> = ({
86
89
  }
87
90
  };
88
91
 
89
- const handleResize = useCallback(
90
- (index: number, event: React.MouseEvent<HTMLDivElement>) => {
91
- event.preventDefault();
92
-
93
- const iframes = splitterRef.current?.querySelectorAll("iframe");
94
- iframes?.forEach((iframe) => {
95
- iframe.classList.add("pointer-events-none");
96
- });
97
-
98
- const startX = event.clientX;
99
- // create a copy with the panel name
100
- const initialSizes = panelSizes ? { ...panelSizes } : {};
101
-
102
- const panelElement = panelRefs.current[index];
103
- const nextPanelElement = panelRefs.current[index + 1];
104
-
105
- if (!panelElement || !nextPanelElement || !splitterRef.current) {
106
- return;
107
- }
108
-
109
- const panelWidth = panelElement.offsetWidth;
110
- const nextPanelWidth = nextPanelElement.offsetWidth;
111
-
112
- setIsResizing(true);
113
-
114
- const onMouseMove = (moveEvent: MouseEvent) => {
115
- const delta = moveEvent.clientX - startX;
116
- const newPanelWidth = panelWidth + delta;
117
- const newNextPanelWidth = nextPanelWidth - delta;
118
-
119
- const minPanelWidth = 50;
120
- const minNextPanelWidth = 50;
121
-
122
- if (
123
- newNextPanelWidth < minPanelWidth &&
124
- index == panels.length - 2 &&
125
- lastPanelCollapsible
126
- ) {
127
- setIsLastPanelCollapsed(true);
128
- setPanelSizes(initialSizes);
129
- }
130
-
131
- if (
132
- newPanelWidth < minPanelWidth ||
133
- newNextPanelWidth < minNextPanelWidth
134
- ) {
135
- return;
136
- }
137
-
138
- const updatedSizes: PanelSizes = { ...initialSizes };
139
- updatedSizes[panels[index]!.name] = newPanelWidth;
140
- updatedSizes[panels[index + 1]!.name] = newNextPanelWidth;
141
- setPanelSizes(updatedSizes);
142
- };
143
-
144
- const onMouseUp = () => {
145
- setTimeout(() => {
146
- setIsResizing(false);
147
- }, 100);
148
- iframes?.forEach((iframe) => {
149
- iframe.classList.remove("pointer-events-none");
150
- });
151
-
152
- document.removeEventListener("mousemove", onMouseMove);
153
- document.removeEventListener("mouseup", onMouseUp, true);
154
- };
155
-
156
- document.addEventListener("mousemove", onMouseMove);
157
- document.addEventListener("mouseup", onMouseUp, true);
158
- },
159
- [panels, panelSizes],
160
- );
161
-
162
92
  const isLastResizer = (index: number) => index === panels.length - 2;
163
93
 
164
94
  const getFlexBasis = (index: number): string => {
@@ -182,11 +112,16 @@ export const Splitter: React.FC<SplitterProps> = ({
182
112
  };
183
113
 
184
114
  const getExpandButton = () => {
115
+ const isHorizontal = direction === "horizontal";
116
+
185
117
  return (
186
118
  <div
187
119
  onClick={!isResizing ? toggleLastPanelCollapse : undefined}
188
120
  className="flex cursor-pointer items-center justify-center bg-gray-200 p-1 text-gray-500 select-none hover:bg-blue-700 hover:text-white"
189
- style={{ writingMode: "vertical-rl", userSelect: "none" }}
121
+ style={{
122
+ writingMode: isHorizontal ? "vertical-rl" : "horizontal-tb",
123
+ userSelect: "none",
124
+ }}
190
125
  >
191
126
  {expandLabel}
192
127
  </div>
@@ -194,27 +129,162 @@ export const Splitter: React.FC<SplitterProps> = ({
194
129
  };
195
130
 
196
131
  const getSplitter = (index: number) => {
132
+ const isHorizontal = direction === "horizontal";
133
+
134
+ const handleDragStart = (
135
+ clientX: number,
136
+ clientY: number,
137
+ event: React.MouseEvent | React.TouchEvent,
138
+ ) => {
139
+ const rect = (event.target as HTMLElement).getBoundingClientRect();
140
+ const relativeY = clientY - rect.top;
141
+
142
+ event.stopPropagation();
143
+ event.preventDefault();
144
+
145
+ const isHorizontal = direction === "horizontal";
146
+ const startCoord = isHorizontal ? clientX : clientY;
147
+ const initialSizes = panelSizes ? { ...panelSizes } : {};
148
+
149
+ const panelElement = panelRefs.current[index];
150
+ const nextPanelElement = panelRefs.current[index + 1];
151
+
152
+ if (!panelElement || !nextPanelElement) {
153
+ return;
154
+ }
155
+
156
+ const panelSize = isHorizontal
157
+ ? panelElement.offsetWidth
158
+ : panelElement.offsetHeight;
159
+ const nextPanelSize = isHorizontal
160
+ ? nextPanelElement.offsetWidth
161
+ : nextPanelElement.offsetHeight;
162
+
163
+ setIsResizing(true);
164
+
165
+ // Disable pointer events on panel content during drag
166
+ const allPanels = splitterRef.current?.querySelectorAll(".relative");
167
+ allPanels?.forEach((panel) => {
168
+ (panel as HTMLElement).style.pointerEvents = "none";
169
+ // Also disable on all child elements that might capture events
170
+ const childElements = panel.querySelectorAll("*");
171
+ childElements.forEach((child) => {
172
+ (child as HTMLElement).style.pointerEvents = "none";
173
+ });
174
+ });
175
+
176
+ let isDragging = true;
177
+
178
+ const handleMove = (moveClientX: number, moveClientY: number) => {
179
+ if (!isDragging) return;
180
+
181
+ const currentCoord = isHorizontal ? moveClientX : moveClientY;
182
+ const delta = currentCoord - startCoord;
183
+ const newPanelSize = panelSize + delta;
184
+ const newNextPanelSize = nextPanelSize - delta;
185
+
186
+ const minPanelSize = 50;
187
+ if (newPanelSize < minPanelSize || newNextPanelSize < minPanelSize) {
188
+ return;
189
+ }
190
+
191
+ const updatedSizes: PanelSizes = { ...initialSizes };
192
+ updatedSizes[panels[index]!.name] = newPanelSize;
193
+ updatedSizes[panels[index + 1]!.name] = newNextPanelSize;
194
+ setPanelSizes(updatedSizes);
195
+ };
196
+
197
+ const handleEnd = () => {
198
+ isDragging = false;
199
+ setIsResizing(false);
200
+
201
+ // Re-enable pointer events on panel content
202
+ allPanels?.forEach((panel) => {
203
+ (panel as HTMLElement).style.pointerEvents = "";
204
+ // Also re-enable on all child elements
205
+ const childElements = panel.querySelectorAll("*");
206
+ childElements.forEach((child) => {
207
+ (child as HTMLElement).style.pointerEvents = "";
208
+ });
209
+ });
210
+
211
+ // Remove all event listeners
212
+ window.removeEventListener("mousemove", onMouseMove);
213
+ window.removeEventListener("mouseup", onMouseUp);
214
+ window.removeEventListener("touchmove", onTouchMove);
215
+ window.removeEventListener("touchend", onTouchEnd);
216
+ };
217
+
218
+ const onMouseMove = (moveEvent: MouseEvent) => {
219
+ handleMove(moveEvent.clientX, moveEvent.clientY);
220
+ };
221
+
222
+ const onMouseUp = () => {
223
+ handleEnd();
224
+ };
225
+
226
+ const onTouchMove = (moveEvent: TouchEvent) => {
227
+ if (moveEvent.touches.length === 1) {
228
+ const touch = moveEvent.touches[0];
229
+ if (touch) {
230
+ handleMove(touch.clientX, touch.clientY);
231
+ }
232
+ }
233
+ };
234
+
235
+ const onTouchEnd = () => {
236
+ handleEnd();
237
+ };
238
+
239
+ // Add both mouse and touch event listeners
240
+ window.addEventListener("mousemove", onMouseMove);
241
+ window.addEventListener("mouseup", onMouseUp);
242
+ window.addEventListener("touchmove", onTouchMove, { passive: false });
243
+ window.addEventListener("touchend", onTouchEnd);
244
+ };
245
+
197
246
  if (lastPanelCollapsible && isLastPanelCollapsed && isLastResizer(index)) {
198
247
  return getExpandButton();
199
248
  }
200
249
 
201
250
  return (
202
251
  <div
203
- className={
204
- "relative z-1000 flex w-[4px] cursor-ew-resize items-center justify-center bg-gray-200 select-none hover:bg-blue-700"
205
- }
252
+ className={`relative flex ${
253
+ isHorizontal
254
+ ? "h-full w-[4px] w-[12px] cursor-ew-resize md:w-[4px]"
255
+ : "h-[12px] h-[20px] w-full cursor-ns-resize md:h-[12px]"
256
+ } shrink-0 items-center justify-center bg-gray-300 select-none hover:bg-gray-400`}
257
+ style={{
258
+ touchAction: "none",
259
+ minHeight: isHorizontal ? undefined : "12px",
260
+ minWidth: isHorizontal ? "4px" : undefined,
261
+ boxSizing: "border-box",
262
+ userSelect: "none",
263
+ zIndex: 9999, // Ensure we're above any nested splitters
264
+ }}
206
265
  onDoubleClick={
207
266
  isLastResizer(index) ? toggleLastPanelCollapse : undefined
208
267
  }
209
268
  onMouseDown={(event) => {
210
- handleResize(index, event);
269
+ handleDragStart(event.clientX, event.clientY, event);
270
+ }}
271
+ onTouchStart={(event) => {
272
+ if (event.touches.length === 1) {
273
+ const touch = event.touches[0];
274
+ if (touch) {
275
+ handleDragStart(touch.clientX, touch.clientY, event);
276
+ }
277
+ }
211
278
  }}
212
279
  ></div>
213
280
  );
214
281
  };
215
282
 
216
283
  return (
217
- <div className="flex h-full w-full overflow-hidden" ref={splitterRef}>
284
+ <div
285
+ className={`flex ${direction === "horizontal" ? "flex-row" : "flex-col"} h-full w-full overflow-hidden`}
286
+ ref={splitterRef}
287
+ >
218
288
  {panels.map((panel, index) => (
219
289
  <React.Fragment key={panel.name}>
220
290
  <div
@@ -227,7 +297,8 @@ export const Splitter: React.FC<SplitterProps> = ({
227
297
  index,
228
298
  )}`,
229
299
 
230
- minWidth: 0,
300
+ minWidth: direction === "horizontal" ? 0 : undefined,
301
+ minHeight: direction === "vertical" ? 0 : undefined,
231
302
  display:
232
303
  (panel.collapsible &&
233
304
  isLastPanelCollapsed &&
@@ -241,6 +312,7 @@ export const Splitter: React.FC<SplitterProps> = ({
241
312
  </div>
242
313
  {index < panels.length - 1 &&
243
314
  !panels[index]?.hidden &&
315
+ !panels[index + 1]?.hidden &&
244
316
  getSplitter(index)}
245
317
  </React.Fragment>
246
318
  ))}
package/src/index.ts CHANGED
@@ -19,3 +19,5 @@ export { requestTranslation } from "./editor/services/translationService";
19
19
  export { defaultTranslateAll } from "./editor/commands/localizeItem/LocalizeItemUtils";
20
20
 
21
21
  export * from "./fonts";
22
+
23
+ export { Card } from "./components/ui/card";
@@ -1,40 +1,4 @@
1
- import { cn } from "../lib/utils";
1
+ import { Card } from "../components/ui/card";
2
2
 
3
- export function WizardBox({
4
- children,
5
- icon,
6
- title,
7
- description,
8
- className,
9
- noPadding,
10
- }: {
11
- children: React.ReactNode;
12
- icon: React.ReactNode;
13
- title: string;
14
- description: string;
15
- className?: string;
16
- noPadding?: boolean;
17
- }) {
18
- return (
19
- <div
20
- className={cn(
21
- "flex h-full flex-col gap-2 rounded-md bg-white",
22
- className,
23
- )}
24
- >
25
- <div className="flex flex-col justify-between gap-1 p-6 pb-2">
26
- <div className="flex items-center gap-2">
27
- <div className="text-theme-secondary flex h-4 w-4 items-center justify-center rounded-full">
28
- {icon}
29
- </div>
30
- <div className="text-base font-bold text-neutral-800">{title}</div>
31
- </div>
32
- <div className="mb-2 text-xs text-neutral-500">{description}</div>
33
- </div>
34
-
35
- <div className={cn("flex-1", noPadding ? "" : "p-6 pt-0", className)}>
36
- {children}
37
- </div>
38
- </div>
39
- );
40
- }
3
+ // Re-export Card as WizardBox for backward compatibility
4
+ export const WizardBox = Card;
@@ -7,7 +7,7 @@ import { StepComponentProps } from "../../config/types";
7
7
  import { ActionButton } from "../../components/ActionButton";
8
8
  import { UploadIcon, DocumentIcon } from "../../editor/ui/Icons";
9
9
  import { Spinner } from "../../editor/ui/Spinner";
10
- import { WizardBox } from "../WizardBox";
10
+ import { Card } from "../../components/ui/card";
11
11
  import { LinkIcon } from "lucide-react";
12
12
  import { InputTextarea } from "primereact/inputtextarea";
13
13
 
@@ -171,12 +171,13 @@ export function CollectStep({
171
171
  return (
172
172
  <div className="absolute inset-0 overflow-auto">
173
173
  <div className="grid grid-cols-2 gap-4">
174
- <WizardBox
174
+ <Card
175
175
  icon={<UploadIcon className="text-theme-secondary" />}
176
176
  title="Upload a file (optional)"
177
177
  description="Upload a file to the page"
178
178
  className="flex-1"
179
179
  >
180
+ {error && <div className="mt-2 text-sm text-red-500">{error}</div>}
180
181
  <div
181
182
  className={`flex flex-col items-center justify-center border border-dashed border-gray-300 p-8 ${
182
183
  isUploading ? "bg-gray-200" : "bg-white"
@@ -237,15 +238,13 @@ export function CollectStep({
237
238
  </div>
238
239
  </div>
239
240
  </div>
240
- </WizardBox>
241
- <WizardBox
241
+ </Card>
242
+ <Card
242
243
  icon={<LinkIcon className="text-theme-secondary" />}
243
244
  title="Scrape page from URL (optional)"
244
245
  description="Upload a file to the page"
245
246
  className="flex-1"
246
247
  >
247
- {error && <div className="mt-2 text-sm text-red-500">{error}</div>}
248
-
249
248
  <div className="flex flex-col gap-2">
250
249
  <div className="text-sm font-semibold text-gray-700">
251
250
  <div className="text-xs font-normal text-gray-500">
@@ -273,8 +272,8 @@ export function CollectStep({
273
272
  </ActionButton>
274
273
  </div>
275
274
  </div>
276
- </WizardBox>
277
- <WizardBox
275
+ </Card>
276
+ <Card
278
277
  icon={<DocumentIcon className="text-theme-secondary" />}
279
278
  title="Text"
280
279
  description="Provide the text you want to use for the page"
@@ -291,7 +290,7 @@ export function CollectStep({
291
290
  }))
292
291
  }
293
292
  />
294
- </WizardBox>
293
+ </Card>
295
294
  </div>
296
295
  </div>
297
296
  );
package/src/revision.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = "1.0.3898";
2
- export const buildDate = "2025-05-25 15:23:00";
1
+ export const version = "1.0.3899";
2
+ export const buildDate = "2025-05-26 01:54:10";
@@ -20,6 +20,8 @@ import { ItemDescriptor } from "../editor/pageModel";
20
20
  import { useDebouncedCallback } from "use-debounce";
21
21
  import { getWizards } from "../page-wizard/service";
22
22
  import { Wizard } from "../page-wizard/PageWizard";
23
+ import { Card } from "../components/ui/card";
24
+ import { CardConnector } from "../components/ui/CardConnector";
23
25
  export function NewPage({ selectedItemId }: { selectedItemId?: string }) {
24
26
  const [selectedItem, setSelectedItem] = useState<ItemDescriptor | null>(null);
25
27
  const [isValid, setIsValid] = useState<boolean>(false);
@@ -143,90 +145,115 @@ export function NewPage({ selectedItemId }: { selectedItemId?: string }) {
143
145
  };
144
146
 
145
147
  return (
146
- <div className="flex h-full gap-3">
147
- <div className="tour-pick-location flex w-1/2 flex-col">
148
- <SectionHeadline>1. Pick Location</SectionHeadline>
149
- <div className="relative flex-1">
150
- <div className="absolute inset-0 overflow-auto">
151
- <ScrollingContentTree
152
- selectedItemId={selectedItem?.id || selectedItemId}
153
- onSelectionChange={(selection) => {
154
- const selected = selection[0] as ItemTreeNodeData;
155
- if (selected) setSelectedItem(selected);
156
- }}
157
- />
148
+ <div className="flex h-full flex-col bg-gray-50 p-4 md:flex-row">
149
+ <div className="tour-pick-location flex-1">
150
+ <Card
151
+ icon={<i className="pi pi-map-marker text-sm"></i>}
152
+ title="Pick Location"
153
+ description="Select where to create your new page"
154
+ noPadding
155
+ >
156
+ <div className="relative h-full">
157
+ <div className="absolute inset-0 overflow-auto">
158
+ <ScrollingContentTree
159
+ selectedItemId={selectedItem?.id || selectedItemId}
160
+ onSelectionChange={(selection) => {
161
+ const selected = selection[0] as ItemTreeNodeData;
162
+ if (selected) setSelectedItem(selected);
163
+ }}
164
+ />
165
+ </div>
158
166
  </div>
159
- </div>
167
+ </Card>
160
168
  </div>
161
- <div className="w-1/2 border-l pl-7">
162
- <SectionHeadline className="tour-choose-template">
163
- 2. Choose a Template or Wizard
164
- </SectionHeadline>
165
- <div className="mt-1 flex min-h-12 flex-wrap gap-3">
166
- {!insertOptions?.length && (
167
- <div>No page templates available here.</div>
168
- )}
169
- {insertOptionsAndWizards?.map((option) => (
170
- <div
171
- key={option.id}
172
- onClick={() => setSelectedTemplate(option.id)}
173
- className={classNames(
174
- "mb-2 flex cursor-pointer flex-col items-center bg-gray-100 p-2 text-sm",
175
- selectedTemplate === option.id
176
- ? "tour-selected-template bg-gray-200 outline outline-2 outline-offset-2 outline-gray-200"
177
- : "bg-gray-100",
178
- )}
179
- >
180
- {
181
- <img
182
- src={getAbsoluteIconUrl(option.icon)}
183
- width="32"
184
- height="32"
185
- ></img>
186
- }
187
- {option.name}
188
- </div>
189
- ))}
169
+
170
+ {/* Card Connector - only visible when location is selected */}
171
+ {selectedItem && (
172
+ <div className="hidden items-start justify-center pt-10 md:flex">
173
+ <CardConnector />
190
174
  </div>
191
- {selectedTemplate &&
192
- wizards?.find((x) => x.id === selectedTemplate) && (
193
- <div className="mt-4">
194
- <Button
195
- onClick={launchWizard}
196
- label="Start Wizard"
197
- id="launch-wizard-button"
198
- />
199
- </div>
200
- )}
201
- {selectedTemplate &&
202
- insertOptions?.find((x) => x.id === selectedTemplate) && (
203
- <>
204
- <SectionHeadline>3. Name Your Page</SectionHeadline>
205
-
206
- <InputText
207
- className="w-full"
208
- value={name}
209
- id="new-page-name"
210
- onChange={(e) => setName(e.target.value)}
211
- onKeyDown={(ev) => {
212
- if (ev.key === "Enter" && isValid) handleOk();
213
- }}
214
- data-testid="new-page-name"
215
- />
216
- {validationMessage && (
217
- <div className="mt-2 text-red-500">{validationMessage}</div>
218
- )}
219
- <div className="mt-4">
220
- <Button
221
- onClick={handleOk}
222
- label="Create"
223
- disabled={!isValid}
224
- id="create-new-page-button"
225
- />
175
+ )}
176
+
177
+ {/* Second card - only visible when location is selected */}
178
+ {selectedItem && (
179
+ <div className="flex-1">
180
+ <Card
181
+ icon={<i className="pi pi-palette text-sm"></i>}
182
+ title="Choose Template or Wizard"
183
+ description="Select a template or wizard to create your page"
184
+ >
185
+ <div className="tour-choose-template">
186
+ <div className="flex min-h-12 flex-wrap gap-3">
187
+ {!insertOptions?.length && (
188
+ <div>No page templates available here.</div>
189
+ )}
190
+ {insertOptionsAndWizards?.map((option) => (
191
+ <div
192
+ key={option.id}
193
+ onClick={() => setSelectedTemplate(option.id)}
194
+ className={classNames(
195
+ "mb-2 flex cursor-pointer flex-col items-center rounded bg-gray-100 p-2 text-sm",
196
+ selectedTemplate === option.id
197
+ ? "tour-selected-template bg-gray-200 outline outline-2 outline-offset-2 outline-gray-200"
198
+ : "bg-gray-100",
199
+ )}
200
+ >
201
+ {
202
+ <img
203
+ src={getAbsoluteIconUrl(option.icon)}
204
+ width="32"
205
+ height="32"
206
+ ></img>
207
+ }
208
+ {option.name}
209
+ </div>
210
+ ))}
226
211
  </div>
227
- </>
228
- )}
229
- </div>
212
+ {selectedTemplate &&
213
+ wizards?.find((x) => x.id === selectedTemplate) && (
214
+ <div className="mt-4">
215
+ <Button
216
+ onClick={launchWizard}
217
+ label="Start Wizard"
218
+ id="launch-wizard-button"
219
+ />
220
+ </div>
221
+ )}
222
+ {selectedTemplate &&
223
+ insertOptions?.find((x) => x.id === selectedTemplate) && (
224
+ <div className="mt-6 border-t pt-4">
225
+ <div className="mb-3 text-base font-bold text-neutral-800">
226
+ Name Your Page
227
+ </div>
228
+ <InputText
229
+ className="w-full"
230
+ value={name}
231
+ id="new-page-name"
232
+ onChange={(e) => setName(e.target.value)}
233
+ onKeyDown={(ev) => {
234
+ if (ev.key === "Enter" && isValid) handleOk();
235
+ }}
236
+ data-testid="new-page-name"
237
+ />
238
+ {validationMessage && (
239
+ <div className="mt-2 text-red-500">
240
+ {validationMessage}
241
+ </div>
242
+ )}
243
+ <div className="mt-4">
244
+ <Button
245
+ onClick={handleOk}
246
+ label="Create"
247
+ disabled={!isValid}
248
+ id="create-new-page-button"
249
+ />
250
+ </div>
251
+ </div>
252
+ )}
253
+ </div>
254
+ </Card>
255
+ </div>
256
+ )}
230
257
  </div>
231
258
  );
232
259
  }