# Blueprint Modular — Agent Context File # Version React (@blueprint-modular/core, npm) : 0.3.10 # Version Python (blueprint-modular, PyPI) : 0.1.54 # Date : 2026-08-07 # URL canonique : https://blueprint-modular.com/llms.txt # # Ce fichier est la référence machine de @blueprint-modular/core. # Il est généré automatiquement depuis les sources TypeScript. # À injecter dans le contexte de génération de code BPM. ## IMPORT OBLIGATOIRE import { bpm } from '@blueprint-modular/core' import '@blueprint-modular/core/dist/style.css' INTERDIT : import { bpm.modal } ou tout autre destructuring ## RÈGLES CRITIQUES - 'use client' — en première ligne, une seule fois - Modal — {isOpen && bpm.modal({ isOpen:true, onClose, title, children })} — TOUJOURS dans return() - Graphiques — bpm.plotlyChart UNIQUEMENT — jamais bpm.lineChart/barChart/areaChart - Métriques — bpm.metricRow({ children: <> {bpm.metric(...)} }) - Table — prop render dans columns (pas renderCell) — jamais JSX dans data[] - INTERDIT : renderCell — alias non supporté par Table.tsx ; utiliser render - Spinner — size 'small'|'medium'|'large' — jamais 'md'/'sm' - Toggle — prop value (booléen) — jamais checked - Text — style={{ fontWeight:600 }} — jamais prop weight - Routes — App Router UNIQUEMENT — jamais NextApiRequest/NextApiResponse - Fetch — res.ok vérifié avant JSON.parse - Data — Array.isArray(data) vérifié avant setItems(data) ## COMPOSANTS ## bpm.accordion @component bpm.accordion @description Liste de sections repliables (FAQ, procedures) avec une ou plusieurs ouvertes. Cycle de vie : le content des sections fermées reste MONTÉ (masqué en CSS) — l'état React est préservé à l'ouverture/fermeture (contrairement à bpm.tabs qui démonte). @example bpm.accordion({ sections: [{ title: "Livraison", content: "Delai 48h." }] }) @props - sections (AccordionSection[], optionnel) — title et content par section. Default: []. - allowMultiple (boolean, optionnel) — Plusieurs sections ouvertes. Default: false. - defaultOpenIds (string[], optionnel) — IDs sections ouvertes au montage. Default: []. - className (string, optionnel) — Classes CSS. @usage FAQ, procedures, aide par theme. @context PARENT: bpm.panel | bpm.tabs. ASSOCIATED: bpm.expander, bpm.markdown. FORBIDDEN: bpm.accordion imbriqué dans bpm.accordion. @semantic role=conteneur frame=section status=proposed @guidance Série de sections repliables homogènes (FAQ, groupes de paramètres) dont une seule importe à la fois. Associer : bpm.text, bpm.labelValue. Éviter : Vues alternatives de même rang (bpm.tabs) ou un seul bloc repliable (bpm.expander). ``` sections?: AccordionSection[] allowMultiple?: boolean defaultOpenIds?: string[] className?: string ``` ## bpm.activityFeed @component bpm.activityFeed @description Flux chronologique d'activités métier avec avatars initiaux, horodatages relatifs en français et état vide. @example bpm.activityFeed({ activities: [ { id: "1", actor: "Alice", action: "a validé", target: "le devis DV-001", timestamp: new Date().toISOString(), color: "success" }, ], maxItems: 10, onLoadMore: () => fetchMore(), compact: true, }) @param {object} props @param {ActivityItem[]} props.activities - Liste ordonnée ; chaque entrée : `{ id, actor, action, target, timestamp (ISO), icon?, color? }`. Obligatoire. @param {number} [props.maxItems] - Nombre max d'entrées visibles ; si la liste est plus longue, affiche « Charger plus » si onLoadMore est fourni. Optionnel. @param {function} [props.onLoadMore] - Callback du bouton « Charger plus ». Optionnel. @param {string} [props.emptyMessage="Aucune activité récente."] - Message lorsque activities est vide. Optionnel. @param {boolean} [props.compact=false] - Densité réduite (typo et padding plus petits). Optionnel. @param {string} [props.className=""] - Classes CSS sur le conteneur racine. Optionnel. @usage Historique CRM, journal d'audit léger, timeline d'événements sur une fiche. @context PARENT: bpm.panel | bpm.card | colonne dashboard. ASSOCIATED: bpm.timeline, bpm.statusTracker. @note SSR : composant client (`use client`) ; les libellés relatifs utilisent `Date.now()` — prévoir hydratation côté client pour éviter un écart serveur/client sur l'horodatage affiché. @forbidden Chronologie datée structurée — utiliser bpm.timeline @semantic role=affichage frame=event status=needs-curation @guidance Flux d'activité récent avec acteurs (avatars) et dates relatives : qui a fait quoi, quand. Associer : bpm.avatar, bpm.card, bpm.notificationCenter. Éviter : Historique d'audit d'une instance précise (bpm.timeline) ou notifications actionnables (bpm.notificationCenter). ``` activities*: ActivityItem[] — Liste des activités à afficher (ordre = ordre d'affichage). maxItems?: number — Limite d'affichage ; au-delà, le bouton « Charger plus » apparaît si onLoadMore est défini. onLoadMore?: () => void — Déclenché au clic sur « Charger plus » lorsque activities.length > maxItems. emptyMessage?: string — Texte centré affiché quand `activities` est vide. Défaut : « Aucune activité récente. » compact?: boolean — Mode compact : lignes plus serrées et avatars plus petits. Défaut : `false`. className?: string — Classes CSS additionnelles sur le conteneur `.bpm-activity-feed`. Défaut : `""`. ``` ## bpm.addressInput @component bpm.addressInput @description Champ de saisie d'adresse avec mode simple ou champs séparés (ligne 1, ligne 2, code postal, ville) et validation FR. @example bpm.addressInput({ mode: "fields", onChange: (addr) => console.log(addr) }) @param {object} props @param {"single"|"fields"} [props.mode="fields"] - Mode de saisie : ligne unique ou champs séparés. Optionnel. @param {object} [props.value] - Valeur initiale { line1, line2, city, postal }. Optionnel. @param {function} [props.onChange] - Callback appelé à chaque modification. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.form @associated bpm.input, bpm.autocomplete ``` mode?: AddressInputMode value?: { line1?: string line2?: string city?: string postal?: string onChange?: (v: { line1: string className?: string ``` ## bpm.aiQueryBar @component bpm.aiQueryBar @description Barre de requête IA permettant à l'utilisateur de poser des questions sur ses données avec suggestions et historique. @example bpm.aiQueryBar({ onQuery: async (q) => await fetchAnswer(q), suggestions: ["Quel est le CA ?"] }) @param {object} props @param {function} props.onQuery - Fonction asynchrone appelée lors de l'envoi d'une question. Obligatoire. @param {string} [props.placeholder="Posez une question sur vos données..."] - Texte d'aide dans le champ. Optionnel. @param {string[]} [props.suggestions=[]] - Liste de suggestions cliquables. Optionnel. @param {boolean} [props.loading] - Force l'état de chargement. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.chatInterface, bpm.assistantPanel ``` onQuery*: (question: string) => Promise placeholder?: string suggestions?: string[] loading?: boolean className?: string ``` ## bpm.alarmPanel @component bpm.alarmPanel @description Liste d’alarmes triée par gravité avec accusé de réception, suppression et clignotement pour les alertes critiques. @example bpm.alarmPanel({ alarms: [{ id: "1", title: "Température haute", severity: "critical", timestamp: Date.now() }] }) @param {object} props @param {Alarm[]} props.alarms - Liste des alarmes à afficher. Obligatoire. @param {function} [props.onAcknowledge] - Callback pour accuser réception d’une alarme. Optionnel. @param {function} [props.onDismiss] - Callback pour fermer une alarme. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.anomalyAlert, bpm.statusBox, bpm.panel ``` alarms*: Alarm[] onAcknowledge?: (id: string) => void onDismiss?: (id: string) => void className?: string ``` ## bpm.altairChart @component bpm.altairChart @description Conteneur pour graphiques Vega-Lite / Altair via spécification JSON ou iframe externe. @example bpm.altairChart({ iframeSrc: "/charts/ventes.html", height: 400 }) @param {object} props @param {object} [props.spec] - Spécification Vega-Lite / Altair en JSON. Optionnel. @param {string} [props.iframeSrc] - URL d'un fichier JSON ou vue compilée. Optionnel. @param {number|string} [props.width="100%"] - Largeur du graphique. Optionnel. @param {number|string} [props.height=400] - Hauteur du graphique. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.plotlyChart, bpm.lineChart, bpm.barChart @parent bpm.card, bpm.grid @forbidden Graphique simple — utiliser bpm.lineChart/barChart @semantic role=indicateur frame=kpi type=tendance,distribution direction=contextuel temporalite=contextuel status=proposed @guidance Visualisation déclarative Vega-Lite : exploration de specs complexes (facettes, encodages multiples). Associer : bpm.dataExplorer, bpm.metric. Éviter : Graphiques standards des apps générées (bpm.plotlyChart, imposé par les règles). ``` spec?: Record — Spécification Vega-Lite / Altair (JSON). À fournir côté app. iframeSrc?: string — Ou URL d'un fichier JSON ou d'une vue compilée. width?: number | string height?: number | string className?: string ``` ## bpm.anomalyAlert @component bpm.anomalyAlert @description Alerte d'anomalie affichant l'écart entre valeur attendue et mesurée avec niveau de gravité. @example bpm.anomalyAlert({ expected: "100 kg", actual: "85 kg", severity: "warning" }) @param {object} props @param {string} [props.title="Anomalie détectée"] - Titre de l'alerte. Optionnel. @param {string|number} props.expected - Valeur attendue. Obligatoire. @param {string|number} props.actual - Valeur mesurée. Obligatoire. @param {"info"|"warning"|"critical"} [props.severity="warning"] - Niveau de gravité. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {function} [props.onDismiss] - Callback pour fermer l'alerte. Optionnel. @param {TrajectoryPoint[]} [props.history] - Historique v(t) de la mesure pour la tendance. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : gravité auto-dérivée + verdict interpret révélé. Optionnel. @associated bpm.alarmPanel, bpm.statusBox, bpm.panel ``` title?: string expected*: string | number actual*: string | number severity?: AnomalySeverity — Niveau de gravité. Si omis et context fourni, dérivé automatiquement de interpret().severity. className?: string onDismiss?: () => void history?: TrajectoryPoint[] — Historique v(t) [{t, v}] de la mesure — révèle la tendance dans le verdict si context est fourni. context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : gravité auto-dérivée de la sévérité combinée (≥0.5 critical, >0.15 warning, sinon info) et verdict écart/tendance révélé. Additif : sans context, rendu inchangé. ``` ## bpm.approvalFlow @component bpm.approvalFlow @description Circuit de validation multi-étapes avec approbateurs, statuts et possibilité d'approuver/rejeter avec commentaire. @example bpm.approvalFlow({ steps: [{ id: "1", approver: "Marie", status: "approved" }, { id: "2", approver: "Jean", status: "pending" }] }) @param {object} props @param {ApprovalStep[]} props.steps - Liste des étapes d'approbation. Obligatoire. @param {function} [props.onApprove] - Callback appelé lors de l'approbation (stepId, comment). Optionnel. @param {function} [props.onReject] - Callback appelé lors du rejet (stepId, comment). Optionnel. @param {"horizontal"|"vertical"} [props.direction] - Direction d'affichage. Auto si non spécifié. Optionnel. @param {boolean} [props.showCommentInput=true] - Affiche le champ commentaire. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.stepper, bpm.timeline, bpm.workflow ``` steps*: ApprovalStep[] onApprove?: (stepId: string, comment?: string) => void onReject?: (stepId: string, comment?: string) => void direction?: "horizontal" | "vertical" showCommentInput?: boolean className?: string ``` ## bpm.areaChart @component bpm.areaChart @description Graphique en aire SVG simple pour visualiser une série temporelle ou une distribution. @example bpm.areaChart({ data: [{ x: 1, y: 10 }, { x: 2, y: 25 }], color: "var(--bpm-success)" }) @param {object} props @param {AreaChartDatum[]} props.data - Données du graphique [{x, y}]. Obligatoire. @param {number} [props.width=400] - Largeur du graphique. Optionnel. @param {number} [props.height=200] - Hauteur du graphique. Optionnel. @param {string} [props.color="var(--bpm-accent)"] - Couleur de l'aire. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : repère pointillé, couleur d'aire jugée, aria-label descriptif. Optionnel. @associated bpm.lineChart, bpm.barChart, bpm.plotlyChart @parent bpm.card, bpm.grid, bpm.tableauxDeBord @forbidden Comparaison de catégories — utiliser bpm.barChart @semantic role=indicateur frame=kpi type=tendance direction=contextuel temporalite=cumule status=proposed @guidance Évolution où le volume sous la courbe a du sens : cumul, empilement de contributions. Associer : bpm.metric, bpm.dateRangePicker. Éviter : Comparaison fine de niveaux entre séries (bpm.lineChart, les aires se masquent). Règle apps générées : bpm.plotlyChart. ``` data*: AreaChartDatum[] width?: number height?: number color?: string className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : la série (trajectoire v(t), t = x) est jugée par interpret — repère pointillé, couleur d'aire selon le verdict, aria-label. Additif : sans context, rendu inchangé. ``` ## bpm.assistantPanel @component bpm.assistantPanel @description Panneau d'assistant IA en drawer latéral avec questions pré-configurées et streaming de réponses. @example bpm.assistantPanel({ title: "Assistant Production", demo: true, demoAnswers: { "Question 1": "Réponse 1" } }) @param {object} props @param {Record} [props.demoAnswers] - Réponses statiques pour mode démo. Optionnel. @param {string} [props.title="Assistant Production"] - Titre du panneau. Optionnel. @param {boolean} [props.demo=false] - Mode démo sans appel API. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.chatInterface, bpm.aiQueryBar, bpm.drawer ``` demoAnswers?: Record — Si fourni, les chips affichent les réponses statiques (démo publique, pas d'appel API). title?: string — Titre du panneau demo?: boolean — Utilise demoAnswers si fourni ; le panneau s'ouvre toujours en volet droit (drawer). className?: string ``` ## bpm.audio @component bpm.audio @description Lecteur audio HTML5 avec contrôles natifs pour fichiers audio. @example bpm.audio({ src: "/audio/notification.mp3", controls: true }) @param {object} props @param {string} props.src - URL du fichier audio. Obligatoire. @param {boolean} [props.controls=true] - Affiche les contrôles de lecture. Optionnel. @param {boolean} [props.loop=false] - Active la lecture en boucle. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.video, bpm.filePreview @parent bpm.card, bpm.container, bpm.modal @forbidden aucun @semantic role=affichage frame=entity status=proposed @guidance Restituer un contenu audio attaché à une entité (enregistrement, message vocal). Associer : bpm.card, bpm.filePreview. Éviter : Fichier non audio (bpm.filePreview) ou vidéo (bpm.video). ``` src*: string controls?: boolean loop?: boolean className?: string ``` ## bpm.autocomplete @component bpm.autocomplete @description Champ de saisie avec autocomplétion filtrant les options selon la valeur entrée. @example bpm.autocomplete({ label: "Ville", options: [{ value: "paris", label: "Paris" }], onChange: (v) => console.log(v) }) @param {object} props @param {string} [props.label] - Libellé du champ. Optionnel. @param {string} [props.placeholder=""] - Texte d'aide. Optionnel. @param {string} [props.value=""] - Valeur courante. Optionnel. @param {function} [props.onChange] - Callback appelé à chaque modification (frappe ET sélection). Optionnel. @param {function} [props.onSelect] - Callback appelé UNIQUEMENT à la sélection d'une option, avec l'option entière. Optionnel. @param {string|null} [props.error=null] - Message d'erreur du champ : contour rouge + message sous le champ. Optionnel. @param {AutocompleteOption[]} props.options - Liste des options {value, label}. Obligatoire. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.form @associated bpm.select, bpm.input, bpm.combobox @forbidden Liste figée courte — utiliser bpm.selectbox @semantic role=saisie frame=entity status=proposed @guidance Trouver une valeur par la frappe dans un grand référentiel : champ relation (Field relation) ou longue énumération. Associer : bpm.chip, bpm.wizardForm, bpm.input. Éviter : Petites listes fermées (bpm.selectbox, bpm.radioGroup) ou texte libre sans référentiel (bpm.input). ``` label?: string placeholder?: string value?: string onChange?: (value: string) => void — Texte SAISI — appelé à chaque frappe ET à la sélection. Ne distingue pas les deux : voir `onSelect`. onSelect?: (option: AutocompleteOption) => void options*: AutocompleteOption[] error?: string | null — Message d'erreur du CHAMP : contour rouge + message sous le champ (role=alert, aria-invalid). Additif : défaut null. className?: string ``` ## bpm.avatar @component bpm.avatar @description Avatar utilisateur avec image ou initiales, mode sidebar optionnel (nom + sous-titre + déconnexion). @example bpm.avatar({ src: "/photo.jpg", size: "medium", name: "Jean Dupont", variant: "sidebar" }) @param {object} props @param {string} [props.src] - URL de l'image de l'avatar. Optionnel. @param {string} [props.alt] - Texte alternatif pour l'accessibilité. Optionnel. @param {string} [props.initials] - Initiales affichées si pas d'image. Optionnel. @param {"small"|"medium"|"large"} [props.size="medium"] - Taille de l'avatar. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {"default"|"sidebar"} [props.variant="default"] - Mode d'affichage. Optionnel. @param {string} [props.name] - Nom affiché (variant sidebar). Optionnel. @param {string} [props.subtitle] - Sous-titre sous le nom (variant sidebar). Optionnel. @param {function} [props.onLogout] - Callback déconnexion (variant sidebar). Optionnel. @param {string} [props.logoutLabel="Se déconnecter"] - Libellé du bouton déconnexion. Optionnel. @param {boolean} [props.editable=false] - Active le mode édition avec overlay. Optionnel. @param {function} [props.onImageChange] - Callback avec le fichier sélectionné. Optionnel. @parent bpm.sidebar, bpm.navbar @associated bpm.userMenu, bpm.badge @forbidden aucun @semantic role=affichage frame=entity status=needs-curation @guidance Représenter un acteur (utilisateur, contact) de façon compacte : initiales ou photo. Associer : bpm.activityFeed, bpm.commentThread, bpm.table. Éviter : Illustration générique (bpm.image) ou statut d'un acteur (bpm.badge). ``` src?: string | null — URL de l'image de l'avatar. alt?: string — Texte alternatif (accessibilité). initials?: string — Initiales affichées si pas d'image. Ex. "JD". size?: AvatarSize — Taille de l'avatar. Valeurs : 'small' | 'medium' | 'large'. Default: 'medium'. className?: string variant?: "default" | "sidebar" — Affiche l'avatar dans un bloc type sidebar : avatar + name + subtitle, optionnellement bouton déconnexion. Valeurs : 'default' | 'sidebar'. Default: 'default'. name?: string — Nom affiché à côté de l'avatar (variant sidebar). subtitle?: string — Sous-titre (ex. email) sous le nom (variant sidebar). onLogout?: () => void — Callback déconnexion (variant sidebar) ; si fourni, affiche un bouton. logoutLabel?: string — Libellé du bouton déconnexion (variant sidebar). Default: 'Se déconnecter'. editable?: boolean — Active le mode édition : overlay crayon au survol, file picker au clic. onImageChange?: (file: File) => void — Callback appelé avec le File sélectionné. ``` ## bpm.badge @component bpm.badge @description Étiquette compacte pour afficher un statut, une catégorie ou un compteur avec variantes de couleur. @example bpm.badge({ children: "En cours", variant: "warning" }) @param {object} props @param {ReactNode} props.children - Contenu du badge. Obligatoire. @param {"default"|"primary"|"success"|"warning"|"error"} [props.variant="default"] - Style du badge. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.table, bpm.card, bpm.metric @associated bpm.chip, bpm.statusBox @forbidden Texte long >20 caractères — utiliser bpm.chip @semantic role=indicateur frame=workflow type=statut direction=neutre temporalite=instantane status=proposed @guidance Statut ponctuel d'une instance : valeur d'énumération (WorkflowState) dont la couleur porte la sémantique d'état. Associer : bpm.table, bpm.card, bpm.timeline. Éviter : Élément cliquable ou filtre (bpm.chip), message système (bpm.message), bloc de statut détaillé (bpm.statusBox). ``` children*: React.ReactNode — PARENT: bpm.table (colonne statut) | bpm.metric | bpm.card. INTERDIT: texte long >20 chars — utiliser bpm.chip. ASSOCIÉ: bpm.table, bpm.metric, bpm.statusBox. variant?: BadgeVariant — Style / couleur du badge. Valeurs : 'default' | 'primary' | 'success' | 'warning' | 'error'. Default: 'default'. className?: string size?: "sm" | "md" | "lg" — Taille du badge. 'sm' (défaut) | 'md' | 'lg'. Additif — n'affecte pas le rendu existant. ``` ## bpm.barChart @component bpm.barChart @description Graphique à barres verticales SVG simple pour comparaisons de valeurs. @example bpm.barChart({ data: [{ x: "Jan", y: 100 }, { x: "Fév", y: 150 }], color: "var(--bpm-accent)" }) @param {object} props @param {BarChartDatum[]} props.data - Données du graphique [{x, y}]. Obligatoire. @param {number} [props.width=400] - Largeur du graphique. Optionnel. @param {number} [props.height=200] - Hauteur du graphique. Optionnel. @param {string} [props.color="var(--bpm-accent)"] - Couleur des barres. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : barres colorées par écart individuel au repère + verdict global. Optionnel. @associated bpm.lineChart, bpm.areaChart, bpm.plotlyChart @parent bpm.card, bpm.grid, bpm.tableauxDeBord @forbidden Série temporelle continue — utiliser bpm.lineChart @semantic role=indicateur frame=kpi type=distribution,compte direction=contextuel temporalite=instantane status=proposed @guidance Comparer une mesure entre catégories discrètes : répartition, classement, volumes par segment. Associer : bpm.metric, bpm.filterPanel, bpm.caption. Éviter : Évolution temporelle continue (bpm.lineChart). Règle apps générées : bpm.plotlyChart. ``` data*: BarChartDatum[] width?: number height?: number color?: string className?: string context?: InterpretContext — Contexte de jugement { reference, direction } : chaque barre est jugée individuellement (couleur par écart au repère), le repère est tracé en pointillé et la série entière reçoit un verdict global (aria-label, data-judgment). Additif : sans context, rendu inchangé. ``` ## bpm.barcode @component bpm.barcode @description Générateur de code-barres SVG avec valeur textuelle affichée dessous. @example bpm.barcode({ value: "ABC123456", format: "CODE128", height: 60 }) @param {object} props @param {string} props.value - Valeur à encoder en code-barres. Obligatoire. @param {"EAN13"|"CODE128"} [props.format="CODE128"] - Format du code-barres. Optionnel. @param {number} [props.height=60] - Hauteur des barres. Optionnel. @param {number} [props.width=2] - Largeur d'une barre unitaire. Optionnel. @param {string} [props.lineColor="var(--bpm-text-primary)"] - Couleur des barres. Optionnel. @param {string} [props.background="transparent"] - Couleur de fond. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.qrCode, bpm.labelValue @parent bpm.card, bpm.table, bpm.filePreview @forbidden URL ou vCard — utiliser bpm.qrCode @semantic role=affichage frame=connector status=needs-curation @guidance Matérialiser l'identifiant d'une entité en code-barres scannable (EAN-13, Code 128) : étiquette, traçabilité logistique. Associer : bpm.qrCode, bpm.labelValue, bpm.invoiceTemplate. Éviter : Lien ou contenu riche à encoder (bpm.qrCode) ou identifiant à lire par un humain (bpm.labelValue). ``` value*: string format?: "EAN13" | "CODE128" height?: number width?: number lineColor?: string background?: string className?: string ``` ## bpm.breadcrumb @component bpm.breadcrumb @description Fil d'Ariane pour navigation hiérarchique avec liens cliquables. @example bpm.breadcrumb({ items: [{ label: "Accueil", href: "/" }, { label: "Produits" }] }) @param {object} props @param {BreadcrumbItem[]} [props.items=[]] - Liste des éléments {label, href}. Optionnel. @param {string} [props.separator="›"] - Séparateur entre éléments. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.pageHeader, bpm.navbar @associated bpm.breadcrumbs, bpm.tabs @forbidden aucun @semantic role=navigation frame=section status=proposed @guidance Situer l'écran dans la hiérarchie (liste → détail → sous-détail) et permettre de remonter. Associer : bpm.pageLayout, bpm.topNav. Éviter : Navigation horizontale entre sections de même niveau (bpm.topNav, bpm.tabs). ``` items?: BreadcrumbItem[] separator?: string className?: string ``` ## bpm.breadcrumbs @component bpm.breadcrumbs @description Fil d’Ariane avancé avec séparateur personnalisable et réduction automatique si trop d’entrées. @example bpm.breadcrumbs({ items: [{ label: "Accueil", href: "/" }, { label: "Catégorie" }, { label: "Article" }], maxItems: 4 }) @param {object} props @param {BreadcrumbsItem[]} props.items - Liste des éléments {label, href?, onClick?}. Obligatoire. @param {ReactNode} [props.separator="/"] - Séparateur entre éléments. Optionnel. @param {number} [props.maxItems=8] - Nombre max d’éléments avant réduction. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.pageHeader, bpm.navbar @associated bpm.breadcrumb, bpm.tabs ``` items*: BreadcrumbsItem[] separator?: React.ReactNode maxItems?: number className?: string ``` ## bpm.button @component bpm.button @description Bouton d'action avec variantes (primary, secondary, outline, ghost, destructive, link), tailles et icônes. @example bpm.button({ children: "Enregistrer", variant: "primary", icon: "check", onClick: () => save() }) @param {object} props @param {ReactNode} [props.children] - Contenu textuel du bouton. Optionnel. @param {function} [props.onClick] - Callback au clic. Optionnel. @param {"primary"|"secondary"|"outline"|"ghost"|"destructive"|"link"} [props.variant="primary"] - Style du bouton. Optionnel. @param {"small"|"medium"|"large"|"sm"|"md"|"lg"} [props.size="medium"] - Taille du bouton. Optionnel. @param {boolean} [props.raised=false] - Mode toolbar avec ombre au survol. Optionnel. @param {string} [props.icon] - Nom de l'icône à gauche. Optionnel. @param {string} [props.iconRight] - Nom de l'icône à droite. Optionnel. @param {boolean} [props.loading=false] - Affiche un spinner. Optionnel. @param {boolean} [props.disabled=false] - Désactive le bouton. Optionnel. @param {boolean} [props.fullWidth=false] - Occupe toute la largeur. Optionnel. @param {"button"|"submit"|"reset"} [props.type="button"] - Type HTML du bouton. Optionnel. @param {string} [props.className] - Classes CSS additionnelles. Optionnel. @associated bpm.fab, bpm.iconButton, bpm.buttonGroup @parent bpm.modal, bpm.card, bpm.panel, bpm.topNav @forbidden Navigation entre pages — utiliser un lien @semantic role=action frame=event status=proposed @guidance Déclencher un événement de domaine ou une transition : créer, valider, lancer. La variante reflète la priorité de l'action. Associer : bpm.confirmModal, bpm.modal, bpm.toast. Éviter : Navigation entre pages (lien/bpm.topNav) ou bascule d'état persistante (bpm.checkbox, toggle). ``` children?: React.ReactNode onClick?: () => void variant?: ButtonVariant size?: ButtonSize raised?: boolean — Toolbar : ghost avec hover surface + shadow icon?: string | null iconRight?: string | null loading?: boolean disabled?: boolean fullWidth?: boolean type?: "button" | "submit" | "reset" className?: string style?: React.CSSProperties ``` ## bpm.caption @component bpm.caption @description Légende ou texte secondaire sous un bloc (graphique, carte, champ) pour contexte métier. @example bpm.caption({ children: "Données CA 2024 — source DGFiP." }) @props - children (ReactNode) — Texte de la légende. - className (string, optionnel) — Classes CSS. - style (object, optionnel) — Styles inline. @usage Légendes de graphiques, sources de données, hints sous champs. @context PARENT: bpm.panel | bpm.card | bpm.plotlyChart. ASSOCIATED: bpm.plotlyChart, bpm.table, bpm.image. FORBIDDEN: aucun. @semantic role=affichage frame=section status=proposed @guidance Texte secondaire : légende sous un indicateur, un média ou un champ ; précision de source ou d'unité. Associer : bpm.metric, bpm.image, bpm.lineChart. Éviter : Contenu principal (bpm.text) ou information critique qui doit rester lisible. ``` children*: React.ReactNode className?: string style?: React.CSSProperties ``` ## bpm.card @component bpm.card @description Carte de contenu avec titre, image optionnelle et zone d'actions pour fiches produit ou résumés. @example bpm.card({ title: "Contrat Premium", subtitle: "Renouvellement mars 2025", children: "..." }) @props - title (ReactNode, optionnel) — Titre de la carte. - subtitle (ReactNode, optionnel) — Sous-titre. - image (string, optionnel) — URL image en en-tête. - imageAlt (string, optionnel) — Texte alternatif image. - children (ReactNode, optionnel) — Contenu principal. - actions (ReactNode, optionnel) — Boutons ou liens en pied. - variant ('default' | 'elevated' | 'outlined', optionnel) — Style. Default: 'default'. - inverted (boolean, optionnel) — Fond sombre. Default: false. - className (string, optionnel) — Classes CSS. @usage Fiches produit, résumés contrat, cartes dashboard. @context PARENT: bpm.grid | bpm.tabs (contenu onglet) | page directe. ASSOCIATED: bpm.metric, bpm.button, bpm.badge. FORBIDDEN: bpm.card imbriqué trop profond (max 2 niveaux). @semantic role=conteneur frame=section status=proposed @guidance Unité de contenu autonome : regrouper ce qui se lit ensemble (un indicateur et sa légende, une entité et ses actions). Associer : bpm.grid, bpm.metric, bpm.button. Éviter : Simple espacement (bpm.container) ou mise en avant éditoriale structurée (bpm.highlightBox). ``` title?: React.ReactNode subtitle?: React.ReactNode image?: string imageAlt?: string children?: React.ReactNode actions?: React.ReactNode variant?: CardVariant inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style zone type Executive Summary). className?: string ``` ## bpm.changelog @component bpm.changelog @description Journal des modifications affichant avant/après avec acteur, date et regroupement optionnel par jour. @example bpm.changelog({ changes: [{ field: "prix", before: 100, after: 120, actor: "Marie", date: "2024-01-15T10:00:00Z" }] }) @param {object} props @param {ChangelogEntry[]} props.changes - Liste des modifications à afficher. Obligatoire. @param {boolean} [props.groupByDate=false] - Regroupe par jour (Aujourd'hui, Hier, date). Optionnel. @param {number} [props.maxItems] - Limite le nombre d'entrées affichées. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.activityFeed, bpm.timeline, bpm.diffViewer ``` changes*: ChangelogEntry[] groupByDate?: boolean maxItems?: number className?: string ``` ## bpm.chat Chat Ollama local (démo). ``` model?: string placeholder?: string ``` ## bpm.chatInterface @component bpm.chatInterface @description Interface de chat complète avec messages utilisateur/assistant, indicateur de frappe et champ de saisie. @example bpm.chatInterface({ messages: [{ id: "1", role: "user", content: "Bonjour" }], onSend: (msg) => sendMessage(msg) }) @param {object} props @param {ChatMessage[]} props.messages - Liste des messages {id, role, content, timestamp?}. Obligatoire. @param {function} props.onSend - Callback appelé avec le contenu du message envoyé. Obligatoire. @param {boolean} [props.isLoading=false] - Indicateur de chargement (deprecated, utiliser typing). Optionnel. @param {boolean} [props.typing] - Indicateur de frappe côté assistant. Optionnel. @param {string} [props.placeholder="Écrivez votre message..."] - Texte d'aide du champ. Optionnel. @param {string} [props.systemContext] - Contexte système affiché en haut. Optionnel. @param {string} [props.title] - Titre dans l'en-tête. Optionnel. @param {boolean} [props.disabled=false] - Désactive l'envoi. Optionnel. @param {string} [props.height="100%"] - Hauteur du conteneur. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.assistantPanel, bpm.aiQueryBar, bpm.promptInput @parent bpm.page, bpm.card, bpm.drawer @forbidden aucun @semantic role=composite frame=ai status=proposed @guidance Dialogue avec un assistant IA : messages, saisie, streaming (AIFeature uiComponent chatInterface). Associer : bpm.promptInput, bpm.streamingText, bpm.modelSelector, bpm.spinnerDot. Éviter : Question unique sans conversation (bpm.promptInput + bpm.streamingText) ou commentaire entre humains. ``` messages*: ChatMessage[] onSend*: (content: string) => void isLoading?: boolean — @deprecated Préférez `typing`. typing?: boolean — Indicateur « en cours de frappe » côté assistant. placeholder?: string systemContext?: string — Contexte système affiché en haut si défini. title?: string — Titre dans l’en-tête du panneau. disabled?: boolean height?: string className?: string ``` ## bpm.checkbox @component bpm.checkbox @description Case a cocher pour choix binaire (acceptation CGU, option activée). Prop contrôlée : `checked` (boolean) — PAS `value` ; `value` est la prop de bpm.toggle, ne pas confondre. @example bpm.checkbox({ label: "J'accepte les conditions", checked: false, onChange: setAccepted }) @props - label (ReactNode, optionnel) — Libelle a cote de la case. - checked (boolean, optionnel) — Etat coché. Default: false. - onChange (function, optionnel) — Callback (checked: boolean). - disabled (boolean, optionnel) — Default: false. - className (string, optionnel) — Classes CSS. @usage CGU, options formulaire, filtres liste. @context PARENT: bpm.modal | bpm.panel | bpm.card. ASSOCIATED: bpm.input, bpm.button. FORBIDDEN: aucun. @semantic role=saisie frame=entity status=proposed @guidance Saisir un booléen (Field boolean) : consentement, option, inclusion dans une sélection multiple. Associer : bpm.wizardForm, bpm.filterPanel. Éviter : Choix exclusif entre valeurs (bpm.radioGroup) ou action immédiate (bpm.button). ``` label?: React.ReactNode checked?: boolean onChange?: (checked: boolean) => void disabled?: boolean className?: string ``` ## bpm.chip @component bpm.chip @description Étiquette interactive avec label et bouton de suppression optionnel pour tags ou filtres actifs. @example bpm.chip({ label: "React", variant: "primary", onDelete: () => removeTag("React") }) @param {object} props @param {ReactNode} props.label - Texte ou contenu du chip. Obligatoire. @param {function} [props.onDelete] - Callback pour supprimer le chip. Optionnel. @param {function} [props.onClick] - Callback au clic sur le chip. Optionnel. @param {"default"|"primary"|"outline"} [props.variant="default"] - Style du chip. Optionnel. @param {boolean} [props.disabled=false] - Désactive les interactions. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.filterPanel, bpm.form @associated bpm.badge, bpm.tag @forbidden Statut court figé — utiliser bpm.badge @semantic role=affichage frame=entity status=proposed @guidance Pastille interactive : tag, filtre actif révocable, sélection multiple visible. Associer : bpm.filterPanel, bpm.autocomplete, bpm.input. Éviter : Statut de workflow non interactif (bpm.badge). ``` label*: React.ReactNode onDelete?: () => void onClick?: () => void variant?: ChipVariant disabled?: boolean className?: string ``` ## bpm.codeBlock @component bpm.codeBlock @description Affiche un bloc de code avec coloration syntaxique et bouton Copier pour documentation technique ou procédures. @example bpm.codeBlock({ code: "npm install @blueprint-modular/core", language: "bash" }) @props - code (string) — Contenu du bloc de code. - language (string, optionnel) — Langage pour coloration (bash, json, typescript…). Default: 'text'. - className (string, optionnel) — Classes CSS. @usage Documentation API, procédures d'installation, exemples de requêtes. @context PARENT: bpm.panel | bpm.card. ASSOCIATED: bpm.markdown, bpm.title. FORBIDDEN: aucun. @semantic role=affichage frame=section status=proposed @guidance Montrer du code ou une commande à copier : extrait figé, exemple d'intégration. Associer : bpm.markdown, bpm.tabs. Éviter : Code à modifier (bpm.codeEditor) ou données JSON à inspecter (bpm.jsonViewer). ``` code*: string language?: string className?: string ``` ## bpm.codeEditor @component bpm.codeEditor @description Éditeur de code simple (textarea monospace) pour saisie ou modification de code. @example bpm.codeEditor({ value: code, onChange: setCode, language: "json", height: 400 }) @param {object} props @param {string} props.value - Contenu du code. Obligatoire. @param {function} props.onChange - Callback appelé à chaque modification. Obligatoire. @param {string} [props.language] - Langage (pour référence, pas de coloration). Optionnel. @param {boolean} [props.readOnly=false] - Mode lecture seule. Optionnel. @param {string|number} [props.height=300] - Hauteur de l'éditeur. Optionnel. @param {string} [props.placeholder=""] - Texte d'aide. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.codeBlock, bpm.jsonEditor @parent bpm.card, bpm.modal, bpm.tabs @forbidden Affichage en lecture seule — utiliser bpm.codeBlock @semantic role=saisie frame=entity status=proposed @guidance Saisir ou modifier du code/texte technique (script, template, expression). Associer : bpm.codeBlock, bpm.diffViewer, bpm.button. Éviter : Lecture seule (bpm.codeBlock), JSON structuré validé (bpm.jsonEditor), prose (bpm.textarea). ``` value*: string onChange*: (value: string) => void language?: string readOnly?: boolean height?: string | number placeholder?: string className?: string ``` ## bpm.colorPicker @component bpm.colorPicker @description Sélecteur de couleur avec aperçu et affichage du code hexadécimal. @example bpm.colorPicker({ label: "Couleur principale", value: "#00a3e2", onChange: setColor }) @param {object} props @param {string} [props.label] - Libellé du champ. Optionnel. @param {string} [props.value="#000000"] - Valeur couleur hexadécimale. Optionnel. @param {function} [props.onChange] - Callback appelé avec la nouvelle couleur. Optionnel. @param {string} [props.help] - Texte d'aide affiché en tooltip. Optionnel. @param {boolean} [props.disabled=false] - Désactive le sélecteur. Optionnel. @parent bpm.form @associated bpm.input, bpm.select @forbidden aucun @semantic role=saisie frame=meta status=proposed @guidance Choisir une couleur : branding, catégorisation visuelle d'une entité (étiquette, calendrier). Associer : bpm.chip, bpm.badge. Éviter : Choix dans une palette fermée imposée (bpm.selectbox d'EnumValues colorées). ``` label?: string value?: string onChange?: (value: string) => void help?: string | null disabled?: boolean ``` ## bpm.column @component bpm.column @description Conteneur en grille pour organiser le contenu en colonnes avec espacement configurable. @example bpm.column({ columns: 3, gap: "1rem", children: [, , ] }) @param {object} props @param {number} [props.columns=2] - Nombre de colonnes (1 à 12). Optionnel. @param {number|string} [props.gap="1rem"] - Espacement entre colonnes. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {ReactNode} [props.children] - Contenu des colonnes. Optionnel. @associated bpm.grid, bpm.container, bpm.row @parent bpm.page, bpm.container @forbidden Layout pleine largeur d'un seul bloc — inutile @semantic role=conteneur frame=section status=proposed @guidance Diviser l'écran en colonnes de contenus hétérogènes (formulaire + aide, liste + résumé). Associer : bpm.card, bpm.container. Éviter : Grille d'éléments homogènes (bpm.grid) ou vue liste/détail liée (bpm.masterDetail). ``` columns?: number — Nombre de colonnes (1, 2, 3, 4, etc.). gap?: number | string — Espacement entre les colonnes (CSS, ex. "1rem", 16). className?: string children?: React.ReactNode ``` ## bpm.commandPalette @component bpm.commandPalette @description Palette de commandes modale avec recherche floue, navigation clavier et raccourcis (Cmd/Ctrl+K). @example bpm.commandPalette({ commands: [{ id: "save", label: "Enregistrer", action: save }], onClose: () => setOpen(false) }) @param {object} props @param {Command[]} props.commands - Liste des commandes {id, label, description?, icon?, shortcut?, category?, action}. Obligatoire. @param {boolean} [props.isOpen] - Mode contrôlé : état d'ouverture. Optionnel. @param {function} props.onClose - Callback de fermeture. Obligatoire. @param {function} [props.onRequestOpen] - Callback sur Cmd/Ctrl+K (mode contrôlé). Optionnel. @param {string} [props.placeholder="Rechercher une action..."] - Texte d'aide. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.searchModal, bpm.autocomplete @parent bpm.page, bpm.pageLayout @forbidden Navigation permanente — utiliser bpm.topNav ou bpm.sidebar @semantic role=navigation frame=section status=proposed @guidance Accès clavier universel (Cmd+K) aux commandes et destinations : recherche floue sur tout ce que l'app sait faire. Associer : bpm.topNav, bpm.pageLayout. Éviter : Navigation primaire visible (bpm.topNav) — la palette complète, elle ne remplace pas. ``` commands*: Command[] isOpen?: boolean — Mode contrôlé : si défini, l’ouverture au clavier doit être gérée via `onRequestOpen`. onClose*: () => void onRequestOpen?: () => void — Appelé sur Cmd/Ctrl+K lorsque `isOpen` est fourni (mode contrôlé). placeholder?: string className?: string ``` ## bpm.commentThread @component bpm.commentThread @description Fil de commentaires récursif avec réponses inline, dates relatives et profondeur configurable. @example bpm.commentThread({ comments: [...], onPost: (content, parentId) => addComment(content, parentId), currentUser: { id: "1", name: "Marie" } }) @param {object} props @param {Comment[]} props.comments - Liste des commentaires avec replies optionnelles. Obligatoire. @param {function} props.onPost - Callback pour publier (content, parentId?). Obligatoire. @param {object} props.currentUser - Utilisateur connecté {id, name}. Obligatoire. @param {number} [props.maxDepth=2] - Profondeur maximale des réponses. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.activityFeed, bpm.chatInterface ``` comments*: Comment[] onPost*: (content: string, parentId?: string) => void | Promise currentUser*: { id: string maxDepth?: number className?: string ``` ## bpm.comparison @component bpm.comparison @description Tableau de comparaison multi-critères avec mise en évidence optionnelle des meilleures valeurs. @example bpm.comparison({ items: [{ prix: 100 }, { prix: 80 }], dimensions: ["prix"], highlightBest: true }) @param {object} props @param {Record[]} props.items - Objets à comparer. Obligatoire. @param {string[]} props.dimensions - Clés des critères de comparaison. Obligatoire. @param {Record} [props.labels] - Labels personnalisés pour les dimensions. Optionnel. @param {boolean} [props.highlightBest=true] - Met en évidence les meilleures valeurs. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {Record} [props.contexts] - Contextes de jugement par dimension : cellules jugées vs repère. Optionnel. @associated bpm.table, bpm.metric ``` items*: Record[] dimensions*: string[] labels?: Record highlightBest?: boolean className?: string contexts?: Record — Contextes de jugement PAR DIMENSION { dim: { reference, direction } } : chaque cellule de la dimension est jugée par interpret — valeur colorée par le verdict, écart au repère en title, data-judgment par cellule. Additif : sans contexts, rendu inchangé. ``` ## bpm.confirmModal @component bpm.confirmModal @description Modale de confirmation pour actions critiques (suppression, validation) avec variantes danger/warning/info. @example bpm.confirmModal({ isOpen: true, title: "Supprimer ?", message: "Cette action est irréversible.", onConfirm: delete, onCancel: close, variant: "danger" }) @param {object} props @param {boolean} props.isOpen - État d'ouverture de la modale. Obligatoire. @param {function} props.onConfirm - Callback de confirmation. Obligatoire. @param {function} props.onCancel - Callback d'annulation. Obligatoire. @param {string} props.title - Titre de la modale. Obligatoire. @param {string} props.message - Message explicatif. Obligatoire. @param {string} [props.confirmLabel="Confirmer"] - Texte du bouton confirmer. Optionnel. @param {string} [props.cancelLabel="Annuler"] - Texte du bouton annuler. Optionnel. @param {"danger"|"warning"|"info"} [props.variant="info"] - Style visuel. Optionnel. @param {boolean} [props.isLoading=false] - État de chargement. Optionnel. @associated bpm.modal, bpm.button @parent bpm.page, bpm.card @forbidden Information non bloquante — utiliser bpm.toast @semantic role=feedback frame=rule status=proposed @guidance Garde avant action irréversible ou coûteuse : exiger une confirmation explicite (danger, warning, info). Associer : bpm.button, bpm.toast, bpm.crud. Éviter : Actions réversibles banales (friction inutile) ou saisie complémentaire (bpm.modal). ``` isOpen*: boolean onConfirm*: () => void onCancel*: () => void title*: string message*: string confirmLabel?: string cancelLabel?: string variant?: ConfirmModalVariant isLoading?: boolean ``` ## bpm.container @component bpm.container @description Conteneur de mise en page pour centrer et limiter la largeur du contenu (pages, formulaires). @example bpm.container({ children: "..." }) @props - children (ReactNode) — Contenu. - className (string, optionnel) — Classes CSS. - style (object, optionnel) — Styles inline. @usage Wrapper de page, zone principale formulaire. @context PARENT: page directe | layout. ASSOCIATED: bpm.panel, bpm.grid, bpm.title. FORBIDDEN: aucun. @semantic role=conteneur frame=section status=proposed @guidance Regrouper un bloc de contenu, avec titre optionnel, sans la matérialité d'une carte. Associer : bpm.title3, bpm.text, bpm.table. Éviter : Unité autonome détachée du fond (bpm.card) ou zone défilante (bpm.scrollContainer). ``` children*: React.ReactNode className?: string style?: React.CSSProperties ``` ## bpm.contextMenu @component bpm.contextMenu @description Menu contextuel positionné dynamiquement, déclenché par clic droit ou clic simple. @example bpm.contextMenu({ items: [{ id: "copy", label: "Copier", onSelect: copy }], trigger: , triggerOn: "contextmenu" }) @param {object} props @param {ContextMenuItem[]} props.items - Liste des éléments du menu {id, label, disabled?, onSelect?}. Obligatoire. @param {ReactNode} props.trigger - Élément déclencheur du menu. Obligatoire. @param {"contextmenu"|"click"} [props.triggerOn="contextmenu"] - Mode de déclenchement. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.dropdown, bpm.popover ``` items*: ContextMenuItem[] trigger*: React.ReactNode triggerOn?: "contextmenu" | "click" className?: string ``` ## bpm.crud @component bpm.crudPage @description Page CRUD complète avec table paginée, recherche, modales création/édition/suppression et appels API. @example bpm.crudPage({ title: "Clients", endpoint: "/api/clients", columns: [...], fields: [...] }) @param {object} props @param {string} props.title - Titre de la page. Obligatoire. @param {string} props.endpoint - URL de l'API CRUD. Obligatoire. @param {CrudColumn[]} props.columns - Colonnes du tableau {key, label, type?, sortable?}. Obligatoire. @param {CrudField[]} props.fields - Champs du formulaire {key, label, type, required?, options?}. Obligatoire. @param {string} [props.domain] - Domaine métier. Optionnel. @param {string} [props.semantic] - Sémantique du contenu. Optionnel. @param {string} [props.idKey="id"] - Clé d'identifiant pour les opérations. Optionnel. @associated bpm.table, bpm.modal, bpm.form @parent bpm.page, bpm.pageLayout @forbidden aucun @semantic role=composite frame=entity status=proposed @guidance Gestion complète d'une Entity en un composant : liste, formulaire, colonnes, champs, endpoint (LayoutType crud-table). Associer : bpm.confirmModal, bpm.toast, bpm.filterPanel. Éviter : Écrans sur mesure où la composition fine est requise (bpm.table + bpm.modal + champs) ou exploration analytique (bpm.dataExplorer). ``` title*: string endpoint*: string columns*: CrudColumn[] fields*: CrudField[] domain?: string semantic?: string idKey?: string — Champ utilisé comme identifiant pour GET/PUT/DELETE (défaut: "id"). ``` ## bpm.dataExplorer @component bpm.dataExplorer @description Explorateur de données unifié supportant le mode classique (table) ou analytics (filtres + graphiques). @example bpm.dataExplorer({ mode: "analytics", data: [...], columns: [...], chartConfig: { type: "bar", xKey: "mois", yKey: "ventes" } }) @param {object} props @param {"classic"|"analytics"} [props.mode] - Mode d'affichage. Optionnel (défaut: classic). @param {Record[]} props.data - Données à explorer. Obligatoire. @param {ColumnDef[]|ExplorerAnalyticsColumn[]} props.columns - Définition des colonnes. Obligatoire. @associated bpm.table, bpm.filterPanel, bpm.barChart @parent bpm.page, bpm.pageLayout, bpm.card @forbidden Petite liste statique — utiliser bpm.table @semantic role=composite frame=entity status=proposed @guidance Exploration autonome d'une collection : table + recherche + tri + pagination + export CSV en un composant. Associer : bpm.metric, bpm.filterPanel, bpm.plotlyChart. Éviter : Affichage simple sans outillage (bpm.table) ou gestion avec écriture (bpm.crud). ``` ``` ## bpm.dateInput @component bpm.dateInput @description Champ de saisie de date avec calendrier popover et format FR (JJ/MM/AAAA). @example bpm.dateInput({ label: "Date de livraison", value: new Date(), onChange: setDate }) @param {object} props @param {string} [props.label] - Libellé du champ. Optionnel. @param {Date|string|null} [props.value] - Valeur de la date. Optionnel. @param {function} [props.onChange] - Callback avec la date sélectionnée. Optionnel. @param {boolean} [props.disabled=false] - Désactive le champ. Optionnel. @param {string} [props.help] - Texte d'aide en tooltip. Optionnel. @param {Date|string|null} [props.min] - Date minimale autorisée. Optionnel. @param {Date|string|null} [props.max] - Date maximale autorisée. Optionnel. @param {string|null} [props.error=null] - Message d'erreur du champ : contour rouge + message sous le champ. Optionnel. @parent bpm.form @associated bpm.dateRangePicker, bpm.datePickerPopover @forbidden Plage de dates — utiliser bpm.dateRangePicker @semantic role=saisie frame=entity status=proposed @guidance Saisir une date ponctuelle (Field date/datetime) : échéance, date d'événement. Associer : bpm.wizardForm, bpm.timeInput. Éviter : Période ou intervalle (bpm.dateRangePicker), heure seule (bpm.timeInput). ``` label?: string value?: Date | string | null onChange?: (value: Date | null) => void disabled?: boolean help?: string | null min?: Date | string | null max?: Date | string | null error?: string | null — Message d'erreur du CHAMP : contour rouge + message sous le champ (role=alert, aria-invalid). Additif : défaut null = rendu inchangé. ``` ## bpm.dateRangePicker @component bpm.dateRangePicker @description Sélecteur de plage de dates avec deux champs (début/fin) et calendriers popover coordonnés. @example bpm.dateRangePicker({ label: "Période", start: startDate, end: endDate, onChange: (s, e) => setRange(s, e) }) @param {object} props @param {string} [props.label] - Libellé du champ. Optionnel. @param {Date|string|null} [props.start] - Date de début. Optionnel. @param {Date|string|null} [props.end] - Date de fin. Optionnel. @param {function} [props.onChange] - Callback (start, end). Optionnel. @param {boolean} [props.disabled=false] - Désactive le sélecteur. Optionnel. @param {Date|string|null} [props.min] - Date minimale. Optionnel. @param {Date|string|null} [props.max] - Date maximale. Optionnel. @parent bpm.filterPanel, bpm.form @associated bpm.dateInput, bpm.datePickerPopover @forbidden Date unique — utiliser bpm.dateInput @semantic role=saisie frame=entity status=proposed @guidance Saisir une période (début/fin) : filtre temporel d'une série, plage de validité. Associer : bpm.lineChart, bpm.filterPanel, bpm.dataExplorer. Éviter : Date unique (bpm.dateInput). ``` label?: string start?: Date | string | null end?: Date | string | null onChange?: (start: Date | null, end: Date | null) => void disabled?: boolean min?: Date | string | null max?: Date | string | null ``` ## bpm.decisionTree @component bpm.decisionTree @description Arbre de décision interactif avec questions (losanges), actions et résultats navigables. @example bpm.decisionTree({ rootId: "q1", nodes: [...], currentNodeId: "q1", onNodeClick: handleClick }) @param {object} props @param {string} props.rootId - ID du nœud racine. Obligatoire. @param {DecisionNode[]} props.nodes - Liste des nœuds {id, kind, label, branches?}. Obligatoire. @param {string} [props.currentNodeId] - ID du nœud actif. Optionnel. @param {function} props.onNodeClick - Callback (nodeId, branch?). Obligatoire. @associated bpm.flowDiagram, bpm.stepper ``` rootId*: string nodes*: DecisionNode[] currentNodeId?: string onNodeClick*: (nodeId: string, branch?: { label: string ``` ## bpm.diffViewer @component bpm.diffViewer @description Visualiseur de différences textuelles entre deux versions (mode split ou unified). @example bpm.diffViewer({ original: "ancien", modified: "nouveau", mode: "split" }) @param {object} props @param {string} props.original - Texte original. Obligatoire. @param {string} props.modified - Texte modifié. Obligatoire. @param {string} [props.language] - Langage pour référence. Optionnel. @param {"split"|"unified"} [props.mode="split"] - Mode d'affichage. Optionnel. @param {object} [props.title] - Titres des colonnes {original?, modified?}. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.changelog, bpm.codeBlock @parent bpm.card, bpm.modal, bpm.tabs @forbidden Code sans comparaison — utiliser bpm.codeBlock @semantic role=affichage frame=ai status=needs-curation @guidance Comparer deux versions d'un texte/code (split ou unified) : relecture d'une proposition IA, audit de modification. Associer : bpm.codeEditor, bpm.button, bpm.confirmModal. Éviter : Affichage d'une seule version (bpm.codeBlock) ou comparaison de données tabulaires (bpm.table). ``` original*: string modified*: string language?: string mode?: "split" | "unified" title?: { original?: string className?: string ``` ## bpm.divider @component bpm.divider @description Ligne de separation horizontale ou verticale (optionnellement avec libelle) entre blocs. @example bpm.divider({ label: "ou", orientation: "horizontal" }) @props - label (string, optionnel) — Texte centre sur la ligne. - orientation ('horizontal' | 'vertical', optionnel) — Sens. Default: 'horizontal'. - thickness (number, optionnel) — Epaisseur en px. Default: 1. - color (string, optionnel) — Couleur CSS. Default: var(--bpm-border). - className (string, optionnel) — Classes CSS. @usage Separation de sections, separateur ou dans formulaire. @context PARENT: bpm.panel | bpm.card | page. ASSOCIATED: bpm.input, bpm.button. FORBIDDEN: aucun. @semantic role=affichage frame=section status=proposed @guidance Marquer une rupture thématique entre deux blocs de même niveau. Associer : bpm.title2, bpm.container. Éviter : Compenser un manque de hiérarchie (préférer bpm.title2/title3) ou espacer (marges). ``` label?: string orientation?: "horizontal" | "vertical" thickness?: number — Épaisseur en pixels (défaut 1). color?: string — Couleur de la ligne (CSS, ex. var(--bpm-border), #ccc, rgb(0,0,0)). className?: string ``` ## bpm.drawer @component bpm.drawer @description Panneau latéral glissant (gauche ou droite) avec overlay et fermeture par Escape ou clic extérieur. @example bpm.drawer({ open: true, onClose: close, title: "Détails", side: "right", children: }) @param {object} props @param {ReactNode} props.children - Contenu du drawer. Obligatoire. @param {boolean} props.open - État d'ouverture. Obligatoire. @param {function} props.onClose - Callback de fermeture. Obligatoire. @param {ReactNode} [props.title] - Titre dans l'en-tête. Optionnel. @param {"left"|"right"} [props.side="right"] - Côté d'apparition. Optionnel. @param {number|string} [props.width=360] - Largeur du drawer. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.modal, bpm.panel, bpm.sidebar @parent bpm.page, bpm.pageLayout @forbidden Confirmation courte — utiliser bpm.modal/confirmModal @semantic role=conteneur frame=section status=proposed @guidance Panneau latéral de travail : détail, formulaire ou filtres consultés en parallèle du contenu principal. Associer : bpm.labelValue, bpm.filterPanel, bpm.button. Éviter : Décision bloquante (bpm.modal, bpm.confirmModal) ou contenu ancré ponctuel (bpm.popover). ``` children*: React.ReactNode open*: boolean onClose*: () => void title?: React.ReactNode side?: "left" | "right" width?: number | string className?: string ``` ## bpm.drillDown @component bpm.drillDown @description Navigation multi-niveaux avec fil d'Ariane pour explorer des données hiérarchiques par clic sur les lignes. @example bpm.drillDown({ levels: [...], currentLevel: 0, onDrill: (item, lvl) => setLevel(lvl), onBack: () => setLevel(lvl-1) }) @param {object} props @param {DrillDownLevel[]} props.levels - Niveaux de navigation {key, label, columns, items}. Obligatoire. @param {number} props.currentLevel - Index du niveau actuel. Obligatoire. @param {function} props.onDrill - Callback (item, nextLevel) pour navigation descendante. Obligatoire. @param {function} props.onBack - Callback pour remonter d'un niveau. Obligatoire. @param {boolean} [props.breadcrumbs=true] - Affiche le fil d'Ariane. Optionnel. @associated bpm.table, bpm.breadcrumbs ``` levels*: DrillDownLevel[] currentLevel*: number onDrill*: (item: T, nextLevel: number) => void onBack*: () => void breadcrumbs?: boolean ``` ## bpm.emailComposer @component bpm.emailComposer @description Formulaire de composition d'email avec éditeur riche, modèles prédéfinis et envoi. @example bpm.emailComposer({ to: "client@exemple.fr", templates: [...], onSend: sendEmail, useRichText: true }) @param {object} props @param {string} [props.to=""] - Destinataire initial. Optionnel. @param {string} [props.subject=""] - Objet initial. Optionnel. @param {string} [props.body=""] - Corps initial. Optionnel. @param {EmailTemplate[]} [props.templates=[]] - Modèles d'email {id, label, subject, bodyHtml}. Optionnel. @param {boolean} [props.useRichText=true] - Utilise l'éditeur riche. Optionnel. @param {function} [props.onSend] - Callback d'envoi (payload). Optionnel. @param {function} [props.onCancel] - Callback d'annulation. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.richTextEditor, bpm.form ``` to?: string subject?: string body?: string templates?: EmailTemplate[] useRichText?: boolean onSend?: (payload: { to: string onCancel?: () => void className?: string ``` ## bpm.empty @component bpm.empty @description Conteneur vide minimal servant de placeholder ou espaceur dans une grille/layout. @example bpm.empty({ children: "Texte optionnel" }) @param {object} props @param {ReactNode} [props.children] - Contenu optionnel. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {object} [props.style={}] - Styles inline. Optionnel. @associated bpm.column, bpm.grid @parent bpm.card, bpm.table, bpm.container @forbidden aucun @semantic role=feedback frame=entity status=proposed @guidance Absence de données minimale (icône + message) dans un espace restreint : cellule, panneau, widget. Associer : bpm.card, bpm.drawer. Éviter : État vide pleine page avec action de création (bpm.emptyState). ``` children?: React.ReactNode className?: string style?: React.CSSProperties ``` ## bpm.emptyState @component bpm.emptyState @description État vide centré avec titre, description et action (bouton) quand une liste ou recherche n'a aucun résultat. @example bpm.emptyState({ title: "Aucune commande", description: "Créez votre première commande.", action: }) @props - title (string, optionnel) — Titre. Default: 'Aucune donnée'. - description (ReactNode, optionnel) — Texte explicatif. - icon (ReactNode, optionnel) — Icône au-dessus du titre. - action (ReactNode, optionnel) — Bouton ou lien d'action. - className (string, optionnel) — Classes CSS. @usage Liste vide, recherche sans résultat, premier usage. @context PARENT: bpm.panel | bpm.card | bpm.table (contenu vide). ASSOCIATED: bpm.button, bpm.input. FORBIDDEN: aucun. @semantic role=feedback frame=entity status=proposed @guidance Collection vide : expliquer l'absence de données et proposer l'action qui la comble (créer, importer). Associer : bpm.button, bpm.table, bpm.crud. Éviter : Chargement en cours (bpm.skeleton) ou absence ponctuelle minime (bpm.empty). ``` title?: string description?: React.ReactNode icon?: React.ReactNode action?: React.ReactNode className?: string ``` ## bpm.expander @component bpm.expander @description Bloc dépliable avec titre pour masquer/afficher du contenu (détails, annexes). Cycle de vie : le content replié est DÉMONTÉ (rendu uniquement quand ouvert), son état n'est pas préservé à la fermeture. @example bpm.expander({ title: "Détails techniques", defaultExpanded: false, children: "..." }) @props - title (ReactNode) — Titre du bloc (visible quand replié). - children (ReactNode) — Contenu dépliable. - defaultExpanded (boolean, optionnel) — Ouvert au montage. Default: false. - className (string, optionnel) — Classes CSS. @usage Détails commande, annexes contrat, section technique. @context PARENT: bpm.panel | bpm.card. ASSOCIATED: bpm.accordion, bpm.table. FORBIDDEN: aucun. @semantic role=conteneur frame=section status=proposed @guidance Détail secondaire masquable : l'utilisateur choisit d'approfondir. Associer : bpm.text, bpm.jsonViewer, bpm.table. Éviter : Contenu essentiel à la décision (le laisser visible) ou séries de sections (bpm.accordion). ``` title*: React.ReactNode children*: React.ReactNode defaultExpanded?: boolean className?: string ``` ## bpm.exportButton @component bpm.exportButton @description Bouton d'export avec menu déroulant pour télécharger en CSV ou JSON avec configuration BOM/délimiteur. @example bpm.exportButton({ data: rows, filename: "export", formats: ["csv", "json"], csvDelimiter: ";" }) @param {object} props @param {T[]|function} props.data - Données à exporter ou fonction retournant les données. Obligatoire. @param {string} props.filename - Nom du fichier sans extension. Obligatoire. @param {("csv"|"json")[]} [props.formats=["csv","json"]] - Formats proposés. Optionnel. @param {ExportColumn[]} [props.columns] - Colonnes à exporter {key, header}. Optionnel. @param {";"|","} [props.csvDelimiter=";"] - Délimiteur CSV. Optionnel. @param {boolean} [props.csvBOM=true] - Ajoute le BOM UTF-8. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.table, bpm.dataExplorer ``` data*: T[] | (() => T[]) filename*: string formats?: ("csv" | "json")[] columns?: ExportColumn[] csvDelimiter?: " csvBOM?: boolean className?: string ``` ## bpm.fab @component bpm.fab @description Bouton d'action flottant (Floating Action Button) positionné en coin d'écran pour action principale. @example bpm.fab({ icon: , label: "Nouveau", onClick: create, position: "bottom-right" }) @param {object} props @param {ReactNode} [props.icon] - Icône affichée (défaut: +). Optionnel. @param {string} [props.label] - Texte pour titre/aria-label. Optionnel. @param {function} [props.onClick] - Callback au clic. Optionnel. @param {"bottom-right"|"bottom-left"|"top-right"|"top-left"} [props.position="bottom-right"] - Position. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.button, bpm.iconButton @parent bpm.page, bpm.pageLayout @forbidden Plus d'une action principale — utiliser bpm.button dans une barre @semantic role=action frame=event status=proposed @guidance Action primaire unique et récurrente d'un écran, accessible en permanence (créer, ajouter). Associer : bpm.modal, bpm.crud, bpm.toast. Éviter : Actions secondaires ou multiples (bpm.button) ; écrans sans action dominante. ``` icon?: React.ReactNode label?: string onClick?: () => void position?: "bottom-right" | "bottom-left" | "top-right" | "top-left" className?: string ``` ## bpm.filePreview @component bpm.filePreview @description Prévisualiseur de fichiers (images, PDF, texte/code) avec inférence MIME et bouton téléchargement. @example bpm.filePreview({ url: "/files/doc.pdf", filename: "doc.pdf", showDownload: true }) @param {object} props @param {string} props.url - URL du fichier. Obligatoire. @param {string} props.filename - Nom du fichier. Obligatoire. @param {string} [props.mimeType] - Type MIME (auto-inféré si absent). Optionnel. @param {string|number} [props.height=400] - Hauteur de la prévisualisation. Optionnel. @param {boolean} [props.showDownload=true] - Affiche le lien de téléchargement. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @props - url (string, obligatoire) — URL du fichier à prévisualiser. - filename (string, obligatoire) — Nom du fichier affiché. - mimeType (string, optionnel) — Type MIME (auto-inféré depuis l'extension sinon). - height (string|number, optionnel) — Hauteur de l'aperçu. Default: 400. - showDownload (boolean, optionnel) — Affiche le bouton de téléchargement. Default: true. - className (string, optionnel) — Classes CSS additionnelles. - file_url / file_name / mime_type / show_download / class_name — Alias snake_case (API Python), normalisés en interne. @associated bpm.fileUploader, bpm.codeBlock @parent bpm.card, bpm.modal, bpm.masterDetail @forbidden aucun @semantic role=affichage frame=entity status=proposed @guidance Aperçu adaptatif d'un fichier selon son type (image, PDF, texte/code) : vérification avant/après upload. Associer : bpm.fileUploader, bpm.drawer, bpm.labelValue. Éviter : Type connu et unique (bpm.image, bpm.pdfViewer, bpm.codeBlock directement). ``` url*: string filename*: string mimeType?: string height?: string | number showDownload?: boolean className?: string file_url?: string — Props snake_case (API Python) — normalisées en interne file_name?: string mime_type?: string show_download?: boolean class_name?: string ``` ## bpm.fileUploader @component bpm.fileUploader @description Bouton de téléversement de fichiers avec filtrage par type MIME et taille maximale. @example bpm.fileUploader({ accept: "image/*", multiple: true, maxSizeBytes: 5000000, onFiles: handleFiles }) @param {object} props @param {string} [props.accept] - Types MIME acceptés (ex: "image/*", ".pdf"). Optionnel. @param {boolean} [props.multiple=false] - Autorise la sélection multiple. Optionnel. @param {number} [props.maxSizeBytes] - Taille maximale par fichier en octets. Optionnel. @param {function} [props.onFiles] - Callback avec les fichiers sélectionnés. Optionnel. @param {boolean} [props.disabled=false] - Désactive le bouton. Optionnel. @param {string} [props.label="Choisir un fichier"] - Texte du bouton. Optionnel. @parent bpm.form @associated bpm.filePreview, bpm.button @forbidden aucun @semantic role=saisie frame=entity status=proposed @guidance Joindre un ou plusieurs fichiers à une entité (pièce jointe, justificatif, import). Associer : bpm.filePreview, bpm.wizardForm. Éviter : Saisie de texte structuré (bpm.jsonEditor) ; prévisualisation (bpm.filePreview). ``` accept?: string multiple?: boolean maxSizeBytes?: number onFiles?: (files: File[]) => void disabled?: boolean label?: string ``` ## bpm.filterPanel @component bpm.filterPanel @description Panneau de filtres dynamiques (select, multiselect, daterange, text, toggle) avec réinitialisation. @example bpm.filterPanel({ filters: [...], values: { status: "active" }, onChange: handleChange, onReset: reset }) @param {object} props @param {FilterConfig[]} props.filters - Configuration des filtres {key, label, type, options?}. Obligatoire. @param {Record} [props.values={}] - Valeurs courantes des filtres. Optionnel. @param {function} props.onChange - Callback (key, value). Obligatoire. @param {function} props.onReset - Callback de réinitialisation. Obligatoire. @param {"horizontal"|"vertical"} [props.orientation="horizontal"] - Disposition. Optionnel. @param {boolean} [props.collapsible=false] - Panneau repliable avec badge. Optionnel. @associated bpm.table, bpm.dataExplorer, bpm.chip @parent bpm.drawer, bpm.card, bpm.dataExplorer @forbidden aucun @semantic role=saisie frame=section status=proposed @guidance Restreindre une collection selon plusieurs critères typés (select, multiselect, daterange, text, toggle). Associer : bpm.table, bpm.dataExplorer, bpm.chip, bpm.pagination. Éviter : Critère unique (un bpm.selectbox suffit) ou recherche plein-texte seule (bpm.input). ``` filters*: FilterConfig[] — Liste des filtres à afficher. values?: Record — Valeurs courantes (clé = filter.key). onChange*: (key: string, value: unknown) => void — Callback à chaque changement d'un filtre. onReset*: () => void — Callback réinitialisation. orientation?: "horizontal" | "vertical" — Disposition : horizontal (flex row) ou vertical (colonne 240px). collapsible?: boolean — Afficher un bouton pour replier le panneau (avec badge si filtres actifs). ``` ## bpm.flowDiagram @component bpm.flowDiagram @description Diagramme d'états et transitions SVG avec états colorés et arcs cliquables depuis l'état courant. @example bpm.flowDiagram({ states: [...], transitions: [...], currentState: "pending", onTransition: handleTransition }) @param {object} props @param {FlowDiagramState[]} props.states - Liste des états {value, label, color?, terminal?}. Obligatoire. @param {FlowDiagramTransition[]} props.transitions - Transitions {from, to, label}. Obligatoire. @param {string} [props.currentState] - État actif (surligné). Optionnel. @param {function} [props.onTransition] - Callback (from, to). Optionnel. @param {"horizontal"|"vertical"} [props.direction="horizontal"] - Direction du diagramme. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.decisionTree, bpm.stepper, bpm.timeline @parent bpm.card, bpm.container @forbidden Étapes linéaires — utiliser bpm.stepper @semantic role=affichage frame=workflow status=proposed @guidance Visualiser un processus : états et transitions (miroir du Workflow Ω), avec état courant éventuel. Associer : bpm.statusTracker, bpm.badge, bpm.card. Éviter : Progression personnelle dans un parcours (bpm.stepper) ou hiérarchie (bpm.orgChart, bpm.treeview). ``` states*: FlowDiagramState[] transitions*: FlowDiagramTransition[] currentState?: string onTransition?: (from: string, to: string) => void direction?: "horizontal" | "vertical" className?: string ``` ## bpm.free Composant bpm.free — voir @blueprint-modular/core ou BPM_API.md. ``` ``` ## bpm.funnelChart @component bpm.funnelChart @description Graphique en entonnoir pour visualiser les étapes d'un processus de conversion avec pourcentages. @example bpm.funnelChart({ stages: [{ label: "Visiteurs", value: 1000 }, { label: "Leads", value: 200 }], showPercentage: true }) @param {object} props @param {FunnelStage[]} props.stages - Étapes {label, value}. Obligatoire. @param {boolean} [props.showPercentage=false] - Affiche les pourcentages. Optionnel. @param {boolean} [props.horizontal=false] - Orientation horizontale. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.barChart, bpm.metric @semantic role=indicateur frame=kpi type=taux,compte direction=hausse=bon temporalite=instantane status=proposed @guidance Conversion étape par étape d'un tunnel : volume restant et taux de passage entre phases (acquisition, activation, achat). Associer : bpm.metric, bpm.statusTracker, bpm.caption. Éviter : Étapes d'un parcours sans déperdition mesurée (bpm.stepper) ou comparaison catégorielle simple (bpm.barChart). ``` stages*: FunnelStage[] showPercentage?: boolean horizontal?: boolean className?: string ``` ## bpm.gantt @component bpm.gantt @description Diagramme de Gantt avec tâches, dépendances, groupes et ligne du jour. @example bpm.gantt({ tasks: [...], viewMode: "week", onTaskClick: handleClick, showDependencies: true }) @param {object} props @param {GanttTask[]} props.tasks - Tâches {id, label, start, end, progress?, color?, dependencies?, group?}. Obligatoire. @param {"day"|"week"|"month"} props.viewMode - Mode d'affichage temporel. Obligatoire. @param {function} props.onTaskClick - Callback au clic sur une tâche. Obligatoire. @param {boolean} [props.showDependencies=true] - Affiche les flèches de dépendance. Optionnel. @param {boolean} [props.todayLine=true] - Affiche la ligne du jour. Optionnel. @associated bpm.timeline, bpm.table @semantic role=affichage frame=workflow status=needs-curation @guidance Planifier et suivre des tâches datées avec dépendances et jalons sur un axe temporel : qui fait quoi, quand, dans quel ordre. Associer : bpm.statusTracker, bpm.timeline, bpm.badge. Éviter : Historique d'événements passés en lecture seule (bpm.timeline) ou agenda d'événements ponctuels (bpm.scheduler). ``` tasks*: GanttTask[] viewMode*: "day" | "week" | "month" onTaskClick*: (task: GanttTask) => void showDependencies?: boolean todayLine?: boolean ``` ## bpm.geofence @component bpm.geofence @description Éditeur de zones géographiques sur carte avec polygones cliquables pour définir des périmètres. @example bpm.geofence({ zones: [...], center: [48.85, 2.35], onZonesChange: setZones }) @param {object} props @param {GeofenceZone[]} props.zones - Liste des zones {id, name?, positions, color?}. Obligatoire. @param {function} [props.onZonesChange] - Callback avec les zones modifiées. Optionnel. @param {[number, number]} props.center - Centre de la carte [lat, lng]. Obligatoire. @param {number} [props.zoom=14] - Niveau de zoom initial. Optionnel. @param {number|string} [props.height=400] - Hauteur de la carte. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.mapView, bpm.gps @parent bpm.card, bpm.modal, bpm.container @forbidden aucun ``` zones*: GeofenceZone[] onZonesChange?: (next: GeofenceZone[]) => void center*: [number, number] zoom?: number height?: number | string className?: string ``` ## bpm.gps @component bpm.gps @description Composant de géolocalisation avec carte Leaflet : affiche la position courante de l'utilisateur (mode `display`) ou permet de sélectionner un point sur la carte (mode `picker`). @example // Mode display : récupération et affichage de la position du navigateur bpm.gps({ label: "Ma position", onLocation: ({ lat, lng, accuracy }) => console.log(lat, lng, accuracy), }) @example // Mode picker : sélection contrôlée d'un point sur la carte const [point, setPoint] = useState<{ lat: number; lng: number } | null>(null); bpm.gps({ mode: "picker", value: point, onChange: setPoint, height: 400, }) @param {object} props @param {string} [props.label] - Titre affiché au-dessus du bloc. Optionnel. @param {boolean} [props.showMap=true] - Affiche la carte Leaflet sous les contrôles. Optionnel. @param {function} [props.onLocation] - Callback appelé en mode `display` quand la position du navigateur est obtenue. Reçoit `{ lat, lng, accuracy }`. Optionnel. @param {number} [props.height=300] - Hauteur de la carte en pixels. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles appliquées au conteneur racine. Optionnel. @param {"display"|"picker"} [props.mode="display"] - Mode du composant : `display` pour afficher la position courante, `picker` pour sélectionner un point. Optionnel. @param {{lat:number,lng:number}|null} [props.value=null] - Position courante en mode `picker` (composant contrôlé). Optionnel. @param {function} [props.onChange] - Callback appelé en mode `picker` à chaque clic sur la carte ou déplacement du marqueur. Reçoit `{ lat, lng }`. Optionnel. @note SSR-safe : la carte Leaflet est chargée dynamiquement avec `ssr: false`. L'accès à `navigator.geolocation` est encapsulé dans un handler utilisateur, jamais exécuté pendant le rendu. @note Permission requise : le navigateur demande l'autorisation à l'utilisateur lors du premier clic sur « Localiser ». En cas de refus (code 1), le statut passe à `error` avec le message « Autorisation refusée ». @parent bpm.card, bpm.panel, bpm.modal @associated bpm.mapView, bpm.geofence, bpm.routePlanner, bpm.addressInput @semantic role=saisie frame=entity status=proposed @guidance Saisir ou afficher une position GPS (carte + picker) : géolocalisation d'une entité, pointage terrain. Associer : bpm.map, bpm.labelValue, bpm.wizardForm. Éviter : Pure consultation cartographique multi-points (bpm.map). ``` label?: string — Titre affiché au-dessus du bloc. showMap?: boolean — Afficher une carte Leaflet. Default: true. onLocation?: (coords: { lat: number — Callback appelé quand la position est obtenue (mode display). height?: number — Hauteur de la carte en px. Default: 300. className?: string — Classes CSS additionnelles. mode?: "display" | "picker" — Mode : 'display' = affichage position, 'picker' = sélection d'un point sur la carte. Default: 'display'. value?: { lat: number — Position courante (mode picker). onChange?: (coords: { lat: number — Callback à chaque déplacement du marker ou clic sur la carte (mode picker). ``` ## bpm.grid @component bpm.grid @description Grille responsive pour aligner des cartes, métriques ou champs (layout dashboard). @example bpm.grid({ cols: 3, gap: 16, children: <> ... }) @props - cols (number | object, optionnel) — Nombre de colonnes ou breakpoints. Default: 1. - gap (number | string, optionnel) — Espacement entre cellules. Default: '1rem'. - children (ReactNode, optionnel) — Contenu des cellules. - className (string, optionnel) — Classes CSS. @usage Dashboard KPIs, grille de cartes produit, formulaire multi-colonnes. @context PARENT: bpm.panel | bpm.tabs (contenu onglet) | page directe. ASSOCIATED: bpm.metric, bpm.card, bpm.column. FORBIDDEN: aucun. @semantic role=conteneur frame=section status=proposed @guidance Disposer des éléments homogènes en grille responsive (cartes, métriques, vignettes). Associer : bpm.card, bpm.metric, bpm.image. Éviter : Colonnes de contenus hétérogènes (bpm.column) ou données tabulaires (bpm.table). ``` cols?: number | { xs?: number gap?: number | string className?: string children?: React.ReactNode ``` ## bpm.groupedList @component bpm.groupedList @description Liste générique avec regroupement automatique par clé, en-têtes de groupe personnalisables et sections repliables. @example bpm.groupedList({ items: users, groupBy: "department", renderItem: (u) => {u.name}, collapsible: true }) @param {object} props @param {T[]} props.items - Tableau d'éléments à grouper. Obligatoire. @param {keyof T} props.groupBy - Clé de regroupement. Obligatoire. @param {function} props.renderItem - Fonction de rendu pour chaque élément. Obligatoire. @param {function} [props.renderGroupHeader] - Rendu personnalisé de l'en-tête de groupe. Optionnel. @param {"asc"|"desc"} [props.sortGroups="asc"] - Ordre de tri des groupes. Optionnel. @param {boolean} [props.collapsible=false] - Permet de replier les groupes. Optionnel. @param {boolean} [props.defaultCollapsed=false] - Groupes repliés par défaut. Optionnel. @associated bpm.list, bpm.accordion, bpm.dataList ``` items*: T[] groupBy*: keyof T renderItem*: (item: T, index: number) => React.ReactNode renderGroupHeader?: (key: string, count: number) => React.ReactNode sortGroups?: "asc" | "desc" collapsible?: boolean defaultCollapsed?: boolean ``` ## bpm.heatmap @component bpm.heatmap @description Grille de valeurs numériques avec dégradé de couleur, infobulle au survol et clic optionnel sur cellule. @example bpm.heatmap({ data: [[1,2],[3,4]], xLabels: ["A","B"], yLabels: ["X","Y"], colorScale: { min: "#fff", max: "#f00" } }) @param {object} props @param {number[][]} props.data - Matrice 2D de valeurs numériques. Obligatoire. @param {string[]} props.xLabels - Libellés des colonnes. Obligatoire. @param {string[]} props.yLabels - Libellés des lignes. Obligatoire. @param {{ min: string; max: string }} props.colorScale - Couleurs min/max du dégradé. Obligatoire. @param {number} [props.valueMin] - Valeur minimale pour l'échelle. Optionnel, calculé automatiquement. @param {number} [props.valueMax] - Valeur maximale pour l'échelle. Optionnel, calculé automatiquement. @param {boolean} [props.showValues=false] - Affiche les valeurs dans les cellules. Optionnel. @param {function} [props.onCellClick] - Callback au clic sur une cellule (row, col, value). Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : chaque cellule est jugée vs le repère (liseré coloré sur les écarts, anomalies >2σ — comparisonFrame ou matrice — soulignées, infobulle enrichie du verdict). Optionnel. @semantic role=indicateur frame=kpi type=distribution,compte direction=contextuel temporalite=instantane status=proposed @guidance Intensité d'une mesure sur deux dimensions catégorielles : repérer concentrations, creux et points chauds dans une matrice. Associer : bpm.metric, bpm.caption, bpm.filterPanel. Éviter : Comparaison sur une seule dimension (bpm.barChart) ou évolution temporelle continue (bpm.lineChart). ``` data*: number[][] xLabels*: string[] yLabels*: string[] colorScale*: { min: string valueMin?: number valueMax?: number showValues?: boolean onCellClick?: (row: number, col: number, value: number) => void className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : chaque cellule est jugée par interpret — liseré coloré par verdict (hors zone neutre), data-judgment par cellule, infobulle enrichie. Anomalie >2σ évaluée contre comparisonFrame ou, à défaut, la matrice entière. Additif : sans context, rendu inchangé. ``` ## bpm.highlightBox @component bpm.highlightBox @description Bloc de mise en valeur avec barre latérale colorée, numéro, titre et sections RTB/Cible optionnelles. @example bpm.highlightBox({ value: 1, label: "DAILY", title: "Objectif quotidien", rtbPoints: ["Point 1", "Point 2"] }) @param {object} props @param {number} props.value - Numéro affiché dans la barre gauche. Obligatoire. @param {string} props.label - Texte sous le numéro (ex: "DAILY"). Obligatoire. @param {string} props.title - Titre principal du contenu. Obligatoire. @param {string} [props.momentDescription] - Description "Moment" affichée en italique. Optionnel. @param {string[]} [props.rtbPoints] - Points RTB séparés par "·". Optionnel. @param {string|string[]} [props.targetPoints] - Points Cible (chaîne ou liste). Optionnel. @param {string} [props.barColor="#212121"] - Couleur de la barre latérale. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.grid, bpm.column, bpm.container @associated bpm.metric, bpm.card @forbidden Donnée chiffrée temps réel — utiliser bpm.metric @semantic role=conteneur frame=section status=proposed @guidance Mise en avant éditoriale structurée et numérotée (titre, moment, RTB, cible) — argumentaire ou storytelling. Associer : bpm.title2, bpm.text. Éviter : Contenu applicatif courant (bpm.card) ou alerte (bpm.panel). ``` value*: number — Numéro affiché dans la barre gauche (ex. 1) label*: string — Texte sous le numéro dans la barre (ex. "DAILY") title*: string — Titre principal du contenu momentDescription?: string | null — Description "Moment" (affichée en italique, gris) rtbPoints?: string[] | null — Points RTB (affichés séparés par ·) targetPoints?: string | string[] | null — Points Cible (chaîne ou liste) barColor?: string | null — Couleur de la barre latérale (hex, rgb ou nom CSS). Par défaut : noir (#212121). className?: string ``` ## bpm.html @component bpm.html @description Affiche du HTML brut. À utiliser uniquement avec du contenu de confiance ou préalablement sanitisé. @example bpm.html({ html: "

