@tsiky/components-r19 1.1.0 → 1.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/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/DynamicInput.module.css +125 -126
- 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 +77 -70
- 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/PeriodSelect/PeriodSelect.module.css +64 -65
- package/src/components/PeriodSelect/PeriodSelect.tsx +48 -42
- 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,189 +1,189 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { SimpleListBox } from './SimpleListBox';
|
|
3
|
-
|
|
4
|
-
const meta: Meta<typeof SimpleListBox> = {
|
|
5
|
-
title: 'Components/ListBox/SimpleListBox',
|
|
6
|
-
component: SimpleListBox,
|
|
7
|
-
parameters: {
|
|
8
|
-
layout: 'centered',
|
|
9
|
-
docs: {
|
|
10
|
-
description: {
|
|
11
|
-
component:
|
|
12
|
-
'A simple list component for displaying data in one or two columns with a clean design.',
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
tags: ['autodocs'],
|
|
17
|
-
argTypes: {
|
|
18
|
-
data: {
|
|
19
|
-
control: 'object',
|
|
20
|
-
description: 'Array of strings or [left, right] tuples for two-column display',
|
|
21
|
-
},
|
|
22
|
-
titleBg: {
|
|
23
|
-
control: 'color',
|
|
24
|
-
description: 'Background color for the title',
|
|
25
|
-
},
|
|
26
|
-
titleColor: {
|
|
27
|
-
control: 'color',
|
|
28
|
-
description: 'Text color for the title',
|
|
29
|
-
},
|
|
30
|
-
itemBg: {
|
|
31
|
-
control: 'color',
|
|
32
|
-
description: 'Background color for items',
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export default meta;
|
|
38
|
-
type Story = StoryObj<typeof meta>;
|
|
39
|
-
|
|
40
|
-
export const Default: Story = {
|
|
41
|
-
name: 'Default',
|
|
42
|
-
args: {
|
|
43
|
-
title: 'Simple List',
|
|
44
|
-
data: ['Item 1', 'Item 2', 'Item 3', 'Item 4'],
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const TwoColumns: Story = {
|
|
49
|
-
name: 'Two Columns',
|
|
50
|
-
args: {
|
|
51
|
-
title: 'Product Inventory',
|
|
52
|
-
data: [
|
|
53
|
-
['Apples', '42 units'],
|
|
54
|
-
['Bananas', '28 units'],
|
|
55
|
-
['Oranges', '15 units'],
|
|
56
|
-
['Pears', '33 units'],
|
|
57
|
-
['Pineapples', '8 units'],
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export const MixedData: Story = {
|
|
63
|
-
name: 'Mixed Data',
|
|
64
|
-
args: {
|
|
65
|
-
title: 'System Report',
|
|
66
|
-
data: [
|
|
67
|
-
['CPU', '45% usage'],
|
|
68
|
-
'No critical alerts detected',
|
|
69
|
-
['Memory', '68% used'],
|
|
70
|
-
'All services running normally',
|
|
71
|
-
['Storage', '82% occupied'],
|
|
72
|
-
'Backup scheduled for tonight',
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const PriorityLevels: Story = {
|
|
78
|
-
name: 'Priority Levels',
|
|
79
|
-
args: {
|
|
80
|
-
title: 'Alerts by Priority',
|
|
81
|
-
data: [
|
|
82
|
-
['Critical', '3 alerts'],
|
|
83
|
-
['High', '7 alerts'],
|
|
84
|
-
['Medium', '12 alerts'],
|
|
85
|
-
['Low', '5 alerts'],
|
|
86
|
-
],
|
|
87
|
-
lineClasses: {
|
|
88
|
-
0: 'priority-critical',
|
|
89
|
-
1: 'priority-high',
|
|
90
|
-
2: 'priority-medium',
|
|
91
|
-
3: 'priority-low',
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
decorators: [
|
|
95
|
-
(Story) => (
|
|
96
|
-
<>
|
|
97
|
-
<style>
|
|
98
|
-
{`
|
|
99
|
-
.priority-critical { background-color: #fef2f2; color: #dc2626; }
|
|
100
|
-
.priority-high { background-color: #fffbeb; color: #d97706; }
|
|
101
|
-
.priority-medium { background-color: #f0f9ff; color: #0369a1; }
|
|
102
|
-
.priority-low { background-color: #f0fdf4; color: #16a34a; }
|
|
103
|
-
`}
|
|
104
|
-
</style>
|
|
105
|
-
<Story />
|
|
106
|
-
</>
|
|
107
|
-
),
|
|
108
|
-
],
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export const ServiceStatus: Story = {
|
|
112
|
-
name: 'Service Status',
|
|
113
|
-
args: {
|
|
114
|
-
title: 'Service Status',
|
|
115
|
-
data: [
|
|
116
|
-
['API Gateway', '✅ Online'],
|
|
117
|
-
['Database', '✅ Online'],
|
|
118
|
-
['Redis Cache', '⚠️ Degraded'],
|
|
119
|
-
['Email Service', '❌ Offline'],
|
|
120
|
-
['Payment Service', '✅ Online'],
|
|
121
|
-
],
|
|
122
|
-
lineClasses: {
|
|
123
|
-
2: 'status-degraded',
|
|
124
|
-
3: 'status-offline',
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
decorators: [
|
|
128
|
-
(Story) => (
|
|
129
|
-
<>
|
|
130
|
-
<style>
|
|
131
|
-
{`
|
|
132
|
-
.status-degraded { background-color: #fffbeb; color: #d97706; }
|
|
133
|
-
.status-offline { background-color: #fef2f2; color: #dc2626; }
|
|
134
|
-
`}
|
|
135
|
-
</style>
|
|
136
|
-
<Story />
|
|
137
|
-
</>
|
|
138
|
-
),
|
|
139
|
-
],
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
export const CustomBackgrounds: Story = {
|
|
143
|
-
name: 'Custom Backgrounds',
|
|
144
|
-
args: {
|
|
145
|
-
title: 'System Metrics',
|
|
146
|
-
titleBg: '#1e40af',
|
|
147
|
-
titleColor: 'white',
|
|
148
|
-
itemBg: '#f0f9ff',
|
|
149
|
-
data: [
|
|
150
|
-
['CPU Temperature', '42°C'],
|
|
151
|
-
['Uptime', '99.9%'],
|
|
152
|
-
['Network Latency', '24ms'],
|
|
153
|
-
['Requests/min', '1,245'],
|
|
154
|
-
],
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
export const EmptyState: Story = {
|
|
159
|
-
name: 'Empty State',
|
|
160
|
-
args: {
|
|
161
|
-
title: 'Pending Tasks',
|
|
162
|
-
data: [],
|
|
163
|
-
emptyContent: '🎉 No pending tasks - everything is up to date!',
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
export const CompactView: Story = {
|
|
168
|
-
name: 'Compact View',
|
|
169
|
-
args: {
|
|
170
|
-
title: 'Quick Metrics',
|
|
171
|
-
data: [
|
|
172
|
-
['Visits', '1.2K'],
|
|
173
|
-
['Conversions', '42'],
|
|
174
|
-
['Rate', '3.5%'],
|
|
175
|
-
],
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
export const LongContent: Story = {
|
|
180
|
-
name: 'Long Content',
|
|
181
|
-
args: {
|
|
182
|
-
title: 'Detailed Descriptions',
|
|
183
|
-
data: [
|
|
184
|
-
['Customer Service', 'Available 24/7 with multilingual support and quick problem resolution'],
|
|
185
|
-
['Delivery', 'Free for orders over €50 with real-time tracking'],
|
|
186
|
-
['Returns', '30-day return policy with no fees or questions'],
|
|
187
|
-
],
|
|
188
|
-
},
|
|
189
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { SimpleListBox } from './SimpleListBox';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof SimpleListBox> = {
|
|
5
|
+
title: 'Components/ListBox/SimpleListBox',
|
|
6
|
+
component: SimpleListBox,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component:
|
|
12
|
+
'A simple list component for displaying data in one or two columns with a clean design.',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
tags: ['autodocs'],
|
|
17
|
+
argTypes: {
|
|
18
|
+
data: {
|
|
19
|
+
control: 'object',
|
|
20
|
+
description: 'Array of strings or [left, right] tuples for two-column display',
|
|
21
|
+
},
|
|
22
|
+
titleBg: {
|
|
23
|
+
control: 'color',
|
|
24
|
+
description: 'Background color for the title',
|
|
25
|
+
},
|
|
26
|
+
titleColor: {
|
|
27
|
+
control: 'color',
|
|
28
|
+
description: 'Text color for the title',
|
|
29
|
+
},
|
|
30
|
+
itemBg: {
|
|
31
|
+
control: 'color',
|
|
32
|
+
description: 'Background color for items',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default meta;
|
|
38
|
+
type Story = StoryObj<typeof meta>;
|
|
39
|
+
|
|
40
|
+
export const Default: Story = {
|
|
41
|
+
name: 'Default',
|
|
42
|
+
args: {
|
|
43
|
+
title: 'Simple List',
|
|
44
|
+
data: ['Item 1', 'Item 2', 'Item 3', 'Item 4'],
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const TwoColumns: Story = {
|
|
49
|
+
name: 'Two Columns',
|
|
50
|
+
args: {
|
|
51
|
+
title: 'Product Inventory',
|
|
52
|
+
data: [
|
|
53
|
+
['Apples', '42 units'],
|
|
54
|
+
['Bananas', '28 units'],
|
|
55
|
+
['Oranges', '15 units'],
|
|
56
|
+
['Pears', '33 units'],
|
|
57
|
+
['Pineapples', '8 units'],
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const MixedData: Story = {
|
|
63
|
+
name: 'Mixed Data',
|
|
64
|
+
args: {
|
|
65
|
+
title: 'System Report',
|
|
66
|
+
data: [
|
|
67
|
+
['CPU', '45% usage'],
|
|
68
|
+
'No critical alerts detected',
|
|
69
|
+
['Memory', '68% used'],
|
|
70
|
+
'All services running normally',
|
|
71
|
+
['Storage', '82% occupied'],
|
|
72
|
+
'Backup scheduled for tonight',
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const PriorityLevels: Story = {
|
|
78
|
+
name: 'Priority Levels',
|
|
79
|
+
args: {
|
|
80
|
+
title: 'Alerts by Priority',
|
|
81
|
+
data: [
|
|
82
|
+
['Critical', '3 alerts'],
|
|
83
|
+
['High', '7 alerts'],
|
|
84
|
+
['Medium', '12 alerts'],
|
|
85
|
+
['Low', '5 alerts'],
|
|
86
|
+
],
|
|
87
|
+
lineClasses: {
|
|
88
|
+
0: 'priority-critical',
|
|
89
|
+
1: 'priority-high',
|
|
90
|
+
2: 'priority-medium',
|
|
91
|
+
3: 'priority-low',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
decorators: [
|
|
95
|
+
(Story) => (
|
|
96
|
+
<>
|
|
97
|
+
<style>
|
|
98
|
+
{`
|
|
99
|
+
.priority-critical { background-color: #fef2f2; color: #dc2626; }
|
|
100
|
+
.priority-high { background-color: #fffbeb; color: #d97706; }
|
|
101
|
+
.priority-medium { background-color: #f0f9ff; color: #0369a1; }
|
|
102
|
+
.priority-low { background-color: #f0fdf4; color: #16a34a; }
|
|
103
|
+
`}
|
|
104
|
+
</style>
|
|
105
|
+
<Story />
|
|
106
|
+
</>
|
|
107
|
+
),
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const ServiceStatus: Story = {
|
|
112
|
+
name: 'Service Status',
|
|
113
|
+
args: {
|
|
114
|
+
title: 'Service Status',
|
|
115
|
+
data: [
|
|
116
|
+
['API Gateway', '✅ Online'],
|
|
117
|
+
['Database', '✅ Online'],
|
|
118
|
+
['Redis Cache', '⚠️ Degraded'],
|
|
119
|
+
['Email Service', '❌ Offline'],
|
|
120
|
+
['Payment Service', '✅ Online'],
|
|
121
|
+
],
|
|
122
|
+
lineClasses: {
|
|
123
|
+
2: 'status-degraded',
|
|
124
|
+
3: 'status-offline',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
decorators: [
|
|
128
|
+
(Story) => (
|
|
129
|
+
<>
|
|
130
|
+
<style>
|
|
131
|
+
{`
|
|
132
|
+
.status-degraded { background-color: #fffbeb; color: #d97706; }
|
|
133
|
+
.status-offline { background-color: #fef2f2; color: #dc2626; }
|
|
134
|
+
`}
|
|
135
|
+
</style>
|
|
136
|
+
<Story />
|
|
137
|
+
</>
|
|
138
|
+
),
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export const CustomBackgrounds: Story = {
|
|
143
|
+
name: 'Custom Backgrounds',
|
|
144
|
+
args: {
|
|
145
|
+
title: 'System Metrics',
|
|
146
|
+
titleBg: '#1e40af',
|
|
147
|
+
titleColor: 'white',
|
|
148
|
+
itemBg: '#f0f9ff',
|
|
149
|
+
data: [
|
|
150
|
+
['CPU Temperature', '42°C'],
|
|
151
|
+
['Uptime', '99.9%'],
|
|
152
|
+
['Network Latency', '24ms'],
|
|
153
|
+
['Requests/min', '1,245'],
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export const EmptyState: Story = {
|
|
159
|
+
name: 'Empty State',
|
|
160
|
+
args: {
|
|
161
|
+
title: 'Pending Tasks',
|
|
162
|
+
data: [],
|
|
163
|
+
emptyContent: '🎉 No pending tasks - everything is up to date!',
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const CompactView: Story = {
|
|
168
|
+
name: 'Compact View',
|
|
169
|
+
args: {
|
|
170
|
+
title: 'Quick Metrics',
|
|
171
|
+
data: [
|
|
172
|
+
['Visits', '1.2K'],
|
|
173
|
+
['Conversions', '42'],
|
|
174
|
+
['Rate', '3.5%'],
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export const LongContent: Story = {
|
|
180
|
+
name: 'Long Content',
|
|
181
|
+
args: {
|
|
182
|
+
title: 'Detailed Descriptions',
|
|
183
|
+
data: [
|
|
184
|
+
['Customer Service', 'Available 24/7 with multilingual support and quick problem resolution'],
|
|
185
|
+
['Delivery', 'Free for orders over €50 with real-time tracking'],
|
|
186
|
+
['Returns', '30-day return policy with no fees or questions'],
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
};
|
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import './SimpleListBox.css';
|
|
3
|
-
|
|
4
|
-
export type SimpleListBoxProps = {
|
|
5
|
-
className?: string;
|
|
6
|
-
style?: React.CSSProperties;
|
|
7
|
-
title?: string;
|
|
8
|
-
titleClassName?: string;
|
|
9
|
-
titleStyle?: React.CSSProperties;
|
|
10
|
-
data?: (string | [string, string])[];
|
|
11
|
-
lineClasses?: { [index: number]: string };
|
|
12
|
-
renderCell?: (value: string, row?: number, col?: number) => React.ReactNode;
|
|
13
|
-
bg?: string;
|
|
14
|
-
titleBg?: string;
|
|
15
|
-
titleColor?: string;
|
|
16
|
-
itemBg?: string;
|
|
17
|
-
emptyContent?: React.ReactNode;
|
|
18
|
-
colGap?: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export const SimpleListBox: React.FC<SimpleListBoxProps> = ({
|
|
22
|
-
className = '',
|
|
23
|
-
style = {},
|
|
24
|
-
title,
|
|
25
|
-
titleClassName = '',
|
|
26
|
-
titleStyle,
|
|
27
|
-
data,
|
|
28
|
-
lineClasses = {},
|
|
29
|
-
renderCell,
|
|
30
|
-
bg,
|
|
31
|
-
titleBg,
|
|
32
|
-
titleColor,
|
|
33
|
-
itemBg,
|
|
34
|
-
emptyContent,
|
|
35
|
-
colGap = '1rem',
|
|
36
|
-
}) => {
|
|
37
|
-
const rows = Array.isArray(data) ? data : [];
|
|
38
|
-
const isEmpty = rows.length === 0;
|
|
39
|
-
const all1D = rows.every((r) => typeof r === 'string');
|
|
40
|
-
const has2D = rows.some((r) => Array.isArray(r));
|
|
41
|
-
|
|
42
|
-
const cellRenderer = (value: string, r?: number, c?: number) =>
|
|
43
|
-
renderCell ? renderCell(value, r, c) : <span className='slb-cell-text'>{value}</span>;
|
|
44
|
-
|
|
45
|
-
const gridStyle: React.CSSProperties | undefined = colGap
|
|
46
|
-
? ({ ['--col-gap' as any]: colGap } as React.CSSProperties)
|
|
47
|
-
: undefined;
|
|
48
|
-
|
|
49
|
-
if (isEmpty) {
|
|
50
|
-
return (
|
|
51
|
-
<div className={`slb-root ${className}`} style={{ ...style, background: bg ?? undefined }}>
|
|
52
|
-
{title && (
|
|
53
|
-
<div
|
|
54
|
-
className={`slb-title ${titleClassName}`}
|
|
55
|
-
style={{
|
|
56
|
-
...titleStyle,
|
|
57
|
-
background: titleBg ?? undefined,
|
|
58
|
-
color: titleColor ?? undefined,
|
|
59
|
-
}}
|
|
60
|
-
>
|
|
61
|
-
{title}
|
|
62
|
-
</div>
|
|
63
|
-
)}
|
|
64
|
-
<div className='slb-empty'>{emptyContent ?? null}</div>
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (all1D && !has2D) {
|
|
70
|
-
return (
|
|
71
|
-
<div className={`slb-root ${className}`} style={{ ...style, background: bg ?? undefined }}>
|
|
72
|
-
{title && (
|
|
73
|
-
<div
|
|
74
|
-
className={`slb-title ${titleClassName}`}
|
|
75
|
-
style={{ background: titleBg ?? undefined, color: titleColor ?? undefined }}
|
|
76
|
-
>
|
|
77
|
-
{title}
|
|
78
|
-
</div>
|
|
79
|
-
)}
|
|
80
|
-
<ul className='slb-list'>
|
|
81
|
-
{(rows as string[]).map((it, i) => (
|
|
82
|
-
<li
|
|
83
|
-
key={i}
|
|
84
|
-
className={`slb-item ${lineClasses[i] || ''}`}
|
|
85
|
-
style={{ background: itemBg ?? undefined }}
|
|
86
|
-
>
|
|
87
|
-
{cellRenderer(it, i, 0)}
|
|
88
|
-
</li>
|
|
89
|
-
))}
|
|
90
|
-
</ul>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Mixed mode: each row is a wrapper (ligne) that contains left/right cells.
|
|
96
|
-
return (
|
|
97
|
-
<div className={`slb-root ${className}`} style={{ ...style, background: bg ?? undefined }}>
|
|
98
|
-
{title && (
|
|
99
|
-
<div
|
|
100
|
-
className={`slb-title ${titleClassName}`}
|
|
101
|
-
style={{ background: titleBg ?? undefined, color: titleColor ?? undefined }}
|
|
102
|
-
>
|
|
103
|
-
{title}
|
|
104
|
-
</div>
|
|
105
|
-
)}
|
|
106
|
-
|
|
107
|
-
<div className='slb-grid' style={gridStyle}>
|
|
108
|
-
{rows.map((r, ridx) => {
|
|
109
|
-
const lineClass = lineClasses[ridx] || '';
|
|
110
|
-
if (Array.isArray(r)) {
|
|
111
|
-
const [left, right] = r as [string, string];
|
|
112
|
-
return (
|
|
113
|
-
<div
|
|
114
|
-
key={ridx}
|
|
115
|
-
className={`slb-row ${lineClass}`}
|
|
116
|
-
style={{ background: itemBg ?? undefined }}
|
|
117
|
-
>
|
|
118
|
-
<div className='slb-grid-left'>{cellRenderer(left, ridx, 0)}</div>
|
|
119
|
-
<div className='slb-grid-right'>{cellRenderer(right, ridx, 1)}</div>
|
|
120
|
-
</div>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return (
|
|
125
|
-
<div
|
|
126
|
-
key={ridx}
|
|
127
|
-
className={`slb-row ${lineClass}`}
|
|
128
|
-
style={{ background: itemBg ?? undefined }}
|
|
129
|
-
>
|
|
130
|
-
<div className='slb-grid-left'>{cellRenderer(r as string, ridx, 0)}</div>
|
|
131
|
-
<div className='slb-grid-right slb-empty-cell' aria-hidden='true' />
|
|
132
|
-
</div>
|
|
133
|
-
);
|
|
134
|
-
})}
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
);
|
|
138
|
-
};
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './SimpleListBox.css';
|
|
3
|
+
|
|
4
|
+
export type SimpleListBoxProps = {
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
title?: string;
|
|
8
|
+
titleClassName?: string;
|
|
9
|
+
titleStyle?: React.CSSProperties;
|
|
10
|
+
data?: (string | [string, string])[];
|
|
11
|
+
lineClasses?: { [index: number]: string };
|
|
12
|
+
renderCell?: (value: string, row?: number, col?: number) => React.ReactNode;
|
|
13
|
+
bg?: string;
|
|
14
|
+
titleBg?: string;
|
|
15
|
+
titleColor?: string;
|
|
16
|
+
itemBg?: string;
|
|
17
|
+
emptyContent?: React.ReactNode;
|
|
18
|
+
colGap?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const SimpleListBox: React.FC<SimpleListBoxProps> = ({
|
|
22
|
+
className = '',
|
|
23
|
+
style = {},
|
|
24
|
+
title,
|
|
25
|
+
titleClassName = '',
|
|
26
|
+
titleStyle,
|
|
27
|
+
data,
|
|
28
|
+
lineClasses = {},
|
|
29
|
+
renderCell,
|
|
30
|
+
bg,
|
|
31
|
+
titleBg,
|
|
32
|
+
titleColor,
|
|
33
|
+
itemBg,
|
|
34
|
+
emptyContent,
|
|
35
|
+
colGap = '1rem',
|
|
36
|
+
}) => {
|
|
37
|
+
const rows = Array.isArray(data) ? data : [];
|
|
38
|
+
const isEmpty = rows.length === 0;
|
|
39
|
+
const all1D = rows.every((r) => typeof r === 'string');
|
|
40
|
+
const has2D = rows.some((r) => Array.isArray(r));
|
|
41
|
+
|
|
42
|
+
const cellRenderer = (value: string, r?: number, c?: number) =>
|
|
43
|
+
renderCell ? renderCell(value, r, c) : <span className='slb-cell-text'>{value}</span>;
|
|
44
|
+
|
|
45
|
+
const gridStyle: React.CSSProperties | undefined = colGap
|
|
46
|
+
? ({ ['--col-gap' as any]: colGap } as React.CSSProperties)
|
|
47
|
+
: undefined;
|
|
48
|
+
|
|
49
|
+
if (isEmpty) {
|
|
50
|
+
return (
|
|
51
|
+
<div className={`slb-root ${className}`} style={{ ...style, background: bg ?? undefined }}>
|
|
52
|
+
{title && (
|
|
53
|
+
<div
|
|
54
|
+
className={`slb-title ${titleClassName}`}
|
|
55
|
+
style={{
|
|
56
|
+
...titleStyle,
|
|
57
|
+
background: titleBg ?? undefined,
|
|
58
|
+
color: titleColor ?? undefined,
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
{title}
|
|
62
|
+
</div>
|
|
63
|
+
)}
|
|
64
|
+
<div className='slb-empty'>{emptyContent ?? null}</div>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (all1D && !has2D) {
|
|
70
|
+
return (
|
|
71
|
+
<div className={`slb-root ${className}`} style={{ ...style, background: bg ?? undefined }}>
|
|
72
|
+
{title && (
|
|
73
|
+
<div
|
|
74
|
+
className={`slb-title ${titleClassName}`}
|
|
75
|
+
style={{ background: titleBg ?? undefined, color: titleColor ?? undefined }}
|
|
76
|
+
>
|
|
77
|
+
{title}
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
<ul className='slb-list'>
|
|
81
|
+
{(rows as string[]).map((it, i) => (
|
|
82
|
+
<li
|
|
83
|
+
key={i}
|
|
84
|
+
className={`slb-item ${lineClasses[i] || ''}`}
|
|
85
|
+
style={{ background: itemBg ?? undefined }}
|
|
86
|
+
>
|
|
87
|
+
{cellRenderer(it, i, 0)}
|
|
88
|
+
</li>
|
|
89
|
+
))}
|
|
90
|
+
</ul>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Mixed mode: each row is a wrapper (ligne) that contains left/right cells.
|
|
96
|
+
return (
|
|
97
|
+
<div className={`slb-root ${className}`} style={{ ...style, background: bg ?? undefined }}>
|
|
98
|
+
{title && (
|
|
99
|
+
<div
|
|
100
|
+
className={`slb-title ${titleClassName}`}
|
|
101
|
+
style={{ background: titleBg ?? undefined, color: titleColor ?? undefined }}
|
|
102
|
+
>
|
|
103
|
+
{title}
|
|
104
|
+
</div>
|
|
105
|
+
)}
|
|
106
|
+
|
|
107
|
+
<div className='slb-grid' style={gridStyle}>
|
|
108
|
+
{rows.map((r, ridx) => {
|
|
109
|
+
const lineClass = lineClasses[ridx] || '';
|
|
110
|
+
if (Array.isArray(r)) {
|
|
111
|
+
const [left, right] = r as [string, string];
|
|
112
|
+
return (
|
|
113
|
+
<div
|
|
114
|
+
key={ridx}
|
|
115
|
+
className={`slb-row ${lineClass}`}
|
|
116
|
+
style={{ background: itemBg ?? undefined }}
|
|
117
|
+
>
|
|
118
|
+
<div className='slb-grid-left'>{cellRenderer(left, ridx, 0)}</div>
|
|
119
|
+
<div className='slb-grid-right'>{cellRenderer(right, ridx, 1)}</div>
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div
|
|
126
|
+
key={ridx}
|
|
127
|
+
className={`slb-row ${lineClass}`}
|
|
128
|
+
style={{ background: itemBg ?? undefined }}
|
|
129
|
+
>
|
|
130
|
+
<div className='slb-grid-left'>{cellRenderer(r as string, ridx, 0)}</div>
|
|
131
|
+
<div className='slb-grid-right slb-empty-cell' aria-hidden='true' />
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
})}
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
};
|