npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arche-mc2/vue-ui-lib

v1.2.48

Published

Bibliothèque de composants UI Vue 3 + TypeScript.

Downloads

2,464

Readme

@arche-mc2/vue-ui-lib

Bibliothèque de composants UI Vue 3 + TypeScript.

Stack : Vue 3 · TypeScript · Vite · SCSS · Storybook 9


Installation

yarn add @arche-mc2/vue-ui-lib
# ou
npm install @arche-mc2/vue-ui-lib

Setup

Dans main.ts, importer les styles et initialiser le système de toast :

import { createApp } from 'vue'
import '@arche-mc2/vue-ui-lib/dist/vue-ui-lib.css'
import { provideToast } from '@arche-mc2/vue-ui-lib'
import App from './App.vue'

const app = createApp(App)
provideToast(app)  // requis pour les toasts
app.mount('#app')

Placer <ToastBase /> une seule fois dans App.vue :

<template>
  <RouterView />
  <ToastBase />
</template>

Utilisation

import { ButtonBase, InputBase, SelectBase } from '@arche-mc2/vue-ui-lib'
import type { Option, ButtonTypes, IconName } from '@arche-mc2/vue-ui-lib'

Composants disponibles (28)

| Composant | Description | |-----------|-------------| | ButtonBase | Bouton avec variantes, icône, loader | | InputBase | Input texte/date/password/search avec label flottant | | SelectBase | Dropdown mono/multi-sélection | | CheckboxBase | Case à cocher avec état indéterminé | | RadioBase | Bouton radio | | ToggleBase | Interrupteur on/off | | ToggleAdvanced | Interrupteur 2 boutons gauche/droite | | SegmentedButton | Bouton 3 positions (gauche/centre/droite) | | ModalBase | Modale avec titre et overlay | | ToastBase | Notifications (système inject/provide) | | TooltipBase | Tooltip au survol | | FlyoutMenu | Menu contextuel positionné | | SideMenu | Menu latéral hiérarchique | | TabBar | Barre d'onglets | | DataGrid | Grille de données avancée | | WidgetBase | Carte conteneur avec slots | | CalendarBase | Calendrier (FullCalendar) | | DatePicker | Sélecteur de date | | SvgIcon | Icône SVG (532 icônes) | | LoaderBase | Indicateur de chargement | | TagBase | Badge coloré | | ListWithSearch | Liste filtrée avec recherche | | SelectionGroup | Tags de sélection avec débordement | | AvatarBase | Avatar photo ou initiales en fallback | | HistoryItem | Ligne d'historique expandable (badge, avatar, diff) | | DiffValue | Rendu d'un diff ancienne → nouvelle valeur | | HistoryBadge | Badge de type d'action (modification/création/suppression) | | HistoryFilter | Bouton de filtre d'historique |


API des composants

ButtonBase

Bouton avec variantes de style, icône optionnelle et état de chargement.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | type | ButtonTypes | 'primary' | Variante visuelle | | iconName | IconName | — | Icône à gauche du texte | | loading | boolean | — | Affiche un loader, remplace le contenu | | disabled | boolean | — | Désactive le bouton | | active | boolean | — | État actif (classe CSS) | | id | string | — | Attribut id HTML | | inert | boolean | — | Attribut inert HTML |

Slots : default (texte/contenu du bouton)

ButtonTypes : 'primary' 'primary-pink' 'secondary' 'secondary-pink' 'action1''action7'

<ButtonBase type="primary" @click="save">Enregistrer</ButtonBase>
<ButtonBase type="secondary" icon-name="plus" :loading="isSaving">Ajouter</ButtonBase>
<ButtonBase type="action1" :disabled="true">Désactivé</ButtonBase>

InputBase

Champ de saisie avancé : texte, nombre, email, password, recherche, tel, url, date (avec masque dd/mm/yyyy et datepicker intégré), suggestions autocomplete.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | string \| number | — | Valeur (v-model) | | label | string | — | Label flottant | | type | 'text'\|'number'\|'time'\|'search'\|'email'\|'password'\|'tel'\|'url'\|'date' | 'text' | Type d'input | | iconName | IconName | — | Icône (gauche sans label, droite avec label) | | clearable | boolean | — | Bouton de vidage | | passwordControl | boolean | — | Bouton afficher/masquer mdp | | disabled | boolean | — | Désactivé | | error | boolean | — | État d'erreur (bordure rouge) | | errorMessage | string | — | Message d'erreur affiché sous le champ | | required | boolean | — | Affiche badge "Requis" | | placeholder | string | — | Placeholder | | suggestions | Option[] | — | Liste de suggestions autocomplete |

