Files
Mangarr/.claude/skills/ui-style/SKILL.md
ext.jeremy.guillot@maxicoffee.domains 78897eda4a
All checks were successful
Deploy / deploy (push) Successful in 2m47s
chore(claude): versionner les skills partagés dans le repo
Ajoute les exceptions .gitignore pour tracker .claude/skills/ tout en
continuant d'ignorer settings.local.json et projects/ (fichiers perso).
Inclut les skills task-workflow et ui-style.
2026-03-15 20:42:48 +01:00

7.0 KiB

name, description, allowed-tools
name description allowed-tools
ui-style Design system et harmonisation UI de Mangarr — layout de page canonique (Toolbar + flex + sections border-t), palette Tailwind, patterns composants (boutons, badges, upload, progression). Utiliser quand on crée ou modifie une page Vue ou un composant UI. Read, Grep, Glob

Design system Mangarr — Guide UI

Les pages de référence canoniques sont :

  • assets/vue/app/domain/manga/infrastructure/presentation/pages/NewImportPage.vue
  • assets/vue/app/domain/conversion/infrastructure/presentation/pages/ConversionPage.vue

En cas de doute, les lire pour vérifier le pattern en vigueur.


1. Layout de page canonique

<template>
  <div class="flex flex-col h-full">
    <Toolbar :config="toolbarConfig" />
    <div class="overflow-y-auto flex-1">
      <div class="px-6 py-8">
        <section class="border-t border-gray-200 dark:border-gray-700 pt-6">
          <h2 class="text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider mb-4">
            Titre section
          </h2>
          <!-- contenu -->
        </section>
        <section class="border-t border-gray-200 dark:border-gray-700 pt-6 mt-6">
          <!-- section suivante -->
        </section>
      </div>
    </div>
  </div>
</template>

Règles absolues :

  • flex flex-col h-full toujours à la racine du template
  • <Toolbar> toujours en premier enfant direct de la racine
  • overflow-y-auto flex-1 pour le contenu scrollable
  • px-6 py-8 comme wrapper interne — jamais container mx-auto
  • Chaque bloc logique = une <section> avec border-t border-gray-200 dark:border-gray-700
  • Jamais de <h1> volant dans le contenu — le titre de page va dans toolbarConfig.leftSection

2. Configuration Toolbar

import { computed } from 'vue';
import { SomeIcon } from '@heroicons/vue/24/outline';

const toolbarConfig = computed(() => ({
  leftSection: [
    { type: 'label', text: 'Titre de la page', class: 'text-sm font-medium' },
  ],
  rightSection: [
    {
      type: 'button',
      icon: SomeIcon,
      label: 'Action principale',
      onClick: handler,
      disabled: condition,
    },
    // Bouton conditionnel :
    ...(showAction ? [{
      type: 'button',
      icon: OtherIcon,
      label: 'Action contextuelle',
      onClick: otherHandler,
    }] : []),
  ],
}));
  • Icônes : Heroicons v24/outline (@heroicons/vue/24/outline)
  • Boutons toolbar visibles uniquement si pertinents — utiliser le spread conditionnel
  • rightSection peut être vide []

3. Headers de section

<!-- Header simple -->
<h2 class="text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider mb-4">
  Titre
</h2>

<!-- Header avec info contextuelle à droite -->
<div class="flex items-center justify-between mb-3">
  <h2 class="text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider">
    Titre
  </h2>
  <span class="text-xs text-gray-500 dark:text-gray-400">info contextuelle</span>
</div>

4. Palette de couleurs

Usage Classes Tailwind
Primaire (action principale) bg-green-600 hover:bg-green-700
Secondaire bg-blue-600 hover:bg-blue-700
Danger bg-red-600 hover:bg-red-700
Désactivé disabled:bg-gray-400 disabled:cursor-not-allowed
Texte principal text-gray-900 dark:text-gray-100
Texte secondaire text-gray-600 dark:text-gray-300
Texte subtil text-gray-500 dark:text-gray-400
Étiquette section text-gray-400 dark:text-gray-500
Fond carte / panel bg-white dark:bg-gray-800
Bordure border-gray-200 dark:border-gray-700
Séparateur de liste divide-y divide-gray-100 dark:divide-gray-700/50

5. Boutons

<!-- Bouton action principale (submit, lancer, confirmer) -->
<button
  class="bg-green-600 hover:bg-green-700 disabled:bg-gray-400 disabled:cursor-not-allowed text-white px-4 py-2 rounded-md font-medium transition-colors"
  :disabled="condition"
>
  Label
</button>

<!-- Bouton ghost / discret -->
<button class="text-sm text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors">
  Label
</button>

6. Barre de progression

<div class="bg-gray-200 dark:bg-gray-700 h-1.5 mb-4">
  <div
    class="bg-green-600 h-1.5 transition-all duration-300"
    :style="{ width: progress + '%' }"
  />
</div>

Important : toujours bg-green-600, jamais bg-blue-600 pour les barres de progression.


7. Liste avec séparateurs

<div class="divide-y divide-gray-100 dark:divide-gray-700/50">
  <div
    v-for="item in items"
    :key="item.id"
    class="flex items-center justify-between py-3"
  >
    <!-- contenu de l'item -->
  </div>
</div>

8. Zone de drop / upload de fichier

<div
  class="border-2 border-dashed rounded-lg p-8 text-center transition-colors"
  :class="isDragging
    ? 'border-green-500 bg-green-50 dark:bg-green-900/10'
    : 'border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600'"
  @dragover.prevent="isDragging = true"
  @dragleave="isDragging = false"
  @drop.prevent="handleDrop"
>
  <SomeIcon class="mx-auto h-8 w-8 text-gray-400 mb-3" />
  <p class="text-sm text-gray-600 dark:text-gray-300">
    Message principal
  </p>
  <p class="text-xs text-gray-400 dark:text-gray-500 mt-1">
    Précision format/taille
  </p>
</div>

9. Pages non conformes à corriger

Les pages suivantes dévient encore du pattern canonique :

Page Chemin relatif Déviations principales
HomePage.vue domain/manga/.../pages/ Pas de px-6 py-8, pas de sections border-t
AddManga.vue domain/manga/.../pages/ Pas de Toolbar, pas de flex flex-col h-full
ActivityPage.vue domain/activity/.../pages/ Pas de flex flex-col, pas de Toolbar intégré
UserPreferencesPage.vue domain/setting/.../pages/ h1 volant, pas de Toolbar
ScrapperConfigurations.vue domain/setting/.../pages/ h1 volant, container mx-auto
ScrapperEdit.vue domain/setting/.../pages/ container mx-auto au lieu de px-6 py-8
MangaDetails.vue domain/manga/.../pages/ Layout spécial (cover + chapitres), à traiter séparément
ChapterPage.vue domain/reader/.../pages/ Layout lecteur spécialisé — exception justifiée, ne pas modifier

10. Checklist avant de livrer une page

  • Racine : flex flex-col h-full
  • Premier enfant : <Toolbar :config="toolbarConfig" />
  • Contenu scrollable : overflow-y-auto flex-1
  • Wrapper interne : px-6 py-8 (jamais container mx-auto)
  • Blocs logiques : <section class="border-t border-gray-200 dark:border-gray-700 pt-6">
  • Titre de page dans toolbarConfig.leftSection, pas de <h1> dans le contenu
  • Headers de section : classes text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase tracking-wider
  • Barres de progression : bg-green-600 (pas bg-blue-600)
  • Dark mode : chaque couleur a sa variante dark: