Installation - Angular
Cette page documente l’installation de Ori dans une app Angular (standalone). Pour React/Next.js, voir la section dédiée du Storybook React.
Prérequis
- Node.js 20+
- Angular 20+ (avec composants standalone)
- Tailwind CSS v3
1. Installer les paquets
pnpm add @govpf/ori-angular @govpf/ori-tokens @govpf/ori-tailwind-preset
pnpm add @angular/cdk lucide-angular
pnpm add -D autoprefixer postcss tailwindcss
@angular/cdk est requis pour le focus-trap des <ori-dialog> /
<ori-alert-dialog> et la portal du <ori-dropdown-menu>.
lucide-angular est requis pour les icônes utilisées par certains
composants (Alert, FileUpload, Toast, DropdownMenu, etc.).
Ne pas installer @govpf/ori-css côté Angular tant que #88
n’est pas résolu : son dist/ori.css référence des polices via
chemin relatif cassé dans la version publiée. Le scaffold ci-dessous
régénère les classes .ori-* à la volée via le preset Tailwind, c’est
le pattern utilisé par apps/storybook-angular et apps/demo-portail.
2. Brancher le preset Tailwind
tailwind.config.js (export ESM par défaut, pas d’import nommé) :
import preset from '@govpf/ori-tailwind-preset';
/** @type {import('tailwindcss').Config} */
export default {
presets: [preset],
content: [
'./src/**/*.{ts,html}',
// Indispensable : sans ça, Tailwind ne voit pas les classes
// utilisées dans les templates Angular compilés.
'./node_modules/@govpf/ori-angular/**/*.mjs',
],
// Garde-fou : conserve toutes les classes ori-* même si le scanner
// de contenu rate quelques utilisations dynamiques.
safelist: [{ pattern: /^ori-/ }],
};
postcss.config.js :
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
3. Importer tokens + Tailwind dans styles.css
/* Chemins relatifs vers @govpf/ori-tokens : nécessaire parce que
* postcss-import ne résout pas les "exports" du package, et les
* @font-face de tokens/src/fonts.css référencent des TTF voisins
* (../assets/fonts/) qui ne sont accessibles que via chemin relatif. */
@import '../../node_modules/@govpf/ori-tokens/src/fonts.css';
@import '../../node_modules/@govpf/ori-tokens/build/css/tokens.css';
@import '../../node_modules/@govpf/ori-tokens/src/dark.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
L’ordre importe : tokens d’abord (variables CSS + fonts), puis
Tailwind layers (base reset, components .ori-*, utilities).
4. Bootstrap standalone
src/main.ts :
import 'zone.js';
import { bootstrapApplication } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [provideAnimations()],
}).catch((err) => console.error(err));
provideAnimations() est requis par les composants qui utilisent
@angular/cdk (dialog, dropdown, tooltip).
5. Utiliser un composant
Composants standalone, à importer dans le tableau imports du composant
qui les consomme :
import { Component } from '@angular/core';
import { OriButtonComponent } from '@govpf/ori-angular';
@Component({
selector: 'app-home',
standalone: true,
imports: [OriButtonComponent],
template: `<ori-button variant="primary">Démarrer une démarche</ori-button>`,
})
export class HomeComponent {}
Pièges strict-templates à connaître
strictTemplates: true est activé par défaut dans tsconfig.json des
scaffolds Angular CLI modernes (et obligatoire pour apps/storybook-angular
et toute app du monorepo Ori). Il refuse plusieurs patterns courants
quand on consomme des composants Ori :
Inputs booléens : [x]="true", jamais x seul
<!-- KO : passe la string vide "" au lieu de true -->
<ori-notification dismissible>...</ori-notification>
<!-- OK -->
<ori-notification [dismissible]="true">...</ori-notification>
S’applique à dismissible, iconOnlyButton, striped, loading,
hideLabel, hideCrest, removable, etc.
Variant et statut indexés : passer par un helper typé
<!-- KO : row est typé `any` dans <ng-template let-row>, donc
STATUT_VARIANT[row.statut] devient un index `any` -> rejeté -->
<ori-tag [variant]="STATUT_VARIANT[row.statut]">{{ STATUT_LABEL[row.statut] }}</ori-tag>
Solution : exposer des méthodes typées sur le composant.
statutVariant(row: Dossier) { return STATUT_VARIANT[row.statut]; }
statutLabel(row: Dossier) { return STATUT_LABEL[row.statut]; }
<ori-tag [variant]="statutVariant(row)">{{ statutLabel(row) }}</ori-tag>
cellTemplate du <ori-table> : typer le TemplateRef
OriTableColumn.cellTemplate attend TemplateRef<{ $implicit: TRow; index: number }>.
Avec une typage plus large (TemplateRef<unknown>) le compilateur refuse :
TS2322: Type 'TemplateRef<unknown>' is not assignable to
type 'TemplateRef<{ $implicit: Dossier; index: number; }>'.
Bonne forme :
@ViewChild('statutTpl', { static: true })
statutTpl!: TemplateRef<{ $implicit: Dossier; index: number }>;
ngAfterViewInit() {
this.columns.set([
{ key: 'statut', label: 'Statut', cellTemplate: this.statutTpl },
/* ... */
]);
}
<ng-template #statutTpl let-row let-i="index">
<ori-tag [variant]="statutVariant(row)">{{ statutLabel(row) }}</ori-tag>
</ng-template>
Forms réactifs
Les composants form de Ori (<ori-input>, <ori-checkbox>,
<ori-select>, etc.) sont compatibles avec [(ngModel)] via le couple
[value] / (valueChange) :
<ori-input
label="Nom"
[required]="true"
[(value)]="model.name"
></ori-input>
Pour ReactiveFormsModule, l’app peut wrapper ou accéder via
ViewChild. Un ControlValueAccessor natif n’est pas fourni par le
DS pour rester découplé de @angular/forms (les apps qui utilisent
des Signals exclusivement n’en ont pas besoin). Voir
Patterns Angular pour un wrapper type.
Theme sombre
Le DS supporte light/dark via data-theme="dark" sur l’élément racine :
document.documentElement.setAttribute('data-theme', 'dark');
Exemple complet
Voir apps/example-agent/ dans le monorepo : back-office d’instruction
de dossiers consommant <ori-app-shell>, <ori-table> (sélection
multiple + tri + cellTemplate), <ori-dropdown-menu>, <ori-alert-dialog>,
<ori-notification>, <ori-search-bar>, <ori-statistic> et <ori-tag>.
Toute la stack scaffold (angular.json, tsconfig, tailwind.config, styles.css)
est en place.
Voir aussi
- Patterns Angular : création d’un composant qui consomme le DS, formulaires réactifs, OnPush
- Tokens / Sémantique : référence des classes CSS exposées