Événements : update:modelValue(value: string | number)

<InputBase v-model="name" label="Nom" />
<InputBase v-model="search" type="search" icon-name="search" clearable placeholder="Rechercher..." />
<InputBase v-model="password" type="password" label="Mot de passe" password-control />
<InputBase v-model="birthdate" type="date" label="Date de naissance" />
<InputBase v-model="email" type="email" label="Email" :error="hasError" error-message="Email invalide" required />
<InputBase v-model="city" label="Ville" :suggestions="citySuggestions" />

Le type date intègre un masque dd/mm/yyyy et un DatePicker popup automatique.


SelectBase

Liste déroulante mono ou multi-sélection avec recherche, s'ouvre via Teleport.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | Option[] | — | Sélection courante (v-model, toujours un tableau) | | options | Option[] | requis | Liste des options | | label | string | — | Label flottant | | placeholder | string | — | Texte placeholder | | multiple | boolean | — | Multi-sélection | | searchable | boolean | — | Activer la recherche | | clearable | boolean | true | Bouton de suppression sur les tags | | disabled | boolean | — | Désactivé |

Événements : update:modelValue(value: Option[])

const civility = ref<Option[]>([])
const options = [
  { value: 'mr', label: 'Monsieur' },
  { value: 'mme', label: 'Madame' },
]
<SelectBase v-model="civility" :options="options" label="Civilité" placeholder="Choisir..." />
<SelectBase v-model="tags" :options="tagOptions" label="Tags" multiple searchable />

CheckboxBase

Case à cocher avec label optionnel, état indéterminé et thème personnalisable.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | boolean | false | Coché ou non (v-model) | | label | string | — | Texte affiché à droite | | icon | IconName | — | Icône supplémentaire | | iconStyle | {height?,width?} | — | Taille de l'icône | | theme | {--amc2-checkbox-color?, --amc2-checkbox-disabled-color?, --amc2-checkmark-color?} | — | Couleurs custom | | indeterminate | boolean | — | État partiel (icône minus) | | disabled | boolean | — | Désactivé | | className | string | — | Classe CSS additionnelle |

Événements natifs : change

<CheckboxBase v-model="accepted" label="J'accepte les conditions" />
<CheckboxBase v-model="allSelected" :indeterminate="isPartial" />

RadioBase

Bouton radio. Toujours utilisé avec v-model partagé + prop value distincte par option.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | any | — | Valeur courante du groupe (v-model) | | value | any | requis | Valeur de cette option | | label | string | — | Texte affiché | | icon | IconName | — | Icône | | theme | {--amc2-radio-color?, --amc2-radio-disabled-color?, --amc2-radio-point-color?, --amc2-radio-point-disabled-color?} | — | Couleurs custom | | disabled | boolean | — | Désactivé | | className | string | — | Classe CSS additionnelle |

Événements : update:modelValue(value: any)

<RadioBase v-model="gender" value="male" label="Homme" />
<RadioBase v-model="gender" value="female" label="Femme" />

ToggleBase

Interrupteur on/off simple avec label et icône optionnels.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | boolean | — | État (v-model) | | label | string | — | Texte affiché | | icon | string | — | Nom d'icône | | theme | ToggleTheme | — | CSS custom properties de couleurs | | disabled | boolean | — | Désactivé |

Événements : update:modelValue(value: boolean)

<ToggleBase v-model="notifications" label="Notifications" />
<ToggleBase v-model="darkMode" :disabled="isPremium === false" />

ToggleAdvanced

Interrupteur à deux boutons (gauche/droite) avec labels et icônes.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | boolean | — | true = gauche actif, false = droite actif (v-model) | | labelLeft | string | — | Texte bouton gauche | | iconLeft | IconName | — | Icône bouton gauche | | labelRight | string | — | Texte bouton droit | | iconRight | IconName | — | Icône bouton droit | | theme | ToggleTheme | — | Couleurs custom | | disabled | boolean | — | Désactivé |

