rozenite-sqlite 0.0.7 → 0.0.9

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,139 +0,0 @@
1
- import React, { useState } from 'react';
2
- import {
3
- View,
4
- Text,
5
- StyleSheet,
6
- ScrollView,
7
- Pressable,
8
- ActivityIndicator,
9
- } from 'react-native';
10
- import { C } from '../theme';
11
-
12
- export interface DropdownProps {
13
- label: string;
14
- value: string | null;
15
- options: string[];
16
- onSelect: (value: string) => void;
17
- formatLabel?: (v: string) => string;
18
- loading?: boolean;
19
- disabled?: boolean;
20
- zIndex?: number;
21
- }
22
-
23
- export function Dropdown({
24
- label,
25
- value,
26
- options,
27
- onSelect,
28
- formatLabel,
29
- loading,
30
- disabled,
31
- zIndex = 10,
32
- }: DropdownProps) {
33
- const [open, setOpen] = useState(false);
34
- const fmt = formatLabel ?? ((v: string) => v);
35
-
36
- return (
37
- <View style={[s.root, { zIndex }]}>
38
- <Text style={s.label}>{label}</Text>
39
- <Pressable
40
- style={[s.trigger, open && s.triggerOpen, disabled && s.triggerDisabled]}
41
- onPress={() => !disabled && setOpen((o) => !o)}
42
- >
43
- {loading ? <ActivityIndicator size="small" color={C.textSecondary} style={s.spinner} /> : null}
44
- <Text style={[s.triggerText, !value && s.triggerPlaceholder]} numberOfLines={1}>
45
- {value ? fmt(value) : '— select —'}
46
- </Text>
47
- <Text style={s.chevron}>{open ? '▴' : '▾'}</Text>
48
- </Pressable>
49
-
50
- {open && (
51
- <View style={[s.menu, { zIndex: zIndex + 10 }]}>
52
- <ScrollView style={s.menuScroll} nestedScrollEnabled>
53
- {options.length === 0 ? (
54
- <Text style={s.menuEmpty}>No options</Text>
55
- ) : (
56
- options.map((opt) => (
57
- <Pressable
58
- key={opt}
59
- style={({ pressed }) => [
60
- s.menuItem,
61
- value === opt && s.menuItemSelected,
62
- pressed && s.menuItemPressed,
63
- ]}
64
- onPress={() => {
65
- onSelect(opt);
66
- setOpen(false);
67
- }}
68
- >
69
- <Text style={[s.menuItemText, value === opt && s.menuItemTextSelected]}>
70
- {fmt(opt)}
71
- </Text>
72
- {value === opt && <Text style={s.checkmark}>✓</Text>}
73
- </Pressable>
74
- ))
75
- )}
76
- </ScrollView>
77
- </View>
78
- )}
79
- </View>
80
- );
81
- }
82
-
83
- const s = StyleSheet.create({
84
- root: { position: 'relative', minWidth: 180 },
85
- label: {
86
- fontSize: 10,
87
- fontWeight: '600',
88
- color: C.textMuted,
89
- textTransform: 'uppercase',
90
- letterSpacing: 0.8,
91
- marginBottom: 5,
92
- },
93
- trigger: {
94
- flexDirection: 'row',
95
- alignItems: 'center',
96
- paddingHorizontal: 12,
97
- paddingVertical: 8,
98
- borderRadius: 7,
99
- backgroundColor: C.surface2,
100
- borderWidth: 1,
101
- borderColor: C.border,
102
- minWidth: 180,
103
- },
104
- triggerOpen: { borderColor: C.accent },
105
- triggerDisabled: { opacity: 0.35 },
106
- spinner: { marginRight: 6 },
107
- triggerText: { fontSize: 13, color: C.text, fontWeight: '500', flex: 1 },
108
- triggerPlaceholder: { color: C.textMuted },
109
- chevron: { fontSize: 11, color: C.textSecondary, marginLeft: 8 },
110
- menu: {
111
- position: 'absolute',
112
- top: 62,
113
- left: 0,
114
- right: 0,
115
- backgroundColor: C.surface2,
116
- borderWidth: 1,
117
- borderColor: C.border,
118
- borderRadius: 8,
119
- overflow: 'hidden',
120
- shadowColor: '#000',
121
- shadowOffset: { width: 0, height: 8 },
122
- shadowOpacity: 0.5,
123
- shadowRadius: 20,
124
- },
125
- menuScroll: { maxHeight: 200 },
126
- menuEmpty: { padding: 14, fontSize: 12, color: C.textMuted, textAlign: 'center' },
127
- menuItem: {
128
- flexDirection: 'row',
129
- alignItems: 'center',
130
- justifyContent: 'space-between',
131
- paddingHorizontal: 12,
132
- paddingVertical: 10,
133
- },
134
- menuItemSelected: { backgroundColor: C.accentSubtle },
135
- menuItemPressed: { backgroundColor: C.surface },
136
- menuItemText: { fontSize: 13, color: C.text },
137
- menuItemTextSelected: { color: C.accent, fontWeight: '600' },
138
- checkmark: { fontSize: 12, color: C.accent },
139
- });
@@ -1,266 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { View, Text, Pressable, StyleSheet } from 'react-native';
3
- import { C } from '../theme';
4
-
5
- interface PaginationProps {
6
- page: number;
7
- pageSize: number;
8
- totalFiltered: number;
9
- totalRows: number;
10
- columnCount: number;
11
- onPageChange: (page: number) => void;
12
- onPageSizeChange: (size: number) => void;
13
- onClearTable?: () => void;
14
- }
15
-
16
- const PAGE_SIZES = [10, 25, 50, 100];
17
- const MAX_PAGE_BUTTONS = 5;
18
-
19
- export default function Pagination({
20
- page,
21
- pageSize,
22
- totalFiltered,
23
- totalRows,
24
- columnCount,
25
- onPageChange,
26
- onPageSizeChange,
27
- onClearTable,
28
- }: PaginationProps) {
29
- const [confirmClear, setConfirmClear] = useState(false);
30
- const totalPages = Math.max(1, Math.ceil(totalFiltered / pageSize));
31
- const from = totalFiltered === 0 ? 0 : (page - 1) * pageSize + 1;
32
- const to = Math.min(page * pageSize, totalFiltered);
33
-
34
- const half = Math.floor(MAX_PAGE_BUTTONS / 2);
35
- let startPage = Math.max(1, page - half);
36
- let endPage = startPage + MAX_PAGE_BUTTONS - 1;
37
- if (endPage > totalPages) {
38
- endPage = totalPages;
39
- startPage = Math.max(1, endPage - MAX_PAGE_BUTTONS + 1);
40
- }
41
- const pageButtons: number[] = [];
42
- for (let i = startPage; i <= endPage; i++) pageButtons.push(i);
43
-
44
- const filterActive = totalFiltered !== totalRows;
45
-
46
- return (
47
- <View style={s.bar}>
48
- <View style={s.left}>
49
- {onClearTable && !confirmClear && (
50
- <Pressable style={s.clearBtn} onPress={() => setConfirmClear(true)}>
51
- <Text style={s.clearBtnText}>⊘ Clear table</Text>
52
- </Pressable>
53
- )}
54
- {onClearTable && confirmClear && (
55
- <View style={s.confirmRow}>
56
- <Text style={s.confirmLabel}>Delete all rows?</Text>
57
- <Pressable
58
- style={s.confirmYes}
59
- onPress={() => { setConfirmClear(false); onClearTable(); }}
60
- >
61
- <Text style={s.confirmYesText}>Yes, clear</Text>
62
- </Pressable>
63
- <Pressable style={s.confirmNo} onPress={() => setConfirmClear(false)}>
64
- <Text style={s.confirmNoText}>Cancel</Text>
65
- </Pressable>
66
- </View>
67
- )}
68
- <Text style={s.info}>
69
- {totalFiltered === 0
70
- ? 'No rows'
71
- : `${from}–${to} of ${totalFiltered}${filterActive ? ` (filtered from ${totalRows})` : ''} rows · ${columnCount} col${columnCount !== 1 ? 's' : ''}`}
72
- </Text>
73
- </View>
74
-
75
- <View style={s.controls}>
76
- <NavBtn label="«" disabled={page <= 1} onPress={() => onPageChange(1)} />
77
- <NavBtn label="‹" disabled={page <= 1} onPress={() => onPageChange(page - 1)} />
78
-
79
- {startPage > 1 && (
80
- <>
81
- <PageBtn num={1} active={false} onPress={() => onPageChange(1)} />
82
- {startPage > 2 && <Text style={s.ellipsis}>…</Text>}
83
- </>
84
- )}
85
-
86
- {pageButtons.map((n) => (
87
- <PageBtn key={n} num={n} active={n === page} onPress={() => onPageChange(n)} />
88
- ))}
89
-
90
- {endPage < totalPages && (
91
- <>
92
- {endPage < totalPages - 1 && <Text style={s.ellipsis}>…</Text>}
93
- <PageBtn num={totalPages} active={false} onPress={() => onPageChange(totalPages)} />
94
- </>
95
- )}
96
-
97
- <NavBtn label="›" disabled={page >= totalPages} onPress={() => onPageChange(page + 1)} />
98
- <NavBtn label="»" disabled={page >= totalPages} onPress={() => onPageChange(totalPages)} />
99
- </View>
100
-
101
- <View style={s.sizeRow}>
102
- {PAGE_SIZES.map((sz) => (
103
- <Pressable
104
- key={sz}
105
- onPress={() => onPageSizeChange(sz)}
106
- style={[s.sizeBtn, sz === pageSize && s.sizeBtnActive]}
107
- >
108
- <Text style={[s.sizeBtnText, sz === pageSize && s.sizeBtnTextActive]}>{sz}</Text>
109
- </Pressable>
110
- ))}
111
- </View>
112
- </View>
113
- );
114
- }
115
-
116
- function PageBtn({ num, active, onPress }: { num: number; active: boolean; onPress: () => void }) {
117
- return (
118
- <Pressable onPress={onPress} style={[s.pageBtn, active && s.pageBtnActive]}>
119
- <Text style={[s.pageBtnText, active && s.pageBtnTextActive]}>{num}</Text>
120
- </Pressable>
121
- );
122
- }
123
-
124
- function NavBtn({ label, disabled, onPress }: { label: string; disabled: boolean; onPress: () => void }) {
125
- return (
126
- <Pressable onPress={disabled ? undefined : onPress} style={[s.navBtn, disabled && s.navBtnDisabled]}>
127
- <Text style={[s.navBtnText, disabled && s.navBtnTextDisabled]}>{label}</Text>
128
- </Pressable>
129
- );
130
- }
131
-
132
- const s = StyleSheet.create({
133
- bar: {
134
- flexDirection: 'row',
135
- alignItems: 'center',
136
- justifyContent: 'space-between',
137
- paddingHorizontal: 12,
138
- paddingVertical: 8,
139
- backgroundColor: C.surface,
140
- borderTopWidth: 1,
141
- borderTopColor: C.border,
142
- flexWrap: 'wrap',
143
- gap: 8,
144
- },
145
- left: {
146
- flexDirection: 'row',
147
- alignItems: 'center',
148
- minWidth: 180,
149
- flexShrink: 1,
150
- },
151
- info: {
152
- color: C.textMuted,
153
- fontSize: 12,
154
- },
155
- clearBtn: {
156
- paddingHorizontal: 10,
157
- paddingVertical: 5,
158
- borderRadius: 5,
159
- borderWidth: 1,
160
- borderColor: 'transparent',
161
- cursor: 'pointer',
162
- },
163
- clearBtnText: { fontSize: 12, color: C.danger, fontWeight: '500' },
164
- confirmRow: { flexDirection: 'row', alignItems: 'center', gap: 6 },
165
- confirmLabel: { fontSize: 11, color: C.textMuted },
166
- confirmYes: {
167
- paddingHorizontal: 9,
168
- paddingVertical: 4,
169
- borderRadius: 5,
170
- backgroundColor: C.danger,
171
- cursor: 'pointer',
172
- },
173
- confirmYesText: { fontSize: 11, fontWeight: '600', color: '#fff' },
174
- confirmNo: {
175
- paddingHorizontal: 9,
176
- paddingVertical: 4,
177
- borderRadius: 5,
178
- backgroundColor: C.surface2,
179
- borderWidth: 1,
180
- borderColor: C.border,
181
- cursor: 'pointer',
182
- },
183
- confirmNoText: { fontSize: 11, color: C.textSecondary },
184
- controls: {
185
- flexDirection: 'row',
186
- alignItems: 'center',
187
- gap: 2,
188
- },
189
- ellipsis: {
190
- color: C.textMuted,
191
- fontSize: 13,
192
- paddingHorizontal: 4,
193
- lineHeight: 28,
194
- },
195
- pageBtn: {
196
- minWidth: 28,
197
- height: 28,
198
- borderRadius: 4,
199
- alignItems: 'center',
200
- justifyContent: 'center',
201
- paddingHorizontal: 6,
202
- backgroundColor: C.surface2,
203
- borderWidth: 1,
204
- borderColor: C.border,
205
- },
206
- pageBtnActive: {
207
- backgroundColor: C.accent,
208
- borderColor: C.accent,
209
- },
210
- pageBtnText: {
211
- color: C.text,
212
- fontSize: 12,
213
- },
214
- pageBtnTextActive: {
215
- color: '#fff',
216
- fontWeight: '600',
217
- },
218
- navBtn: {
219
- width: 28,
220
- height: 28,
221
- borderRadius: 4,
222
- alignItems: 'center',
223
- justifyContent: 'center',
224
- backgroundColor: C.surface2,
225
- borderWidth: 1,
226
- borderColor: C.border,
227
- },
228
- navBtnDisabled: {
229
- opacity: 0.3,
230
- },
231
- navBtnText: {
232
- color: C.text,
233
- fontSize: 14,
234
- lineHeight: 18,
235
- },
236
- navBtnTextDisabled: {
237
- color: C.textMuted,
238
- },
239
- sizeRow: {
240
- flexDirection: 'row',
241
- gap: 2,
242
- alignItems: 'center',
243
- },
244
- sizeBtn: {
245
- height: 26,
246
- paddingHorizontal: 8,
247
- borderRadius: 4,
248
- alignItems: 'center',
249
- justifyContent: 'center',
250
- backgroundColor: C.surface2,
251
- borderWidth: 1,
252
- borderColor: C.border,
253
- },
254
- sizeBtnActive: {
255
- backgroundColor: C.surface2,
256
- borderColor: C.accent,
257
- },
258
- sizeBtnText: {
259
- color: C.textMuted,
260
- fontSize: 11,
261
- },
262
- sizeBtnTextActive: {
263
- color: C.accent,
264
- fontWeight: '600',
265
- },
266
- });
@@ -1,273 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { View, Text, StyleSheet, ScrollView, Pressable, TextInput } from 'react-native';
3
- import { C, type RowData } from '../theme';
4
-
5
- function isJsonString(val: string): boolean {
6
- const t = val.trim();
7
- if (t.length < 2 || (t[0] !== '{' && t[0] !== '[')) return false;
8
- try { JSON.parse(t); return true; } catch { return false; }
9
- }
10
-
11
- export interface RowDetailPanelProps {
12
- row: RowData | null;
13
- rowIndex: number | null;
14
- onClose: () => void;
15
- onSave: (updated: RowData) => void;
16
- onDelete: () => void;
17
- }
18
-
19
- export function RowDetailPanel({ row, rowIndex, onClose, onSave, onDelete }: RowDetailPanelProps) {
20
- const [draft, setDraft] = useState<RowData>({});
21
- const [dirty, setDirty] = useState(false);
22
- const [confirmDelete, setConfirmDelete] = useState(false);
23
-
24
- useEffect(() => {
25
- if (row) {
26
- const formatted = Object.fromEntries(
27
- Object.entries(row).map(([k, v]) => {
28
- const s = v == null ? v : String(v);
29
- if (s != null && isJsonString(s)) {
30
- try { return [k, JSON.stringify(JSON.parse(s), null, 2)]; } catch {}
31
- }
32
- return [k, v];
33
- })
34
- );
35
- setDraft(formatted);
36
- setDirty(false);
37
- setConfirmDelete(false);
38
- }
39
- }, [row]);
40
-
41
- if (!row) return null;
42
-
43
- const handleChange = (key: string, value: string) => {
44
- setDraft((prev) => ({ ...prev, [key]: value }));
45
- setDirty(true);
46
- };
47
-
48
- const handleSave = () => {
49
- onSave(draft);
50
- setDirty(false);
51
- };
52
-
53
- const handleCancel = () => {
54
- setDraft({ ...row });
55
- setDirty(false);
56
- setConfirmDelete(false);
57
- onClose();
58
- };
59
-
60
- return (
61
- <View style={s.panel}>
62
- <View style={s.header}>
63
- <View>
64
- <Text style={s.eyebrow}>ROW DETAIL</Text>
65
- <View style={s.titleRow}>
66
- <Text style={s.title}>Row #{(rowIndex ?? 0) + 1}</Text>
67
- {dirty && <View style={s.dirtyDot} />}
68
- </View>
69
- </View>
70
- <Pressable
71
- onPress={onClose}
72
- style={({ pressed }) => [s.closeBtn, pressed && { opacity: 0.6 }]}
73
- >
74
- <Text style={s.closeBtnText}>✕</Text>
75
- </Pressable>
76
- </View>
77
-
78
- <ScrollView style={s.scroll} showsVerticalScrollIndicator={false}>
79
- {Object.entries(draft).map(([key, value]) => {
80
- const strVal = value === null || value === undefined ? '' : String(value);
81
- const isJson = isJsonString(strVal);
82
- return (
83
- <View key={key} style={s.field}>
84
- <View style={s.fieldKeyRow}>
85
- <Text style={s.fieldKey}>{key}</Text>
86
- {isJson && <Text style={s.fieldJsonBadge}>JSON</Text>}
87
- </View>
88
- <TextInput
89
- style={[s.fieldInput, isJson && s.fieldInputJson]}
90
- value={strVal}
91
- onChangeText={(text) => handleChange(key, text)}
92
- placeholder="NULL"
93
- placeholderTextColor={C.textMuted}
94
- multiline={isJson || strVal.length > 50}
95
- />
96
- </View>
97
- );
98
- })}
99
- <View style={{ height: 20 }} />
100
- </ScrollView>
101
-
102
- <View style={s.primaryActions}>
103
- <Pressable
104
- style={({ pressed }) => [s.btn, s.btnSave, !dirty && s.btnSaveDisabled, pressed && !dirty ? {} : pressed && s.btnPressed]}
105
- onPress={dirty ? handleSave : undefined}
106
- >
107
- <Text style={[s.btnSaveText, !dirty && s.btnSaveTextDisabled]}>Save</Text>
108
- </Pressable>
109
- <Pressable
110
- style={({ pressed }) => [s.btn, s.btnCancel, pressed && s.btnPressed]}
111
- onPress={handleCancel}
112
- >
113
- <Text style={s.btnCancelText}>Cancel</Text>
114
- </Pressable>
115
- </View>
116
-
117
- <View style={s.deleteZone}>
118
- {!confirmDelete ? (
119
- <Pressable
120
- style={({ pressed }) => [s.btnDeleteSmall, pressed && s.btnPressed]}
121
- onPress={() => setConfirmDelete(true)}
122
- >
123
- <Text style={s.btnDeleteSmallText}>⊘ Delete this row</Text>
124
- </Pressable>
125
- ) : (
126
- <View style={s.confirmBox}>
127
- <Text style={s.confirmLabel}>This action cannot be undone.</Text>
128
- <View style={s.confirmRow}>
129
- <Pressable
130
- style={({ pressed }) => [s.btn, s.btnConfirm, { flex: 1 }, pressed && s.btnPressed]}
131
- onPress={onDelete}
132
- >
133
- <Text style={s.btnConfirmText}>Yes, delete</Text>
134
- </Pressable>
135
- <Pressable
136
- style={({ pressed }) => [s.btn, s.btnCancelSmall, { flex: 1 }, pressed && s.btnPressed]}
137
- onPress={() => setConfirmDelete(false)}
138
- >
139
- <Text style={s.btnCancelText}>Cancel</Text>
140
- </Pressable>
141
- </View>
142
- </View>
143
- )}
144
- </View>
145
- </View>
146
- );
147
- }
148
-
149
- const s = StyleSheet.create({
150
- panel: {
151
- width: 300,
152
- backgroundColor: C.surface,
153
- borderLeftWidth: 1,
154
- borderLeftColor: C.border,
155
- flexDirection: 'column',
156
- shadowColor: '#000',
157
- shadowOffset: { width: -8, height: 0 },
158
- shadowOpacity: 0.45,
159
- shadowRadius: 20,
160
- elevation: 10,
161
- boxShadow: '-8px 0 24px rgba(0,0,0,0.45)',
162
- },
163
- header: {
164
- flexDirection: 'row',
165
- alignItems: 'center',
166
- justifyContent: 'space-between',
167
- paddingHorizontal: 16,
168
- paddingVertical: 14,
169
- borderBottomWidth: 1,
170
- borderBottomColor: C.border,
171
- },
172
- eyebrow: {
173
- fontSize: 10,
174
- fontWeight: '700',
175
- color: C.textMuted,
176
- textTransform: 'uppercase',
177
- letterSpacing: 0.8,
178
- },
179
- titleRow: { flexDirection: 'row', alignItems: 'center', gap: 8, marginTop: 2 },
180
- title: { fontSize: 16, fontWeight: '700', color: C.text },
181
- dirtyDot: { width: 7, height: 7, borderRadius: 4, backgroundColor: C.accent },
182
- closeBtn: {
183
- width: 28,
184
- height: 28,
185
- borderRadius: 6,
186
- backgroundColor: C.surface2,
187
- alignItems: 'center',
188
- justifyContent: 'center',
189
- },
190
- closeBtnText: { fontSize: 12, color: C.textSecondary },
191
- scroll: { flex: 1, paddingHorizontal: 16, paddingTop: 16 },
192
- field: { marginBottom: 16 },
193
- fieldKeyRow: { flexDirection: 'row', alignItems: 'center', gap: 6, marginBottom: 5 },
194
- fieldKey: {
195
- fontSize: 10,
196
- fontWeight: '700',
197
- color: C.textMuted,
198
- textTransform: 'uppercase',
199
- letterSpacing: 0.7,
200
- },
201
- fieldJsonBadge: {
202
- fontSize: 9,
203
- fontWeight: '700',
204
- color: '#a78bfa',
205
- backgroundColor: 'rgba(167,139,250,0.12)',
206
- paddingHorizontal: 4,
207
- paddingVertical: 2,
208
- borderRadius: 3,
209
- },
210
- fieldInput: {
211
- backgroundColor: C.surface2,
212
- borderWidth: 1,
213
- borderColor: C.border,
214
- borderRadius: 6,
215
- paddingHorizontal: 10,
216
- paddingVertical: 8,
217
- fontSize: 13,
218
- color: C.text,
219
- outlineStyle: 'none' as any,
220
- },
221
- fieldInputJson: {
222
- fontFamily: 'monospace',
223
- fontSize: 12,
224
- lineHeight: 18,
225
- borderColor: 'rgba(167,139,250,0.3)',
226
- minHeight: 180,
227
- textAlignVertical: 'top',
228
- paddingTop: 10,
229
- },
230
- primaryActions: {
231
- flexDirection: 'row',
232
- gap: 8,
233
- paddingHorizontal: 16,
234
- paddingTop: 14,
235
- paddingBottom: 10,
236
- borderTopWidth: 1,
237
- borderTopColor: C.border,
238
- },
239
- deleteZone: {
240
- paddingHorizontal: 16,
241
- paddingBottom: 14,
242
- paddingTop: 2,
243
- },
244
- btn: {
245
- flex: 1,
246
- borderRadius: 6,
247
- paddingVertical: 9,
248
- alignItems: 'center',
249
- justifyContent: 'center',
250
- },
251
- btnPressed: { opacity: 0.72 },
252
- btnSave: { backgroundColor: C.accent },
253
- btnSaveDisabled: { backgroundColor: C.surface2 },
254
- btnSaveText: { fontSize: 13, fontWeight: '600', color: '#fff' },
255
- btnSaveTextDisabled: { color: C.textMuted },
256
- btnCancel: { backgroundColor: C.surface2, borderWidth: 1, borderColor: C.border },
257
- btnCancelText: { fontSize: 13, fontWeight: '500', color: C.textSecondary },
258
- btnDeleteSmall: {
259
- paddingVertical: 7,
260
- alignItems: 'center',
261
- justifyContent: 'center',
262
- borderRadius: 6,
263
- borderWidth: 1,
264
- borderColor: 'transparent',
265
- },
266
- btnDeleteSmallText: { fontSize: 12, color: C.danger, fontWeight: '500' },
267
- confirmBox: { gap: 8 },
268
- confirmLabel: { fontSize: 11, color: C.textMuted, textAlign: 'center' },
269
- confirmRow: { flexDirection: 'row', gap: 8 },
270
- btnConfirm: { backgroundColor: C.danger },
271
- btnConfirmText: { fontSize: 12, fontWeight: '600', color: '#fff' },
272
- btnCancelSmall: { backgroundColor: C.surface2, borderWidth: 1, borderColor: C.border },
273
- });