Skip to content

Commit

Permalink
enh(NcContent): Add skip content buttons
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Dec 21, 2023
1 parent c910776 commit dfe135b
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 3 deletions.
6 changes: 6 additions & 0 deletions l10n/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,12 @@ msgstr ""
msgid "Show password"
msgstr ""

msgid "Skip to app navigation"
msgstr ""

msgid "Skip to main content"
msgstr ""

msgid "Smart Picker"
msgstr ""

Expand Down
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
],
"dependencies": {
"@floating-ui/dom": "^1.1.0",
"@linusborg/vue-simple-portal": "^0.1.5",
"@nextcloud/auth": "^2.0.0",
"@nextcloud/axios": "^2.0.0",
"@nextcloud/browser-storage": "^0.3.0",
Expand Down
24 changes: 21 additions & 3 deletions src/components/NcAppNavigation/NcAppNavigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,29 @@ emit('toggle-navigation', {
</template>

<script>
import NcAppNavigationToggle from '../NcAppNavigationToggle/index.js'
import { useIsMobile } from '../../composables/useIsMobile/index.js'
import { getTrapStack } from '../../utils/focusTrap.js'

import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'

import { createFocusTrap } from 'focus-trap'

import NcAppNavigationToggle from '../NcAppNavigationToggle/index.js'
import Vue from 'vue'

export default {
name: 'NcAppNavigation',

components: {
NcAppNavigationToggle,
},

// Injected from NcContent
inject: {
setHasAppNavigation: {
default: () => () => Vue.util.warn('NcAppNavigation is not mounted inside NcContent, this is probably an error.'),
from: 'NcContent:setHasAppNavigation',
},
},

props: {
/**
* The aria label to describe the navigation
Expand Down Expand Up @@ -135,6 +143,7 @@ export default {
},

mounted() {
this.setHasAppNavigation(true)
subscribe('toggle-navigation', this.toggleNavigationByEventBus)
// Emit an event with the initial state of the navigation
emit('navigation-toggled', {
Expand All @@ -150,6 +159,7 @@ export default {
this.toggleFocusTrap()
},
unmounted() {
this.setHasAppNavigation(false)
unsubscribe('toggle-navigation', this.toggleNavigationByEventBus)
this.focusTrap.deactivate()
},
Expand All @@ -161,6 +171,14 @@ export default {
* @param {boolean} [state] set the state instead of inverting the current one
*/
toggleNavigation(state) {
// Early return if alreay in that state
if (this.open === state) {
emit('navigation-toggled', {
open: this.open,
})
return
}

this.open = (typeof state === 'undefined') ? !this.open : state
const bodyStyles = getComputedStyle(document.body)
const animationLength = parseInt(bodyStyles.getPropertyValue('--animation-quick')) || 100
Expand Down
64 changes: 64 additions & 0 deletions src/components/NcContent/NcContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ This component provides the default container of all apps.
It _MUST_ be used as the main wrapper of your app.
It includes the Navigation, the App content and the Sidebar.

It also will set the skip content buttons needed for accessibility.

### Standard usage

```vue
Expand Down Expand Up @@ -72,22 +74,84 @@ It includes the Navigation, the App content and the Sidebar.
<div id="content-vue"
:class="`app-${appName.toLowerCase()}`"
class="content">
<!-- TODO: with vue3 the `selector` attribute needs to be changed to `to="#skip-actions"` -->
<Teleport selector="#skip-actions">
<div class="skip-actions">
<NcButton type="primary" href="#app-content-vue">
{{ t('Skip to main content') }}
</NcButton>
<NcButton v-show="hasAppNavigation"
type="primary"
href="#app-navigation-vue"
@click.prevent="openAppNavigation">
{{ t('Skip to app navigation') }}
</NcButton>
</div>
</Teleport>
<slot />
</div>
</template>

<script>
import { emit } from '@nextcloud/event-bus'
import { t } from '../../l10n.js'

import NcButton from '../NcButton/NcButton.vue'
// TODO: This is built-in for vue3 just drop the import
import { Portal as Teleport } from '@linusborg/vue-simple-portal'

export default {
name: 'NcContent',
components: {
NcButton,
Teleport,
},
provide() {
return {
'NcContent:setHasAppNavigation': this.setAppNavigation,
}
},
props: {
appName: {
type: String,
required: true,
},
},
data() {
return {
hasAppNavigation: false,
}
},
beforeMount() {
const container = document.getElementById('skip-actions')
if (container) {
// clear default buttons
container.innerHTML = ''
}
},
methods: {
t,
openAppNavigation() {
emit('toggle-navigation', { open: true })
this.$nextTick(() => {
window.location.hash = 'app-navigation-vue'
// we need to manually focus if the window location is already set to the app-navigation then it will not focus again
document.getElementById('app-navigation-vue').focus()
})
},
setAppNavigation(value) {
this.hasAppNavigation = value
},
},
}
</script>

<style lang="scss" scoped>
.skip-actions {
display: flex;
gap: 12px;
}

.content {
box-sizing: border-box;
margin: var(--body-container-margin);
Expand Down

0 comments on commit dfe135b

Please sign in to comment.