Événements : update:modelValue(value: boolean)

<ToggleAdvanced v-model="isListView" label-left="Liste" label-right="Grille"
  icon-left="list" icon-right="grid" />

SegmentedButton

Bouton segmenté 3 positions (gauche/centre/droite) avec tooltips. Conçu pour le tri.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | 'left'\|'center'\|'right' | 'center' | Position active (v-model) | | labelLeft | string | 'Croissant' | — | | iconLeft | IconName | 'arrow-down-a-z' | — | | toolTipLabelLeft | string | — | Tooltip gauche | | labelCenter | string | 'Aucun tri' | — | | iconCenter | IconName | — | — | | toolTipLabelCenter | string | — | Tooltip centre | | labelRight | string | 'Décroissant' | — | | iconRight | IconName | 'arrow-down-z-a' | — | | toolTipLabelRight | string | — | Tooltip droit | | disabled | boolean | — | — | | theme | SegmentedButtonTheme | — | CSS vars de couleur |

Événements : update:modelValue(value: 'left' | 'center' | 'right')

<SegmentedButton v-model="sortOrder" label-left="A→Z" label-right="Z→A" />

ModalBase

Modale avec titre, fond sombre, croix de fermeture. Supporte les modales empilées.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | visible | boolean | requis | Affichage | | title | string | requis | Titre de la modale | | additionnal | boolean | — | Modale secondaire (style décalé) |

Événements : close

Slots : default (contenu de la modale)

<ModalBase :visible="showModal" title="Confirmer la suppression" @close="showModal = false">
  <p>Cette action est irréversible.</p>
  <ButtonBase type="secondary" @click="showModal = false">Annuler</ButtonBase>
  <ButtonBase type="primary" @click="confirmDelete">Supprimer</ButtonBase>
</ModalBase>

ToastBase + useToast

Système de notifications. Nécessite provideToast(app) dans main.ts. Placer <ToastBase /> une seule fois dans App.vue.

Setup main.ts : provideToast(app) (voir section Setup)

Utilisation :

import { useToast } from '@arche-mc2/vue-ui-lib'
const toast = useToast()
toast.show('Enregistré avec succès', 'success')        // durée défaut 3000ms
toast.show('Email invalide', 'error', 5000)
toast.show('Mise à jour disponible', 'info')
toast.show('Attention, données incomplètes', 'warning')

Intents disponibles : 'success' | 'warning' | 'error' | 'info'


TooltipBase

Tooltip au survol, positionnée automatiquement, avec flèche.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | position | Position | 'bottom' | Côté d'apparition | | className | string | — | Classe CSS sur le tooltip | | style | CSSProperties | — | Styles inline | | removeDelay | number | — | Délai de disparition en ms (utile si contenu cliquable) |

Slots : default (élément déclencheur), content (contenu du tooltip)

<TooltipBase position="top">
  <ButtonBase>Supprimer</ButtonBase>
  <template #content>Cette action est irréversible</template>
</TooltipBase>

FlyoutMenu

Menu contextuel positionné, déclenché au clic. Peut afficher une liste d'items ou du contenu libre.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | items | FlyoutMenuItem[] | — | Liste de {label, onClick?} (mode liste simple) | | position | Position | 'bottom' | Position du menu | | displayEl | HTMLElement \| null | — | Conteneur scrollable (pour repositionnement) | | autoClose | boolean | true | Fermeture automatique après clic item |

Événements : close

Slots : default (déclencheur), content (contenu libre, si pas de prop items)

<!-- Mode liste -->
<FlyoutMenu :items="[{ label: 'Éditer', onClick: edit }, { label: 'Supprimer', onClick: del }]">
  <ButtonBase>Actions</ButtonBase>
</FlyoutMenu>

<!-- Mode contenu libre -->
<FlyoutMenu position="bottom-left">
  <SvgIcon icon-name="settings" />
  <template #content>
    <div>Contenu personnalisé</div>
  </template>
</FlyoutMenu>

SideMenu

Menu latéral de navigation avec items hiérarchiques (2 niveaux), icônes, et sélection active.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | items | MenuItem[] | requis | Arbre de navigation | | idSelected | number | — | ID de l'item actif au montage |

