@bit.rhplus/ui.f7.detail-item 0.0.9 → 0.0.11
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/components/Category.jsx +3 -39
- package/components/Grid.jsx +1 -1
- package/components/InputText.jsx +2 -16
- package/components/List.jsx +239 -159
- package/components/Project.jsx +948 -0
- package/components/Select.jsx +1 -1
- package/components/index.jsx +2 -1
- package/dist/components/Category.js +2 -20
- package/dist/components/Category.js.map +1 -1
- package/dist/components/Grid.js +1 -1
- package/dist/components/Grid.js.map +1 -1
- package/dist/components/InputText.js +0 -14
- package/dist/components/InputText.js.map +1 -1
- package/dist/components/List.d.ts +6 -1
- package/dist/components/List.js +67 -21
- package/dist/components/List.js.map +1 -1
- package/dist/components/Project.d.ts +30 -0
- package/dist/components/Project.js +617 -0
- package/dist/components/Project.js.map +1 -0
- package/dist/components/Select.js +1 -1
- package/dist/components/Select.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/index.jsx +2 -1
- package/package.json +7 -4
- /package/dist/{preview-1757968550277.js → preview-1758232567717.js} +0 -0
package/components/Category.jsx
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from 'framework7-react';
|
|
18
18
|
import { Tag } from 'lucide-react';
|
|
19
19
|
import CircleButton from '@bit.rhplus/ui.circle-button';
|
|
20
|
+
import CategoryItems from '@bit.rhplus/ui.f7.category';
|
|
20
21
|
|
|
21
22
|
// Category komponenta s modální editací - zobrazuje výběr jedné kategorie jako avatar
|
|
22
23
|
export const Category = ({
|
|
@@ -135,7 +136,7 @@ export const Category = ({
|
|
|
135
136
|
>
|
|
136
137
|
<div className="view view-init">
|
|
137
138
|
<div className="page page-with-navbar-large">
|
|
138
|
-
<Navbar large
|
|
139
|
+
<Navbar large>
|
|
139
140
|
<NavLeft>
|
|
140
141
|
<Link onClick={handleCancel}>
|
|
141
142
|
<Icon f7="arrow_left" style={{ fontWeight: 'bold' }} />
|
|
@@ -146,44 +147,7 @@ export const Category = ({
|
|
|
146
147
|
</Navbar>
|
|
147
148
|
|
|
148
149
|
<div className="page-content">
|
|
149
|
-
{
|
|
150
|
-
<Block>
|
|
151
|
-
<div style={{
|
|
152
|
-
display: 'grid',
|
|
153
|
-
gridTemplateColumns: 'repeat(auto-fit, minmax(80px, 1fr))',
|
|
154
|
-
gap: '15px',
|
|
155
|
-
marginTop: '15px',
|
|
156
|
-
padding: '10px 5px'
|
|
157
|
-
}}>
|
|
158
|
-
{categories.map((category, index) => {
|
|
159
|
-
const isSelected = selectedCategory && selectedCategory.id === category.id;
|
|
160
|
-
return (
|
|
161
|
-
<div key={category.id} style={{
|
|
162
|
-
display: 'flex',
|
|
163
|
-
justifyContent: 'center',
|
|
164
|
-
minWidth: '80px'
|
|
165
|
-
}}>
|
|
166
|
-
<CircleButton
|
|
167
|
-
icon={category.icon || 'tag'}
|
|
168
|
-
name={category.name}
|
|
169
|
-
bgColor={isSelected ? '#28a745' : (category.color ? (category.color.startsWith('#') ? category.color : `#${category.color}`) : undefined)}
|
|
170
|
-
colorIndex={index}
|
|
171
|
-
iconColor="white"
|
|
172
|
-
textColor="#333"
|
|
173
|
-
onClick={() => selectCategory(category)}
|
|
174
|
-
style={{
|
|
175
|
-
opacity: isSelected ? 1 : 0.7,
|
|
176
|
-
transform: isSelected ? 'scale(1.05)' : 'scale(1)',
|
|
177
|
-
transition: 'all 0.2s ease',
|
|
178
|
-
width: '100%',
|
|
179
|
-
maxWidth: '100px'
|
|
180
|
-
}}
|
|
181
|
-
/>
|
|
182
|
-
</div>
|
|
183
|
-
);
|
|
184
|
-
})}
|
|
185
|
-
</div>
|
|
186
|
-
</Block>
|
|
150
|
+
<CategoryItems categories={categories} onCategorySelect={selectCategory} />
|
|
187
151
|
</div>
|
|
188
152
|
</div>
|
|
189
153
|
</div>
|
package/components/Grid.jsx
CHANGED
|
@@ -174,7 +174,7 @@ export const Grid = ({
|
|
|
174
174
|
>
|
|
175
175
|
<div className="view view-init">
|
|
176
176
|
<div className="page page-with-navbar-large">
|
|
177
|
-
<Navbar large
|
|
177
|
+
<Navbar large>
|
|
178
178
|
<NavLeft>
|
|
179
179
|
<Link onClick={handleCancel}>
|
|
180
180
|
<Icon f7="arrow_left" style={{ fontWeight: 'bold' }} />
|
package/components/InputText.jsx
CHANGED
|
@@ -51,29 +51,18 @@ export const InputText = ({
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
const handleSave = () => {
|
|
54
|
-
|
|
55
|
-
console.log("🔥 inputValue:", inputValue);
|
|
56
|
-
console.log("🔥 value prop:", value);
|
|
57
|
-
console.log("🔥 children prop:", children);
|
|
58
|
-
console.log("🔥 onChange exists:", !!onChange);
|
|
59
|
-
console.log("🔥 onSave exists:", !!onSave);
|
|
60
|
-
|
|
54
|
+
|
|
61
55
|
// Rozhodni jakou hodnotu vrátit podle field parametru (pro InputText nevyžíváme pole objektu)
|
|
62
56
|
const returnValue = inputValue;
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
|
|
65
58
|
// Preferuj onChange pro Form.Item kompatibilitu, jinak použij onSave
|
|
66
59
|
if (onChange) {
|
|
67
|
-
console.log("🔥 Calling onChange with:", returnValue);
|
|
68
60
|
onChange(returnValue);
|
|
69
61
|
} else if (onSave) {
|
|
70
|
-
console.log("🔥 Calling onSave with:", returnValue);
|
|
71
62
|
onSave(returnValue);
|
|
72
63
|
} else {
|
|
73
|
-
console.log("❌ No onChange or onSave handler available!");
|
|
74
64
|
}
|
|
75
65
|
|
|
76
|
-
console.log("🔥 Closing popup");
|
|
77
66
|
setPopupOpened(false);
|
|
78
67
|
};
|
|
79
68
|
|
|
@@ -135,9 +124,6 @@ export const InputText = ({
|
|
|
135
124
|
</Block>
|
|
136
125
|
<SaveButton
|
|
137
126
|
onClick={() => {
|
|
138
|
-
console.log("🔥 SaveButton onClick triggered!");
|
|
139
|
-
console.log("🔥 SaveButton - inputValue před handleSave:", inputValue);
|
|
140
|
-
console.log("🔥 SaveButton - onChange existuje:", !!onChange);
|
|
141
127
|
handleSave();
|
|
142
128
|
}}
|
|
143
129
|
variant="black"
|
package/components/List.jsx
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
import React, { useState, useEffect, useMemo } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
Link,
|
|
5
|
-
Icon,
|
|
6
|
-
Popup,
|
|
2
|
+
import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
Link,
|
|
5
|
+
Icon,
|
|
6
|
+
Popup,
|
|
7
7
|
Navbar,
|
|
8
|
-
NavLeft,
|
|
9
|
-
NavTitle,
|
|
8
|
+
NavLeft,
|
|
9
|
+
NavTitle,
|
|
10
10
|
NavTitleLarge,
|
|
11
|
-
NavRight,
|
|
12
|
-
Page,
|
|
13
|
-
Block,
|
|
14
|
-
List as F7List,
|
|
15
|
-
ListItem,
|
|
11
|
+
NavRight,
|
|
12
|
+
Page,
|
|
13
|
+
Block,
|
|
14
|
+
List as F7List,
|
|
15
|
+
ListItem,
|
|
16
16
|
Card,
|
|
17
|
-
Button
|
|
17
|
+
Button,
|
|
18
18
|
} from 'framework7-react';
|
|
19
19
|
import { List as ListIcon, Globe } from 'lucide-react';
|
|
20
20
|
import SaveButton from '@bit.rhplus/ui.f7.save-button';
|
|
21
|
+
import Filter from '@bit.rhplus/ui.f7.filter';
|
|
21
22
|
|
|
22
23
|
// List komponenta s modální editací - zobrazuje seznam jako ListItem komponenty
|
|
23
|
-
export const List = ({
|
|
24
|
-
children,
|
|
25
|
-
value,
|
|
26
|
-
onSave,
|
|
24
|
+
export const List = ({
|
|
25
|
+
children,
|
|
26
|
+
value,
|
|
27
|
+
onSave,
|
|
27
28
|
onChange, // Přidáno pro Form.Item kompatibilitu
|
|
28
|
-
title = 'Editace výběru',
|
|
29
|
+
title = 'Editace výběru',
|
|
29
30
|
placeholder = 'Vyberte položku',
|
|
30
|
-
color = '#6887d3',
|
|
31
|
+
color = '#6887d3',
|
|
31
32
|
size = 16,
|
|
32
33
|
lucideIcon, // Lucide React ikona (např. List)
|
|
33
34
|
icon, // Jakákoliv React komponenta ikony
|
|
@@ -42,25 +43,45 @@ export const List = ({
|
|
|
42
43
|
showCountryFlag = false, // Zda zobrazit vlajku země místo standardní ikony
|
|
43
44
|
flagSize = 16, // Velikost vlajky
|
|
44
45
|
ItemRenderer, // Custom komponenta pro renderování jednotlivých položek
|
|
45
|
-
field = null // Pole pro výběr konkrétní vlastnosti objektu
|
|
46
|
+
field = null, // Pole pro výběr konkrétní vlastnosti objektu
|
|
47
|
+
filterMultiSelect = false,
|
|
48
|
+
filterPopupContent,
|
|
49
|
+
onFilterTextClear,
|
|
50
|
+
onFilter, // Filtrovací funkce
|
|
51
|
+
filterFunction // Funkce pro aplikování filtrů
|
|
46
52
|
}) => {
|
|
47
53
|
const [popupOpened, setPopupOpened] = useState(false);
|
|
48
|
-
|
|
54
|
+
const [activeFilters, setActiveFilters] = useState(null);
|
|
55
|
+
|
|
56
|
+
// Filtrovaná data na základě aktivních filtrů
|
|
57
|
+
const filteredOptions = useMemo(() => {
|
|
58
|
+
const baseOptions = Array.isArray(options) ? options : [];
|
|
59
|
+
|
|
60
|
+
// Pokud existuje filterFunction, použij ji
|
|
61
|
+
if (filterFunction && activeFilters) {
|
|
62
|
+
return filterFunction(baseOptions, activeFilters.filters, activeFilters.searchText);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return baseOptions;
|
|
66
|
+
}, [options, activeFilters, filterFunction]);
|
|
67
|
+
|
|
49
68
|
// Najíst objekty na základě value (pokud je field nastaven, value může být jen pole konkrétních vlastností)
|
|
50
69
|
const findItemsByValue = (val) => {
|
|
51
70
|
if (!val || !options.length) return [];
|
|
52
|
-
|
|
71
|
+
|
|
53
72
|
const valueArray = Array.isArray(val) ? val : [val];
|
|
54
|
-
|
|
73
|
+
|
|
55
74
|
if (field) {
|
|
56
75
|
// Pokud je field nastaven, hledej objekty podle této vlastnosti
|
|
57
|
-
return valueArray
|
|
76
|
+
return valueArray
|
|
77
|
+
.map((v) => options.find((opt) => opt[field] === v))
|
|
78
|
+
.filter(Boolean);
|
|
58
79
|
} else {
|
|
59
80
|
// Pokud field není nastaven, očekáváme objekty
|
|
60
81
|
return valueArray;
|
|
61
82
|
}
|
|
62
83
|
};
|
|
63
|
-
|
|
84
|
+
|
|
64
85
|
// Inicializuj selectedItems pouze jednou při mount
|
|
65
86
|
const initialSelectedItems = useMemo(() => {
|
|
66
87
|
return findItemsByValue(value);
|
|
@@ -68,12 +89,12 @@ export const List = ({
|
|
|
68
89
|
|
|
69
90
|
const [selectedItems, setSelectedItems] = useState(initialSelectedItems);
|
|
70
91
|
|
|
71
|
-
const linkStyle = {
|
|
72
|
-
color,
|
|
92
|
+
const linkStyle = {
|
|
93
|
+
color,
|
|
73
94
|
cursor: 'pointer',
|
|
74
95
|
display: 'flex',
|
|
75
96
|
alignItems: 'center',
|
|
76
|
-
gap: '6px'
|
|
97
|
+
gap: '6px',
|
|
77
98
|
};
|
|
78
99
|
|
|
79
100
|
const handleCancel = () => {
|
|
@@ -88,22 +109,22 @@ export const List = ({
|
|
|
88
109
|
};
|
|
89
110
|
|
|
90
111
|
const isSelected = (item) => {
|
|
91
|
-
return selectedItems.some(selected => selected.id === item.id);
|
|
112
|
+
return selectedItems.some((selected) => selected.id === item.id);
|
|
92
113
|
};
|
|
93
114
|
|
|
94
115
|
const handleItemClick = (item) => {
|
|
95
116
|
if (selectionMode === 'single') {
|
|
96
117
|
// Single selection - přímé uložení položky bez použití state
|
|
97
|
-
|
|
118
|
+
|
|
98
119
|
// Rozhodni jakou hodnotu vrátit podle field parametru
|
|
99
120
|
const returnValue = field && item ? item[field] : item;
|
|
100
|
-
|
|
121
|
+
|
|
101
122
|
if (onChange) {
|
|
102
123
|
onChange(returnValue);
|
|
103
124
|
} else if (onSave) {
|
|
104
125
|
onSave(returnValue);
|
|
105
126
|
}
|
|
106
|
-
|
|
127
|
+
|
|
107
128
|
// Zavři popup
|
|
108
129
|
setPopupOpened(false);
|
|
109
130
|
return;
|
|
@@ -111,11 +132,13 @@ export const List = ({
|
|
|
111
132
|
// Multiple selection - toggle výběr
|
|
112
133
|
let newSelection;
|
|
113
134
|
if (isSelected(item)) {
|
|
114
|
-
newSelection = selectedItems.filter(
|
|
135
|
+
newSelection = selectedItems.filter(
|
|
136
|
+
(selected) => selected.id !== item.id
|
|
137
|
+
);
|
|
115
138
|
} else {
|
|
116
139
|
newSelection = [...selectedItems, item];
|
|
117
140
|
}
|
|
118
|
-
|
|
141
|
+
|
|
119
142
|
setSelectedItems(newSelection);
|
|
120
143
|
}
|
|
121
144
|
};
|
|
@@ -123,32 +146,58 @@ export const List = ({
|
|
|
123
146
|
const handleSaveSelection = () => {
|
|
124
147
|
// Uložení vybraných položek pro oba režimy
|
|
125
148
|
let result;
|
|
126
|
-
|
|
149
|
+
|
|
127
150
|
if (selectionMode === 'single') {
|
|
128
151
|
result = selectedItems.length > 0 ? selectedItems[0] : null;
|
|
129
152
|
} else {
|
|
130
153
|
result = selectedItems.length === 1 ? selectedItems[0] : selectedItems;
|
|
131
154
|
}
|
|
132
|
-
|
|
155
|
+
|
|
133
156
|
// Rozhodni jakou hodnotu vrátit podle field parametru
|
|
134
|
-
const returnValue =
|
|
135
|
-
|
|
157
|
+
const returnValue =
|
|
158
|
+
field && result
|
|
159
|
+
? Array.isArray(result)
|
|
160
|
+
? result.map((item) => item[field])
|
|
161
|
+
: result[field]
|
|
162
|
+
: result;
|
|
163
|
+
|
|
136
164
|
if (onChange) {
|
|
137
165
|
onChange(returnValue);
|
|
138
166
|
} else if (onSave) {
|
|
139
167
|
onSave(returnValue);
|
|
140
168
|
}
|
|
141
|
-
|
|
169
|
+
|
|
142
170
|
setPopupOpened(false);
|
|
143
171
|
};
|
|
144
172
|
|
|
173
|
+
// Handle filtrování - aplikuj filtry a informuj rodiče
|
|
174
|
+
const handleFilterApply = useCallback((searchText, filters) => {
|
|
175
|
+
setActiveFilters({ searchText, filters });
|
|
176
|
+
|
|
177
|
+
// Spočítej počet filtrovaných položek pomocí filterFunction
|
|
178
|
+
let filteredOptions = options;
|
|
179
|
+
if (filterFunction) {
|
|
180
|
+
filteredOptions = filterFunction(options, filters, searchText);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Informuj rodiče o aplikovaných filtrech
|
|
184
|
+
if (onFilter) {
|
|
185
|
+
onFilter({
|
|
186
|
+
searchText: searchText,
|
|
187
|
+
filters: filters,
|
|
188
|
+
filteredCount: filteredOptions.length,
|
|
189
|
+
totalCount: options.length
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}, [onFilter, options, filterFunction]);
|
|
193
|
+
|
|
145
194
|
// Určí jakou ikonu použít - priorita: vlajka země > icon > lucideIcon > výchozí List
|
|
146
195
|
const renderIcon = () => {
|
|
147
196
|
// Pokud chceme zobrazit vlajku země a máme vybranou hodnotu
|
|
148
197
|
if (showCountryFlag && value) {
|
|
149
198
|
const currentValue = Array.isArray(value) ? value[0] : value;
|
|
150
199
|
const country = currentValue?.[countryField];
|
|
151
|
-
|
|
200
|
+
|
|
152
201
|
if (country?.code) {
|
|
153
202
|
return (
|
|
154
203
|
<div
|
|
@@ -183,7 +232,7 @@ export const List = ({
|
|
|
183
232
|
);
|
|
184
233
|
}
|
|
185
234
|
}
|
|
186
|
-
|
|
235
|
+
|
|
187
236
|
if (icon) {
|
|
188
237
|
return React.cloneElement(icon, { size, color, ...icon.props });
|
|
189
238
|
}
|
|
@@ -198,11 +247,11 @@ export const List = ({
|
|
|
198
247
|
const renderItemIcon = (item) => {
|
|
199
248
|
const itemIcon = item[iconField];
|
|
200
249
|
const itemColor = item[colorField] || color;
|
|
201
|
-
|
|
250
|
+
|
|
202
251
|
if (React.isValidElement(itemIcon)) {
|
|
203
252
|
return React.cloneElement(itemIcon, { size: 20, color: itemColor });
|
|
204
253
|
}
|
|
205
|
-
|
|
254
|
+
|
|
206
255
|
return <Icon f7="circle_fill" color={itemColor} size="20" />;
|
|
207
256
|
};
|
|
208
257
|
|
|
@@ -213,11 +262,17 @@ export const List = ({
|
|
|
213
262
|
{(() => {
|
|
214
263
|
// Použij objekty pro zobrazení (převedené z value)
|
|
215
264
|
const currentItems = findItemsByValue(value);
|
|
216
|
-
|
|
265
|
+
|
|
217
266
|
if (currentItems.length === 1) {
|
|
218
267
|
// Pokud je vybraná jedna položka, zobraz hodnotu z displayField
|
|
219
268
|
const item = currentItems[0];
|
|
220
|
-
return
|
|
269
|
+
return (
|
|
270
|
+
item[displayField] ||
|
|
271
|
+
item.name ||
|
|
272
|
+
item.title ||
|
|
273
|
+
item.id ||
|
|
274
|
+
'Vybraná položka'
|
|
275
|
+
);
|
|
221
276
|
} else if (currentItems.length > 1) {
|
|
222
277
|
return `${currentItems.length} vybraných položek`;
|
|
223
278
|
}
|
|
@@ -225,8 +280,8 @@ export const List = ({
|
|
|
225
280
|
})()}
|
|
226
281
|
</Link>
|
|
227
282
|
|
|
228
|
-
<Popup
|
|
229
|
-
opened={popupOpened}
|
|
283
|
+
<Popup
|
|
284
|
+
opened={popupOpened}
|
|
230
285
|
onPopupClosed={() => setPopupOpened(false)}
|
|
231
286
|
animate
|
|
232
287
|
backdrop
|
|
@@ -234,131 +289,156 @@ export const List = ({
|
|
|
234
289
|
className="f7-parallax list-popup"
|
|
235
290
|
style={{
|
|
236
291
|
'--f7-popup-tablet-width': '90vw',
|
|
237
|
-
'--f7-popup-tablet-height': '90vh'
|
|
292
|
+
'--f7-popup-tablet-height': '90vh',
|
|
238
293
|
}}
|
|
239
294
|
>
|
|
240
295
|
<div className="view view-init">
|
|
241
296
|
<div className="page page-with-navbar-large">
|
|
242
|
-
<Navbar large
|
|
297
|
+
<Navbar large>
|
|
243
298
|
<NavLeft>
|
|
244
299
|
<Link onClick={handleCancel}>
|
|
245
300
|
<Icon f7="arrow_left" style={{ fontWeight: 'bold' }} />
|
|
246
301
|
</Link>
|
|
247
302
|
</NavLeft>
|
|
248
303
|
<NavTitle>{title}</NavTitle>
|
|
249
|
-
<NavTitleLarge>
|
|
304
|
+
<NavTitleLarge>
|
|
305
|
+
<div>{title}</div>
|
|
306
|
+
<Filter
|
|
307
|
+
data={options}
|
|
308
|
+
onTextClear={onFilterTextClear}
|
|
309
|
+
popupContent={filterPopupContent}
|
|
310
|
+
multiSelect={filterMultiSelect}
|
|
311
|
+
onFilterApply={handleFilterApply}
|
|
312
|
+
/>
|
|
313
|
+
</NavTitleLarge>
|
|
250
314
|
</Navbar>
|
|
251
|
-
|
|
315
|
+
|
|
252
316
|
<div className="page-content">
|
|
253
|
-
<Block
|
|
254
|
-
|
|
255
|
-
|
|
317
|
+
<Block
|
|
318
|
+
style={{
|
|
319
|
+
padding: '10px 0',
|
|
320
|
+
}}
|
|
321
|
+
>
|
|
256
322
|
<Card>
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
323
|
+
<F7List
|
|
324
|
+
style={{
|
|
325
|
+
marginTop: '0',
|
|
326
|
+
marginBottom: '0',
|
|
327
|
+
}}
|
|
328
|
+
>
|
|
329
|
+
{filteredOptions.map((item, index) => {
|
|
330
|
+
const selected = isSelected(item);
|
|
331
|
+
|
|
332
|
+
// Pokud je předán custom ItemRenderer, použij ho
|
|
333
|
+
if (ItemRenderer) {
|
|
334
|
+
return (
|
|
335
|
+
<ItemRenderer
|
|
336
|
+
key={item.id || index}
|
|
337
|
+
item={item}
|
|
338
|
+
index={index}
|
|
339
|
+
selected={selected}
|
|
340
|
+
onItemClick={(e) => {
|
|
341
|
+
e.preventDefault();
|
|
342
|
+
e.stopPropagation();
|
|
343
|
+
handleItemClick(item);
|
|
344
|
+
}}
|
|
345
|
+
titleField={titleField}
|
|
346
|
+
subtitleField={subtitleField}
|
|
347
|
+
iconField={iconField}
|
|
348
|
+
colorField={colorField}
|
|
349
|
+
color={color}
|
|
350
|
+
/>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Defaultní renderování
|
|
355
|
+
const title =
|
|
356
|
+
item[titleField] ||
|
|
357
|
+
item.name ||
|
|
358
|
+
item.title ||
|
|
359
|
+
`Položka ${index + 1}`;
|
|
360
|
+
const subtitle = item[subtitleField] || item.description;
|
|
361
|
+
|
|
362
|
+
return (
|
|
363
|
+
<ListItem
|
|
364
|
+
key={item.id || index}
|
|
365
|
+
link="#"
|
|
366
|
+
noChevron
|
|
367
|
+
onClick={() => handleItemClick(item)}
|
|
368
|
+
style={{
|
|
369
|
+
'--f7-list-item-padding-horizontal': '15px',
|
|
370
|
+
'--f7-list-item-padding-vertical': '12px',
|
|
371
|
+
backgroundColor: selected
|
|
372
|
+
? '#f0f9ff'
|
|
373
|
+
: 'transparent',
|
|
374
|
+
}}
|
|
375
|
+
>
|
|
376
|
+
<div
|
|
377
|
+
slot="media"
|
|
378
|
+
style={{
|
|
379
|
+
display: 'flex',
|
|
380
|
+
alignItems: 'center',
|
|
381
|
+
marginRight: '12px',
|
|
382
|
+
}}
|
|
383
|
+
>
|
|
384
|
+
{renderItemIcon(item)}
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
<div
|
|
388
|
+
slot="inner"
|
|
389
|
+
style={{
|
|
390
|
+
display: 'flex',
|
|
391
|
+
flexDirection: 'column',
|
|
392
|
+
width: '100%',
|
|
393
|
+
minHeight: '50px',
|
|
394
|
+
}}
|
|
395
|
+
>
|
|
396
|
+
{/* Title row */}
|
|
397
|
+
<div
|
|
398
|
+
style={{
|
|
399
|
+
display: 'flex',
|
|
400
|
+
justifyContent: 'space-between',
|
|
401
|
+
alignItems: 'center',
|
|
402
|
+
marginBottom: subtitle ? '4px' : '0',
|
|
403
|
+
}}
|
|
404
|
+
>
|
|
405
|
+
<span
|
|
406
|
+
style={{
|
|
407
|
+
fontWeight: selected ? 600 : 500,
|
|
408
|
+
fontSize: '16px',
|
|
409
|
+
color: selected ? '#007aff' : '#000',
|
|
410
|
+
}}
|
|
411
|
+
>
|
|
412
|
+
{title}
|
|
413
|
+
</span>
|
|
414
|
+
{selected && (
|
|
415
|
+
<Icon
|
|
416
|
+
f7="checkmark_circle_fill"
|
|
417
|
+
color="#007aff"
|
|
418
|
+
size="20"
|
|
419
|
+
/>
|
|
420
|
+
)}
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
{/* Subtitle */}
|
|
424
|
+
{subtitle && (
|
|
425
|
+
<div
|
|
426
|
+
style={{
|
|
427
|
+
fontSize: '14px',
|
|
428
|
+
color: '#666',
|
|
429
|
+
overflow: 'hidden',
|
|
430
|
+
textOverflow: 'ellipsis',
|
|
431
|
+
whiteSpace: 'nowrap',
|
|
432
|
+
}}
|
|
433
|
+
>
|
|
434
|
+
{subtitle}
|
|
435
|
+
</div>
|
|
436
|
+
)}
|
|
355
437
|
</div>
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
})}
|
|
361
|
-
</F7List>
|
|
438
|
+
</ListItem>
|
|
439
|
+
);
|
|
440
|
+
})}
|
|
441
|
+
</F7List>
|
|
362
442
|
</Card>
|
|
363
443
|
</Block>
|
|
364
444
|
</div>
|
|
@@ -367,4 +447,4 @@ export const List = ({
|
|
|
367
447
|
</Popup>
|
|
368
448
|
</>
|
|
369
449
|
);
|
|
370
|
-
};
|
|
450
|
+
};
|