slidev icon indicating copy to clipboard operation
slidev copied to clipboard

Slide export doesn't handle `v-if` in `global-top` or `global-bottom` based on conditional using `currentPage`, `currentLayout`

Open ani-per opened this issue 10 months ago • 5 comments

Describe the bug

The exporter seems to fail to handle v-if conditionals in global-top or global-bottom that use currentPage, currentLayout, and other navigation composables.

My global bottom is intended to only be displayed on non-cover slides after the first. This functions properly in browser view but fails to display properly on export.

<script setup lang="ts">
// import { computed } from "vue";
import { useNav, useSlideContext } from "@slidev/client"

// const { $slidev, $route } = useSlideContext()
const { currentPage, currentLayout } = useNav()
</script>

<template>
  <div v-if="currentPage.value > 1 && currentLayout !== 'cover'" class="slide-footer absolute w-full bottom-0 left-0 p-0 text-sm" style="display: grid; grid-template-columns: 33.33% 33.33% 33.34%; color: #ffffff">
    <div class="footer-comp justify-start" style="display: flex; flex-direction: row; gap: 7px; padding-left: 10px">
      <Item text="Ani Perumalla">
        <carbon:user-avatar-filled-alt />
      </Item>
      <Item text="ani-per.gitlab.io">
        <carbon:link />
      </Item>
    </div>
    <div class="footer-comp justify-center" style="display: flex; flex-direction: row; gap: 4px; padding-top: 4px; padding-bottom: 4px;">
      <img src="./img/logos/PSU_Engineering.png" alt="PSU Mark">
      <img src="./img/logos/PSU_Aero.png" alt="PSU Mark">
    </div>
    <div class="footer-comp justify-end" style="display: flex; flex-direction: row; gap: 7px; padding-right: 10px">
      <Item text="PSU UAS Research Lab">
        <carbon:drone />
      </Item>
      <Item text="<a href='https://purl.psu.edu'>purl.psu.edu</a>">
        <carbon:link />
      </Item>
    </div>
  </div>
</template>

This produces a proper global bottom in browser view, but no global bottom in the exported pdf:

Correct browser view

Incorrect exported pdf slide

When I remove the conditional v-if="currentPage.value > 1 && currentLayout !== 'cover'" from the first div in the template, the exporter displays the global bottom correctly:

Correct exported pdf slide

Desktop

  • OS: Windows 11
  • Browser: Brave, Firefox, Edge
  • Slidev version: 0.48.8

ani-per avatar Mar 31 '24 18:03 ani-per

useNav() is the global navigation API, which is a singleton.

useNav().currentPage is the page displayed in the main area, while $page.value is the page this component is rendered on. (Refer to https://sli.dev/custom/vue-context#page)

If you want to get the current layout, you can use $nav.currentLayout.value.

$page and $nav are available without importing manually. See https://sli.dev/custom/vue-context .

kermanx avatar Apr 01 '24 04:04 kermanx

useNav() is the global navigation API, which is a singleton.

useNav().currentPage is the page displayed in the main area, while $page.value is the page this component is rendered on. (Refer to https://sli.dev/custom/vue-context#page)

If you want to get the current layout, you can use $nav.currentLayout.value.

$page and $nav are available without importing manually. See https://sli.dev/custom/vue-context .

Thank you for the clarification. However, I'm having a few issues when trying to correct based on this information.

  • I can't use $page and $nav in global-top/bottom in the conditional without importing from useSlideContext(). I tried without and the conditional failed like before. Is there an exception for root-level files like global-top/bottom?
  • Even when I ignore this and use $page and $nav in global-top/bottom imported from useSlideContext() in the conditional, the global top/bottom still did not show up on the exported slides even though they were rendered properly in browser view.

ani-per avatar Apr 01 '24 14:04 ani-per

I can't use $page and $nav in global-top/bottom in the conditional without importing from useSlideContext(). I tried without and the conditional failed like before. Is there an exception for root-level files like global-top/bottom?

After some debugging I found this is because there is a "useSlideContext()" in the source code (even it's commented out), and then Slidev won't inject const { $page, ...} = useSlideContext() automatically in this condition.

  • Even when I ignore this and use $page and $nav in global-top/bottom imported from useSlideContext() in the conditional, the global top/bottom still did not show up on the exported slides even though they were rendered properly in browser view.

This is a bug. In print mode, the global-top is rendered before injectionCurrentPage is provided, so the value fallbacks to the global one. I will fix this ASAP.

kermanx avatar Apr 01 '24 15:04 kermanx

I can't use $page and $nav in global-top/bottom in the conditional without importing from useSlideContext(). I tried without and the conditional failed like before. Is there an exception for root-level files like global-top/bottom?

After some debugging I found this is because there is a "useSlideContext()" in the source code (even it's commented out), and then Slidev won't inject const { $page, ...} = useSlideContext() automatically in this condition.

  • Even when I ignore this and use $page and $nav in global-top/bottom imported from useSlideContext() in the conditional, the global top/bottom still did not show up on the exported slides even though they were rendered properly in browser view.

This is a bug. In print mode, the global-top is rendered before injectionCurrentPage is provided, so the value fallbacks to the global one. I will fix this ASAP.

Thank you for the very quick response! I really appreciate your help, and I'm glad to have helped identify the bugs.

ani-per avatar Apr 01 '24 15:04 ani-per

I've opened #1492 for this. However, as antfu pointed out in https://github.com/slidevjs/slidev/pull/1492#issuecomment-2031616230, #1492 is currently not mergable, and the --per-slide flag as a workaround currently.

kermanx avatar Apr 02 '24 12:04 kermanx

Now we have slide layers for this use case. You can simply migrate global layers to slide layers, which is also described in https://sli.dev/features/global-layers.

kermanx avatar Jul 19 '24 06:07 kermanx