La navigation appelle item.action?.() à la sélection. Les sous-menus s'ouvrent en accordéon.

const menuItems: MenuItem[] = [
  { id: 1, label: 'Tableau de bord', icon: 'home', action: () => router.push('/') },
  {
    id: 2, label: 'Gestion', icon: 'users',
    children: [
      { id: 3, label: 'Clients', action: () => router.push('/clients') },
      { id: 4, label: 'Contrats', action: () => router.push('/contracts') },
    ]
  },
]
<SideMenu :items="menuItems" :id-selected="currentId" />

TabBar

Barre d'onglets simple avec liste de labels.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | listItems | string[] | requis | Labels des onglets | | listType | string | requis | Onglet actif courant |

Événements : change(selectedItem: string)

const tabs = ['Informations', 'Contrats', 'Documents']
const activeTab = ref('Informations')
<TabBar :list-items="tabs" :list-type="activeTab" @change="activeTab = $event" />

DataGrid

Grille de données avec colonnes configurables, tri, filtre, sélection par checkbox, scroll infini, menu d'actions par ligne, et colonne de paramétrage de visibilité des colonnes.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | headers | DatagridHeader[] | requis | Définition des colonnes | | items | any[] | requis | Données. Chaque item doit avoir id: number, et peut avoir isSelected: boolean, actions: FlyoutMenuItem[], onClick_<key>: () => void | | hasMore | boolean | requis | Indique s'il y a plus de données à charger | | selection | boolean | false | Activer colonne de checkboxes | | allCheckState | {isChecked: boolean, partially: boolean} | {false,false} | État checkbox "tout cocher" | | displaySettingsHeader | boolean | true | Afficher la colonne de paramétrage | | displaySettings | boolean | true | Afficher le menu d'actions par ligne | | modalFilter | (header: DatagridHeader) => void | — | Callback clic filtre | | dataSort | (header: DatagridHeader) => void | — | Callback clic tri |

Événements :

  • loadMore — déclenché au scroll infini (et au montage)
  • updateCheckItem(id: number, isChecked: boolean) — checkbox ligne
  • updateCheckAll(isChecked: boolean) — checkbox header

Expose : resetScroll(), checkLoadMore()

Contenu d'un item :

  • item[header.key] → valeur texte, nombre, date, ou tableau (formaté automatiquement)
  • item[header.key] = { render: Component } → rendu d'un composant Vue dans la cellule
  • item['onClick_<key>'] → rend la cellule cliquable (lien <a>)
  • item.actions → tableau FlyoutMenuItem[] pour le menu d'actions rapides
  • item.isSelected → état de sélection checkbox
import { DataGrid } from '@arche-mc2/vue-ui-lib'
import type { DatagridHeader, FlyoutMenuItem } from '@arche-mc2/vue-ui-lib'

const headers = ref<DatagridHeader[]>([
  {
    key: 'name', label: 'Nom', dataType: 'string', sortable: true,
    visibility: { isShown: true, isDisabled: false, update: (v) => { headers.value[0].visibility.isShown = v } }
  },
  {
    key: 'date', label: 'Date', dataType: 'date', sortable: true,
    visibility: { isShown: true, isDisabled: false, update: (v) => { headers.value[1].visibility.isShown = v } }
  },
])

const items = ref([
  { id: 1, name: 'Alice', date: '01/01/2024', isSelected: false,
    actions: [{ label: 'Voir', onClick: () => openDetail(1) }] },
])

const gridRef = ref()
const page = ref(0)

const loadMore = async () => {
  const data = await fetchPage(page.value++)
  items.value = [...items.value, ...data]
  hasMore.value = data.length === PAGE_SIZE
}
<DataGrid
  ref="gridRef"
  :headers="headers"
  :items="items"
  :has-more="hasMore"
  selection
  @load-more="loadMore"
  @update-check-item="(id, checked) => toggleItem(id, checked)"
  @update-check-all="(checked) => toggleAll(checked)"
/>

WidgetBase

Conteneur carte avec slots header/body/footer, état de chargement, et état vide automatique.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | width | string | '50%' | Largeur CSS | | height | string | '180px' | Hauteur CSS | | color | string | — | Couleur de fond | | isLoading | boolean | — | Affiche un loader à la place du body |

Slots : header, body, footer Si body est vide, affiche automatiquement une icône "Aucune donnée".

<WidgetBase width="100%" height="300px" :is-loading="loading">
  <template #header>
    <h3>Statistiques du mois</h3>
  </template>
  <template #body>
    <p>42 contrats signés</p>
  </template>
  <template #footer>
    <ButtonBase type="secondary">Voir le détail</ButtonBase>
  </template>
</WidgetBase>

CalendarBase

Calendrier plein-écran (FullCalendar) avec vues jour/semaine/mois, événements et sélection de plage.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | events | CalendarEvent[] | — | Événements à afficher | | initialView | 'day'\|'week'\|'month' | 'month' | Vue initiale | | btnToday | boolean | — | Afficher bouton "Aujourd'hui" | | btnViewOption | boolean | — | Afficher les boutons de changement de vue |

Événements :

  • onSelectDate(range: CalendarRange) — sélection d'une plage (clic + drag)
  • onClickEvent(event: CalendarEvent) — clic sur un événement
  • onChangeView(range: CalendarRange) — changement de période/vue
const events: CalendarEvent[] = [
  { id: '1', title: 'Réunion', start: '2024-04-15T09:00:00', end: '2024-04-15T10:00:00' }
]
<CalendarBase
  :events="events"
  initial-view="week"
  btn-today
  btn-view-option
  @on-select-date="range => createEvent(range)"
  @on-click-event="event => openEvent(event)"
/>

DatePicker

Sélecteur de date avec navigation mois/année. Généralement intégré via InputBase (type="date"). Peut aussi être utilisé seul.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | Date | — | Date sélectionnée (v-model) | | min | Date | — | Date minimale | | max | Date | — | Date maximale |

Événements : update:modelValue(date: Date)

<!-- Usage recommandé via InputBase -->
<InputBase v-model="birthdate" type="date" label="Date de naissance" />

<!-- Usage direct -->
<DatePicker v-model="selectedDate" :min="minDate" :max="maxDate" />

SvgIcon

Icône SVG depuis le sprite interne. 532 icônes disponibles.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | iconName | IconName | requis | Nom de l'icône | | color | string | '#2C2274' | Couleur primaire (fill) | | colorSecondary | string | 'transparent' | Couleur secondaire | | colorHover | string | — | Couleur au survol | | colorSecondaryHover | string | — | Couleur secondaire au survol | | height | string | '20' | Hauteur en px | | width | string | '20' | Largeur en px | | accessibilityTitle | string | — | <title> SVG pour accessibilité | | classIcon | string | — | Classe CSS | | id | string | — | Attribut id |

<SvgIcon icon-name="user" color="#5B4DBE" width="24" height="24" />
<SvgIcon icon-name="check" color="#55BDBE" />

Pour obtenir la liste complète des icônes :

import { iconNames } from '@arche-mc2/vue-ui-lib'
// iconNames est un tableau de 532 strings

LoaderBase

Gif de chargement animé.

Props : | Prop | Type | Défaut | |------|------|--------| | size | number | 50 |

<LoaderBase :size="30" />

TagBase

Badge coloré avec label.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | label | string | — | Texte du badge | | backgroundColor | 'blue'\|'green'\|'primary'\|'secondary' | requis | Couleur de fond |

<TagBase label="Actif" background-color="green" />
<TagBase background-color="secondary" />

ListWithSearch

Liste d'options avec recherche et sélection mono/multi. Composant interne de SelectBase, mais peut être utilisé seul.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | Option[] | requis | Sélection courante (v-model) | | options | Option[] | requis | Options disponibles | | multiple | boolean | — | Multi-sélection | | searchable | boolean | — | Activer la recherche | | stickyHeader | boolean | true | Header (search + tout sélectionner) sticky | | emptyMessage | string | 'Aucune valeur' | Message si liste vide | | disabled | boolean | — | — |

Événements : update:modelValue(value: Option[])


SelectionGroup

Affichage compact des valeurs sélectionnées sous forme de tags, avec gestion du débordement (tooltip "+N").

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | modelValue | {value: any, label: string}[] | requis | Items sélectionnés (v-model) | | clearable | boolean | — | Bouton de suppression par item | | disabled | boolean | — | — | | placeholder | string | — | Texte si vide | | tooltipPosition | Position | — | Position du tooltip "+N" | | tooltipStyle | CSSProperties | — | Style custom du tooltip |

