Files
arboretum/packages/web/src/components/workspace/FileRow.vue
T
johanleroy 063f5e928b feat(web): refonte visuelle « Emerald » (thème clair/sombre, polices, tokens)
Adopte le langage visuel du design system Emerald dans l'IDE web :
neutres zinc + accent emerald, polices auto-hébergées Inter + JetBrains
Mono, radii/pills mono, points de statut, motif terminal, halo/grain.
Refonte purement visuelle et additive (layout, routing, stores, protocole
inchangés).

- style.css : défauts sombres dans @theme + override clair sous
  html[data-theme=light] ; accent scindé (bright #34d399 / solid #059669 /
  hover) ; tokens border-soft/info/warn/danger/coffee ; idiomes globaux
  (focus/selection accent, scrollbars fines, jl-pulse/jl-blink, classes
  .chip/.status/.eyebrow/.label-mono/.caret/.halo/.grain, .btn*/.badge pill).
- lib/theme.ts : singleton themeMode/resolvedTheme (dark/light/system,
  persistedRef arb.theme) + application dataset.theme/metas ; script
  anti-FOUC inline dans index.html ; toggle ActivityBar + Réglages.
- Thèmes Monaco + xterm dark/light réactifs (palette ANSI + coloration
  syntaxique) ; fonts.ready + remeasureFonts pour l'alignement des glyphes.
- status-tokens : tons sémantiques tokenisés ; balayage des ~340 couleurs
  Tailwind brutes vers les tokens sur tout components/* et views/*
  (exceptions assumées commentées).
- GroupSummary.color exploité : icône de groupe teintée + ColorSwatchPicker
  (lib/group-colors.ts) dans les modals de groupe.
- Polices via @fontsource-variable/{inter,jetbrains-mono} (offline).
2026-07-20 21:30:57 +02:00

54 lines
2.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div
class="group flex items-center gap-2 rounded px-2 py-0.5 text-xs"
:class="active ? 'bg-surface-2 text-fg' : 'text-fg-muted hover:bg-surface-2/60'"
>
<button
type="button"
class="flex min-w-0 flex-1 items-center gap-2 text-left"
:title="c.renamedFrom ? `${c.renamedFrom} → ${c.path}` : c.path"
@click="emit('select')"
>
<span class="w-3 shrink-0 text-center font-mono font-bold" :class="tone">{{ letter }}</span>
<span class="min-w-0 flex-1 truncate font-mono">{{ basename }}<span class="text-fg-subtle">{{ dir }}</span></span>
<span v-if="c.insertions" class="shrink-0 text-accent">+{{ c.insertions }}</span>
<span v-if="c.deletions" class="shrink-0 text-danger">−{{ c.deletions }}</span>
</button>
<span class="flex shrink-0 items-center gap-0.5 opacity-60 group-hover:opacity-100">
<slot />
</span>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import type { FileChange } from '@arboretum/shared';
const props = defineProps<{ c: FileChange; active: boolean; staged?: boolean }>();
const emit = defineEmits<{ select: [] }>();
const letter = computed(() => {
if (props.c.conflicted) return 'U';
if (props.c.untracked) return '?';
const x = props.staged
? props.c.indexStatus
: props.c.worktreeStatus !== '.' && props.c.worktreeStatus !== ' ' && props.c.worktreeStatus
? props.c.worktreeStatus
: props.c.indexStatus;
return (x || 'M').toUpperCase();
});
const tone = computed(() => {
if (props.c.conflicted) return 'text-danger';
if (props.c.untracked) return 'text-fg-muted';
return letter.value === 'A' ? 'text-accent' : letter.value === 'D' ? 'text-danger' : letter.value === 'R' ? 'text-info' : 'text-warn';
});
const basename = computed(() => {
const i = props.c.path.lastIndexOf('/');
return i >= 0 ? props.c.path.slice(i + 1) : props.c.path;
});
const dir = computed(() => {
const i = props.c.path.lastIndexOf('/');
return i >= 0 ? ` ${props.c.path.slice(0, i)}` : '';
});
</script>