Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix highlighting for items not included in custom ToC #532

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -648,101 +648,78 @@
"slideIndex": 0,
"sublist": [
{
"title": "Community Directory",
"title": "Interactive Content + Maps",
"slideIndex": 1
},
{
"title": "Interactive Map",
"slideIndex": 2
},
{
"title": "RAMP Carousel",
"slideIndex": 3
},
{
"title": "Dynamic Panel",
"slideIndex": 4
},
{
"title": "YouTube Video",
"slideIndex": 5
},
{
"title": "Cumulative Effects Video",
"title": "YouTube Video",
"slideIndex": 6
}
]
},
{
"title": "Oil Sands Deposits",
"slideIndex": 7
},
{
"title": "Oil Sands Extraction",
"slideIndex": 8,
"sublist": []
"slideIndex": 8
},
{
"title": "In-situ Extraction",
"slideIndex": 9
"slideIndex": 10
},
{
"title": "Where are Facilities Located?",
"slideIndex": 10,
"slideIndex": 11,
"sublist": [
{
"title": "NPRI Substances Reported for Oil Sands Mining Faciltiies",
"slideIndex": 11
"slideIndex": 12
},
{
"title": "NPRI Substances Reported for Oil Sands Mining Facilities (2)",
"slideIndex": 12
"slideIndex": 13
},
{
"title": "Criteria Air Contaminant Releases From Oil Sands Mines",
"slideIndex": 13
"slideIndex": 14
},
{
"title": "Reported Mine Tailings From Oil Sands Surface Mining Facilities",
"slideIndex": 14
"slideIndex": 15
},
{
"title": "Reported Mine Tailings From Oil Sands Surface Mining Facilities (2)",
"slideIndex": 15
"slideIndex": 16
},
{
"title": "Trends in Mine Tailings Reported From Surface Mining Facilities",
"slideIndex": 16
"slideIndex": 17
},
{
"title": "Thermal in Situ Facilities",
"slideIndex": 17
"slideIndex": 18
},
{
"title": "NPRI Releases From Thermal in-situ Faciltiies",
"slideIndex": 18
"slideIndex": 19
}
]
},
{
"title": "Highcharts Demo (╯°□°)╯︵ ┻━┻",
"slideIndex": 19,
"slideIndex": 20,
"sublist": [
{
"title": "Dynamic Slideshow with Hybrid Chart",
"slideIndex": 20
"slideIndex": 21
}
]
},
{
"title": "Managing Environmental Impacts",
"slideIndex": 21,
"sublist": [
{
"title": "Last Slide",
"slideIndex": 22
}
]
"slideIndex": 22
}
],
"tocOrientation": "horizontal",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,17 +342,7 @@
},
{
"title": "Extraction de sables bitumineux",
"slideIndex": 2,
"sublist": [
{
"title": "Extraction des sables bitumineux (2)",
"slideIndex": 3
},
{
"title": "Où sont situées les installations?",
"slideIndex": 4
}
]
"slideIndex": 2
},
{
"title": "Substances de l'INRP déclarées par les installations d’exploitation minière de sables bitumineux",
Expand Down
36 changes: 32 additions & 4 deletions src/components/story/chapter-menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
v-for="(item, idx) in customToc"
:key="idx"
:class="{
'is-active': lastActiveIdx === item.slideIndex
'is-active': lastActiveIdx === item.slideIndex || isSublistActive(item.sublist)
}"
>
<toc-item :tocItem="item" :slides="slides" :plugin="plugin">
Expand Down Expand Up @@ -221,7 +221,7 @@
<script setup lang="ts">
import type { PropType } from 'vue';
import { computed, ref, watch, onMounted } from 'vue';
import { MenuItem, Slide } from '@storylines/definitions';
import type { MenuItem, Slide } from '@storylines/definitions';
import TocItem from '@storylines/components/panels/helpers/toc-item.vue';

