mirror of
https://github.com/chenasraf/nextcloud-forum.git
synced 2026-05-17 17:28:02 +00:00
feat: improve accessibility
This commit is contained in:
@@ -3,12 +3,12 @@
|
||||
<div class="bbcode-help">
|
||||
<!-- Built-in BBCodes Section -->
|
||||
<section class="bbcode-section">
|
||||
<h3 class="section-title">{{ strings.builtInTitle }}</h3>
|
||||
<h2 class="section-title">{{ strings.builtInTitle }}</h2>
|
||||
<p class="section-description">{{ strings.builtInDescription }}</p>
|
||||
|
||||
<div class="bbcode-list">
|
||||
<ul class="bbcode-list">
|
||||
<!-- Library-provided BBCodes -->
|
||||
<div v-for="code in builtInCodes" :key="code.tag" class="bbcode-item">
|
||||
<li v-for="code in builtInCodes" :key="code.tag" class="bbcode-item">
|
||||
<div class="bbcode-header">
|
||||
<code class="bbcode-tag">[{{ code.tag }}]</code>
|
||||
<span class="bbcode-name">{{ code.name }}</span>
|
||||
@@ -17,10 +17,10 @@
|
||||
<span class="example-label">{{ strings.example }}:</span>
|
||||
<code class="example-code">{{ code.example }}</code>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Database builtin BBCodes -->
|
||||
<div v-for="code in builtinDbCodes" :key="code.id" class="bbcode-item">
|
||||
<li v-for="code in builtinDbCodes" :key="code.id" class="bbcode-item">
|
||||
<div class="bbcode-header">
|
||||
<code class="bbcode-tag">[{{ code.tag }}]</code>
|
||||
<span v-if="code.description" class="bbcode-name">{{ code.description }}</span>
|
||||
@@ -29,13 +29,13 @@
|
||||
<span class="example-label">{{ strings.example }}:</span>
|
||||
<code class="example-code">{{ code.example }}</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<!-- Custom BBCodes Section -->
|
||||
<section v-if="showCustom" class="bbcode-section">
|
||||
<h3 class="section-title">{{ strings.customTitle }}</h3>
|
||||
<h2 class="section-title">{{ strings.customTitle }}</h2>
|
||||
<p class="section-description">{{ strings.customDescription }}</p>
|
||||
|
||||
<!-- Loading state -->
|
||||
@@ -55,8 +55,8 @@
|
||||
</div>
|
||||
|
||||
<!-- Custom codes list -->
|
||||
<div v-else class="bbcode-list">
|
||||
<div v-for="code in customCodes" :key="code.id" class="bbcode-item">
|
||||
<ul v-else class="bbcode-list">
|
||||
<li v-for="code in customCodes" :key="code.id" class="bbcode-item">
|
||||
<div class="bbcode-header">
|
||||
<code class="bbcode-tag">[{{ code.tag }}]</code>
|
||||
<span v-if="code.description" class="bbcode-name">{{ code.description }}</span>
|
||||
@@ -65,8 +65,8 @@
|
||||
<span class="example-label">{{ strings.example }}:</span>
|
||||
<code class="example-code" :v-html="code.example"></code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</NcDialog>
|
||||
@@ -313,6 +313,9 @@ export default defineComponent({
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.bbcode-item {
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
@update:open="uploadDialog = $event"
|
||||
size="small"
|
||||
>
|
||||
<div class="upload-progress">
|
||||
<div class="upload-progress" aria-live="polite">
|
||||
<p class="upload-filename">{{ uploadFileName }}</p>
|
||||
<template v-if="uploadError">
|
||||
<p class="upload-error-message">{{ uploadError }}</p>
|
||||
|
||||
@@ -3,9 +3,17 @@
|
||||
class="category-card"
|
||||
:class="{ unread: isUnread, colored: !!category.color }"
|
||||
:style="cardStyle"
|
||||
role="link"
|
||||
tabindex="0"
|
||||
>
|
||||
<div class="category-header">
|
||||
<span v-if="isUnread" class="unread-indicator" :title="strings.unread"></span>
|
||||
<span
|
||||
v-if="isUnread"
|
||||
class="unread-indicator"
|
||||
:title="strings.unread"
|
||||
:aria-label="strings.unread"
|
||||
role="img"
|
||||
></span>
|
||||
<h4 class="category-name">{{ category.name }}</h4>
|
||||
<div class="category-stats">
|
||||
<span class="stat">
|
||||
|
||||
@@ -8,12 +8,16 @@
|
||||
@update:model-value="$emit('update:modelValue', $event)"
|
||||
@submit="$emit('update:modelValue', $event)"
|
||||
>
|
||||
<NcButton>
|
||||
<NcButton
|
||||
:aria-label="modelValue ? strings.changeColor + ': ' + modelValue : strings.pickColor"
|
||||
>
|
||||
<template #icon>
|
||||
<div
|
||||
class="color-preview"
|
||||
:class="{ empty: !modelValue }"
|
||||
:style="modelValue ? { backgroundColor: modelValue } : {}"
|
||||
role="img"
|
||||
:aria-label="modelValue || strings.noColor"
|
||||
/>
|
||||
</template>
|
||||
{{ modelValue || strings.pickColor }}
|
||||
@@ -53,6 +57,8 @@ export default defineComponent({
|
||||
return {
|
||||
strings: {
|
||||
pickColor: t('forum', 'Pick a color'),
|
||||
changeColor: t('forum', 'Change color'),
|
||||
noColor: t('forum', 'No color selected'),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</template>
|
||||
{{ initializing ? strings.initializingButton : strings.initializeButton }}
|
||||
</NcButton>
|
||||
<NcNoteCard v-if="errorMessage" type="error" class="init-note">
|
||||
<NcNoteCard v-if="errorMessage" type="error" class="init-note" role="alert">
|
||||
{{ errorMessage }}
|
||||
</NcNoteCard>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="deleted-item-list">
|
||||
<!-- Loading -->
|
||||
<div v-if="loading" class="center mt-16">
|
||||
<div v-if="loading" class="center mt-16" aria-live="polite" aria-busy="true">
|
||||
<NcLoadingIcon :size="32" />
|
||||
</div>
|
||||
|
||||
@@ -27,14 +27,17 @@
|
||||
|
||||
<!-- Items -->
|
||||
<template v-else>
|
||||
<div class="item-list">
|
||||
<ul class="item-list">
|
||||
<!-- Thread items: clickable to open preview -->
|
||||
<div
|
||||
<li
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
class="deleted-item-wrapper"
|
||||
:class="{ clickable: mode === 'threads' }"
|
||||
:role="mode === 'threads' ? 'button' : undefined"
|
||||
:tabindex="mode === 'threads' ? 0 : undefined"
|
||||
@click="mode === 'threads' && $emit('view', item)"
|
||||
@keydown.enter="mode === 'threads' && $emit('view', item)"
|
||||
>
|
||||
<div class="deleted-item-overlay">
|
||||
<span class="deleted-badge">
|
||||
@@ -67,8 +70,8 @@
|
||||
</div>
|
||||
<ThreadCard v-if="mode === 'threads'" :thread="item" />
|
||||
<PostCard v-else :post="item" />
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Pagination
|
||||
v-if="maxPages > 1"
|
||||
@@ -140,6 +143,8 @@ export default defineComponent({
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.deleted-item-wrapper {
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
<div class="post-card" :class="{ 'first-post': isFirstPost, unread: isUnread }">
|
||||
<div class="post-header">
|
||||
<div class="author-info">
|
||||
<span v-if="isUnread" class="unread-indicator" :title="strings.unread"></span>
|
||||
<span
|
||||
v-if="isUnread"
|
||||
class="unread-indicator"
|
||||
:title="strings.unread"
|
||||
:aria-label="strings.unread"
|
||||
role="img"
|
||||
></span>
|
||||
<UserInfo
|
||||
:user-id="post.author?.userId || post.authorId"
|
||||
:display-name="post.author?.displayName || post.authorId"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<NcDialog :name="strings.title" :open="open" @update:open="handleClose" size="large">
|
||||
<div class="post-history-dialog">
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="loading-state">
|
||||
<div v-if="loading" class="loading-state" aria-live="polite" aria-busy="true">
|
||||
<NcLoadingIcon :size="32" />
|
||||
<span class="loading-text">{{ strings.loading }}</span>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
class="reaction-button"
|
||||
:class="{ reacted: isReacted(emoji), 'has-count': getCount(emoji) > 0 }"
|
||||
:title="getReactionTooltip(emoji)"
|
||||
:aria-label="getReactionTooltip(emoji)"
|
||||
:aria-pressed="isReacted(emoji)"
|
||||
@click="handleToggleReaction(emoji)"
|
||||
>
|
||||
<span class="emoji">{{ emoji }}</span>
|
||||
@@ -15,7 +17,11 @@
|
||||
|
||||
<!-- Add custom reaction button -->
|
||||
<LazyEmojiPicker @select="handleSelectEmoji" style="display: inline-block">
|
||||
<button class="add-reaction-button" :title="strings.addReaction">
|
||||
<button
|
||||
class="add-reaction-button"
|
||||
:title="strings.addReaction"
|
||||
:aria-label="strings.addReaction"
|
||||
>
|
||||
<span class="icon">+</span>
|
||||
</button>
|
||||
</LazyEmojiPicker>
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<template>
|
||||
<div class="search-post-result" :class="{ 'dark-theme': isDarkTheme }" @click="navigateToPost">
|
||||
<div
|
||||
class="search-post-result"
|
||||
:class="{ 'dark-theme': isDarkTheme }"
|
||||
role="link"
|
||||
tabindex="0"
|
||||
@click="navigateToPost"
|
||||
@keydown.enter="navigateToPost"
|
||||
>
|
||||
<div class="result-header">
|
||||
<div class="thread-context">
|
||||
<span class="meta-label">{{ strings.inThread }}:</span>
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
<template>
|
||||
<div class="search-thread-result" :class="{ 'dark-theme': isDarkTheme }" @click="$emit('click')">
|
||||
<div
|
||||
class="search-thread-result"
|
||||
:class="{ 'dark-theme': isDarkTheme }"
|
||||
role="link"
|
||||
tabindex="0"
|
||||
@click="$emit('click')"
|
||||
@keydown.enter="$emit('click')"
|
||||
>
|
||||
<div class="result-header">
|
||||
<h4 class="thread-title">
|
||||
<span v-if="thread.isPinned" class="badge badge-pinned" :title="strings.pinned">
|
||||
<span
|
||||
v-if="thread.isPinned"
|
||||
class="badge badge-pinned"
|
||||
:title="strings.pinned"
|
||||
:aria-label="strings.pinned"
|
||||
role="img"
|
||||
>
|
||||
<PinIcon :size="16" />
|
||||
</span>
|
||||
<span v-if="thread.isLocked" class="badge badge-locked" :title="strings.locked">
|
||||
<span
|
||||
v-if="thread.isLocked"
|
||||
class="badge badge-locked"
|
||||
:title="strings.locked"
|
||||
:aria-label="strings.locked"
|
||||
role="img"
|
||||
>
|
||||
<LockIcon :size="16" />
|
||||
</span>
|
||||
<span v-html="highlightedTitle"></span>
|
||||
@@ -35,6 +54,7 @@
|
||||
</span>
|
||||
<a
|
||||
v-if="thread.lastReply"
|
||||
href="#"
|
||||
class="meta-item last-reply"
|
||||
@click.prevent.stop="$emit('navigate-last-reply', thread)"
|
||||
>
|
||||
|
||||
@@ -6,7 +6,13 @@
|
||||
<div class="thread-main">
|
||||
<div class="thread-header">
|
||||
<div class="thread-title-row">
|
||||
<span v-if="isUnread" class="unread-indicator" :title="strings.unread"></span>
|
||||
<span
|
||||
v-if="isUnread"
|
||||
class="unread-indicator"
|
||||
:title="strings.unread"
|
||||
:aria-label="strings.unread"
|
||||
role="img"
|
||||
></span>
|
||||
<h4 class="thread-title">
|
||||
<span v-if="thread.isPinned" class="badge badge-pinned" :title="strings.pinned">
|
||||
<PinIcon :size="16" />
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
:placeholder="strings.searchPlaceholder"
|
||||
:aria-label="strings.searchTitle"
|
||||
class="search-input"
|
||||
@keydown.enter="performSearch"
|
||||
/>
|
||||
@@ -23,7 +24,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Search Options -->
|
||||
<div class="search-options">
|
||||
<fieldset class="search-options">
|
||||
<NcCheckboxRadioSwitch v-model="searchThreads" @update:checked="onOptionsChange">
|
||||
{{ strings.searchThreads }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
@@ -37,7 +38,7 @@
|
||||
</template>
|
||||
{{ strings.syntaxHelp }}
|
||||
</NcButton>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Syntax Help -->
|
||||
<div v-if="showSyntaxHelp" class="syntax-help">
|
||||
@@ -53,7 +54,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="center mt-16">
|
||||
<div v-if="loading" class="center mt-16" aria-live="polite">
|
||||
<NcLoadingIcon :size="32" />
|
||||
<span class="muted ml-8">{{ strings.searching }}</span>
|
||||
</div>
|
||||
@@ -95,7 +96,7 @@
|
||||
</NcEmptyContent>
|
||||
|
||||
<!-- Results -->
|
||||
<div v-else class="search-results mt-16">
|
||||
<div v-else class="search-results mt-16" aria-live="polite">
|
||||
<!-- Thread Results Section -->
|
||||
<section v-if="searchThreads && threadResults.length > 0" class="results-section">
|
||||
<h3 class="results-header">
|
||||
@@ -328,6 +329,9 @@ export default defineComponent({
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.syntax-help {
|
||||
|
||||
Reference in New Issue
Block a user