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

feat: improve printing experience. #4041

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions docs/en/reference/default-theme-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,13 @@ Can be used to customize the light mode switch title that appears on hovering.

Can be used to customize the dark mode switch title that appears on hovering.

## removeExtraElementsInPrint

- Type: `boolean`
- Default: `false`

When set to `true`, it will remove extra elements like the sidebar, navbar, and footer when printing the page. If you want to print your docs and don't want to include the extra elements, you can set this option to `true`.

## sidebarMenuLabel

- Type: `string`
Expand Down
20 changes: 16 additions & 4 deletions docs/zh/reference/default-theme-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export default {

- 类型:`boolean`

将本地语言更改为 `zh` 会将 URL 从 `/foo`(或 `/en/foo/`)更改为 `/zh/foo`。可以通过将 `themeConfig.i18nRouting` 设置为 `false` 来禁用此行为。
将本地语言更改为 `zh` 会将 URL 从 `/foo`(或 `/en/foo/`)更改为 `/zh/foo`。可以通过将 `themeConfig.i18nRouting`
设置为 `false` 来禁用此行为。

## logo

Expand All @@ -50,7 +51,8 @@ type ThemeableImage =

- 类型:`string | false`

可以自定义此项以替换导航中的默认站点标题 (应用配置中的 `title`)。当设置为 `false` 时,导航中的标题将被禁用。这在当 `logo` 已经包含站点标题文本时很有用。
可以自定义此项以替换导航中的默认站点标题 (应用配置中的 `title`)。当设置为 `false` 时,导航中的标题将被禁用。这在当 `logo`
已经包含站点标题文本时很有用。

```ts
export default {
Expand Down Expand Up @@ -283,7 +285,8 @@ export interface Footer {
- 类型:`EditLink`
- 每个页面可以通过 [frontmatter](./frontmatter-config#editlink) 覆盖

编辑链接可让显示链接以编辑 Git 管理服务 (例如 GitHub 或 GitLab) 上的页面。有关详细信息,请参阅[默认主题:编辑链接](./default-theme-edit-link)。
编辑链接可让显示链接以编辑 Git 管理服务 (例如 GitHub 或 GitLab)
上的页面。有关详细信息,请参阅[默认主题:编辑链接](./default-theme-edit-link)。

```ts
export default {
Expand Down Expand Up @@ -342,7 +345,8 @@ export interface LastUpdatedOptions {

- 类型:`AlgoliaSearch`

支持使用 [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch) 搜索站点文档。在[默认主题:搜索](./default-theme-search) 中了解更多信息。
支持使用 [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch)
搜索站点文档。在[默认主题:搜索](./default-theme-search) 中了解更多信息。

```ts
export interface AlgoliaSearchOptions extends DocSearchProps {
Expand Down Expand Up @@ -423,6 +427,14 @@ export interface DocFooter {

用于自定义悬停时显示的深色模式开关标题。

## removeExtraElementsInPrint

- 类型:`boolean`
- 默认值:`false`

删除打印页面中的额外元素。当设置为 `true`
时,打印页面时会删除侧边栏、导航栏和页脚等额外元素。如果要打印文档且并不想包含额外元素,可以将此选项设置为 `true`。

## sidebarMenuLabel

- 类型:`string`
Expand Down
9 changes: 8 additions & 1 deletion src/client/theme-default/components/VPDocFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,17 @@ const showFooter = computed(
control.value.prev ||
control.value.next
)

const classes = computed(() => {
return {
VPDocFooter: true,
'hidden-print': theme.value.removeExtraElementsInPrint
}
})
</script>

<template>
<footer v-if="showFooter" class="VPDocFooter">
<footer v-if="showFooter" :class="classes">
<slot name="doc-footer-before" />

<div v-if="hasEditLink || hasLastUpdated" class="edit-info">
Expand Down
1 change: 1 addition & 0 deletions src/client/theme-default/components/VPLocalNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const emptyAndNoSidebar = computed(() => {
const classes = computed(() => {
return {
VPLocalNav: true,
'hidden-print': theme.value.removeExtraElementsInPrint,
'has-sidebar': hasSidebar.value,
empty: empty.value,
fixed: emptyAndNoSidebar.value
Expand Down
11 changes: 9 additions & 2 deletions src/client/theme-default/components/VPNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import VPNavBar from './VPNavBar.vue'
import VPNavScreen from './VPNavScreen.vue'

const { isScreenOpen, closeScreen, toggleScreen } = useNav()
const { frontmatter } = useData()
const { frontmatter, theme } = useData()

const hasNavbar = computed(() => {
return frontmatter.value.navbar !== false
Expand All @@ -20,10 +20,17 @@ watchEffect(() => {
document.documentElement.classList.toggle('hide-nav', !hasNavbar.value)
}
})

const classes = computed(() => {
return {
VPNav: true,
'hidden-print': theme.value.removeExtraElementsInPrint
}
})
</script>

<template>
<header v-if="hasNavbar" class="VPNav">
<header v-if="hasNavbar" :class="classes">
<VPNavBar :is-screen-open="isScreenOpen" @toggle-screen="toggleScreen">
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>
Expand Down
10 changes: 4 additions & 6 deletions src/client/theme-default/components/VPSwitchAppearance.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<script lang="ts" setup>
import { inject, ref, watchPostEffect } from 'vue'
import { ref, watchPostEffect } from 'vue'
import { useData } from '../composables/data'
import VPSwitch from './VPSwitch.vue'
import { useDark } from '../composables/dark'

const { isDark, theme } = useData()

const toggleAppearance = inject('toggle-appearance', () => {
isDark.value = !isDark.value
})
const { theme } = useData()
const { isDark, toggleAppearance } = useDark({ triggerPrint: true });

const switchTitle = ref('')

Expand Down
38 changes: 38 additions & 0 deletions src/client/theme-default/composables/dark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { inject, type Ref } from 'vue'
import { useData } from './data'
import { onMounted } from 'vue'

export interface UseDarkOptions {
triggerPrint: boolean
}

export interface UseDark {
isDark: Ref<boolean>
toggleAppearance: () => void
}

export function useDark(options?: UseDarkOptions): UseDark {
const { isDark } = useData()
const toggleAppearance = inject('toggle-appearance', () => {
isDark.value = !isDark.value
})
let previousPreferred = isDark.value
let isPrinting = false

// FIXME it will remain light when preferring dark mode after printing.
if (options?.triggerPrint) {
onMounted(() => {
window.addEventListener('beforeprint', () => {
if (isPrinting) return
isPrinting = true
previousPreferred = isDark.value
isDark.value = false
})
window.addEventListener('afterprint', () => {
isPrinting = false
isDark.value = previousPreferred
})
})
}
return { isDark, toggleAppearance }
}
3 changes: 3 additions & 0 deletions src/client/theme-default/styles/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ body {
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
page-break-inside: avoid;
page-break-after: avoid;
page-break-before: avoid;
}

main {
Expand Down
6 changes: 6 additions & 0 deletions src/client/theme-default/styles/utils.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@
clip-path: inset(50%);
overflow: hidden;
}

@media print {
.hidden-print {
display: none !important;
}
}
9 changes: 9 additions & 0 deletions types/default-theme.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ export namespace DefaultTheme {
*/
returnToTopLabel?: string

/**
* @default false
*
* Remove extraneous elements when printing, such as
* the sidebar, navbar, and footer. It can clean print pages, and focus on
* the main content.
*/
removeExtraElementsInPrint?: boolean

/**
* Set custom `aria-label` for language menu button.
*
Expand Down