@tsiky/components-r19 1.1.0 → 1.2.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 (47) hide show
  1. package/package.json +1 -1
  2. package/src/components/AnnouncementPanel/FlexRowContainer.css +17 -17
  3. package/src/components/AnnouncementPanel/FlexRowContainer.stories.tsx +329 -329
  4. package/src/components/AnnouncementPanel/FlexRowContainer.tsx +24 -24
  5. package/src/components/AnnouncementPanel/ListBox/CounterListBox.css +56 -56
  6. package/src/components/AnnouncementPanel/ListBox/CounterListBox.stories.tsx +292 -292
  7. package/src/components/AnnouncementPanel/ListBox/CounterListBox.tsx +106 -106
  8. package/src/components/AnnouncementPanel/ListBox/SimpleListBox.css +57 -57
  9. package/src/components/AnnouncementPanel/ListBox/SimpleListBox.stories.tsx +189 -189
  10. package/src/components/AnnouncementPanel/ListBox/SimpleListBox.tsx +138 -138
  11. package/src/components/AnnouncementPanel/ListBox/TrendListBox.css +61 -61
  12. package/src/components/AnnouncementPanel/ListBox/TrendListBox.stories.tsx +257 -257
  13. package/src/components/AnnouncementPanel/ListBox/TrendListBox.tsx +90 -90
  14. package/src/components/AnnouncementPanel/ListBox/index.ts +3 -3
  15. package/src/components/AnnouncementPanel/ListContentContainer.css +23 -23
  16. package/src/components/AnnouncementPanel/ListContentContainer.stories.tsx +212 -212
  17. package/src/components/AnnouncementPanel/ListContentContainer.tsx +33 -33
  18. package/src/components/AnnouncementPanel/index.ts +3 -3
  19. package/src/components/Charts/area-chart-admission/AreaChartAdmission.tsx +7 -1
  20. package/src/components/Charts/bar-chart/BarChart.tsx +6 -2
  21. package/src/components/Charts/boxplot-chart/BoxPlotChart.tsx +114 -114
  22. package/src/components/Charts/mixed-chart/MixedChart.tsx +1 -1
  23. package/src/components/Charts/sankey-adaptation/sankey.tsx +70 -70
  24. package/src/components/DraggableSwitcher/DraggableSwitcherButton.tsx +58 -58
  25. package/src/components/DraggableSwitcher/context/useDraggableSwitcher.tsx +45 -45
  26. package/src/components/DraggableSwitcher/index.ts +2 -2
  27. package/src/components/DynamicInput/input/SelectInput.tsx +75 -75
  28. package/src/components/DynamicInput/input/assets/SelectInput.module.css +95 -95
  29. package/src/components/DynamicTable/AdvancedFilters.tsx +196 -196
  30. package/src/components/DynamicTable/ColumnSorter.tsx +185 -185
  31. package/src/components/DynamicTable/Pagination.tsx +115 -115
  32. package/src/components/DynamicTable/TableCell.tsx +38 -30
  33. package/src/components/DynamicTable/TableHeader.tsx +39 -34
  34. package/src/components/DynamicTable/TableauDynamique.module.css +79 -33
  35. package/src/components/DynamicTable/TableauDynamique.tsx +154 -154
  36. package/src/components/DynamicTable/filters/SelectFilter.tsx +69 -69
  37. package/src/components/DynamicTable/tools/tableTypes.ts +63 -63
  38. package/src/components/EntryControl/EntryControl.tsx +117 -117
  39. package/src/components/Grid/grid.css +285 -285
  40. package/src/components/MetricsPanel/MetricsPanel.tsx +37 -37
  41. package/src/components/MetricsPanel/renderers/CompactRenderer.tsx +1 -1
  42. package/src/components/NavItem/NavItem.tsx +58 -58
  43. package/src/components/PeriodRange/PeriodRange.module.css +158 -158
  44. package/src/components/PeriodRange/PeriodRange.tsx +130 -130
  45. package/src/components/SearchBar/SearchBar.css +40 -40
  46. package/src/components/TranslationKey/TranslationKey.css +272 -272
  47. package/src/components/TranslationKey/TranslationKey.tsx +8 -7
