@gouvfr-lasuite/ui-kit 0.19.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1,705 @@
1
- # design-system
1
+ # @gouvfr-lasuite/ui-kit
2
+
3
+ <!-- TODO: Add CI/CD badge when available -->
4
+ [![npm version](https://img.shields.io/npm/v/@gouvfr-lasuite/ui-kit.svg)](https://www.npmjs.com/package/@gouvfr-lasuite/ui-kit)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
6
+ [![React](https://img.shields.io/badge/React-19.x-61DAFB?logo=react)](https://react.dev/)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.6-3178C6?logo=typescript)](https://www.typescriptlang.org/)
8
+
9
+ > Official UI Kit for **La Suite numérique** - A modern, accessible, and customizable React component library built on [Cunningham](https://github.com/openfun/cunningham).
10
+
11
+ ---
12
+
13
+ ## Table of Contents
14
+
15
+ - [Introduction](#introduction)
16
+ - [Features](#features)
17
+ - [Technologies](#technologies)
18
+ - [Prerequisites](#prerequisites)
19
+ - [Installation](#installation)
20
+ - [Quick Start](#quick-start)
21
+ - [Project Structure](#project-structure)
22
+ - [Available Components](#available-components)
23
+ - [Themes](#themes)
24
+ - [Hooks](#hooks)
25
+ - [Internationalization](#internationalization)
26
+ - [Storybook Documentation](#storybook-documentation)
27
+ - [Development](#development)
28
+ - [Customization](#customization)
29
+ - [Usage Examples](#usage-examples)
30
+ - [Compatibility](#compatibility)
31
+ - [Contributing](#contributing)
32
+ - [License](#license)
33
+
34
+ ---
35
+
36
+ ## Introduction
37
+
38
+ `@gouvfr-lasuite/ui-kit` is the official design system for **La Suite numérique**, the French government's collaborative tools ecosystem. This library provides a consistent set of reusable, accessible React components that comply with governmental design standards.
39
+
40
+ Built on top of [Cunningham](https://github.com/openfun/cunningham) (v4), this kit extends the design system capabilities with components specific to La Suite numérique needs.
41
+
42
+ ### Goals
43
+
44
+ - **Visual Consistency**: Ensure a uniform user experience across all La Suite numérique products
45
+ - **Accessibility**: Comply with WCAG and RGAA standards for maximum accessibility
46
+ - **Performance**: Optimized and tree-shakable components
47
+ - **Flexibility**: Support for multiple themes (DSFR, ANCT, White Label)
48
+ - **Developer-friendly**: Native TypeScript, comprehensive documentation, easy integration
49
+
50
+ ---
51
+
52
+ ## Features
53
+
54
+ - **25+ components** ready to use
55
+ - **Multiple themes**: DSFR, ANCT, White Label (light/dark)
56
+ - **Accessibility**: Keyboard navigation, screen readers, ARIA
57
+ - **Internationalization**: Built-in French and English support
58
+ - **Responsive**: Adaptive components with dedicated hooks
59
+ - **Layouts**: Page layout system with resizable panels
60
+ - **La Gaufre Integration**: Component for La Suite numérique services integration
61
+ - **TypeScript**: Full typing for better DX
62
+ - **Design tokens**: Customizable CSS/SCSS/TS token system
63
+
64
+ ---
65
+
66
+ ## Technologies
67
+
68
+ | Technology | Version | Usage |
69
+ |------------|---------|-------|
70
+ | React | 19.x | UI Framework |
71
+ | TypeScript | 5.6 | Static typing |
72
+ | Vite | 6.x | Bundler / Dev server |
73
+ | Cunningham | 4.1 | Base design system |
74
+ | Storybook | 8.5 | Documentation / Playground |
75
+ | Sass | 1.83 | CSS preprocessor |
76
+ | Vitest | 2.1 | Unit testing |
77
+ | react-aria-components | 1.8 | Accessible primitives |
78
+ | react-resizable-panels | 2.1 | Resizable panels |
79
+ | dnd-kit | 6.3 | Drag and Drop |
80
+
81
+ ---
82
+
83
+ ## Prerequisites
84
+
85
+ - **Node.js**: >= 20.x
86
+ - **Package manager**: yarn (recommended) or npm
87
+ - **React**: 19.x
88
+
89
+ ---
90
+
91
+ ## Installation
92
+
93
+ ### Via Yarn (recommended)
94
+
95
+ ```bash
96
+ yarn add @gouvfr-lasuite/ui-kit
97
+ ```
98
+
99
+ ### Via npm
100
+
101
+ ```bash
102
+ npm install @gouvfr-lasuite/ui-kit
103
+ ```
104
+
105
+ ### Peer dependencies
106
+
107
+ Make sure you have the peer dependencies installed:
108
+
109
+ ```bash
110
+ yarn add react react-dom
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Quick Start
116
+
117
+ ### 1. Import styles
118
+
119
+ In your entry file (e.g., `main.tsx` or `App.tsx`):
120
+
121
+ ```tsx
122
+ // UI Kit styles (includes Cunningham)
123
+ import "@gouvfr-lasuite/ui-kit/style";
124
+
125
+ // Optional: Marianne font
126
+ import "@gouvfr-lasuite/ui-kit/fonts/Marianne";
127
+ ```
128
+
129
+ ### 2. Configure the Provider
130
+
131
+ Wrap your application with the `CunninghamProvider`:
132
+
133
+ ```tsx
134
+ import { CunninghamProvider } from "@gouvfr-lasuite/ui-kit";
135
+
136
+ function App() {
137
+ return (
138
+ <CunninghamProvider>
139
+ <YourApp />
140
+ </CunninghamProvider>
141
+ );
142
+ }
143
+ ```
144
+
145
+ ### 3. Use components
146
+
147
+ ```tsx
148
+ import { MainLayout, QuickSearch, TreeView } from "@gouvfr-lasuite/ui-kit";
149
+
150
+ function MyPage() {
151
+ return (
152
+ <MainLayout
153
+ leftPanelContent={<TreeView data={treeData} />}
154
+ >
155
+ <QuickSearch placeholder="Search..." />
156
+ {/* Your content */}
157
+ </MainLayout>
158
+ );
159
+ }
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Project Structure
165
+
166
+ ```
167
+ ui-kit/
168
+ ├── src/
169
+ │ ├── components/ # React components
170
+ │ │ ├── badge/ # Badge
171
+ │ │ ├── button/ # Buttons (ProConnect)
172
+ │ │ ├── datagrid/ # Data grid
173
+ │ │ ├── dnd/ # Drag and Drop
174
+ │ │ ├── dropdown-menu/ # Dropdown menu
175
+ │ │ ├── filter/ # Filters
176
+ │ │ ├── footer/ # Footer
177
+ │ │ ├── form/ # Form fields
178
+ │ │ ├── hero/ # Hero section
179
+ │ │ ├── icon/ # Icons
180
+ │ │ ├── la-gaufre/ # La Suite integration
181
+ │ │ ├── language/ # Language selector
182
+ │ │ ├── layout/ # Layouts and panels
183
+ │ │ ├── loader/ # Loading indicators
184
+ │ │ ├── modal/ # Modals
185
+ │ │ ├── Provider/ # Cunningham Provider
186
+ │ │ ├── quick-search/ # Quick search
187
+ │ │ ├── separator/ # Separators
188
+ │ │ ├── share/ # Sharing and permissions
189
+ │ │ ├── tabs/ # Tabs
190
+ │ │ ├── tooltip/ # Tooltips
191
+ │ │ ├── tree-view/ # Tree view
192
+ │ │ └── users/ # User avatars and menus
193
+ │ ├── hooks/ # Custom React hooks
194
+ │ ├── locales/ # Translation files
195
+ │ ├── styles/ # Global styles and variables
196
+ │ ├── assets/ # Resources (fonts, images)
197
+ │ └── utils/ # Utilities
198
+ ├── .storybook/ # Storybook configuration
199
+ ├── cunningham.ts # Design tokens configuration
200
+ └── dist/ # Production build
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Available Components
206
+
207
+ ### Layout & Navigation
208
+
209
+ | Component | Description |
210
+ |-----------|-------------|
211
+ | `MainLayout` | Main layout with header and resizable panels |
212
+ | `Header` | Application header |
213
+ | `LeftPanel` | Left side panel (navigation) |
214
+ | `RightPanel` | Right side panel (details) |
215
+ | `Footer` | Official footer |
216
+ | `Tabs` | Tab navigation |
217
+ | `DropdownMenu` | Contextual dropdown menu |
218
+
219
+ ### Forms
220
+
221
+ | Component | Description |
222
+ |-----------|-------------|
223
+ | `Input` | Text input field |
224
+ | `Textarea` | Multi-line text area |
225
+ | `Select` | Selection list |
226
+ | `Checkbox` | Checkbox |
227
+ | `Radio` | Radio button |
228
+ | `Switch` | Toggle switch |
229
+ | `Label` | Field label |
230
+
231
+ ### Data & Display
232
+
233
+ | Component | Description |
234
+ |-----------|-------------|
235
+ | `TreeView` | Interactive tree view with pagination |
236
+ | `Datagrid` | Data grid |
237
+ | `QuickSearch` | Quick search bar (cmd+k) |
238
+ | `Badge` | Status badge |
239
+ | `Icon` | Material icons |
240
+ | `Loader` | Loading indicator |
241
+ | `Tooltip` | Tooltip |
242
+
243
+ ### Sharing & Collaboration
244
+
245
+ | Component | Description |
246
+ |-----------|-------------|
247
+ | `ShareModal` | Share modal with access management |
248
+ | `UserAvatar` | User avatar |
249
+ | `UserMenu` | User menu with logout |
250
+ | `UsersInvitation` | User invitation |
251
+
252
+ ### Integration
253
+
254
+ | Component | Description |
255
+ |-----------|-------------|
256
+ | `LaGaufre` | La Suite numérique services menu |
257
+ | `LaGaufreV2` | Enhanced version of La Gaufre |
258
+ | `ProConnectButton` | ProConnect login button |
259
+
260
+ ### Utilities
261
+
262
+ | Component | Description |
263
+ |-----------|-------------|
264
+ | `Modal` | Generic modal |
265
+ | `Separator` | Visual separator |
266
+ | `Hero` | Hero section |
267
+ | `Filter` | Filter component |
268
+ | `LanguageSelector` | Language selector |
269
+
270
+ ---
271
+
272
+ ## Themes
273
+
274
+ The UI Kit supports multiple predefined themes:
275
+
276
+ ### Available Themes
277
+
278
+ | Theme | Description |
279
+ |-------|-------------|
280
+ | `default` | White Label - Light mode |
281
+ | `dark` | White Label - Dark mode |
282
+ | `dsfr-light` | French State Design System - Light mode |
283
+ | `dsfr-dark` | French State Design System - Dark mode |
284
+ | `anct-light` | ANCT - Light mode |
285
+ | `anct-dark` | ANCT - Dark mode |
286
+
287
+ ### Using Themes
288
+
289
+ ```tsx
290
+ import { CunninghamProvider, cunninghamConfig } from "@gouvfr-lasuite/ui-kit";
291
+
292
+ // Use a predefined theme
293
+ <CunninghamProvider theme="dsfr-light">
294
+ <App />
295
+ </CunninghamProvider>
296
+ ```
297
+
298
+ ### Creating a Custom Theme
299
+
300
+ see [Cunningham docs](https://suitenumerique.github.io/cunningham/storybook/?path=/docs/getting-started-customization--docs) for more information
301
+
302
+
303
+
304
+ ## Hooks
305
+
306
+ ### useResponsive
307
+
308
+ Detects responsive breakpoints:
309
+
310
+ ```tsx
311
+ import { useResponsive } from "@gouvfr-lasuite/ui-kit";
312
+
313
+ function MyComponent() {
314
+ const { isMobile, isTablet, isDesktop } = useResponsive();
315
+
316
+ return isDesktop ? <DesktopView /> : <MobileView />;
317
+ }
318
+ ```
319
+
320
+
321
+
322
+ ### useCustomTranslations
323
+
324
+ Override default translations:
325
+
326
+ ```tsx
327
+ import { useCustomTranslations } from "@gouvfr-lasuite/ui-kit";
328
+
329
+ // In your Provider
330
+ const customTranslations = {
331
+ "en-US": {
332
+ components: {
333
+ share: {
334
+ modalTitle: "Share this document",
335
+ },
336
+ },
337
+ },
338
+ };
339
+ ```
340
+
341
+ ---
342
+
343
+ ## Internationalization
344
+
345
+ The UI Kit natively supports French and English.
346
+
347
+ ### Supported Languages
348
+
349
+ - `fr-FR` - French (default)
350
+ - `en-US` - English
351
+
352
+ ### Changing Language
353
+
354
+ ```tsx
355
+ <CunninghamProvider currentLanguage="en-US">
356
+ <App />
357
+ </CunninghamProvider>
358
+ ```
359
+
360
+ ### Contribute to add a language with a new PR
361
+
362
+ - Create a new translation file in `src/locales`
363
+ - Add all translations
364
+ - Create a PR
365
+
366
+ ### Adding Custom Translations dynamically
367
+
368
+ ```tsx
369
+ import { locales } from "@gouvfr-lasuite/ui-kit";
370
+
371
+ const customLocales = {
372
+ ...locales,
373
+ "de-DE": {
374
+ components: {
375
+ share: {
376
+ modalTitle: "Teilen",
377
+ // ...
378
+ },
379
+ },
380
+ },
381
+ };
382
+
383
+ <CunninghamProvider customLocales={customLocales}>
384
+ <App />
385
+ </CunninghamProvider>
386
+ ```
387
+
388
+
389
+
390
+ ---
391
+
392
+ ## Storybook Documentation
393
+
394
+ Interactive documentation is available via Storybook.
395
+
396
+ ### Run Storybook Locally
397
+
398
+ ```bash
399
+ yarn storybook
400
+ ```
401
+
402
+ Then access [http://localhost:6006](http://localhost:6006)
403
+
404
+
405
+
406
+ ---
407
+
408
+ ## Development
409
+
410
+ ### Install Dependencies
411
+
412
+ ```bash
413
+ yarn install
414
+ ```
415
+
416
+ ### Available Scripts
417
+
418
+ | Script | Description |
419
+ |--------|-------------|
420
+ | `yarn dev` | Start Vite development server |
421
+ | `yarn build` | Build library for production |
422
+ | `yarn lint` | Check code with ESLint |
423
+ | `yarn test` | Run tests with Vitest |
424
+ | `yarn storybook` | Start Storybook (port 6006) |
425
+ | `yarn build-storybook` | Build Storybook for deployment |
426
+ | `yarn build-theme` | Generate CSS/SCSS/TS token files |
427
+
428
+ ### Running Tests
429
+
430
+ ```bash
431
+ # Tests in watch mode
432
+ yarn test
433
+
434
+ # Tests with coverage
435
+ yarn test --coverage
436
+ ```
437
+
438
+ ### Component Structure
439
+
440
+ ```
441
+ src/components/my-component/
442
+ ├── index.tsx # Main export
443
+ ├── index.scss # Component styles
444
+ ├── MyComponent.tsx # React component
445
+ ├── types.ts # TypeScript types
446
+ └── my-component.stories.tsx # Storybook stories
447
+ ```
448
+
449
+ ---
450
+
451
+ ## Customization
452
+
453
+ ### Design Tokens
454
+
455
+ Design tokens are defined in `cunningham.ts` and can be overridden:
456
+
457
+ ```tsx
458
+ // Available tokens
459
+ {
460
+ globals: {
461
+ font: { sizes, weights, families },
462
+ spacings: { xs, sm, md, lg, xl, ... },
463
+ colors: { brand-*, gray-*, info-*, success-*, warning-*, error-* },
464
+ breakpoints: { xxs, xs, mobile, tablet },
465
+ },
466
+ contextutals: {
467
+ background: {
468
+ semantic: {
469
+ brand: {
470
+ primary: '..'
471
+ }
472
+ }
473
+ }
474
+ }
475
+
476
+ }
477
+ ```
478
+
479
+ ### CSS Variables
480
+
481
+ Tokens are exposed as CSS variables:
482
+
483
+ ```css
484
+ .my-custom-element {
485
+ color: var(--c--globals--colors--brand-500);
486
+ padding: var(--c--globals--spacings--md);
487
+ font-size: var(--c--globals--font--sizes--lg);
488
+ background: var(--c--contextuals--background--semantic--brand--primary);
489
+ }
490
+ ```
491
+
492
+ ### Utility Classes
493
+
494
+ ```html
495
+ <!-- Colors -->
496
+ <div class="clr-green-500">Primary text</div>
497
+ <div class="bg-success-500">Secondary background</div>
498
+
499
+ <!-- Spacing -->
500
+ <div class="p-md">Medium padding</div>
501
+ <div class="m-lg">Large margin</div>
502
+ ```
503
+
504
+ ---
505
+
506
+ ## Usage Examples
507
+
508
+ ### Layout with TreeView and Search
509
+
510
+ ```tsx
511
+ import {
512
+ CunninghamProvider,
513
+ MainLayout,
514
+ TreeView,
515
+ QuickSearch,
516
+ UserMenu,
517
+ } from "@gouvfr-lasuite/ui-kit";
518
+ import "@gouvfr-lasuite/ui-kit/style";
519
+
520
+ const treeData = [
521
+ {
522
+ id: "1",
523
+ name: "Documents",
524
+ children: [
525
+ { id: "1-1", name: "Report.pdf" },
526
+ { id: "1-2", name: "Notes.md" },
527
+ ],
528
+ },
529
+ ];
530
+
531
+ function App() {
532
+ return (
533
+ <CunninghamProvider>
534
+ <MainLayout
535
+ icon={<Logo />}
536
+ leftPanelContent={
537
+ <TreeView
538
+ data={treeData}
539
+ onSelect={(node) => console.log(node)}
540
+ />
541
+ }
542
+ rightHeaderContent={
543
+ <UserMenu
544
+ user={{ name: "John Doe", email: "john@example.com" }}
545
+ onLogout={() => {}}
546
+ />
547
+ }
548
+ >
549
+ <QuickSearch
550
+ onSearch={(query) => console.log(query)}
551
+ groups={[
552
+ {
553
+ title: "Recent documents",
554
+ items: [
555
+ { id: "1", label: "Q4 Report" },
556
+ { id: "2", label: "Budget 2024" },
557
+ ],
558
+ },
559
+ ]}
560
+ />
561
+ <main>Main content</main>
562
+ </MainLayout>
563
+ </CunninghamProvider>
564
+ );
565
+ }
566
+ ```
567
+
568
+ ### Share Modal
569
+
570
+ ```tsx
571
+ import { ShareModal } from "@gouvfr-lasuite/ui-kit";
572
+
573
+ function ShareButton() {
574
+ const [isOpen, setIsOpen] = useState(false);
575
+
576
+ return (
577
+ <>
578
+ <button onClick={() => setIsOpen(true)}>Share</button>
579
+ <ShareModal
580
+ isOpen={isOpen}
581
+ onClose={() => setIsOpen(false)}
582
+ members={[
583
+ { id: "1", name: "Marie", email: "marie@example.com", role: "editor" },
584
+ ]}
585
+ onAddMember={(user, role) => {}}
586
+ onRemoveMember={(userId) => {}}
587
+ onCopyLink={() => navigator.clipboard.writeText(window.location.href)}
588
+ />
589
+ </>
590
+ );
591
+ }
592
+ ```
593
+
594
+ ### Form with Validation
595
+
596
+ ```tsx
597
+ import { Input, Select, Switch, Label } from "@gouvfr-lasuite/ui-kit";
598
+
599
+ function ContactForm() {
600
+ return (
601
+ <form>
602
+ <div>
603
+ <Label htmlFor="name">Name</Label>
604
+ <Input id="name" placeholder="Your name" required />
605
+ </div>
606
+
607
+ <div>
608
+ <Label htmlFor="department">Department</Label>
609
+ <Select
610
+ id="department"
611
+ options={[
612
+ { value: "hr", label: "Human Resources" },
613
+ { value: "tech", label: "Technology" },
614
+ { value: "admin", label: "Administration" },
615
+ ]}
616
+ />
617
+ </div>
618
+
619
+ <div>
620
+ <Switch id="newsletter" />
621
+ <Label htmlFor="newsletter">Subscribe to newsletter</Label>
622
+ </div>
623
+ </form>
624
+ );
625
+ }
626
+ ```
627
+
628
+ ---
629
+
630
+ ## Compatibility
631
+
632
+ ### Supported Browsers
633
+
634
+ | Browser | Version |
635
+ |---------|---------|
636
+ | Chrome | Last 2 versions |
637
+ | Firefox | Last 2 versions |
638
+ | Safari | Last 2 versions |
639
+ | Edge | Last 2 versions |
640
+
641
+ ### Compatible Frameworks
642
+
643
+ - **React**: 19.x (peer dependency)
644
+ - **Next.js**: 14+ (with appropriate configuration)
645
+ - **Remix**: Compatible
646
+ - **Vite**: Optimized
647
+
648
+ ### Accessibility
649
+
650
+ - WCAG 2.1 Level AA compliant
651
+ - RGAA 4.1 compliant
652
+ - Full keyboard navigation
653
+ - Screen reader support (NVDA, VoiceOver, JAWS)
654
+
655
+ ---
656
+
657
+ ## Contributing
658
+
659
+ Contributions are welcome! See the [CONTRIBUTING.md](./CONTRIBUTING.md) file for details.
660
+
661
+ ### Contribution Process
662
+
663
+ 1. Fork the repository
664
+ 2. Create a feature branch (`git checkout -b feature/my-feature`)
665
+ 3. Commit your changes (follow commit conventions)
666
+ 4. Push the branch (`git push origin feature/my-feature`)
667
+ 5. Open a Pull Request
668
+
669
+ ### Commit Conventions
670
+
671
+ This project follows conventional commit conventions:
672
+
673
+ ```
674
+ type(scope): description
675
+
676
+ # Examples
677
+ feat(tree-view): add pagination support
678
+ fix(modal): resolve focus trap issue
679
+ docs(readme): update installation section
680
+ ```
681
+
682
+ ### Release
683
+
684
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the release process.
685
+
686
+ ---
687
+
688
+ ## License
689
+
690
+ This project is licensed under the **MIT License**. See the [LICENSE](./LICENSE) file for details.
691
+
692
+ ---
693
+
694
+ ## Support
695
+
696
+ - **Issues**: [GitHub Issues](https://github.com/suitenumerique/ui-kit/issues)
697
+ - **Documentation**: [Storybook](#storybook-documentation)
698
+ - **Cunningham**: [Cunningham Documentation](https://github.com/openfun/cunningham)
699
+
700
+ ---
701
+
702
+ <p align="center">
703
+ <strong>Made with care for La Suite numérique</strong><br>
704
+ <sub>A French government initiative</sub>
705
+ </p>