Contenu HTML

" }) @param {object} props @param {string} props.html - Contenu HTML brut à afficher. Obligatoire. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {React.CSSProperties} [props.style={}] - Styles inline additionnels. Optionnel. @parent bpm.card, bpm.container @associated bpm.markdown @forbidden Contenu non sanitisé — risque XSS ; préférer bpm.markdown @semantic role=affichage frame=section status=proposed @guidance Intégrer un contenu HTML externe isolé (iframe) : widget tiers, page embarquée. Associer : bpm.card, bpm.container. Éviter : Contenu rédactionnel (bpm.markdown) ou code à montrer (bpm.codeBlock) ; jamais de HTML non fiable sans sandbox. ``` html*: string — HTML brut à afficher (équivalent st.html). À n'utiliser qu'avec du contenu de confiance ou sanitized. className?: string style?: React.CSSProperties ``` ## bpm.image @component bpm.image @description Affiche une image avec chargement différé et options de dimensionnement/ajustement. @example bpm.image({ src: "/photo.jpg", alt: "Photo de profil", width: 200, fit: "cover" }) @param {object} props @param {string} props.src - URL de l'image. Obligatoire. @param {string} props.alt - Texte alternatif pour l'accessibilité. Obligatoire. @param {string} [props.title] - Titre affiché au survol. Optionnel. @param {number|string} [props.width] - Largeur en pixels ou CSS. Optionnel. @param {number|string} [props.height] - Hauteur en pixels ou CSS. Optionnel. @param {"contain"|"cover"|"fill"|"none"} [props.fit="contain"] - Mode d'ajustement object-fit. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.card, bpm.grid, bpm.container @associated bpm.avatar, bpm.filePreview @forbidden Contenu HTML/vidéo — utiliser bpm.html / bpm.video @semantic role=affichage frame=entity status=proposed @guidance Afficher une image avec alt et cadrage maîtrisés : photo d'entité, illustration. Associer : bpm.card, bpm.grid, bpm.caption. Éviter : Identité d'un acteur (bpm.avatar) ou aperçu de fichier quelconque (bpm.filePreview). ``` src*: string alt*: string title?: string width?: number | string height?: number | string fit?: "contain" | "cover" | "fill" | "none" className?: string ``` ## bpm.inlineEdit @component bpm.inlineEdit @description Champ éditable au clic : texte, nombre ou select. Validation par Entrée/blur, annulation par Échap. @example bpm.inlineEdit({ value: "Mon texte", onSave: (v) => console.log(v), type: "text" }) @param {object} props @param {string|number} props.value - Valeur actuelle affichée. Obligatoire. @param {function} props.onSave - Callback appelé à la sauvegarde avec la nouvelle valeur. Obligatoire. @param {"text"|"number"|"select"} [props.type="text"] - Type d'édition. Optionnel. @param {{ value: string; label: string }[]} [props.options=[]] - Options pour le type select. Optionnel. @param {string} [props.placeholder=""] - Placeholder si valeur vide. Optionnel. @param {boolean} [props.disabled=false] - Désactive l'édition. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.table, bpm.labelValue ``` value*: string | number onSave*: (next: string | number) => void | Promise type?: InlineEditType options?: { value: string placeholder?: string disabled?: boolean className?: string ``` ## bpm.input @component bpm.input @description Champ de saisie texte avec label optionnel. Supporte différents types HTML (text, email, password, etc.). @example bpm.input({ label: "Email", value: email, onChange: setEmail, type: "email", placeholder: "exemple@mail.com" }) @param {object} props @param {string} [props.label] - Label affiché au-dessus du champ. Optionnel. @param {string} [props.value=""] - Valeur contrôlée. Optionnel. @param {function} [props.onChange] - Callback recevant la valeur string directement. Optionnel. @param {string} [props.placeholder=""] - Texte indicatif. Optionnel. @param {"text"|"email"|"password"|"number"|"search"|"date"} [props.type="text"] - Type HTML du champ. Optionnel. @param {boolean} [props.disabled=false] - Désactive le champ. Optionnel. @param {string|null} [props.error=null] - Message d'erreur du champ : contour rouge + message sous le champ. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.modal, bpm.panel, bpm.card @associated bpm.button, bpm.selectbox @semantic role=saisie frame=entity status=proposed @guidance Saisir un champ texte court d'une entité (nom, référence, email). Associer : bpm.wizardForm, bpm.button, bpm.autocomplete. Éviter : Texte long multiligne (bpm.textarea), nombre (bpm.numberInput), recherche d'entité liée (bpm.autocomplete). ``` label?: string — Label affiché au-dessus du champ. value?: string — Valeur contrôlée. onChange?: (value: string) => void — Callback — reçoit la valeur string, pas un Event. Ex: (v) => setValue(v) placeholder?: string type?: "text" | "email" | "password" | "number" | "search" | "date" — Type HTML. Default: 'text'. disabled?: boolean — Désactive le champ. error?: string | null — Message d'erreur du CHAMP : contour rouge + message sous le champ (role=alert, aria-invalid). Additif : défaut null = rendu inchangé. className?: string ``` ## bpm.invoiceTemplate @component bpm.invoiceTemplate @description Modèle de facture A4 prêt pour impression avec lignes, TVA et totaux calculés automatiquement. @example bpm.invoiceTemplate({ issuer: "Ma Société", client: "Client SA", lines: [{ label: "Service", qty: 2, unitPrice: 100 }] }) @param {object} props @param {string} [props.title="Facture"] - Titre du document. Optionnel. @param {string} props.issuer - Informations de l'émetteur. Obligatoire. @param {string} props.client - Informations du client. Obligatoire. @param {InvoiceLine[]} props.lines - Lignes de facturation (label, qty, unitPrice). Obligatoire. @param {number} [props.taxRate=0.2] - Taux de TVA (0.2 = 20%). Optionnel. @param {string} [props.invoiceNo="—"] - Numéro de facture. Optionnel. @param {string} [props.date] - Date de la facture (YYYY-MM-DD). Optionnel, défaut aujourd'hui. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.printLayout ``` title?: string issuer*: string client*: string lines*: InvoiceLine[] taxRate?: number invoiceNo?: string date?: string className?: string ``` ## bpm.jsonEditor @component bpm.jsonEditor @description Éditeur JSON avec validation en temps réel, formatage automatique au blur et indicateur de validité. @example bpm.jsonEditor({ value: '{"key": "value"}', onChange: (v, valid) => console.log(v, valid) }) @param {object} props @param {string} props.value - Contenu JSON sous forme de chaîne. Obligatoire. @param {function} props.onChange - Callback (value, isValid) appelé à chaque modification. Obligatoire. @param {boolean} [props.readOnly=false] - Mode lecture seule (affiche un CodeBlock). Optionnel. @param {string|number} [props.height=300] - Hauteur du textarea. Optionnel. @param {boolean} [props.showValidation=true] - Affiche l'indicateur de validité. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.jsonViewer, bpm.codeBlock @parent bpm.card, bpm.modal, bpm.drawer @forbidden Affichage non éditable — utiliser bpm.jsonViewer @semantic role=saisie frame=entity status=proposed @guidance Éditer une structure JSON avec validation et formatage : configuration, payload, Field json. Associer : bpm.jsonViewer, bpm.button, bpm.message. Éviter : Lecture seule (bpm.jsonViewer) ou code non-JSON (bpm.codeEditor). ``` value*: string onChange*: (value: string, isValid: boolean) => void readOnly?: boolean height?: string | number showValidation?: boolean className?: string ``` ## bpm.jsonViewer @component bpm.jsonViewer @description Affiche un objet JSON de façon repliable et lisible pour debug ou inspection de réponses API. @example bpm.jsonViewer({ data: { contrat: "Premium", ca: 125000 }, defaultExpandedLevel: 1 }) @props - data (unknown) — Objet ou chaîne JSON à afficher. - defaultExpandedLevel (number, optionnel) — Niveaux ouverts par défaut (0 = tout replié). Default: 1. - maxHeight (number, optionnel) — Hauteur max en px avec scroll. Default: 400. - className (string, optionnel) — Classes CSS. @usage Inspection de payload API, logs structurés, configuration. @context PARENT: bpm.panel | bpm.modal. ASSOCIATED: bpm.codeBlock, bpm.message. FORBIDDEN: aucun. @semantic role=affichage frame=entity status=proposed @guidance Inspection en lecture d'une structure de données brute (payload, configuration, réponse d'API). Associer : bpm.expander, bpm.codeBlock, bpm.drawer. Éviter : Édition de JSON (bpm.jsonEditor) ou restitution métier mise en forme (bpm.table, bpm.labelValue). ``` data*: unknown — Objet ou chaîne JSON à afficher. defaultExpandedLevel?: number — Nombre de niveaux ouverts par défaut (0 = tout replié). maxHeight?: number — Hauteur max en px pour scroll. className?: string ``` ## bpm.labelValue @component bpm.labelValue @description Affiche une paire label/valeur avec options de style, orientation et bouton copier. @example bpm.labelValue({ label: "Référence", value: "REF-001", copyable: true, valueStyle: "bold" }) @param {object} props @param {string} props.label - Libellé affiché en majuscules. Obligatoire. @param {string|number|React.ReactNode} props.value - Valeur à afficher. Obligatoire. @param {"horizontal"|"vertical"} [props.orientation="horizontal"] - Disposition label/valeur. Optionnel. @param {"sm"|"md"|"lg"} [props.size="md"] - Taille du texte. Optionnel. @param {"default"|"bold"|"accent"|"muted"} [props.valueStyle="default"] - Style de la valeur. Optionnel. @param {boolean} [props.copyable=false] - Affiche un bouton pour copier la valeur. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {TrajectoryPoint[]} [props.trajectory] - Trajectoire v(t) de la valeur, jugée si context fourni. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : la valeur est colorée et un verdict écart/tendance est révélé. Optionnel. @parent bpm.card, bpm.panel @associated bpm.metric, bpm.inlineEdit @forbidden Valeur chiffrée à juger — utiliser bpm.metric @semantic role=affichage frame=entity status=proposed @guidance Énoncer un fait : un champ d'entité et sa valeur (référence, date, montant) sans jugement porté. Associer : bpm.card, bpm.masterDetail, bpm.drawer. Éviter : Mesure qui appelle un jugement — delta, cible, tendance (bpm.metric). ``` label*: string value*: string | number | React.ReactNode orientation?: "horizontal" | "vertical" size?: "sm" | "md" | "lg" valueStyle?: "default" | "bold" | "accent" | "muted" copyable?: boolean className?: string trajectory?: TrajectoryPoint[] — Trajectoire v(t) [{t, v}] de la mesure (la valeur affichée reste value) — jugée si context est fourni. context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : la valeur prend la couleur du verdict et un suffixe écart/tendance role=status est révélé. Additif : sans context, rendu inchangé. ``` ## bpm.lineChart @component bpm.lineChart @description Graphique en ligne SVG simple et responsive pour afficher une série de données. @example bpm.lineChart({ data: [{ x: 0, y: 10 }, { x: 1, y: 25 }], color: "#3b82f6" }) @param {object} props @param {LineChartDatum[]} props.data - Tableau de points { x, y }. Obligatoire. @param {number} [props.width=400] - Largeur du SVG. Optionnel. @param {number} [props.height=200] - Hauteur du SVG. Optionnel. @param {string} [props.color="var(--bpm-accent)"] - Couleur de la ligne. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : ligne de repère pointillée, couleur de série jugée, aria-label descriptif. Optionnel. @associated bpm.areaChart, bpm.barChart, bpm.scatterChart @parent bpm.card, bpm.grid, bpm.tableauxDeBord @forbidden Catégories discrètes — utiliser bpm.barChart @semantic role=indicateur frame=kpi type=tendance direction=contextuel temporalite=serie status=proposed @guidance Évolution continue d'une mesure dans le temps : tendance, saisonnalité, rupture. Associer : bpm.metric, bpm.dateRangePicker, bpm.caption. Éviter : Comparaison de catégories sans ordre (bpm.barChart) ou corrélation entre deux mesures (bpm.scatterChart). Règle apps générées : bpm.plotlyChart. ``` data*: LineChartDatum[] width?: number height?: number color?: string className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : la série (lue comme trajectoire v(t), t = x) est jugée par interpret — repère tracé en pointillé, couleur de ligne selon le verdict, aria-label. Additif : sans context, rendu inchangé. ``` ## bpm.liveChart @component bpm.liveChart @description Graphique temps réel avec fenêtre glissante, seuils en pointillés et rafraîchissement automatique. @example bpm.liveChart({ data: [{ timestamp: Date.now(), value: 42 }], bufferDuration: 60, refreshInterval: 1000 }) @param {object} props @param {LiveChartDatum[]} props.data - Points { timestamp, value }. Obligatoire. @param {number} [props.bufferDuration=120] - Durée de la fenêtre en secondes. Optionnel. @param {{ value: number; label?: string }[]} [props.thresholds=[]] - Lignes de seuil horizontales. Optionnel. @param {number} [props.refreshInterval] - Intervalle de rafraîchissement en ms. Optionnel. @param {number} [props.width=400] - Largeur du graphique. Optionnel. @param {number} [props.height=180] - Hauteur du graphique. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : courbe colorée par le verdict, repère pointillé, verdict sous le graphique. Optionnel. @associated bpm.liveGauge, bpm.lineChart, bpm.sparkline ``` data*: LiveChartDatum[] bufferDuration?: number thresholds?: { value: number refreshInterval?: number width?: number height?: number className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : la fenêtre courante est jugée par interpret (couleur de courbe selon le verdict, repère pointillé, verdict écart/tendance sous le graphique). Additif : sans context, rendu inchangé. ``` ## bpm.liveGauge @component bpm.liveGauge @description Jauge demi-cercle avec aiguille et zones colorées (normal/avertissement/critique). @example bpm.liveGauge({ value: 75, min: 0, max: 100, warningAbove: 70, criticalAbove: 90, label: "CPU" }) @param {object} props @param {number} props.value - Valeur actuelle affichée. Obligatoire. @param {number} [props.min=0] - Valeur minimale de l'échelle. Optionnel. @param {number} [props.max=100] - Valeur maximale de l'échelle. Optionnel. @param {number} [props.warningAbove] - Seuil d'avertissement (zone jaune). Optionnel. @param {number} [props.criticalAbove] - Seuil critique (zone rouge). Optionnel. @param {"sm"|"md"|"lg"} [props.size="md"] - Taille de la jauge. Optionnel. @param {string} [props.label] - Libellé affiché sous la jauge. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : la valeur affichée prend la couleur du jugement, écart/tendance révélés sous la jauge. Optionnel. @associated bpm.liveChart, bpm.metric, bpm.progress ``` value*: number | TrajectoryPoint[] — Valeur actuelle, ou trajectoire v(t) [{t, v}] (l'aiguille pointe le dernier point ; tendance jugée si context fourni). min?: number max?: number warningAbove?: number criticalAbove?: number size?: LiveGaugeSize label?: string className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : interpret() colore la valeur et révèle écart au repère + tendance + anomalie sous la jauge. Additif : sans context, rendu inchangé. ``` ## bpm.loadingBar @component bpm.loadingBar @description Barre de progression horizontale (déterminée ou indéterminée) pour chargement de tâches. @example bpm.loadingBar({ variant: "sweep", value: 65, size: "default" }) @props - variant (string, optionnel) — Style (sweep, blocks, iso…). Default: 'sweep'. - value (number, optionnel) — 0–100 pour barre déterminée. Omit = indéterminé. - size ('thin' | 'default' | 'thick', optionnel) — Hauteur. Default: 'default'. - animated (boolean, optionnel) — Animation. Default: true. - className (string, optionnel) — Classes CSS. - aria-label (string, optionnel) — Accessibilité. @usage Import en cours, génération de rapport, upload fichier. @context PARENT: bpm.panel | page directe. ASSOCIATED: bpm.spinner, bpm.progress. FORBIDDEN: aucun. @semantic role=feedback frame=section status=proposed @guidance Chargement global de page ou de zone, avec variantes visuelles (sweep, blocks, iso…). Associer : bpm.pageLayout, bpm.skeleton. Éviter : Progression mesurable vers une borne (bpm.progress) ou attente locale (bpm.spinner). ``` variant?: LoadingBarVariant — Variant visuel (sweep, blocks, iso, stacked, arc, dots). value?: number — Pour les barres déterminées (ex. iso) : 0–100. Non fourni = indéterminé. size?: "thin" | "default" | "thick" — Hauteur : thin (6px), default (8px), thick (12px). animated?: boolean — Désactive l'animation (utile pour screenshots ou prefers-reduced-motion). className?: string ``` ## bpm.locationField @component bpm.locationField @description Champ de saisie d'un LIEU : recherche par adresse (géocodage Nominatim), tracé du contour sur la carte au clic, surface (ha) calculée automatiquement. Remplace toute saisie de latitude/longitude à la main. @example bpm.locationField({ value, onChange: setValue }) @param {object} props @param {LocationValue} [props.value] - Valeur contrôlée {address, lat, lng, polygon, surfaceHa}. Optionnel. @param {function} [props.onChange] - Callback à chaque modification. Optionnel. @param {[number, number]} [props.defaultCenter=[46.6,2.4]] - Centre initial si vide. Optionnel. @param {number|string} [props.height=360] - Hauteur de la carte. Optionnel. @param {string} [props.countryCodes="fr"] - Restriction pays du géocodage. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.mapView, bpm.geofence @parent bpm.form, bpm.card, bpm.modal, bpm.container ``` value?: LocationValue onChange?: (next: LocationValue) => void defaultCenter?: [number, number] height?: number | string countryCodes?: string className?: string ``` ## bpm.machineStatus @component bpm.machineStatus @description Carte d'état machine avec indicateur LED animé (clignotement en production ou défaut). @example bpm.machineStatus({ title: "Machine A", state: "running", detail: "Lot #1234" }) @param {object} props @param {string} props.title - Nom de la machine. Obligatoire. @param {"running"|"idle"|"fault"|"unknown"} props.state - État actuel. Obligatoire. @param {string} [props.detail] - Détail additionnel affiché sous l'état. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {number|TrajectoryPoint[]} [props.value] - Mesure de production associée (scalaire ou trajectoire v(t)), jugée si context fourni. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : verdict écart/tendance révélé sous l'état. Optionnel. @associated bpm.sensorGrid, bpm.liveGauge, bpm.statusBox ``` title*: string state*: MachineStatusState detail?: string className?: string value?: number | TrajectoryPoint[] — Mesure de production associée (cadence, TRS… ; scalaire ou trajectoire v(t) [{t,v}]) — jugée via interpret si context est fourni. context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : un verdict écart/tendance/anomalie est révélé sous l'état (role=status) et la bordure gauche prend la couleur du jugement. Additif : sans context, rendu inchangé. ``` ## bpm.map @component bpm.map @description Carte OpenStreetMap embarquée en iframe. Utiliser MapView pour des fonctionnalités interactives. @example bpm.map({ lat: 48.8566, lng: 2.3522, height: 300 }) @param {object} props @param {string} [props.iframeSrc] - URL iframe personnalisée. Optionnel. @param {number} [props.lat] - Latitude du centre. Optionnel. @param {number} [props.lng] - Longitude du centre. Optionnel. @param {number|string} [props.width="100%"] - Largeur. Optionnel. @param {number|string} [props.height=400] - Hauteur. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.mapView, bpm.gps @parent bpm.card, bpm.container, bpm.modal @forbidden aucun @semantic role=affichage frame=entity status=proposed @guidance Situer géographiquement des entités (adresses, positions) sur un fond de carte. Associer : bpm.labelValue, bpm.card, bpm.gps. Éviter : Sélection/saisie d'une position (bpm.gps) ou données non géographiques. ``` iframeSrc?: string lat?: number lng?: number width?: number | string height?: number | string className?: string ``` ## bpm.mapView @component bpm.mapView @description Carte Leaflet interactive avec marqueurs, polylignes, polygones et gestion des clics. @example bpm.mapView({ center: [48.8566, 2.3522], zoom: 13, markers: [{ position: [48.8566, 2.3522], label: "Paris" }] }) @param {object} props @param {[number, number]} props.center - Coordonnées [lat, lng] du centre. Obligatoire. @param {number} [props.zoom=13] - Niveau de zoom initial. Optionnel. @param {number|string} [props.height=320] - Hauteur de la carte. Optionnel. @param {MapMarker[]} [props.markers=[]] - Liste des marqueurs. Optionnel. @param {function} [props.onMarkerClick] - Callback au clic sur un marqueur. Optionnel. @param {string} [props.tileUrl] - URL du serveur de tuiles. Optionnel. @param {string} [props.tileAttribution] - Attribution du fournisseur de tuiles. Optionnel. @param {[number, number][][]} [props.polylines] - Lignes à tracer. Optionnel. @param {string} [props.polylineColor] - Couleur des polylignes. Optionnel. @param {MapPolygonSpec[]} [props.polygons] - Polygones à afficher. Optionnel. @param {MapOverlaySpec[]} [props.overlays] - Calques superposables (données app + WMS/tuiles externes), activables via un contrôle de couches, en transparence. Optionnel. @param {function} [props.onMapClick] - Callback au clic sur la carte. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.map, bpm.routePlanner, bpm.gps ``` center*: [number, number] zoom?: number height?: number | string markers?: MapMarker[] onMarkerClick?: (index: number, marker: MapMarker) => void tileUrl?: string tileAttribution?: string polylines?: [number, number][][] polylineColor?: string polygons?: MapPolygonSpec[] overlays?: MapOverlaySpec[] — Calques superposables (données app + WMS/tuiles externes), en transparence. onMapClick?: (latlng: [number, number]) => void className?: string ``` ## bpm.markdown @component bpm.markdown @description Affiche du contenu formaté en Markdown (titres, listes, gras, code) pour notices et documentation métier. @example bpm.markdown({ text: "## Procédure\n\n1. Valider le devis\n2. Envoyer au client." }) @props - text (string) — Contenu Markdown (utiliser `---` pour une ligne horizontale). - className (string, optionnel) — Classes CSS. @usage Notices, FAQ, procédures, documentation produit. @context PARENT: bpm.panel | bpm.card | bpm.tabs. ASSOCIATED: bpm.title, bpm.codeBlock. FORBIDDEN: aucun. @semantic role=affichage frame=section status=proposed @guidance Restituer un contenu riche rédigé (listes, liens, titres) de source maîtrisée : doc, note, réponse IA formatée. Associer : bpm.streamingText, bpm.card, bpm.codeBlock. Éviter : Texte brut court (bpm.text) ou HTML arbitraire (bpm.html). ``` text*: string — Contenu Markdown. Utilisez `---` sur une ligne pour une ligne horizontale (hr). className?: string ``` ## bpm.masterDetail @component bpm.masterDetail @description Liste à gauche et détail à droite ; sur mobile, le détail s’ouvre en plein cadre avec retour. Cycle de vie : liste et détail restent MONTÉS — l'état React est préservé. @example bpm.masterDetail({ items, columns: [{ key: "name", label: "Nom" }], renderDetail: (it) =>
{it.name}
, onSelect: setSel }) @props - items (T[], obligatoire) — Données de la liste. - columns (MasterDetailColumn[], obligatoire) — Colonnes de la liste de gauche. - renderDetail (function, obligatoire) — (item) => ReactElement, panneau de détail. - onSelect (function, obligatoire) — Callback (item) à la sélection. - selectedId (string, optionnel) — Id sélectionné (mode contrôlé). - idKey (string, optionnel) — Clé d’identité des items. Default: "id". - searchable (boolean, optionnel) — Active la barre de recherche. - emptyDetailMessage (string, optionnel) — Message quand rien n’est sélectionné. - splitRatio (number, optionnel) — Ratio largeur liste/détail. - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.page, bpm.pageLayout @associated bpm.table, bpm.drawer, bpm.filterPanel @forbidden Détail ponctuel — utiliser bpm.modal/drawer @semantic role=conteneur frame=entity status=proposed @guidance Parcourir une collection et consulter le détail de la sélection sans changer de page (liste + détail liés). Associer : bpm.table, bpm.labelValue, bpm.badge. Éviter : Colonnes indépendantes (bpm.column) ou gestion CRUD complète (bpm.crud). ``` items*: T[] columns*: MasterDetailColumn[] renderDetail*: (item: T) => React.ReactElement selectedId?: string onSelect*: (item: T) => void idKey?: string searchable?: boolean emptyDetailMessage?: string splitRatio?: number className?: string ``` ## bpm.message @component bpm.message @description Bandeau de message contextuel (succès, avertissement, erreur) pour retours utilisateur après action. @example bpm.message({ type: "success", children: "Devis enregistré et envoyé au client." }) @props - type ('info' | 'success' | 'warning' | 'error', optionnel) — Type de message. Default: 'info'. - children (ReactNode) — Texte du message. - className (string, optionnel) — Classes CSS. @usage Retour après enregistrement, validation formulaire, erreur API. @context PARENT: bpm.panel | bpm.modal | page directe. ASSOCIATED: bpm.button, bpm.input. FORBIDDEN: aucun. @semantic role=feedback frame=event status=proposed @guidance Réaction inline à une action ou un état : bandeau info/success/warning/error dans le flux de la page. Associer : bpm.button, bpm.wizardForm. Éviter : Notification éphémère hors flux (bpm.toast) ou encart durable (bpm.panel). ``` type?: MessageType children*: React.ReactNode className?: string ``` ## bpm.metric @component bpm.metric @description Affiche une métrique chiffrée avec label, valeur, variation delta et options de formatage (devise, locale). @example bpm.metric({ label: "Chiffre d'affaires", value: 125000, delta: "+12%", currency: "EUR" }) @param {object} props @param {string} props.label - Libellé de la métrique. Obligatoire. @param {string|number} props.value - Valeur principale. Obligatoire. @param {number|string} [props.delta] - Variation affichée (ex: "+12%"). Optionnel. @param {string} [props.name] - Nom pour référencer dans le chat IA. Optionnel. @param {"aucun"|"normal"|"inverse"} [props.deltaType="normal"] - Coloration du delta. Optionnel. @param {string} [props.help] - Texte d'aide au survol. Optionnel. @param {number} [props.deltaDecimals=0] - Décimales pour le delta. Optionnel. @param {string} [props.currency="EUR"] - Devise pour l'affichage. Optionnel. @param {string} [props.valueLocale] - Locale pour formatage (fr-FR, en-US). Optionnel. @param {number} [props.valueDecimals=0] - Décimales pour la valeur. Optionnel. @param {boolean} [props.valueGrouping=true] - Séparateur de milliers. Optionnel. @param {boolean} [props.border=true] - Affiche la bordure. Optionnel. @param {React.ReactNode} [props.icon] - Icône à gauche du label. Optionnel. @param {string} [props.subtext] - Texte contextuel sous la valeur. Optionnel. @param {string} [props.accentColor] - Couleur d'accent. Optionnel. @param {boolean} [props.compact=false] - Mode compact réduit. Optionnel. @param {boolean} [props.trackContext=false] - Expose au contexte IA. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement { reference, direction, comparisonFrame? } : révèle écart/tendance/anomalie via interpret. Optionnel. @parent bpm.metricRow, bpm.grid, bpm.card @associated bpm.badge, bpm.plotlyChart @semantic role=indicateur frame=kpi type=scalaire-kpi,monetaire,compte,taux direction=contextuel temporalite=instantane status=proposed @guidance KPI scalaire en tête de dashboard : une valeur qui porte un jugement (delta, repère via context, tendance via trajectoire). Associer : bpm.metricRow, bpm.lineChart, bpm.badge. Éviter : Valeur descriptive sans jugement (bpm.labelValue) ou liste de faits (bpm.table). ``` label*: string — Libellé affiché au-dessus de la valeur. value*: string | number | TrajectoryPoint[] — Valeur principale (string, number, ou trajectoire v(t) [{t, v}] — affiche le dernier point et révèle la tendance si context est fourni). delta?: number | string | null — Variation affichée. Format string (ex. "+12%") ou number. name?: string | null — Nom optionnel pour référencer la métrique dans le chat IA : $metric:name ou @name deltaType?: "aucun" | "normal" | "inverse" — Aucun = pas de couleur, normal = + vert / - rouge, inverse = + rouge / - vert help?: string | null deltaDecimals?: number currency?: string valueLocale?: MetricValueLocale — Locale pour formater value (et delta) quand ce sont des nombres. Ex. "fr-FR" (1 000,50), "en-US" (1,000.50). valueDecimals?: number — Nombre de décimales pour value (si value est un number et valueLocale est défini). valueGrouping?: boolean — Afficher le séparateur de milliers (true par défaut). false → 1000,50 au lieu de 1 000,50. border?: boolean — Afficher la bordure autour de la métrique (true par défaut). icon?: React.ReactNode | null — Icône distinctive (ex. lucide-react) affichée à gauche du label. subtext?: string | null — Micro-info contextuelle sous la métrique (gris clair). accentColor?: string | null — Couleur d'accent (bordure gauche ou fond icône). compact?: boolean — Mode compact : hauteur réduite (~80px), padding et typo plus serrés. trackContext?: boolean — Si true, expose cette métrique au contexte IA. context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : la métrique porte alors un jugement via interpret(value, context) — écart au repère, tendance (si trajectoire), anomalie — révélé sous la valeur. Additif : sans context, rendu inchangé. onClick?: (() => void) | null — Rend la carte CLIQUABLE — ex. « voir les factures impayées » depuis le KPI qui les compte. Ajoute le rôle bouton, le focus clavier et Entrée/Espace : une carte cliquable à la souris seulement serait inatteignable au clavier et muette pour un lecteur d'écran. Absent = rendu et sémantique inchangés. ``` INTERDIT : Carte cliquable : on n'ajoute JAMAIS le curseur seul. Une affordance visuelle ## bpm.metricRow @component bpm.metricRow @description Ligne horizontale de KPIs (bpm.metric) pour tableaux de bord et résumés chiffrés. @example bpm.metricRow({ children: <> {bpm.metric({ label: "CA", value: "142 500 €" })} {bpm.metric({ label: "Marge", value: "28%" })} }) @props - children (ReactNode) — Un ou plusieurs bpm.metric. - className (string, optionnel) — Classes CSS. @usage Dashboard, résumé commande, indicateurs ligne de production. @context PARENT: bpm.panel | bpm.tabs | page directe. ASSOCIATED: bpm.metric, bpm.grid. FORBIDDEN: div custom comme parent. @semantic role=conteneur frame=section status=proposed @guidance Aligner plusieurs KPI scalaires de même rang en tête de tableau de bord : une rangée de bpm.metric lus ensemble. Associer : bpm.metric, bpm.lineChart, bpm.card. Éviter : Une seule mesure (bpm.metric seul) ou des éléments hétérogènes de poids visuel inégal (bpm.grid, bpm.column). ``` children*: React.ReactNode className?: string ``` ## bpm.modal @component bpm.modal @description Fenêtre modale avec backdrop, fermeture Échap/clic extérieur. Pattern: {isOpen && bpm.modal({...})} @example bpm.modal({ isOpen: true, onClose: () => setOpen(false), title: "Confirmation", children:

