@bit.rhplus/ui.grid-layout 0.0.2 → 0.0.4

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.
@@ -1,370 +1,427 @@
1
- /* eslint-disable */
2
- import React, { useState, useCallback, useMemo } from 'react';
3
- import { default as Button } from 'antd/es/button';
4
- import { default as Input } from 'antd/es/input';
5
- import { default as InputNumber } from 'antd/es/input-number';
6
- import { default as Space } from 'antd/es/space';
7
- import { default as Typography } from 'antd/es/typography';
8
- import { default as Divider } from 'antd/es/divider';
9
- import {
10
- HolderOutlined,
11
- EyeOutlined,
12
- EyeInvisibleOutlined,
13
- SettingOutlined
14
- } from '@ant-design/icons';
15
- import DraggableModal from '@bit.rhplus/draggable-modal';
16
- import {
17
- DndContext,
18
- closestCenter,
19
- KeyboardSensor,
20
- PointerSensor,
21
- useSensor,
22
- useSensors,
23
- } from '@dnd-kit/core';
24
- import {
25
- arrayMove,
26
- SortableContext,
27
- sortableKeyboardCoordinates,
28
- verticalListSortingStrategy,
29
- useSortable,
30
- } from '@dnd-kit/sortable';
31
- import {
32
- CSS,
33
- } from '@dnd-kit/utilities';
34
-
35
- const { Text, Title } = Typography;
36
-
37
- /**
38
- * Sortable řádek pro jeden sloupec
39
- */
40
- const SortableColumnRow = ({ column, onVisibilityChange, onWidthChange, onHeaderNameChange }) => {
41
- const {
42
- attributes,
43
- listeners,
44
- setNodeRef,
45
- transform,
46
- transition,
47
- isDragging,
48
- } = useSortable({ id: column.id });
49
-
50
- const style = {
51
- transform: CSS.Transform.toString(transform),
52
- transition,
53
- opacity: isDragging ? 0.5 : 1,
54
- backgroundColor: isDragging ? '#f0f0f0' : 'white',
55
- };
56
-
57
- return (
58
- <div
59
- ref={setNodeRef}
60
- style={style}
61
- className="column-row"
62
- >
63
- <div className="column-row-content">
64
- {/* Drag Handle */}
65
- <div className="drag-handle" {...attributes} {...listeners}>
66
- <HolderOutlined style={{ color: '#999', cursor: 'grab' }} />
67
- </div>
68
-
69
- {/* Column Name */}
70
- <div className="column-name">
71
- <Input
72
- value={column.headerName}
73
- onChange={(e) => onHeaderNameChange(column.id, e.target.value)}
74
- placeholder="Název sloupce"
75
- size="small"
76
- style={{ fontWeight: 'bold', marginBottom: '4px' }}
77
- />
78
- <div style={{ fontSize: '11px', color: '#999', lineHeight: '1.2' }}>
79
- {column.originalHeaderName}
80
- </div>
81
- </div>
82
-
83
- {/* Width Input */}
84
- <div className="column-width">
85
- <InputNumber
86
- min={50}
87
- max={1000}
88
- value={column.width}
89
- onChange={(value) => onWidthChange(column.id, value)}
90
- addonAfter="px"
91
- size="small"
92
- style={{ width: '100px', marginBottom: '4px' }}
93
- />
94
- <div style={{ fontSize: '11px', color: '#999', lineHeight: '1.2', textAlign: 'center' }}>
95
- {column.originalWidth}px
96
- </div>
97
- </div>
98
-
99
- {/* Visibility Toggle */}
100
- <div className="column-visibility">
101
- <Button
102
- type="text"
103
- icon={column.visible ? <EyeOutlined /> : <EyeInvisibleOutlined />}
104
- onClick={() => onVisibilityChange(column.id, !column.visible)}
105
- style={{
106
- color: column.visible ? '#52c41a' : '#999',
107
- cursor: 'pointer'
108
- }}
109
- title={column.visible ? 'Skrýt sloupec' : 'Zobrazit sloupec'}
110
- >
111
- {column.visible ? 'Zobrazit' : 'Skrýt'}
112
- </Button>
113
- </div>
114
- </div>
115
- </div>
116
- );
117
- };
118
-
119
- /**
120
- * Modal pro editaci sloupců AG-Grid gridu
121
- * @param {Object} props
122
- * @param {boolean} props.open - Zda je modal otevřený
123
- * @param {Function} props.onCancel - Callback pro zavření modalu
124
- * @param {Function} props.onSave - Callback pro uložení změn
125
- * @param {Array} props.columns - Pole sloupců k editaci
126
- * @param {Function} props.getContainer - Container pro modal
127
- */
128
- export default function ColumnEditorModal({
129
- open,
130
- onCancel,
131
- onSave,
132
- columns = [],
133
- getContainer
134
- }) {
135
- // Lokální stav pro editaci sloupců
136
- const [editingColumns, setEditingColumns] = useState([]);
137
-
138
- // Inicializace editovacího stavu při otevření modalu
139
- React.useEffect(() => {
140
- if (open && columns.length > 0) {
141
- console.log("📝 ColumnEditorModal initializing with columns:", columns.map(c => ({
142
- field: c.field,
143
- headerName: c.headerName,
144
- width: c.width,
145
- visible: c.visible
146
- })));
147
-
148
- const initialColumns = columns.map((col, index) => ({
149
- id: col.field,
150
- field: col.field,
151
- headerName: col.headerName || col.field,
152
- originalHeaderName: col.originalHeaderName || col.headerName || col.field, // Původní název
153
- width: col.width || 100,
154
- originalWidth: col.originalWidth || col.width || 100, // Původní šířka
155
- visible: col.visible !== undefined ? col.visible : !col.hide,
156
- order: index
157
- }));
158
-
159
- console.log("📝 ColumnEditorModal initialized editingColumns:", initialColumns.map(c => ({
160
- field: c.field,
161
- headerName: c.headerName,
162
- width: c.width,
163
- visible: c.visible
164
- })));
165
-
166
- setEditingColumns(initialColumns);
167
- }
168
- }, [open, columns]);
169
-
170
- // Sensor pro drag&drop
171
- const sensors = useSensors(
172
- useSensor(PointerSensor),
173
- useSensor(KeyboardSensor, {
174
- coordinateGetter: sortableKeyboardCoordinates,
175
- })
176
- );
177
-
178
- // Handler pro ukončení drag operace
179
- const handleDragEnd = useCallback((event) => {
180
- const { active, over } = event;
181
-
182
- if (active.id !== over?.id) {
183
- setEditingColumns((items) => {
184
- const oldIndex = items.findIndex((item) => item.id === active.id);
185
- const newIndex = items.findIndex((item) => item.id === over.id);
186
-
187
- return arrayMove(items, oldIndex, newIndex);
188
- });
189
- }
190
- }, []);
191
-
192
- // Handler pro změnu viditelnosti sloupce
193
- const handleVisibilityChange = useCallback((columnId, visible) => {
194
- setEditingColumns((prev) =>
195
- prev.map((col) =>
196
- col.id === columnId ? { ...col, visible } : col
197
- )
198
- );
199
- }, []);
200
-
201
- // Handler pro změnu šířky sloupce
202
- const handleWidthChange = useCallback((columnId, width) => {
203
- if (width && width >= 50) {
204
- setEditingColumns((prev) =>
205
- prev.map((col) =>
206
- col.id === columnId ? { ...col, width } : col
207
- )
208
- );
209
- }
210
- }, []);
211
-
212
- // Handler pro změnu názvu sloupce
213
- const handleHeaderNameChange = useCallback((columnId, headerName) => {
214
- setEditingColumns((prev) =>
215
- prev.map((col) =>
216
- col.id === columnId ? { ...col, headerName } : col
217
- )
218
- );
219
- }, []);
220
-
221
- // Handler pro uložení změn
222
- const handleSave = useCallback(() => {
223
- if (onSave) {
224
- onSave(editingColumns);
225
- }
226
- onCancel();
227
- }, [editingColumns, onSave, onCancel]);
228
-
229
- // Handler pro reset na původní stav
230
- const handleReset = useCallback(() => {
231
- const resetColumns = columns.map((col, index) => ({
232
- id: col.field,
233
- field: col.field,
234
- headerName: col.headerName || col.field,
235
- originalHeaderName: col.headerName || col.field,
236
- width: col.width || 100,
237
- originalWidth: col.width || 100,
238
- visible: !col.hide,
239
- order: index
240
- }));
241
- setEditingColumns(resetColumns);
242
- }, [columns]);
243
-
244
- const columnIds = useMemo(() => editingColumns.map((col) => col.id), [editingColumns]);
245
-
246
- // Dynamická výška podle velikosti obrazovky
247
- const modalHeight = useMemo(() => {
248
- if (typeof window !== 'undefined') {
249
- const screenHeight = window.innerHeight;
250
- // 80% výšky obrazovky (65% + 25%), minimálně 600px, maximálně 900px
251
- // Odečteme 80px pro margin/padding aby se modál vždy vešel
252
- return Math.min(Math.max((screenHeight - 80) * 0.80, 600), 900);
253
- }
254
- return 700;
255
- }, []);
256
-
257
- return (
258
- <DraggableModal
259
- width="650px"
260
- height={`${modalHeight}px`}
261
- open={open}
262
- getContainer={getContainer}
263
- onCancel={onCancel}
264
- maskClosable={false}
265
- zIndex={10000}
266
- title={
267
- <Space>
268
- <SettingOutlined />
269
- Nastavení sloupců
270
- </Space>
271
- }
272
- footer={
273
- <Space>
274
- <Button onClick={handleReset}>
275
- Obnovit původní
276
- </Button>
277
- <Button onClick={onCancel}>
278
- Storno
279
- </Button>
280
- <Button type="primary" onClick={handleSave}>
281
- Uložit změny
282
- </Button>
283
- </Space>
284
- }
285
- >
286
- <div className="column-editor-content">
287
- <div className="column-list">
288
- <DndContext
289
- sensors={sensors}
290
- collisionDetection={closestCenter}
291
- onDragEnd={handleDragEnd}
292
- >
293
- <SortableContext items={columnIds} strategy={verticalListSortingStrategy}>
294
- {editingColumns.map((column) => (
295
- <SortableColumnRow
296
- key={column.id}
297
- column={column}
298
- onVisibilityChange={handleVisibilityChange}
299
- onWidthChange={handleWidthChange}
300
- onHeaderNameChange={handleHeaderNameChange}
301
- />
302
- ))}
303
- </SortableContext>
304
- </DndContext>
305
- </div>
306
-
307
- </div>
308
-
309
- <style jsx>{`
310
- .column-editor-content {
311
- height: 100%;
312
- display: flex;
313
- flex-direction: column;
314
- overflow: hidden;
315
- }
316
-
317
- .column-list {
318
- flex: 1;
319
- overflow-y: auto;
320
- border: 1px solid #f0f0f0;
321
- border-radius: 6px;
322
- min-height: 300px;
323
- }
324
-
325
- .column-row {
326
- border-bottom: 1px solid #f0f0f0;
327
- transition: background-color 0.2s;
328
- }
329
-
330
- .column-row:hover {
331
- background-color: #fafafa;
332
- }
333
-
334
- .column-row:last-child {
335
- border-bottom: none;
336
- }
337
-
338
- .column-row-content {
339
- display: flex;
340
- align-items: center;
341
- padding: 12px 16px;
342
- gap: 16px;
343
- }
344
-
345
- .drag-handle {
346
- flex-shrink: 0;
347
- width: 20px;
348
- display: flex;
349
- align-items: center;
350
- justify-content: center;
351
- }
352
-
353
- .column-name {
354
- flex: 1;
355
- min-width: 150px;
356
- }
357
-
358
- .column-width {
359
- flex-shrink: 0;
360
- }
361
-
362
- .column-visibility {
363
- flex-shrink: 0;
364
- width: 120px;
365
- }
366
-
367
- `}</style>
368
- </DraggableModal>
369
- );
1
+ /* eslint-disable */
2
+ import React, { useState, useCallback, useMemo } from 'react';
3
+ import { default as Button } from 'antd/es/button';
4
+ import { default as Input } from 'antd/es/input';
5
+ import { default as InputNumber } from 'antd/es/input-number';
6
+ import { default as Space } from 'antd/es/space';
7
+ import { default as Typography } from 'antd/es/typography';
8
+ import { default as Divider } from 'antd/es/divider';
9
+ import {
10
+ HolderOutlined,
11
+ SettingOutlined,
12
+ HistoryOutlined
13
+ } from '@ant-design/icons';
14
+ import { default as Checkbox } from 'antd/es/checkbox';
15
+ import { default as Tooltip } from 'antd/es/tooltip';
16
+ import DraggableModal from '@bit.rhplus/draggable-modal';
17
+ import {
18
+ DndContext,
19
+ closestCenter,
20
+ KeyboardSensor,
21
+ PointerSensor,
22
+ useSensor,
23
+ useSensors,
24
+ } from '@dnd-kit/core';
25
+ import {
26
+ arrayMove,
27
+ SortableContext,
28
+ sortableKeyboardCoordinates,
29
+ verticalListSortingStrategy,
30
+ useSortable,
31
+ } from '@dnd-kit/sortable';
32
+ import {
33
+ CSS,
34
+ } from '@dnd-kit/utilities';
35
+
36
+ const { Text, Title } = Typography;
37
+
38
+ /**
39
+ * Sortable řádek pro jeden sloupec
40
+ */
41
+ const SortableColumnRow = ({ column, onVisibilityChange, onWidthChange, onHeaderNameChange, onResetColumn }) => {
42
+ const {
43
+ attributes,
44
+ listeners,
45
+ setNodeRef,
46
+ transform,
47
+ transition,
48
+ isDragging,
49
+ } = useSortable({ id: column.id });
50
+
51
+ const style = {
52
+ transform: CSS.Transform.toString(transform),
53
+ transition,
54
+ opacity: isDragging ? 0.5 : 1,
55
+ backgroundColor: isDragging ? '#f0f0f0' : 'white',
56
+ };
57
+
58
+ return (
59
+ <div
60
+ ref={setNodeRef}
61
+ style={style}
62
+ className="column-row"
63
+ >
64
+ <div className="column-row-content">
65
+ {/* Drag Handle */}
66
+ <div className="drag-handle" {...attributes} {...listeners}>
67
+ <HolderOutlined style={{ color: '#999', cursor: 'grab' }} />
68
+ </div>
69
+
70
+ {/* Visibility Checkbox */}
71
+ <div className="column-checkbox">
72
+ <Checkbox
73
+ checked={column.visible}
74
+ onChange={(e) => onVisibilityChange(column.id, e.target.checked)}
75
+ />
76
+ </div>
77
+
78
+ {/* Column Name */}
79
+ <div className="column-name">
80
+ <div className="column-name-wrapper">
81
+ <div style={{ position: 'relative', flex: 1, display: 'flex', alignItems: 'center' }}>
82
+ <Input
83
+ value={column.headerName}
84
+ onChange={(e) => onHeaderNameChange(column.id, e.target.value)}
85
+ placeholder="Název sloupce"
86
+ size="small"
87
+ variant="borderless"
88
+ style={{
89
+ fontWeight: '500',
90
+ // Modrá barva, pokud se aktuální text liší od původního textu v columnDefs (ne od uložených preferencí)
91
+ color: column.headerName !== column.originalHeaderName ? '#1890ff' : undefined,
92
+ width: '100%',
93
+ paddingRight: column.headerName !== column.originalHeaderName ? '24px' : '0'
94
+ }}
95
+ title={column.headerName !== column.originalHeaderName ? `Původní text v definici sloupce: ${column.originalHeaderName}` : undefined}
96
+ />
97
+ {/* Ikona pro obnovení původního textu - zobrazí se pouze při hover a pokud se text liší */}
98
+ {column.headerName !== column.originalHeaderName && (
99
+ <Tooltip title={`Obnovit původní název: "${column.originalHeaderName}"`}>
100
+ <HistoryOutlined
101
+ className="reset-icon"
102
+ onClick={() => onResetColumn(column.id)}
103
+ style={{
104
+ position: 'absolute',
105
+ right: '4px',
106
+ top: '50%',
107
+ transform: 'translateY(-50%)',
108
+ color: '#999',
109
+ cursor: 'pointer',
110
+ fontSize: '14px',
111
+ opacity: 0,
112
+ transition: 'opacity 0.2s, color 0.2s'
113
+ }}
114
+ />
115
+ </Tooltip>
116
+ )}
117
+ </div>
118
+ </div>
119
+ </div>
120
+
121
+ {/* Width Input */}
122
+ <div className="column-width">
123
+ <InputNumber
124
+ min={50}
125
+ max={1000}
126
+ value={column.width}
127
+ onChange={(value) => onWidthChange(column.id, value)}
128
+ addonAfter="px"
129
+ size="small"
130
+ style={{ width: '100px' }}
131
+ />
132
+ </div>
133
+ </div>
134
+ </div>
135
+ );
136
+ };
137
+
138
+ /**
139
+ * Modal pro editaci sloupců AG-Grid gridu
140
+ * @param {Object} props
141
+ * @param {boolean} props.open - Zda je modal otevřený
142
+ * @param {Function} props.onCancel - Callback pro zavření modalu
143
+ * @param {Function} props.onSave - Callback pro uložení změn
144
+ * @param {Array} props.columns - Pole sloupců k editaci
145
+ * @param {Function} props.getContainer - Container pro modal
146
+ */
147
+ export default function ColumnEditorModal({
148
+ open,
149
+ onCancel,
150
+ onSave,
151
+ columns = [],
152
+ getContainer
153
+ }) {
154
+ // Lokální stav pro editaci sloupců
155
+ const [editingColumns, setEditingColumns] = useState([]);
156
+
157
+ // Inicializace editovacího stavu při otevření modalu
158
+ React.useEffect(() => {
159
+ if (open && columns.length > 0) {
160
+ // Removed console.log for production
161
+
162
+ const initialColumns = columns.map((col, index) => ({
163
+ id: col.field,
164
+ field: col.field,
165
+ // Prioritně použij aktuální headerName
166
+ headerName: col.headerName || col.field,
167
+ // Zachovej původní originalHeaderName z columnDefs
168
+ originalHeaderName: col.originalHeaderName || col.headerName || col.field,
169
+ // Prioritně použij aktuální šířku
170
+ width: col.width || 100,
171
+ // Zachovej původní originalWidth z columnDefs
172
+ originalWidth: col.originalWidth || col.width || 100,
173
+ // Prioritně použij aktuální viditelnost
174
+ visible: col.visible !== undefined ? col.visible : !col.hide,
175
+ // Zachovej původní originalVisible
176
+ originalVisible: col.originalVisible !== undefined ? col.originalVisible : !col.hide,
177
+ order: index
178
+ }));
179
+
180
+ // Removed console.log for production
181
+
182
+ setEditingColumns(initialColumns);
183
+ }
184
+ }, [open]); // Odstraněna závislost na 'columns' - inicializace jen při otevření
185
+
186
+ // Sensor pro drag&drop
187
+ const sensors = useSensors(
188
+ useSensor(PointerSensor),
189
+ useSensor(KeyboardSensor, {
190
+ coordinateGetter: sortableKeyboardCoordinates,
191
+ })
192
+ );
193
+
194
+ // Handler pro ukončení drag operace
195
+ const handleDragEnd = useCallback((event) => {
196
+ const { active, over } = event;
197
+
198
+ if (active.id !== over?.id) {
199
+ setEditingColumns((items) => {
200
+ const oldIndex = items.findIndex((item) => item.id === active.id);
201
+ const newIndex = items.findIndex((item) => item.id === over.id);
202
+
203
+ return arrayMove(items, oldIndex, newIndex);
204
+ });
205
+ }
206
+ }, []);
207
+
208
+ // Handler pro změnu viditelnosti sloupce
209
+ const handleVisibilityChange = useCallback((columnId, visible) => {
210
+ setEditingColumns((prev) =>
211
+ prev.map((col) =>
212
+ col.id === columnId ? { ...col, visible } : col
213
+ )
214
+ );
215
+ }, []);
216
+
217
+ // Handler pro změnu šířky sloupce
218
+ const handleWidthChange = useCallback((columnId, width) => {
219
+ // Akceptujeme všechny hodnoty včetně null/undefined pro reset
220
+ // Minimální validace proběhne při ukládání
221
+ if (width === null || width === undefined || (width && width >= 50)) {
222
+ setEditingColumns((prev) =>
223
+ prev.map((col) =>
224
+ col.id === columnId ? { ...col, width } : col
225
+ )
226
+ );
227
+ }
228
+ }, []);
229
+
230
+ // Handler pro změnu názvu sloupce
231
+ const handleHeaderNameChange = useCallback((columnId, headerName) => {
232
+ setEditingColumns((prev) =>
233
+ prev.map((col) =>
234
+ col.id === columnId ? { ...col, headerName } : col
235
+ )
236
+ );
237
+ }, []);
238
+
239
+ // Handler pro reset jednotlivého sloupce na původní hodnotu
240
+ const handleResetColumn = useCallback((columnId) => {
241
+ setEditingColumns((prev) =>
242
+ prev.map((col) =>
243
+ col.id === columnId
244
+ ? { ...col, headerName: col.originalHeaderName }
245
+ : col
246
+ )
247
+ );
248
+ }, []);
249
+
250
+ // Handler pro uložení změn
251
+ const handleSave = useCallback(() => {
252
+ if (onSave) {
253
+ onSave(editingColumns);
254
+ }
255
+ onCancel();
256
+ }, [editingColumns, onSave, onCancel]);
257
+
258
+ // Handler pro reset na původní stav
259
+ const handleReset = useCallback(() => {
260
+ const resetColumns = columns.map((col) => ({
261
+ id: col.field,
262
+ field: col.field,
263
+ // Prioritně použij originalHeaderName, pokud existuje
264
+ headerName: col.originalHeaderName || col.headerName || col.field,
265
+ // Zachovej původní originalHeaderName
266
+ originalHeaderName: col.originalHeaderName || col.headerName || col.field,
267
+ // Prioritně použij originalWidth, pokud existuje
268
+ width: col.originalWidth || col.width || 100,
269
+ // Zachovej původní originalWidth
270
+ originalWidth: col.originalWidth || col.width || 100,
271
+ // Použij původní viditelnost z columnDefs
272
+ visible: col.originalVisible !== undefined ? col.originalVisible : !col.hide,
273
+ // Zachovej původní originalVisible
274
+ originalVisible: col.originalVisible !== undefined ? col.originalVisible : !col.hide,
275
+ // Použij původní pořadí z columnDefs
276
+ order: col.originalOrder !== undefined ? col.originalOrder : col.order
277
+ }));
278
+
279
+ // Seřadíme podle původního pořadí
280
+ const sortedResetColumns = resetColumns.sort((a, b) => a.order - b.order);
281
+ setEditingColumns(sortedResetColumns);
282
+ }, [columns]);
283
+
284
+ const columnIds = useMemo(() => editingColumns.map((col) => col.id), [editingColumns]);
285
+
286
+ // Dynamická výška podle velikosti obrazovky
287
+ const modalHeight = useMemo(() => {
288
+ if (typeof window !== 'undefined') {
289
+ const screenHeight = window.innerHeight;
290
+ // 80% výšky obrazovky (65% + 25%), minimálně 600px, maximálně 900px
291
+ // Odečteme 80px pro margin/padding aby se modál vždy vešel
292
+ return Math.min(Math.max((screenHeight - 80) * 0.80, 600), 900);
293
+ }
294
+ return 700;
295
+ }, []);
296
+
297
+ return (
298
+ <DraggableModal
299
+ width="650px"
300
+ height={`${modalHeight}px`}
301
+ open={open}
302
+ getContainer={getContainer}
303
+ onCancel={onCancel}
304
+ maskClosable={false}
305
+ zIndex={10000}
306
+ title={
307
+ <Space>
308
+ <SettingOutlined />
309
+ Nastavení sloupců
310
+ </Space>
311
+ }
312
+ footer={
313
+ <Space>
314
+ <Button onClick={handleReset}>
315
+ Obnovit původní
316
+ </Button>
317
+ <Button onClick={onCancel}>
318
+ Storno
319
+ </Button>
320
+ <Button type="primary" onClick={handleSave}>
321
+ Uložit změny
322
+ </Button>
323
+ </Space>
324
+ }
325
+ >
326
+ <div className="column-editor-content">
327
+ <div className="column-list">
328
+ <DndContext
329
+ sensors={sensors}
330
+ collisionDetection={closestCenter}
331
+ onDragEnd={handleDragEnd}
332
+ >
333
+ <SortableContext items={columnIds} strategy={verticalListSortingStrategy}>
334
+ {editingColumns.map((column) => (
335
+ <SortableColumnRow
336
+ key={column.id}
337
+ column={column}
338
+ onVisibilityChange={handleVisibilityChange}
339
+ onWidthChange={handleWidthChange}
340
+ onHeaderNameChange={handleHeaderNameChange}
341
+ onResetColumn={handleResetColumn}
342
+ />
343
+ ))}
344
+ </SortableContext>
345
+ </DndContext>
346
+ </div>
347
+
348
+ </div>
349
+
350
+ <style jsx>{`
351
+ .column-editor-content {
352
+ height: 100%;
353
+ display: flex;
354
+ flex-direction: column;
355
+ overflow: hidden;
356
+ }
357
+
358
+ .column-list {
359
+ flex: 1;
360
+ overflow-y: auto;
361
+ border: 1px solid #f0f0f0;
362
+ border-radius: 6px;
363
+ min-height: 300px;
364
+ }
365
+
366
+ .column-row {
367
+ transition: background-color 0.2s, box-shadow 0.2s;
368
+ border-radius: 6px;
369
+ margin: 2px 4px;
370
+ }
371
+
372
+ .column-row:hover {
373
+ background-color: #fafafa;
374
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
375
+ }
376
+
377
+ .column-row:hover .reset-icon {
378
+ opacity: 1 !important;
379
+ }
380
+
381
+ .column-row-content {
382
+ display: flex;
383
+ align-items: center;
384
+ padding: 12px 16px;
385
+ gap: 12px;
386
+ }
387
+
388
+ .column-checkbox {
389
+ flex-shrink: 0;
390
+ width: 20px;
391
+ display: flex;
392
+ align-items: center;
393
+ justify-content: center;
394
+ }
395
+
396
+ .column-name {
397
+ flex: 1;
398
+ min-width: 150px;
399
+ }
400
+
401
+ .column-name-wrapper {
402
+ display: flex;
403
+ align-items: center;
404
+ width: 100%;
405
+ }
406
+
407
+ .reset-icon:hover {
408
+ color: #1890ff !important;
409
+ transform: scale(1.1);
410
+ }
411
+
412
+ .column-width {
413
+ flex-shrink: 0;
414
+ }
415
+
416
+ .drag-handle {
417
+ flex-shrink: 0;
418
+ width: 20px;
419
+ display: flex;
420
+ align-items: center;
421
+ justify-content: center;
422
+ }
423
+
424
+ `}</style>
425
+ </DraggableModal>
426
+ );
370
427
  }