astro-tractstack 2.1.3 → 2.2.1

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 (128) hide show
  1. package/README.md +54 -266
  2. package/bin/create-tractstack.js +9 -6
  3. package/dist/index.js +109 -71
  4. package/package.json +4 -2
  5. package/templates/css/custom.css +5 -0
  6. package/templates/icons/code.svg +18 -0
  7. package/templates/icons/li.svg +4 -0
  8. package/templates/icons/link.svg +22 -0
  9. package/templates/icons/p.svg +3 -0
  10. package/templates/src/client/app.js +80 -1
  11. package/templates/src/components/Footer.astro +1 -1
  12. package/templates/src/components/codehooks/BunnyVideoSetup.tsx +6 -6
  13. package/templates/src/components/codehooks/EpinetDurationSelector.tsx +3 -3
  14. package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +1 -1
  15. package/templates/src/components/codehooks/ListContentSetup.tsx +2 -2
  16. package/templates/src/components/codehooks/ProductCardSetup.tsx +1 -1
  17. package/templates/src/components/codehooks/ProductGridSetup.tsx +2 -2
  18. package/templates/src/components/codehooks/SandboxRegisterForm.tsx +3 -3
  19. package/templates/src/components/compositor/Compositor.tsx +25 -9
  20. package/templates/src/components/compositor/Node.tsx +168 -496
  21. package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +1 -0
  22. package/templates/src/components/compositor/elements/SignUp.tsx +1 -1
  23. package/templates/src/components/compositor/elements/YouTubeWrapper.tsx +2 -0
  24. package/templates/src/components/compositor/nodes/CreativePane.tsx +262 -0
  25. package/templates/src/components/compositor/nodes/GhostInsertBlock.tsx +4 -6
  26. package/templates/src/components/compositor/nodes/GridLayout.tsx +4 -2
  27. package/templates/src/components/compositor/nodes/Markdown.tsx +18 -3
  28. package/templates/src/components/compositor/nodes/Pane.tsx +11 -5
  29. package/templates/src/components/compositor/nodes/RenderChildren.tsx +1 -1
  30. package/templates/src/components/compositor/nodes/tagElements/NodeAnchorComponent.tsx +5 -5
  31. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +90 -42
  32. package/templates/src/components/compositor/nodes/tagElements/NodeImg.tsx +2 -0
  33. package/templates/src/components/compositor/nodes/tagElements/NodeText.tsx +27 -1
  34. package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +10 -8
  35. package/templates/src/components/compositor/tools/NodeOverlay.tsx +224 -0
  36. package/templates/src/components/compositor/tools/PaneOverlay.tsx +122 -0
  37. package/templates/src/components/edit/Header.tsx +68 -9
  38. package/templates/src/components/edit/PanelSwitch.tsx +42 -4
  39. package/templates/src/components/edit/SettingsPanel.tsx +2 -3
  40. package/templates/src/components/edit/ToolMode.tsx +1 -31
  41. package/templates/src/components/edit/pane/AddPanePanel_break.tsx +2 -2
  42. package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +1 -1
  43. package/templates/src/components/edit/pane/AddPanePanel_new.tsx +193 -659
  44. package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +15 -82
  45. package/templates/src/components/edit/pane/AiRestylePaneModal.tsx +95 -45
  46. package/templates/src/components/edit/pane/ConfigPanePanel.tsx +137 -49
  47. package/templates/src/components/edit/pane/RestylePaneModal.tsx +1 -1
  48. package/templates/src/components/edit/pane/steps/AiCreativeDesignStep.tsx +375 -0
  49. package/templates/src/components/edit/pane/steps/AiDesignStep.tsx +1 -23
  50. package/templates/src/components/edit/pane/steps/AiLibraryCopyStep.tsx +327 -0
  51. package/templates/src/components/edit/pane/steps/AiRefineDesignStep.tsx +267 -0
  52. package/templates/src/components/edit/pane/steps/AiStandardDesignStep.tsx +371 -0
  53. package/templates/src/components/edit/pane/steps/CopyInputStep.tsx +201 -76
  54. package/templates/src/components/edit/pane/steps/CreativeInjectStep.tsx +141 -0
  55. package/templates/src/components/edit/panels/CreativeImagePanel.tsx +435 -0
  56. package/templates/src/components/edit/panels/CreativeLinkPanel.tsx +110 -0
  57. package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +1 -1
  58. package/templates/src/components/edit/panels/StyleParentPanel.tsx +118 -126
  59. package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +3 -2
  60. package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +1 -0
  61. package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +3 -1
  62. package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +3 -1
  63. package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +1 -1
  64. package/templates/src/components/edit/state/SaveModal.tsx +19 -787
  65. package/templates/src/components/edit/state/SaveToLibraryModal.tsx +2 -2
  66. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +1 -1
  67. package/templates/src/components/edit/widgets/BunnyWidget.tsx +5 -5
  68. package/templates/src/components/edit/widgets/InteractiveDisclosureWidget.tsx +1 -1
  69. package/templates/src/components/edit/widgets/SignupWidget.tsx +1 -1
  70. package/templates/src/components/fields/ActionBuilderTimeSelector.tsx +1 -1
  71. package/templates/src/components/fields/ArtpackImage.tsx +11 -3
  72. package/templates/src/components/fields/BackgroundImage.tsx +8 -0
  73. package/templates/src/components/fields/BackgroundImageWrapper.tsx +15 -9
  74. package/templates/src/components/fields/ImageUpload.tsx +6 -0
  75. package/templates/src/components/form/ActionBuilderField.tsx +15 -5
  76. package/templates/src/components/form/ActionBuilderSlugSelector.tsx +1 -1
  77. package/templates/src/components/form/ColorPicker.tsx +1 -1
  78. package/templates/src/components/form/EnumSelect.tsx +1 -1
  79. package/templates/src/components/form/NumberInput.tsx +1 -1
  80. package/templates/src/components/form/StringArrayInput.tsx +1 -1
  81. package/templates/src/components/form/StringInput.tsx +1 -1
  82. package/templates/src/components/form/UnsavedChangesBar.tsx +1 -1
  83. package/templates/src/components/form/advanced/APIConfigSection.tsx +2 -2
  84. package/templates/src/components/form/advanced/AuthConfigSection.tsx +2 -2
  85. package/templates/src/components/profile/ProfileCreate.tsx +1 -1
  86. package/templates/src/components/profile/ProfileEdit.tsx +1 -1
  87. package/templates/src/components/storykeep/Dashboard_Advanced.tsx +2 -2
  88. package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +1 -1
  89. package/templates/src/components/storykeep/controls/content/ContentSummary.tsx +2 -2
  90. package/templates/src/components/storykeep/controls/content/KnownResourceTable.tsx +1 -1
  91. package/templates/src/components/storykeep/controls/content/ManageContent.tsx +6 -6
  92. package/templates/src/components/storykeep/controls/content/MenuForm.tsx +1 -1
  93. package/templates/src/components/storykeep/controls/content/PaneTable.tsx +358 -0
  94. package/templates/src/components/storykeep/controls/content/ResourceTable.tsx +1 -1
  95. package/templates/src/constants/prompts.json +18 -10
  96. package/templates/src/constants.ts +3 -0
  97. package/templates/src/hooks/usePaneFragments.ts +60 -0
  98. package/templates/src/lib/session.ts +71 -16
  99. package/templates/src/pages/[...slug].astro +4 -46
  100. package/templates/src/pages/api/css.ts +149 -0
  101. package/templates/src/pages/maint.astro +1 -1
  102. package/templates/src/pages/storykeep/login.astro +2 -2
  103. package/templates/src/stores/nodes.ts +162 -49
  104. package/templates/src/stores/orphanAnalysis.ts +6 -30
  105. package/templates/src/stores/previews.ts +7 -0
  106. package/templates/src/stores/storykeep.ts +0 -8
  107. package/templates/src/types/compositorTypes.ts +53 -10
  108. package/templates/src/utils/compositor/aiGeneration.ts +93 -0
  109. package/templates/src/utils/compositor/allowInsert.ts +2 -0
  110. package/templates/src/utils/compositor/htmlAst.ts +704 -0
  111. package/templates/src/utils/compositor/nodesHelper.ts +281 -102
  112. package/templates/src/utils/compositor/savePipeline.ts +893 -0
  113. package/templates/src/utils/etl/index.ts +3 -0
  114. package/templates/src/utils/etl/transformer.ts +10 -0
  115. package/templates/src/utils/helpers.ts +101 -0
  116. package/utils/inject-files.ts +100 -62
  117. package/templates/icons/text.svg +0 -6
  118. package/templates/src/components/compositor/NodeWithGuid.tsx +0 -69
  119. package/templates/src/components/compositor/nodes/GridLayout_eraser.tsx +0 -33
  120. package/templates/src/components/compositor/nodes/Markdown_eraser.tsx +0 -56
  121. package/templates/src/components/compositor/nodes/Pane_DesignLibrary.tsx +0 -269
  122. package/templates/src/components/compositor/nodes/Pane_eraser.tsx +0 -186
  123. package/templates/src/components/compositor/nodes/Pane_layout.tsx +0 -79
  124. package/templates/src/components/compositor/nodes/tagElements/NodeA_eraser.tsx +0 -26
  125. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx +0 -61
  126. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx +0 -120
  127. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx +0 -62
  128. package/templates/src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx +0 -26
