v3 : modules d'ordre et de titre — l'interface, restes mineurs (L11, C25–C27)
Chaque section du lecteur finit par l'ordre de ses articles (inertie 2) : ses articles numérotés, son vote déplié, « Proposer un autre ordre » — une liste où l'on clique un article puis sa place, ses flèches, ou le clavier. Le titre du document (inertie 4) se vote et se propose sous le titre, « traduction à revoir » quand il a changé. Les deux sont dans la liste des propositions, le panier et la chaîne Ğ1 ; un nouvel article se propose dans une section, à sa fin. La liste du groupe compte les propositions ouvertes des modules. Restes mineurs : la participation ramenée se dit en deux temps (la mesure, puis ce que le groupe demande), les lignes « habituelle » des réglages resserrées, le sélecteur d'inertie se parcourt aux flèches (le cran actuel atteignable, jamais choisi), la marque « seed a minima » porte le vrai nombre de votes. Contrôles : C25 (ordre, dont la chaîne et le téléphone), C26 (titre), C27 (participation ramenée) ; C3, C17 (41 modules), C20 mis à jour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<script lang="ts">
|
||||
// The title of the document is a module (ADR 0009, inertia 4): under the title,
|
||||
// the gestures of an article — the vote, the proposals, another title.
|
||||
import type { Snippet } from 'svelte';
|
||||
import { i18n, t } from '$lib/i18n/index.svelte';
|
||||
import { inertiaBadge, moduleName } from '$lib/labels';
|
||||
import type { Unit } from '$lib/types';
|
||||
|
||||
let {
|
||||
unit,
|
||||
stale = false,
|
||||
selected = false,
|
||||
voteOpen = false,
|
||||
fold,
|
||||
onaction,
|
||||
}: {
|
||||
/** The title module of the document. */
|
||||
unit: Unit;
|
||||
/** The title read is a translation of an older title. */
|
||||
stale?: boolean;
|
||||
selected?: boolean;
|
||||
voteOpen?: boolean;
|
||||
fold?: Snippet;
|
||||
onaction: (action: 'vote' | 'proposals' | 'propose') => void;
|
||||
} = $props();
|
||||
|
||||
const p = $derived(unit.inForce);
|
||||
const votes = $derived((p?.tally.for ?? 0) + (p?.tally.against ?? 0));
|
||||
const rivals = $derived(unit.proposals.filter((x) => x.status === 'open' && x.kind === 'title').length);
|
||||
</script>
|
||||
|
||||
<div class="title-unit" class:selected class:unfolded={voteOpen}>
|
||||
<p class="bar">
|
||||
<span class="status faint">
|
||||
{moduleName(unit)} · {inertiaBadge(unit.inertia)}
|
||||
{#if p?.seedMinimal} · <span title={t('doc.seed.long')}>{i18n.plural('doc.seed.votes', votes)}</span>
|
||||
{:else if p?.enteredAt} · {t('doc.adopted', { date: i18n.date(p.enteredAt) })}{/if}
|
||||
</span>
|
||||
{#if stale}<span class="tag ochre">{t('doc.lang.stale')}</span>{/if}
|
||||
<span class="links">
|
||||
<button type="button" class:on={voteOpen} aria-expanded={voteOpen} aria-controls={p ? `vote-${p.id}` : undefined} onclick={() => onaction('vote')}>{t('doc.action.vote')}</button>
|
||||
<button type="button" onclick={() => onaction('proposals')}>{t('doc.action.proposals')}{#if rivals > 0}{` · ${rivals}`}{/if}</button>
|
||||
<button type="button" onclick={() => onaction('propose')}>{t('title.propose')}</button>
|
||||
</span>
|
||||
</p>
|
||||
{#if voteOpen && fold}<div class="fold">{@render fold()}</div>{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.title-unit {
|
||||
margin: 0.5rem -1.3rem 0;
|
||||
padding: 0.2rem 1.3rem;
|
||||
border-radius: var(--r-card);
|
||||
transition: background-color 0.18s ease;
|
||||
}
|
||||
.title-unit.selected,
|
||||
.title-unit.unfolded {
|
||||
background: var(--surface);
|
||||
box-shadow: var(--shadow);
|
||||
padding-block: 0.5rem 0.9rem;
|
||||
}
|
||||
.bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.3rem 0.8rem;
|
||||
font-size: 0.82rem;
|
||||
min-height: 2.25rem;
|
||||
}
|
||||
.status {
|
||||
font-weight: 700;
|
||||
}
|
||||
.links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.2rem;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s ease;
|
||||
}
|
||||
/* Discreet as under an article: the gestures show when the head is pointed at. */
|
||||
:global(.head:hover) .links,
|
||||
.title-unit:focus-within .links,
|
||||
.title-unit.selected .links,
|
||||
.title-unit.unfolded .links {
|
||||
opacity: 1;
|
||||
}
|
||||
.links button {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--water);
|
||||
font-weight: 750;
|
||||
padding: 0.3rem 0.6rem;
|
||||
min-height: 2.25rem;
|
||||
border-radius: var(--r-pill);
|
||||
}
|
||||
.links button:hover,
|
||||
.links button.on {
|
||||
background: var(--water-wash);
|
||||
}
|
||||
.fold {
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
@media (hover: none) {
|
||||
.links {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.title-unit,
|
||||
.links {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user