@abyss-project/commons-front-core 9.1.1 → 9.3.0
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 +63 -0
- package/catalog/catalog-entries.ts +12 -0
- package/catalog/pages/AmbientBackground.tsx +83 -0
- package/catalog/pages/AvatarGroup.tsx +45 -0
- package/catalog/pages/BarChart.tsx +127 -0
- package/catalog/pages/CompanySearchField.tsx +113 -0
- package/catalog/pages/ConfirmDialog.tsx +43 -1
- package/catalog/pages/ConfirmDialogWarning.tsx +45 -0
- package/catalog/pages/CopyField.tsx +24 -1
- package/catalog/pages/EntityImageField.tsx +124 -0
- package/catalog/pages/LineChart.tsx +138 -0
- package/catalog/pages/Pagination.tsx +52 -0
- package/catalog/pages/Section.tsx +16 -2
- package/catalog/pages/TeamAvatar.tsx +40 -0
- package/catalog/pages/UserPicker.tsx +124 -0
- package/catalog/pages/index.ts +20 -0
- package/dist/{AbyssCookieConsentProvider-B7-F6osY.js → AbyssCookieConsentProvider-CeDdkoPq.js} +104 -36
- package/dist/{CookieConsentSettings.component-DxQL4ULz.js → CookieConsentSettings.component-tJE0g-SS.js} +1 -1
- package/dist/components/data/BarChart/BarChart.d.ts +47 -0
- package/dist/components/data/BarChart/BarChart.spec.d.ts +1 -0
- package/dist/components/data/DataTable/DataTableDesktop.d.ts +1 -1
- package/dist/components/data/DataTable/DataTableMobile.d.ts +1 -1
- package/dist/components/data/DataTable/data-table.types.d.ts +6 -0
- package/dist/components/data/LineChart/LineChart.d.ts +44 -0
- package/dist/components/data/LineChart/LineChart.spec.d.ts +1 -0
- package/dist/components/data/LineChart/line-chart-ticks.d.ts +31 -0
- package/dist/components/data/LineChart/line-chart-ticks.spec.d.ts +1 -0
- package/dist/components/data/Pagination/Pagination.d.ts +16 -0
- package/dist/components/data/Pagination/Pagination.spec.d.ts +1 -0
- package/dist/components/data/chart-series-tone.d.ts +21 -0
- package/dist/components/data/chart-series-tone.spec.d.ts +1 -0
- package/dist/components/data/index.d.ts +4 -0
- package/dist/components/inputs/ColorField/ColorField.d.ts +8 -5
- package/dist/components/inputs/CompanySearchField/CompanySearchField.d.ts +24 -0
- package/dist/components/inputs/CompanySearchField/CompanySearchField.spec.d.ts +1 -0
- package/dist/components/inputs/CompanySearchField/pappers-company.d.ts +18 -0
- package/dist/components/inputs/CopyField/CopyField.d.ts +22 -6
- package/dist/components/inputs/EntityImageField/EntityImageField.d.ts +47 -0
- package/dist/components/inputs/EntityImageField/EntityImageField.spec.d.ts +1 -0
- package/dist/components/inputs/UserPicker/UserPicker.d.ts +50 -0
- package/dist/components/inputs/UserPicker/UserPicker.spec.d.ts +1 -0
- package/dist/components/inputs/index.d.ts +3 -0
- package/dist/components/layers/ConfirmDialog/ConfirmDialog.d.ts +6 -2
- package/dist/components/layers/ConfirmDialog/useConfirmDialog.d.ts +21 -0
- package/dist/components/layers/ConfirmDialog/useConfirmDialog.spec.d.ts +1 -0
- package/dist/components/layers/index.d.ts +1 -0
- package/dist/components/meaning/AvatarGroup/AvatarGroup.d.ts +22 -0
- package/dist/components/meaning/AvatarGroup/AvatarGroup.spec.d.ts +1 -0
- package/dist/components/meaning/TeamAvatar/TeamAvatar.d.ts +14 -0
- package/dist/components/meaning/TeamAvatar/TeamAvatar.spec.d.ts +1 -0
- package/dist/components/meaning/index.d.ts +2 -0
- package/dist/components/structure/AmbientBackground/AmbientBackground.d.ts +24 -0
- package/dist/components/structure/AmbientBackground/AmbientBackground.spec.d.ts +1 -0
- package/dist/components/structure/Section/Section.d.ts +10 -2
- package/dist/components/structure/index.d.ts +1 -0
- package/dist/cookie-consent.js +2 -2
- package/dist/design-theme-D3DQFMu-.js +27614 -0
- package/dist/hooks/use-rich-intl.hook.d.ts +68 -0
- package/dist/{index-uLh81uFU.js → index-3wZ_n-X5.js} +2 -2
- package/dist/{index-BuQlif6i.js → index-7E3aXufv.js} +2 -2
- package/dist/{index-iQhqBjKY.js → index-9E4QhCRp.js} +2 -2
- package/dist/{index-BtzB7aR_.js → index-B7yu6Zm9.js} +2 -2
- package/dist/{index-DkcMwm_T.js → index-BK4lWFRR.js} +3 -3
- package/dist/{index-2zbZ2URx.js → index-BTfe4Sz-.js} +3 -3
- package/dist/{index-CspGahq0.js → index-BbwAoYtC.js} +4 -4
- package/dist/{index-Waz6-pQr.js → index-BcUA-oDy.js} +4 -4
- package/dist/{index-CTP0QoCT.js → index-BfICcXrk.js} +3 -3
- package/dist/{index-DflXNluH.js → index-By24n0PI.js} +2 -2
- package/dist/{index-C5OyIHCq.js → index-CMyNL_Kk.js} +2 -2
- package/dist/{index-BloHDADq.js → index-CNMUrFys.js} +35281 -47311
- package/dist/{index-BMM6rvML.js → index-CTkBexi5.js} +2 -2
- package/dist/{index-Bhhwuj39.js → index-CUoOFhRH.js} +2 -2
- package/dist/{index-RkXYGPSf.js → index-CZvosKer.js} +4 -4
- package/dist/{index-uGXjK3xv.js → index-CzkoqdQK.js} +3 -3
- package/dist/{index-CsyAu658.js → index-D3QW807K.js} +2 -2
- package/dist/{index-IooWxH41.js → index-D6Gkj-V6.js} +2 -2
- package/dist/{index-Dew1ymFy.js → index-DYUdQPwj.js} +2 -2
- package/dist/{index-jhW25X__.js → index-DeoE1f9Z.js} +2 -2
- package/dist/{index-BXtPl6pH.js → index-F67JSDx7.js} +1 -1
- package/dist/{index-BAcf97X_.js → index-rpW-_Gh4.js} +2 -2
- package/dist/index.js +5979 -4545
- package/dist/legacy/components/CompanySearchAutocomplete/CompanySearchAutocomplete.d.ts +2 -14
- package/dist/legacy/components/Layouts/AbyssFamilyBanner/AbyssFamilyBanner.component.d.ts +3 -7
- package/dist/legacy/utils/file.utils.d.ts +1 -2
- package/dist/legacy.js +107 -107
- package/dist/theme/tokens/choice-swatches.d.ts +12 -0
- package/dist/theme/tokens/choice-swatches.spec.d.ts +1 -0
- package/dist/theme/tokens/index.d.ts +1 -0
- package/dist/theme/tokens/semantic.d.ts +4 -1
- package/dist/translations/en.d.ts +34 -0
- package/dist/translations/fr.d.ts +34 -0
- package/dist/utils/family.d.ts +12 -0
- package/dist/utils/file.utils.d.ts +10 -0
- package/dist/utils/file.utils.spec.d.ts +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/package.json +1 -1
- package/dist/design-theme-BztWe75w.js +0 -15490
package/README.md
CHANGED
|
@@ -90,6 +90,69 @@ export const buildRumOptions = () =>
|
|
|
90
90
|
|
|
91
91
|
## Changements visibles
|
|
92
92
|
|
|
93
|
+
### 9.3.0
|
|
94
|
+
|
|
95
|
+
Pages des outils du front principal sur le design system (carte #286, zone 4a). Pièces nouvelles et évolutions,
|
|
96
|
+
chacune documentée dans le `README.md` de son dossier et montrée dans le catalogue.
|
|
97
|
+
|
|
98
|
+
- **`BarChart`** (`data`) : barres Nivo sous `abyssNivoTheme`, groupées ou empilées (`stacked`), verticales ou
|
|
99
|
+
horizontales (`BarChartLayout`) ; une série par `id`, une catégorie par groupe, une clé absente n'est pas une barre ;
|
|
100
|
+
infobulle à la valeur propre de la série ; légende au-delà d'une série ; figure nommée et tableau des valeurs pour
|
|
101
|
+
les lecteurs d'écran ; « Aucune donnée à afficher » sans valeur. Graduations de l'axe des catégories selon la
|
|
102
|
+
largeur mesurée. Remplace `AbyssBarChart`.
|
|
103
|
+
- **Ton sémantique des séries** (`data`) : `ChartSeriesTone` (`Success`, `Warning`, `Danger`, `Info`, `Neutral`) et
|
|
104
|
+
`seriesColorTokens`, partagés par `LineChart` et `BarChart`. Une série à ton prend le jeton `status.*` de son ton ;
|
|
105
|
+
les séries sans ton gardent la palette `data.series.*` dans leur ordre (ADR-0174, avenant 9.3.0).
|
|
106
|
+
- **`LineChart`** (`data`) : `tone` par série et `stacked` (aires empilées depuis zéro, une abscisse absente d'une
|
|
107
|
+
série comptée à zéro ; infobulle et tableau gardent les valeurs propres). Le reste du contrat 9.2.0 est inchangé.
|
|
108
|
+
- **`AmbientBackground`** (`structure`) : fond de décor animé et sobre (lueurs d'`accent` et de `data.series.5` en
|
|
109
|
+
`color-mix` sur les variables `--abyss-*`), `aria-hidden`, hors du flux, `Viewport` ou `Container` ; figé sous
|
|
110
|
+
`prefers-reduced-motion`, sous 768 px et avec `paused`, état exposé par `data-motion`. Remplace `WaterParticles`.
|
|
111
|
+
- **`ConfirmDialogTone.Warning`** (`layers`) : bouton en `status.warning`, texte dans l'encre `paper`/`paper.on` la
|
|
112
|
+
plus contrastée, focus initial sur « Annuler » ; accepté par `useConfirmDialog`.
|
|
113
|
+
- **`DataTable`** (`data`) : `label` facultatif, nom accessible de la table et de la liste mobile.
|
|
114
|
+
- **Palette de choix** (`theme`) : `CHOICE_SWATCHES`, douze teintes catégorielles (une tous les 30° depuis la teinte
|
|
115
|
+
de marque, `0.72 0.12` en OKLCH), valeurs hexadécimales stables, lisibles sous l'encre `paper.on` à 4,5:1 au moins
|
|
116
|
+
dans les deux thèmes. **`ColorField`** les propose quand l'hôte ne passe pas `swatches` (devenu facultatif).
|
|
117
|
+
- **Utilitaires sortis de `legacy/`** : `getFileIcon` et `getFileColor` sont exportés de la racine ; `getFileColor`
|
|
118
|
+
y rend une couleur des jetons, `var(--abyss-data-series-n)` ou `var(--abyss-text-muted)`.
|
|
119
|
+
- **Traductions** : clés `ds.data.bar-chart.*` (FR et EN).
|
|
120
|
+
|
|
121
|
+
### 9.2.0
|
|
122
|
+
|
|
123
|
+
Organisation et projet du front principal sur le design system (carte #286, zone 3). Pièces nouvelles et évolutions,
|
|
124
|
+
chacune documentée dans le `README.md` de son dossier et montrée dans le catalogue.
|
|
125
|
+
|
|
126
|
+
- **`AvatarGroup`** (`meaning`) : pile d'avatars nommés, `max` au-delà duquel « +N » est nommé par les noms restants (`intl.formatList`) et les liste en infobulle ; aucun élément interactif. Remplace `UserAvatarList`.
|
|
127
|
+
- **`TeamAvatar`** (`meaning`) : initiale d'équipe sur sa couleur, encre `paper` ou `paper.on` la plus contrastée ; une couleur absente ou illisible (`CSS.supports`) donne la teinte neutre au lieu d'une exception (dette `DS-TEAM-COLOR`).
|
|
128
|
+
- **`Pagination`** (`data`) : précédent, numéros de page avec ellipses (sept places fixes), suivant ; page courante
|
|
129
|
+
en `aria-current="page"`, bornes désactivées, rien sous deux pages ; sous 768 px, précédent, « Page x sur y »,
|
|
130
|
+
suivant, cibles de 44 px.
|
|
131
|
+
- **`LineChart`** (`data`) : courbes Nivo sous `abyssNivoTheme`, échelle de temps ou linéaire, aire facultative ;
|
|
132
|
+
couleurs prises dans l'ordre de la palette de séries, jamais passées par l'hôte ; légende au-delà d'une série ;
|
|
133
|
+
figure nommée et tableau des valeurs pour les lecteurs d'écran ; « Aucune donnée à afficher » sans point.
|
|
134
|
+
Graduations de l'axe x selon la largeur mesurée du graphique (et non celle de l'écran) : pas le plus fin, jamais plus
|
|
135
|
+
fin que les données, dont les libellés mono gardent `space[8]` entre eux ; un libellé qui déborderait des marges
|
|
136
|
+
n'est pas affiché.
|
|
137
|
+
- **Palette de séries** (`theme`) : jetons `data.series.1` à `data.series.6` (et `--abyss-data-series-*`), ordre
|
|
138
|
+
exporté par `DATA_SERIES_TOKENS` ; luminosité et chroma égales, 3:1 au moins sur les fonds (ADR-0174, avenant).
|
|
139
|
+
- **`UserPicker`** (`inputs`) : choix simple ou multiple d'utilisateurs (`{ id, name, email, pictureUrl }`), avatar,
|
|
140
|
+
nom et e-mail par option ; filtre local sur le nom et l'e-mail, ou recherche serveur par `onSearch` avec `loading` ;
|
|
141
|
+
`disabledIds` ; en multiple, puces parcourues à la flèche gauche et retirées par Retour arrière ou Suppr ; sous
|
|
142
|
+
768 px, 44 px par option, puces de 44 px de haut dont la croix de retrait est un carré tactile, et texte du champ
|
|
143
|
+
jamais plus étroit que 44 px quand les puces remplissent la ligne.
|
|
144
|
+
- **`CompanySearchField`** (`inputs`) : contrat de `CompanySearchAutocomplete` (Pappers, `onSelect(PappersCompany)`,
|
|
145
|
+
erreur distincte d'une réponse vide, date de création dans la langue de l'utilisateur) sur `FormField` et les jetons
|
|
146
|
+
du core ; temporisation annulée au démontage, réponse dépassée ignorée.
|
|
147
|
+
- **Types sortis de `legacy/`** : `PappersCompany` et `CurrentFamilyInfo` (avec `CurrentFamilyStatus`) sont exportés de
|
|
148
|
+
la racine ; `/legacy` les réexporte.
|
|
149
|
+
- **Traductions** : clés `ds.inputs.user-picker.*` et `ds.inputs.company-search-field.*` (FR et EN).
|
|
150
|
+
- **`EntityImageField`** (`inputs`) : image d'entité changée sur place, `EntityImageVariant.Avatar` (pastille d'appareil photo, `EntityImageShape.Round` ou `Square`) ou `Banner` (bouton en surimpression) ; sélecteur de l'appareil, ou menu d'`ImportButton` avec `cloudImport` ; envoi indiqué, annoncé, et bloquant.
|
|
151
|
+
- **`useConfirmDialog`** et **`ConfirmDialogProvider`** (`layers`) : `confirm(options)` renvoie `Promise<boolean>` et ouvre le `ConfirmDialog` ; une demande à la fois, les suivantes attendent ; hors du fournisseur, une erreur qui le nomme.
|
|
152
|
+
- **`CopyField.loadValue`** : la valeur n'est demandée qu'au premier « Afficher » ou « Copier », puis gardée ; chargement sur le bouton, échec annoncé et rejouable. `value` et `loadValue` sont exclusifs.
|
|
153
|
+
- **`Section tone`** : `SectionTone.Danger` met le titre et un filet en `status.danger` (zones de danger).
|
|
154
|
+
- **`DataTable`, liste mobile** : sous 768 px, chaque contrôle de la colonne `trailing` (lien, bouton, `role="button"`, `role="link"`, `role="menuitem"`) offre une cible de 44 × 44 (`densityValues.touchTarget`), même rendu en `size="small"` par l'hôte ; rien ne change à partir de 768 px.
|
|
155
|
+
|
|
93
156
|
### 9.1.1
|
|
94
157
|
|
|
95
158
|
- **`useServiceTour`** : sous un `AbyssCookieConsentProvider`, une première visite attend que le bandeau de cookies
|
|
@@ -52,6 +52,9 @@ export const CATALOG_ENTRIES: CatalogEntry[] = [
|
|
|
52
52
|
entry('FilterBar', 'structure', 'filter-bar', RESPONSIVE),
|
|
53
53
|
entry('SplitView', 'structure', 'split-view', RESPONSIVE),
|
|
54
54
|
entry('Tabs', 'structure', 'tabs', RESPONSIVE),
|
|
55
|
+
entry('AmbientBackground', 'structure', 'ambient-background', {
|
|
56
|
+
mobileCapture: true,
|
|
57
|
+
}),
|
|
55
58
|
entry('NotificationsMenu', 'structure', 'notifications-menu', {
|
|
56
59
|
mobileCapture: true,
|
|
57
60
|
}),
|
|
@@ -66,6 +69,9 @@ export const CATALOG_ENTRIES: CatalogEntry[] = [
|
|
|
66
69
|
entry('KeyValueList', 'data', 'key-value-list'),
|
|
67
70
|
entry('StatTile', 'data', 'stat-tile'),
|
|
68
71
|
entry('Sparkline', 'data', 'sparkline'),
|
|
72
|
+
entry('Pagination', 'data', 'pagination', RESPONSIVE),
|
|
73
|
+
entry('LineChart', 'data', 'line-chart'),
|
|
74
|
+
entry('BarChart', 'data', 'bar-chart'),
|
|
69
75
|
entry('ChartTheme', 'data', 'chart-theme'),
|
|
70
76
|
entry('UsageMeter', 'data', 'usage-meter'),
|
|
71
77
|
entry('StatusBadge', 'meaning', 'status-badge'),
|
|
@@ -75,6 +81,8 @@ export const CATALOG_ENTRIES: CatalogEntry[] = [
|
|
|
75
81
|
entry('RoleBadge', 'meaning', 'role-badge'),
|
|
76
82
|
entry('ToolIcon', 'meaning', 'tool-icon'),
|
|
77
83
|
entry('Avatar', 'meaning', 'avatar'),
|
|
84
|
+
entry('AvatarGroup', 'meaning', 'avatar-group'),
|
|
85
|
+
entry('TeamAvatar', 'meaning', 'team-avatar'),
|
|
78
86
|
entry('InfectedDownloadModal', 'business', 'infected-download-modal'),
|
|
79
87
|
entry('CloudImport', 'business', 'cloud-import', RESPONSIVE),
|
|
80
88
|
entry('ImportFromCloudModal', 'business', 'import-from-cloud-modal', {
|
|
@@ -83,6 +91,7 @@ export const CATALOG_ENTRIES: CatalogEntry[] = [
|
|
|
83
91
|
entry('QRCodeModal', 'business', 'qr-code-modal', { mobileCapture: true }),
|
|
84
92
|
entry('Modal', 'layers', 'modal', { mobileCapture: true }),
|
|
85
93
|
entry('ConfirmDialog', 'layers', 'confirm-dialog'),
|
|
94
|
+
entry('ConfirmDialogWarning', 'layers', 'confirm-dialog-warning'),
|
|
86
95
|
entry('Drawer', 'layers', 'drawer'),
|
|
87
96
|
entry('Menu', 'layers', 'menu'),
|
|
88
97
|
entry('Toast', 'layers', 'toast'),
|
|
@@ -97,6 +106,9 @@ export const CATALOG_ENTRIES: CatalogEntry[] = [
|
|
|
97
106
|
entry('NumberField', 'inputs', 'number-field'),
|
|
98
107
|
entry('SettingsRow', 'inputs', 'settings-row', RESPONSIVE),
|
|
99
108
|
entry('CopyField', 'inputs', 'copy-field', RESPONSIVE),
|
|
109
|
+
entry('UserPicker', 'inputs', 'user-picker', RESPONSIVE),
|
|
110
|
+
entry('CompanySearchField', 'inputs', 'company-search-field', RESPONSIVE),
|
|
111
|
+
entry('EntityImageField', 'inputs', 'entity-image-field', RESPONSIVE),
|
|
100
112
|
entry('ContextSelector', 'inputs', 'context-selector', RESPONSIVE),
|
|
101
113
|
entry('DropZone', 'inputs', 'drop-zone', RESPONSIVE),
|
|
102
114
|
entry('ImportButton', 'inputs', 'import-button'),
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import Button from '@mui/material/Button';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
AmbientBackground,
|
|
7
|
+
AmbientBackgroundPlacement,
|
|
8
|
+
} from '../../src/components/structure/AmbientBackground/AmbientBackground';
|
|
9
|
+
import { hairline, px } from '../../src/theme/components/shared';
|
|
10
|
+
import { Example, Showcase } from '../frame';
|
|
11
|
+
|
|
12
|
+
/** A panel the background stops at: positioned, clipped, as a host lays it out. */
|
|
13
|
+
const Panel = styled('div')(({ theme }) => {
|
|
14
|
+
const { tokens, space, radii, typeScale } = theme.design;
|
|
15
|
+
return {
|
|
16
|
+
position: 'relative',
|
|
17
|
+
overflow: 'hidden',
|
|
18
|
+
display: 'flex',
|
|
19
|
+
flexDirection: 'column',
|
|
20
|
+
alignItems: 'flex-start',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
gap: px(space[3]),
|
|
23
|
+
minHeight: px(space[10] * 4),
|
|
24
|
+
padding: px(space[6]),
|
|
25
|
+
backgroundColor: tokens['bg.canvas'],
|
|
26
|
+
border: hairline(tokens['border.subtle']),
|
|
27
|
+
borderRadius: px(radii.md),
|
|
28
|
+
color: tokens['text.primary'],
|
|
29
|
+
fontSize: px(typeScale.body),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/** The content of a panel, laid above its background. */
|
|
34
|
+
const Content = styled('div')(({ theme }) => ({
|
|
35
|
+
position: 'relative',
|
|
36
|
+
display: 'flex',
|
|
37
|
+
flexDirection: 'column',
|
|
38
|
+
alignItems: 'flex-start',
|
|
39
|
+
gap: px(theme.design.space[2]),
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
const Title = styled('strong')(({ theme }) => ({
|
|
43
|
+
fontSize: px(theme.design.typeScale.sectionTitle),
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
const PausableScanner = () => {
|
|
47
|
+
const [scanning, setScanning] = useState(true);
|
|
48
|
+
return (
|
|
49
|
+
<Panel>
|
|
50
|
+
<AmbientBackground
|
|
51
|
+
placement={AmbientBackgroundPlacement.Container}
|
|
52
|
+
paused={!scanning}
|
|
53
|
+
/>
|
|
54
|
+
<Content>
|
|
55
|
+
<Title>{scanning ? 'Analyse en cours…' : 'Analyse terminée'}</Title>
|
|
56
|
+
<Button variant="outlined" onClick={() => setScanning(!scanning)}>
|
|
57
|
+
{scanning ? 'Figer le fond' : 'Relancer le fond'}
|
|
58
|
+
</Button>
|
|
59
|
+
</Content>
|
|
60
|
+
</Panel>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const AmbientBackgroundPage = () => (
|
|
65
|
+
<Showcase
|
|
66
|
+
family="Structure"
|
|
67
|
+
name="AmbientBackground"
|
|
68
|
+
description="Fond de décor : lueurs d'accent et de data.series.5 qui dérivent lentement sous le contenu, masquées aux lecteurs d'écran, figées sous prefers-reduced-motion, sous 768 px et en pause."
|
|
69
|
+
>
|
|
70
|
+
<Example title="Dans un panneau (placement Container)">
|
|
71
|
+
<Panel>
|
|
72
|
+
<AmbientBackground placement={AmbientBackgroundPlacement.Container} />
|
|
73
|
+
<Content>
|
|
74
|
+
<Title>Envoyez vos fichiers avec Beam</Title>
|
|
75
|
+
<span>Le fond reste sous le contenu et ne prend aucun clic.</span>
|
|
76
|
+
</Content>
|
|
77
|
+
</Panel>
|
|
78
|
+
</Example>
|
|
79
|
+
<Example title="En pause : le scanner de Probe entre deux analyses">
|
|
80
|
+
<PausableScanner />
|
|
81
|
+
</Example>
|
|
82
|
+
</Showcase>
|
|
83
|
+
);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AvatarGroup } from '../../src/components/meaning/AvatarGroup/AvatarGroup';
|
|
2
|
+
import type { AvatarGroupPerson } from '../../src/components/meaning/AvatarGroup/AvatarGroup';
|
|
3
|
+
import { LogoAbyssSmall } from '../../src/assets';
|
|
4
|
+
import { Example, Showcase } from '../frame';
|
|
5
|
+
|
|
6
|
+
const PEOPLE: AvatarGroupPerson[] = [
|
|
7
|
+
{ id: 'u1', name: 'Mehdi', pictureUrl: LogoAbyssSmall },
|
|
8
|
+
{ id: 'u2', name: 'Camille', pictureUrl: null },
|
|
9
|
+
{ id: 'u3', name: 'Lina', pictureUrl: null },
|
|
10
|
+
// A picture that cannot load: the initial stays.
|
|
11
|
+
{ id: 'u4', name: 'Paul', pictureUrl: '/catalogue-introuvable/u4.png' },
|
|
12
|
+
{ id: 'u5', name: 'Zoé', pictureUrl: null },
|
|
13
|
+
{ id: 'u6', name: 'Hugo', pictureUrl: null },
|
|
14
|
+
{ id: 'u7', name: 'Inès', pictureUrl: null },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
export const AvatarGroupPage = () => (
|
|
18
|
+
<Showcase
|
|
19
|
+
family="Sens"
|
|
20
|
+
name="AvatarGroup"
|
|
21
|
+
description="Personnes en pile : la photo ou l'initiale, chaque avatar nommé. Au-delà de max, « +N » compte les autres et les nomme dans une infobulle. Rien n'est interactif."
|
|
22
|
+
>
|
|
23
|
+
<Example title="Tout le monde (sans max)" framed>
|
|
24
|
+
<AvatarGroup people={PEOPLE.slice(0, 4)} label="Membres de Design" />
|
|
25
|
+
</Example>
|
|
26
|
+
<Example title="max = 3 : « +4 », noms au survol" framed>
|
|
27
|
+
<AvatarGroup people={PEOPLE} max={3} label="Membres de Ops" />
|
|
28
|
+
</Example>
|
|
29
|
+
<Example title="Tailles : 22, 32 (défaut), 40" framed>
|
|
30
|
+
<AvatarGroup
|
|
31
|
+
people={PEOPLE}
|
|
32
|
+
max={4}
|
|
33
|
+
size={22}
|
|
34
|
+
label="Membres de Support"
|
|
35
|
+
/>
|
|
36
|
+
<AvatarGroup people={PEOPLE} max={4} label="Membres de Finance" />
|
|
37
|
+
<AvatarGroup
|
|
38
|
+
people={PEOPLE}
|
|
39
|
+
max={4}
|
|
40
|
+
size={40}
|
|
41
|
+
label="Membres de Ventes"
|
|
42
|
+
/>
|
|
43
|
+
</Example>
|
|
44
|
+
</Showcase>
|
|
45
|
+
);
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BarChart,
|
|
3
|
+
BarChartLayout,
|
|
4
|
+
} from '../../src/components/data/BarChart/BarChart';
|
|
5
|
+
import type {
|
|
6
|
+
BarChartCategory,
|
|
7
|
+
BarChartSeries,
|
|
8
|
+
} from '../../src/components/data/BarChart/BarChart';
|
|
9
|
+
import { ChartSeriesTone } from '../../src/components/data/chart-series-tone';
|
|
10
|
+
import { Surface } from '../../src/components/structure/Surface/Surface';
|
|
11
|
+
import { Example, Showcase } from '../frame';
|
|
12
|
+
|
|
13
|
+
const count = new Intl.NumberFormat('fr-FR');
|
|
14
|
+
const seconds = new Intl.NumberFormat('fr-FR', {
|
|
15
|
+
style: 'unit',
|
|
16
|
+
unit: 'second',
|
|
17
|
+
maximumFractionDigits: 1,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const DURATION: BarChartSeries[] = [{ id: 'duration', label: 'Durée moyenne' }];
|
|
21
|
+
|
|
22
|
+
const CONFIGS: BarChartCategory[] = [
|
|
23
|
+
{ id: 'invoice', label: 'Factures', values: { duration: 4.2 } },
|
|
24
|
+
{ id: 'receipt', label: 'Reçus', values: { duration: 2.8 } },
|
|
25
|
+
{ id: 'payslip', label: 'Bulletins de paie', values: { duration: 6.1 } },
|
|
26
|
+
{ id: 'id-card', label: 'Pièces d’identité', values: { duration: 3.4 } },
|
|
27
|
+
{ id: 'bank', label: 'Relevés bancaires', values: { duration: 7.9 } },
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const OUTCOMES: BarChartSeries[] = [
|
|
31
|
+
{ id: 'succeeded', label: 'Réussies', tone: ChartSeriesTone.Success },
|
|
32
|
+
{ id: 'failed', label: 'Échouées', tone: ChartSeriesTone.Danger },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const OUTCOMES_BY_CONFIG: BarChartCategory[] = [
|
|
36
|
+
{ id: 'invoice', label: 'Factures', values: { succeeded: 412, failed: 9 } },
|
|
37
|
+
{ id: 'receipt', label: 'Reçus', values: { succeeded: 268, failed: 21 } },
|
|
38
|
+
{ id: 'payslip', label: 'Bulletins', values: { succeeded: 133 } },
|
|
39
|
+
{ id: 'id-card', label: 'Identité', values: { succeeded: 96, failed: 14 } },
|
|
40
|
+
{ id: 'bank', label: 'Relevés', values: { succeeded: 57, failed: 3 } },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const TOOLS: BarChartSeries[] = ['Atlas', 'Board', 'Draw'].map((label) => ({
|
|
44
|
+
id: label.toLowerCase(),
|
|
45
|
+
label,
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
const MONTHS = [
|
|
49
|
+
'Jan.',
|
|
50
|
+
'Fév.',
|
|
51
|
+
'Mars',
|
|
52
|
+
'Avr.',
|
|
53
|
+
'Mai',
|
|
54
|
+
'Juin',
|
|
55
|
+
'Juil.',
|
|
56
|
+
'Août',
|
|
57
|
+
'Sept.',
|
|
58
|
+
'Oct.',
|
|
59
|
+
'Nov.',
|
|
60
|
+
'Déc.',
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
const BY_MONTH: BarChartCategory[] = MONTHS.map((label, month) => ({
|
|
64
|
+
id: `m${month + 1}`,
|
|
65
|
+
label,
|
|
66
|
+
values: Object.fromEntries(
|
|
67
|
+
TOOLS.map(({ id }, index) => [
|
|
68
|
+
id,
|
|
69
|
+
12 + index * 6 + Math.round(8 * Math.sin((month + index) / 2)),
|
|
70
|
+
]),
|
|
71
|
+
),
|
|
72
|
+
}));
|
|
73
|
+
|
|
74
|
+
export const BarChartPage = () => (
|
|
75
|
+
<Showcase
|
|
76
|
+
family="Données"
|
|
77
|
+
name="BarChart"
|
|
78
|
+
description="Barres Nivo sous abyssNivoTheme, groupées ou empilées, verticales ou horizontales : palette data.series ou ton status.* quand la série porte un sens, légende au-delà d'une série, figure nommée et tableau des valeurs pour les lecteurs d'écran."
|
|
79
|
+
>
|
|
80
|
+
<Example title="Une série, horizontale">
|
|
81
|
+
<Surface padding={4}>
|
|
82
|
+
<BarChart
|
|
83
|
+
series={DURATION}
|
|
84
|
+
categories={CONFIGS}
|
|
85
|
+
height={220}
|
|
86
|
+
layout={BarChartLayout.Horizontal}
|
|
87
|
+
formatValue={(value) => seconds.format(value)}
|
|
88
|
+
label="Durée moyenne d’une extraction par configuration"
|
|
89
|
+
/>
|
|
90
|
+
</Surface>
|
|
91
|
+
</Example>
|
|
92
|
+
<Example title="Empilées, séries à ton (réussites et échecs)">
|
|
93
|
+
<Surface padding={4}>
|
|
94
|
+
<BarChart
|
|
95
|
+
series={OUTCOMES}
|
|
96
|
+
categories={OUTCOMES_BY_CONFIG}
|
|
97
|
+
height={240}
|
|
98
|
+
stacked
|
|
99
|
+
formatValue={(value) => count.format(value)}
|
|
100
|
+
label="Extractions réussies et échouées par configuration"
|
|
101
|
+
/>
|
|
102
|
+
</Surface>
|
|
103
|
+
</Example>
|
|
104
|
+
<Example title="Groupées, palette de séries, douze catégories">
|
|
105
|
+
<Surface padding={4}>
|
|
106
|
+
<BarChart
|
|
107
|
+
series={TOOLS}
|
|
108
|
+
categories={BY_MONTH}
|
|
109
|
+
height={240}
|
|
110
|
+
formatValue={(value) => count.format(value)}
|
|
111
|
+
label="Contenus créés par outil et par mois"
|
|
112
|
+
/>
|
|
113
|
+
</Surface>
|
|
114
|
+
</Example>
|
|
115
|
+
<Example title="Aucune donnée">
|
|
116
|
+
<Surface padding={4}>
|
|
117
|
+
<BarChart
|
|
118
|
+
series={DURATION}
|
|
119
|
+
categories={[]}
|
|
120
|
+
height={160}
|
|
121
|
+
formatValue={(value) => seconds.format(value)}
|
|
122
|
+
label="Durée moyenne d’une extraction par configuration"
|
|
123
|
+
/>
|
|
124
|
+
</Surface>
|
|
125
|
+
</Example>
|
|
126
|
+
</Showcase>
|
|
127
|
+
);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { CompanySearchField } from '../../src/components/inputs/CompanySearchField/CompanySearchField';
|
|
3
|
+
import type { PappersCompany } from '../../src/components/inputs/CompanySearchField/pappers-company';
|
|
4
|
+
import { Example, LastEvent, Showcase, useEventLog } from '../frame';
|
|
5
|
+
|
|
6
|
+
const COMPANIES: PappersCompany[] = [
|
|
7
|
+
{
|
|
8
|
+
siren: '901234567',
|
|
9
|
+
nom_entreprise: 'ABYSS PROJECT',
|
|
10
|
+
date_creation: '2021-09-14',
|
|
11
|
+
forme_juridique: 'SAS',
|
|
12
|
+
domaine_activite: 'Édition de logiciels applicatifs',
|
|
13
|
+
siege: {
|
|
14
|
+
adresse: '12 rue de la Paix',
|
|
15
|
+
code_postal: '75002',
|
|
16
|
+
ville: 'Paris',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
siren: '812345678',
|
|
21
|
+
nom_entreprise:
|
|
22
|
+
'ABYSSAL CONSEIL ET ACCOMPAGNEMENT DES ENTREPRISES DE LA RÉGION AUVERGNE-RHÔNE-ALPES',
|
|
23
|
+
date_creation: '2016-02-03',
|
|
24
|
+
forme_juridique: 'SARL',
|
|
25
|
+
siege: { ville: 'Lyon' },
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
siren: '723456789',
|
|
29
|
+
nom_entreprise: 'KARBON STUDIO',
|
|
30
|
+
date_creation: '2012-06-30',
|
|
31
|
+
forme_juridique: 'EURL',
|
|
32
|
+
domaine_activite: 'Activités photographiques',
|
|
33
|
+
siege: {
|
|
34
|
+
adresse: '4 quai des Chartrons',
|
|
35
|
+
code_postal: '33000',
|
|
36
|
+
ville: 'Bordeaux',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
/** The text that makes the stand-in for Pappers fail, to show the error state. */
|
|
42
|
+
const FAILING_QUERY = 'panne';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Pappers answered from memory while the page is shown: the catalog has no network. Typing
|
|
46
|
+
* « panne » shows the error state.
|
|
47
|
+
*/
|
|
48
|
+
const usePappersFromMemory = () => {
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const realFetch = window.fetch;
|
|
51
|
+
window.fetch = async (input, init) => {
|
|
52
|
+
const url = new URL(
|
|
53
|
+
typeof input === 'string' || input instanceof URL ? input : input.url,
|
|
54
|
+
);
|
|
55
|
+
if (url.hostname !== 'suggestions.pappers.fr') {
|
|
56
|
+
return realFetch(input, init);
|
|
57
|
+
}
|
|
58
|
+
const query = (url.searchParams.get('q') ?? '').toLowerCase();
|
|
59
|
+
if (query.includes(FAILING_QUERY)) {
|
|
60
|
+
return new Response(null, { status: 503 });
|
|
61
|
+
}
|
|
62
|
+
const found = COMPANIES.filter((company) =>
|
|
63
|
+
company.nom_entreprise.toLowerCase().includes(query),
|
|
64
|
+
);
|
|
65
|
+
return new Response(JSON.stringify({ resultats_nom_entreprise: found }), {
|
|
66
|
+
status: 200,
|
|
67
|
+
headers: { 'Content-Type': 'application/json' },
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
return () => {
|
|
71
|
+
window.fetch = realFetch;
|
|
72
|
+
};
|
|
73
|
+
}, []);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const CompanySearchFieldPage = () => {
|
|
77
|
+
const { log } = useEventLog();
|
|
78
|
+
const [name, setName] = useState('');
|
|
79
|
+
const [filled, setFilled] = useState('ABYSS PROJECT');
|
|
80
|
+
usePappersFromMemory();
|
|
81
|
+
return (
|
|
82
|
+
<Showcase
|
|
83
|
+
family="Saisie"
|
|
84
|
+
name="CompanySearchField"
|
|
85
|
+
description="Nom d'entreprise avec les suggestions de Pappers : forme juridique, SIREN, date de création, siège et activité. Une requête en échec met le champ en erreur, distincte d'une recherche sans résultat. Ici, Pappers répond de mémoire (« abyss », « karbon » ; « panne » simule une panne)."
|
|
86
|
+
>
|
|
87
|
+
<Example title="Recherche" maxWidth={640}>
|
|
88
|
+
<CompanySearchField
|
|
89
|
+
value={name}
|
|
90
|
+
onInputChange={setName}
|
|
91
|
+
onSelect={(company) => log(`entreprise ${company.siren}`)}
|
|
92
|
+
/>
|
|
93
|
+
</Example>
|
|
94
|
+
<Example title="Nom déjà saisi" maxWidth={640}>
|
|
95
|
+
<CompanySearchField
|
|
96
|
+
value={filled}
|
|
97
|
+
onInputChange={setFilled}
|
|
98
|
+
onSelect={(company) => log(`entreprise ${company.siren}`)}
|
|
99
|
+
label="Raison sociale"
|
|
100
|
+
/>
|
|
101
|
+
</Example>
|
|
102
|
+
<Example title="Inactif" maxWidth={640}>
|
|
103
|
+
<CompanySearchField
|
|
104
|
+
value="ABYSS PROJECT"
|
|
105
|
+
onInputChange={() => undefined}
|
|
106
|
+
onSelect={() => undefined}
|
|
107
|
+
disabled
|
|
108
|
+
/>
|
|
109
|
+
</Example>
|
|
110
|
+
<LastEvent />
|
|
111
|
+
</Showcase>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
@@ -4,7 +4,44 @@ import {
|
|
|
4
4
|
ConfirmDialog,
|
|
5
5
|
ConfirmDialogTone,
|
|
6
6
|
} from '../../src/components/layers/ConfirmDialog/ConfirmDialog';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
ConfirmDialogProvider,
|
|
9
|
+
useConfirmDialog,
|
|
10
|
+
} from '../../src/components/layers/ConfirmDialog/useConfirmDialog';
|
|
11
|
+
import { Example, LastEvent, Row, Showcase, useEventLog } from '../frame';
|
|
12
|
+
|
|
13
|
+
/** Asks through `useConfirmDialog`, twice in a row: the second request waits for the first. */
|
|
14
|
+
const ImperativeConfirm = () => {
|
|
15
|
+
const { log } = useEventLog();
|
|
16
|
+
const { confirm } = useConfirmDialog();
|
|
17
|
+
const ask = async () => {
|
|
18
|
+
const removed = await confirm({
|
|
19
|
+
title: 'Supprimer l’équipe Design ?',
|
|
20
|
+
body: 'Ses 4 membres perdent les accès donnés par l’équipe.',
|
|
21
|
+
confirmLabel: 'Supprimer l’équipe',
|
|
22
|
+
tone: ConfirmDialogTone.Danger,
|
|
23
|
+
});
|
|
24
|
+
log(removed ? 'équipe supprimée' : 'suppression annulée');
|
|
25
|
+
};
|
|
26
|
+
const askTwice = () => {
|
|
27
|
+
void ask();
|
|
28
|
+
void confirm({
|
|
29
|
+
title: 'Quitter l’organisation ?',
|
|
30
|
+
body: 'Vous perdez l’accès à ses projets.',
|
|
31
|
+
confirmLabel: 'Quitter',
|
|
32
|
+
}).then((left) => log(left ? 'quitter' : 'rester'));
|
|
33
|
+
};
|
|
34
|
+
return (
|
|
35
|
+
<Row>
|
|
36
|
+
<Button variant="outlined" onClick={() => void ask()}>
|
|
37
|
+
Supprimer l’équipe
|
|
38
|
+
</Button>
|
|
39
|
+
<Button variant="outlined" onClick={askTwice}>
|
|
40
|
+
Deux demandes à la suite
|
|
41
|
+
</Button>
|
|
42
|
+
</Row>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
8
45
|
|
|
9
46
|
export const ConfirmDialogPage = () => {
|
|
10
47
|
const { log } = useEventLog();
|
|
@@ -20,6 +57,11 @@ export const ConfirmDialogPage = () => {
|
|
|
20
57
|
Supprimer Impôts 2026
|
|
21
58
|
</Button>
|
|
22
59
|
</Example>
|
|
60
|
+
<Example title="useConfirmDialog : confirm() renvoie une promesse">
|
|
61
|
+
<ConfirmDialogProvider>
|
|
62
|
+
<ImperativeConfirm />
|
|
63
|
+
</ConfirmDialogProvider>
|
|
64
|
+
</Example>
|
|
23
65
|
<LastEvent />
|
|
24
66
|
<ConfirmDialog
|
|
25
67
|
open={open}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import Button from '@mui/material/Button';
|
|
3
|
+
import {
|
|
4
|
+
ConfirmDialog,
|
|
5
|
+
ConfirmDialogTone,
|
|
6
|
+
} from '../../src/components/layers/ConfirmDialog/ConfirmDialog';
|
|
7
|
+
import { Example, LastEvent, Showcase, useEventLog } from '../frame';
|
|
8
|
+
|
|
9
|
+
export const ConfirmDialogWarningPage = () => {
|
|
10
|
+
const { log } = useEventLog();
|
|
11
|
+
const [open, setOpen] = useState(true);
|
|
12
|
+
return (
|
|
13
|
+
<Showcase
|
|
14
|
+
family="Couches"
|
|
15
|
+
name="ConfirmDialog — ton Warning"
|
|
16
|
+
description="Confirmation d'une action permise mais risquée : bouton en status.warning, texte dans l'encre paper la plus contrastée, focus initial sur « Annuler »."
|
|
17
|
+
>
|
|
18
|
+
<Example title="Télécharger un fichier encore en analyse">
|
|
19
|
+
<Button
|
|
20
|
+
variant="outlined"
|
|
21
|
+
color="warning"
|
|
22
|
+
onClick={() => setOpen(true)}
|
|
23
|
+
>
|
|
24
|
+
Télécharger contrat-2026.pdf
|
|
25
|
+
</Button>
|
|
26
|
+
</Example>
|
|
27
|
+
<LastEvent />
|
|
28
|
+
<ConfirmDialog
|
|
29
|
+
open={open}
|
|
30
|
+
tone={ConfirmDialogTone.Warning}
|
|
31
|
+
title="Télécharger un fichier en cours d’analyse ?"
|
|
32
|
+
body="L’analyse antivirus de contrat-2026.pdf n’est pas terminée : rien ne garantit encore que le fichier est sain."
|
|
33
|
+
confirmLabel="Télécharger quand même"
|
|
34
|
+
onConfirm={() => {
|
|
35
|
+
setOpen(false);
|
|
36
|
+
log('télécharger');
|
|
37
|
+
}}
|
|
38
|
+
onCancel={() => {
|
|
39
|
+
setOpen(false);
|
|
40
|
+
log('annuler');
|
|
41
|
+
}}
|
|
42
|
+
/>
|
|
43
|
+
</Showcase>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
@@ -7,7 +7,7 @@ export const CopyFieldPage = () => {
|
|
|
7
7
|
<Showcase
|
|
8
8
|
family="Saisie"
|
|
9
9
|
name="CopyField"
|
|
10
|
-
description="Valeur à copier, masquable : bouton de copie, annonce du résultat dans une région vivante, bouton pour afficher une valeur masquée."
|
|
10
|
+
description="Valeur à copier, masquable : bouton de copie, annonce du résultat dans une région vivante, bouton pour afficher une valeur masquée. Avec loadValue, la valeur n'est demandée qu'au premier « Afficher » ou « Copier »."
|
|
11
11
|
>
|
|
12
12
|
<Example title="Clé d'API, masquée" maxWidth={640}>
|
|
13
13
|
<CopyField
|
|
@@ -17,6 +17,29 @@ export const CopyFieldPage = () => {
|
|
|
17
17
|
copyLabel="Copier la clé"
|
|
18
18
|
/>
|
|
19
19
|
</Example>
|
|
20
|
+
<Example title="Jeton chargé au premier geste" maxWidth={640}>
|
|
21
|
+
<CopyField
|
|
22
|
+
loadValue={() =>
|
|
23
|
+
new Promise<string>((resolve) => {
|
|
24
|
+
log('jeton demandé');
|
|
25
|
+
setTimeout(() => resolve('abyss_env_tok_9c1e4b7a2f6d8e30'), 800);
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
masked
|
|
29
|
+
onReveal={() => log('afficher le jeton')}
|
|
30
|
+
copyLabel="Copier le jeton"
|
|
31
|
+
/>
|
|
32
|
+
</Example>
|
|
33
|
+
<Example title="Jeton dont le chargement échoue" maxWidth={640}>
|
|
34
|
+
<CopyField
|
|
35
|
+
loadValue={() => {
|
|
36
|
+
log('jeton refusé');
|
|
37
|
+
return Promise.reject(new Error('forbidden'));
|
|
38
|
+
}}
|
|
39
|
+
masked
|
|
40
|
+
copyLabel="Copier le jeton"
|
|
41
|
+
/>
|
|
42
|
+
</Example>
|
|
20
43
|
<Example title="Identifiant de connexion IA" maxWidth={640}>
|
|
21
44
|
<CopyField
|
|
22
45
|
value="https://mcp.abyss-project.fr/u/7f3a9c2e"
|