Contenu

}) @param {object} props @param {boolean} props.isOpen - Contrôle l'affichage. Obligatoire. @param {function} props.onClose - Callback de fermeture. Obligatoire. @param {React.ReactNode} [props.title] - Titre de la modale. Optionnel. @param {React.ReactNode} props.children - Contenu. Obligatoire. @param {"small"|"medium"|"large"} [props.size="medium"] - Taille (400/600/800px). Optionnel. @param {boolean} [props.showCloseButton=true] - Affiche le bouton fermer. Optionnel. @associated bpm.button, bpm.input, bpm.selectbox, bpm.confirmModal @forbidden bpm.modal (pas d'imbrication) @semantic role=conteneur frame=section status=proposed @guidance Tâche focale qui interrompt le flux : création/édition courte, décision requise avant de continuer. Associer : bpm.input, bpm.button, bpm.wizardForm. Éviter : Confirmation destructive (bpm.confirmModal), consultation parallèle (bpm.drawer), contenu ancré (bpm.popover). ``` isOpen*: boolean — Contrôle l'affichage. PATTERN OBLIGATOIRE : {isOpen && bpm.modal({ isOpen:true, ... })} onClose*: () => void — Callback de fermeture — obligatoire. title?: React.ReactNode children*: React.ReactNode — Contenu du modal. size?: ModalSize — Largeur : small=400px, medium=600px, large=800px. showCloseButton?: boolean ``` ## bpm.modelSelector @component bpm.modelSelector @description Sélecteur de modèle IA avec dropdown groupé par fournisseur et affichage des capacités. @example bpm.modelSelector({ models: [{ id: "gpt-4", label: "GPT-4", provider: "OpenAI" }], selected: "gpt-4", onChange: setModel }) @param {object} props @param {ModelOption[]} props.models - Liste des modèles disponibles. Obligatoire. @param {string} props.selected - ID du modèle sélectionné. Obligatoire. @param {function} props.onChange - Callback au changement de sélection. Obligatoire. @param {boolean} [props.showCapabilities=true] - Affiche les capacités et fenêtre de contexte. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.chatInterface, bpm.promptInput @parent bpm.promptInput, bpm.chatInterface, bpm.card @forbidden Sélection générique — utiliser bpm.selectbox @semantic role=saisie frame=ai status=proposed @guidance Choisir le modèle IA (par fournisseur, capacités) qui exécutera la requête. Associer : bpm.chatInterface, bpm.promptInput. Éviter : Énumération métier quelconque (bpm.selectbox). ``` models*: ModelOption[] selected*: string onChange*: (modelId: string) => void showCapabilities?: boolean className?: string ``` ## bpm.nfcBadge @component bpm.nfcBadge @description Badge indicateur de statut NFC/scannable avec icône et variantes de couleur. @example bpm.nfcBadge({ label: "Actif", variant: "success" }) @param {object} props @param {string} [props.label="Scannable"] - Texte affiché. Optionnel. @param {"default"|"primary"|"success"} [props.variant="default"] - Variante de couleur. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.badge, bpm.qrCode, bpm.barcode @parent bpm.card, bpm.table @forbidden aucun @semantic role=affichage frame=connector status=needs-curation @guidance Représenter un badge/tag NFC et son état de lecture (Scannable…) : contrôle d'accès, pointage, inventaire. Associer : bpm.badge, bpm.labelValue, bpm.toast. Éviter : Identification visuelle scannable par caméra (bpm.qrCode, bpm.barcode). ``` label?: string variant?: "default" | "primary" | "success" className?: string ``` ## bpm.notificationCenter @component bpm.notificationCenter @description Liste de notifications groupées (non lues / lues), actions lecture et suppression. @example bpm.notificationCenter({ notifications, onMarkRead: markRead, onDismiss: dismiss }) @props - notifications (NotificationItem[], obligatoire) — { id, title, message?, read, date }. - onMarkRead (function, obligatoire) — Callback (id) marque comme lu. - onMarkAllRead (function, optionnel) — Marque toutes les notifications comme lues. - onDismiss (function, optionnel) — Callback (id) supprime une notification. - maxVisible (number, optionnel) — Nombre maximum affiché. - emptyMessage (string, optionnel) — Message liste vide. - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.topNav, bpm.drawer, bpm.page @associated bpm.activityFeed, bpm.toast, bpm.badge @forbidden Message éphémère unique — utiliser bpm.toast @semantic role=affichage frame=event status=proposed @guidance Centre de notifications persistant : lu/non-lu, marquage, suppression — la mémoire des EventEffects notify. Associer : bpm.toast, bpm.topNav, bpm.activityFeed. Éviter : Confirmation immédiate d'action (bpm.toast) ou flux d'activité d'équipe (bpm.activityFeed). ``` notifications*: NotificationItem[] onMarkRead*: (id: string) => void onMarkAllRead?: () => void onDismiss?: (id: string) => void maxVisible?: number emptyMessage?: string className?: string ``` ## bpm.numberInput @component bpm.numberInput @description Champ de saisie numérique avec validation min/max et formatage au blur. @example bpm.numberInput({ label: "Quantité", value: 10, onChange: setQty, min: 0, max: 100, step: 1 }) @param {object} props @param {string} [props.label] - Label affiché au-dessus. Optionnel. @param {number|null} [props.value] - Valeur contrôlée. Optionnel. @param {function} [props.onChange] - Callback (number | null). Optionnel. @param {number|null} [props.min] - Valeur minimale autorisée. Optionnel. @param {number|null} [props.max] - Valeur maximale autorisée. Optionnel. @param {number} [props.step=1] - Pas d'incrémentation. Optionnel. @param {boolean} [props.disabled=false] - Désactive le champ. Optionnel. @param {string} [props.help] - Texte d'aide au survol. Optionnel. @param {string} [props.placeholder=""] - Placeholder. Optionnel. @param {string|null} [props.error=null] - Message d'erreur du champ : contour rouge + message sous le champ. Optionnel. @parent bpm.modal, bpm.panel @associated bpm.input, bpm.slider @forbidden Valeur non numérique — utiliser bpm.input @semantic role=saisie frame=entity status=proposed @guidance Saisir une valeur numérique précise (Field number), avec min/max/step traduisant les contraintes du champ. Associer : bpm.wizardForm, bpm.labelValue. Éviter : Valeur approximative dans une plage bornée (bpm.slider) ou texte libre (bpm.input). ``` label?: string value?: number | null onChange?: (value: number | null) => void min?: number | null max?: number | null step?: number disabled?: boolean help?: string | null placeholder?: string error?: string | null — Message d'erreur du CHAMP : contour rouge + message sous le champ (role=alert, aria-invalid). Additif : défaut null = rendu inchangé. ``` ## bpm.offlineIndicator @component bpm.offlineIndicator @description Indicateur de statut hors ligne avec compteur de requêtes en attente et bouton de synchronisation. @example bpm.offlineIndicator({ demo: false }) @param {object} props @param {boolean} [props.demo=false] - Mode démo pour afficher le composant même sans file. Optionnel. @associated bpm.toast, bpm.statusBox ``` demo?: boolean — Affiche le composant même sans file (pour démo / page composants). ``` ## bpm.orgChart @component bpm.orgChart @description Organigramme hiérarchique HTML/CSS, repliable. @example bpm.orgChart({ nodes: [{ id: "1", label: "CEO" }, { id: "2", label: "CTO", parentId: "1" }], expandable: true }) @props - nodes (OrgChartNode[], obligatoire) — Nœuds { id, label, parentId?, ... }. - direction ("vertical"|"horizontal", optionnel) — Sens de l’arbre. Default: "vertical". - onNodeClick (function, optionnel) — Callback (node) au clic sur un nœud. - expandable (boolean, optionnel) — Nœuds repliables. Default: false. - rootId (string, optionnel) — Id du nœud racine. - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.card, bpm.container, bpm.page @associated bpm.treeview, bpm.flowDiagram @forbidden Arbre de données/fichiers — utiliser bpm.treeview @semantic role=affichage frame=entity status=needs-curation @guidance Hiérarchie d'acteurs ou d'unités (organigramme) repliable. Associer : bpm.avatar, bpm.drawer. Éviter : Arborescence de données génériques (bpm.treeview) ou processus (bpm.flowDiagram). ``` nodes*: OrgChartNode[] direction?: "vertical" | "horizontal" onNodeClick?: (node: OrgChartNode) => void expandable?: boolean rootId?: string className?: string ``` ## bpm.page Conteneur page (core) — props : children. ``` children*: React.ReactNode ``` ## bpm.pageLayout @component bpm.pageLayout @description Layout d'application avec sidebar rétractable, navigation par icônes Material et switch de thème. @example bpm.pageLayout({ title: "Mon App", items: [{ key: "home", label: "Accueil", icon: "home" }], currentItem: "home", onNavigate: setPage, children: }) @param {object} props @param {string} props.title - Titre affiché dans la sidebar. Obligatoire. @param {SidebarItem[]} props.items - Éléments de navigation (key, label, icon). Obligatoire. @param {string} props.currentItem - Clé de l'élément actif. Obligatoire. @param {function} props.onNavigate - Callback au clic sur un item (key). Obligatoire. @param {React.ReactNode} props.children - Contenu principal. Obligatoire. @param {boolean} [props.defaultCollapsed=false] - Sidebar rétractée par défaut. Optionnel. @param {"light"|"dark"} [props.theme] - Thème actuel. Optionnel. @param {function} [props.onThemeChange] - Callback changement de thème. Optionnel. @param {React.ReactNode} [props.brandLogo] - Pastille de marque rendue à gauche du titre (ex. logo). Centrée en mode replié. Optionnel. @param {string} [props.brandEyebrow] - Sur-étiquette au-dessus du titre (petites capitales espacées). Masquée en mode replié. Optionnel. @param {"soft"|"solid"} [props.activeItemStyle="soft"] - Rendu de l'item actif : teinte translucide (défaut) ou aplat plein accent. Optionnel. @param {React.ReactNode} [props.footer] - Pied de sidebar (compte, déconnexion…) au-dessus du bouton thème. Optionnel. @associated bpm.topNav, bpm.sidebar @parent bpm.page @forbidden aucun @semantic role=conteneur frame=section status=proposed @guidance Ossature d'écran applicatif : sidebar de navigation repliable, titre, zone de contenu. Associer : bpm.topNav, bpm.breadcrumb, bpm.container. Éviter : Pages sans navigation latérale (bpm.topNav seul) ou sous-zones (bpm.container). ``` title*: string items*: SidebarItem[] currentItem*: string onNavigate*: (key: string) => void children*: React.ReactNode defaultCollapsed?: boolean theme?: "light" | "dark" — Thème courant (optionnel). Si fourni avec onThemeChange, affiche le bouton thème en bas de la sidebar (aligné .Maker). onThemeChange?: (theme: "light" | "dark") => void — Callback changement de thème (clair ↔ sombre). Affiche le bouton thème en bas si défini. brandLogo?: React.ReactNode brandEyebrow?: string activeItemStyle?: "soft" | "solid" footer?: React.ReactNode ``` ## bpm.pagination @component bpm.pagination @description Contrôle de pagination avec boutons précédent/suivant, indicateur de page et compteur d'éléments. @example bpm.pagination({ page: 1, totalPages: 10, onPageChange: setPage, totalItems: 100, pageSize: 10 }) @param {object} props @param {number} props.page - Page courante (1-based). Obligatoire. @param {number} props.totalPages - Nombre total de pages. Obligatoire. @param {function} props.onPageChange - Callback au changement de page. Obligatoire. @param {number} [props.pageSize] - Taille de page pour affichage. Optionnel. @param {number} [props.totalItems] - Nombre total d'éléments. Optionnel. @param {string} [props.label] - Libellé personnalisé. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.table, bpm.crud @parent bpm.table, bpm.dataExplorer, bpm.card @forbidden Liste défilante infinie — utiliser le scroll @semantic role=navigation frame=entity status=proposed @guidance Parcourir une collection paginée : situer la page courante et le volume total. Associer : bpm.table, bpm.dataExplorer, bpm.groupedList. Éviter : Petites collections affichables en entier ou défilement continu (bpm.scrollContainer). ``` page*: number — Page courante (1-based). totalPages*: number — Nombre total de pages. onPageChange*: (page: number) => void — Callback au changement de page. Reçoit le numéro de page. pageSize?: number — Taille de page (optionnel, pour affichage). totalItems?: number — Nombre total d’éléments (optionnel). label?: string — Libellé optionnel (ex. "Page 1 sur 5"). className?: string ``` ## bpm.panel @component bpm.panel @description Bloc d'information, alerte ou résumé encadré (type notice ou executive summary) pour mettre en avant un message métier. @example bpm.panel({ variant: "warning", title: "TRS sous seuil", children: "Ligne FORM-1 : 68,4%." }) @props - variant ('info' | 'success' | 'warning' | 'error', optionnel) — Type visuel. Default: 'info'. - title (ReactNode, optionnel) — Titre du panneau. - icon (string | false, optionnel) — Icône ou false pour masquer. - inverted (boolean, optionnel) — Fond sombre. Default: false. - children (ReactNode, optionnel) — Contenu. - className (string, optionnel) — Classes CSS. @usage Alertes production, notices légales, résumés chiffrés. @context PARENT: page directe | bpm.grid | bpm.tabs (contenu onglet). ASSOCIATED: bpm.title, bpm.metric, bpm.table, bpm.plotlyChart. FORBIDDEN: bpm.panel imbriqué trop profond (max 2 niveaux). @semantic role=feedback frame=section status=proposed @guidance Encart informatif persistant avec sévérité (info, success, warning, error) qui qualifie un contenu de page. Associer : bpm.text, bpm.button, bpm.card. Éviter : Notification transitoire (bpm.toast), réaction à une action (bpm.message), statut d'instance (bpm.statusBox). ``` variant?: "info" | "success" | "warning" | "error" — PARENT: page directe | bpm.grid | bpm.tabs (contenu onglet). INTERDIT: bpm.panel imbriqué trop profond (max 2 niveaux). ASSOCIÉ: bpm.title, bpm.metric, bpm.table, bpm.plotlyChart. title?: string | null icon?: string | null | false inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style zone type Executive Summary). children?: React.ReactNode className?: string ``` ## bpm.pdfViewer @component bpm.pdfViewer @description Visionneuse PDF embarquée en iframe avec dimensions personnalisables. @example bpm.pdfViewer({ src: "/documents/rapport.pdf", title: "Rapport annuel", height: 600 }) @param {object} props @param {string} props.src - URL du fichier PDF. Obligatoire. @param {string} [props.title="PDF"] - Titre pour l'accessibilité. Optionnel. @param {number|string} [props.width="100%"] - Largeur. Optionnel. @param {number|string} [props.height="600px"] - Hauteur. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.filePreview, bpm.fileUploader @parent bpm.card, bpm.modal, bpm.drawer @forbidden Image simple — utiliser bpm.image @semantic role=affichage frame=entity status=proposed @guidance Consulter un document PDF attaché (contrat, facture, rapport) sans quitter l'application. Associer : bpm.drawer, bpm.fileUploader, bpm.labelValue. Éviter : Aperçu multi-format (bpm.filePreview) ou contenu éditable. ``` src*: string title?: string width?: number | string height?: number | string className?: string ``` ## bpm.pivotTable @component bpm.pivotTable @description Tableau croisé dynamique avec agrégation (sum, avg, count, min, max), tri et heatmap. @example bpm.pivotTable({ data: rows, rowKey: "region", colKey: "produit", valueKey: "ventes", agg: "sum" }) @param {object} props @param {Record[]} props.data - Données source. Obligatoire. @param {string} props.rowKey - Clé pour les lignes. Obligatoire. @param {string} props.colKey - Clé pour les colonnes. Obligatoire. @param {string} props.valueKey - Clé pour les valeurs à agréger. Obligatoire. @param {"sum"|"avg"|"count"|"min"|"max"} [props.agg="sum"] - Fonction d'agrégation. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.table, bpm.dataExplorer, bpm.heatmap @semantic role=indicateur frame=kpi type=distribution,compte direction=contextuel temporalite=instantane status=proposed @guidance Croiser une mesure agrégée selon deux dimensions (somme/moyenne/compte par ligne × colonne) : analyse multidimensionnelle, totaux par segment. Associer : bpm.metric, bpm.heatmap, bpm.exportButton. Éviter : Liste d'entités non agrégées (bpm.table) ou exploration libre tri/recherche/export (bpm.dataExplorer). ``` data*: Record[] rowKey*: string colKey*: string valueKey*: string agg?: PivotAgg className?: string ``` ## bpm.plcConnector @component bpm.plcConnector @description Formulaire de configuration de connexion automate industriel (Modbus, OPC UA, MQTT, EtherNet/IP). @example bpm.plcConnector({ className: "my-class" }) @param {object} props @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.machineStatus, bpm.sensorGrid, bpm.liveChart ``` className?: string ``` ## bpm.plotlyChart @component bpm.plotlyChart @description Graphique interactif Plotly.js avec support de tous types de traces (bar, line, scatter, etc.). @example bpm.plotlyChart({ data: [{ type: "bar", x: ["A", "B"], y: [10, 20] }], height: 400 }) @param {object} props @param {object[]} [props.data] - Tableau de traces Plotly. Optionnel. @param {object} [props.layout] - Config layout Plotly (title, axes). Optionnel. @param {object} [props.config] - Config Plotly (responsive, displayModeBar). Optionnel. @param {number} [props.height=400] - Hauteur en pixels. Optionnel. @param {number|string} [props.width="100%"] - Largeur. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {string} [props.iframeSrc] - URL iframe (compatibilité ascendante). Optionnel. @parent bpm.panel, bpm.card, bpm.tabs @associated bpm.metric, bpm.selectbox, bpm.dateRangePicker @semantic role=indicateur frame=kpi type=tendance,distribution,ratio direction=contextuel temporalite=contextuel status=needs-curation @guidance Graphique générique des apps générées (règle llms.txt : seul graphique autorisé) : porte le type de mesure que sa trace exprime (ligne=tendance, barres=distribution, jauge=progression…). Associer : bpm.metric, bpm.dateRangePicker, bpm.dataExplorer. Éviter : Visualisations où un composant dédié dit mieux le sens dans CE repo (bpm.lineChart & co servent la vitrine) ; jamais pour une valeur unique (bpm.metric). ``` data?: object[] — Tableau de traces Plotly (ex. [{type:'bar', x:[], y:[]}]). Obligatoire. layout?: object — Config layout Plotly (title, xaxis, yaxis, etc.). config?: object — Config Plotly (responsive, displayModeBar, etc.). height?: number — Hauteur en pixels. Default: 400. width?: number | string className?: string iframeSrc?: string ``` ## bpm.popover @component bpm.popover @description Bulle contextuelle positionnée autour d'un déclencheur avec fermeture au clic extérieur. @example bpm.popover({ trigger: , children:

