Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
All results audio tabbing, single result link, and play/pause fixes (#…
Browse files Browse the repository at this point in the history
…683)

* tabindex -1 on play/pause when layout is box

* play/pause on spacebar
  • Loading branch information
zackkrida authored Jan 21, 2022
1 parent fe4008a commit f5ce564
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 20 deletions.
26 changes: 9 additions & 17 deletions src/components/VAllResultsGrid/VAudioCell.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<template>
<NuxtLink
:to="localePath(`/audio/${audio.id}`)"
class="block focus:bg-white focus:border-tx focus:ring focus:ring-pink focus:outline-none focus:shadow-ring rounded-sm"
@click.native="navigateToSinglePage(audio)"
>
<VAudioTrack :audio="audio" layout="box" size="full" />
</NuxtLink>
<VAudioTrack
:audio="audio"
layout="box"
size="full"
@boxedAudioClick="navigateToSinglePage"
/>
</template>

<script>
Expand All @@ -17,17 +16,10 @@ export default defineComponent({
components: { VAudioTrack },
props: ['audio'],
setup() {
const { i18n } = useContext()
const { app } = useContext()
const router = useRouter()
const navigateToSinglePage = (audio) => (/** @type MouseEvent */ event) => {
if (!event.metaKey && !event.ctrlKey) {
event.preventDefault()
const detailRoute = i18n.localeRoute({
name: 'AudioDetailPage',
params: { id: audio.id, location: window.scrollY },
})
router.push(detailRoute)
}
const navigateToSinglePage = (audio) => {
router.push(app.localePath({ path: `/audio/${audio.id}` }))
}
return {
Expand Down
52 changes: 51 additions & 1 deletion src/components/VAudioTrack/VAudioTrack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
class="audio-track"
:aria-label="$t('audio-track.aria-label')"
role="region"
v-bind="layoutBasedProps"
v-on="layoutBasedListeners"
>
<Component :is="layoutComponent" :audio="audio" :size="size">
<template #controller="waveformProps">
Expand All @@ -18,6 +20,7 @@

<template #play-pause="playPauseProps">
<VPlayPause
ref="playPauseRef"
:status="status"
v-bind="playPauseProps"
@toggle="handleToggle"
Expand Down Expand Up @@ -67,6 +70,7 @@ const propTypes = {
/**
* the arrangement of the contents on the canvas; This determines the
* overall L&F of the audio component.
* @todo This type def should be extracted for reuse across components
*/
layout: {
type: /** @type {import('@nuxtjs/composition-api').PropType<'full' | 'box' | 'row' | 'global'>} */ (
Expand Down Expand Up @@ -111,7 +115,7 @@ export default defineComponent({
VGlobalLayout,
},
props: propTypes,
setup(props) {
setup(props, { emit }) {
const store = useStore()
const route = useRoute()
Expand Down Expand Up @@ -328,6 +332,47 @@ export default defineComponent({
}
const layoutComponent = computed(() => layoutMappings[props.layout])
/**
* A ref used on the play/pause button,
* so we can capture clicks and skip
* sending an event to the boxed layout.
*/
const playPauseRef = ref(null)
/**
* These layout-conditional props and listeners allow us
* to set properties on the parent element depending on
* the layout in use. This is currently relevant for the
* boxed layout exclusively.
*/
const isBoxed = computed(() => props.layout === 'box')
const layoutBasedProps = computed(() => {
if (!isBoxed.value) return {}
return {
tabindex: isBoxed.value ? 0 : -1,
class:
'block focus:bg-white focus:border-tx focus:ring focus:ring-pink focus:outline-none focus:shadow-ring rounded-sm overflow-hidden cursor-pointer',
}
})
const layoutBasedListeners = computed(() => {
if (!isBoxed.value) return {}
return {
click: (event) => {
// Emit an event when the boxed layout is clicked
// unless the click is on the play/pause button
if (event.target === playPauseRef?.value?.$el) return
emit('boxedAudioClick', props.audio)
},
keydown: (event) => {
// 32 is Spacebar
if (event.keyCode !== 32) return
event.preventDefault()
status.value = status.value === 'playing' ? 'paused' : 'playing'
handleToggle(status.value)
},
}
})
return {
status,
message,
Expand All @@ -338,6 +383,11 @@ export default defineComponent({
duration,
layoutComponent,
layoutBasedProps,
layoutBasedListeners,
playPauseRef,
}
},
})
Expand Down
1 change: 1 addition & 0 deletions src/components/VAudioTrack/VGlobalAudioTrack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const propTypes = {
/**
* the arrangement of the contents on the canvas; This determines the
* overall L&F of the audio component.
* @todo This type def should be extracted for reuse across components
*/
layout: {
type: /** @type {import('@nuxtjs/composition-api').PropType<'full' | 'box' | 'row' | 'global'>} */ (
Expand Down
15 changes: 15 additions & 0 deletions src/components/VAudioTrack/VPlayPause.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<VIconButton
v-bind="$attrs"
:tabindex="layout === 'box' ? -1 : 0"
class="play-pause flex-shrink-0 bg-dark-charcoal border-dark-charcoal text-white disabled:opacity-70"
:icon-props="{ iconPath: icon }"
:aria-label="$t(label)"
Expand Down Expand Up @@ -37,6 +38,20 @@ export default defineComponent({
type: String,
validator: (val) => ['playing', 'paused', 'played'].includes(val),
},
/**
* The parent audio layout currently in use
* @todo This type def should be extracted for reuse across components
*/
layout: {
type: /** @type {import('@nuxtjs/composition-api').PropType<'full' | 'box' | 'row' | 'global'>} */ (
String
),
default: 'full',
/**
* @param {string} val
*/
validator: (val) => ['full', 'box', 'row', 'global'].includes(val),
},
},
data() {
return {
Expand Down
2 changes: 1 addition & 1 deletion src/components/VAudioTrack/layouts/VBoxLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</div>

<div class="hidden player md:flex flex-row">
<slot name="play-pause" size="small" />
<slot name="play-pause" size="small" layout="box" />
<slot name="controller" :features="[]" />
</div>
</div>
Expand Down
6 changes: 5 additions & 1 deletion src/components/VIconButton/VIconButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
:type="type"
v-on="$listeners"
>
<VIcon :class="[...iconSizeClasses]" v-bind="iconProps" />
<VIcon
class="pointer-events-none"
:class="[...iconSizeClasses]"
v-bind="iconProps"
/>
</button>
</template>

Expand Down

0 comments on commit f5ce564

Please sign in to comment.