@@ -50,6 +50,45 @@ The list size must be between the min and the max width value.
50
50
:list-max-width="45"
51
51
>...</NcAppContent>
52
52
```
53
+
54
+ #### Usage: Custom document title
55
+ For accessibility reasons every document should have a `h1` heading,
56
+ this is visually hidden, but required for a semantically correct document.
57
+ You can use your app name or current view for the heading.
58
+
59
+ Additionally you can set a custom document title, e.g. to show the current status.
60
+
61
+ ```vue
62
+ <template>
63
+ <NcAppContent :pageHeading="heading ? 'Heading' : undefined" :pageTitle="title ? 'Title' : undefined" >
64
+ <NcCheckboxRadioSwitch type="switch" :checked.sync="title">
65
+ Toggle title
66
+ </NcCheckboxRadioSwitch>
67
+ <NcCheckboxRadioSwitch type="switch" :checked.sync="heading">
68
+ Toggle Heading
69
+ </NcCheckboxRadioSwitch>
70
+ <NcButton @click="reset">Reset</NcButton>
71
+ </NcAppContent>
72
+ </template>
73
+
74
+ <script>
75
+ export default {
76
+ data() {
77
+ return {
78
+ heading: false,
79
+ title: false,
80
+ }
81
+ },
82
+ methods: {
83
+ reset() {
84
+ this.heading = false
85
+ this.title = false
86
+ document.title = ''
87
+ },
88
+ },
89
+ }
90
+ </script>
91
+ ```
53
92
</docs>
54
93
55
94
<template>
@@ -103,18 +142,22 @@ The list size must be between the min and the max width value.
103
142
</template>
104
143
105
144
<script>
106
- import NcAppDetailsToggle from './NcAppDetailsToggle.vue'
107
- import { useIsMobile } from '../../composables/useIsMobile/index.js'
108
-
109
145
import { getBuilder } from '@nextcloud/browser-storage'
146
+ import { emit } from '@nextcloud/event-bus'
147
+ import { loadState } from '@nextcloud/initial-state'
110
148
import { useSwipe } from '@vueuse/core'
111
149
import { Splitpanes, Pane } from 'splitpanes'
150
+ import { useIsMobile } from '../../composables/useIsMobile/index.js'
151
+ import { isRtl } from '../../utils/rtl.ts'
152
+
153
+ import NcAppDetailsToggle from './NcAppDetailsToggle.vue'
112
154
113
155
import 'splitpanes/dist/splitpanes.css'
114
- import { emit } from '@nextcloud/event-bus'
115
- import { isRtl } from '../../utils/rtl.ts'
116
156
117
157
const browserStorage = getBuilder('nextcloud').persist().build()
158
+ const { name: productName } = loadState('theming', 'data', { name: 'Nextcloud' })
159
+ const activeApp = loadState('core', 'active-app', appName)
160
+ const localizedAppName = loadState('core', 'apps', {})[activeApp]?.name ?? appName
118
161
119
162
/**
120
163
* App content container to be used for the main content of your app
@@ -217,6 +260,18 @@ export default {
217
260
return ['no-split', 'vertical-split', 'horizontal-split'].includes(value)
218
261
},
219
262
},
263
+
264
+ /**
265
+ * Allow setting the page's `<title>`
266
+ *
267
+ * If a page heading is set it defaults to `{pageHeading} - {appName} - {productName}` e.g. `Favorites - Files - Nextcloud`.
268
+ * When the page heading and the app name is the same only one is used, e.g. `Files - Files - Nextcloud` is shown as `Files - Nextcloud`.
269
+ * When setting the prop then the following format will be used: `{pageTitle} - {pageHeading || appName} - {productName}`
270
+ */
271
+ pageTitle: {
272
+ type: String,
273
+ default: null,
274
+ },
220
275
},
221
276
222
277
emits: [
@@ -284,6 +339,37 @@ export default {
284
339
},
285
340
}
286
341
},
342
+
343
+ realPageTitle() {
344
+ const entries = new Set()
345
+ if (this.pageTitle) {
346
+ entries.add(this.pageTitle)
347
+ }
348
+ if (this.pageHeading) {
349
+ entries.add(this.pageHeading)
350
+ }
351
+ if (entries.size === 0) {
352
+ return null
353
+ }
354
+
355
+ if (entries.size < 2) {
356
+ // Only add if not already pageHeading and pageTitle are included
357
+ entries.add(localizedAppName)
358
+ }
359
+ entries.add(productName)
360
+ return [...entries.values()].join(' - ')
361
+ },
362
+ },
363
+
364
+ watch: {
365
+ realPageTitle: {
366
+ immediate: true,
367
+ handler() {
368
+ if (this.realPageTitle !== null) {
369
+ document.title = this.realPageTitle
370
+ }
371
+ },
372
+ },
287
373
},
288
374
289
375
updated() {
0 commit comments