Files
decision/web/src/lib/components/ChoicePicker.svelte
T
YvvandClaude Opus 5.5 5d1f8652fc v3 : interface d'une version retenue — « Contre » et « Retirer mon vote », jamais « Pour »
Sous l'article, une version retenue montre « Contre » et le retrait, avec la
phrase qui dit pourquoi. Dans le panier, elle se choisit en « contre » ou en
retrait ; « Tout pour » la saute et le dit, « Tout contre » la prend ; un « pour »
gardé d'avant l'objection quitte le panier (basket.kept). Les phrases qui disaient
« ne se vote plus » disent la règle d'Yvv, en fr, en et es. C28 ajusté.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 00:41:50 +01:00

86 lines
2.3 KiB
Svelte

<script lang="ts">
// One choice of the basket: for, against, or withdraw one's vote (when there is
// one). Pressing the chosen one again takes the version out of the basket. A
// version held back by an objection offers no « for » (Yvv, 2026-11-01).
import { t } from '$lib/i18n/index.svelte';
import type { Choice } from '$lib/types';
let {
value,
voted,
label,
held = false,
disabled = false,
onpick,
}: {
value: Choice | undefined;
voted: boolean;
label: string;
/** Held back by an objection: against or a withdrawal only. */
held?: boolean;
disabled?: boolean;
onpick: (c: Choice) => void;
} = $props();
</script>
<span class="picker" role="group" aria-label={label}>
{#if !held}
<button type="button" class="for" aria-pressed={value === 'for'} {disabled} onclick={() => onpick('for')}>{t('vote.for')}</button>
{/if}
<button type="button" class="against" aria-pressed={value === 'against'} {disabled} onclick={() => onpick('against')}>{t('vote.against')}</button>
{#if voted || value === 'none'}
<button type="button" class="none" aria-pressed={value === 'none'} {disabled} onclick={() => onpick('none')}>{t('basket.pick.retract')}</button>
{/if}
</span>
<style>
.picker {
display: inline-flex;
flex-wrap: wrap;
gap: 0.25rem;
background: var(--surface-2);
padding: 3px;
border-radius: var(--r-pill);
}
button {
border: 0;
background: transparent;
border-radius: var(--r-pill);
padding: 0.3rem 0.75rem;
min-height: 2.25rem;
min-width: 2.75rem;
font-weight: 750;
font-size: 0.84rem;
color: var(--ink-soft);
transition: background-color 0.15s var(--ease), color 0.15s var(--ease);
}
button:hover:not(:disabled) {
color: var(--ink);
background: var(--surface);
}
.for[aria-pressed='true'],
.for[aria-pressed='true']:hover {
background: var(--moss);
color: var(--on-water);
}
.against[aria-pressed='true'],
.against[aria-pressed='true']:hover {
background: var(--ochre);
color: var(--on-water);
}
.none[aria-pressed='true'],
.none[aria-pressed='true']:hover {
background: var(--ink-soft);
color: var(--surface);
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
@media (prefers-reduced-motion: reduce) {
button {
transition: none;
}
}
</style>