@@ -1,45 +1,45 @@
1
- 'use client';
2
- import { createContext, useContext, useState, useEffect } from 'react';
3
- import type { ReactNode } from 'react';
4
-
5
- interface DraggableContextType {
6
- isDraggable: boolean;
7
- switchDraggable: (value: boolean) => void;
8
- }
9
-
10
- const DraggableContext = createContext<DraggableContextType | undefined>(undefined);
11
-
12
- export const DraggableProvider = ({ children }: { children: ReactNode }) => {
13
- const [isDraggable, setIsDraggable] = useState(false);
14
-
15
- // Charger depuis localStorage au premier rendu
16
- useEffect(() => {
17
- const stored = localStorage.getItem('isDraggable');
18
- if (stored !== null) {
19
- setIsDraggable(stored === 'true'); // localStorage stocke toujours des strings
20
- }
21
- }, []);
22
-
23
- // Sauvegarder dans localStorage quand ça change
24
- useEffect(() => {
25
- localStorage.setItem('isDraggable', String(isDraggable));
26
- }, [isDraggable]);
27
-
28
- const switchDraggable = (value: boolean) => {
29
- setIsDraggable(value);
30
- };
31
-
32
- return (
33
- <DraggableContext.Provider value={{ isDraggable, switchDraggable }}>
34
- {children}
35
- </DraggableContext.Provider>
36
- );
37
- };
38
-
39
- export const useDraggableSwitcher = () => {
40
- const context = useContext(DraggableContext);
41
- if (!context) {
42
- throw new Error('useDraggableSwitcher must be used inside a DraggableProvider');
43
- }
44
- return context;
45
- };
1
+ 'use client';
2
+ import { createContext, useContext, useState, useEffect } from 'react';
3
+ import type { ReactNode } from 'react';
4
+
5
+ interface DraggableContextType {
6
+ isDraggable: boolean;
7
+ switchDraggable: (value: boolean) => void;
8
+ }
9
+
10
+ const DraggableContext = createContext<DraggableContextType | undefined>(undefined);
11
+
12
+ export const DraggableProvider = ({ children }: { children: ReactNode }) => {
13
+ const [isDraggable, setIsDraggable] = useState(false);
14
+
15
+ // Charger depuis localStorage au premier rendu
16
+ useEffect(() => {
17
+ const stored = localStorage.getItem('isDraggable');
18
+ if (stored !== null) {
19
+ setIsDraggable(stored === 'true'); // localStorage stocke toujours des strings
20
+ }
21
+ }, []);
22
+
23
+ // Sauvegarder dans localStorage quand ça change
24
+ useEffect(() => {
25
+ localStorage.setItem('isDraggable', String(isDraggable));
26
+ }, [isDraggable]);
27
+
28
+ const switchDraggable = (value: boolean) => {
29
+ setIsDraggable(value);
30
+ };
31
+
32
+ return (
33
+ <DraggableContext.Provider value={{ isDraggable, switchDraggable }}>
34
+ {children}
35
+ </DraggableContext.Provider>
36
+ );
37
+ };
38
+
39
+ export const useDraggableSwitcher = () => {
40
+ const context = useContext(DraggableContext);
41
+ if (!context) {
42
+ throw new Error('useDraggableSwitcher must be used inside a DraggableProvider');
43
+ }
44
+ return context;
45
+ };
@@ -1,2 +1,2 @@
1
- export * from './DraggableSwitcherButton';
2
- export * from './context/useDraggableSwitcher';
1
+ export * from './DraggableSwitcherButton';
2
+ export * from './context/useDraggableSwitcher';
@@ -1,75 +1,75 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import React from 'react';
3
- import styles from './assets/SelectInput.module.css';
4
-
5
- interface SelectInputProps {
6
- field: any;
7
- value: any;
8
- onChange: (value: any) => void;
9
- onBlur: () => void;
10
- error?: string;
11
- touched?: boolean;
12
- }
13
-
14
- export const SelectInput: React.FC<SelectInputProps> = ({
15
- field,
16
- value,
17
- onChange,
18
- onBlur,
19
- error,
20
- touched,
21
- }) => {
22
- const hasError = Boolean(touched && error);
23
- const displayLabel = field.label || '';
24
- const placeholder = field.placeholder || '';
25
-
26
- // Trouve le label de l'option sélectionnée si présente
27
- const selectedOptionLabel =
28
- field.options?.find((o: any) => String(o.value) === String(value))?.label ?? '';
29
-
30
- return (
31
- <div
32
- className={`${styles.wrapper} ${hasError ? styles.wrapperInvalid : ''} ${
33
- value ? styles.wrapperHasValue : ''
34
- }`}
35
- >
36
- {/* Select natif (masqué visuellement mais accessible) */}
37
- <select
38
- id={field.name}
39
- name={field.name}
40
- className={styles.nativeSelect}
41
- value={value ?? ''}
42
- onChange={(e) => onChange(e.target.value)}
43
- onBlur={onBlur}
44
- aria-invalid={hasError}
45
- aria-label={displayLabel}
46
- >
47
- {/* Placeholder : visible quand le select est fermé, caché dans la liste */}
48
- <option value='' disabled hidden>
49
- {placeholder || `Sélectionnez ${displayLabel?.toLowerCase() || ''}`}
50
- </option>
51
-
52
- {field.options?.map((option: any, idx: number) => (
53
- <option key={idx} value={option.value} className={styles.optionStyle}>
54
- {option.label}
55
- </option>
56
- ))}
57
- </select>
58
-
59
- {/* Couche visuelle */}
60
- <div className={styles.display}>
61
- {displayLabel && <span className={styles.topLabel}>{displayLabel}</span>}
62
- <span
63
- className={`${styles.valueLine} ${value ? styles.valueActive : styles.valuePlaceholder}`}
64
- >
65
- {value ? selectedOptionLabel : placeholder}
66
- </span>
67
-
68
- {/* caret (SVG) */}
69
- <span className={styles.caret} aria-hidden='true'></span>
70
- </div>
71
-
72
- {hasError && <span className={styles.error}>{error}</span>}
73
- </div>
74
- );
75
- };
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React from 'react';
3
+ import styles from './assets/SelectInput.module.css';
4
+
5
+ interface SelectInputProps {
6
+ field: any;
7
+ value: any;
8
+ onChange: (value: any) => void;
9
+ onBlur: () => void;
10
+ error?: string;
11
+ touched?: boolean;
12
+ }
13
+
14
+ export const SelectInput: React.FC<SelectInputProps> = ({
15
+ field,
16
+ value,
17
+ onChange,
18
+ onBlur,
19
+ error,
20
+ touched,
21
+ }) => {
22
+ const hasError = Boolean(touched && error);
23
+ const displayLabel = field.label || '';
24
+ const placeholder = field.placeholder || '';
25
+
26
+ // Trouve le label de l'option sélectionnée si présente
27
+ const selectedOptionLabel =
28
+ field.options?.find((o: any) => String(o.value) === String(value))?.label ?? '';
29
+
30
+ return (
31
+ <div
32
+ className={`${styles.wrapper} ${hasError ? styles.wrapperInvalid : ''} ${
33
+ value ? styles.wrapperHasValue : ''
34
+ }`}
35
+ >
36
+ {/* Select natif (masqué visuellement mais accessible) */}
37
+ <select
38
+ id={field.name}
39
+ name={field.name}
40
+ className={styles.nativeSelect}
41
+ value={value ?? ''}
42
+ onChange={(e) => onChange(e.target.value)}
43
+ onBlur={onBlur}
44
+ aria-invalid={hasError}
45
+ aria-label={displayLabel}
46
+ >
47
+ {/* Placeholder : visible quand le select est fermé, caché dans la liste */}
48
+ <option value='' disabled hidden>
49
+ {placeholder || `Sélectionnez ${displayLabel?.toLowerCase() || ''}`}
50
+ </option>
51
+
52
+ {field.options?.map((option: any, idx: number) => (
53
+ <option key={idx} value={option.value} className={styles.optionStyle}>
54
+ {option.label}
55
+ </option>
56
+ ))}
57
+ </select>
58
+
59
+ {/* Couche visuelle */}
60
+ <div className={styles.display}>
61
+ {displayLabel && <span className={styles.topLabel}>{displayLabel}</span>}
62
+ <span
63
+ className={`${styles.valueLine} ${value ? styles.valueActive : styles.valuePlaceholder}`}
64
+ >
65
+ {value ? selectedOptionLabel : placeholder}
66
+ </span>
67
+
68
+ {/* caret (SVG) */}
69
+ <span className={styles.caret} aria-hidden='true'></span>
70
+ </div>
71
+
72
+ {hasError && <span className={styles.error}>{error}</span>}
73
+ </div>
74
+ );
75
+ };
@@ -1,95 +1,95 @@
1
- .wrapper {
2
- position: relative;
3
- width: 100%;
4
- border: 1px solid #d3d6db;
5
- border-radius: 10px;
6
- padding: 12px 44px 12px 14px;
7
- box-sizing: border-box;
8
- cursor: pointer;
9
- transition:
10
- border-color 0.15s ease,
11
- box-shadow 0.15s ease;
12
- }
13
-
14
- .wrapper:focus-within {
15
- border-color: #2684ff;
16
- }
17
-
18
- .wrapperInvalid {
19
- border-color: #dc3545;
20
- }
21
-
22
- .nativeSelect {
23
- position: absolute;
24
- inset: 0;
25
- width: 100%;
26
- height: 100%;
27
- opacity: 0;
28
- border: none;
29
- background: transparent;
30
- cursor: pointer;
31
- }
32
-
33
- .display {
34
- display: flex;
35
- flex-direction: column;
36
- pointer-events: none;
37
- user-select: none;
38
- }
39
-
40
- .topLabel {
41
- font-size: 0.8rem;
42
- color: #8b9094;
43
- font-weight: 500;
44
- line-height: 1;
45
- margin-bottom: 6px;
46
- }
47
-
48
- .valueLine {
49
- font-size: 1rem;
50
- line-height: 1.1;
51
- white-space: nowrap;
52
- overflow: hidden;
53
- text-overflow: ellipsis;
54
- }
55
-
56
- .valuePlaceholder {
57
- color: #99a0a6;
58
- }
59
-
60
- .valueActive {
61
- color: var(--color-text, #222);
62
- }
63
-
64
- .caret {
65
- position: absolute;
66
- right: 12px;
67
- top: 50%;
68
- transform: translateY(-50%);
69
- width: 16px;
70
- height: 16px;
71
- pointer-events: none;
72
- background-image: url("data:image/svg+xml;utf8,<svg fill='%23888' height='16' viewBox='0 0 24 24' width='16' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/></svg>");
73
- background-repeat: no-repeat;
74
- background-position: center;
75
- background-size: 16px;
76
- }
77
-
78
- .error {
79
- display: block;
80
- margin-top: 8px;
81
- font-size: 0.85rem;
82
- color: #dc3545;
83
- }
84
-
85
- @media (prefers-reduced-motion: reduce) {
86
- .wrapper,
87
- .wrapper:focus-within {
88
- transition: none;
89
- }
90
- }
91
-
92
- .optionStyle {
93
- background-color: var(--color-card-background);
94
- color: var(--color-text);
95
- }
1
+ .wrapper {
2
+ position: relative;
3
+ width: 100%;
4
+ border: 1px solid #d3d6db;
5
+ border-radius: 10px;
6
+ padding: 12px 44px 12px 14px;
7
+ box-sizing: border-box;
8
+ cursor: pointer;
9
+ transition:
10
+ border-color 0.15s ease,
11
+ box-shadow 0.15s ease;
12
+ }
13
+
14
+ .wrapper:focus-within {
15
+ border-color: #2684ff;
16
+ }
17
+
18
+ .wrapperInvalid {
19
+ border-color: #dc3545;
20
+ }
21
+
22
+ .nativeSelect {
23
+ position: absolute;
24
+ inset: 0;
25
+ width: 100%;
26
+ height: 100%;
27
+ opacity: 0;
28
+ border: none;
29
+ background: transparent;
30
+ cursor: pointer;
31
+ }
32
+
33
+ .display {
34
+ display: flex;
35
+ flex-direction: column;
36
+ pointer-events: none;
37
+ user-select: none;
38
+ }
39
+
40
+ .topLabel {
41
+ font-size: 0.8rem;
42
+ color: #8b9094;
43
+ font-weight: 500;
44
+ line-height: 1;
45
+ margin-bottom: 6px;
46
+ }
47
+
48
+ .valueLine {
49
+ font-size: 1rem;
50
+ line-height: 1.1;
51
+ white-space: nowrap;
52
+ overflow: hidden;
53
+ text-overflow: ellipsis;
54
+ }
55
+
56
+ .valuePlaceholder {
57
+ color: #99a0a6;
58
+ }
59
+
60
+ .valueActive {
61
+ color: var(--color-text, #222);
62
+ }
63
+
64
+ .caret {
65
+ position: absolute;
66
+ right: 12px;
67
+ top: 50%;
68
+ transform: translateY(-50%);
69
+ width: 16px;
70
+ height: 16px;
71
+ pointer-events: none;
72
+ background-image: url("data:image/svg+xml;utf8,<svg fill='%23888' height='16' viewBox='0 0 24 24' width='16' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/></svg>");
73
+ background-repeat: no-repeat;
74
+ background-position: center;
75
+ background-size: 16px;
76
+ }
77
+
78
+ .error {
79
+ display: block;
80
+ margin-top: 8px;
81
+ font-size: 0.85rem;
82
+ color: #dc3545;
83
+ }
84
+
85
+ @media (prefers-reduced-motion: reduce) {
86
+ .wrapper,
87
+ .wrapper:focus-within {
88
+ transition: none;
89
+ }
90
+ }
91
+
92
+ .optionStyle {
93
+ background-color: var(--color-card-background);
94
+ color: var(--color-text);
95
+ }