@tsiky/components-r19 1.0.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.
Files changed (287) hide show
  1. package/.prettierignore +4 -0
  2. package/.prettierrc +9 -0
  3. package/.storybook/main.ts +17 -0
  4. package/.storybook/preview.ts +21 -0
  5. package/.storybook/vitest.setup.ts +7 -0
  6. package/README.md +69 -0
  7. package/chart.ts +1 -0
  8. package/eslint.config.js +40 -0
  9. package/index.html +13 -0
  10. package/index.ts +33 -0
  11. package/package.json +63 -0
  12. package/public/vite.svg +1 -0
  13. package/src/App.css +42 -0
  14. package/src/App.tsx +12 -0
  15. package/src/assets/accessibility.png +0 -0
  16. package/src/assets/accessibility.svg +1 -0
  17. package/src/assets/addon-library.png +0 -0
  18. package/src/assets/assets.png +0 -0
  19. package/src/assets/avif-test-image.avif +0 -0
  20. package/src/assets/context.png +0 -0
  21. package/src/assets/discord.svg +1 -0
  22. package/src/assets/docs.png +0 -0
  23. package/src/assets/figma-plugin.png +0 -0
  24. package/src/assets/github.svg +1 -0
  25. package/src/assets/react.svg +1 -0
  26. package/src/assets/share.png +0 -0
  27. package/src/assets/styling.png +0 -0
  28. package/src/assets/testing.png +0 -0
  29. package/src/assets/theming.png +0 -0
  30. package/src/assets/tutorials.svg +1 -0
  31. package/src/assets/youtube.svg +1 -0
  32. package/src/components/AddItemModal/AddItemModal.module.css +72 -0
  33. package/src/components/AddItemModal/AddItemModal.tsx +82 -0
  34. package/src/components/AddItemModal/index.ts +1 -0
  35. package/src/components/Alert/Alert.css +54 -0
  36. package/src/components/Alert/Alert.stories.tsx +82 -0
  37. package/src/components/Alert/Alert.tsx +85 -0
  38. package/src/components/Alert/AlertContext.tsx +200 -0
  39. package/src/components/Alert/AlertModels.ts +34 -0
  40. package/src/components/Alert/index.ts +3 -0
  41. package/src/components/AnnouncementPanel/FlexRowContainer.css +17 -0
  42. package/src/components/AnnouncementPanel/FlexRowContainer.stories.tsx +329 -0
  43. package/src/components/AnnouncementPanel/FlexRowContainer.tsx +24 -0
  44. package/src/components/AnnouncementPanel/ListBox/CounterListBox.css +56 -0
  45. package/src/components/AnnouncementPanel/ListBox/CounterListBox.stories.tsx +292 -0
  46. package/src/components/AnnouncementPanel/ListBox/CounterListBox.tsx +106 -0
  47. package/src/components/AnnouncementPanel/ListBox/SimpleListBox.css +57 -0
  48. package/src/components/AnnouncementPanel/ListBox/SimpleListBox.stories.tsx +189 -0
  49. package/src/components/AnnouncementPanel/ListBox/SimpleListBox.tsx +138 -0
  50. package/src/components/AnnouncementPanel/ListBox/TrendListBox.css +61 -0
  51. package/src/components/AnnouncementPanel/ListBox/TrendListBox.stories.tsx +257 -0
  52. package/src/components/AnnouncementPanel/ListBox/TrendListBox.tsx +90 -0
  53. package/src/components/AnnouncementPanel/ListBox/index.ts +3 -0
  54. package/src/components/AnnouncementPanel/ListContentContainer.css +23 -0
  55. package/src/components/AnnouncementPanel/ListContentContainer.stories.tsx +212 -0
  56. package/src/components/AnnouncementPanel/ListContentContainer.tsx +33 -0
  57. package/src/components/AnnouncementPanel/index.ts +3 -0
  58. package/src/components/BandChart/index.tsx +282 -0
  59. package/src/components/Button/Button.module.css +165 -0
  60. package/src/components/Button/Button.stories.ts +132 -0
  61. package/src/components/Button/Button.tsx +55 -0
  62. package/src/components/Button/button.css +29 -0
  63. package/src/components/Button/index.ts +2 -0
  64. package/src/components/ChartContainer/ChartContainer.css +116 -0
  65. package/src/components/ChartContainer/ChartContainer.stories.tsx +159 -0
  66. package/src/components/ChartContainer/ChartContainer.tsx +155 -0
  67. package/src/components/ChartContainer/index.ts +1 -0
  68. package/src/components/Charts/area-chart-admission/AreaChartAdmission.stories.tsx +65 -0
  69. package/src/components/Charts/area-chart-admission/AreaChartAdmission.tsx +89 -0
  70. package/src/components/Charts/area-chart-admission/content.json +48 -0
  71. package/src/components/Charts/area-chart-hospitalisation/AreaChartHospitalisation.stories.tsx +141 -0
  72. package/src/components/Charts/area-chart-hospitalisation/AreaChartHospitalisation.tsx +262 -0
  73. package/src/components/Charts/area-chart-hospitalisation/content.json +55 -0
  74. package/src/components/Charts/bar-chart/BarChart.stories.tsx +50 -0
  75. package/src/components/Charts/bar-chart/BarChart.tsx +132 -0
  76. package/src/components/Charts/bar-chart/content.json +15 -0
  77. package/src/components/Charts/boxplot-chart/BoxPlotChart.stories.tsx +63 -0
  78. package/src/components/Charts/boxplot-chart/BoxPlotChart.tsx +114 -0
  79. package/src/components/Charts/boxplot-chart/boxUtils.ts +22 -0
  80. package/src/components/Charts/boxplot-chart/content.json +11 -0
  81. package/src/components/Charts/mixed-chart/MixedChart.stories.tsx +83 -0
  82. package/src/components/Charts/mixed-chart/MixedChart.tsx +625 -0
  83. package/src/components/Charts/mixed-chart/content.json +34 -0
  84. package/src/components/Charts/sankey-adaptation/sankey.tsx +70 -0
  85. package/src/components/Charts/sankey-chart/SankeyChart.stories.tsx +69 -0
  86. package/src/components/Charts/sankey-chart/SankeyChart.tsx +155 -0
  87. package/src/components/Charts/sankey-chart/content.json +15 -0
  88. package/src/components/Charts/stacked-column/StackedColumn.stories.tsx +72 -0
  89. package/src/components/Charts/stacked-column/StackedColumn.tsx +406 -0
  90. package/src/components/Charts/stacked-column/content.json +37 -0
  91. package/src/components/Charts/stacked-column-one-hundred-percent/StackedColumnOneHundredPercent.stories.tsx +43 -0
  92. package/src/components/Charts/stacked-column-one-hundred-percent/StackedColumnOneHundredPercent.tsx +75 -0
  93. package/src/components/Charts/stacked-column-one-hundred-percent/content.json +6 -0
  94. package/src/components/CircularProgress/CircularProgress.css +79 -0
  95. package/src/components/CircularProgress/CircularProgress.stories.tsx +251 -0
  96. package/src/components/CircularProgress/CircularProgress.tsx +101 -0
  97. package/src/components/CircularProgress/index.ts +2 -0
  98. package/src/components/Configure.mdx +369 -0
  99. package/src/components/DayStatCard/DayStatCard.css +50 -0
  100. package/src/components/DayStatCard/DayStatCard.stories.tsx +273 -0
  101. package/src/components/DayStatCard/DayStatCard.tsx +69 -0
  102. package/src/components/DayStatCard/index.ts +2 -0
  103. package/src/components/DraggableSwitcher/DraggableSwitcherButton.tsx +58 -0
  104. package/src/components/DraggableSwitcher/context/useDraggableSwitcher.tsx +45 -0
  105. package/src/components/DraggableSwitcher/index.ts +2 -0
  106. package/src/components/DropdownMenu/DropdownMenu.css +100 -0
  107. package/src/components/DropdownMenu/DropdownMenu.stories.tsx +174 -0
  108. package/src/components/DropdownMenu/DropdownMenu.tsx +106 -0
  109. package/src/components/DropdownMenu/index.ts +1 -0
  110. package/src/components/DynamicForm/DynamicFom.stories.ts +773 -0
  111. package/src/components/DynamicForm/DynamicForm.module.css +468 -0
  112. package/src/components/DynamicForm/DynamicForm.tsx +224 -0
  113. package/src/components/DynamicForm/index.ts +3 -0
  114. package/src/components/DynamicForm/tools/form-metadata.ts +82 -0
  115. package/src/components/DynamicForm/tools/validation.ts +168 -0
  116. package/src/components/DynamicInput/DynamicInput.module.css +126 -0
  117. package/src/components/DynamicInput/DynamicInput.stories.ts +350 -0
  118. package/src/components/DynamicInput/DynamicInput.tsx +144 -0
  119. package/src/components/DynamicInput/index.ts +2 -0
  120. package/src/components/DynamicInput/input/CheckboxInput.tsx +41 -0
  121. package/src/components/DynamicInput/input/ColorInput.tsx +46 -0
  122. package/src/components/DynamicInput/input/DateInput.tsx +57 -0
  123. package/src/components/DynamicInput/input/FileInput.tsx +174 -0
  124. package/src/components/DynamicInput/input/InputWrapper.tsx +26 -0
  125. package/src/components/DynamicInput/input/RadioInput.tsx +46 -0
  126. package/src/components/DynamicInput/input/RangeInput.tsx +46 -0
  127. package/src/components/DynamicInput/input/SelectInput.tsx +75 -0
  128. package/src/components/DynamicInput/input/TextInput.tsx +101 -0
  129. package/src/components/DynamicInput/input/TextareaInput.tsx +47 -0
  130. package/src/components/DynamicInput/input/assets/ColorInput.module.css +48 -0
  131. package/src/components/DynamicInput/input/assets/DateInput.module.css +83 -0
  132. package/src/components/DynamicInput/input/assets/FileInput.module.css +133 -0
  133. package/src/components/DynamicInput/input/assets/RangeInput.module.css +169 -0
  134. package/src/components/DynamicInput/input/assets/SelectInput.module.css +95 -0
  135. package/src/components/DynamicInput/input/index.ts +10 -0
  136. package/src/components/DynamicTable/AdvancedFilters.tsx +196 -0
  137. package/src/components/DynamicTable/ColumnSorter.tsx +185 -0
  138. package/src/components/DynamicTable/Pagination.tsx +115 -0
  139. package/src/components/DynamicTable/TableBody.tsx +42 -0
  140. package/src/components/DynamicTable/TableCell.tsx +30 -0
  141. package/src/components/DynamicTable/TableHeader.tsx +34 -0
  142. package/src/components/DynamicTable/TableRow.tsx +56 -0
  143. package/src/components/DynamicTable/TableauDynamic.stories.ts +1014 -0
  144. package/src/components/DynamicTable/TableauDynamique.module.css +1287 -0
  145. package/src/components/DynamicTable/TableauDynamique.tsx +154 -0
  146. package/src/components/DynamicTable/filters/BooleanFilter.tsx +30 -0
  147. package/src/components/DynamicTable/filters/DateFilter.tsx +28 -0
  148. package/src/components/DynamicTable/filters/DateRangeFilter.tsx +51 -0
  149. package/src/components/DynamicTable/filters/FilterRenderer.tsx +117 -0
  150. package/src/components/DynamicTable/filters/MultiSelectFilter.tsx +59 -0
  151. package/src/components/DynamicTable/filters/NumberFilter.tsx +37 -0
  152. package/src/components/DynamicTable/filters/OperatorFilter.tsx +64 -0
  153. package/src/components/DynamicTable/filters/SelectFilter.tsx +69 -0
  154. package/src/components/DynamicTable/filters/TextFilter.tsx +39 -0
  155. package/src/components/DynamicTable/filters/index.ts +9 -0
  156. package/src/components/DynamicTable/hooks/index.ts +2 -0
  157. package/src/components/DynamicTable/hooks/useAsyncActions.ts +36 -0
  158. package/src/components/DynamicTable/hooks/useFilters.ts +142 -0
  159. package/src/components/DynamicTable/hooks/useTableData.ts +216 -0
  160. package/src/components/DynamicTable/index.ts +11 -0
  161. package/src/components/DynamicTable/tools/filterTypes.ts +118 -0
  162. package/src/components/DynamicTable/tools/index.ts +3 -0
  163. package/src/components/DynamicTable/tools/tableConfig.ts +96 -0
  164. package/src/components/DynamicTable/tools/tableTypes.ts +63 -0
  165. package/src/components/EntryControl/EntryControl.module.css +218 -0
  166. package/src/components/EntryControl/EntryControl.stories.tsx +71 -0
  167. package/src/components/EntryControl/EntryControl.tsx +117 -0
  168. package/src/components/EntryControl/index.ts +2 -0
  169. package/src/components/Grid/Grid.stories.tsx +94 -0
  170. package/src/components/Grid/Grid.tsx +214 -0
  171. package/src/components/Grid/grid.css +285 -0
  172. package/src/components/Grid/index.ts +2 -0
  173. package/src/components/Header/Header.stories.tsx +164 -0
  174. package/src/components/Header/Header.tsx +59 -0
  175. package/src/components/Header/header.css +31 -0
  176. package/src/components/Header/index.ts +1 -0
  177. package/src/components/IconText/IconText..stories.tsx +135 -0
  178. package/src/components/IconText/IconText.css +43 -0
  179. package/src/components/IconText/IconText.tsx +43 -0
  180. package/src/components/IconText/index.ts +1 -0
  181. package/src/components/LanguageSelector/LanguageSelector.css +31 -0
  182. package/src/components/LanguageSelector/LanguageSelector.stories.tsx +38 -0
  183. package/src/components/LanguageSelector/LanguageSelector.tsx +37 -0
  184. package/src/components/LanguageSelector/index.ts +1 -0
  185. package/src/components/Logo/Logo.css +89 -0
  186. package/src/components/Logo/Logo.stories.tsx +79 -0
  187. package/src/components/Logo/Logo.tsx +22 -0
  188. package/src/components/Logo/index.ts +2 -0
  189. package/src/components/MetricsPanel/MetricsItem.tsx +128 -0
  190. package/src/components/MetricsPanel/MetricsPanel.module.css +636 -0
  191. package/src/components/MetricsPanel/MetricsPanel.stories.tsx +692 -0
  192. package/src/components/MetricsPanel/MetricsPanel.tsx +282 -0
  193. package/src/components/MetricsPanel/PanelHeader.tsx +19 -0
  194. package/src/components/MetricsPanel/SummaryCard.tsx +61 -0
  195. package/src/components/MetricsPanel/index.ts +4 -0
  196. package/src/components/MetricsPanel/renderers/CompactRenderer.tsx +125 -0
  197. package/src/components/MetricsPanel/renderers/ImageCard.tsx +62 -0
  198. package/src/components/MetricsPanel/renderers/PertinenceCard.tsx +55 -0
  199. package/src/components/MetricsPanel/tools/MetricsPanelTypes.ts +62 -0
  200. package/src/components/MetricsPanel/tools/chooseDefaultRender.ts +50 -0
  201. package/src/components/MetricsPanel/tools/colorUtils.ts +39 -0
  202. package/src/components/MetricsPanel/tools/index.ts +2 -0
  203. package/src/components/ModuleHeader/ModuleHeader.css +37 -0
  204. package/src/components/ModuleHeader/ModuleHeader.stories.tsx +37 -0
  205. package/src/components/ModuleHeader/ModuleHeader.tsx +42 -0
  206. package/src/components/ModuleHeader/index.ts +1 -0
  207. package/src/components/ModuleSideBar/ModuleSideBar.css +227 -0
  208. package/src/components/ModuleSideBar/ModuleSideBar.stories.tsx +40 -0
  209. package/src/components/ModuleSideBar/ModuleSideBar.tsx +155 -0
  210. package/src/components/ModuleSideBar/index.ts +1 -0
  211. package/src/components/NavBar/NavBar.css +58 -0
  212. package/src/components/NavBar/NavBar.stories.tsx +169 -0
  213. package/src/components/NavBar/NavBar.tsx +100 -0
  214. package/src/components/NavBar/NavContext.tsx +30 -0
  215. package/src/components/NavBar/index.ts +2 -0
  216. package/src/components/NavItem/NavItem.css +29 -0
  217. package/src/components/NavItem/NavItem.tsx +58 -0
  218. package/src/components/NavItem/index.ts +1 -0
  219. package/src/components/Page/Dashboard.tsx +93 -0
  220. package/src/components/Page/Page.stories.ts +33 -0
  221. package/src/components/Page/Page.tsx +73 -0
  222. package/src/components/Page/page.css +81 -0
  223. package/src/components/PerformanceCard/PerformanceCard.module.css +232 -0
  224. package/src/components/PerformanceCard/PerformanceCard.stories.tsx +441 -0
  225. package/src/components/PerformanceCard/PerformanceCard.tsx +198 -0
  226. package/src/components/PerformanceCard/defaultHistogramRenderer.tsx +32 -0
  227. package/src/components/PerformanceCard/tools/types.ts +50 -0
  228. package/src/components/PerformanceCard/tools/usePerformanceCard.ts +93 -0
  229. package/src/components/PeriodRange/PeriodRange.module.css +158 -0
  230. package/src/components/PeriodRange/PeriodRange.stories.tsx +66 -0
  231. package/src/components/PeriodRange/PeriodRange.tsx +130 -0
  232. package/src/components/PeriodSelect/PeriodSelect.module.css +65 -0
  233. package/src/components/PeriodSelect/PeriodSelect.stories.tsx +40 -0
  234. package/src/components/PeriodSelect/PeriodSelect.tsx +42 -0
  235. package/src/components/PeriodSelect/index.ts +1 -0
  236. package/src/components/ScrollableHorizontale/ScrollableHorizontale.css +40 -0
  237. package/src/components/ScrollableHorizontale/ScrollableHorizontale.stories.tsx +133 -0
  238. package/src/components/ScrollableHorizontale/ScrollableHorizontale.tsx +29 -0
  239. package/src/components/ScrollableHorizontale/index.ts +1 -0
  240. package/src/components/SearchBar/SearchBar.css +40 -0
  241. package/src/components/SearchBar/SearchBar.stories.tsx +36 -0
  242. package/src/components/SearchBar/SearchBar.tsx +30 -0
  243. package/src/components/SearchBar/index.ts +1 -0
  244. package/src/components/SectionTitle/SectionTitle.css +21 -0
  245. package/src/components/SectionTitle/SectionTitle.stories.tsx +39 -0
  246. package/src/components/SectionTitle/SectionTitle.tsx +18 -0
  247. package/src/components/SideComponent/PatientEditor.tsx +64 -0
  248. package/src/components/SideComponent/SideComponent.css +179 -0
  249. package/src/components/SideComponent/SideComponent.stories.tsx +547 -0
  250. package/src/components/SideComponent/SideComponent.tsx +243 -0
  251. package/src/components/SideComponent/hooks/useBodyScrollLock.ts +15 -0
  252. package/src/components/SideComponent/index.ts +2 -0
  253. package/src/components/SideComponent/portal.ts +11 -0
  254. package/src/components/SubNavBar/SubNavBar.tsx +41 -0
  255. package/src/components/SubNavBar/index.ts +1 -0
  256. package/src/components/Switcher/Switcher.css +65 -0
  257. package/src/components/Switcher/Switcher.stories.tsx +153 -0
  258. package/src/components/Switcher/Switcher.tsx +83 -0
  259. package/src/components/Switcher/index.ts +1 -0
  260. package/src/components/Title/Title.stories.tsx +18 -0
  261. package/src/components/Title/Title.tsx +26 -0
  262. package/src/components/Title/index.ts +1 -0
  263. package/src/components/TranslationKey/TranslationKey.css +272 -0
  264. package/src/components/TranslationKey/TranslationKey.stories.tsx +50 -0
  265. package/src/components/TranslationKey/TranslationKey.tsx +245 -0
  266. package/src/components/TranslationKey/index.ts +1 -0
  267. package/src/components/TrendItem/TrendItem.css +36 -0
  268. package/src/components/TrendItem/TrendItem.stories.tsx +276 -0
  269. package/src/components/TrendItem/TrendItem.tsx +46 -0
  270. package/src/components/TrendItem/index.ts +1 -0
  271. package/src/components/TrendList/TrendList.css +16 -0
  272. package/src/components/TrendList/TrendList.stories.tsx +337 -0
  273. package/src/components/TrendList/TrendList.tsx +45 -0
  274. package/src/components/TrendList/index.ts +1 -0
  275. package/src/components/theme/ThemeSwitcherButton.tsx +64 -0
  276. package/src/components/theme/context/ThemeContext.tsx +61 -0
  277. package/src/components/theme/context/index.ts +2 -0
  278. package/src/components/theme/context/useThemeSwitcher.ts +18 -0
  279. package/src/components/theme/index.ts +1 -0
  280. package/src/index.css +68 -0
  281. package/src/main.tsx +10 -0
  282. package/src/vite-env.d.ts +1 -0
  283. package/tsconfig.app.json +27 -0
  284. package/tsconfig.json +4 -0
  285. package/tsconfig.node.json +25 -0
  286. package/vite.config.ts +43 -0
  287. package/vitest.shims.d.ts +1 -0
