astro-tractstack 2.0.0-rc.8 → 2.0.0
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/LICENSE +8 -97
- package/README.md +7 -5
- package/bin/create-tractstack.js +35 -11
- package/dist/index.js +106 -29
- package/package.json +10 -5
- package/templates/css/frontend.css +1 -1
- package/templates/custom/minimal/CodeHook.astro +13 -12
- package/templates/custom/minimal/CustomRoutes.astro +25 -31
- package/templates/custom/with-examples/CodeHook.astro +22 -11
- package/templates/custom/with-examples/CustomRoutes.astro +4 -8
- package/templates/custom/with-examples/ProductCard.astro +29 -0
- package/templates/custom/with-examples/ProductCardWrapper.astro +43 -0
- package/templates/custom/with-examples/ProductGrid.astro +64 -0
- package/templates/custom/with-examples/pages/Collections.astro +58 -98
- package/templates/gitignore +42 -0
- package/templates/prettierignore +5 -0
- package/templates/prettierrc +19 -0
- package/templates/src/client/app.js +127 -0
- package/templates/src/client/htmx.min.js +3519 -0
- package/templates/src/client/view.js +429 -0
- package/templates/src/components/Footer.astro +4 -9
- package/templates/src/components/Header.astro +67 -60
- package/templates/src/components/Menu.tsx +188 -52
- package/templates/src/components/codehooks/BunnyVideoSetup.tsx +2 -2
- package/templates/src/components/codehooks/EpinetDurationSelector.tsx +9 -13
- package/templates/src/components/codehooks/EpinetTableView.tsx +11 -7
- package/templates/src/components/codehooks/EpinetWrapper.tsx +1 -0
- package/templates/src/components/codehooks/FeaturedArticle.astro +105 -0
- package/templates/src/components/codehooks/FeaturedArticleSetup.tsx +318 -0
- package/templates/src/components/codehooks/ListContent.astro +32 -162
- package/templates/src/components/codehooks/ListContentSetup.tsx +43 -138
- package/templates/src/components/codehooks/ProductCardSetup.tsx +152 -0
- package/templates/src/components/codehooks/ProductGridSetup.tsx +274 -0
- package/templates/src/components/codehooks/SearchWidget.tsx +453 -0
- package/templates/src/components/compositor/Node.tsx +3 -6
- package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +21 -11
- package/templates/src/components/compositor/elements/BunnyVideo.tsx +21 -20
- package/templates/src/components/compositor/nodes/Pane.tsx +51 -21
- package/templates/src/components/compositor/nodes/RenderChildren.tsx +6 -1
- package/templates/src/components/compositor/nodes/Widget.tsx +16 -2
- package/templates/src/components/compositor/preview/FeaturedArticlePreview.tsx +155 -0
- package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +20 -1
- package/templates/src/components/edit/Header.tsx +10 -4
- package/templates/src/components/edit/PanelSwitch.tsx +11 -7
- package/templates/src/components/edit/SettingsPanel.tsx +29 -18
- package/templates/src/components/edit/ToolBar.tsx +1 -28
- package/templates/src/components/edit/ToolMode.tsx +45 -32
- package/templates/src/components/edit/pane/AddPanePanel_break.tsx +12 -2
- package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +8 -2
- package/templates/src/components/edit/pane/AddPanePanel_newAICopy_modal.tsx +1 -1
- package/templates/src/components/edit/pane/ConfigPanePanel.tsx +17 -27
- package/templates/src/components/edit/pane/PageGenSelector.tsx +16 -16
- package/templates/src/components/edit/pane/PageGenSpecial.tsx +26 -49
- package/templates/src/components/edit/pane/PageGen_preview.tsx +17 -2
- package/templates/src/components/edit/pane/PanePanel_path.tsx +2 -4
- package/templates/src/components/edit/pane/PanePanel_title.tsx +243 -76
- package/templates/src/components/edit/panels/StyleBreakPanel.tsx +17 -19
- package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +48 -37
- package/templates/src/components/edit/panels/StyleElementPanel_add.tsx +60 -55
- package/templates/src/components/edit/panels/StyleImagePanel_add.tsx +56 -50
- package/templates/src/components/edit/panels/StyleLiElementPanel_add.tsx +54 -47
- package/templates/src/components/edit/panels/StyleLinkPanel_add.tsx +54 -44
- package/templates/src/components/edit/panels/StyleLinkPanel_config.tsx +113 -138
- package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +54 -40
- package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +3 -3
- package/templates/src/components/edit/panels/StyleWidgetPanel_add.tsx +56 -49
- package/templates/src/components/edit/panels/StyleWidgetPanel_config.tsx +14 -5
- package/templates/src/components/edit/state/SaveModal.tsx +316 -169
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_og.tsx +1 -1
- package/templates/src/components/edit/storyfragment/StoryFragmentPanel_slug.tsx +56 -55
- package/templates/src/components/edit/widgets/BunnyWidget.tsx +538 -59
- package/templates/src/components/edit/widgets/InteractiveDisclosureWidget.tsx +656 -0
- package/templates/src/components/edit/widgets/ToggleWidget.tsx +9 -16
- package/templates/src/components/fields/ArtpackImage.tsx +4 -1
- package/templates/src/components/fields/BackgroundImage.tsx +1 -1
- package/templates/src/components/fields/BackgroundImageWrapper.tsx +127 -35
- package/templates/src/components/fields/ColorPickerCombo.tsx +66 -62
- package/templates/src/components/fields/ImageUpload.tsx +1 -1
- package/templates/src/components/fields/ViewportComboBox.tsx +59 -42
- package/templates/src/components/form/ActionBuilderBeliefSelector.tsx +117 -0
- package/templates/src/components/form/ActionBuilderField.tsx +306 -87
- package/templates/src/components/search/SearchModal.tsx +420 -0
- package/templates/src/components/search/SearchResults.tsx +367 -0
- package/templates/src/components/search/SearchWrapper.tsx +46 -0
- package/templates/src/components/storykeep/Dashboard_Advanced.tsx +1 -1
- package/templates/src/components/storykeep/Dashboard_Analytics.tsx +34 -8
- package/templates/src/components/storykeep/Dashboard_Content.tsx +6 -0
- package/templates/src/components/storykeep/StoryKeepBackdrop.astro +87 -0
- package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +37 -33
- package/templates/src/components/storykeep/controls/content/MenuForm.tsx +55 -7
- package/templates/src/components/storykeep/controls/content/ResourceForm.tsx +17 -2
- package/templates/src/components/storykeep/controls/content/StoryFragmentTable.tsx +5 -8
- package/templates/src/components/storykeep/state/FetchAnalytics.tsx +274 -228
- package/templates/src/components/storykeep/widgets/Wizard.tsx +14 -7
- package/templates/src/components/tenant/RegistrationForm.tsx +1 -1
- package/templates/src/components/widgets/ImpressionWrapper.tsx +0 -1
- package/templates/src/constants/shapes.ts +9 -0
- package/templates/src/constants.ts +2121 -16
- package/templates/src/hooks/useSearch.ts +228 -0
- package/templates/src/layouts/Layout.astro +213 -104
- package/templates/src/lib/storyData.ts +4 -1
- package/templates/src/pages/[...slug]/edit.astro +14 -14
- package/templates/src/pages/[...slug].astro +82 -21
- package/templates/src/pages/api/orphan-analysis.ts +0 -1
- package/templates/src/pages/api/tailwind.ts +23 -21
- package/templates/src/pages/context/[...contextSlug]/edit.astro +14 -14
- package/templates/src/pages/context/[...contextSlug].astro +7 -2
- package/templates/src/pages/storykeep/advanced.astro +5 -4
- package/templates/src/pages/storykeep/branding.astro +5 -4
- package/templates/src/pages/storykeep/content.astro +5 -4
- package/templates/src/pages/storykeep/init.astro +40 -1
- package/templates/src/pages/storykeep/login.astro +1 -1
- package/templates/src/pages/storykeep.astro +5 -4
- package/templates/src/stores/nodes.ts +59 -88
- package/templates/src/stores/orphanAnalysis.ts +19 -21
- package/templates/src/stores/storykeep.ts +7 -0
- package/templates/src/types/compositorTypes.ts +6 -0
- package/templates/src/types/tractstack.ts +17 -0
- package/templates/src/utils/actions/lispLexer.ts +2 -2
- package/templates/src/utils/actions/preParse_Action.ts +3 -0
- package/templates/src/utils/api/beliefHelpers.ts +12 -36
- package/templates/src/utils/api/menuHelpers.ts +2 -2
- package/templates/src/utils/api.ts +26 -0
- package/templates/src/utils/compositor/TemplateNodes.ts +7 -0
- package/templates/src/utils/compositor/allowInsert.ts +5 -3
- package/templates/src/utils/compositor/nodesHelper.ts +4 -0
- package/templates/src/utils/compositor/processMarkdown.ts +16 -2
- package/templates/src/utils/compositor/reduceNodesClassNames.ts +4 -0
- package/templates/src/utils/compositor/templateMarkdownStyles.ts +13 -13
- package/templates/src/utils/compositor/typeGuards.ts +1 -0
- package/templates/src/utils/customHelpers.ts +38 -0
- package/templates/src/utils/helpers.ts +2 -2
- package/templates/src/utils/layout.ts +65 -144
- package/utils/inject-files.ts +95 -18
- package/templates/src/client/analytics-events.js +0 -207
- package/templates/src/client/belief-events.js +0 -191
- package/templates/src/client/sse.js +0 -613
- package/templates/src/components/codehooks/FeaturedContent.astro +0 -273
- package/templates/src/components/codehooks/FeaturedContentSetup.tsx +0 -738
- package/templates/src/components/compositor/preview/FeaturedContentPreview.tsx +0 -128
- package/templates/src/components/edit/pane/PanePanel_slug.tsx +0 -219
|
@@ -2,6 +2,7 @@ import { ulid } from 'ulid';
|
|
|
2
2
|
import {
|
|
3
3
|
TemplateBeliefNode,
|
|
4
4
|
TemplateBunnyNode,
|
|
5
|
+
TemplateDisclosureNode,
|
|
5
6
|
TemplateEmailSignUpNode,
|
|
6
7
|
TemplateH2Node,
|
|
7
8
|
TemplateH3Node,
|
|
@@ -56,6 +57,9 @@ export const getTemplateNode = (value: ToolAddMode): TemplateNode => {
|
|
|
56
57
|
case 'identify':
|
|
57
58
|
templateNode = cloneDeep(TemplateIdentifyAsNode);
|
|
58
59
|
break;
|
|
60
|
+
case 'interactiveDisclosure':
|
|
61
|
+
templateNode = cloneDeep(TemplateDisclosureNode);
|
|
62
|
+
break;
|
|
59
63
|
case 'p':
|
|
60
64
|
default:
|
|
61
65
|
templateNode = cloneDeep(TemplatePNode);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ulid } from 'ulid';
|
|
2
2
|
import { NodesContext } from '@/stores/nodes';
|
|
3
3
|
import { fullContentMapStore } from '@/stores/storykeep';
|
|
4
|
+
import { tailwindToHex } from './tailwindColors';
|
|
5
|
+
import { SvgBreaks } from '@/constants/shapes';
|
|
4
6
|
import { findUniqueSlug } from '@/utils/helpers';
|
|
5
7
|
import type {
|
|
6
8
|
PageDesign,
|
|
@@ -276,8 +278,20 @@ export async function createPagePanes(
|
|
|
276
278
|
const aboveColor = abovePane?.bgColour || 'white';
|
|
277
279
|
const nextContentPane = design.contentDesign(!useOdd);
|
|
278
280
|
const belowColor = nextContentPane.bgColour;
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
+
const breakData = breakTemplate.bgPane?.breakDesktop;
|
|
282
|
+
const shapeName = breakData
|
|
283
|
+
? `${breakData.collection}${breakData.image}`
|
|
284
|
+
: '';
|
|
285
|
+
const isFlipped = (shapeName && SvgBreaks[shapeName]?.flipped) || false;
|
|
286
|
+
|
|
287
|
+
breakTemplate.bgColour = tailwindToHex(
|
|
288
|
+
isFlipped ? belowColor : aboveColor,
|
|
289
|
+
null
|
|
290
|
+
);
|
|
291
|
+
const svgFill = tailwindToHex(
|
|
292
|
+
isFlipped ? aboveColor : belowColor,
|
|
293
|
+
null
|
|
294
|
+
);
|
|
281
295
|
if (breakTemplate.bgPane) {
|
|
282
296
|
if (breakTemplate.bgPane.breakDesktop) {
|
|
283
297
|
breakTemplate.bgPane.breakDesktop.svgFill = svgFill;
|
|
@@ -85,6 +85,10 @@ const reduceClassName = (
|
|
|
85
85
|
if (useKeyAsClass && typeof v === 'string')
|
|
86
86
|
return `${modifier}${applyPrefix(v)}`;
|
|
87
87
|
if (typeof v === 'string' || typeof v === 'number') {
|
|
88
|
+
// Add check for empty string
|
|
89
|
+
if (typeof v === 'string' && v.trim() === '') {
|
|
90
|
+
return '';
|
|
91
|
+
}
|
|
88
92
|
if (typeof v === 'string' && v.startsWith('-')) {
|
|
89
93
|
return `${modifier}-${applyPrefix(`${thisSelector}${v}`)}`;
|
|
90
94
|
}
|
|
@@ -360,6 +360,7 @@ export function getJustCopyDesign(
|
|
|
360
360
|
baseClasses[2].mobile.maxW = '3xl';
|
|
361
361
|
if (bordered) {
|
|
362
362
|
baseClasses[2].mobile.rounded = 'lg';
|
|
363
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
363
364
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
364
365
|
{
|
|
365
366
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -371,7 +372,6 @@ export function getJustCopyDesign(
|
|
|
371
372
|
},
|
|
372
373
|
theme
|
|
373
374
|
);
|
|
374
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
375
375
|
}
|
|
376
376
|
break;
|
|
377
377
|
}
|
|
@@ -385,6 +385,7 @@ export function getJustCopyDesign(
|
|
|
385
385
|
baseClasses[2].mobile.textWRAP = 'balance';
|
|
386
386
|
if (bordered) {
|
|
387
387
|
baseClasses[2].mobile.rounded = 'lg';
|
|
388
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
388
389
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
389
390
|
{
|
|
390
391
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -396,7 +397,6 @@ export function getJustCopyDesign(
|
|
|
396
397
|
},
|
|
397
398
|
theme
|
|
398
399
|
);
|
|
399
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
400
400
|
}
|
|
401
401
|
break;
|
|
402
402
|
}
|
|
@@ -408,6 +408,7 @@ export function getJustCopyDesign(
|
|
|
408
408
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
409
409
|
if (bordered) {
|
|
410
410
|
baseClasses[2].mobile.rounded = 'lg';
|
|
411
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
411
412
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
412
413
|
{
|
|
413
414
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -419,7 +420,6 @@ export function getJustCopyDesign(
|
|
|
419
420
|
},
|
|
420
421
|
theme
|
|
421
422
|
);
|
|
422
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
423
423
|
}
|
|
424
424
|
}
|
|
425
425
|
}
|
|
@@ -507,6 +507,7 @@ export function getSubTitleDesign(
|
|
|
507
507
|
baseClasses[2].mobile.maxW = '3xl';
|
|
508
508
|
if (bordered) {
|
|
509
509
|
baseClasses[2].mobile.rounded = 'lg';
|
|
510
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
510
511
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
511
512
|
{
|
|
512
513
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -518,7 +519,6 @@ export function getSubTitleDesign(
|
|
|
518
519
|
},
|
|
519
520
|
theme
|
|
520
521
|
);
|
|
521
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
522
522
|
}
|
|
523
523
|
break;
|
|
524
524
|
}
|
|
@@ -557,6 +557,7 @@ export function getSubTitleDesign(
|
|
|
557
557
|
baseClasses[2].mobile.textWRAP = 'balance';
|
|
558
558
|
if (bordered) {
|
|
559
559
|
baseClasses[2].mobile.rounded = 'lg';
|
|
560
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
560
561
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
561
562
|
{
|
|
562
563
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -568,7 +569,6 @@ export function getSubTitleDesign(
|
|
|
568
569
|
},
|
|
569
570
|
theme
|
|
570
571
|
);
|
|
571
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
572
572
|
}
|
|
573
573
|
break;
|
|
574
574
|
}
|
|
@@ -605,6 +605,7 @@ export function getSubTitleDesign(
|
|
|
605
605
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
606
606
|
baseClasses[2].mobile.maxW = '3xl';
|
|
607
607
|
if (bordered) {
|
|
608
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
608
609
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
609
610
|
{
|
|
610
611
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -616,7 +617,6 @@ export function getSubTitleDesign(
|
|
|
616
617
|
},
|
|
617
618
|
theme
|
|
618
619
|
);
|
|
619
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
620
620
|
}
|
|
621
621
|
break;
|
|
622
622
|
}
|
|
@@ -653,6 +653,7 @@ export function getSubTitleDesign(
|
|
|
653
653
|
baseClasses[2].mobile.textWRAP = 'balance';
|
|
654
654
|
if (bordered) {
|
|
655
655
|
baseClasses[2].mobile.rounded = 'lg';
|
|
656
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
656
657
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
657
658
|
{
|
|
658
659
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -664,7 +665,6 @@ export function getSubTitleDesign(
|
|
|
664
665
|
},
|
|
665
666
|
theme
|
|
666
667
|
);
|
|
667
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
668
668
|
}
|
|
669
669
|
break;
|
|
670
670
|
}
|
|
@@ -700,6 +700,7 @@ export function getSubTitleDesign(
|
|
|
700
700
|
baseClasses[2].mobile.textALIGN = 'left';
|
|
701
701
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
702
702
|
if (bordered) {
|
|
703
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
703
704
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
704
705
|
{
|
|
705
706
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -711,7 +712,6 @@ export function getSubTitleDesign(
|
|
|
711
712
|
},
|
|
712
713
|
theme
|
|
713
714
|
);
|
|
714
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
715
715
|
}
|
|
716
716
|
break;
|
|
717
717
|
}
|
|
@@ -748,6 +748,7 @@ export function getSubTitleDesign(
|
|
|
748
748
|
baseClasses[2].mobile.textWRAP = 'pretty';
|
|
749
749
|
if (bordered) {
|
|
750
750
|
baseClasses[2].mobile.rounded = 'lg';
|
|
751
|
+
baseClasses[2].mobile.shadow = 'md';
|
|
751
752
|
baseClasses[2].mobile.bgCOLOR = getColor(
|
|
752
753
|
{
|
|
753
754
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -759,7 +760,6 @@ export function getSubTitleDesign(
|
|
|
759
760
|
},
|
|
760
761
|
theme
|
|
761
762
|
);
|
|
762
|
-
baseClasses[2].mobile.shadow = 'md';
|
|
763
763
|
}
|
|
764
764
|
}
|
|
765
765
|
}
|
|
@@ -994,6 +994,7 @@ export const getIntroDesign = (
|
|
|
994
994
|
parentClasses[2].mobile.textWRAP = 'balance';
|
|
995
995
|
if (bordered) {
|
|
996
996
|
parentClasses[2].mobile.rounded = 'lg';
|
|
997
|
+
parentClasses[2].mobile.shadow = 'lg';
|
|
997
998
|
parentClasses[2].mobile.bgCOLOR = getColor(
|
|
998
999
|
{
|
|
999
1000
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -1005,7 +1006,6 @@ export const getIntroDesign = (
|
|
|
1005
1006
|
},
|
|
1006
1007
|
theme
|
|
1007
1008
|
);
|
|
1008
|
-
parentClasses[2].mobile.shadow = 'lg';
|
|
1009
1009
|
}
|
|
1010
1010
|
break;
|
|
1011
1011
|
}
|
|
@@ -1019,6 +1019,7 @@ export const getIntroDesign = (
|
|
|
1019
1019
|
parentClasses[2].mobile.textWRAP = 'pretty';
|
|
1020
1020
|
parentClasses[2].mobile.maxW = '3xl';
|
|
1021
1021
|
if (bordered) {
|
|
1022
|
+
parentClasses[2].mobile.shadow = 'lg';
|
|
1022
1023
|
parentClasses[2].mobile.bgCOLOR = getColor(
|
|
1023
1024
|
{
|
|
1024
1025
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -1030,7 +1031,6 @@ export const getIntroDesign = (
|
|
|
1030
1031
|
},
|
|
1031
1032
|
theme
|
|
1032
1033
|
);
|
|
1033
|
-
parentClasses[2].mobile.shadow = 'lg';
|
|
1034
1034
|
}
|
|
1035
1035
|
break;
|
|
1036
1036
|
}
|
|
@@ -1041,6 +1041,7 @@ export const getIntroDesign = (
|
|
|
1041
1041
|
(parentClasses[2].mobile.textALIGN = 'left');
|
|
1042
1042
|
parentClasses[2].mobile.textWRAP = 'pretty';
|
|
1043
1043
|
if (bordered) {
|
|
1044
|
+
parentClasses[2].mobile.shadow = 'lg';
|
|
1044
1045
|
parentClasses[2].mobile.bgCOLOR = getColor(
|
|
1045
1046
|
{
|
|
1046
1047
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -1052,7 +1053,6 @@ export const getIntroDesign = (
|
|
|
1052
1053
|
},
|
|
1053
1054
|
theme
|
|
1054
1055
|
);
|
|
1055
|
-
parentClasses[2].mobile.shadow = 'lg';
|
|
1056
1056
|
}
|
|
1057
1057
|
}
|
|
1058
1058
|
}
|
|
@@ -1101,6 +1101,7 @@ export const getImageHeroSectionDefault = (
|
|
|
1101
1101
|
parentClasses[2].mobile.textALIGN = 'left';
|
|
1102
1102
|
parentClasses[2].mobile.textWRAP = 'pretty';
|
|
1103
1103
|
if (bordered) {
|
|
1104
|
+
parentClasses[2].mobile.shadow = 'lg';
|
|
1104
1105
|
parentClasses[2].mobile.bgCOLOR = getColor(
|
|
1105
1106
|
{
|
|
1106
1107
|
light: useOdd ? 'brand-2' : 'white',
|
|
@@ -1112,7 +1113,6 @@ export const getImageHeroSectionDefault = (
|
|
|
1112
1113
|
},
|
|
1113
1114
|
theme
|
|
1114
1115
|
);
|
|
1115
|
-
parentClasses[2].mobile.shadow = 'lg';
|
|
1116
1116
|
}
|
|
1117
1117
|
|
|
1118
1118
|
return {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// URL Helper: Strip category prefix from slug
|
|
2
|
+
// e.g., "people-bleako" -> "bleako"
|
|
3
|
+
export function getCleanSlug(categorySlug: string, fullSlug: string): string {
|
|
4
|
+
const prefix = `${categorySlug}-`;
|
|
5
|
+
return fullSlug.startsWith(prefix) ? fullSlug.slice(prefix.length) : fullSlug;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Build proper URL for resource
|
|
9
|
+
// e.g., category="people", slug="people-bleako" -> "/people/bleako"
|
|
10
|
+
export function getResourceUrl(categorySlug: string, fullSlug: string): string {
|
|
11
|
+
const cleanSlug = getCleanSlug(categorySlug, fullSlug);
|
|
12
|
+
return `/${categorySlug}/${cleanSlug}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Image Helper: Placeholder implementation
|
|
16
|
+
export function getResourceImage(
|
|
17
|
+
id: string,
|
|
18
|
+
slug: string,
|
|
19
|
+
category: string
|
|
20
|
+
): string {
|
|
21
|
+
console.log(`please define getResourceImage`, id, slug, category);
|
|
22
|
+
return '/static.jpg';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getResourceDescription(
|
|
26
|
+
id: string,
|
|
27
|
+
slug: string,
|
|
28
|
+
category: string
|
|
29
|
+
): string | null {
|
|
30
|
+
console.log(`please define getResourceDescription`, id, slug, category);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Initialize search data - override in custom implementation
|
|
35
|
+
export function initSearch(): void {
|
|
36
|
+
// Default implementation does nothing
|
|
37
|
+
// Override this function in your custom implementation to load search data
|
|
38
|
+
}
|
|
@@ -328,8 +328,8 @@ export function useDropdownDirection(
|
|
|
328
328
|
const spaceAbove = rect.top;
|
|
329
329
|
const newOpenAbove = spaceBelow < 300 && spaceAbove > spaceBelow;
|
|
330
330
|
const newMaxHeight = newOpenAbove
|
|
331
|
-
? Math.min(spaceAbove -
|
|
332
|
-
: Math.min(spaceBelow -
|
|
331
|
+
? Math.max(0, Math.min(spaceAbove - 20, 400))
|
|
332
|
+
: Math.max(0, Math.min(spaceBelow - 20, 400));
|
|
333
333
|
setState({ openAbove: newOpenAbove, maxHeight: newMaxHeight });
|
|
334
334
|
}
|
|
335
335
|
}, [triggerRef]);
|
|
@@ -1,188 +1,116 @@
|
|
|
1
1
|
import {
|
|
2
2
|
settingsPanelOpenStore,
|
|
3
|
+
settingsPanelStore,
|
|
3
4
|
headerPositionStore,
|
|
4
5
|
setHeaderPosition,
|
|
5
6
|
setMobileHeaderFaded,
|
|
6
7
|
} from '@/stores/storykeep';
|
|
8
|
+
import { debounce } from '@/utils/helpers';
|
|
7
9
|
|
|
8
|
-
// Track whether initial scroll adjustment has been made for settings panel
|
|
9
10
|
let hasScrolledForSettingsPanel = false;
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export function setupLayoutStyles(): void {
|
|
15
|
-
// Calculate and set CSS custom properties for positioning
|
|
16
|
-
const updateBottomOffset = () => {
|
|
17
|
-
const mobileNavHeight = window.innerWidth < 801 ? 80 : 0;
|
|
18
|
-
const padding = 16;
|
|
19
|
-
const offset = `${mobileNavHeight + padding}px`;
|
|
20
|
-
|
|
21
|
-
document.documentElement.style.setProperty(
|
|
22
|
-
'--bottom-right-controls-bottom-offset',
|
|
23
|
-
offset
|
|
24
|
-
);
|
|
25
|
-
};
|
|
12
|
+
// Replace your existing setupPaneObserver with this one.
|
|
13
|
+
function setupPaneObserver() {
|
|
14
|
+
let currentObserver: IntersectionObserver | null = null;
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
settingsPanelStore.subscribe((signalValue) => {
|
|
17
|
+
if (currentObserver) {
|
|
18
|
+
currentObserver.disconnect();
|
|
19
|
+
currentObserver = null;
|
|
20
|
+
}
|
|
29
21
|
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
if (signalValue && signalValue.nodeId) {
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
const { nodeId } = signalValue;
|
|
25
|
+
|
|
26
|
+
const targetElement =
|
|
27
|
+
document.getElementById(`pane-${nodeId}`) ||
|
|
28
|
+
document.querySelector(`[data-node-id="${nodeId}"]`);
|
|
29
|
+
|
|
30
|
+
if (targetElement) {
|
|
31
|
+
currentObserver = new IntersectionObserver(
|
|
32
|
+
([entry]) => {
|
|
33
|
+
const signal = settingsPanelStore.get();
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
if (signal?.editLock && now - signal.editLock < 100) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (!entry.isIntersecting) {
|
|
39
|
+
settingsPanelStore.set(null);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{ threshold: 0 }
|
|
43
|
+
);
|
|
44
|
+
currentObserver.observe(targetElement);
|
|
45
|
+
}
|
|
46
|
+
}, 100);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
32
49
|
}
|
|
33
50
|
|
|
34
|
-
/**
|
|
35
|
-
* Sets up scroll observers for header positioning behavior
|
|
36
|
-
*/
|
|
37
51
|
export function setupLayoutObservers(): void {
|
|
38
|
-
const
|
|
39
|
-
const toolModeNav = document.getElementById('mainNav');
|
|
40
|
-
const mainContent = document.getElementById('mainContent');
|
|
52
|
+
const storykeepHeader = document.getElementById('storykeepHeader');
|
|
41
53
|
const settingsControls = document.getElementById('settingsControls');
|
|
42
54
|
const standardHeader = document.querySelector('header');
|
|
43
55
|
|
|
44
|
-
if (!
|
|
56
|
+
if (!storykeepHeader || !settingsControls || !standardHeader) return;
|
|
45
57
|
|
|
46
|
-
let
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
headerHeight = standardHeader.offsetHeight;
|
|
50
|
-
}
|
|
58
|
+
let standardHeaderHeight = 0;
|
|
59
|
+
const updateStandardHeaderHeight = () => {
|
|
60
|
+
standardHeaderHeight = standardHeader.offsetHeight;
|
|
51
61
|
};
|
|
52
62
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const bottomOffset = window.innerWidth < 801 ? 96 : 16; // Mobile nav + padding
|
|
58
|
-
|
|
59
|
-
// Set top margin to avoid StoryKeep header overlap only
|
|
60
|
-
settingsControls.style.marginTop = `${storyKeepHeaderHeight + 20}px`;
|
|
61
|
-
|
|
62
|
-
// Set max height for inner scroll
|
|
63
|
-
const maxHeight =
|
|
64
|
-
viewportHeight - storyKeepHeaderHeight - bottomOffset - 20;
|
|
65
|
-
settingsControls.style.maxHeight = `${maxHeight}px`;
|
|
66
|
-
}
|
|
63
|
+
const updatePanelPosition = () => {
|
|
64
|
+
const headerRect = storykeepHeader.getBoundingClientRect();
|
|
65
|
+
const panelTop = headerRect.bottom;
|
|
66
|
+
settingsControls.style.top = `${panelTop}px`;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
const handleScroll = () => {
|
|
70
70
|
const scrollY = window.scrollY;
|
|
71
|
-
const shouldBeSticky = scrollY >
|
|
72
|
-
|
|
73
|
-
// Only update header position if it actually needs to change
|
|
71
|
+
const shouldBeSticky = scrollY > standardHeaderHeight;
|
|
74
72
|
const currentPosition = headerPositionStore.get();
|
|
75
73
|
const newPosition = shouldBeSticky ? 'sticky' : 'normal';
|
|
76
74
|
|
|
77
75
|
if (currentPosition !== newPosition) {
|
|
78
76
|
setHeaderPosition(newPosition);
|
|
79
|
-
|
|
80
|
-
if (shouldBeSticky) {
|
|
81
|
-
if (header) {
|
|
82
|
-
const headerHeight = header.offsetHeight;
|
|
83
|
-
// Add padding to body to prevent layout shift
|
|
84
|
-
document.body.style.paddingTop = `${headerHeight}px`;
|
|
85
|
-
|
|
86
|
-
header.style.position = 'fixed';
|
|
87
|
-
header.style.top = '0';
|
|
88
|
-
header.style.left = '0';
|
|
89
|
-
header.style.right = '0';
|
|
90
|
-
header.style.zIndex = '101';
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
if (header) {
|
|
94
|
-
// Remove padding when header is not fixed
|
|
95
|
-
document.body.style.paddingTop = '';
|
|
96
|
-
|
|
97
|
-
header.style.position = '';
|
|
98
|
-
header.style.top = '';
|
|
99
|
-
header.style.left = '';
|
|
100
|
-
header.style.right = '';
|
|
101
|
-
header.style.zIndex = '';
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Update tool mode nav position and main content margin
|
|
107
|
-
if (toolModeNav && window.innerWidth >= 801) {
|
|
108
77
|
if (shouldBeSticky) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
toolModeNav.style.top = '60px'; // Below fixed header
|
|
113
|
-
toolModeNav.style.left = '0';
|
|
114
|
-
|
|
115
|
-
// Add margin to main content when nav becomes fixed (nav no longer takes flex space)
|
|
116
|
-
if (mainContent) {
|
|
117
|
-
mainContent.classList.add('md:ml-16');
|
|
118
|
-
}
|
|
78
|
+
document.body.style.paddingTop = `${storykeepHeader.offsetHeight}px`;
|
|
79
|
+
storykeepHeader.style.position = 'fixed';
|
|
80
|
+
storykeepHeader.style.top = '0';
|
|
119
81
|
} else {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
toolModeNav.style.top = '';
|
|
124
|
-
toolModeNav.style.left = '';
|
|
125
|
-
|
|
126
|
-
// Remove margin from main content when nav is static (nav takes flex space naturally)
|
|
127
|
-
if (mainContent) {
|
|
128
|
-
mainContent.classList.remove('md:ml-16');
|
|
129
|
-
}
|
|
82
|
+
document.body.style.paddingTop = '';
|
|
83
|
+
storykeepHeader.style.position = '';
|
|
84
|
+
storykeepHeader.style.top = '';
|
|
130
85
|
}
|
|
131
86
|
}
|
|
132
87
|
};
|
|
133
88
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
updateHeaderHeight();
|
|
137
|
-
updateSettingsMargin();
|
|
138
|
-
|
|
139
|
-
// Handle desktop/mobile breakpoint transitions
|
|
140
|
-
const isMobile = window.innerWidth < 801;
|
|
141
|
-
|
|
142
|
-
if (isMobile && toolModeNav && mainContent) {
|
|
143
|
-
// Force reset to mobile layout
|
|
144
|
-
toolModeNav.classList.remove('md:fixed', 'md:static');
|
|
145
|
-
toolModeNav.style.top = '';
|
|
146
|
-
toolModeNav.style.left = '';
|
|
147
|
-
|
|
148
|
-
// Remove desktop margin
|
|
149
|
-
mainContent.classList.remove('md:ml-16');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Re-run scroll logic to handle desktop/mobile transitions
|
|
89
|
+
const debouncedUpdate = debounce(() => {
|
|
90
|
+
updateStandardHeaderHeight();
|
|
153
91
|
handleScroll();
|
|
154
|
-
|
|
92
|
+
updatePanelPosition();
|
|
93
|
+
}, 50);
|
|
155
94
|
|
|
156
|
-
// Listen for settings panel state changes
|
|
157
95
|
const handleSettingsPanelChange = () => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// Reset scroll flag when panel state changes
|
|
161
|
-
if (!isSettingsOpen) {
|
|
96
|
+
if (!settingsPanelOpenStore.get()) {
|
|
162
97
|
hasScrolledForSettingsPanel = false;
|
|
163
98
|
}
|
|
164
99
|
};
|
|
165
100
|
|
|
166
|
-
|
|
167
|
-
window.addEventListener('
|
|
168
|
-
window.addEventListener('resize', handleResize);
|
|
169
|
-
|
|
170
|
-
// Subscribe to settings panel state changes
|
|
101
|
+
window.addEventListener('scroll', debouncedUpdate, { passive: true });
|
|
102
|
+
window.addEventListener('resize', debouncedUpdate);
|
|
171
103
|
settingsPanelOpenStore.subscribe(handleSettingsPanelChange);
|
|
172
104
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
105
|
+
setupPaneObserver();
|
|
106
|
+
|
|
107
|
+
updateStandardHeaderHeight();
|
|
176
108
|
handleScroll();
|
|
109
|
+
updatePanelPosition();
|
|
177
110
|
}
|
|
178
111
|
|
|
179
|
-
/**
|
|
180
|
-
* Handle settings panel mobile behavior
|
|
181
|
-
* This is called when the settings panel is toggled
|
|
182
|
-
*/
|
|
183
112
|
export function handleSettingsPanelMobile(isOpen: boolean): void {
|
|
184
113
|
const isMobile = window.innerWidth < 801;
|
|
185
|
-
|
|
186
114
|
if (!isMobile) return;
|
|
187
115
|
|
|
188
116
|
if (isOpen) {
|
|
@@ -190,19 +118,12 @@ export function handleSettingsPanelMobile(isOpen: boolean): void {
|
|
|
190
118
|
const headerHeight = header?.offsetHeight || 0;
|
|
191
119
|
const currentScrollY = window.scrollY;
|
|
192
120
|
|
|
193
|
-
// Only scroll if we're near the top and haven't already scrolled
|
|
194
121
|
if (currentScrollY <= headerHeight && !hasScrolledForSettingsPanel) {
|
|
195
|
-
window.scrollTo({
|
|
196
|
-
top: headerHeight + 10,
|
|
197
|
-
behavior: 'smooth',
|
|
198
|
-
});
|
|
122
|
+
window.scrollTo({ top: headerHeight + 10, behavior: 'smooth' });
|
|
199
123
|
hasScrolledForSettingsPanel = true;
|
|
200
124
|
}
|
|
201
|
-
|
|
202
|
-
// Fade the header
|
|
203
125
|
setMobileHeaderFaded(true);
|
|
204
126
|
} else {
|
|
205
|
-
// Unfade the header and reset scroll flag
|
|
206
127
|
setMobileHeaderFaded(false);
|
|
207
128
|
hasScrolledForSettingsPanel = false;
|
|
208
129
|
}
|