Contenu

, placement: "bottom" }) @param {object} props @param {React.ReactNode} props.trigger - Élément déclencheur. Obligatoire. @param {React.ReactNode} props.children - Contenu de la bulle. Obligatoire. @param {"top"|"bottom"|"left"|"right"} [props.placement="bottom"] - Position de la bulle. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.tooltip, bpm.dropdown @parent bpm.button, bpm.topNav, bpm.table @forbidden Contenu long ou formulaire — utiliser bpm.modal ou bpm.drawer @semantic role=conteneur frame=section status=proposed @guidance Contenu contextuel ancré à un déclencheur (détail, mini-formulaire, menu) sans quitter la page. Associer : bpm.button, bpm.labelValue. Éviter : Aide d'un mot (bpm.tooltip), tâche bloquante (bpm.modal), panneau de travail (bpm.drawer). ``` trigger*: React.ReactNode children*: React.ReactNode placement?: "top" | "bottom" | "left" | "right" className?: string ``` ## bpm.predictiveChart @component bpm.predictiveChart @description Graphique de prévision avec données historiques, prédictions et intervalle de confiance. @example bpm.predictiveChart({ historical: [{x:1,y:10}], predicted: [{x:2,y:15}], confidenceUpper: [{x:2,y:18}], confidenceLower: [{x:2,y:12}], todayX: 1.5 }) @param {object} props @param {{ x: number; y: number }[]} props.historical - Points historiques. Obligatoire. @param {{ x: number; y: number }[]} props.predicted - Points prédits (ligne pointillée). Obligatoire. @param {{ x: number; y: number }[]} [props.confidenceUpper] - Borne supérieure de confiance. Optionnel. @param {{ x: number; y: number }[]} [props.confidenceLower] - Borne inférieure de confiance. Optionnel. @param {number} [props.todayX] - Position X de la ligne "aujourd'hui". Optionnel. @param {number} [props.width=520] - Largeur du SVG. Optionnel. @param {number} [props.height=220] - Hauteur du SVG. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : la trajectoire PRÉDITE est jugée par interpret (couleur de la prévision, repère pointillé, verdict). Optionnel. @associated bpm.lineChart, bpm.liveChart, bpm.metric ``` historical*: { x: number predicted*: { x: number confidenceUpper?: { x: number confidenceLower?: { x: number todayX?: number width?: number height?: number className?: string context?: InterpretContext — Contexte de jugement { reference, direction } : la trajectoire prédite est jugée par interpret — la prévision (pointillés) prend la couleur du verdict, le repère est tracé, l'aria-label décrit le jugement. Additif : sans context, rendu inchangé. ``` ## bpm.printLayout @component bpm.printLayout @description Mise en page optimisée pour l'impression A4 avec en-tête, pied de page et marges personnalisables. @example bpm.printLayout({ children: , orientation: "portrait", header: , footer: "Page 1", marginsMm: { top: 20 } }) @param {object} props @param {React.ReactNode} props.children - Contenu principal. Obligatoire. @param {"portrait"|"landscape"} [props.orientation="portrait"] - Orientation de la page. Optionnel. @param {React.ReactNode} [props.header] - En-tête affiché en haut. Optionnel. @param {React.ReactNode} [props.footer] - Pied de page. Optionnel. @param {PrintLayoutMarginsMm} [props.marginsMm] - Marges en mm (top, right, bottom, left). Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.invoiceTemplate, bpm.reportPage ``` children*: React.ReactNode orientation?: "portrait" | "landscape" header?: React.ReactNode footer?: React.ReactNode marginsMm?: PrintLayoutMarginsMm className?: string ``` ## bpm.progress @component bpm.progress @description Barre de progression (value/max) pour avancement de tâche ou objectif (ex. TRS cible). @example bpm.progress({ value: 74, max: 100, label: "TRS cible 80%", showValue: true }) @props - value (number, optionnel) — Valeur actuelle. Default: 0. - max (number, optionnel) — Valeur max. Default: 1. - label (string, optionnel) — Libelle au-dessus. - showValue (boolean, optionnel) — Afficher le pourcentage. Default: true. - className (string, optionnel) — Classes CSS. - context (InterpretContext, optionnel) — Contexte de jugement { reference, direction } : couleur + ligne écart/tendance via interpret. @usage Avancement commande, TRS ligne, objectif commercial. @context PARENT: bpm.panel | bpm.card | bpm.tabs. ASSOCIATED: bpm.metric, bpm.slider. FORBIDDEN: aucun. @semantic role=indicateur frame=kpi type=progression,taux direction=borne-cible temporalite=cumule status=proposed @guidance Avancement vers une borne connue : complétion d'une tâche, consommation d'un quota, remplissage d'un objectif. Associer : bpm.card, bpm.statusTracker, bpm.labelValue. Éviter : Valeur sans borne ni cible (bpm.metric) ou attente système indéterminée (bpm.spinner, bpm.loadingBar). ``` value?: number | TrajectoryPoint[] — Valeur actuelle, ou trajectoire v(t) [{t, v}] (le dernier point remplit la barre ; la tendance est jugée si context est fourni). max?: number label?: string showValue?: boolean className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : la barre prend la couleur du jugement et une ligne écart/tendance est révélée sous la barre. Additif : sans context, rendu inchangé. ``` ## bpm.progressRing @component bpm.progressRing @description Anneau de progression circulaire SVG avec animation de transition. @example bpm.progressRing({ value: 75, max: 100, size: 80, strokeWidth: 8 }) @param {object} props @param {number} props.value - Valeur actuelle (ou trajectoire v(t) [{t,v}] : dernier point). Obligatoire. @param {number} [props.max=100] - Valeur maximale. Optionnel. @param {number} [props.size=72] - Diamètre en pixels. Optionnel. @param {number} [props.strokeWidth=8] - Épaisseur du trait. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : couleur de l'anneau selon l'écart au repère, flèche de tendance au centre si trajectoire. Optionnel. @associated bpm.progress, bpm.liveGauge, bpm.metric ``` value*: number | TrajectoryPoint[] — Valeur actuelle, ou trajectoire v(t) [{t, v}] (le dernier point remplit l'anneau, la tendance est révélée au centre si context est fourni). max?: number size?: number strokeWidth?: number className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : l'anneau prend la couleur du jugement (favorable/neutre/défavorable) au lieu de l'accent. Additif : sans context, rendu inchangé. ``` ## bpm.promptInput @component bpm.promptInput @description Zone de saisie multi-lignes pour prompts IA avec auto-resize, compteur de tokens et envoi Ctrl+Enter. @example bpm.promptInput({ value: prompt, onChange: setPrompt, onSubmit: handleSend, placeholder: "Posez votre question...", isLoading: false }) @param {object} props @param {string} props.value - Contenu du prompt. Obligatoire. @param {function} props.onChange - Callback au changement de texte. Obligatoire. @param {function} props.onSubmit - Callback à l'envoi (Ctrl+Enter ou bouton). Obligatoire. @param {string} [props.placeholder="Écrivez votre message..."] - Placeholder. Optionnel. @param {boolean} [props.isLoading=false] - État de chargement (désactive l'envoi). Optionnel. @param {boolean} [props.disabled=false] - Désactive la saisie et l'envoi. Optionnel. @param {number} [props.maxLength] - Longueur maximale. Optionnel. @param {boolean} [props.showTokenCount=false] - Affiche le compteur de tokens estimé. Optionnel. @param {number} [props.minRows=3] - Nombre minimum de lignes. Optionnel. @param {number} [props.maxRows=8] - Nombre maximum de lignes. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.chatInterface @associated bpm.modelSelector, bpm.streamingText @forbidden Saisie d'une ligne simple — utiliser bpm.input @semantic role=saisie frame=ai status=proposed @guidance Saisir une intention pour l'IA : auto-resize, Cmd+Enter, compteur de tokens — la saisie devient le prompt. Associer : bpm.chatInterface, bpm.streamingText, bpm.modelSelector. Éviter : Champ de formulaire métier (bpm.input, bpm.textarea) ou recherche dans un référentiel (bpm.autocomplete). ``` value*: string onChange*: (value: string) => void onSubmit*: (value: string) => void placeholder?: string isLoading?: boolean disabled?: boolean — Désactive la zone de saisie et l’envoi (ex. chat désactivé). maxLength?: number showTokenCount?: boolean minRows?: number maxRows?: number className?: string ``` ## bpm.qrCode @component bpm.qrCode @description Génère un QR code SVG à partir d'une valeur texte avec couleurs personnalisables. @example bpm.qrCode({ value: "https://example.com", size: 150, fgColor: "#000" }) @param {object} props @param {string} props.value - Texte/URL à encoder. Obligatoire. @param {number} [props.size=128] - Taille en pixels. Optionnel. @param {string} [props.fgColor="var(--bpm-text-primary)"] - Couleur des modules. Optionnel. @param {string} [props.bgColor="var(--bpm-bg-primary)"] - Couleur de fond. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.barcode, bpm.nfcBadge @parent bpm.card, bpm.modal, bpm.filePreview @forbidden Code produit numérique court — utiliser bpm.barcode @semantic role=affichage frame=connector status=needs-curation @guidance Encoder un lien ou un contenu (URL, vCard, texte) à destination d'un scan mobile : passerelle écran→téléphone. Associer : bpm.barcode, bpm.card. Éviter : Identifiant logistique normé (bpm.barcode) ou information à lire à l'œil. ``` value*: string size?: number fgColor?: string bgColor?: string className?: string ``` ## bpm.radarChart @component bpm.radarChart @description Graphique radar SVG pour comparer des valeurs sur plusieurs axes. @example bpm.radarChart({ axes: ["Vitesse", "Force", "Endurance"], values: [80, 60, 90], max: 100 }) @param {object} props @param {string[]} props.axes - Libellés des axes. Obligatoire. @param {number[]} props.values - Valeurs correspondantes aux axes. Obligatoire. @param {number} [props.max] - Valeur maximale de l'échelle. Optionnel, calculé auto. @param {number} [props.width=320] - Largeur du SVG. Optionnel. @param {number} [props.height=320] - Hauteur du SVG. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.plotlyChart, bpm.lineChart @semantic role=indicateur frame=kpi type=distribution direction=contextuel temporalite=instantane status=proposed @guidance Comparer un même sujet sur plusieurs axes normés (profil multi-critères) : forces et faiblesses d'un coup d'œil. Associer : bpm.metric, bpm.comparison, bpm.caption. Éviter : Comparaison sur un seul axe (bpm.barChart) ou évolution temporelle (bpm.lineChart). ``` axes*: string[] values*: number[] max?: number width?: number height?: number className?: string context?: InterpretContext — Contexte de repère { reference, direction } : un anneau de repère pointillé est tracé au niveau de reference (même échelle que les axes). Pas de verdict agrégé : un polygone sur N axes hétérogènes n'a pas de couleur de jugement unique — la lecture se fait par axe vs l'anneau. Additif : sans context, rendu inchangé. ``` ## bpm.radioGroup @component bpm.radioGroup @description Groupe de boutons radio avec disposition verticale ou horizontale. @example bpm.radioGroup({ name: "choix", label: "Choisissez", options: ["A", "B", "C"], value: selected, onChange: setSelected }) @param {object} props @param {string} [props.name] - Nom du groupe pour le formulaire. Optionnel. @param {string} [props.label] - Label affiché au-dessus. Optionnel. @param {RadioOption[]} [props.options=[]] - Options (string ou { value, label }). Optionnel. @param {string} [props.value] - Valeur sélectionnée. Optionnel. @param {function} [props.onChange] - Callback au changement. Optionnel. @param {boolean} [props.disabled=false] - Désactive le groupe. Optionnel. @param {"vertical"|"horizontal"} [props.layout="vertical"] - Disposition. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.checkbox, bpm.selectbox, bpm.input @parent bpm.modal, bpm.card, bpm.wizardForm @forbidden Plus de ~6 options — utiliser bpm.selectbox @semantic role=saisie frame=entity status=proposed @guidance Choix exclusif parmi ≤5 options toutes visibles : l'utilisateur compare avant de choisir. Associer : bpm.wizardForm, bpm.card. Éviter : Plus de 5 options (bpm.selectbox) ou choix multiples (bpm.checkbox). ``` name?: string label?: string options?: RadioOption[] value?: string onChange?: (value: string) => void disabled?: boolean layout?: "vertical" | "horizontal" className?: string ``` ## bpm.rating @component bpm.rating @description Composant d'évaluation par étoiles cliquables avec taille personnalisable. @example bpm.rating({ value: 3, max: 5, onChange: setRating, size: "medium" }) @param {object} props @param {number} [props.value=0] - Note actuelle. Optionnel. @param {number} [props.max=5] - Nombre maximum d'étoiles. Optionnel. @param {function} [props.onChange] - Callback au clic sur une étoile. Optionnel. @param {boolean} [props.disabled=false] - Désactive l'interaction. Optionnel. @param {"small"|"medium"|"large"} [props.size="medium"] - Taille des étoiles. Optionnel. @param {TrajectoryPoint[]} [props.history] - Historique v(t) de la note, pour la tendance. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement (ex. note cible) : étoiles colorées par le verdict + suffixe écart/tendance. Optionnel. @associated bpm.slider, bpm.metric @parent bpm.card, bpm.table, bpm.commentThread @forbidden Mesure continue à juger — utiliser bpm.metric avec context @semantic role=saisie frame=entity status=proposed @guidance Saisir une appréciation bornée (1-5 étoiles) : satisfaction, qualité perçue. Associer : bpm.textarea, bpm.card. Éviter : Mesure objective (bpm.numberInput) ; en lecture seule, la moyenne des notes devient un indicateur (bpm.metric en taux). ``` value?: number max?: number onChange?: (value: number) => void disabled?: boolean size?: "small" | "medium" | "large" history?: TrajectoryPoint[] — Historique v(t) [{t, v}] de la note — révèle la tendance si context est fourni. context?: InterpretContext — Contexte de jugement { reference, direction } (ex. note cible 4.0) : les étoiles pleines prennent la couleur du verdict et un suffixe écart/tendance role=status est révélé. Additif : sans context, rendu inchangé. ``` ## bpm.relationGraph @component bpm.relationGraph @description Graphe relationnel SVG interactif avec layouts force/grille/circulaire, zoom, panoramique et drag-and-drop des nœuds. @example bpm.relationGraph({ nodes: [{ id: "1", label: "A" }], edges: [{ from: "1", to: "2" }], layout: "force" }) @param {object} props @param {GraphNode[]} props.nodes - Liste des nœuds (id, label, width?, height?). Obligatoire. @param {GraphEdge[]} props.edges - Liste des arêtes (from, to). Obligatoire. @param {"force"|"grid"|"circular"} [props.layout="force"] - Algorithme de placement. Optionnel. @param {number} [props.width=640] - Largeur du SVG. Optionnel. @param {number} [props.height=420] - Hauteur du SVG. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.orgChart, bpm.treeview ``` nodes*: GraphNode[] edges*: GraphEdge[] layout?: RelationGraphLayout width?: number height?: number className?: string ``` ## bpm.reportPage @component bpm.reportPage @description Page de rapport structurée avec sections (titre, texte, tableau, graphique, KPI), impression PDF via window.print. @example bpm.reportPage({ title: "Rapport mensuel", sections: [{ type: "heading", text: "Résumé" }, { type: "kpi", label: "CA", value: "150k€" }] }) @param {object} props @param {string} props.title - Titre principal du rapport. Obligatoire. @param {string} [props.subtitle] - Sous-titre. Optionnel. @param {string} [props.date] - Date du rapport. Optionnel. @param {React.ReactNode} [props.logo] - Logo affiché en haut à droite. Optionnel. @param {ReportSection[]} props.sections - Sections du rapport (heading, text, table, chart, kpi, divider). Obligatoire. @param {boolean} [props.exportable=true] - Affiche le bouton Imprimer/PDF. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.printLayout, bpm.invoiceTemplate, bpm.lineChart ``` title*: string subtitle?: string date?: string logo?: React.ReactNode sections*: ReportSection[] exportable?: boolean className?: string ``` ## bpm.richTextEditor @component bpm.richTextEditor @description Éditeur WYSIWYG contentEditable avec barre d'outils (gras, italique, titres, listes, liens, images) et export HTML/Markdown. @example bpm.richTextEditor({ value: html, onChange: ({ html, markdown }) => save(html), placeholder: "Rédigez ici..." }) @param {object} props @param {string} [props.defaultHtml=""] - HTML initial. Optionnel. @param {string} [props.value] - HTML contrôlé. Optionnel. @param {function} [props.onChange] - Callback ({ html, markdown }). Optionnel. @param {"html"|"markdown"} [props.format="html"] - Affiche l'aperçu Markdown si "markdown". Optionnel. @param {number} [props.minHeight=160] - Hauteur minimale. Optionnel. @param {number} [props.maxHeight=360] - Hauteur maximale. Optionnel. @param {boolean} [props.readOnly=false] - Mode lecture seule. Optionnel. @param {string} [props.placeholder=""] - Placeholder. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.textarea, bpm.markdown, bpm.codeEditor ``` defaultHtml?: string value?: string onChange?: (payload: { html: string format?: RichTextExportFormat minHeight?: number maxHeight?: number readOnly?: boolean placeholder?: string className?: string ``` ## bpm.routePlanner @component bpm.routePlanner @description Planificateur d'itinéraire avec liste de points réordonnables, carte Leaflet et calcul de distance orthodromique. @example bpm.routePlanner({ stops: [{ id: "1", label: "Paris", position: [48.85, 2.35] }], onReorder: setStops, showDistance: true }) @param {object} props @param {RouteStop[]} props.stops - Points de l'itinéraire (id, label, position [lat, lng]). Obligatoire. @param {function} [props.onReorder] - Callback à la réorganisation. Optionnel. @param {boolean} [props.showDistance=true] - Affiche la distance totale. Optionnel. @param {number|string} [props.mapHeight=360] - Hauteur de la carte. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.mapView, bpm.gps, bpm.timeline ``` stops*: RouteStop[] onReorder?: (next: RouteStop[]) => void showDistance?: boolean mapHeight?: number | string className?: string ``` ## bpm.scatterChart @component bpm.scatterChart @description Graphique de dispersion (nuage de points) SVG simple et responsive. @example bpm.scatterChart({ data: [{ x: 1, y: 10 }, { x: 2, y: 25 }], color: "#3b82f6", radius: 5 }) @param {object} props @param {ScatterChartDatum[]} props.data - Points { x, y }. Obligatoire. @param {number} [props.width=400] - Largeur du SVG. Optionnel. @param {number} [props.height=200] - Hauteur du SVG. Optionnel. @param {string} [props.color="var(--bpm-accent)"] - Couleur des points. Optionnel. @param {number} [props.radius=4] - Rayon des cercles. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : points colorés par écart individuel, anomalies (>2σ du nuage) cerclées, repère pointillé, verdict global. Optionnel. @associated bpm.lineChart, bpm.areaChart, bpm.plotlyChart @parent bpm.card, bpm.grid @forbidden Évolution temporelle — utiliser bpm.lineChart @semantic role=indicateur frame=kpi type=distribution direction=neutre temporalite=instantane status=proposed @guidance Relation entre deux mesures : corrélation, dispersion, valeurs atypiques. Associer : bpm.metric, bpm.caption. Éviter : Évolution d'une seule mesure (bpm.lineChart). Règle apps générées : bpm.plotlyChart. ``` data*: ScatterChartDatum[] width?: number height?: number color?: string radius?: number className?: string context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : chaque point est jugé (couleur par écart au repère ; anomalie >2σ — du comparisonFrame ou, à défaut, du nuage lui-même — cerclée), repère pointillé tracé, verdict global de la série en aria-label + data-judgment. Additif : sans context, rendu inchangé. ``` ## bpm.scheduler @component bpm.scheduler @description Calendrier/agenda avec vues jour, semaine et mois, gestion d'événements et de ressources. @example bpm.scheduler({ view: "week", events: [{ id: "1", title: "Réunion", start: "2024-01-15T10:00", end: "2024-01-15T11:00" }], onEventClick: handleEvent, onSlotClick: handleSlot }) @param {object} props @param {"day"|"week"|"month"} props.view - Vue active. Obligatoire. @param {SchedulerEvent[]} props.events - Liste des événements (id, title, start, end, resourceId?, color?). Obligatoire. @param {SchedulerResource[]} [props.resources] - Ressources associables (id, label). Optionnel. @param {function} props.onEventClick - Callback au clic sur un événement. Obligatoire. @param {function} props.onSlotClick - Callback au clic sur un créneau vide (dayStart, hour). Obligatoire. @param {number} [props.startHour=8] - Première heure affichée. Optionnel. @param {number} [props.endHour=20] - Dernière heure affichée. Optionnel. @param {string} [props.locale] - Locale BCP-47 des dates et des libellés de navigation. Optionnel — défaut : locale du moteur. @param {object} [props.labels] - Surcharge de { prev, today, next }. Optionnel — défaut : dérivé de la locale. @associated bpm.calendar, bpm.timeline @semantic role=composite frame=event status=proposed @guidance Agenda autoporteur d'événements positionnés dans le temps (jour/semaine/mois) : afficher, créer au clic sur un créneau, répartir par ressource. Associer : bpm.timeline, bpm.badge, bpm.drawer. Éviter : Planning de tâches à dépendances (bpm.gantt) ou historique chronologique en lecture seule (bpm.timeline). ``` view*: "day" | "week" | "month" events*: SchedulerEvent[] resources?: SchedulerResource[] onEventClick*: (ev: SchedulerEvent) => void onSlotClick*: (dayStart: Date, hour: number) => void startHour?: number endHour?: number locale?: string — Locale BCP-47 des dates ET des libellés de navigation. Absente = locale du moteur (comportement historique). labels?: SchedulerNavLabels — Surcharge des trois mots que `Intl` ne rend pas. Absente = dérivée de `locale`. ``` ## bpm.scrollContainer @component bpm.scrollContainer @description Conteneur avec scroll vertical, horizontal ou bidirectionnel et option pour masquer la scrollbar. @example bpm.scrollContainer({ children: , height: 400, direction: "vertical", hideScrollbar: true }) @param {object} props @param {React.ReactNode} props.children - Contenu scrollable. Obligatoire. @param {string|number} [props.height="100%"] - Hauteur du conteneur. Optionnel. @param {string|number} [props.maxHeight] - Hauteur maximale. Optionnel. @param {"vertical"|"horizontal"|"both"} [props.direction="vertical"] - Direction du scroll. Optionnel. @param {boolean} [props.hideScrollbar=false] - Masque la scrollbar visuellement. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.panel, bpm.card @associated bpm.table, bpm.list @forbidden Toute la page défile déjà — inutile @semantic role=conteneur frame=section status=proposed @guidance Contenir un contenu long dans une hauteur bornée avec défilement interne (logs, listes denses). Associer : bpm.activityFeed, bpm.codeBlock, bpm.table. Éviter : Pagination de collections (bpm.pagination) ou laisser défiler la page entière. ``` children*: React.ReactNode height?: string | number — Hauteur du conteneur (défaut '100%'). maxHeight?: string | number — Hauteur max pour limiter le scroll. direction?: "vertical" | "horizontal" | "both" — Direction du scroll (défaut 'vertical'). hideScrollbar?: boolean — Masquer la scrollbar visuelle (défaut false). className?: string ``` ## bpm.selectbox @component bpm.selectbox @description Liste déroulante avec dropdown portalé, support clavier et placeholder. @example bpm.selectbox({ label: "Pays", options: ["France", "Belgique", "Suisse"], value: selected, onChange: setSelected }) @param {object} props @param {string} [props.label] - Label affiché au-dessus. Optionnel. @param {SelectboxOption[]} [props.options=[]] - Options (string ou { value, label }). Optionnel. @param {string|null} [props.value] - Valeur sélectionnée. Optionnel. @param {function} [props.onChange] - Callback au changement. Optionnel. @param {boolean} [props.disabled=false] - Désactive le composant. Optionnel. @param {string} [props.help] - Texte d'aide au survol. Optionnel. @param {string} [props.placeholder="Sélectionner..."] - Placeholder. Optionnel. @param {boolean} [props.required=false] - Champ obligatoire. Optionnel. @param {string|null} [props.error=null] - Message d'erreur du champ : contour rouge + message sous le champ. Optionnel. @param {number} [props.triggerHeight] - Hauteur du trigger en pixels. Optionnel. @parent bpm.panel, bpm.modal, bpm.card @associated bpm.input, bpm.radioGroup, bpm.autocomplete @semantic role=saisie frame=entity status=proposed @guidance Choisir UNE valeur parmi une énumération fermée (Field enum) de taille moyenne (5-15 options). Associer : bpm.filterPanel, bpm.wizardForm, bpm.input. Éviter : ≤5 options visibles d'un coup (bpm.radioGroup) ou recherche dans une longue liste/relation (bpm.autocomplete). ``` label?: string — Label affiché au-dessus. options?: SelectboxOption[] — Liste d'options. Format : string[] ou [{value, label}]. value?: string | null — Valeur sélectionnée (contrôlé). onChange?: (value: string) => void — Callback — reçoit la valeur string sélectionnée. disabled?: boolean help?: string | null placeholder?: string required?: boolean error?: string | null — Message d'erreur du CHAMP : contour rouge + message sous le champ (role=alert, aria-invalid). Additif : défaut null = rendu inchangé. triggerHeight?: number — Hauteur du trigger (px) pour alignement avec d'autres champs (ex. FilterPanel). ``` ## bpm.sensorGrid @component bpm.sensorGrid @description Grille de cartes capteur avec valeur, unité, statut coloré et détail optionnel. @example bpm.sensorGrid({ sensors: [{ id: "1", label: "Température", value: 24.5, unit: "°C", status: "ok" }], columns: 3 }) @param {object} props @param {SensorReading[]} props.sensors - Liste des capteurs (id, label, value, unit?, status, detail?). Obligatoire. @param {number} [props.columns=3] - Nombre de colonnes de la grille. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.machineStatus, bpm.liveGauge, bpm.metric ``` sensors*: SensorReading[] columns?: number className?: string ``` ## bpm.signaturePad @component bpm.signaturePad @description Zone de signature canvas avec export data URL PNG et boutons effacer/enregistrer. @example bpm.signaturePad({ width: 400, height: 160, onChangeDataUrl: setSignature }) @param {object} props @param {number} [props.width=400] - Largeur du canvas. Optionnel. @param {number} [props.height=160] - Hauteur du canvas. Optionnel. @param {string} [props.lineColor="var(--bpm-text-primary)"] - Couleur du trait. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {function} [props.onChangeDataUrl] - Callback (dataUrl | null). Optionnel. @associated bpm.fileUploader, bpm.image ``` width?: number height?: number lineColor?: string className?: string onChangeDataUrl?: (dataUrl: string | null) => void ``` ## bpm.skeleton @component bpm.skeleton @description Placeholder anime (rectangles, cercles) pendant le chargement de contenu pour eviter layout shift. @example bpm.skeleton({ width: 200, height: 20, variant: "text" }) @props - variant ('rectangular' | 'circular' | 'text', optionnel) — Forme. Default: 'rectangular'. - width (number | string, optionnel) — Largeur. - height (number | string, optionnel) — Hauteur. - className (string, optionnel) — Classes CSS. - animated (boolean, optionnel) — Animation pulse. Default: true. - shimmer (boolean, optionnel) — Animation shimmer. Default: false. - rounded ('sm' | 'md' | 'lg' | 'full', optionnel) — Bords arrondis. Default: 'md'. - lines (number, optionnel) — Nombre de lignes empilées. Default: 1. @usage Chargement liste, fiche produit, tableau. @context PARENT: bpm.panel | bpm.card. ASSOCIATED: bpm.spinner, bpm.table. FORBIDDEN: aucun. @semantic role=feedback frame=section status=proposed @guidance Attente de contenu dont la forme est connue : préfigure la mise en page pendant le chargement. Associer : bpm.card, bpm.table, bpm.grid. Éviter : Attente sans forme prévisible (bpm.spinner) ou absence réelle de données (bpm.emptyState). ``` variant?: SkeletonVariant width?: number | string height?: number | string className?: string animated?: boolean — Désactive l'animation pulse (utile pour screenshots, tests, prefers-reduced-motion). shimmer?: boolean — Animation shimmer (dégradé balayant) en alternative au pulse. rounded?: SkeletonRounded — Contrôle le rayon des bords (ignoré si variant === "circular"). lines?: number — Nombre de lignes de skeleton empilées (variant text). Default: 1. ``` ## bpm.slider @component bpm.slider @description Curseur de saisie numerique (min-max) pour volume, pourcentage, seuil. @example bpm.slider({ label: "Volume", value: 70, min: 0, max: 100, onChange: setVolume }) @props - value (number, optionnel) — Valeur courante. - min (number, optionnel) — Minimum. Default: 0. - max (number, optionnel) — Maximum. Default: 100. - step (number, optionnel) — Pas. Default: 1. - onChange (function, optionnel) — Callback (value: number). - label (string, optionnel) — Libelle au-dessus. - disabled (boolean, optionnel) — Default: false. - className (string, optionnel) — Classes CSS. @usage Parametres volume, seuil TRS, pourcentage objectif. @context PARENT: bpm.panel | bpm.modal | bpm.card. ASSOCIATED: bpm.input, bpm.progress. FORBIDDEN: aucun. @semantic role=saisie frame=entity status=proposed @guidance Valeur approximative dans une plage bornée où la position relative compte plus que le chiffre exact. Associer : bpm.labelValue, bpm.numberInput. Éviter : Valeur précise à saisir (bpm.numberInput) ou plage non bornée. ``` value?: number min?: number max?: number step?: number onChange?: (value: number) => void label?: string disabled?: boolean className?: string ``` ## bpm.sparkline @component bpm.sparkline @description Courbe SVG compacte pour afficher une tendance avec couleur selon la direction (up/down/flat). @example bpm.sparkline({ values: [10, 15, 12, 18, 22], width: 120, height: 36, trend: "up" }) @param {object} props @param {number[]} props.values - Valeurs de la série. Obligatoire. @param {number} [props.width=120] - Largeur du SVG. Optionnel. @param {number} [props.height=36] - Hauteur du SVG. Optionnel. @param {"up"|"down"|"flat"} [props.trend="flat"] - Tendance pour la couleur. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : couleur déduite de la tendance jugée (interpret), ligne de repère pointillée, aria-label descriptif. Optionnel. @associated bpm.metric, bpm.lineChart, bpm.liveChart ``` values*: number[] — Valeurs de la série (t implicite = index). Trajectoire v(t) explicite possible via points [{t, v}]. width?: number height?: number trend?: SparklineTrend className?: string points?: TrajectoryPoint[] — Trajectoire v(t) explicite [{t, v}] — prioritaire sur values pour le jugement (les v sont aussi tracés). context?: InterpretContext — Contexte de jugement { reference, direction } : la couleur suit la tendance jugée (improving→succès, worsening→erreur) au lieu de la prop trend, et le repère est tracé en pointillé. Additif : sans context, rendu inchangé. ``` ## bpm.spinner @component bpm.spinner @description Indicateur de chargement (cercle, points, barres…) pendant une requête ou traitement asynchrone. @example bpm.spinner({ text: "Chargement des commandes...", size: "medium" }) @props - text (string, optionnel) — Texte sous le spinner. Default: 'Chargement...'. - size ('small' | 'medium' | 'large', optionnel) — Taille. Default: 'medium'. - variant (string, optionnel) — Style d'animation (circle, dot, wheel…). Default: 'circle'. - neutral (boolean, optionnel) — Couleur grise au lieu de l'accent. Default: false. - className (string, optionnel) — Classes CSS. @usage Chargement de données, soumission formulaire, synchronisation. @context PARENT: partout — composant universel. ASSOCIATED: bpm.statusBox, bpm.loadingBar, bpm.message. FORBIDDEN: aucun. @semantic role=feedback frame=section status=proposed @guidance Attente courte et indéterminée d'une opération locale. Associer : bpm.button, bpm.card. Éviter : Contenu à forme prévisible (bpm.skeleton) ou progression mesurable (bpm.progress). ``` text?: string size?: SpinnerSize variant?: SpinnerVariant neutral?: boolean — Utilise la couleur texte (gris) au lieu de l'accent pour homogénéiser avec flèches/icônes neutres className?: string ``` ## bpm.spinnerDot @component bpm.spinnerDot @description Spinner compact type cercle tournant pour indicateur de chargement inline. @example bpm.spinnerDot({ size: "medium" }) @param {object} props @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {"small"|"medium"|"large"} [props.size="medium"] - Taille (16/24/32px). Optionnel. @associated bpm.spinner, bpm.loadingBar, bpm.skeleton @parent bpm.button, bpm.card, bpm.panel @forbidden Chargement de zone de contenu — utiliser bpm.skeleton @semantic role=feedback frame=section status=proposed @guidance Attente discrète en points : chargement inline (bouton, frappe IA, cellule). Associer : bpm.chatInterface, bpm.button. Éviter : Attente de zone entière (bpm.spinner, bpm.skeleton). ``` className?: string size?: "small" | "medium" | "large" — Taille : small (16px), medium (24px), large (32px). ``` ## bpm.splitView @component bpm.splitView @description Deux volets redimensionnables avec séparateur draggable. Empile verticalement sous 640px. Cycle de vie : les deux volets restent MONTÉS — leur état React est préservé. @example bpm.splitView({ left: , right: , defaultSplit: 30, direction: "horizontal" }) @param {object} props @param {React.ReactNode} props.left - Contenu du volet gauche/haut. Obligatoire. @param {React.ReactNode} props.right - Contenu du volet droit/bas. Obligatoire. @param {number} [props.defaultSplit=50] - Pourcentage initial du premier volet. Optionnel. @param {number} [props.minLeft=15] - Pourcentage minimum du premier volet. Optionnel. @param {number} [props.minRight=15] - Pourcentage minimum du second volet. Optionnel. @param {"horizontal"|"vertical"} [props.direction="horizontal"] - Direction du split. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.masterDetail, bpm.panel ``` left*: React.ReactNode right*: React.ReactNode defaultSplit?: number minLeft?: number minRight?: number direction?: "horizontal" | "vertical" className?: string ``` ## bpm.stateMachine @component bpm.stateMachine @description Visualisation d'une machine à états avec graphe circulaire, transitions cliquables et historique. @example bpm.stateMachine({ states: ["A", "B", "C"], transitions: [{ from: "A", to: "B" }], currentState: "A", onTransition: handleTransition }) @param {object} props @param {string[]} props.states - Liste des états. Obligatoire. @param {StateTransition[]} props.transitions - Liste des transitions (from, to, label?). Obligatoire. @param {string} props.currentState - État actuel. Obligatoire. @param {string[]} [props.history=[]] - Historique des états traversés. Optionnel. @param {function} [props.onTransition] - Callback (from, to) au clic sur une transition. Optionnel. @param {number} [props.width=420] - Largeur du SVG. Optionnel. @param {number} [props.height=420] - Hauteur du SVG. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.stepper, bpm.timeline, bpm.relationGraph ``` states*: string[] transitions*: StateTransition[] currentState*: string history?: string[] onTransition?: (from: string, to: string) => void width?: number height?: number className?: string ``` ## bpm.statusBox @component bpm.statusBox @description Affiche le statut d'une opération ou d'un service (en cours, terminé, erreur) avec zone dépliable pour détails. @example bpm.statusBox({ label: "Synchronisation CRM", state: "complete", defaultExpanded: false }) @props - label (string) — Libellé du statut affiché (ex. "Connecté", "Synchronisation en cours"). - state ('running' | 'complete' | 'error', optionnel) — État affiché. Default: 'running'. - children (ReactNode, optionnel) — Contenu dépliable sous le bandeau. - defaultExpanded (boolean, optionnel) — Ouvrir la zone dépliable au montage. Default: true. - compact (boolean, optionnel) — Réduit le padding. Default: false. - className (string, optionnel) — Classes CSS additionnelles. - value (number | TrajectoryPoint[], optionnel) — Valeur mesurée associée, jugée si context fourni. - context (InterpretContext, optionnel) — Contexte de jugement : verdict interpret révélé (écart, tendance, anomalie). @usage Indicateur de statut pour tableaux de bord, synchronisation données, connexion API. @context PARENT: bpm.panel | bpm.card | page directe. ASSOCIATED: bpm.metric, bpm.badge, bpm.spinner. FORBIDDEN: aucun. @semantic role=indicateur frame=workflow type=statut direction=neutre temporalite=instantane status=proposed @guidance Statut détaillé d'un objet ou d'un système : l'état (success/warning/error/info) accompagné de son explication. Associer : bpm.card, bpm.labelValue, bpm.timeline. Éviter : Statut compact en liste (bpm.badge) ou réaction à une action (bpm.message). ``` label*: string state?: "running" | "complete" | "error" children?: React.ReactNode defaultExpanded?: boolean compact?: boolean — Réduit le padding pour contextes denses. className?: string value?: number | TrajectoryPoint[] — Valeur mesurée associée au statut (scalaire ou trajectoire v(t) [{t,v}]) — jugée si context est fourni. context?: InterpretContext — Contexte de jugement { reference, direction, comparisonFrame? } : un verdict écart/tendance/anomalie est révélé à droite du libellé et la bordure gauche prend la couleur du jugement. Additif : sans context, rendu inchangé. ``` ## bpm.statusTracker @component bpm.statusTracker @description Historique réel d'un objet : étapes completed / current / pending / error. @example bpm.statusTracker({ stages: [{ label: "Reçu", state: "completed" }, { label: "En cours", state: "current" }, { label: "Livré", state: "pending" }] }) @props - stages (StatusTrackerStage[], obligatoire) — Étapes { label, state: completed|current|pending|error }. - direction ("horizontal"|"vertical", optionnel) — Orientation. Default: "horizontal". - compact (boolean, optionnel) — Affichage condensé. Default: false. - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.card, bpm.masterDetail, bpm.page @associated bpm.stepper, bpm.timeline, bpm.badge @forbidden Saisie multi-étapes — utiliser bpm.stepper/wizardForm @semantic role=indicateur frame=workflow type=progression,statut direction=borne-cible temporalite=instantane status=proposed @guidance Position réelle d'une instance dans un processus à étapes normées (commande, dossier) : completed/current/pending/error. Associer : bpm.timeline, bpm.badge, bpm.card. Éviter : Parcours de saisie piloté par l'utilisateur (bpm.stepper) ou pourcentage continu (bpm.progress). ``` stages*: StatusTrackerStage[] direction?: "horizontal" | "vertical" compact?: boolean className?: string ``` ## bpm.stepper @component bpm.stepper @description Progression multi-étapes horizontale ou verticale, complété / courant / à venir. @example bpm.stepper({ steps: [{ label: "Panier" }, { label: "Livraison" }, { label: "Paiement" }], currentStep: 1 }) @props - steps (StepperStep[], optionnel) — Étapes { label, description?, icon?, optional? }. - currentStep (number, optionnel) — Index de l’étape courante (0-based). Default: 0. - direction ("horizontal"|"vertical", optionnel) — Orientation. Default: "horizontal". - onStepClick (function, optionnel) — Callback (stepIndex) au clic sur une étape. - size ("sm"|"md"|"lg", optionnel) — Taille des pastilles. Default: "md". - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.wizardForm, bpm.card, bpm.page @associated bpm.statusTracker, bpm.button @forbidden Suivi d'état d'un objet — utiliser bpm.statusTracker @semantic role=navigation frame=workflow status=proposed @guidance Situer l'utilisateur dans un parcours linéaire à étapes (assistant, onboarding) et matérialiser l'étape courante. Associer : bpm.wizardForm, bpm.button. Éviter : Suivi du statut métier réel d'une instance (bpm.statusTracker) ou vues non ordonnées (bpm.tabs). ``` steps?: StepperStep[] currentStep?: number direction?: "horizontal" | "vertical" onStepClick?: (stepIndex: number) => void size?: "sm" | "md" | "lg" className?: string ``` ## bpm.streamingText @component bpm.streamingText @description Affichage de texte en streaming avec curseur clignotant et rendu Markdown optionnel. @example bpm.streamingText({ content: partialText, isStreaming: true, renderMarkdown: true }) @param {object} props @param {string} props.content - Texte courant (s'allonge au fil du stream). Obligatoire. @param {boolean} [props.isStreaming=false] - Affiche le curseur clignotant. Optionnel. @param {boolean} [props.renderMarkdown=true] - Interprète le contenu comme Markdown. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.chatInterface @associated bpm.markdown, bpm.promptInput @forbidden Texte statique — utiliser bpm.markdown/text @semantic role=affichage frame=ai status=proposed @guidance Restituer une génération IA au fil de l'eau (curseur, option Markdown) : la progressivité signale que le contenu se construit (AIFeature uiComponent streamingText). Associer : bpm.promptInput, bpm.markdown, bpm.chatInterface. Éviter : Contenu statique connu d'avance (bpm.text, bpm.markdown). ``` content*: string — Texte courant (s'allonge au fil du stream). isStreaming?: boolean — Affiche le curseur clignotant quand true. renderMarkdown?: boolean — Passe le contenu dans bpm.markdown (défaut true). className?: string ``` ## bpm.suggestionCard @component bpm.suggestionCard @description Carte de suggestion IA avec titre, description, barre de confiance et boutons d'action. @example bpm.suggestionCard({ title: "Suggestion", description: "Détail...", confidence: 85, actions: [{ label: "Appliquer", onClick: apply, variant: "primary" }] }) @param {object} props @param {string} props.title - Titre de la suggestion. Obligatoire. @param {string} props.description - Description détaillée. Obligatoire. @param {number} [props.confidence] - Niveau de confiance 0-100. Optionnel. @param {string} [props.icon] - Nom d'icône Material Symbols. Optionnel. @param {{ label: string; onClick: () => void; variant?: "primary" | "secondary" }[]} props.actions - Boutons d'action. Obligatoire. @param {boolean} [props.dismissable] - Affiche le bouton fermer. Optionnel. @param {function} [props.onDismiss] - Callback à la fermeture. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.card, bpm.message ``` title*: string description*: string confidence?: number icon?: string actions*: { label: string dismissable?: boolean onDismiss?: () => void className?: string ``` ## bpm.table @component bpm.table @description Tableau de données triable avec colonnes personnalisables, formatage numérique et scroll horizontal. @example bpm.table({ columns: [{ key: "nom", label: "Nom" }, { key: "montant", label: "Montant", align: "right" }], data: rows, striped: true, hover: true }) @param {object} props @param {TableColumn[]} props.columns - Définition des colonnes (key, label, align?, render?, decimals?). Obligatoire. @param {Record[]} props.data - Tableau de données. Obligatoire. @param {boolean} [props.striped=true] - Lignes alternées. Optionnel. @param {boolean} [props.hover=true] - Surbrillance au survol. Optionnel. @param {function} [props.onRowClick] - Callback au clic sur une ligne. Optionnel. @param {string} [props.defaultSortColumn] - Colonne triée par défaut. Optionnel. @param {"asc"|"desc"} [props.defaultSortDirection="asc"] - Direction de tri par défaut. Optionnel. @param {string} [props.name] - Nom pour référence IA. Optionnel. @param {string} [props.keyColumn] - Colonne d'ID unique. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {string} [props.valueLocale="fr-FR"] - Locale pour formatage. Optionnel. @param {number} [props.valueDecimals=0] - Décimales par défaut. Optionnel. @param {boolean} [props.valueGrouping=true] - Séparateur de milliers. Optionnel. @param {number} [props.minWidth] - Largeur minimale en pixels. Optionnel. @param {boolean} [props.trackContext=false] - Expose au contexte IA. Optionnel. @param {string} [props.emptyMessage="Aucune donnée disponible"] - Message si vide. Optionnel. @props - columns (TableColumn[], obligatoire) — Colonnes (key, label, align?, render?, decimals?). - data (Record[], obligatoire) — Lignes ; jamais de JSX dans data[] (utiliser render). - striped / hover (boolean, optionnel) — Lignes alternées / surbrillance au survol. - onRowClick (function, optionnel) — Callback (row) au clic sur une ligne. - defaultSortColumn / defaultSortDirection (optionnel) — Tri initial. - name / keyColumn (string, optionnel) — Identifiant IA du tableau / colonne-clé React. - valueLocale / valueDecimals / valueGrouping (optionnel) — Formatage numérique des cellules. - minWidth (number, optionnel) — Largeur minimale en px (déclenche le scroll horizontal). - trackContext (boolean, optionnel) — Expose le tableau au contexte IA. - emptyMessage (string, optionnel) — Message affiché quand data est vide. - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.panel, bpm.container @associated bpm.pagination, bpm.input, bpm.badge, bpm.button @forbidden bpm.card (overflow caché) @semantic role=affichage frame=entity status=proposed @guidance Collection homogène d'entités à comparer ligne à ligne : chaque ligne est une instance, chaque colonne un champ. Associer : bpm.pagination, bpm.filterPanel, bpm.badge, bpm.exportButton. Éviter : Mesures agrégées (bpm.metric) ou exploration libre avec tri/recherche/export intégrés (bpm.dataExplorer). ``` columns*: TableColumn[] — Définition des colonnes — obligatoire. data*: Record[] — Tableau de données — obligatoire. INTERDIT : JSX dans data[], utiliser render dans TableColumn. striped?: boolean hover?: boolean onRowClick?: (row: Record) => void — Callback au clic sur une ligne. defaultSortColumn?: string | null defaultSortDirection?: "asc" | "desc" name?: string | null keyColumn?: string | null className?: string valueLocale?: MetricValueLocale — Locale pour formater les nombres (ex. "fr-FR", "en-US"). valueDecimals?: number — Nombre de décimales par défaut pour les cellules numériques. valueGrouping?: boolean — Séparateur de milliers (true = 1 000,50). minWidth?: number — Largeur minimale du tableau en px (déclenche le scroll horizontal dans le wrapper si conteneur plus étroit). Non défini = pas de min-width. trackContext?: boolean — Si true, expose ce tableau au contexte IA. emptyMessage?: string — Message affiché quand data est vide. Default: "Aucune donnée disponible". loading?: boolean — État chargement : affiche des lignes squelettes (aria-busy). Additif : défaut false. error?: string | null — État erreur : affiche le message en ligne role=alert (prioritaire sur loading/empty). Additif : défaut null. density?: "normal" | "compact" — Densité d'affichage : "normal" (défaut, rendu historique) ou "compact" (padding réduit). totalsLabel?: string — Libellé de la première cellule du pied de totaux. Défaut : "Total". ``` INTERDIT : - data (Record[], obligatoire) — Lignes ; jamais de JSX dans data[] (utiliser render). INTERDIT : Tableau de données — obligatoire. INTERDIT : JSX dans data[], utiliser render dans TableColumn. */ INTERDIT : censé ne jamais faire. */ ## bpm.tabs @component bpm.tabs @description Système d'onglets avec contenu associé, scroll horizontal si débordement. Cycle de vie : seul l'onglet ACTIF est rendu — le content des onglets inactifs est DÉMONTÉ, son état React n'est pas préservé au changement d'onglet. Ne pas y placer d'état de saisie non persisté ; lever l'état dans le composant parent. @example bpm.tabs({ tabs: [{ label: "Aperçu", content: }, { label: "Détails", content:
}], defaultTab: 0 }) @param {object} props @param {TabsItems} [props.tabs=[]] - Onglets (string[] ou { label, content, key? }[]). Optionnel. @param {number} [props.defaultTab=0] - Index de l'onglet actif au montage. Optionnel. @param {function} [props.onChange] - Callback au changement d'onglet (index). Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @parent bpm.panel, bpm.container @associated bpm.table, bpm.plotlyChart, bpm.metric @forbidden bpm.tabs (pas d'imbrication) @semantic role=conteneur frame=section status=proposed @guidance Vues alternatives de même rang sur un même sujet : une seule visible à la fois. Associer : bpm.card, bpm.table, bpm.pageLayout. Éviter : Étapes ordonnées d'un processus (bpm.stepper, bpm.wizardForm) ou sections à lecture continue (bpm.accordion). ``` tabs?: TabsItems — Onglets : tableau de { label, content } ou chaînes (label uniquement). defaultTab?: number — Index de l'onglet actif au montage. Default: 0. onChange?: (index: number) => void className?: string ``` ## bpm.text @component bpm.text @description Affiche un paragraphe ou bloc de texte dans une page ou un formulaire (équivalent st.write / st.text). @example bpm.text({ children: "Chiffre d'affaires Q3 : 1,2 M€." }) @props - children (ReactNode) — Contenu texte à afficher. - mono (boolean, optionnel) — Police monospace. Default: false. - className (string, optionnel) — Classes CSS. - style (object, optionnel) — Styles inline. @usage Corps de texte dans rapports, fiches produit, messages d'aide. @context PARENT: bpm.panel | bpm.card | bpm.modal. ASSOCIATED: bpm.caption, bpm.markdown, bpm.title. FORBIDDEN: aucun. @semantic role=affichage frame=section status=proposed @guidance Texte courant : explication, description, contenu rédactionnel. Associer : bpm.title, bpm.caption, bpm.markdown. Éviter : Texte secondaire atténué (bpm.caption) ou contenu riche structuré (bpm.markdown). ``` children*: React.ReactNode mono?: boolean — Style inline comme st.text (monospace). className?: string style?: React.CSSProperties ``` ## bpm.textarea @component bpm.textarea @description Champ de saisie multiligne pour commentaires, description, notes métier. @example bpm.textarea({ label: "Commentaire", value: comment, onChange: setComment, rows: 4 }) @props - label (string, optionnel) — Libellé au-dessus du champ. - value (string, optionnel) — Valeur contrôlée. - onChange (function, optionnel) — Callback (value: string). - placeholder (string, optionnel) — Texte indicatif. - rows (number, optionnel) — Nombre de lignes visibles. Default: 4. - disabled (boolean, optionnel) — Désactive le champ. Default: false. - inverted (boolean, optionnel) — Fond sombre. Default: false. - className (string, optionnel) — Classes CSS. @usage Commentaire de commande, description produit, notes internes. @context PARENT: bpm.modal | bpm.panel | bpm.card. ASSOCIATED: bpm.input, bpm.button. FORBIDDEN: onChange absent si value contrôlé. @semantic role=saisie frame=entity status=proposed @guidance Saisir un texte long multiligne : description, commentaire, note. Associer : bpm.wizardForm, bpm.markdown. Éviter : Champ court (bpm.input), code (bpm.codeEditor), prompt IA (bpm.promptInput). ``` label?: string value?: string onChange?: (value: string) => void placeholder?: string rows?: number disabled?: boolean inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style zone type PJ). className?: string ``` ## bpm.theme @component bpm.theme @description Sélecteur de thème clair/sombre avec toggle ou select, persiste en localStorage. @example bpm.theme({ variant: "toggle", label: "Mode sombre" }) @param {object} props @param {"toggle"|"select"} [props.variant="toggle"] - Type de contrôle. Optionnel. @param {React.ReactNode} [props.label] - Label du toggle. Optionnel. @param {string} [props.lightLabel="Clair"] - Libellé option claire. Optionnel. @param {string} [props.darkLabel="Sombre"] - Libellé option sombre. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.toggle, bpm.pageLayout @parent bpm.topNav, bpm.sidebar @forbidden aucun @semantic role=action frame=meta status=proposed @guidance Basculer la préférence d'affichage clair/sombre de l'application. Associer : bpm.topNav, bpm.pageLayout. Éviter : Tout réglage métier — la bascule ne touche que la présentation (AppSpecMeta.theme). ``` variant?: ThemeVariant — Type de contrôle : interrupteur (toggle) ou liste (select). label?: React.ReactNode — Label à côté du toggle (variant toggle uniquement). lightLabel?: string — Libellé option "Clair" (variant select). darkLabel?: string — Libellé option "Sombre" (variant select). className?: string ``` ## bpm.timeInput @component bpm.timeInput @description Champ de sélection d'heure avec popover heures/minutes. @example bpm.timeInput({ label: "Heure de début", value: time, onChange: setTime }) @param {object} props @param {string} [props.label] - Label affiché au-dessus. Optionnel. @param {Date|string|null} [props.value] - Valeur (Date ou "HH:MM"). Optionnel. @param {function} [props.onChange] - Callback (Date | null). Optionnel. @param {boolean} [props.disabled=false] - Désactive le champ. Optionnel. @param {string} [props.min] - Heure minimale "HH:MM". Optionnel. @param {string} [props.max] - Heure maximale "HH:MM". Optionnel. @associated bpm.dateInput, bpm.timePickerPopover, bpm.scheduler @parent bpm.modal, bpm.card, bpm.wizardForm @forbidden aucun @semantic role=saisie frame=entity status=proposed @guidance Saisir une heure seule (créneau, horaire récurrent). Associer : bpm.dateInput, bpm.wizardForm. Éviter : Date complète (bpm.dateInput) ou durée libre (bpm.numberInput + unité). ``` label?: string value?: Date | string | null onChange?: (value: Date | null) => void disabled?: boolean min?: string max?: string ``` ## bpm.timeline @component bpm.timeline @description Frise chronologique verticale (événements ou ancienne prop items). @example bpm.timeline({ events: [{ date: "2026-06-01", title: "Création", description: "Dossier ouvert" }] }) @props - events (TimelineEvent[], optionnel) — Événements { date, title, description?, icon? } (API recommandée). - items (TimelineItem[], optionnel) — Ancienne API, conservée pour compatibilité. - maxItems (number, optionnel) — Limite d’éléments affichés. - sortOrder ("asc"|"desc", optionnel) — Ordre chronologique. Default: "desc". - groupByDate (boolean, optionnel) — Regroupe les événements par date. - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.card, bpm.drawer, bpm.page @associated bpm.activityFeed, bpm.statusTracker @forbidden Flux non daté en continu — utiliser bpm.activityFeed @semantic role=affichage frame=event status=needs-curation @guidance Historique ordonné d'événements datés : audit d'une instance, jalons d'un dossier. Associer : bpm.badge, bpm.card, bpm.statusTracker. Éviter : Flux social avec acteurs (bpm.activityFeed) ou suivi d'étapes normées (bpm.statusTracker). ``` events?: TimelineEvent[] — Nouvelle API — fil chronologique riche. items?: TimelineItem[] — Ancienne API — conservée pour compatibilité. maxItems?: number sortOrder?: "asc" | "desc" groupByDate?: boolean className?: string ``` ## bpm.title Titre h1 minimal (core) — children uniquement. Pour titres hiérarchiques : bpm.title1 … title4 ou titleBpm. @semantic role=affichage frame=section status=proposed @guidance Hiérarchiser la page : annoncer une Section Ω et son niveau (1 à 4). Associer : bpm.text, bpm.divider, bpm.pageLayout. Éviter : Mettre en avant une valeur de données (bpm.metric ou bpm.labelValue). ``` children*: React.ReactNode ``` ## bpm.title1 @component bpm.title @description Titre de page ou de section avec niveaux 1–4 pour structurer rapports et tableaux de bord. @example bpm.title({ children: "Dashboard Production", level: 1 }) @props - children (ReactNode) — Texte du titre. - level (1 | 2 | 3 | 4, optionnel) — Niveau hiérarchique. Default: 1. - size (string, optionnel) — Surcharge taille (ex. "1.5rem"). - bold (boolean | number, optionnel) — Gras. - color (string, optionnel) — Couleur texte. - bar (boolean, optionnel) — Barre verticale à gauche. Default: false. - barColor (string, optionnel) — Couleur de la barre. - inverted (boolean, optionnel) — Fond sombre. Default: false. - logoUrl (string, optionnel) — URL logo (level 1). - onLogoClick (function, optionnel) — Clic sur le logo. - className, style (optionnel) — Reste des props. @usage En-têtes de page, titres de section, rapports. @context PARENT: page directe | bpm.panel | bpm.tabs. ASSOCIATED: bpm.metric, bpm.table. FORBIDDEN: aucun. — bpm.title1 : niveau 1 implicite, ne pas passer level. @semantic role=affichage frame=section status=proposed @guidance Titre de page (niveau 1) : nomme l'écran, une seule occurrence par page. Associer : bpm.title2, bpm.text. Éviter : Titres de sous-sections (bpm.title2/title3) ou valeurs de données. ``` children*: React.ReactNode level?: 1 | 2 | 3 | 4 size?: string | null — Taille de police (ex. "1.5rem", "24px"). Surcharge le défaut du niveau. bold?: boolean | number | null — Gras : true = 700, false = 400, ou nombre (ex. 600). Surcharge le défaut du niveau. color?: string | null — Couleur du texte (ex. "var(--bpm-text-primary)", "#333"). Surcharge la couleur par défaut. bar?: boolean — Barre verticale sombre à gauche du titre (comme en-tête de section). barColor?: string | null — Couleur de la barre gauche (hex, rgb ou nom CSS). Ignoré si bar=false. inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style badge / scénario). invertedBackground?: string | null — Couleur de fond quand inverted=true (hex, rgb ou nom CSS). Par défaut : #1d1d1f. logoUrl?: string | null — Optional logo URL (e.g. from localStorage). Shown only when level === 1. onLogoClick?: () => void ``` ## bpm.title2 @component bpm.title @description Titre de page ou de section avec niveaux 1–4 pour structurer rapports et tableaux de bord. @example bpm.title({ children: "Dashboard Production", level: 1 }) @props - children (ReactNode) — Texte du titre. - level (1 | 2 | 3 | 4, optionnel) — Niveau hiérarchique. Default: 1. - size (string, optionnel) — Surcharge taille (ex. "1.5rem"). - bold (boolean | number, optionnel) — Gras. - color (string, optionnel) — Couleur texte. - bar (boolean, optionnel) — Barre verticale à gauche. Default: false. - barColor (string, optionnel) — Couleur de la barre. - inverted (boolean, optionnel) — Fond sombre. Default: false. - logoUrl (string, optionnel) — URL logo (level 1). - onLogoClick (function, optionnel) — Clic sur le logo. - className, style (optionnel) — Reste des props. @usage En-têtes de page, titres de section, rapports. @context PARENT: page directe | bpm.panel | bpm.tabs. ASSOCIATED: bpm.metric, bpm.table. FORBIDDEN: aucun. — bpm.title2 : niveau 2 implicite, ne pas passer level. @semantic role=affichage frame=section status=proposed @guidance Titre de section (niveau 2) sous un title1. Associer : bpm.title1, bpm.title3, bpm.divider. Éviter : Titre de page (bpm.title1) ou emphase dans un paragraphe (bpm.text stylé). ``` children*: React.ReactNode level?: 1 | 2 | 3 | 4 size?: string | null — Taille de police (ex. "1.5rem", "24px"). Surcharge le défaut du niveau. bold?: boolean | number | null — Gras : true = 700, false = 400, ou nombre (ex. 600). Surcharge le défaut du niveau. color?: string | null — Couleur du texte (ex. "var(--bpm-text-primary)", "#333"). Surcharge la couleur par défaut. bar?: boolean — Barre verticale sombre à gauche du titre (comme en-tête de section). barColor?: string | null — Couleur de la barre gauche (hex, rgb ou nom CSS). Ignoré si bar=false. inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style badge / scénario). invertedBackground?: string | null — Couleur de fond quand inverted=true (hex, rgb ou nom CSS). Par défaut : #1d1d1f. logoUrl?: string | null — Optional logo URL (e.g. from localStorage). Shown only when level === 1. onLogoClick?: () => void ``` ## bpm.title3 @component bpm.title @description Titre de page ou de section avec niveaux 1–4 pour structurer rapports et tableaux de bord. @example bpm.title({ children: "Dashboard Production", level: 1 }) @props - children (ReactNode) — Texte du titre. - level (1 | 2 | 3 | 4, optionnel) — Niveau hiérarchique. Default: 1. - size (string, optionnel) — Surcharge taille (ex. "1.5rem"). - bold (boolean | number, optionnel) — Gras. - color (string, optionnel) — Couleur texte. - bar (boolean, optionnel) — Barre verticale à gauche. Default: false. - barColor (string, optionnel) — Couleur de la barre. - inverted (boolean, optionnel) — Fond sombre. Default: false. - logoUrl (string, optionnel) — URL logo (level 1). - onLogoClick (function, optionnel) — Clic sur le logo. - className, style (optionnel) — Reste des props. @usage En-têtes de page, titres de section, rapports. @context PARENT: page directe | bpm.panel | bpm.tabs. ASSOCIATED: bpm.metric, bpm.table. FORBIDDEN: aucun. — bpm.title3 : niveau 3 implicite, ne pas passer level. @semantic role=affichage frame=section status=proposed @guidance Titre de sous-section (niveau 3) sous un title2. Associer : bpm.title2, bpm.text. Éviter : Sauter des niveaux de hiérarchie (title1 → title3 sans title2). ``` children*: React.ReactNode level?: 1 | 2 | 3 | 4 size?: string | null — Taille de police (ex. "1.5rem", "24px"). Surcharge le défaut du niveau. bold?: boolean | number | null — Gras : true = 700, false = 400, ou nombre (ex. 600). Surcharge le défaut du niveau. color?: string | null — Couleur du texte (ex. "var(--bpm-text-primary)", "#333"). Surcharge la couleur par défaut. bar?: boolean — Barre verticale sombre à gauche du titre (comme en-tête de section). barColor?: string | null — Couleur de la barre gauche (hex, rgb ou nom CSS). Ignoré si bar=false. inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style badge / scénario). invertedBackground?: string | null — Couleur de fond quand inverted=true (hex, rgb ou nom CSS). Par défaut : #1d1d1f. logoUrl?: string | null — Optional logo URL (e.g. from localStorage). Shown only when level === 1. onLogoClick?: () => void ``` ## bpm.title4 @component bpm.title @description Titre de page ou de section avec niveaux 1–4 pour structurer rapports et tableaux de bord. @example bpm.title({ children: "Dashboard Production", level: 1 }) @props - children (ReactNode) — Texte du titre. - level (1 | 2 | 3 | 4, optionnel) — Niveau hiérarchique. Default: 1. - size (string, optionnel) — Surcharge taille (ex. "1.5rem"). - bold (boolean | number, optionnel) — Gras. - color (string, optionnel) — Couleur texte. - bar (boolean, optionnel) — Barre verticale à gauche. Default: false. - barColor (string, optionnel) — Couleur de la barre. - inverted (boolean, optionnel) — Fond sombre. Default: false. - logoUrl (string, optionnel) — URL logo (level 1). - onLogoClick (function, optionnel) — Clic sur le logo. - className, style (optionnel) — Reste des props. @usage En-têtes de page, titres de section, rapports. @context PARENT: page directe | bpm.panel | bpm.tabs. ASSOCIATED: bpm.metric, bpm.table. FORBIDDEN: aucun. — bpm.title4 : niveau 4 implicite, ne pas passer level. ``` children*: React.ReactNode level?: 1 | 2 | 3 | 4 size?: string | null — Taille de police (ex. "1.5rem", "24px"). Surcharge le défaut du niveau. bold?: boolean | number | null — Gras : true = 700, false = 400, ou nombre (ex. 600). Surcharge le défaut du niveau. color?: string | null — Couleur du texte (ex. "var(--bpm-text-primary)", "#333"). Surcharge la couleur par défaut. bar?: boolean — Barre verticale sombre à gauche du titre (comme en-tête de section). barColor?: string | null — Couleur de la barre gauche (hex, rgb ou nom CSS). Ignoré si bar=false. inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style badge / scénario). invertedBackground?: string | null — Couleur de fond quand inverted=true (hex, rgb ou nom CSS). Par défaut : #1d1d1f. logoUrl?: string | null — Optional logo URL (e.g. from localStorage). Shown only when level === 1. onLogoClick?: () => void ``` ## bpm.titleBpm @component bpm.title @description Titre de page ou de section avec niveaux 1–4 pour structurer rapports et tableaux de bord. @example bpm.title({ children: "Dashboard Production", level: 1 }) @props - children (ReactNode) — Texte du titre. - level (1 | 2 | 3 | 4, optionnel) — Niveau hiérarchique. Default: 1. - size (string, optionnel) — Surcharge taille (ex. "1.5rem"). - bold (boolean | number, optionnel) — Gras. - color (string, optionnel) — Couleur texte. - bar (boolean, optionnel) — Barre verticale à gauche. Default: false. - barColor (string, optionnel) — Couleur de la barre. - inverted (boolean, optionnel) — Fond sombre. Default: false. - logoUrl (string, optionnel) — URL logo (level 1). - onLogoClick (function, optionnel) — Clic sur le logo. - className, style (optionnel) — Reste des props. @usage En-têtes de page, titres de section, rapports. @context PARENT: page directe | bpm.panel | bpm.tabs. ASSOCIATED: bpm.metric, bpm.table. FORBIDDEN: aucun. @semantic role=affichage frame=section status=proposed @guidance Alias de bpm.title (niveaux 1 à 4) : hiérarchiser la page quand title est masqué par un import local. Associer : bpm.text, bpm.divider. Éviter : Usage par défaut — préférer bpm.title ou bpm.title1…title4. ``` children*: React.ReactNode level?: 1 | 2 | 3 | 4 size?: string | null — Taille de police (ex. "1.5rem", "24px"). Surcharge le défaut du niveau. bold?: boolean | number | null — Gras : true = 700, false = 400, ou nombre (ex. 600). Surcharge le défaut du niveau. color?: string | null — Couleur du texte (ex. "var(--bpm-text-primary)", "#333"). Surcharge la couleur par défaut. bar?: boolean — Barre verticale sombre à gauche du titre (comme en-tête de section). barColor?: string | null — Couleur de la barre gauche (hex, rgb ou nom CSS). Ignoré si bar=false. inverted?: boolean — Couleur inversée : fond sombre, texte blanc (style badge / scénario). invertedBackground?: string | null — Couleur de fond quand inverted=true (hex, rgb ou nom CSS). Par défaut : #1d1d1f. logoUrl?: string | null — Optional logo URL (e.g. from localStorage). Shown only when level === 1. onLogoClick?: () => void ``` ## bpm.toast Toast visuel ; en production préférer useToast(). @semantic role=feedback frame=event status=proposed @guidance Confirmer brièvement l'issue d'une action (succès, erreur) sans interrompre le flux. Associer : bpm.button, bpm.crud, bpm.confirmModal. Éviter : Information durable (bpm.panel), erreur bloquante (bpm.message inline), flux consultable (bpm.notificationCenter). ``` message*: string — Texte principal type?: string — success | error | warning | info title?: string | null pageName?: string | null pageIcon?: string | null — SVG HTML id?: number — Clé React onClose*: () => void — Fermeture — apps : ToastProvider + useToast() ``` ## bpm.toggle @component bpm.toggle @description Interrupteur on/off pour activer ou désactiver une option (notifications, mode maintenance). Prop contrôlée : `value` (boolean) — PAS `checked` ; `checked` est la prop de bpm.checkbox, ne pas confondre. @example bpm.toggle({ label: "Notifications email", value: true, onChange: (v) => setNotif(v) }) @props - label (ReactNode, optionnel) — Libellé à côté du toggle. - value (boolean, optionnel) — État coché. Default: false. - onChange (function, optionnel) — Callback (checked: boolean). - disabled (boolean, optionnel) — Désactive le toggle. Default: false. - className (string, optionnel) — Classes CSS. @usage Paramètres utilisateur, options de module, activation de fonctionnalité. @context PARENT: bpm.panel | bpm.modal | bpm.card. ASSOCIATED: bpm.input, bpm.button. FORBIDDEN: aucun. @semantic role=saisie frame=entity status=proposed @guidance Basculer immédiatement un état binaire on/off (activer un mode, une option de réglage) avec effet direct, sans étape de validation. Associer : bpm.filterPanel, bpm.card, bpm.labelValue. Éviter : Booléen confirmé dans un formulaire à valider (bpm.checkbox) ou choix exclusif entre plusieurs valeurs (bpm.radioGroup). ``` label?: React.ReactNode value?: boolean onChange?: (checked: boolean) => void disabled?: boolean className?: string ``` ## bpm.tooltip @component bpm.tooltip @description Info-bulle au survol d'un élément (bouton, icône) pour aide contextuelle. @example bpm.tooltip({ text: "Exporter en PDF", children: }) @props - text (string) — Texte du tooltip. - children (ReactNode) — Élément déclencheur (bouton, icône). - position (string, optionnel) — Placement (top, bottom, left, right…). Default: 'top'. - backgroundColor (string, optionnel) — Fond du tooltip. - textColor (string, optionnel) — Couleur du texte. @usage Aide sur boutons, explication de champs, raccourcis. @context PARENT: partout. ASSOCIATED: bpm.button, bpm.input. FORBIDDEN: aucun. @semantic role=feedback frame=section status=proposed @guidance Aide contextuelle d'un mot ou d'une icône au survol : définition, unité, raccourci. Associer : bpm.button, bpm.metric, bpm.badge. Éviter : Contenu indispensable (le rendre visible) ou contenu riche (bpm.popover). ``` text*: string children*: React.ReactNode position?: TooltipPlacement backgroundColor?: string | null — Couleur de fond du tooltip (hex, rgb ou nom CSS). Par défaut : noir. textColor?: string | null — Couleur du texte du tooltip (hex, rgb ou nom CSS). Par défaut : blanc. ``` ## bpm.topNav @component bpm.topNav @description Barre de navigation horizontale avec titre/logo et liens/boutons. @example bpm.topNav({ title: "Mon App", titleHref: "/", items: [{ label: "Accueil", href: "/" }, { label: "Aide", onClick: showHelp }] }) @param {object} props @param {React.ReactNode} [props.title] - Titre ou logo. Optionnel. @param {string} [props.titleHref="#"] - Lien du titre. Optionnel. @param {TopNavItem[]} [props.items=[]] - Éléments de navigation (label, href?, onClick?). Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.pageLayout, bpm.sidebar, bpm.breadcrumb @parent bpm.page, bpm.pageLayout @forbidden Navigation latérale dense — utiliser bpm.sidebar @semantic role=navigation frame=section status=proposed @guidance Navigation principale horizontale entre les sections de premier niveau de l'application. Associer : bpm.pageLayout, bpm.theme, bpm.avatar. Éviter : Hiérarchie profonde (bpm.breadcrumb) ou navigation lourde multi-niveaux (sidebar de bpm.pageLayout). ``` title?: React.ReactNode titleHref?: string items?: TopNavItem[] className?: string ``` ## bpm.tour @component bpm.tour @description Visite guidée interactive avec overlay sombre et mise en surbrillance des éléments cibles étape par étape. @example bpm.tour({ steps: [{ target: "#btn", title: "Bienvenue", content: "Cliquez ici" }], isActive: true, onClose: () => setActive(false) }) @param {object} props @param {TourStep[]} props.steps - Liste des étapes (target sélecteur CSS, title, content). Obligatoire. @param {boolean} props.isActive - Active/désactive la visite. Obligatoire. @param {function} [props.onClose] - Callback à la fermeture. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.modal, bpm.stepper ``` steps*: TourStep[] isActive*: boolean onClose?: () => void className?: string ``` ## bpm.transition @component bpm.transition @description Conteneur de vues avec transition animée (fade, shimmer, border, grid) pour wizard ou carrousel. @example bpm.transition({ activeIndex: 0, variant: "fade", children: [, ] }) @props - activeIndex (number) — Index de la vue affichée (0-based). - variant ('fade' | 'shimmer' | 'border' | 'grid', optionnel) — Type de transition. Default: 'fade'. - children (ReactNode[]) — Une entrée par vue. - duration (number, optionnel) — Durée transition ms. Default: 380. - onTransitionEnd (function, optionnel) — Callback fin de transition. - className (string, optionnel) — Classes CSS. @usage Wizard de saisie, carrousel d'étapes, changement de vue. @context PARENT: bpm.panel | bpm.modal. ASSOCIATED: bpm.stepper, bpm.button. FORBIDDEN: aucun. ``` activeIndex*: number — Index de la page / vue active (0-based). variant?: TransitionVariant — Variant de transition : fade (slide), shimmer, border, grid. children*: ReactNode[] — Enfants : tableau de nœuds (une « page » par entrée). duration?: number — Durée de la transition fade (ms). Défaut 380. onTransitionEnd?: () => void — Callback à la fin de la transition. className?: string ``` ## bpm.treemap @component bpm.treemap @description Visualisation treemap (carte de chaleur hiérarchique) en SVG avec algorithme squarify. @example bpm.treemap({ data: [{ name: "A", value: 50 }, { name: "B", value: 30 }], width: 400, height: 300 }) @param {object} props @param {TreemapItem[]} props.data - Données à afficher (name, value, fill optionnel). Obligatoire. @param {number} [props.width=400] - Largeur du SVG en pixels. Optionnel. @param {number} [props.height=280] - Hauteur du SVG en pixels. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement par tuile : chaque cellule est jugée vs le repère (contour coloré par le verdict hors zone neutre, data-judgment par tuile). Optionnel. @associated bpm.heatmap, bpm.pieChart, bpm.sunburst ``` data*: TreemapItem[] width?: number height?: number className?: string context?: InterpretContext — Contexte de jugement { reference, direction } : chaque tuile est jugée individuellement par interpret vs le repère (contour coloré par le verdict hors zone neutre, data-judgment par tuile). Pas de verdict agrégé : un total de tuiles hétérogènes n'a pas de jugement unique. Additif : sans context, rendu inchangé. ``` ## bpm.treeview @component bpm.treeview @description Arborescence hiérarchique dépliable avec sélection de nœud. @example bpm.treeview({ nodes: [{ id: "1", label: "Parent", children: [{ id: "1.1", label: "Enfant" }] }], onSelect: handleSelect }) @param {object} props @param {TreeviewNode[]} [props.nodes=[]] - Liste des nœuds racines (id, label, children, defaultOpen). Optionnel. @param {function} [props.onSelect] - Callback à la sélection d'un nœud (node). Optionnel. @param {string|null} [props.selectedId=null] - ID du nœud sélectionné. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.sidebar, bpm.accordion, bpm.menu @parent bpm.card, bpm.drawer, bpm.masterDetail @forbidden Hiérarchie d'organisation — utiliser bpm.orgChart @semantic role=affichage frame=entity status=proposed @guidance Hiérarchie de nœuds explorables (arborescence de dossiers, taxonomie, relations parent-enfant). Associer : bpm.masterDetail, bpm.drawer, bpm.labelValue. Éviter : Hiérarchie d'acteurs (bpm.orgChart) ou liste plate (bpm.table). ``` nodes?: TreeviewNode[] onSelect?: (node: TreeviewNode) => void selectedId?: string | null className?: string ``` ## bpm.video @component bpm.video @description Lecteur vidéo HTML5 avec contrôles natifs et options de lecture en boucle/silencieux. @example bpm.video({ src: "/videos/demo.mp4", controls: true, width: 640, height: 360 }) @param {object} props @param {string} props.src - URL de la vidéo. Obligatoire. @param {boolean} [props.controls=true] - Affiche les contrôles natifs. Optionnel. @param {boolean} [props.loop=false] - Lecture en boucle. Optionnel. @param {boolean} [props.muted=false] - Lecture silencieuse. Optionnel. @param {number} [props.width] - Largeur en pixels. Optionnel. @param {number} [props.height] - Hauteur en pixels. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.image, bpm.carousel, bpm.lightbox @parent bpm.card, bpm.container, bpm.modal @forbidden aucun @semantic role=affichage frame=entity status=proposed @guidance Restituer un contenu vidéo (démonstration, captation liée à une entité). Associer : bpm.card, bpm.filePreview. Éviter : Simple image (bpm.image) ou audio seul (bpm.audio). ``` src*: string controls?: boolean loop?: boolean muted?: boolean width?: number height?: number className?: string ``` ## bpm.waterfall @component bpm.waterfall @description Graphique en cascade (waterfall chart) montrant l'évolution cumulative de valeurs positives/négatives. @example bpm.waterfall({ data: [{ label: "Début", value: 100, type: "start" }, { label: "+Ventes", value: 50 }, { label: "Total", value: 150, type: "total" }] }) @param {object} props @param {WaterfallDatum[]} props.data - Données (label, value, type optionnel: "start"|"delta"|"total"). Obligatoire. @param {number} [props.width=480] - Largeur du SVG en pixels. Optionnel. @param {number} [props.height=260] - Hauteur du SVG en pixels. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @param {InterpretContext} [props.context] - Contexte de jugement : le cumul final de la cascade est jugé vs le repère, verdict révélé sous le graphique. Optionnel. @associated bpm.barChart, bpm.stackedBarChart, bpm.kpi ``` data*: WaterfallDatum[] width?: number height?: number className?: string context?: InterpretContext — Contexte de jugement { reference, direction } : le cumul FINAL de la cascade est jugé par interpret — verdict écart au repère révélé sous le graphique (role=status), data-judgment. Additif : sans context, rendu inchangé. ``` ## bpm.wizardForm @component bpm.wizardForm @description Assistant multi-étapes avec stepper, validation et transition slide. Cycle de vie : seule l'étape COURANTE est rendue — les étapes inactives sont DÉMONTÉES, leur état n'est pas préservé. Persister les valeurs de chaque étape dans le parent. @example bpm.wizardForm({ steps: [{ title: "Profil", content: <>… }], onComplete: handleDone }) @props - steps (WizardStep[], obligatoire) — Étapes { title, content, validate? }. - onComplete (function, obligatoire) — Callback à la dernière étape validée. - onCancel (function, optionnel) — Callback d’annulation. - submitLabel (string, optionnel) — Libellé du bouton final. Default: "Terminer". - showSummary (boolean, optionnel) — Affiche un récapitulatif final. - className (string, optionnel) — Classes CSS additionnelles. @parent bpm.modal, bpm.page, bpm.card @associated bpm.stepper, bpm.input, bpm.button @forbidden Formulaire court d'un seul tenant — utiliser bpm.modal @semantic role=saisie frame=entity status=proposed @guidance Création/édition guidée en plusieurs étapes validées : formulaire long découpé en séquence logique. Associer : bpm.stepper, bpm.input, bpm.selectbox, bpm.confirmModal. Éviter : Formulaire court d'un seul tenant (bpm.modal + champs) ou suivi d'un processus métier (bpm.statusTracker). ``` steps*: WizardStep[] onComplete*: () => void onCancel?: () => void submitLabel?: string showSummary?: boolean className?: string ``` ## bpm.dataExplorerAnalytics @component bpm.dataExplorerAnalytics @description Explorateur de données mode analytics avec filtres dynamiques, graphiques et tableau des résultats. @example bpm.dataExplorerAnalytics({ data: [...], columns: [...], chartConfig: { type: "bar", xKey: "categorie", yKey: "montant" } }) @param {object} props @param {Record[]} props.data - Données à analyser. Obligatoire. @param {ExplorerAnalyticsColumn[]} props.columns - Colonnes avec type (string/number/date/enum). Obligatoire. @param {object} [props.chartConfig] - Configuration du graphique {type, xKey, yKey}. Optionnel. @param {function} [props.onFilter] - Callback avec les données filtrées. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.filterPanel, bpm.barChart, bpm.table ``` mode*: "analytics" data*: Record[] columns*: ExplorerAnalyticsColumn[] chartConfig?: { type: "bar" | "line" | "pie" onFilter?: (filtered: Record[]) => void className?: string ``` ## bpm.dataExplorerClassic @component bpm.dataExplorerClassic @description Explorateur de données classique avec table triable, recherche, pagination et export CSV. @example bpm.dataExplorerClassic({ data: [...], columns: [...], searchable: true, exportable: true }) @param {object} props @param {Record[]} props.data - Données à afficher. Obligatoire. @param {ColumnDef[]} [props.columns] - Définition des colonnes (auto-inféré si absent). Optionnel. @param {string} [props.title] - Titre de l'explorateur. Optionnel. @param {boolean} [props.searchable=true] - Active la recherche. Optionnel. @param {boolean} [props.exportable=false] - Active l'export CSV. Optionnel. @param {number} [props.pageSize=20] - Nombre d'éléments par page. Optionnel. @param {string} [props.className=""] - Classes CSS additionnelles. Optionnel. @associated bpm.table, bpm.pagination, bpm.input ``` data*: Record[] columns?: ColumnDef[] title?: string searchable?: boolean exportable?: boolean pageSize?: number className?: string ``` ## bpm.datePickerPopover @component bpm.datePickerPopover @description Calendrier popover pour sélection de date avec navigation mois/année et contraintes min/max. @example bpm.datePickerPopover({ anchorRef: ref, value: new Date(), onSelect: setDate, onClose: close }) @param {object} props @param {React.RefObject} props.anchorRef - Référence de l'élément déclencheur pour le positionnement. Obligatoire. @param {Date|null} props.value - Date actuellement sélectionnée. Obligatoire. @param {Date|null} [props.min] - Date minimale sélectionnable. Optionnel. @param {Date|null} [props.max] - Date maximale sélectionnable. Optionnel. @param {function} props.onSelect - Callback appelé avec la date choisie. Obligatoire. @param {function} props.onClose - Callback de fermeture. Obligatoire. @associated bpm.dateInput, bpm.dateRangePicker ``` anchorRef*: React.RefObject value*: Date | null min?: Date | null max?: Date | null onSelect*: (date: Date) => void onClose*: () => void ``` ## bpm.gpsMap @component bpm.gpsMap @description Carte Leaflet avec marqueur GPS (mode affichage ou picker) et gestion des clics. @example bpm.gpsMap({ mode: "picker", center: { lat: 48.85, lng: 2.35 }, markerPosition: pos, onMapClick: setPos, height: 300 }) @param {object} props @param {"display"|"picker"} props.mode - Mode affichage ou sélection. Obligatoire. @param {object} props.center - Centre initial {lat, lng}. Obligatoire. @param {object|null} props.markerPosition - Position du marqueur {lat, lng} ou null. Obligatoire. @param {function} [props.onMarkerChange] - Callback au déplacement du marqueur (mode picker). Optionnel. @param {function} [props.onMapClick] - Callback au clic sur la carte (mode picker). Optionnel. @param {number} props.height - Hauteur de la carte en pixels. Obligatoire. @associated bpm.gps, bpm.mapView, bpm.geofence ``` mode*: "display" | "picker" center*: { lat: number markerPosition*: { lat: number onMarkerChange?: (lat: number, lng: number) => void onMapClick?: (lat: number, lng: number) => void height*: number ``` ## bpm.mapViewLeaflet @component bpm.mapViewLeaflet @description Composant interne Leaflet utilisé par MapView après chargement dynamique des dépendances. @example // Usage interne uniquement - utiliser bpm.mapView à la place @param {object} props @param {typeof import("react-leaflet")} props.rl - Module react-leaflet. Obligatoire. @param {typeof import("leaflet")} props.L - Module leaflet. Obligatoire. @param {[number, number]} props.center - Centre de la carte. Obligatoire. @param {number} props.zoom - Niveau de zoom. Obligatoire. @param {number|string} props.height - Hauteur. Obligatoire. @param {MapMarker[]} props.markers - Marqueurs. Obligatoire. @param {function} [props.onMarkerClick] - Callback clic marqueur. Optionnel. @param {string} props.tileUrl - URL des tuiles. Obligatoire. @param {string} [props.tileAttribution] - Attribution. Optionnel. @param {[number, number][][]} [props.polylines] - Polylignes. Optionnel. @param {string} [props.polylineColor] - Couleur polylignes. Optionnel. @param {MapPolygonSpec[]} [props.polygons] - Polygones. Optionnel. @param {function} [props.onMapClick] - Callback clic carte. Optionnel. @param {string} [props.className=""] - Classes CSS. Optionnel. @parent bpm.mapView ``` rl*: typeof import("react-leaflet") L*: typeof import("leaflet") center*: [number, number] zoom*: number height*: number | string markers*: MapMarker[] onMarkerClick?: (index: number, marker: MapMarker) => void tileUrl*: string tileAttribution?: string polylines?: [number, number][][] polylineColor?: string polygons?: MapPolygonSpec[] overlays?: MapOverlaySpec[] — Calques superposables (données app + WMS/tuiles externes). onMapClick?: (latlng: [number, number]) => void className?: string ``` ## bpm.timePickerPopover @component bpm.timePickerPopover @description Popover de sélection heures/minutes utilisé par TimeInput. @example // Usage interne via bpm.timeInput @param {object} props @param {React.RefObject} props.anchorRef - Référence à l'élément ancre. Obligatoire. @param {Date|null} props.value - Heure actuelle. Obligatoire. @param {function} props.onSelect - Callback (hours, minutes). Obligatoire. @param {function} props.onClose - Callback à la fermeture. Obligatoire. @parent bpm.timeInput ``` anchorRef*: React.RefObject value*: Date | null onSelect*: (hours: number, minutes: number) => void onClose*: () => void ``` ## PATTERN MODAL OBLIGATOIRE ```tsx const [isOpen, setIsOpen] = useState(false) const [form, setForm] = useState({ nom: '', valeur: 0 }) const [saving, setSaving] = useState(false) const handleSave = async () => { setSaving(true) try { const res = await fetch('/api/items', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(form), }) if (!res.ok) throw new Error('Erreur serveur') setIsOpen(false) } catch (e) { console.error(e) } finally { setSaving(false) } } // Dans return() : {isOpen && bpm.modal({ isOpen: true, onClose: () => setIsOpen(false), title: 'Créer', children: ( <> {bpm.input({ label: 'Nom', value: form.nom, onChange: (v) => setForm({ ...form, nom: v }) })} {bpm.button({ children: saving ? '...' : 'Enregistrer', onClick: handleSave, disabled: saving })} ) })} ``` ## ROUTES API — App Router uniquement ```ts // app/api/items/route.ts import { NextResponse } from 'next/server' export async function GET() { return NextResponse.json([]) } export async function POST(req: Request) { const body = await req.json() return NextResponse.json({ success: true, data: body }) } // INTERDIT : NextApiRequest / export default dans app/api/ ```