@@ -1,3 +1,5 @@
1
+ import type { CreativePanePayload } from '@/types/compositorTypes';
2
+
1
3
  export interface BackendSavePayload {
2
4
  id: string;
3
5
  title: string;
@@ -23,6 +25,7 @@ export interface OptionsPayload {
23
25
  heldBeliefs?: any;
24
26
  withheldBeliefs?: any;
25
27
  codeHookPayload?: object;
28
+ htmlAst?: CreativePanePayload;
26
29
 
27
30
  // Flattened nodes array - ALL child nodes in flat structure
28
31
  nodes: Array<{
@@ -45,6 +45,16 @@ export function transformToOptionsPayload(
45
45
  })),
46
46
  });
47
47
 
48
+ if (subtree.paneNode.htmlAst) {
49
+ return {
50
+ isDecorative: false,
51
+ heldBeliefs: subtree.paneNode.heldBeliefs ?? {},
52
+ withheldBeliefs: subtree.paneNode.withheldBeliefs ?? {},
53
+ htmlAst: subtree.paneNode.htmlAst,
54
+ nodes: [],
55
+ };
56
+ }
57
+
48
58
  const flattenedNodes = subtree.allChildNodes
49
59
  .map((node) => {
50
60
  if (VERBOSE)
@@ -435,3 +435,104 @@ export function getSettingsPanelTitle(action: string): string {
435
435
  return 'Settings';
436
436
  }
437
437
  }
438
+
439
+ export const resolveCollisions = () => {
440
+ const paneEls = Array.from(
441
+ document.querySelectorAll<HTMLElement>('.pane-overlay')
442
+ );
443
+ const nodeEls = Array.from(
444
+ document.querySelectorAll<HTMLElement>('.node-overlay')
445
+ );
446
+
447
+ // 1. Reset Panes to natural state to get accurate measurements
448
+ paneEls.forEach((el) => (el.style.transform = ''));
449
+
450
+ if (paneEls.length === 0) return;
451
+
452
+ const paneItems = paneEls.map((el) => ({
453
+ el,
454
+ rect: el.getBoundingClientRect(),
455
+ layer: parseInt(el.getAttribute('data-layer') || '1', 10),
456
+ x: 0,
457
+ y: 0,
458
+ }));
459
+
460
+ const nodeRects = nodeEls.map((el) => el.getBoundingClientRect());
461
+
462
+ // 2. Y-Axis Logic: Pane vs. Node Collision (Move UP)
463
+ paneItems.forEach((pane) => {
464
+ let maxOverlapY = 0;
465
+
466
+ for (const nodeRect of nodeRects) {
467
+ // Check AABB intersection
468
+ const intersects =
469
+ pane.rect.left < nodeRect.right &&
470
+ pane.rect.right > nodeRect.left &&
471
+ pane.rect.top < nodeRect.bottom &&
472
+ pane.rect.bottom > nodeRect.top;
473
+
474
+ if (intersects) {
475
+ // Calculate intersection height
476
+ const overlap =
477
+ Math.min(pane.rect.bottom, nodeRect.bottom) -
478
+ Math.max(pane.rect.top, nodeRect.top);
479
+ if (overlap > maxOverlapY) {
480
+ maxOverlapY = overlap;
481
+ }
482
+ }
483
+ }
484
+
485
+ if (maxOverlapY > 0) {
486
+ // Move up by overlap + buffer, capped at 48px
487
+ const shift = Math.min(maxOverlapY + 2, 48);
488
+ pane.y = -shift;
489
+ }
490
+ });
491
+
492
+ // 3. X-Axis Logic: Pane vs. Pane Collision (Move LEFT)
493
+ // Sort by physical top position to find vertical clusters
494
+ paneItems.sort((a, b) => a.rect.top - b.rect.top);
495
+
496
+ const clusters: (typeof paneItems)[] = [];
497
+ if (paneItems.length > 0) {
498
+ let currentCluster = [paneItems[0]];
499
+ for (let i = 1; i < paneItems.length; i++) {
500
+ const current = paneItems[i];
501
+ const prev = currentCluster[currentCluster.length - 1];
502
+
503
+ // Check if they occupy the same vertical space (with small buffer)
504
+ const isOverlappingY =
505
+ current.rect.top < prev.rect.bottom - 4 &&
506
+ current.rect.bottom > prev.rect.top + 4;
507
+
508
+ if (isOverlappingY) {
509
+ currentCluster.push(current);
510
+ } else {
511
+ clusters.push(currentCluster);
512
+ currentCluster = [current];
513
+ }
514
+ }
515
+ clusters.push(currentCluster);
516
+ }
517
+
518
+ // Apply X-shifts to clusters
519
+ clusters.forEach((cluster) => {
520
+ if (cluster.length > 1) {
521
+ // Sort by Layer ID (Layer 1 stays right, Layer 2 moves left, etc.)
522
+ cluster.sort((a, b) => a.layer - b.layer);
523
+
524
+ cluster.forEach((item, index) => {
525
+ if (index > 0) {
526
+ item.x = -(index * 32); // Shift left 32px per layer index
527
+ }
528
+ });
529
+ }
530
+ });
531
+
532
+ // 4. Apply Final Transforms
533
+ paneItems.forEach((item) => {
534
+ if (item.x !== 0 || item.y !== 0) {
535
+ item.el.style.transform = `translate(${item.x}px, ${item.y}px)`;
536
+ }
537
+ });
538
+ };
@@ -96,8 +96,16 @@ export async function injectTemplateFiles(
96
96
  dest: 'src/components/compositor/Node.tsx',
97
97
  },
98
98
  {
99
- src: resolve('../templates/src/components/compositor/NodeWithGuid.tsx'),
100
- dest: 'src/components/compositor/NodeWithGuid.tsx',
99
+ src: resolve(
100
+ '../templates/src/components/compositor/tools/NodeOverlay.tsx'
101
+ ),
102
+ dest: 'src/components/compositor/tools/NodeOverlay.tsx',
103
+ },
104
+ {
105
+ src: resolve(
106
+ '../templates/src/components/compositor/tools/PaneOverlay.tsx'
107
+ ),
108
+ dest: 'src/components/compositor/tools/PaneOverlay.tsx',
101
109
  },
102
110
  {
103
111
  src: resolve(
@@ -107,15 +115,15 @@ export async function injectTemplateFiles(
107
115
  },
108
116
  {
109
117
  src: resolve(
110
- '../templates/src/components/compositor/nodes/GridLayout.tsx'
118
+ '../templates/src/components/compositor/nodes/CreativePane.tsx'
111
119
  ),
112
- dest: 'src/components/compositor/nodes/GridLayout.tsx',
120
+ dest: 'src/components/compositor/nodes/CreativePane.tsx',
113
121
  },
114
122
  {
115
123
  src: resolve(
116
- '../templates/src/components/compositor/nodes/GridLayout_eraser.tsx'
124
+ '../templates/src/components/compositor/nodes/GridLayout.tsx'
117
125
  ),
118
- dest: 'src/components/compositor/nodes/GridLayout_eraser.tsx',
126
+ dest: 'src/components/compositor/nodes/GridLayout.tsx',
119
127
  },
120
128
  {
121
129
  src: resolve(
@@ -133,24 +141,6 @@ export async function injectTemplateFiles(
133
141
  src: resolve('../templates/src/components/compositor/nodes/Pane.tsx'),
134
142
  dest: 'src/components/compositor/nodes/Pane.tsx',
135
143
  },
136
- {
137
- src: resolve(
138
- '../templates/src/components/compositor/nodes/Pane_eraser.tsx'
139
- ),
140
- dest: 'src/components/compositor/nodes/Pane_eraser.tsx',
141
- },
142
- {
143
- src: resolve(
144
- '../templates/src/components/compositor/nodes/Pane_DesignLibrary.tsx'
145
- ),
146
- dest: 'src/components/compositor/nodes/Pane_DesignLibrary.tsx',
147
- },
148
- {
149
- src: resolve(
150
- '../templates/src/components/compositor/nodes/Pane_layout.tsx'
151
- ),
152
- dest: 'src/components/compositor/nodes/Pane_layout.tsx',
153
- },
154
144
  {
155
145
  src: resolve(
156
146
  '../templates/src/components/codehooks/SandboxRegisterForm.tsx'
@@ -161,12 +151,6 @@ export async function injectTemplateFiles(
161
151
  src: resolve('../templates/src/components/compositor/nodes/Markdown.tsx'),
162
152
  dest: 'src/components/compositor/nodes/Markdown.tsx',
163
153
  },
164
- {
165
- src: resolve(
166
- '../templates/src/components/compositor/nodes/Markdown_eraser.tsx'
167
- ),
168
- dest: 'src/components/compositor/nodes/Markdown_eraser.tsx',
169
- },
170
154
  {
171
155
  src: resolve(
172
156
  '../templates/src/components/compositor/nodes/BgPaneWrapper.tsx'
@@ -195,24 +179,6 @@ export async function injectTemplateFiles(
195
179
  ),
196
180
  dest: 'src/components/compositor/nodes/tagElements/NodeBasicTag.tsx',
197
181
  },
198
- {
199
- src: resolve(
200
- '../templates/src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx'
201
- ),
202
- dest: 'src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx',
203
- },
204
- {
205
- src: resolve(
206
- '../templates/src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx'
207
- ),
208
- dest: 'src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx',
209
- },
210
- {
211
- src: resolve(
212
- '../templates/src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx'
213
- ),
214
- dest: 'src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx',
215
- },
216
182
  {
217
183
  src: resolve(
218
184
  '../templates/src/components/compositor/nodes/tagElements/NodeText.tsx'
@@ -231,24 +197,12 @@ export async function injectTemplateFiles(
231
197
  ),
232
198
  dest: 'src/components/compositor/nodes/tagElements/NodeA.tsx',
233
199
  },
234
- {
235
- src: resolve(
236
- '../templates/src/components/compositor/nodes/tagElements/NodeA_eraser.tsx'
237
- ),
238
- dest: 'src/components/compositor/nodes/tagElements/NodeA_eraser.tsx',
239
- },
240
200
  {
241
201
  src: resolve(
242
202
  '../templates/src/components/compositor/nodes/tagElements/NodeButton.tsx'
243
203
  ),
244
204
  dest: 'src/components/compositor/nodes/tagElements/NodeButton.tsx',
245
205
  },
246
- {
247
- src: resolve(
248
- '../templates/src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx'
249
- ),
250
- dest: 'src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx',
251
- },
252
206
  {
253
207
  src: resolve(
254
208
  '../templates/src/components/compositor/nodes/tagElements/NodeImg.tsx'
@@ -483,6 +437,30 @@ export async function injectTemplateFiles(
483
437
  ),
484
438
  dest: 'src/components/edit/pane/steps/CopyInputStep.tsx',
485
439
  },
440
+ {
441
+ src: resolve(
442
+ '../templates/src/components/edit/pane/steps/AiCreativeDesignStep.tsx'
443
+ ),
444
+ dest: 'src/components/edit/pane/steps/AiCreativeDesignStep.tsx',
445
+ },
446
+ {
447
+ src: resolve(
448
+ '../templates/src/components/edit/pane/steps/AiStandardDesignStep.tsx'
449
+ ),
450
+ dest: 'src/components/edit/pane/steps/AiStandardDesignStep.tsx',
451
+ },
452
+ {
453
+ src: resolve(
454
+ '../templates/src/components/edit/pane/steps/AiLibraryCopyStep.tsx'
455
+ ),
456
+ dest: 'src/components/edit/pane/steps/AiLibraryCopyStep.tsx',
457
+ },
458
+ {
459
+ src: resolve(
460
+ '../templates/src/components/edit/pane/steps/AiRefineDesignStep.tsx'
461
+ ),
462
+ dest: 'src/components/edit/pane/steps/AiRefineDesignStep.tsx',
463
+ },
486
464
  {
487
465
  src: resolve(
488
466
  '../templates/src/components/edit/pane/steps/DesignLibraryStep.tsx'
@@ -501,6 +479,12 @@ export async function injectTemplateFiles(
501
479
  ),
502
480
  dest: 'src/components/edit/pane/steps/DirectInjectStep.tsx',
503
481
  },
482
+ {
483
+ src: resolve(
484
+ '../templates/src/components/edit/pane/steps/CreativeInjectStep.tsx'
485
+ ),
486
+ dest: 'src/components/edit/pane/steps/CreativeInjectStep.tsx',
487
+ },
504
488
  {
505
489
  src: resolve(
506
490
  '../templates/src/components/edit/pane/AddPanePanel_newCustomCopy.tsx'
@@ -633,10 +617,22 @@ export async function injectTemplateFiles(
633
617
  dest: 'src/utils/etl/loader.ts',
634
618
  },
635
619
  // Compositor utils
620
+ {
621
+ src: resolve('../templates/src/utils/compositor/savePipeline.ts'),
622
+ dest: 'src/utils/compositor/savePipeline.ts',
623
+ },
636
624
  {
637
625
  src: resolve('../templates/src/utils/compositor/aiPaneParser.ts'),
638
626
  dest: 'src/utils/compositor/aiPaneParser.ts',
639
627
  },
628
+ {
629
+ src: resolve('../templates/src/utils/compositor/aiGeneration.ts'),
630
+ dest: 'src/utils/compositor/aiGeneration.ts',
631
+ },
632
+ {
633
+ src: resolve('../templates/src/utils/compositor/htmlAst.ts'),
634
+ dest: 'src/utils/compositor/htmlAst.ts',
635
+ },
640
636
  {
641
637
  src: resolve(
642
638
  '../templates/src/utils/compositor/nodesMarkdownGenerator.ts'
@@ -715,6 +711,10 @@ export async function injectTemplateFiles(
715
711
  src: resolve('../templates/src/stores/storykeep.ts'),
716
712
  dest: 'src/stores/storykeep.ts',
717
713
  },
714
+ {
715
+ src: resolve('../templates/src/stores/previews.ts'),
716
+ dest: 'src/stores/previews.ts',
717
+ },
718
718
  {
719
719
  src: resolve('../templates/src/stores/analytics.ts'),
720
720
  dest: 'src/stores/analytics.ts',
@@ -888,6 +888,10 @@ export async function injectTemplateFiles(
888
888
  src: resolve('../templates/src/pages/api/tailwind.ts'),
889
889
  dest: 'src/pages/api/tailwind.ts',
890
890
  },
891
+ {
892
+ src: resolve('../templates/src/pages/api/css.ts'),
893
+ dest: 'src/pages/api/css.ts',
894
+ },
891
895
  {
892
896
  src: resolve('../templates/src/pages/api/sandbox.ts'),
893
897
  dest: 'src/pages/api/sandbox.ts',
@@ -959,6 +963,10 @@ export async function injectTemplateFiles(
959
963
  src: resolve('../templates/src/components/search/SearchResults.tsx'),
960
964
  dest: 'src/components/search/SearchResults.tsx',
961
965
  },
966
+ {
967
+ src: resolve('../templates/src/hooks/usePaneFragments.ts'),
968
+ dest: 'src/hooks/usePaneFragments.ts',
969
+ },
962
970
  {
963
971
  src: resolve('../templates/src/hooks/useSearch.ts'),
964
972
  dest: 'src/hooks/useSearch.ts',
@@ -1186,6 +1194,12 @@ export async function injectTemplateFiles(
1186
1194
  ),
1187
1195
  dest: 'src/components/storykeep/controls/content/StoryFragmentTable.tsx',
1188
1196
  },
1197
+ {
1198
+ src: resolve(
1199
+ '../templates/src/components/storykeep/controls/content/PaneTable.tsx'
1200
+ ),
1201
+ dest: 'src/components/storykeep/controls/content/PaneTable.tsx',
1202
+ },
1189
1203
  {
1190
1204
  src: resolve(
1191
1205
  '../templates/src/components/storykeep/controls/content/ContentBrowser.tsx'
@@ -1420,6 +1434,18 @@ export async function injectTemplateFiles(
1420
1434
  src: resolve('../templates/src/components/edit/state/StylesMemory.tsx'),
1421
1435
  dest: 'src/components/edit/state/StylesMemory.tsx',
1422
1436
  },
1437
+ {
1438
+ src: resolve(
1439
+ '../templates/src/components/edit/panels/CreativeImagePanel.tsx'
1440
+ ),
1441
+ dest: 'src/components/edit/panels/CreativeImagePanel.tsx',
1442
+ },
1443
+ {
1444
+ src: resolve(
1445
+ '../templates/src/components/edit/panels/CreativeLinkPanel.tsx'
1446
+ ),
1447
+ dest: 'src/components/edit/panels/CreativeLinkPanel.tsx',
1448
+ },
1423
1449
  {
1424
1450
  src: resolve(
1425
1451
  '../templates/src/components/edit/panels/StyleWordCarouselPanel.tsx'
@@ -2029,8 +2055,20 @@ export async function injectTemplateFiles(
2029
2055
  dest: 'public/icons/image.svg',
2030
2056
  },
2031
2057
  {
2032
- src: resolve('../templates/icons/text.svg'),
2033
- dest: 'public/icons/text.svg',
2058
+ src: resolve('../templates/icons/link.svg'),
2059
+ dest: 'public/icons/link.svg',
2060
+ },
2061
+ {
2062
+ src: resolve('../templates/icons/p.svg'),
2063
+ dest: 'public/icons/p.svg',
2064
+ },
2065
+ {
2066
+ src: resolve('../templates/icons/li.svg'),
2067
+ dest: 'public/icons/li.svg',
2068
+ },
2069
+ {
2070
+ src: resolve('../templates/icons/code.svg'),
2071
+ dest: 'public/icons/code.svg',
2034
2072
  },
2035
2073
 
2036
2074
  // Social Icons
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
3
- viewBox="0 0 100.16 122.88" width="512" height="273.292" preserveAspectRatio="xMidYMid meet">
4
- <style type="text/css">.st0{fill-rule:evenodd;clip-rule:evenodd;}</style>
5
- <path class="st0" d="M89.06,18.28v101c0,1.98-1.64,3.6-3.66,3.6H74.43c-2.01,0-3.66-1.62-3.66-3.6v-101H58.24v100.99 c0,1.98-1.64,3.6-3.66,3.6H43.62c-2.01,0-3.66-1.62-3.66-3.6V79l-0.39,0C17.72,79,0,61.28,0,39.44C0,14.12,20.45,0,43.75,0H96.5 c2.01,0,3.66,1.64,3.66,3.66v10.97c0,2.01-1.65,3.66-3.66,3.66H89.06L89.06,18.28z"/>
6
- </svg>
@@ -1,69 +0,0 @@
1
- import { memo, type ReactElement } from 'react';
2
- import { getCtx, type NodesContext } from '@/stores/nodes';
3
- import { getType } from '@/utils/compositor/typeGuards';
4
- import type { BaseNode, FlatNode } from '@/types/compositorTypes';
5
- import type { NodeProps } from '@/types/nodeProps';
6
- import ArrowDownTrayIcon from '@heroicons/react/24/outline/ArrowDownTrayIcon';
7
-
8
- const getNodeTree = (nodeId: string, ctx: NodesContext): BaseNode | null => {
9
- const allNodesMap = ctx.allNodes.get();
10
- const node = allNodesMap.get(nodeId);
11
-
12
- if (!node) {
13
- return null;
14
- }
15
-
16
- // Use JSON stringify/parse to get a deep clone, breaking any proxies/reactivity
17
- const clonedNode = JSON.parse(JSON.stringify(node));
18
-
19
- const childIds = ctx.getChildNodeIDs(nodeId);
20
-
21
- if (childIds.length > 0) {
22
- clonedNode.children = childIds
23
- .map((childId) => getNodeTree(childId, ctx))
24
- .filter((child): child is BaseNode => child !== null);
25
- }
26
-
27
- return clonedNode;
28
- };
29
-
30
- export type RenderableNodes = NodeProps & { element: ReactElement };
31
-
32
- export const NodeWithGuid = memo((props: RenderableNodes) => {
33
- const ctx = getCtx(props);
34
- const node = ctx.allNodes.get().get(props.nodeId) as FlatNode;
35
-
36
- const handleDumpTree = (e: React.MouseEvent) => {
37
- e.stopPropagation();
38
- const nodeTree = getNodeTree(props.nodeId, ctx);
39
- console.log(
40
- `%c--- Dumping Node Tree for ${getType(node)}: ${props.nodeId} ---`,
41
- 'color: #0891b2; font-weight: bold;'
42
- );
43
- console.log(nodeTree);
44
- };
45
-
46
- return (
47
- <div className="relative">
48
- <div
49
- className="outline-dotted outline-2 outline-cyan-600"
50
- data-node-id={props.nodeId}
51
- data-node-type={getType(node)}
52
- >
53
- <div className="flex items-center justify-between border-b border-dotted border-cyan-600 p-1 font-mono text-xs text-cyan-600">
54
- <span className="truncate pr-2">
55
- {getType(node)}: {props.nodeId}
56
- </span>
57
- <button
58
- onClick={handleDumpTree}
59
- title={`Log tree for ${props.nodeId}`}
60
- className="flex-shrink-0 rounded p-0.5 hover:bg-cyan-100"
61
- >
62
- <ArrowDownTrayIcon className="h-4 w-4 text-cyan-700" />
63
- </button>
64
- </div>
65
- <div className="p-0.5">{props.element}</div>
66
- </div>
67
- </div>
68
- );
69
- });
@@ -1,33 +0,0 @@
1
- import { getCtx } from '@/stores/nodes';
2
- import type { NodeProps } from '@/types/nodeProps';
3
- import { GridLayout } from './GridLayout';
4
- import type { MouseEvent } from 'react';
5
-
6
- export function GridLayoutEraser(props: NodeProps) {
7
- const ctx = getCtx(props);
8
-
9
- const handleClick = (e: MouseEvent<HTMLDivElement>) => {
10
- e.stopPropagation();
11
- e.preventDefault();
12
-
13
- const node = ctx.allNodes.get().get(props.nodeId);
14
- if (!node) return;
15
-
16
- if (
17
- window.confirm(
18
- 'Are you sure you want to delete this grid layout and all its columns?'
19
- )
20
- ) {
21
- ctx.deleteNode(props.nodeId);
22
- }
23
- };
24
-
25
- return (
26
- <div
27
- className="outline-dashed outline-2 outline-red-500 hover:bg-red-500/10"
28
- onClick={handleClick}
29
- >
30
- <GridLayout {...props} />
31
- </div>
32
- );
33
- }
@@ -1,56 +0,0 @@
1
- import { getCtx } from '@/stores/nodes';
2
- import { Markdown } from './Markdown';
3
- import { isGridLayoutNode } from '@/utils/compositor/typeGuards';
4
- import { revertFromGrid } from '@/utils/compositor/nodesHelper';
5
- import type { NodeProps } from '@/types/nodeProps';
6
- import type { MouseEvent } from 'react';
7
-
8
- export function MarkdownEraser(props: NodeProps) {
9
- const ctx = getCtx(props);
10
-
11
- const handleClick = (e: MouseEvent<HTMLDivElement>) => {
12
- e.stopPropagation();
13
- e.preventDefault();
14
-
15
- const node = ctx.allNodes.get().get(props.nodeId);
16
- if (!node || !node.parentId) return;
17
-
18
- const parentNode = ctx.allNodes.get().get(node.parentId);
19
- if (!parentNode || !isGridLayoutNode(parentNode)) {
20
- ctx.deleteNode(props.nodeId);
21
- return;
22
- }
23
-
24
- const children = ctx.getChildNodeIDs(parentNode.id);
25
- const columnCount = children.length;
26
-
27
- if (columnCount === 1) {
28
- if (
29
- window.confirm(
30
- 'This is the last column. Do you want to delete it and revert to a standard pane layout?'
31
- )
32
- ) {
33
- revertFromGrid(parentNode.id);
34
- }
35
- } else {
36
- if (
37
- window.confirm(
38
- `Are you sure you want to delete this column? ${
39
- columnCount - 1
40
- } columns will remain.`
41
- )
42
- ) {
43
- ctx.deleteNode(props.nodeId);
44
- }
45
- }
46
- };
47
-
48
- return (
49
- <div
50
- className="outline-dashed outline-2 outline-red-500 hover:bg-red-500/10"
51
- onClick={handleClick}
52
- >
53
- <Markdown {...props} />
54
- </div>
55
- );
56
- }