@@ -0,0 +1,692 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React from 'react';
3
+ // eslint-disable-next-line storybook/no-renderer-packages
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+ import MetricsPanel from './MetricsPanel';
6
+ import type { MetricsItem } from './tools/MetricsPanelTypes';
7
+ import { hexToRgba as utilHexToRgba } from './tools/colorUtils';
8
+ import {
9
+ Users,
10
+ CheckCircle,
11
+ Bed,
12
+ XCircle,
13
+ Lock,
14
+ Clock,
15
+ AlertCircle,
16
+ Home,
17
+ Plane,
18
+ Calendar,
19
+ } from 'lucide-react';
20
+
21
+ const meta: Meta<typeof MetricsPanel> = {
22
+ title: 'Components/MetricsPanel',
23
+ component: MetricsPanel,
24
+ parameters: { layout: 'padded' },
25
+ tags: ['autodocs'],
26
+ };
27
+ export default meta;
28
+ type Story = StoryObj<typeof MetricsPanel>;
29
+
30
+ const hexToRgba = (color: string, alpha = 1) => {
31
+ try {
32
+ return utilHexToRgba(color, alpha);
33
+ } catch {
34
+ return `rgba(124, 58, 237, ${alpha})`;
35
+ }
36
+ };
37
+
38
+ /* ---- demo items (shared) ---- */
39
+ const demoItems: MetricsItem[] = [
40
+ {
41
+ id: 1,
42
+ label: 'DMS',
43
+ subLabel: '2023-08-02',
44
+ value: '3.8h',
45
+ badge: { text: 'Prédiction', color: 'transparent', textColor: '#6b7280', small: true },
46
+ } as any,
47
+ {
48
+ id: 2,
49
+ label: 'Admissions',
50
+ subLabel: '03.08',
51
+ value: '205',
52
+ badge: { text: '205', subText: '100%', color: '#10b981', small: true },
53
+ } as any,
54
+ {
55
+ id: 3,
56
+ label: 'Tension',
57
+ subLabel: '03.08',
58
+ value: '68',
59
+ badge: { text: '30', subText: '78%', color: '#fb923c', small: true },
60
+ } as any,
61
+ {
62
+ id: 4,
63
+ label: 'Hospitalisations',
64
+ subLabel: '03.08',
65
+ value: '48',
66
+ badge: { text: '33', subText: '66%', color: '#fb7185', small: true },
67
+ } as any,
68
+ {
69
+ id: 5,
70
+ label: 'Imagerie',
71
+ subLabel: '03.08',
72
+ value: '109',
73
+ badge: { text: '104', subText: '95%', color: '#10b981', small: true },
74
+ } as any,
75
+ {
76
+ id: 6,
77
+ label: 'Sorties',
78
+ subLabel: '03.08',
79
+ value: '219',
80
+ badge: { text: '211', subText: '97%', color: '#10b981', small: true },
81
+ } as any,
82
+ {
83
+ id: 7,
84
+ label: '> 75 ans',
85
+ subLabel: '03.08',
86
+ value: '38',
87
+ badge: { text: '30', subText: '78%', color: '#fb923c', small: true },
88
+ } as any,
89
+ {
90
+ id: 8,
91
+ label: 'Charge des médecins',
92
+ subLabel: '03.08',
93
+ value: '12',
94
+ badge: { text: '10', subText: '85%', color: '#10b981', small: true },
95
+ } as any,
96
+ ];
97
+
98
+ /* ---------------- Stories ---------------- */
99
+
100
+ /* Default (compact preset) */
101
+ export const Default: Story = {
102
+ render: (args) => (
103
+ <MetricsPanel
104
+ {...(args as any)}
105
+ items={demoItems}
106
+ title='Mesures'
107
+ color='#7c3aed'
108
+ layout='vertical'
109
+ compact
110
+ preset='compact'
111
+ onItemClick={(it) => console.log('clicked', it)}
112
+ />
113
+ ),
114
+ parameters: {
115
+ docs: {
116
+ source: {
117
+ code: `import React from 'react';
118
+ import MetricsPanel from './MetricsPanel';
119
+
120
+ const items = ${JSON.stringify(demoItems, null, 2)};
121
+
122
+ <MetricsPanel
123
+ title="Mesures"
124
+ items={items}
125
+ color="#7c3aed"
126
+ layout="vertical"
127
+ compact
128
+ preset="compact"
129
+ />`,
130
+ },
131
+ },
132
+ },
133
+ };
134
+
135
+ /* Compact sized: montre comment forcer largeur/hauteur des items compact */
136
+ export const CompactSized: Story = {
137
+ render: (args) => (
138
+ <MetricsPanel
139
+ {...(args as any)}
140
+ items={demoItems}
141
+ title='Compact — taille fixe des items'
142
+ color='#7c3aed'
143
+ layout='vertical'
144
+ compact
145
+ preset='compact'
146
+ compactItemWidth={280}
147
+ compactItemHeight={96}
148
+ compactItemStyle={{ borderRadius: 12, padding: 10 }}
149
+ onItemClick={(it) => console.log('clicked', it)}
150
+ />
151
+ ),
152
+ parameters: {
153
+ docs: {
154
+ source: {
155
+ code: `import React from 'react';
156
+ import MetricsPanel from './MetricsPanel';
157
+
158
+ const items = ${JSON.stringify(demoItems, null, 2)};
159
+
160
+ <MetricsPanel
161
+ title="Compact — taille fixe des items"
162
+ items={items}
163
+ layout="vertical"
164
+ compact
165
+ preset="compact"
166
+ compactItemWidth={280}
167
+ compactItemHeight={96}
168
+ compactItemStyle={{ borderRadius: 12, padding: 10 }}
169
+ />`,
170
+ },
171
+ },
172
+ },
173
+ };
174
+
175
+ /* Summary style (démo couleurs) */
176
+ export const SummaryStyle: Story = {
177
+ args: {
178
+ summaryBgColors: [
179
+ 'rgba(239,68,68,0.08)',
180
+ 'rgba(249,115,22,0.08)',
181
+ 'rgba(234,179,8,0.08)',
182
+ 'rgba(34,197,94,0.08)',
183
+ ],
184
+ summaryBorderColors: [
185
+ 'rgba(239,68,68,0.12)',
186
+ 'rgba(249,115,22,0.12)',
187
+ 'rgba(234,179,8,0.12)',
188
+ 'rgba(34,197,94,0.12)',
189
+ ],
190
+ summaryValueColors: ['#dc2626', '#ea580c', '#a16207', '#15803d'],
191
+ },
192
+ render: (args) => (
193
+ <MetricsPanel
194
+ {...(args as any)}
195
+ items={[
196
+ { id: 's1', label: 'Précision moyenne', value: '92%' } as any,
197
+ { id: 's2', label: 'Métriques suivies', value: '8' } as any,
198
+ { id: 's3', label: 'Alertes actives', value: '3' } as any,
199
+ { id: 's4', label: 'Période analysée', value: '24h' } as any,
200
+ ]}
201
+ title='Résumé de performance'
202
+ summary
203
+ preset='summary'
204
+ onItemClick={(it) => console.log('summary clicked', it)}
205
+ />
206
+ ),
207
+ parameters: {
208
+ docs: {
209
+ source: {
210
+ code: `import React from 'react';
211
+ import MetricsPanel from './MetricsPanel';
212
+
213
+ const items = [
214
+ { id: 's1', label: 'Précision moyenne', value: '92%' },
215
+ { id: 's2', label: 'Métriques suivies', value: '8' },
216
+ { id: 's3', label: 'Alertes actives', value: '3' },
217
+ { id: 's4', label: 'Période analysée', value: '24h' },
218
+ ];
219
+
220
+ const summaryBgColors = [
221
+ 'rgba(239,68,68,0.08)',
222
+ 'rgba(249,115,22,0.08)',
223
+ 'rgba(234,179,8,0.08)',
224
+ 'rgba(34,197,94,0.08)',
225
+ ];
226
+
227
+ const summaryBorderColors = [
228
+ 'rgba(239,68,68,0.12)',
229
+ 'rgba(249,115,22,0.12)',
230
+ 'rgba(234,179,8,0.12)',
231
+ 'rgba(34,197,94,0.12)',
232
+ ];
233
+
234
+ const summaryValueColors = ['#dc2626', '#ea580c', '#a16207', '#15803d'];
235
+
236
+ <MetricsPanel
237
+ title="Résumé de performance"
238
+ summary
239
+ preset="summary"
240
+ items={items}
241
+ summaryBgColors={summaryBgColors}
242
+ summaryBorderColors={summaryBorderColors}
243
+ summaryValueColors={summaryValueColors}
244
+ />`,
245
+ },
246
+ },
247
+ },
248
+ };
249
+
250
+ /* Summary sized: fixe largeur/hauteur des cartes summary */
251
+ export const SummarySized: Story = {
252
+ render: (args) => (
253
+ <MetricsPanel
254
+ {...(args as any)}
255
+ items={[
256
+ { id: 's1', label: 'Précision moyenne', value: '92%', valueColor: '#059669' } as any,
257
+ { id: 's2', label: 'Métriques suivies', value: '8', valueColor: '#2563eb' } as any,
258
+ { id: 's3', label: 'Alertes actives', value: '3', valueColor: '#b45309' } as any,
259
+ { id: 's4', label: 'Période analysée', value: '24h', valueColor: '#7c3aed' } as any,
260
+ ]}
261
+ title='Summary — taille fixe des cartes'
262
+ summary
263
+ orientation='horizontal'
264
+ preset='summary'
265
+ summaryCardWidth='220px'
266
+ summaryCardHeight={100}
267
+ summaryCardStyle={{ borderRadius: 12, boxShadow: '0 10px 24px rgba(15,23,42,0.06)' }}
268
+ />
269
+ ),
270
+ parameters: {
271
+ docs: {
272
+ source: {
273
+ code: `import React from 'react';
274
+ import MetricsPanel from './MetricsPanel';
275
+
276
+ const items = [
277
+ { id: 's1', label: 'Précision moyenne', value: '92%', valueColor: '#059669' },
278
+ { id: 's2', label: 'Métriques suivies', value: '8', valueColor: '#2563eb' },
279
+ { id: 's3', label: 'Alertes actives', value: '3', valueColor: '#b45309' },
280
+ { id: 's4', label: 'Période analysée', value: '24h', valueColor: '#7c3aed' },
281
+ ];
282
+
283
+ <MetricsPanel
284
+ title="Summary — taille fixe des cartes"
285
+ summary
286
+ orientation="horizontal"
287
+ preset="summary"
288
+ items={items}
289
+ summaryCardWidth="220px"
290
+ summaryCardHeight={100}
291
+ summaryCardStyle={{ borderRadius: 12, boxShadow: '0 10px 24px rgba(15,23,42,0.06)' }}
292
+ />`,
293
+ },
294
+ },
295
+ },
296
+ };
297
+
298
+ /* AlternateHorizontal */
299
+ export const AlternateHorizontal: Story = {
300
+ render: (args) => (
301
+ <MetricsPanel
302
+ {...(args as any)}
303
+ items={[
304
+ {
305
+ id: 'a1',
306
+ label: "ER Temps d'attente",
307
+ subLabel: '04.09',
308
+ value: '1.2h',
309
+ badge: { text: 'Trend', subText: '+5%', color: '#fb923c', small: true },
310
+ } as any,
311
+ {
312
+ id: 'a2',
313
+ label: 'Consultations',
314
+ subLabel: '04.09',
315
+ value: '482',
316
+ badge: { text: '482', subText: '↑', color: '#10b981', small: true },
317
+ } as any,
318
+ {
319
+ id: 'a3',
320
+ label: 'Imagerie urg.',
321
+ subLabel: '04.09',
322
+ value: '76',
323
+ badge: { text: '76', subText: '↓', color: '#fb7185', small: true },
324
+ } as any,
325
+ {
326
+ id: 'a4',
327
+ label: 'Opérations',
328
+ subLabel: '04.09',
329
+ value: '34',
330
+ badge: { text: '34', subText: 'OK', color: '#2563eb', small: true },
331
+ } as any,
332
+ ]}
333
+ title='Vue rapide (Horizontal)'
334
+ color='#0ea5a4'
335
+ layout='horizontal'
336
+ orientation='horizontal'
337
+ compact
338
+ preset='alternateHorizontal'
339
+ />
340
+ ),
341
+ parameters: {
342
+ docs: {
343
+ source: {
344
+ code: `import React from 'react';
345
+ import MetricsPanel from './MetricsPanel';
346
+
347
+ const items = [
348
+ { id: 'a1', label: 'ER Temps d\\'attente', subLabel: '04.09', value: '1.2h', badge: { text: 'Trend', subText: '+5%', color:'#fb923c' } },
349
+ { id: 'a2', label: 'Consultations', subLabel: '04.09', value: '482', badge: { text: '482', subText: '↑', color:'#10b981' } },
350
+ { id: 'a3', label: 'Imagerie urg.', subLabel: '04.09', value: '76', badge: { text: '76', subText: '↓', color:'#fb7185' } },
351
+ { id: 'a4', label: 'Opérations', subLabel: '04.09', value: '34', badge: { text: '34', subText: 'OK', color:'#2563eb' } },
352
+ ];
353
+
354
+ <MetricsPanel
355
+ title="Vue rapide (Horizontal)"
356
+ items={items}
357
+ color="#0ea5a4"
358
+ layout="horizontal"
359
+ orientation="horizontal"
360
+ compact
361
+ preset="alternateHorizontal"
362
+ />`,
363
+ },
364
+ },
365
+ },
366
+ };
367
+
368
+ /* CustomColors */
369
+ export const CustomColors: Story = {
370
+ render: (args) => (
371
+ <MetricsPanel
372
+ {...(args as any)}
373
+ items={[
374
+ { id: 'c1', label: 'Urgences', value: '124' } as any,
375
+ { id: 'c2', label: 'Consultations', value: '58' } as any,
376
+ { id: 'c3', label: 'Hospitalisations', value: '23' } as any,
377
+ { id: 'c4', label: 'Opérations', value: '12' } as any,
378
+ ]}
379
+ title='Statistiques personnalisées'
380
+ summary
381
+ layout='horizontal'
382
+ orientation='horizontal'
383
+ summaryBgColors={[
384
+ 'rgba(255,0,0,0.08)',
385
+ 'rgba(0,255,0,0.08)',
386
+ 'rgba(0,0,255,0.08)',
387
+ 'rgba(255,255,0,0.08)',
388
+ ]}
389
+ summaryBorderColors={[
390
+ 'rgba(255,0,0,0.12)',
391
+ 'rgba(0,255,0,0.12)',
392
+ 'rgba(0,0,255,0.12)',
393
+ 'rgba(255,255,0,0.12)',
394
+ ]}
395
+ summaryValueColors={['#ff0000', '#00ff00', '#0000ff', '#ffff00']}
396
+ preset='summary'
397
+ />
398
+ ),
399
+ parameters: {
400
+ docs: {
401
+ source: {
402
+ code: `import React from 'react';
403
+ import MetricsPanel from './MetricsPanel';
404
+
405
+ const items = [
406
+ { id: 'c1', label: 'Urgences', value: '124' },
407
+ { id: 'c2', label: 'Consultations', value: '58' },
408
+ { id: 'c3', label: 'Hospitalisations', value: '23' },
409
+ { id: 'c4', label: 'Opérations', value: '12' },
410
+ ];
411
+
412
+ const summaryBgColors = [
413
+ 'rgba(255,0,0,0.08)',
414
+ 'rgba(0,255,0,0.08)',
415
+ 'rgba(0,0,255,0.08)',
416
+ 'rgba(255,255,0,0.08)',
417
+ ];
418
+
419
+ const summaryBorderColors = [
420
+ 'rgba(255,0,0,0.12)',
421
+ 'rgba(0,255,0,0.12)',
422
+ 'rgba(0,0,255,0.12)',
423
+ 'rgba(255,255,0,0.12)',
424
+ ];
425
+
426
+ const summaryValueColors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00'];
427
+
428
+ <MetricsPanel
429
+ title="Statistiques personnalisées"
430
+ summary
431
+ layout="horizontal"
432
+ orientation="horizontal"
433
+ preset="summary"
434
+ items={items}
435
+ summaryBgColors={summaryBgColors}
436
+ summaryBorderColors={summaryBorderColors}
437
+ summaryValueColors={summaryValueColors}
438
+ />`,
439
+ },
440
+ },
441
+ },
442
+ };
443
+
444
+ /* ImageExample */
445
+ const imageItems: MetricsItem[] = [
446
+ {
447
+ id: 'c-patients',
448
+ label: 'Patients entrants',
449
+ value: '694',
450
+ bgColor: hexToRgba('#7c3aed', 0.03),
451
+ borderColor: hexToRgba('#7c3aed', 0.08),
452
+ iconComponent: Users,
453
+ iconSquareBg: hexToRgba('#7c3aed', 0.12),
454
+ iconColor: '#7c3aed',
455
+ } as any,
456
+ {
457
+ id: 'c-disponibles',
458
+ label: 'Disponibles',
459
+ value: '336',
460
+ bgColor: hexToRgba('#10b981', 0.03),
461
+ borderColor: hexToRgba('#10b981', 0.08),
462
+ iconComponent: CheckCircle,
463
+ iconSquareBg: hexToRgba('#10b981', 0.12),
464
+ iconColor: '#10b981',
465
+ } as any,
466
+ {
467
+ id: 'c-occupes',
468
+ label: 'Occupés',
469
+ value: '655',
470
+ bgColor: hexToRgba('#f59e0b', 0.03),
471
+ borderColor: hexToRgba('#f59e0b', 0.08),
472
+ iconComponent: Bed,
473
+ iconSquareBg: hexToRgba('#f59e0b', 0.12),
474
+ iconColor: '#f59e0b',
475
+ } as any,
476
+ {
477
+ id: 'c-indispo',
478
+ label: 'Indisponibles',
479
+ value: '0',
480
+ bgColor: hexToRgba('#ef4444', 0.03),
481
+ borderColor: hexToRgba('#ef4444', 0.08),
482
+ iconComponent: XCircle,
483
+ iconSquareBg: hexToRgba('#ef4444', 0.12),
484
+ iconColor: '#ef4444',
485
+ } as any,
486
+ {
487
+ id: 'c-femmes',
488
+ label: 'Femmes',
489
+ value: '76',
490
+ bgColor: hexToRgba('#374151', 0.03),
491
+ borderColor: hexToRgba('#374151', 0.08),
492
+ iconComponent: Lock,
493
+ iconSquareBg: hexToRgba('#374151', 0.12),
494
+ iconColor: '#374151',
495
+ } as any,
496
+ {
497
+ id: 'c-permis',
498
+ label: 'Permis Durée Déterminée',
499
+ value: '43',
500
+ bgColor: hexToRgba('#7c3aed', 0.03),
501
+ borderColor: hexToRgba('#7c3aed', 0.08),
502
+ iconComponent: Clock,
503
+ iconSquareBg: hexToRgba('#a855f7', 0.12),
504
+ iconColor: '#7c3aed',
505
+ } as any,
506
+ ];
507
+
508
+ /* ImageBasedExample (custom itemsContainerStyle) */
509
+ export const ImageBasedExample: Story = {
510
+ render: () => (
511
+ <MetricsPanel
512
+ title='Tableau de bord'
513
+ summary
514
+ orientation='horizontal'
515
+ itemsContainerStyle={{
516
+ display: 'flex',
517
+ flexDirection: 'row',
518
+ flexWrap: 'wrap',
519
+ gap: '8px',
520
+ justifyContent: 'flex-start',
521
+ }}
522
+ items={[
523
+ {
524
+ id: 'un-count',
525
+ label: 'Un Count',
526
+ value: '950',
527
+ bgColor: hexToRgba('#7c3aed', 0.03),
528
+ borderColor: hexToRgba('#7c3aed', 0.08),
529
+ valueColor: '#7c3aed',
530
+ iconComponent: Users,
531
+ iconSquareBg: hexToRgba('#7c3aed', 0.12),
532
+ iconColor: '#7c3aed',
533
+ } as any,
534
+ {
535
+ id: 'un-month',
536
+ label: 'Un Month',
537
+ value: '40',
538
+ bgColor: hexToRgba('#10b981', 0.03),
539
+ borderColor: hexToRgba('#10b981', 0.08),
540
+ valueColor: '#10b981',
541
+ iconComponent: Calendar,
542
+ iconSquareBg: hexToRgba('#10b981', 0.12),
543
+ iconColor: '#10b981',
544
+ } as any,
545
+ {
546
+ id: 'departure',
547
+ label: 'Departure',
548
+ value: '307',
549
+ bgColor: hexToRgba('#f59e0b', 0.03),
550
+ borderColor: hexToRgba('#f59e0b', 0.08),
551
+ valueColor: '#f59e0b',
552
+ iconComponent: Plane,
553
+ iconSquareBg: hexToRgba('#f59e0b', 0.12),
554
+ iconColor: '#f59e0b',
555
+ } as any,
556
+ {
557
+ id: 'oversite',
558
+ label: 'Oversite',
559
+ value: '643',
560
+ bgColor: hexToRgba('#ef4444', 0.03),
561
+ borderColor: hexToRgba('#ef4444', 0.08),
562
+ valueColor: '#ef4444',
563
+ iconComponent: Home,
564
+ iconSquareBg: hexToRgba('#ef4444', 0.12),
565
+ iconColor: '#ef4444',
566
+ } as any,
567
+ {
568
+ id: 'tier-accident',
569
+ label: 'Tier (Accident)',
570
+ value: '67.68%',
571
+ bgColor: hexToRgba('#374151', 0.03),
572
+ borderColor: hexToRgba('#374151', 0.08),
573
+ valueColor: '#374151',
574
+ iconComponent: AlertCircle,
575
+ iconSquareBg: hexToRgba('#374151', 0.12),
576
+ iconColor: '#374151',
577
+ } as any,
578
+ ]}
579
+ preset='image'
580
+ />
581
+ ),
582
+ parameters: {
583
+ docs: {
584
+ source: {
585
+ code: `import React from 'react';
586
+ import MetricsPanel from './MetricsPanel';
587
+ import { hexToRgba } from './tools/colorUtils';
588
+
589
+ const items = [
590
+ { id: 'un-count', label: 'Un Count', value: '950', bgColor: hexToRgba('#7c3aed', 0.03), borderColor: hexToRgba('#7c3aed', 0.08) },
591
+ { id: 'un-month', label: 'Un Month', value: '40', bgColor: hexToRgba('#10b981', 0.03), borderColor: hexToRgba('#10b981', 0.08) },
592
+ { id: 'departure', label: 'Departure', value: '307', bgColor: hexToRgba('#f59e0b', 0.03), borderColor: hexToRgba('#f59e0b', 0.08) },
593
+ { id: 'oversite', label: 'Oversite', value: '643', bgColor: hexToRgba('#ef4444', 0.03), borderColor: hexToRgba('#ef4444', 0.08) },
594
+ { id: 'tier-accident', label: 'Tier (Accident)', value: '67.68%', bgColor: hexToRgba('#374151', 0.03), borderColor: hexToRgba('#374151', 0.08) },
595
+ ];
596
+
597
+ <MetricsPanel
598
+ title="Tableau de bord"
599
+ summary
600
+ orientation="horizontal"
601
+ itemsContainerStyle={{
602
+ display: 'flex',
603
+ flexDirection: 'row',
604
+ flexWrap: 'wrap',
605
+ gap: '8px',
606
+ justifyContent: 'flex-start'
607
+ }}
608
+ items={items}
609
+ preset="image"
610
+ />`,
611
+ },
612
+ },
613
+ },
614
+ };
615
+
616
+ /* PertinenceCards */
617
+ export const PertinenceCards: Story = {
618
+ render: () => (
619
+ <MetricsPanel
620
+ summary
621
+ title=''
622
+ orientation='horizontal'
623
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
624
+ // @ts-ignore optional
625
+ summaryGridColumns={3}
626
+ items={[
627
+ {
628
+ id: 'p1',
629
+ label: 'Pertinence heure (h) de sortie',
630
+ value: '4.1',
631
+ valueColor: '#7c3aed',
632
+ bgColor: '#ffffff',
633
+ borderColor: 'rgba(15,23,42,0.08)',
634
+ } as any,
635
+ {
636
+ id: 'p2',
637
+ label: 'Pertinence séquence (s)',
638
+ value: '100%',
639
+ valueColor: '#7c3aed',
640
+ bgColor: '#ffffff',
641
+ borderColor: 'rgba(15,23,42,0.08)',
642
+ } as any,
643
+ {
644
+ id: 'p3',
645
+ label: 'Pertinence type (t) de sortie',
646
+ value: '0%',
647
+ valueColor: '#7c3aed',
648
+ bgColor: '#ffffff',
649
+ borderColor: 'rgba(15,23,42,0.08)',
650
+ } as any,
651
+ ]}
652
+ itemsContainerStyle={{
653
+ display: 'grid',
654
+ gridTemplateColumns: 'repeat(3, 1fr)',
655
+ gap: 18,
656
+ alignItems: 'stretch',
657
+ width: '100%',
658
+ }}
659
+ preset='pertinence'
660
+ />
661
+ ),
662
+ parameters: {
663
+ docs: {
664
+ source: {
665
+ code: `import React from 'react';
666
+ import MetricsPanel from './MetricsPanel';
667
+
668
+ const items = [
669
+ { id: 'p1', label: 'Pertinence heure (h) de sortie', value: '4.1', valueColor: '#7c3aed', bgColor: '#ffffff', borderColor: 'rgba(15,23,42,0.08)' },
670
+ { id: 'p2', label: 'Pertinence séquence (s)', value: '100%', valueColor: '#7c3aed', bgColor: '#ffffff', borderColor: 'rgba(15,23,42,0.08)' },
671
+ { id: 'p3', label: 'Pertinence type (t) de sortie', value: '0%', valueColor: '#7c3aed', bgColor: '#ffffff', borderColor: 'rgba(15,23,42,0.08)' },
672
+ ];
673
+
674
+ <MetricsPanel
675
+ summary
676
+ title=""
677
+ orientation="horizontal"
678
+ summaryGridColumns={3}
679
+ items={items}
680
+ itemsContainerStyle={{
681
+ display: 'grid',
682
+ gridTemplateColumns: 'repeat(3, 1fr)',
683
+ gap: 18,
684
+ alignItems: 'stretch',
685
+ width: '100%',
686
+ }}
687
+ preset="pertinence"
688
+ />`,
689
+ },
690
+ },
691
+ },
692
+ };