feat(a11y): improve focus state (#116)
This commit is contained in:
parent
2cf970225f
commit
1ad3fcf20c
|
@ -18,8 +18,8 @@ defineOptions({
|
||||||
:account="account"
|
:account="account"
|
||||||
absolute top-0 left-0 z-10
|
absolute top-0 left-0 z-10
|
||||||
op0 pointer-events-none rotate--2 mt--100vh
|
op0 pointer-events-none rotate--2 mt--100vh
|
||||||
font-normal delay-300 duration-300 transition transform
|
font-normal delay-300 duration-300 transition transform invisible
|
||||||
group-hover="pointer-events-auto op100 rotate-0 mt-0"
|
group-hover="visible pointer-events-auto op100 rotate-0 mt-0"
|
||||||
translate="x-[calc(-1rem-1px)] y-[calc(-1rem-1px)]"
|
translate="x-[calc(-1rem-1px)] y-[calc(-1rem-1px)]"
|
||||||
class="ease-[cubic-bezier(0.4, 0.0, 0.2, 1)]"
|
class="ease-[cubic-bezier(0.4, 0.0, 0.2, 1)]"
|
||||||
style="transform-origin: calc(1rem + 1px) calc(0.75rem + 1px);"
|
style="transform-origin: calc(1rem + 1px) calc(0.75rem + 1px);"
|
||||||
|
|
|
@ -4,58 +4,58 @@
|
||||||
<template>
|
<template>
|
||||||
<div px3 py4 flex="~ col gap2" text-lg>
|
<div px3 py4 flex="~ col gap2" text-lg>
|
||||||
<template v-if="currentUser">
|
<template v-if="currentUser">
|
||||||
<NuxtLink to="/home" active-class="text-primary" group>
|
<NuxtLink to="/home" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:home-5-line />
|
<div i-ri:home-5-line />
|
||||||
<span>Home</span>
|
<span>Home</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/notifications" active-class="text-primary" group>
|
<NuxtLink to="/notifications" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:notification-4-line />
|
<div i-ri:notification-4-line />
|
||||||
<span>Notifications</span>
|
<span>Notifications</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
<NuxtLink to="/explore" active-class="text-primary" group>
|
<NuxtLink to="/explore" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:hashtag />
|
<div i-ri:hashtag />
|
||||||
<span>Explore</span>
|
<span>Explore</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink group to="/public/local" active-class="text-primary">
|
<NuxtLink to="/public/local" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:group-2-line />
|
<div i-ri:group-2-line />
|
||||||
<span>Local</span>
|
<span>Local</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/public" active-class="text-primary" group>
|
<NuxtLink to="/public" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:earth-line />
|
<div i-ri:earth-line />
|
||||||
<span>Federated</span>
|
<span>Federated</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<template v-if="currentUser">
|
<template v-if="currentUser">
|
||||||
<NuxtLink to="/conversations" active-class="text-primary" group>
|
<NuxtLink to="/conversations" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:at-line />
|
<div i-ri:at-line />
|
||||||
<span>Conversations</span>
|
<span>Conversations</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/favourites" active-class="text-primary" group>
|
<NuxtLink to="/favourites" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:heart-3-line />
|
<div i-ri:heart-3-line />
|
||||||
<span>Favorites</span>
|
<span>Favorites</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/bookmarks" active-class="text-primary" group>
|
<NuxtLink to="/bookmarks" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 group-hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<div i-ri:bookmark-line />
|
<div i-ri:bookmark-line />
|
||||||
<span>Bookmarks</span>
|
<span>Bookmarks</span>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink :to="getAccountPath(currentUser.account)" active-class="text-primary" group>
|
<NuxtLink :to="getAccountPath(currentUser.account)" active-class="text-primary" group focus:outline-none>
|
||||||
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 hover:bg-active>
|
<div flex w-fit px5 py2 gap2 items-center transition-100 rounded-10 hover:bg-active group-focus-visible:ring="2 current">
|
||||||
<AccountAvatar :account="currentUser.account" h="1.2em" />
|
<AccountAvatar :account="currentUser.account" h="1.2em" />
|
||||||
<span>Profile</span>
|
<span>Profile</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- Use external to force refresh page and jump to top of timeline -->
|
<!-- Use external to force refresh page and jump to top of timeline -->
|
||||||
<NuxtLink flex items-center text-2xl gap-2 to="/" external>
|
<NuxtLink flex px3 py2 items-center text-2xl gap-2 hover:bg-active focus-visible:ring="2 current" rounded-full to="/" external>
|
||||||
<img aria-label="Elk Logo" src="/logo.svg" w-10 h-10>
|
<img aria-label="Elk Logo" src="/logo.svg" w-10 h-10>
|
||||||
<div>
|
<div>
|
||||||
Elk <sup text-sm italic op50 mt-1>alpha</sup>
|
Elk <sup text-sm italic op50 mt-1>alpha</sup>
|
||||||
|
|
|
@ -8,6 +8,7 @@ defineProps<{
|
||||||
groupHover: string
|
groupHover: string
|
||||||
active?: boolean
|
active?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
as?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
|
@ -16,15 +17,17 @@ defineOptions({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<button
|
<component
|
||||||
flex gap-1 items-center rounded :hover="`op100 ${hover}`" group
|
:is="as || 'button'"
|
||||||
|
flex gap-1 items-center rounded group
|
||||||
|
:hover="`op100 ${hover}`" focus:outline-none :focus-visible="`op100 ${hover}`"
|
||||||
:class="active ? [color, 'op100'] : 'op50'"
|
:class="active ? [color, 'op100'] : 'op50'"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
>
|
>
|
||||||
<div rounded-full p2 :group-hover="groupHover">
|
<div rounded-full p2 :group-hover="groupHover" :group-focus-visible="groupHover" group-focus-visible:ring="2 current">
|
||||||
<div :class="[active && activeIcon ? activeIcon : icon, { 'pointer-events-none': disabled }]" />
|
<div :class="[active && activeIcon ? activeIcon : icon, { 'pointer-events-none': disabled }]" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span v-if="text">{{ text }}</span>
|
<span v-if="text">{{ text }}</span>
|
||||||
</button>
|
</component>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -117,13 +117,13 @@ function editStatus() {
|
||||||
<template>
|
<template>
|
||||||
<div flex justify-between>
|
<div flex justify-between>
|
||||||
<CommonTooltip placement="bottom" content="Reply">
|
<CommonTooltip placement="bottom" content="Reply">
|
||||||
<RouterLink :to="getStatusPath(status)">
|
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
|
as="router-link"
|
||||||
|
:to="getStatusPath(status)"
|
||||||
:text="status.repliesCount"
|
:text="status.repliesCount"
|
||||||
color="text-blue" hover="text-blue" group-hover="bg-blue/10"
|
color="text-blue" hover="text-blue" group-hover="bg-blue/10"
|
||||||
icon="i-ri:chat-3-line"
|
icon="i-ri:chat-3-line"
|
||||||
/>
|
/>
|
||||||
</RouterLink>
|
|
||||||
</CommonTooltip>
|
</CommonTooltip>
|
||||||
|
|
||||||
<CommonTooltip placement="bottom" content="Boost">
|
<CommonTooltip placement="bottom" content="Boost">
|
||||||
|
|
|
@ -55,6 +55,15 @@ const aspectRatio = computed(() => {
|
||||||
</audio>
|
</audio>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
<button
|
||||||
|
focus:outline-none
|
||||||
|
focus:ring="2 primary inset"
|
||||||
|
rounded-lg
|
||||||
|
@click="openImagePreviewDialog({
|
||||||
|
src: attachment.url || attachment.previewUrl!,
|
||||||
|
alt: attachment.description!,
|
||||||
|
})"
|
||||||
|
>
|
||||||
<CommonBlurhash
|
<CommonBlurhash
|
||||||
:blurhash="attachment.blurhash"
|
:blurhash="attachment.blurhash"
|
||||||
class="status-attachment-image"
|
class="status-attachment-image"
|
||||||
|
@ -64,12 +73,11 @@ const aspectRatio = computed(() => {
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
}"
|
}"
|
||||||
border="~ base"
|
border="~ base"
|
||||||
object-cover
|
|
||||||
rounded-lg
|
rounded-lg
|
||||||
@click="openImagePreviewDialog({
|
h-full
|
||||||
src: attachment.url || attachment.previewUrl!,
|
w-full
|
||||||
alt: attachment.description!,
|
object-cover
|
||||||
})"
|
|
||||||
/>
|
/>
|
||||||
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -68,7 +68,7 @@ const timeago = useTimeAgo(() => status.createdAt, {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="el" flex flex-col gap-2 px-4 transition-100 :class="{ 'hover:bg-active': hover }" @click="onclick">
|
<div ref="el" flex flex-col gap-2 px-4 transition-100 :class="{ 'hover:bg-active': hover }" tabindex="0" focus:outline-none focus-visible:ring="2 primary" @click="onclick" @keydown.enter="onclick">
|
||||||
<div v-if="rebloggedBy" pl8>
|
<div v-if="rebloggedBy" pl8>
|
||||||
<div flex="~ wrap" gap-1 items-center text-gray:75 text-sm>
|
<div flex="~ wrap" gap-1 items-center text-gray:75 text-sm>
|
||||||
<div i-ri:repeat-fill mr-1 />
|
<div i-ri:repeat-fill mr-1 />
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="hidden md:block w-1/4 zen-hide" relative>
|
<div class="hidden md:block w-1/4 zen-hide" relative>
|
||||||
<div sticky top-0 h-screen flex="~ col">
|
<div sticky top-0 h-screen flex="~ col">
|
||||||
<slot name="left">
|
<slot name="left">
|
||||||
<NavTitle px6 pt6 pb4 />
|
<NavTitle mx3 mt4 mb2 self-start />
|
||||||
<div flex="~ col" overflow-y-auto>
|
<div flex="~ col" overflow-y-auto>
|
||||||
<NavSide />
|
<NavSide />
|
||||||
<PublishButton v-if="currentUser" m5 />
|
<PublishButton v-if="currentUser" m5 />
|
||||||
|
|
Loading…
Reference in a new issue