const props = defineProps({
Expand Down Expand Up @@ -266,6 +266,22 @@ const tocSlides = computed(() => {
return slides;
});

const customTocSlides = computed(() => {
if (props.customToc) {
// for custom ToC extract slides including nested sublist items
let slides: MenuItem[] = [];
props.customToc.forEach((item) => {
slides.push(item);
if (item.sublist && item.sublist.length) {
item.sublist.forEach((subItem) => {
slides.push(subItem);
});
}
});
return slides;
}
});

watch(
() => props.activeChapterIndex,
() => {
Expand Down Expand Up @@ -298,9 +314,21 @@ const isSublistToggled = (index: number): boolean => {
return sublistToggled.value[index];
};

const isSublistActive = (sublist: MenuItem[] | undefined): boolean => {
if (sublist) {
return sublist.some(subItem => lastActiveIdx.value === subItem.slideIndex);
}
return false;
};

const updateActiveIdx = () => {
const prevSlides = tocSlides.value.filter((slide) => slide.index <= props.activeChapterIndex);
lastActiveIdx.value = prevSlides.length ? prevSlides[prevSlides.length - 1].index : -1;
if (props.customToc) {
const prevCustomSlides: MenuItem[] = customTocSlides.value!.filter((slide) => slide.slideIndex <= props.activeChapterIndex);
lastActiveIdx.value = prevCustomSlides.length ? prevCustomSlides[prevCustomSlides.length - 1].slideIndex : -1;
} else {
const prevSlides = tocSlides.value.filter((slide) => slide.index <= props.activeChapterIndex);
lastActiveIdx.value = prevSlides.length ? prevSlides[prevSlides.length - 1].index : -1;
}
};
</script>

Expand Down
40 changes: 33 additions & 7 deletions src/components/story/horizontal-menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
v-for="(item, idx) in customToc"
:key="idx"
:class="{
'is-active': lastActiveIdx === item.slideIndex,
'is-active': lastActiveIdx === item.slideIndex || isSublistActive(item.sublist),
separator: (!returnToTop && idx !== 0) || returnToTop
}"
ref="itemContainer"
Expand Down Expand Up @@ -120,7 +120,7 @@
<script setup lang="ts">
import type { PropType } from 'vue';
import { computed, ref, watch, onMounted, onBeforeUnmount } from 'vue';
import { MenuItem, Slide } from '@storylines/definitions';
import type { MenuItem, Slide } from '@storylines/definitions';
import TocItem from '@storylines/components/panels/helpers/toc-item.vue';

const props = defineProps({
Expand Down Expand Up @@ -159,12 +159,26 @@ const itemContainer = ref(null);
// filter out which slides are visible in the table of contents while preserving original slide index
const tocSlides = computed(() => {
const slides = props.slides.map((slide, idx) => ({ ...slide, index: idx }));
if (!props.customToc) {
slides.filter((slide) => slide.includeInToc !== false);
}
slides.filter((slide) => slide.includeInToc !== false);
return slides;
});

const customTocSlides = computed(() => {
if (props.customToc) {
// for custom ToC extract slides including nested sublist items
let slides: MenuItem[] = [];
props.customToc.forEach((item) => {
slides.push(item);
if (item.sublist && item.sublist.length) {
item.sublist.forEach((subItem) => {
slides.push(subItem);
});
}
});
return slides;
}
});

watch(
() => props.activeChapterIndex,
() => {
Expand Down Expand Up @@ -211,9 +225,21 @@ const toggleSublist = (index: number): void => {
sublistToggled.value = sublistToggled.value !== index ? index : -1;
};

const isSublistActive = (sublist: MenuItem[] | undefined): boolean => {
if (sublist) {
return sublist.some(subItem => lastActiveIdx.value === subItem.slideIndex);
}
return false;
};

const updateActiveIdx = () => {
const prevSlides = tocSlides.value.filter((slide) => slide.index <= props.activeChapterIndex);
lastActiveIdx.value = prevSlides.length ? prevSlides[prevSlides.length - 1].index : -1;
if (props.customToc) {
const prevCustomSlides: MenuItem[] = customTocSlides.value!.filter((slide) => slide.slideIndex <= props.activeChapterIndex);
lastActiveIdx.value = prevCustomSlides.length ? prevCustomSlides[prevCustomSlides.length - 1].slideIndex : -1;
} else {
const prevSlides = tocSlides.value.filter((slide) => slide.index <= props.activeChapterIndex);
lastActiveIdx.value = prevSlides.length ? prevSlides[prevSlides.length - 1].index : -1;
}
};

const handleFocus = (idx: number) => {
Expand Down
36 changes: 32 additions & 4 deletions src/components/story/mobile-menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
v-for="(item, idx) in customToc"
:key="idx"
:class="{
'is-active': lastActiveIdx === item.slideIndex
'is-active': lastActiveIdx === item.slideIndex || isSublistActive(item.sublist)
}"
>
<toc-item :tocItem="item" :slides="slides" :plugin="plugin">
Expand Down Expand Up @@ -196,7 +196,7 @@
<script setup lang="ts">
import type { PropType } from 'vue';
import { computed, ref, watch, onMounted } from 'vue';
import { MenuItem, Slide } from '@storylines/definitions';
import type { MenuItem, Slide } from '@storylines/definitions';
import TocItem from '@storylines/components/panels/helpers/toc-item.vue';

const props = defineProps({
Expand Down Expand Up @@ -240,6 +240,22 @@ const tocSlides = computed(() => {
return slides;
});

const customTocSlides = computed(() => {
if (props.customToc) {
// for custom ToC extract slides including nested sublist items
let slides: MenuItem[] = [];
props.customToc.forEach((item) => {
slides.push(item);
if (item.sublist && item.sublist.length) {
item.sublist.forEach((subItem) => {
slides.push(subItem);
});
}
});
return slides;
}
});

watch(
() => props.activeChapterIndex,
() => {
Expand Down Expand Up @@ -273,9 +289,21 @@ const isSublistToggled = (index: number): boolean => {
return sublistToggled.value[index];
};

const isSublistActive = (sublist: MenuItem[] | undefined): boolean => {
if (sublist) {
return sublist.some(subItem => lastActiveIdx.value === subItem.slideIndex);
}
return false;
};

const updateActiveIdx = () => {
const prevSlides = tocSlides.value.filter((slide) => slide.index <= props.activeChapterIndex);
lastActiveIdx.value = prevSlides.length ? prevSlides[prevSlides.length - 1].index : -1;
if (props.customToc) {
const prevCustomSlides: MenuItem[] = customTocSlides.value!.filter((slide) => slide.slideIndex <= props.activeChapterIndex);
lastActiveIdx.value = prevCustomSlides.length ? prevCustomSlides[prevCustomSlides.length - 1].slideIndex : -1;
} else {
const prevSlides = tocSlides.value.filter((slide) => slide.index <= props.activeChapterIndex);
lastActiveIdx.value = prevSlides.length ? prevSlides[prevSlides.length - 1].index : -1;
}
};
</script>

Expand Down
Loading