astro-tractstack 2.0.17 → 2.0.18
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.
- package/dist/index.js +18 -0
- package/package.json +1 -1
- package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +1 -1
- package/templates/src/components/codehooks/ListContentSetup.tsx +1 -1
- package/templates/src/components/compositor/Compositor.tsx +1 -0
- package/templates/src/components/compositor/Node.tsx +41 -17
- package/templates/src/components/compositor/nodes/GhostInsertBlock.tsx +9 -6
- package/templates/src/components/compositor/nodes/GridLayout.tsx +124 -0
- package/templates/src/components/compositor/nodes/GridLayout_eraser.tsx +33 -0
- package/templates/src/components/compositor/nodes/Markdown.tsx +67 -37
- package/templates/src/components/compositor/nodes/Markdown_eraser.tsx +56 -0
- package/templates/src/components/compositor/preview/FeaturedArticlePreview.tsx +8 -2
- package/templates/src/components/edit/PanelSwitch.tsx +232 -75
- package/templates/src/components/edit/SettingsPanel.tsx +0 -1
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +3 -3
- package/templates/src/components/edit/pane/AddPanePanel_new.tsx +167 -145
- package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +2 -2
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +1 -7
- package/templates/src/components/edit/pane/PanePanel_impression.tsx +1 -1
- package/templates/src/components/edit/pane/RestylePaneModal.tsx +8 -5
- package/templates/src/components/edit/pane/steps/AiDesignStep.tsx +6 -6
- package/templates/src/components/edit/pane/steps/CopyInputStep.tsx +3 -3
- package/templates/src/components/edit/pane/steps/DesignLibraryStep.tsx +4 -4
- package/templates/src/components/edit/panels/StyleElementPanel.tsx +11 -4
- package/templates/src/components/edit/panels/StyleElementPanel_add.tsx +8 -8
- package/templates/src/components/edit/panels/StyleElementPanel_remove.tsx +14 -4
- package/templates/src/components/edit/panels/StyleElementPanel_update.tsx +16 -4
- package/templates/src/components/edit/panels/StyleImagePanel.tsx +8 -3
- package/templates/src/components/edit/panels/StyleImagePanel_add.tsx +9 -2
- package/templates/src/components/edit/panels/StyleImagePanel_remove.tsx +5 -2
- package/templates/src/components/edit/panels/StyleImagePanel_update.tsx +5 -2
- package/templates/src/components/edit/panels/StyleLiElementPanel.tsx +7 -3
- package/templates/src/components/edit/panels/StyleLiElementPanel_add.tsx +9 -2
- package/templates/src/components/edit/panels/StyleLiElementPanel_remove.tsx +5 -2
- package/templates/src/components/edit/panels/StyleLiElementPanel_update.tsx +5 -2
- package/templates/src/components/edit/panels/StyleParentPanel.tsx +530 -171
- package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +77 -42
- package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +38 -22
- package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +171 -66
- package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +166 -98
- package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +7 -3
- package/templates/src/components/edit/panels/StyleWidgetPanel_add.tsx +9 -2
- package/templates/src/components/edit/panels/StyleWidgetPanel_remove.tsx +5 -2
- package/templates/src/components/edit/panels/StyleWidgetPanel_update.tsx +6 -2
- package/templates/src/components/edit/state/SaveModal.tsx +10 -2
- package/templates/src/components/edit/state/SaveToLibraryModal.tsx +6 -6
- package/templates/src/components/fields/PaneBreakShapeSelector.tsx +1 -1
- package/templates/src/components/widgets/ImpressionWrapper.tsx +4 -1
- package/templates/src/constants/prompts.json +1 -1
- package/templates/src/stores/nodes.ts +110 -33
- package/templates/src/stores/storykeep.ts +3 -1
- package/templates/src/types/compositorTypes.ts +37 -2
- package/templates/src/utils/compositor/TemplateNodes.ts +8 -0
- package/templates/src/utils/compositor/nodesHelper.ts +229 -0
- package/templates/src/utils/compositor/reduceNodesClassNames.ts +40 -1
- package/templates/src/utils/compositor/typeGuards.ts +7 -0
- package/templates/src/utils/etl/extractor.ts +1 -5
- package/templates/src/utils/etl/index.ts +1 -0
- package/templates/src/utils/etl/transformer.ts +70 -25
- package/utils/inject-files.ts +18 -0
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
hasTagName,
|
|
16
16
|
isDefined,
|
|
17
17
|
isValidTag,
|
|
18
|
+
isGridLayoutNode,
|
|
18
19
|
toTag,
|
|
19
20
|
} from '@/utils/compositor/typeGuards';
|
|
20
21
|
import { startLoadingAnimation } from '@/utils/helpers';
|
|
@@ -29,6 +30,7 @@ import type {
|
|
|
29
30
|
BaseNode,
|
|
30
31
|
FlatNode,
|
|
31
32
|
ImpressionNode,
|
|
33
|
+
GridLayoutNode,
|
|
32
34
|
MarkdownPaneFragmentNode,
|
|
33
35
|
MenuNode,
|
|
34
36
|
NodeType,
|
|
@@ -1390,6 +1392,30 @@ export class NodesContext {
|
|
|
1390
1392
|
if (!node) return '';
|
|
1391
1393
|
|
|
1392
1394
|
switch (node.nodeType) {
|
|
1395
|
+
case 'GridLayoutNode': {
|
|
1396
|
+
const gridNode = node as GridLayoutNode;
|
|
1397
|
+
if (gridNode.parentClasses) {
|
|
1398
|
+
const [all, mobile, tablet, desktop] = processClassesForViewports(
|
|
1399
|
+
gridNode.parentClasses[depth],
|
|
1400
|
+
{}, // No override classes for GridLayout parent case
|
|
1401
|
+
1
|
|
1402
|
+
);
|
|
1403
|
+
|
|
1404
|
+
if (isPreview) return desktop[0];
|
|
1405
|
+
switch (viewport) {
|
|
1406
|
+
case 'desktop':
|
|
1407
|
+
return desktop[0];
|
|
1408
|
+
case 'tablet':
|
|
1409
|
+
return tablet[0];
|
|
1410
|
+
case 'mobile':
|
|
1411
|
+
return mobile[0];
|
|
1412
|
+
default:
|
|
1413
|
+
return all[0];
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
break;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1393
1419
|
case 'Markdown':
|
|
1394
1420
|
{
|
|
1395
1421
|
const markdownFragment = node as MarkdownPaneFragmentNode;
|
|
@@ -1485,33 +1511,54 @@ export class NodesContext {
|
|
|
1485
1511
|
}
|
|
1486
1512
|
}
|
|
1487
1513
|
|
|
1488
|
-
|
|
1514
|
+
// Begin Default Class Lookup Logic
|
|
1515
|
+
const markdownParentId = this.getClosestNodeTypeFromId(
|
|
1489
1516
|
nodeId,
|
|
1490
1517
|
'Markdown'
|
|
1491
1518
|
);
|
|
1492
|
-
|
|
1519
|
+
if (!markdownParentId) break;
|
|
1520
|
+
|
|
1521
|
+
const markdownParentNode = this.allNodes
|
|
1493
1522
|
.get()
|
|
1494
|
-
.get(
|
|
1495
|
-
if (
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1523
|
+
.get(markdownParentId) as MarkdownPaneFragmentNode;
|
|
1524
|
+
if (!markdownParentNode) break;
|
|
1525
|
+
|
|
1526
|
+
const tagNameStr = (node as FlatNode).tagName as string;
|
|
1527
|
+
|
|
1528
|
+
// By default, assume the markdown node is the source of styles.
|
|
1529
|
+
let styleSourceNode: MarkdownPaneFragmentNode | GridLayoutNode =
|
|
1530
|
+
markdownParentNode;
|
|
1531
|
+
let styles = styleSourceNode.defaultClasses?.[tagNameStr];
|
|
1532
|
+
|
|
1533
|
+
// If the markdown node has no styles for this tag, check for a GridLayout grandparent.
|
|
1534
|
+
// This handles the case where the MarkdownNode is a column.
|
|
1535
|
+
if (!styles || Object.keys(styles.mobile).length === 0) {
|
|
1536
|
+
const grandparent = markdownParentNode.parentId
|
|
1537
|
+
? this.allNodes.get().get(markdownParentNode.parentId)
|
|
1538
|
+
: null;
|
|
1539
|
+
|
|
1540
|
+
if (grandparent && isGridLayoutNode(grandparent)) {
|
|
1541
|
+
styleSourceNode = grandparent;
|
|
1542
|
+
styles = styleSourceNode.defaultClasses?.[tagNameStr];
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
if (styles && styles.mobile) {
|
|
1547
|
+
const [all, mobile, tablet, desktop] = processClassesForViewports(
|
|
1548
|
+
styles,
|
|
1549
|
+
(node as FlatNode)?.overrideClasses || {},
|
|
1550
|
+
1
|
|
1551
|
+
);
|
|
1552
|
+
if (isPreview) return desktop[0];
|
|
1553
|
+
switch (viewport) {
|
|
1554
|
+
case 'desktop':
|
|
1555
|
+
return desktop[0];
|
|
1556
|
+
case 'tablet':
|
|
1557
|
+
return tablet[0];
|
|
1558
|
+
case 'mobile':
|
|
1559
|
+
return mobile[0];
|
|
1560
|
+
default:
|
|
1561
|
+
return all[0];
|
|
1515
1562
|
}
|
|
1516
1563
|
}
|
|
1517
1564
|
}
|
|
@@ -1584,19 +1631,44 @@ export class NodesContext {
|
|
|
1584
1631
|
}
|
|
1585
1632
|
|
|
1586
1633
|
switch (node.nodeType) {
|
|
1587
|
-
case
|
|
1588
|
-
case
|
|
1589
|
-
case
|
|
1634
|
+
case 'GridLayoutNode':
|
|
1635
|
+
case 'TagElement':
|
|
1636
|
+
case 'BgPane':
|
|
1637
|
+
case 'Markdown': {
|
|
1638
|
+
const nodesToDirty: BaseNode[] = [];
|
|
1590
1639
|
const paneNodeId = this.getClosestNodeTypeFromId(node.id, 'Pane');
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1640
|
+
|
|
1641
|
+
if (paneNodeId) {
|
|
1642
|
+
const paneNode = this.allNodes.get().get(paneNodeId);
|
|
1643
|
+
if (paneNode && !paneNode.isChanged) {
|
|
1644
|
+
nodesToDirty.push({ ...paneNode, isChanged: true });
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
if (node.parentId) {
|
|
1649
|
+
const parentNode = this.allNodes.get().get(node.parentId);
|
|
1650
|
+
if (
|
|
1651
|
+
parentNode &&
|
|
1652
|
+
parentNode.nodeType === 'GridLayoutNode' &&
|
|
1653
|
+
!parentNode.isChanged
|
|
1654
|
+
) {
|
|
1655
|
+
if (!nodesToDirty.some((n) => n.id === parentNode.id)) {
|
|
1656
|
+
nodesToDirty.push({ ...parentNode, isChanged: true });
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
if (nodesToDirty.length > 0) {
|
|
1662
|
+
this.modifyNodes(nodesToDirty, {
|
|
1663
|
+
notify: false,
|
|
1664
|
+
recordHistory: false,
|
|
1665
|
+
});
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1597
1668
|
this.notifyNode(ROOT_NODE_NAME);
|
|
1598
1669
|
break;
|
|
1599
1670
|
}
|
|
1671
|
+
|
|
1600
1672
|
case `Menu`:
|
|
1601
1673
|
case `Pane`:
|
|
1602
1674
|
case `StoryFragment`:
|
|
@@ -1970,7 +2042,9 @@ export class NodesContext {
|
|
|
1970
2042
|
});
|
|
1971
2043
|
break;
|
|
1972
2044
|
}
|
|
1973
|
-
|
|
2045
|
+
if ([`p`, `h2`, `h3`, `h4`, `li`].includes(tagName))
|
|
2046
|
+
this.toolModeValStore.set({ value: 'text' });
|
|
2047
|
+
else this.toolModeValStore.set({ value: 'styles' });
|
|
1974
2048
|
this.notifyNode('root');
|
|
1975
2049
|
}
|
|
1976
2050
|
|
|
@@ -2024,6 +2098,7 @@ export class NodesContext {
|
|
|
2024
2098
|
|
|
2025
2099
|
let autoCreatedMarkdownNode: MarkdownPaneFragmentNode | null = null;
|
|
2026
2100
|
|
|
2101
|
+
console.log(`--- [TRAP - TEMPLATE BEFORE] ---`, cloneDeep(node));
|
|
2027
2102
|
// 3. HANDLE EMPTY PANE BY AUTO-CREATING A MARKDOWN NODE
|
|
2028
2103
|
if (targetNode.nodeType === 'Pane') {
|
|
2029
2104
|
// Create a minimal markdown node to act as the container
|
|
@@ -2101,6 +2176,8 @@ export class NodesContext {
|
|
|
2101
2176
|
);
|
|
2102
2177
|
}
|
|
2103
2178
|
|
|
2179
|
+
console.log(`--- [TRAP - FLATTENED AFTER] ---`, cloneDeep(flattenedNodes));
|
|
2180
|
+
|
|
2104
2181
|
// 5. PERFORM REMAINING STATE MUTATIONS
|
|
2105
2182
|
if (originalPaneNode) {
|
|
2106
2183
|
this.modifyNodes([{ ...originalPaneNode, isChanged: true }], {
|
|
@@ -157,7 +157,9 @@ export const resetStoryKeepState = () => {
|
|
|
157
157
|
};
|
|
158
158
|
|
|
159
159
|
export const settingsPanelStore = atom<SettingsPanelSignal | null>(null);
|
|
160
|
-
|
|
160
|
+
export const stylePanelTargetMemoryStore = atom<Map<string, number>>(
|
|
161
|
+
new Map<string, number>()
|
|
162
|
+
);
|
|
161
163
|
export const styleElementInfoStore = map<{
|
|
162
164
|
markdownParentId: string | null;
|
|
163
165
|
tagName: string | null;
|
|
@@ -76,6 +76,7 @@ export type SettingsPanelSignal = {
|
|
|
76
76
|
minimized?: boolean;
|
|
77
77
|
expanded?: boolean;
|
|
78
78
|
editLock?: number;
|
|
79
|
+
targetProperty?: 'parentClasses' | 'gridClasses';
|
|
79
80
|
};
|
|
80
81
|
|
|
81
82
|
export interface OgImageParams {
|
|
@@ -173,6 +174,7 @@ export type NodeType =
|
|
|
173
174
|
| 'Pane'
|
|
174
175
|
| 'StoryFragment'
|
|
175
176
|
| 'BgPane'
|
|
177
|
+
| 'GridLayoutNode'
|
|
176
178
|
| 'Markdown'
|
|
177
179
|
| 'TagElement'
|
|
178
180
|
| 'TractStack'
|
|
@@ -253,7 +255,12 @@ export interface TractStackNode extends BaseNode {
|
|
|
253
255
|
}
|
|
254
256
|
|
|
255
257
|
export interface PaneFragmentNode extends BaseNode {
|
|
256
|
-
type:
|
|
258
|
+
type:
|
|
259
|
+
| 'markdown'
|
|
260
|
+
| 'visual-break'
|
|
261
|
+
| 'background-image'
|
|
262
|
+
| 'artpack-image'
|
|
263
|
+
| 'grid-layout';
|
|
257
264
|
hiddenViewportMobile?: boolean;
|
|
258
265
|
hiddenViewportTablet?: boolean;
|
|
259
266
|
hiddenViewportDesktop?: boolean;
|
|
@@ -272,6 +279,22 @@ export interface MarkdownPaneFragmentNode extends PaneFragmentNode {
|
|
|
272
279
|
>;
|
|
273
280
|
parentClasses?: ParentClassesPayload;
|
|
274
281
|
parentCss?: string[];
|
|
282
|
+
gridClasses?: DefaultClassValue;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface GridLayoutNode extends PaneFragmentNode {
|
|
286
|
+
nodeType: 'GridLayoutNode';
|
|
287
|
+
type: 'grid-layout';
|
|
288
|
+
parentClasses?: ParentClassesPayload;
|
|
289
|
+
defaultClasses?: Record<
|
|
290
|
+
string,
|
|
291
|
+
{
|
|
292
|
+
mobile: Record<string, string>;
|
|
293
|
+
tablet: Record<string, string>;
|
|
294
|
+
desktop: Record<string, string>;
|
|
295
|
+
}
|
|
296
|
+
>;
|
|
297
|
+
gridColumns: { mobile: number; tablet: number; desktop: number };
|
|
275
298
|
}
|
|
276
299
|
|
|
277
300
|
export interface ArtpackImageNode extends PaneFragmentNode {
|
|
@@ -481,7 +504,7 @@ export type LoadData = {
|
|
|
481
504
|
paneNodes?: PaneNode[];
|
|
482
505
|
tractstackNodes?: TractStackNode[];
|
|
483
506
|
childNodes?: (BaseNode | FlatNode)[];
|
|
484
|
-
paneFragmentNodes?: PaneFragmentNode[];
|
|
507
|
+
paneFragmentNodes?: (PaneFragmentNode | GridLayoutNode)[];
|
|
485
508
|
flatNodes?: FlatNode[];
|
|
486
509
|
impressionNodes?: ImpressionNode[];
|
|
487
510
|
beliefNodes?: BeliefNode[];
|
|
@@ -511,6 +534,18 @@ export interface BasePanelProps {
|
|
|
511
534
|
onTitleChange?: (title: string) => void;
|
|
512
535
|
}
|
|
513
536
|
|
|
537
|
+
export type ParentBasePanelProps = {
|
|
538
|
+
node: MarkdownPaneFragmentNode | GridLayoutNode | null;
|
|
539
|
+
parentNode?: FlatNode | PaneNode;
|
|
540
|
+
config?: BrandConfig | null;
|
|
541
|
+
layer?: number;
|
|
542
|
+
className?: string;
|
|
543
|
+
childId?: string;
|
|
544
|
+
availableCodeHooks?: string[];
|
|
545
|
+
onTitleChange?: (title: string) => void;
|
|
546
|
+
targetProperty?: 'parentClasses' | 'gridClasses';
|
|
547
|
+
};
|
|
548
|
+
|
|
514
549
|
interface WidgetParameterDefinition {
|
|
515
550
|
label: string;
|
|
516
551
|
defaultValue: string;
|
|
@@ -7,6 +7,7 @@ export const TemplateH2Node = {
|
|
|
7
7
|
{
|
|
8
8
|
copy: 'Catchy title',
|
|
9
9
|
tagName: 'text',
|
|
10
|
+
nodeType: 'TagElement',
|
|
10
11
|
},
|
|
11
12
|
],
|
|
12
13
|
} as TemplateNode;
|
|
@@ -18,6 +19,7 @@ export const TemplateH3Node = {
|
|
|
18
19
|
{
|
|
19
20
|
copy: 'Catchy sub-title',
|
|
20
21
|
tagName: 'text',
|
|
22
|
+
nodeType: 'TagElement',
|
|
21
23
|
},
|
|
22
24
|
],
|
|
23
25
|
} as TemplateNode;
|
|
@@ -29,6 +31,7 @@ export const TemplateH4Node = {
|
|
|
29
31
|
{
|
|
30
32
|
copy: 'Catchy sub-title',
|
|
31
33
|
tagName: 'text',
|
|
34
|
+
nodeType: 'TagElement',
|
|
32
35
|
},
|
|
33
36
|
],
|
|
34
37
|
} as TemplateNode;
|
|
@@ -40,6 +43,7 @@ export const TemplatePNode = {
|
|
|
40
43
|
{
|
|
41
44
|
copy: '...',
|
|
42
45
|
tagName: 'text',
|
|
46
|
+
nodeType: 'TagElement',
|
|
43
47
|
},
|
|
44
48
|
],
|
|
45
49
|
} as TemplateNode;
|
|
@@ -51,6 +55,7 @@ export const TemplateOLNode = {
|
|
|
51
55
|
{
|
|
52
56
|
copy: '...',
|
|
53
57
|
tagName: 'text',
|
|
58
|
+
nodeType: 'TagElement',
|
|
54
59
|
},
|
|
55
60
|
],
|
|
56
61
|
} as TemplateNode;
|
|
@@ -62,6 +67,7 @@ export const TemplateULNode = {
|
|
|
62
67
|
{
|
|
63
68
|
copy: '...',
|
|
64
69
|
tagName: 'text',
|
|
70
|
+
nodeType: 'TagElement',
|
|
65
71
|
},
|
|
66
72
|
],
|
|
67
73
|
} as TemplateNode;
|
|
@@ -73,6 +79,7 @@ export const TemplateLINode = {
|
|
|
73
79
|
{
|
|
74
80
|
copy: '...',
|
|
75
81
|
tagName: 'text',
|
|
82
|
+
nodeType: 'TagElement',
|
|
76
83
|
},
|
|
77
84
|
],
|
|
78
85
|
} as TemplateNode;
|
|
@@ -84,6 +91,7 @@ export const TemplateLINode = {
|
|
|
84
91
|
// {
|
|
85
92
|
// copy: "aside node",
|
|
86
93
|
// tagName: "text",
|
|
94
|
+
//nodeType: 'TagElement',
|
|
87
95
|
// },
|
|
88
96
|
// ],
|
|
89
97
|
//} as TemplateNode;
|
|
@@ -14,13 +14,19 @@ import {
|
|
|
14
14
|
TemplateYoutubeNode,
|
|
15
15
|
} from './TemplateNodes';
|
|
16
16
|
import { getCtx, NodesContext } from '@/stores/nodes';
|
|
17
|
+
import { settingsPanelStore } from '@/stores/storykeep';
|
|
18
|
+
import { PatchOp } from '@/stores/nodesHistory';
|
|
17
19
|
import { cloneDeep } from '@/utils/helpers';
|
|
20
|
+
import { isPaneNode } from './typeGuards';
|
|
18
21
|
import type {
|
|
19
22
|
BaseNode,
|
|
20
23
|
FlatNode,
|
|
21
24
|
StoryFragmentNode,
|
|
22
25
|
TemplateNode,
|
|
23
26
|
ToolAddMode,
|
|
27
|
+
MarkdownPaneFragmentNode,
|
|
28
|
+
GridLayoutNode,
|
|
29
|
+
PaneNode,
|
|
24
30
|
} from '@/types/compositorTypes';
|
|
25
31
|
import type { NodeTagProps } from '@/types/nodeProps';
|
|
26
32
|
|
|
@@ -512,3 +518,226 @@ export function extractClassesFromNodes(dirtyNodes: BaseNode[]): string[] {
|
|
|
512
518
|
|
|
513
519
|
return Array.from(uniqueClasses);
|
|
514
520
|
}
|
|
521
|
+
|
|
522
|
+
export function revertFromGrid(gridLayoutId: string) {
|
|
523
|
+
const ctx = getCtx();
|
|
524
|
+
const originalAllNodes = new Map(ctx.allNodes.get());
|
|
525
|
+
const originalParentNodes = new Map(ctx.parentNodes.get());
|
|
526
|
+
|
|
527
|
+
const gridLayoutNode = originalAllNodes.get(gridLayoutId) as GridLayoutNode;
|
|
528
|
+
if (!gridLayoutNode || !gridLayoutNode.parentId) return;
|
|
529
|
+
|
|
530
|
+
const paneNode = originalAllNodes.get(gridLayoutNode.parentId) as PaneNode;
|
|
531
|
+
if (!paneNode || !isPaneNode(paneNode)) return;
|
|
532
|
+
|
|
533
|
+
const childIds = originalParentNodes.get(gridLayoutId) || [];
|
|
534
|
+
|
|
535
|
+
const redoLogic = () => {
|
|
536
|
+
const newAllNodes = new Map(originalAllNodes);
|
|
537
|
+
const newParentNodes = new Map(originalParentNodes);
|
|
538
|
+
|
|
539
|
+
if (childIds.length === 0) {
|
|
540
|
+
const paneChildren = [...(newParentNodes.get(paneNode.id) || [])];
|
|
541
|
+
const gridIndex = paneChildren.indexOf(gridLayoutId);
|
|
542
|
+
if (gridIndex > -1) {
|
|
543
|
+
paneChildren.splice(gridIndex, 1);
|
|
544
|
+
}
|
|
545
|
+
newParentNodes.set(paneNode.id, paneChildren);
|
|
546
|
+
newAllNodes.delete(gridLayoutId);
|
|
547
|
+
newParentNodes.delete(gridLayoutId);
|
|
548
|
+
} else {
|
|
549
|
+
const markdownNodeToKeepId = childIds[0];
|
|
550
|
+
const markdownNodeToKeep = cloneDeep(
|
|
551
|
+
newAllNodes.get(markdownNodeToKeepId)
|
|
552
|
+
) as MarkdownPaneFragmentNode;
|
|
553
|
+
|
|
554
|
+
markdownNodeToKeep.parentId = paneNode.id;
|
|
555
|
+
markdownNodeToKeep.parentClasses = gridLayoutNode.parentClasses || [];
|
|
556
|
+
markdownNodeToKeep.defaultClasses = gridLayoutNode.defaultClasses || {};
|
|
557
|
+
markdownNodeToKeep.isChanged = true;
|
|
558
|
+
newAllNodes.set(markdownNodeToKeepId, markdownNodeToKeep);
|
|
559
|
+
|
|
560
|
+
const paneChildren = [...(newParentNodes.get(paneNode.id) || [])];
|
|
561
|
+
const gridIndex = paneChildren.indexOf(gridLayoutId);
|
|
562
|
+
if (gridIndex > -1) {
|
|
563
|
+
paneChildren.splice(gridIndex, 1, markdownNodeToKeepId);
|
|
564
|
+
}
|
|
565
|
+
newParentNodes.set(paneNode.id, paneChildren);
|
|
566
|
+
|
|
567
|
+
const nodesToDeleteIds = [gridLayoutId, ...childIds.slice(1)];
|
|
568
|
+
nodesToDeleteIds.forEach((id) => {
|
|
569
|
+
newAllNodes.delete(id);
|
|
570
|
+
newParentNodes.delete(id);
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const updatedPaneNode = cloneDeep(paneNode);
|
|
575
|
+
updatedPaneNode.isChanged = true;
|
|
576
|
+
newAllNodes.set(paneNode.id, updatedPaneNode);
|
|
577
|
+
|
|
578
|
+
ctx.allNodes.set(newAllNodes);
|
|
579
|
+
ctx.parentNodes.set(newParentNodes);
|
|
580
|
+
ctx.notifyNode('root');
|
|
581
|
+
settingsPanelStore.set(null);
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
const undoLogic = () => {
|
|
585
|
+
ctx.allNodes.set(originalAllNodes);
|
|
586
|
+
ctx.parentNodes.set(originalParentNodes);
|
|
587
|
+
ctx.notifyNode('root');
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
ctx.history.addPatch({
|
|
591
|
+
op: PatchOp.REPLACE,
|
|
592
|
+
undo: undoLogic,
|
|
593
|
+
redo: redoLogic,
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
redoLogic();
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
export function convertToGrid(markdownNodeId: string) {
|
|
600
|
+
const ctx = getCtx();
|
|
601
|
+
|
|
602
|
+
const originalAllNodes = new Map(ctx.allNodes.get());
|
|
603
|
+
const originalParentNodes = new Map(ctx.parentNodes.get());
|
|
604
|
+
|
|
605
|
+
const markdownNode = originalAllNodes.get(
|
|
606
|
+
markdownNodeId
|
|
607
|
+
) as MarkdownPaneFragmentNode;
|
|
608
|
+
if (!markdownNode || !markdownNode.parentId) return;
|
|
609
|
+
|
|
610
|
+
const paneNode = originalAllNodes.get(markdownNode.parentId) as PaneNode & {
|
|
611
|
+
markdownId?: string;
|
|
612
|
+
markdownBody?: string;
|
|
613
|
+
};
|
|
614
|
+
if (!paneNode || !isPaneNode(paneNode)) return;
|
|
615
|
+
|
|
616
|
+
const gridLayoutId = ulid();
|
|
617
|
+
|
|
618
|
+
const redoLogic = () => {
|
|
619
|
+
const newAllNodes = new Map(originalAllNodes);
|
|
620
|
+
const newParentNodes = new Map(originalParentNodes);
|
|
621
|
+
|
|
622
|
+
const newGridLayoutNode: GridLayoutNode = {
|
|
623
|
+
id: gridLayoutId,
|
|
624
|
+
parentId: paneNode.id,
|
|
625
|
+
nodeType: 'GridLayoutNode',
|
|
626
|
+
type: 'grid-layout',
|
|
627
|
+
parentClasses: markdownNode.parentClasses || [],
|
|
628
|
+
defaultClasses: markdownNode.defaultClasses || {},
|
|
629
|
+
gridColumns: { mobile: 1, tablet: 2, desktop: 2 },
|
|
630
|
+
isChanged: true,
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
const updatedMarkdownNode = cloneDeep(markdownNode);
|
|
634
|
+
updatedMarkdownNode.parentId = gridLayoutId;
|
|
635
|
+
updatedMarkdownNode.parentClasses = [];
|
|
636
|
+
updatedMarkdownNode.parentCss = [];
|
|
637
|
+
updatedMarkdownNode.defaultClasses = {};
|
|
638
|
+
updatedMarkdownNode.isChanged = true;
|
|
639
|
+
|
|
640
|
+
// Create a new, truly empty MarkdownNode for the second column.
|
|
641
|
+
const newColumnNodeId = ulid();
|
|
642
|
+
const newColumnNode: MarkdownPaneFragmentNode = {
|
|
643
|
+
id: newColumnNodeId,
|
|
644
|
+
parentId: gridLayoutId,
|
|
645
|
+
nodeType: 'Markdown',
|
|
646
|
+
type: 'markdown',
|
|
647
|
+
markdownId: ulid(),
|
|
648
|
+
defaultClasses: {},
|
|
649
|
+
parentClasses: [],
|
|
650
|
+
isChanged: true,
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
newAllNodes.set(gridLayoutId, newGridLayoutNode);
|
|
654
|
+
newAllNodes.set(markdownNodeId, updatedMarkdownNode);
|
|
655
|
+
newAllNodes.set(paneNode.id, { ...cloneDeep(paneNode), isChanged: true });
|
|
656
|
+
newAllNodes.set(newColumnNodeId, newColumnNode);
|
|
657
|
+
|
|
658
|
+
const paneChildren = [...(newParentNodes.get(paneNode.id) || [])];
|
|
659
|
+
const mdIndex = paneChildren.indexOf(markdownNodeId);
|
|
660
|
+
if (mdIndex > -1) {
|
|
661
|
+
paneChildren.splice(mdIndex, 1, gridLayoutId);
|
|
662
|
+
}
|
|
663
|
+
newParentNodes.set(paneNode.id, paneChildren);
|
|
664
|
+
newParentNodes.set(gridLayoutId, [markdownNodeId, newColumnNodeId]);
|
|
665
|
+
newParentNodes.set(newColumnNodeId, []); // Set children to an empty array
|
|
666
|
+
|
|
667
|
+
ctx.allNodes.set(newAllNodes);
|
|
668
|
+
ctx.parentNodes.set(newParentNodes);
|
|
669
|
+
ctx.notifyNode('root');
|
|
670
|
+
settingsPanelStore.set(null);
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
const undoLogic = () => {
|
|
674
|
+
ctx.allNodes.set(originalAllNodes);
|
|
675
|
+
ctx.parentNodes.set(originalParentNodes);
|
|
676
|
+
ctx.notifyNode('root');
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
ctx.history.addPatch({
|
|
680
|
+
op: PatchOp.REPLACE,
|
|
681
|
+
undo: undoLogic,
|
|
682
|
+
redo: redoLogic,
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
redoLogic();
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
export function addColumn(gridLayoutId: string) {
|
|
689
|
+
const ctx = getCtx();
|
|
690
|
+
const originalAllNodes = new Map(ctx.allNodes.get());
|
|
691
|
+
const originalParentNodes = new Map(ctx.parentNodes.get());
|
|
692
|
+
|
|
693
|
+
const gridLayoutNode = originalAllNodes.get(gridLayoutId);
|
|
694
|
+
if (!gridLayoutNode) return;
|
|
695
|
+
|
|
696
|
+
const newMarkdownNodeId = ulid();
|
|
697
|
+
|
|
698
|
+
const redoLogic = () => {
|
|
699
|
+
const newAllNodes = new Map(originalAllNodes);
|
|
700
|
+
const newParentNodes = new Map(originalParentNodes);
|
|
701
|
+
|
|
702
|
+
const newColumnNode: MarkdownPaneFragmentNode = {
|
|
703
|
+
id: newMarkdownNodeId,
|
|
704
|
+
parentId: gridLayoutId,
|
|
705
|
+
nodeType: 'Markdown',
|
|
706
|
+
type: 'markdown',
|
|
707
|
+
markdownId: ulid(),
|
|
708
|
+
defaultClasses: {},
|
|
709
|
+
parentClasses: [],
|
|
710
|
+
gridClasses: { mobile: {}, tablet: {}, desktop: {} },
|
|
711
|
+
isChanged: true,
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
newAllNodes.set(newMarkdownNodeId, newColumnNode);
|
|
715
|
+
|
|
716
|
+
const gridChildren = [...(newParentNodes.get(gridLayoutId) || [])];
|
|
717
|
+
gridChildren.push(newMarkdownNodeId);
|
|
718
|
+
newParentNodes.set(gridLayoutId, gridChildren);
|
|
719
|
+
newParentNodes.set(newMarkdownNodeId, []); // Set children to an empty array
|
|
720
|
+
|
|
721
|
+
const updatedGridLayoutNode = cloneDeep(gridLayoutNode);
|
|
722
|
+
updatedGridLayoutNode.isChanged = true;
|
|
723
|
+
newAllNodes.set(gridLayoutId, updatedGridLayoutNode);
|
|
724
|
+
|
|
725
|
+
ctx.allNodes.set(newAllNodes);
|
|
726
|
+
ctx.parentNodes.set(newParentNodes);
|
|
727
|
+
ctx.notifyNode('root');
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
const undoLogic = () => {
|
|
731
|
+
ctx.allNodes.set(originalAllNodes);
|
|
732
|
+
ctx.parentNodes.set(originalParentNodes);
|
|
733
|
+
ctx.notifyNode('root');
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
ctx.history.addPatch({
|
|
737
|
+
op: PatchOp.ADD,
|
|
738
|
+
undo: undoLogic,
|
|
739
|
+
redo: redoLogic,
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
redoLogic();
|
|
743
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { tailwindClasses, tailwindCoreLayoutClasses } from './tailwindClasses';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
TupleValue,
|
|
4
|
+
ViewportKey,
|
|
5
|
+
DefaultClassValue,
|
|
6
|
+
} from '@/types/compositorTypes';
|
|
3
7
|
|
|
4
8
|
const tailwindModifier = ['', 'md:', 'xl:'];
|
|
5
9
|
const tailwindCoreModifier = ['xs:', 'md:', 'xl:'];
|
|
@@ -194,3 +198,38 @@ function getTailwindClassInfo(selector: string): {
|
|
|
194
198
|
useKeyAsClass: classInfo.useKeyAsClass,
|
|
195
199
|
};
|
|
196
200
|
}
|
|
201
|
+
|
|
202
|
+
export function processGridClassesToString(
|
|
203
|
+
classes?: DefaultClassValue
|
|
204
|
+
): string {
|
|
205
|
+
if (!classes) {
|
|
206
|
+
return '';
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const finalClasses: string[] = [];
|
|
210
|
+
const mobileStyles = classes.mobile || {};
|
|
211
|
+
const tabletStyles = classes.tablet || {};
|
|
212
|
+
const desktopStyles = classes.desktop || {};
|
|
213
|
+
|
|
214
|
+
for (const [selector, value] of Object.entries(mobileStyles)) {
|
|
215
|
+
if (value) {
|
|
216
|
+
finalClasses.push(reduceClassName(selector, value, 0));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
for (const [selector, value] of Object.entries(tabletStyles)) {
|
|
221
|
+
if (value && mobileStyles[selector] !== value) {
|
|
222
|
+
finalClasses.push(reduceClassName(selector, value, 1));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
for (const [selector, value] of Object.entries(desktopStyles)) {
|
|
227
|
+
const tabletValue = tabletStyles[selector];
|
|
228
|
+
const mobileValue = mobileStyles[selector];
|
|
229
|
+
if (value && tabletValue !== value && mobileValue !== value) {
|
|
230
|
+
finalClasses.push(reduceClassName(selector, value, 2));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return finalClasses.filter(Boolean).join(' ');
|
|
235
|
+
}
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
ArtpackImageNode,
|
|
11
11
|
BgImageNode,
|
|
12
12
|
Tag,
|
|
13
|
+
GridLayoutNode,
|
|
13
14
|
} from '@/types/compositorTypes';
|
|
14
15
|
|
|
15
16
|
interface BreakData {
|
|
@@ -192,3 +193,9 @@ export function hasPlayerJS(
|
|
|
192
193
|
): window is Window & { playerjs: PlayerJS } {
|
|
193
194
|
return 'playerjs' in window;
|
|
194
195
|
}
|
|
196
|
+
|
|
197
|
+
export function isGridLayoutNode(
|
|
198
|
+
node: BaseNode | undefined | null
|
|
199
|
+
): node is GridLayoutNode {
|
|
200
|
+
return node?.nodeType === 'GridLayoutNode';
|
|
201
|
+
}
|
|
@@ -52,11 +52,8 @@ export function extractPaneSubtree(
|
|
|
52
52
|
bgColour: paneNode.bgColour,
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
// --- START: REPLACEMENT FOR getNodesRecursively ---
|
|
56
|
-
// Use a safe, non-recursive breadth-first traversal to gather all descendant
|
|
57
|
-
// nodes, which preserves the correct sibling order.
|
|
58
55
|
const allDescendantNodes: BaseNode[] = [];
|
|
59
|
-
const queue: string[] = [...ctx.getChildNodeIDs(paneNode.id)];
|
|
56
|
+
const queue: string[] = [...ctx.getChildNodeIDs(paneNode.id)];
|
|
60
57
|
|
|
61
58
|
while (queue.length > 0) {
|
|
62
59
|
const currentId = queue.shift();
|
|
@@ -70,7 +67,6 @@ export function extractPaneSubtree(
|
|
|
70
67
|
queue.push(...childrenIds);
|
|
71
68
|
}
|
|
72
69
|
}
|
|
73
|
-
// --- END: REPLACEMENT FOR getNodesRecursively ---
|
|
74
70
|
|
|
75
71
|
if (VERBOSE)
|
|
76
72
|
console.log(
|