@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.
- package/package.json +1 -1
- package/src/components/AnnouncementPanel/FlexRowContainer.css +17 -17
- package/src/components/AnnouncementPanel/FlexRowContainer.stories.tsx +329 -329
- package/src/components/AnnouncementPanel/FlexRowContainer.tsx +24 -24
- package/src/components/AnnouncementPanel/ListBox/CounterListBox.css +56 -56
- package/src/components/AnnouncementPanel/ListBox/CounterListBox.stories.tsx +292 -292
- package/src/components/AnnouncementPanel/ListBox/CounterListBox.tsx +106 -106
- package/src/components/AnnouncementPanel/ListBox/SimpleListBox.css +57 -57
- package/src/components/AnnouncementPanel/ListBox/SimpleListBox.stories.tsx +189 -189
- package/src/components/AnnouncementPanel/ListBox/SimpleListBox.tsx +138 -138
- package/src/components/AnnouncementPanel/ListBox/TrendListBox.css +61 -61
- package/src/components/AnnouncementPanel/ListBox/TrendListBox.stories.tsx +257 -257
- package/src/components/AnnouncementPanel/ListBox/TrendListBox.tsx +90 -90
- package/src/components/AnnouncementPanel/ListBox/index.ts +3 -3
- package/src/components/AnnouncementPanel/ListContentContainer.css +23 -23
- package/src/components/AnnouncementPanel/ListContentContainer.stories.tsx +212 -212
- package/src/components/AnnouncementPanel/ListContentContainer.tsx +33 -33
- package/src/components/AnnouncementPanel/index.ts +3 -3
- package/src/components/Charts/area-chart-admission/AreaChartAdmission.tsx +7 -1
- package/src/components/Charts/bar-chart/BarChart.tsx +6 -2
- package/src/components/Charts/boxplot-chart/BoxPlotChart.tsx +114 -114
- package/src/components/Charts/mixed-chart/MixedChart.tsx +1 -1
- package/src/components/Charts/sankey-adaptation/sankey.tsx +70 -70
- package/src/components/DraggableSwitcher/DraggableSwitcherButton.tsx +58 -58
- package/src/components/DraggableSwitcher/context/useDraggableSwitcher.tsx +45 -45
- package/src/components/DraggableSwitcher/index.ts +2 -2
- package/src/components/DynamicInput/input/SelectInput.tsx +75 -75
- package/src/components/DynamicInput/input/assets/SelectInput.module.css +95 -95
- package/src/components/DynamicTable/AdvancedFilters.tsx +196 -196
- package/src/components/DynamicTable/ColumnSorter.tsx +185 -185
- package/src/components/DynamicTable/Pagination.tsx +115 -115
- package/src/components/DynamicTable/TableCell.tsx +38 -30
- package/src/components/DynamicTable/TableHeader.tsx +39 -34
- package/src/components/DynamicTable/TableauDynamique.module.css +79 -33
- package/src/components/DynamicTable/TableauDynamique.tsx +154 -154
- package/src/components/DynamicTable/filters/SelectFilter.tsx +69 -69
- package/src/components/DynamicTable/tools/tableTypes.ts +63 -63
- package/src/components/EntryControl/EntryControl.tsx +117 -117
- package/src/components/Grid/grid.css +285 -285
- package/src/components/MetricsPanel/MetricsPanel.tsx +37 -37
- package/src/components/MetricsPanel/renderers/CompactRenderer.tsx +1 -1
- package/src/components/NavItem/NavItem.tsx +58 -58
- package/src/components/PeriodRange/PeriodRange.module.css +158 -158
- package/src/components/PeriodRange/PeriodRange.tsx +130 -130
- package/src/components/SearchBar/SearchBar.css +40 -40
- package/src/components/TranslationKey/TranslationKey.css +272 -272
- package/src/components/TranslationKey/TranslationKey.tsx +8 -7
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
/* File: components/PeriodRange/PeriodRange.tsx */
|
|
2
|
-
'use client';
|
|
3
|
-
import { useEffect, useRef, useState } from 'react';
|
|
4
|
-
import styles from './PeriodRange.module.css';
|
|
5
|
-
|
|
6
|
-
export type Sampling = 'Par jour' | 'Par semaine' | 'Par mois' | 'Par heure';
|
|
7
|
-
|
|
8
|
-
export interface PeriodRangeProps {
|
|
9
|
-
start?: string; // 'YYYY-MM-DD' or 'YYYY-MM-DDTHH:mm'
|
|
10
|
-
end?: string;
|
|
11
|
-
onChange?: (range: { start: string; end: string }) => void;
|
|
12
|
-
sampling?: Sampling;
|
|
13
|
-
onSamplingChange?: (s: Sampling) => void;
|
|
14
|
-
className?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export default function PeriodRange({
|
|
18
|
-
start = '',
|
|
19
|
-
end = '',
|
|
20
|
-
onChange,
|
|
21
|
-
sampling = 'Par jour',
|
|
22
|
-
onSamplingChange,
|
|
23
|
-
className = '',
|
|
24
|
-
}: PeriodRangeProps) {
|
|
25
|
-
const [from, setFrom] = useState<string>(start);
|
|
26
|
-
const [to, setTo] = useState<string>(end);
|
|
27
|
-
const [localSampling, setLocalSampling] = useState<Sampling>(sampling);
|
|
28
|
-
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
29
|
-
|
|
30
|
-
// keep local state in sync if parent changes props
|
|
31
|
-
useEffect(() => setFrom(start), [start]);
|
|
32
|
-
useEffect(() => setTo(end), [end]);
|
|
33
|
-
useEffect(() => setLocalSampling(sampling), [sampling]);
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
function handleClickOutside(e: MouseEvent) {
|
|
37
|
-
const t = e.target as Node | null;
|
|
38
|
-
if (containerRef.current && t && !containerRef.current.contains(t)) {
|
|
39
|
-
// keep behaviour simple: we don't show custom popovers here
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
43
|
-
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
44
|
-
}, []);
|
|
45
|
-
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
onChange?.({ start: from, end: to });
|
|
48
|
-
}, [from, to, onChange]);
|
|
49
|
-
|
|
50
|
-
const handleSamplingChange = (s: Sampling) => {
|
|
51
|
-
setLocalSampling(s);
|
|
52
|
-
onSamplingChange?.(s);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<div className={`${styles.wrapper} ${className}`} ref={containerRef}>
|
|
57
|
-
<label className={styles.label} aria-hidden>
|
|
58
|
-
<svg
|
|
59
|
-
className={styles.calendarIcon}
|
|
60
|
-
xmlns='http://www.w3.org/2000/svg'
|
|
61
|
-
viewBox='0 0 24 24'
|
|
62
|
-
width='18'
|
|
63
|
-
height='18'
|
|
64
|
-
aria-hidden
|
|
65
|
-
>
|
|
66
|
-
<path fill='currentColor' d='M7 10h5v5H7z' opacity='0' />
|
|
67
|
-
<path
|
|
68
|
-
fill='currentColor'
|
|
69
|
-
d='M19 4h-1V2h-2v2H8V2H6v2H5a2 2 0 00-2 2v12a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2zM5 20V9h14l.002 11H5z'
|
|
70
|
-
/>
|
|
71
|
-
</svg>
|
|
72
|
-
<span className={styles.labelText}>Période</span>
|
|
73
|
-
</label>
|
|
74
|
-
|
|
75
|
-
<div className={styles.rangeRow}>
|
|
76
|
-
<div className={styles.dateWrap}>
|
|
77
|
-
<label className={styles.innerLabel} htmlFor='period-from'>
|
|
78
|
-
Début
|
|
79
|
-
</label>
|
|
80
|
-
<input
|
|
81
|
-
id='period-from'
|
|
82
|
-
className={styles.dateInput}
|
|
83
|
-
type='date'
|
|
84
|
-
value={from}
|
|
85
|
-
onChange={(e) => setFrom(e.target.value)}
|
|
86
|
-
aria-label='Date de début'
|
|
87
|
-
/>
|
|
88
|
-
</div>
|
|
89
|
-
|
|
90
|
-
<div className={styles.sepWrap} aria-hidden>
|
|
91
|
-
<span className={styles.separator}>—</span>
|
|
92
|
-
</div>
|
|
93
|
-
|
|
94
|
-
<div className={styles.dateWrap}>
|
|
95
|
-
<label className={styles.innerLabel} htmlFor='period-to'>
|
|
96
|
-
Fin
|
|
97
|
-
</label>
|
|
98
|
-
<div className={styles.inputWithIcon}>
|
|
99
|
-
<input
|
|
100
|
-
id='period-to'
|
|
101
|
-
className={styles.dateInput}
|
|
102
|
-
type='date'
|
|
103
|
-
value={to}
|
|
104
|
-
onChange={(e) => setTo(e.target.value)}
|
|
105
|
-
aria-label='Date de fin'
|
|
106
|
-
/>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
|
|
110
|
-
<div className={styles.samplingWrap}>
|
|
111
|
-
<label className={styles.samplingLabel} htmlFor='period-sampling'>
|
|
112
|
-
Échantillonnage
|
|
113
|
-
</label>
|
|
114
|
-
<select
|
|
115
|
-
id='period-sampling'
|
|
116
|
-
className={styles.samplingSelect}
|
|
117
|
-
value={localSampling}
|
|
118
|
-
onChange={(e) => handleSamplingChange(e.target.value as Sampling)}
|
|
119
|
-
aria-label='Échantillonnage'
|
|
120
|
-
>
|
|
121
|
-
<option>Par jour</option>
|
|
122
|
-
<option>Par semaine</option>
|
|
123
|
-
<option>Par mois</option>
|
|
124
|
-
<option>Par heure</option>
|
|
125
|
-
</select>
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
);
|
|
130
|
-
}
|
|
1
|
+
/* File: components/PeriodRange/PeriodRange.tsx */
|
|
2
|
+
'use client';
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import styles from './PeriodRange.module.css';
|
|
5
|
+
|
|
6
|
+
export type Sampling = 'Par jour' | 'Par semaine' | 'Par mois' | 'Par heure';
|
|
7
|
+
|
|
8
|
+
export interface PeriodRangeProps {
|
|
9
|
+
start?: string; // 'YYYY-MM-DD' or 'YYYY-MM-DDTHH:mm'
|
|
10
|
+
end?: string;
|
|
11
|
+
onChange?: (range: { start: string; end: string }) => void;
|
|
12
|
+
sampling?: Sampling;
|
|
13
|
+
onSamplingChange?: (s: Sampling) => void;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function PeriodRange({
|
|
18
|
+
start = '',
|
|
19
|
+
end = '',
|
|
20
|
+
onChange,
|
|
21
|
+
sampling = 'Par jour',
|
|
22
|
+
onSamplingChange,
|
|
23
|
+
className = '',
|
|
24
|
+
}: PeriodRangeProps) {
|
|
25
|
+
const [from, setFrom] = useState<string>(start);
|
|
26
|
+
const [to, setTo] = useState<string>(end);
|
|
27
|
+
const [localSampling, setLocalSampling] = useState<Sampling>(sampling);
|
|
28
|
+
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
29
|
+
|
|
30
|
+
// keep local state in sync if parent changes props
|
|
31
|
+
useEffect(() => setFrom(start), [start]);
|
|
32
|
+
useEffect(() => setTo(end), [end]);
|
|
33
|
+
useEffect(() => setLocalSampling(sampling), [sampling]);
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
function handleClickOutside(e: MouseEvent) {
|
|
37
|
+
const t = e.target as Node | null;
|
|
38
|
+
if (containerRef.current && t && !containerRef.current.contains(t)) {
|
|
39
|
+
// keep behaviour simple: we don't show custom popovers here
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
43
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
onChange?.({ start: from, end: to });
|
|
48
|
+
}, [from, to, onChange]);
|
|
49
|
+
|
|
50
|
+
const handleSamplingChange = (s: Sampling) => {
|
|
51
|
+
setLocalSampling(s);
|
|
52
|
+
onSamplingChange?.(s);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className={`${styles.wrapper} ${className}`} ref={containerRef}>
|
|
57
|
+
<label className={styles.label} aria-hidden>
|
|
58
|
+
<svg
|
|
59
|
+
className={styles.calendarIcon}
|
|
60
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
61
|
+
viewBox='0 0 24 24'
|
|
62
|
+
width='18'
|
|
63
|
+
height='18'
|
|
64
|
+
aria-hidden
|
|
65
|
+
>
|
|
66
|
+
<path fill='currentColor' d='M7 10h5v5H7z' opacity='0' />
|
|
67
|
+
<path
|
|
68
|
+
fill='currentColor'
|
|
69
|
+
d='M19 4h-1V2h-2v2H8V2H6v2H5a2 2 0 00-2 2v12a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2zM5 20V9h14l.002 11H5z'
|
|
70
|
+
/>
|
|
71
|
+
</svg>
|
|
72
|
+
<span className={styles.labelText}>Période</span>
|
|
73
|
+
</label>
|
|
74
|
+
|
|
75
|
+
<div className={styles.rangeRow}>
|
|
76
|
+
<div className={styles.dateWrap}>
|
|
77
|
+
<label className={styles.innerLabel} htmlFor='period-from'>
|
|
78
|
+
Début
|
|
79
|
+
</label>
|
|
80
|
+
<input
|
|
81
|
+
id='period-from'
|
|
82
|
+
className={styles.dateInput}
|
|
83
|
+
type='date'
|
|
84
|
+
value={from}
|
|
85
|
+
onChange={(e) => setFrom(e.target.value)}
|
|
86
|
+
aria-label='Date de début'
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<div className={styles.sepWrap} aria-hidden>
|
|
91
|
+
<span className={styles.separator}>—</span>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div className={styles.dateWrap}>
|
|
95
|
+
<label className={styles.innerLabel} htmlFor='period-to'>
|
|
96
|
+
Fin
|
|
97
|
+
</label>
|
|
98
|
+
<div className={styles.inputWithIcon}>
|
|
99
|
+
<input
|
|
100
|
+
id='period-to'
|
|
101
|
+
className={styles.dateInput}
|
|
102
|
+
type='date'
|
|
103
|
+
value={to}
|
|
104
|
+
onChange={(e) => setTo(e.target.value)}
|
|
105
|
+
aria-label='Date de fin'
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div className={styles.samplingWrap}>
|
|
111
|
+
<label className={styles.samplingLabel} htmlFor='period-sampling'>
|
|
112
|
+
Échantillonnage
|
|
113
|
+
</label>
|
|
114
|
+
<select
|
|
115
|
+
id='period-sampling'
|
|
116
|
+
className={styles.samplingSelect}
|
|
117
|
+
value={localSampling}
|
|
118
|
+
onChange={(e) => handleSamplingChange(e.target.value as Sampling)}
|
|
119
|
+
aria-label='Échantillonnage'
|
|
120
|
+
>
|
|
121
|
+
<option>Par jour</option>
|
|
122
|
+
<option>Par semaine</option>
|
|
123
|
+
<option>Par mois</option>
|
|
124
|
+
<option>Par heure</option>
|
|
125
|
+
</select>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
.search-container {
|
|
2
|
-
position: relative;
|
|
3
|
-
width: 100%;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.search-icon {
|
|
7
|
-
position: absolute;
|
|
8
|
-
left: 1rem;
|
|
9
|
-
top: 50%;
|
|
10
|
-
transform: translateY(-50%);
|
|
11
|
-
width: 1.25rem;
|
|
12
|
-
height: 1.25rem;
|
|
13
|
-
color: #9ca3af;
|
|
14
|
-
pointer-events: none;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.search-input {
|
|
18
|
-
width: 100%;
|
|
19
|
-
padding: 1rem 1rem 1rem 3rem; /* top right bottom left */
|
|
20
|
-
border: 1px solid #d1d5db;
|
|
21
|
-
border-radius: 0.5rem;
|
|
22
|
-
outline: none;
|
|
23
|
-
background-color: white;
|
|
24
|
-
color: var(--color-text);
|
|
25
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
26
|
-
box-sizing: border-box;
|
|
27
|
-
border: 1px solid var(--color-border);
|
|
28
|
-
background-color: var(--color-card-background);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.search-input::placeholder {
|
|
32
|
-
color: #9ca3af;
|
|
33
|
-
font-family: var(--font-primary);
|
|
34
|
-
font-size: var(--text-paragraph);
|
|
35
|
-
font-weight: var(--font-normal);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.search-input:focus {
|
|
39
|
-
border-color: #d1d5db;
|
|
40
|
-
}
|
|
1
|
+
.search-container {
|
|
2
|
+
position: relative;
|
|
3
|
+
width: 100%;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.search-icon {
|
|
7
|
+
position: absolute;
|
|
8
|
+
left: 1rem;
|
|
9
|
+
top: 50%;
|
|
10
|
+
transform: translateY(-50%);
|
|
11
|
+
width: 1.25rem;
|
|
12
|
+
height: 1.25rem;
|
|
13
|
+
color: #9ca3af;
|
|
14
|
+
pointer-events: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.search-input {
|
|
18
|
+
width: 100%;
|
|
19
|
+
padding: 1rem 1rem 1rem 3rem; /* top right bottom left */
|
|
20
|
+
border: 1px solid #d1d5db;
|
|
21
|
+
border-radius: 0.5rem;
|
|
22
|
+
outline: none;
|
|
23
|
+
background-color: white;
|
|
24
|
+
color: var(--color-text);
|
|
25
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
26
|
+
box-sizing: border-box;
|
|
27
|
+
border: 1px solid var(--color-border);
|
|
28
|
+
background-color: var(--color-card-background);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.search-input::placeholder {
|
|
32
|
+
color: #9ca3af;
|
|
33
|
+
font-family: var(--font-primary);
|
|
34
|
+
font-size: var(--text-paragraph);
|
|
35
|
+
font-weight: var(--font-normal);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.search-input:focus {
|
|
39
|
+
border-color: #d1d5db;
|
|
40
|
+
}
|