Événements : update:modelValue, clearAll(previous: Option[]), clear(option: Option)


AvatarBase

Avatar utilisateur : photo, ou initiales en fallback si pas d'image.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | src | string | — | URL de l'image ; si absent, affiche les initiales | | alt | string | '' | Texte alternatif de l'image | | initials | string | '?' | 1 ou 2 caractères affichés en fallback | | size | AvatarSize | 'md' | 'xs' 'sm' 'md' 'lg' 'xl' | | shape | AvatarShape | 'circle' | 'circle' 'square' | | color | AvatarColor | 'primary' | 'primary' 'secondary' 'green' 'blue' 'grey' |

<AvatarBase initials="GV" size="md" color="primary" />
<AvatarBase src="/photos/user.jpg" alt="Jean Dupont" size="lg" />
<AvatarBase initials="AB" shape="square" color="secondary" />

HistoryItem

Ligne d'historique d'une fiche. Affiche une action (Modification, Création ou Suppression) avec badge de type, horodatage et auteur. Cliquable : dépliée, elle révèle un panneau détaillant les champs concernés. Compose HistoryBadge, AvatarBase et DiffValue. Le rendu des valeurs dépend du type : modification (ancienne barrée → nouvelle ; ancienne vide = ajout, rendu nouvelle seule ; nouvelle vide = vidage, rendu suppression), création (nouvelle seule), suppression (ancienne barrée → « Supprimé »).

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | type | HistoryItemType | 'modification' | Type d'action ; pilote le badge et le rendu des valeurs | | open | boolean | false | Panneau de détail déplié (v-model:open) | | date | string | '' | Horodatage affiché | | author | string | '' | Nom de l'auteur | | initials | string | '?' | Initiales de l'auteur (avatar) | | fields | HistoryItemField[] | [] | Champs détaillés affichés quand open |

Le bloc avatar + nom est masqué quand aucun auteur n'est connu (author vide et initials vide ou '?') : le chevron reste aligné à droite. Utile pour les actions automatiques ou les logs sans utilisateur.

Événements : update:open(value: boolean) · toggle(value: boolean)

<HistoryItem
  type="modification"
  v-model:open="open"
  date="02/05/2026 14:08"
  author="Gilles Vasse"
  initials="GV"
  :fields="[{ label: 'Prénom', oldValue: 'Jean', newValue: 'Jean-Pierre' }]"
/>

DiffValue

Rendu d'un diff de valeur selon le type d'action : modification (ancienne barrée → nouvelle), création (nouvelle seule), suppression (ancienne barrée → « Supprimé »). Deux cas particuliers de modification, symétriques : oldValue vide = ajout d'information, rendu comme une création (nouvelle valeur seule, sans pastille barrée vide ni flèche) ; newValue vide = vidage d'information, rendu comme une suppression (ancienne barrée → « Supprimé », sans pastille verte vide). Utilisé par HistoryItem, utilisable seul.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | kind | DiffValueKind | 'modification' | Pilote le rendu (couple, nouvelle seule, suppression) | | oldValue | string | '' | Ancienne valeur (modification, suppression). Vide sur une modification = ajout : nouvelle valeur seule | | newValue | string | '' | Nouvelle valeur (modification, création). Vide sur une modification = vidage : rendu « suppression » |

<DiffValue kind="modification" old-value="Jean" new-value="Jean-Pierre" />
<DiffValue kind="modification" new-value="[email protected]" /> <!-- ajout : rendu « création » -->
<DiffValue kind="modification" old-value="06 12 34 56 78" /> <!-- vidage : rendu « suppression » -->
<DiffValue kind="creation" new-value="[email protected]" />
<DiffValue kind="suppression" old-value="06 12 34 56 78" />

HistoryBadge

Badge coloré du type d'action d'historique (libellé automatique : Modification / Création / Suppression).

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | type | HistoryBadgeType | requis | 'modification' 'creation' 'suppression' |

<HistoryBadge type="creation" />

HistoryFilter

Bouton de filtre d'historique (libellé automatique : Tout / Modification / Création / Suppression). Exclusif au sein d'un groupe : l'état actif est porté par le parent.

