Toggle sobre 2 options (role radiogroup, flèches/Home/End, focus visible, reduced-motion), étiquette de mode sur les réponses approfondies, et useChatProfondeur (état par clé, desktop et mobile synchronisés). Libellés lus dans utils/chatProfondeur.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015vcVGz8i4WpZm2dixKUiSD
81 lines
2.4 KiB
Vue
81 lines
2.4 KiB
Vue
<template>
|
|
<div class="chat-mode" role="radiogroup" aria-label="Mode de réponse">
|
|
<button
|
|
v-for="(p, i) in CHAT_PROFONDEURS"
|
|
:key="p"
|
|
:ref="(el) => (boutons[i] = el as HTMLButtonElement | null)"
|
|
type="button"
|
|
role="radio"
|
|
class="chat-mode-option"
|
|
:class="{ active: modelValue === p }"
|
|
:aria-checked="modelValue === p"
|
|
:tabindex="modelValue === p ? 0 : -1"
|
|
:title="CHAT_PROFONDEUR_AIDES[p]"
|
|
:disabled="disabled"
|
|
@click="choisir(p)"
|
|
@keydown="onKey($event, i)"
|
|
>{{ CHAT_PROFONDEUR_LIBELLES[p] }}</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
// Toggle 2 options partagé par les 5 chatbots. Libellés : utils/chatProfondeur.ts.
|
|
// radiogroup : flèches déplacent la sélection, Tab entre/sort du groupe (roving tabindex).
|
|
const props = defineProps<{ modelValue: 'rapide' | 'approfondi'; disabled?: boolean }>()
|
|
const emit = defineEmits<{ 'update:modelValue': [value: 'rapide' | 'approfondi'] }>()
|
|
|
|
const boutons = ref<(HTMLButtonElement | null)[]>([])
|
|
|
|
function choisir(p: ChatProfondeur) {
|
|
if (!props.disabled) emit('update:modelValue', p)
|
|
}
|
|
|
|
function onKey(e: KeyboardEvent, i: number) {
|
|
const n = CHAT_PROFONDEURS.length
|
|
let j = -1
|
|
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') j = (i + 1) % n
|
|
else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') j = (i - 1 + n) % n
|
|
else if (e.key === 'Home') j = 0
|
|
else if (e.key === 'End') j = n - 1
|
|
if (j < 0) return
|
|
e.preventDefault()
|
|
choisir(CHAT_PROFONDEURS[j])
|
|
nextTick(() => boutons.value[j]?.focus())
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.chat-mode {
|
|
display: inline-flex;
|
|
gap: 2px;
|
|
padding: 2px;
|
|
border-radius: 9999px;
|
|
background: var(--nav-bg-alt);
|
|
align-self: flex-start;
|
|
}
|
|
.chat-mode-option {
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--nav-text-muted);
|
|
font-family: var(--nav-font);
|
|
font-size: 0.72rem;
|
|
line-height: 1.2;
|
|
padding: 4px 10px;
|
|
border-radius: 9999px;
|
|
cursor: pointer;
|
|
transition: background 0.15s, color 0.15s;
|
|
}
|
|
.chat-mode-option:hover:not(.active):not(:disabled) { color: var(--nav-text); }
|
|
.chat-mode-option.active {
|
|
background: var(--nav-primary);
|
|
color: var(--nav-text-on-primary);
|
|
font-weight: 600;
|
|
}
|
|
.chat-mode-option:focus-visible { outline: 2px solid var(--nav-primary); outline-offset: 2px; }
|
|
.chat-mode-option:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.chat-mode-option { transition: none; }
|
|
}
|
|
</style>
|