Props : | Prop | Type | Défaut | Description | |------|------|--------|-------------| | type | HistoryFilterType | requis | 'all' 'modification' 'creation' 'suppression' | | active | boolean | — | État sélectionné (piloté par le parent) |

Événements : click

<HistoryFilter type="all" :active="filter === 'all'" @click="filter = 'all'" />

Types TypeScript exportés

import type {
  ButtonTypes, IconName, Option, Intent, Position,
  MenuItem, Header, DatagridHeader,
  FlyoutMenuItem, ToggleTheme,
  CalendarEvent, CalendarRange,
  Toast, DayInfo, WeekInfo,
  AvatarSize, AvatarShape, AvatarColor,
  HistoryItemType, HistoryItemField,
  DiffValueKind, HistoryBadgeType, HistoryFilterType
} from '@arche-mc2/vue-ui-lib'

Détail des principaux types :

// Variantes de bouton
type ButtonTypes = 'primary' | 'primary-pink' | 'secondary' | 'secondary-pink'
  | 'action1' | 'action2' | 'action3' | 'action4' | 'action5' | 'action6' | 'action7'

// Position tooltip/flyout
type Position = 'top' | 'bottom' | 'left' | 'right' | 'bottom-left'

// Option pour Select, ListWithSearch, SelectionGroup
type Option = { value: string; label: string; id?: number }

// Intent pour Toast
type Intent = 'success' | 'warning' | 'error' | 'info'

// Icône SVG (union de 532 noms)
type IconName = string  // voir iconNames[] pour la liste complète

// Interface MenuItem (SideMenu)
interface MenuItem {
  id: number; label: string; icon?: IconName
  action?: () => void; children?: MenuItem[]
}

// Interface Header (DataGrid)
interface Header {
  key: string; label: string; style?: CSSProperties
  sortable?: boolean; filtered?: boolean; sortOrder?: 'ASC' | 'DESC'
  dataType: 'string' | 'number' | 'date' | 'array'
}
interface DatagridHeader extends Header {
  visibility: { isShown: boolean; isDisabled: boolean; update: (value: boolean) => void }
  fixedWidth?: boolean
}

// Thème ToggleBase / ToggleAdvanced (CSS custom properties)
interface ToggleTheme {
  'amc2-toggle-on-color'?: string
  'amc2-toggle-off-color'?: string
  'amc2-toggle-on-disabled-color'?: string
  'amc2-toggle-off-disabled-color'?: string
  'amc2-slider-on-color'?: string
  'amc2-slider-off-color'?: string
  'amc2-slider-on-disabled-color'?: string
  'amc2-slider-off-disabled-color'?: string
}

// Événements CalendarBase
interface CalendarRange { start: string; end: string }
interface CalendarEvent extends CalendarRange { id: string; title: string }

// AvatarBase
type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
type AvatarShape = 'circle' | 'square'
type AvatarColor = 'primary' | 'secondary' | 'green' | 'blue' | 'grey'

// Historique (HistoryItem / DiffValue / HistoryBadge / HistoryFilter)
type HistoryItemType = 'modification' | 'creation' | 'suppression'
interface HistoryItemField { label: string; oldValue?: string; newValue?: string }
type DiffValueKind = 'modification' | 'creation' | 'suppression'
type HistoryBadgeType = 'modification' | 'creation' | 'suppression'
type HistoryFilterType = 'all' | 'modification' | 'creation' | 'suppression'

Theming — CSS Custom Properties

Les composants avec prop theme acceptent des CSS custom properties :

<!-- CheckboxBase -->
<CheckboxBase :theme="{ '--amc2-checkbox-color': '#5B4DBE' }" v-model="checked" />

<!-- RadioBase -->
<RadioBase :theme="{ '--amc2-radio-color': '#EB5A77' }" v-model="val" :value="1" />

<!-- ToggleBase / ToggleAdvanced -->
<ToggleBase :theme="{
  'amc2-toggle-on-color': '#5B4DBE',
  'amc2-toggle-off-color': '#CCC',
  'amc2-slider-on-color': '#FFF',
}" v-model="on" />

Développement

yarn storybook          # Démo interactive http://localhost:6006
yarn build              # Build bibliothèque → dist/
yarn build-storybook    # Build Storybook statique

Voir storybook-docs.md pour le guide complet de contribution et de publication.