react-native-storage-inspector 1.0.1 → 1.0.3

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/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var React6 = require('react');
3
+ var React7 = require('react');
4
4
  var reactNative = require('react-native');
5
5
 
6
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
- var React6__default = /*#__PURE__*/_interopDefault(React6);
8
+ var React7__default = /*#__PURE__*/_interopDefault(React7);
9
9
 
10
10
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
11
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -41,7 +41,6 @@ function createMMKVAdapter(instance, name) {
41
41
  }
42
42
 
43
43
  // src/adapters/async-storage.ts
44
- var asyncStorage = null;
45
44
  function getAsyncStorageFromRequire() {
46
45
  try {
47
46
  const mod = require("@react-native-async-storage/async-storage");
@@ -50,8 +49,8 @@ function getAsyncStorageFromRequire() {
50
49
  return null;
51
50
  }
52
51
  }
53
- function createAsyncStorageAdapter(instance) {
54
- const getStorage = () => instance ?? (asyncStorage ?? (asyncStorage = getAsyncStorageFromRequire()));
52
+ function createAsyncStorageAdapter() {
53
+ const getStorage = () => getAsyncStorageFromRequire();
55
54
  return {
56
55
  type: "async-storage",
57
56
  name: "Async Storage",
@@ -82,7 +81,6 @@ function createAsyncStorageAdapter(instance) {
82
81
  }
83
82
 
84
83
  // src/adapters/keychain.ts
85
- var keychain = null;
86
84
  function getKeychainFromRequire() {
87
85
  try {
88
86
  return require("react-native-keychain");
@@ -90,14 +88,14 @@ function getKeychainFromRequire() {
90
88
  return null;
91
89
  }
92
90
  }
93
- function createKeychainAdapter(knownKeys = [], instance) {
94
- const getKc = () => instance ?? (keychain ?? (keychain = getKeychainFromRequire()));
91
+ function createKeychainAdapter() {
92
+ const getKc = () => getKeychainFromRequire();
95
93
  return {
96
94
  type: "keychain",
97
95
  name: "Keychain",
98
96
  async getAllKeys() {
99
97
  const kc = getKc();
100
- if (!kc) return [...knownKeys];
98
+ if (!kc) return [];
101
99
  const genericServices = [];
102
100
  if (typeof kc.getAllGenericPasswordServices === "function") {
103
101
  try {
@@ -106,42 +104,32 @@ function createKeychainAdapter(knownKeys = [], instance) {
106
104
  } catch {
107
105
  }
108
106
  }
109
- const merged = /* @__PURE__ */ new Set([...genericServices, ...knownKeys]);
110
- return Array.from(merged);
107
+ return genericServices;
111
108
  },
112
109
  async getItem(key) {
113
110
  const kc = getKc();
114
- if (!kc) return null;
115
- if (typeof kc.getGenericPassword === "function") {
116
- try {
117
- const creds2 = await kc.getGenericPassword({ service: key });
118
- if (creds2 && typeof creds2 === "object" && "password" in creds2) {
119
- return creds2.password;
120
- }
121
- } catch {
111
+ if (!kc?.getGenericPassword) return null;
112
+ try {
113
+ const creds = await kc.getGenericPassword({ service: key });
114
+ if (creds && typeof creds === "object" && "password" in creds) {
115
+ return creds.password;
122
116
  }
117
+ } catch {
123
118
  }
124
- const creds = await kc.getInternetCredentials(key);
125
- return creds?.password ?? null;
119
+ return null;
126
120
  },
127
121
  async setItem(key, value) {
128
122
  const kc = getKc();
129
- if (!kc) throw new Error("react-native-keychain is not available");
130
- if (typeof kc.setGenericPassword === "function") {
131
- const result2 = await kc.setGenericPassword(key, value, { service: key });
132
- if (result2 === false) throw new Error("Keychain set failed");
133
- return;
134
- }
135
- const result = await kc.setInternetCredentials(key, key, value);
123
+ if (!kc?.setGenericPassword)
124
+ throw new Error("react-native-keychain is not available");
125
+ const result = await kc.setGenericPassword(key, value, { service: key });
136
126
  if (result === false) throw new Error("Keychain set failed");
137
127
  },
138
128
  async removeItem(key) {
139
129
  const kc = getKc();
140
- if (!kc) throw new Error("react-native-keychain is not available");
141
- if (typeof kc.resetGenericPassword === "function") {
142
- await kc.resetGenericPassword({ service: key });
143
- }
144
- await kc.resetInternetCredentials(key);
130
+ if (!kc?.resetGenericPassword)
131
+ throw new Error("react-native-keychain is not available");
132
+ await kc.resetGenericPassword({ service: key });
145
133
  },
146
134
  isAvailable() {
147
135
  return getKc() !== null;
@@ -149,8 +137,20 @@ function createKeychainAdapter(knownKeys = [], instance) {
149
137
  };
150
138
  }
151
139
 
140
+ // src/utils.ts
141
+ function parsePersistedKeys(raw) {
142
+ if (raw == null || raw === "") return [];
143
+ try {
144
+ const parsed = JSON.parse(raw);
145
+ if (!Array.isArray(parsed)) return [];
146
+ return parsed.filter((item) => typeof item === "string");
147
+ } catch {
148
+ return [];
149
+ }
150
+ }
151
+
152
152
  // src/adapters/secure-store.ts
153
- var secureStore = null;
153
+ var PERSISTED_KEYS_STORAGE_KEY = "__storage_inspector_secure_store_keys__";
154
154
  function getSecureStoreFromRequire() {
155
155
  try {
156
156
  return require("expo-secure-store");
@@ -158,13 +158,17 @@ function getSecureStoreFromRequire() {
158
158
  return null;
159
159
  }
160
160
  }
161
- function createSecureStoreAdapter(knownKeys = [], instance) {
162
- const getStore = () => instance ?? (secureStore ?? (secureStore = getSecureStoreFromRequire()));
161
+ function createSecureStoreAdapter(knownKeys = []) {
162
+ const getStore = () => getSecureStoreFromRequire();
163
163
  return {
164
164
  type: "expo-secure-store",
165
165
  name: "Secure Store",
166
166
  async getAllKeys() {
167
- return [...knownKeys];
167
+ const store = getStore();
168
+ if (!store) return [];
169
+ const persistedKeysString = await store.getItemAsync(PERSISTED_KEYS_STORAGE_KEY);
170
+ const persistedKeys = parsePersistedKeys(persistedKeysString);
171
+ return [.../* @__PURE__ */ new Set([...knownKeys, ...persistedKeys])];
168
172
  },
169
173
  async getItem(key) {
170
174
  const store = getStore();
@@ -175,11 +179,26 @@ function createSecureStoreAdapter(knownKeys = [], instance) {
175
179
  const store = getStore();
176
180
  if (!store) throw new Error("expo-secure-store is not available");
177
181
  await store.setItemAsync(key, value);
182
+ if (key === PERSISTED_KEYS_STORAGE_KEY) return;
183
+ const persistedKeysString = await store.getItemAsync(PERSISTED_KEYS_STORAGE_KEY);
184
+ const persistedKeys = parsePersistedKeys(persistedKeysString);
185
+ const newPersistedKeys = [.../* @__PURE__ */ new Set([...persistedKeys, key])];
186
+ await store.setItemAsync(
187
+ PERSISTED_KEYS_STORAGE_KEY,
188
+ JSON.stringify(newPersistedKeys)
189
+ );
178
190
  },
179
191
  async removeItem(key) {
180
192
  const store = getStore();
181
193
  if (!store) throw new Error("expo-secure-store is not available");
182
194
  await store.deleteItemAsync(key);
195
+ const persistedKeysString = await store.getItemAsync(PERSISTED_KEYS_STORAGE_KEY);
196
+ const persistedKeys = parsePersistedKeys(persistedKeysString);
197
+ const newPersistedKeys = persistedKeys.filter((k) => k !== key);
198
+ await store.setItemAsync(
199
+ PERSISTED_KEYS_STORAGE_KEY,
200
+ JSON.stringify(newPersistedKeys)
201
+ );
183
202
  },
184
203
  isAvailable() {
185
204
  return getStore() !== null;
@@ -187,10 +206,10 @@ function createSecureStoreAdapter(knownKeys = [], instance) {
187
206
  };
188
207
  }
189
208
  function useStorageItems(adapter) {
190
- const [items, setItems] = React6.useState([]);
191
- const [loading, setLoading] = React6.useState(true);
192
- const [error, setError] = React6.useState(null);
193
- const refresh = React6.useCallback(async () => {
209
+ const [items, setItems] = React7.useState([]);
210
+ const [loading, setLoading] = React7.useState(true);
211
+ const [error, setError] = React7.useState(null);
212
+ const refresh = React7.useCallback(async () => {
194
213
  if (!adapter || !adapter.isAvailable()) {
195
214
  setItems([]);
196
215
  setLoading(false);
@@ -203,7 +222,8 @@ function useStorageItems(adapter) {
203
222
  const pairs = [];
204
223
  for (const key of keys) {
205
224
  const value = await adapter.getItem(key);
206
- pairs.push({ key, value: value ?? "" });
225
+ if (value === null) continue;
226
+ pairs.push({ key, value });
207
227
  }
208
228
  setItems(pairs);
209
229
  } catch (e) {
@@ -213,7 +233,7 @@ function useStorageItems(adapter) {
213
233
  setLoading(false);
214
234
  }
215
235
  }, [adapter]);
216
- React6.useEffect(() => {
236
+ React7.useEffect(() => {
217
237
  refresh();
218
238
  }, [refresh]);
219
239
  return { items, loading, error, refresh };
@@ -230,7 +250,8 @@ var theme = {
230
250
  text: "#000000",
231
251
  textSecondary: "#666666",
232
252
  textMuted: "#999999",
233
- inverted: "#ffffff"
253
+ inverted: "#ffffff",
254
+ overlayBackdrop: "rgba(0,0,0,0.5)"
234
255
  }
235
256
  };
236
257
 
@@ -251,15 +272,11 @@ var ROTATION = {
251
272
  chevronDown: "90deg",
252
273
  chevronUp: "-90deg"
253
274
  };
254
- function Icon({
255
- name,
256
- size = 20,
257
- tintColor = theme.colors.text,
258
- iconStyle
259
- }) {
275
+ function Icon(props) {
276
+ const { name, size = 20, tintColor = theme.colors.text, iconStyle } = props;
260
277
  const glyph = GLYPHS[name] ?? "?";
261
278
  const rotation = ROTATION[name];
262
- return /* @__PURE__ */ React6__default.default.createElement(
279
+ return /* @__PURE__ */ React7__default.default.createElement(
263
280
  reactNative.Text,
264
281
  {
265
282
  style: [
@@ -282,7 +299,6 @@ var { width: SCREEN_WIDTH } = reactNative.Dimensions.get("window");
282
299
  var LAYOUT = {
283
300
  padding: 16,
284
301
  fontSize: 14,
285
- headerHeight: 52,
286
302
  rowMinHeight: 48,
287
303
  sectionHeaderHeight: 48,
288
304
  iconSize: 20,
@@ -296,432 +312,20 @@ var LAYOUT = {
296
312
  sectionRadius: 4,
297
313
  screenWidth: SCREEN_WIDTH
298
314
  };
299
- var { colors } = theme;
300
- var styles2 = reactNative.StyleSheet.create({
301
- container: {
302
- flex: 1,
303
- width: "100%",
304
- backgroundColor: colors.background
305
- },
306
- content: {
307
- flex: 1
308
- },
309
- scroll: {
310
- flex: 1
311
- },
312
- header: {
313
- height: LAYOUT.headerHeight,
314
- flexDirection: "row",
315
- alignItems: "center",
316
- justifyContent: "space-between",
317
- paddingHorizontal: LAYOUT.padding,
318
- borderBottomWidth: reactNative.StyleSheet.hairlineWidth,
319
- borderBottomColor: colors.border,
320
- backgroundColor: colors.background
321
- },
322
- headerLeft: {
323
- minWidth: 44,
324
- alignItems: "flex-start"
325
- },
326
- headerCenter: {
327
- flex: 1,
328
- alignItems: "center",
329
- justifyContent: "center"
330
- },
331
- headerRight: {
332
- minWidth: 44,
333
- alignItems: "flex-end"
334
- },
335
- sectionHeaderLabelWrap: {
336
- flex: 1
337
- },
338
- headerTitle: {
339
- fontSize: 17,
340
- fontWeight: "600",
341
- color: colors.text
342
- },
343
- headerButton: {
344
- width: 44,
345
- height: 44,
346
- alignItems: "center",
347
- justifyContent: "center"
348
- },
349
- scrollContent: {
350
- flexGrow: 1,
351
- paddingBottom: LAYOUT.fabSize + LAYOUT.padding + 20,
352
- paddingTop: LAYOUT.padding
353
- },
354
- sectionHeader: {
355
- height: LAYOUT.sectionHeaderHeight,
356
- flexDirection: "row",
357
- alignItems: "center",
358
- paddingHorizontal: LAYOUT.padding,
359
- borderBottomWidth: reactNative.StyleSheet.hairlineWidth,
360
- borderBottomColor: colors.border,
361
- backgroundColor: colors.backgroundSecondary,
362
- marginTop: LAYOUT.padding,
363
- marginHorizontal: LAYOUT.padding,
364
- borderRadius: LAYOUT.sectionRadius
365
- },
366
- sectionHeaderLabel: {
367
- fontSize: 15,
368
- fontWeight: "600",
369
- color: colors.text
370
- },
371
- sectionHeaderCount: {
372
- color: colors.textSecondary,
373
- fontWeight: "400"
374
- },
375
- storageRowActions: {
376
- flexDirection: "row",
377
- alignItems: "center",
378
- gap: LAYOUT.iconGap
379
- },
380
- iconButton: {
381
- width: LAYOUT.iconButtonSize,
382
- height: LAYOUT.iconButtonSize,
383
- alignItems: "center",
384
- justifyContent: "center"
385
- },
386
- iconSlot: {
387
- width: LAYOUT.iconButtonSize,
388
- height: LAYOUT.iconButtonSize,
389
- alignItems: "center",
390
- justifyContent: "center"
391
- },
392
- itemRow: {
393
- minHeight: LAYOUT.rowMinHeight,
394
- paddingHorizontal: LAYOUT.padding,
395
- paddingVertical: 12,
396
- borderBottomWidth: reactNative.StyleSheet.hairlineWidth,
397
- borderBottomColor: colors.borderLight,
398
- backgroundColor: colors.background,
399
- marginHorizontal: LAYOUT.padding,
400
- marginBottom: 4
401
- },
402
- itemRowCollapsed: {
403
- flexDirection: "row",
404
- alignItems: "center",
405
- alignSelf: "stretch"
406
- },
407
- itemKey: {
408
- flex: 1,
409
- fontSize: LAYOUT.fontSize,
410
- fontWeight: "500",
411
- color: colors.text
412
- },
413
- itemChars: {
414
- fontSize: 12,
415
- color: colors.textSecondary,
416
- marginTop: 2
417
- },
418
- itemRowActions: {
419
- flexDirection: "row",
420
- alignItems: "center",
421
- marginLeft: LAYOUT.iconGap,
422
- gap: LAYOUT.iconGap
423
- },
424
- itemRowExpanded: {
425
- paddingTop: 4
426
- },
427
- valueBox: {
428
- backgroundColor: colors.backgroundSecondary,
429
- borderRadius: 8,
430
- padding: 12,
431
- marginTop: 8,
432
- marginBottom: 8,
433
- borderWidth: reactNative.StyleSheet.hairlineWidth,
434
- borderColor: colors.border
435
- },
436
- valueBoxLabel: {
437
- fontSize: 11,
438
- fontWeight: "600",
439
- color: colors.textSecondary,
440
- marginBottom: 4,
441
- textTransform: "uppercase"
442
- },
443
- valueBoxText: {
444
- fontSize: LAYOUT.fontSize,
445
- color: colors.text
446
- },
447
- empty: {
448
- padding: LAYOUT.padding * 2,
449
- alignItems: "center",
450
- marginHorizontal: LAYOUT.padding
451
- },
452
- emptyText: {
453
- fontSize: LAYOUT.fontSize,
454
- color: colors.textMuted
455
- },
456
- loading: {
457
- padding: LAYOUT.padding * 2,
458
- alignItems: "center",
459
- marginHorizontal: LAYOUT.padding
460
- },
461
- loadingText: {
462
- fontSize: LAYOUT.fontSize,
463
- color: colors.textSecondary
464
- },
465
- error: {
466
- padding: LAYOUT.padding,
467
- backgroundColor: colors.backgroundTertiary,
468
- marginHorizontal: LAYOUT.padding,
469
- marginVertical: 8,
470
- borderRadius: 8
471
- },
472
- errorText: {
473
- fontSize: LAYOUT.fontSize,
474
- color: colors.text
475
- },
476
- keychainHint: {
477
- padding: LAYOUT.padding,
478
- marginHorizontal: LAYOUT.padding,
479
- marginTop: 8,
480
- marginBottom: 4,
481
- backgroundColor: colors.backgroundSecondary,
482
- borderRadius: 8
483
- },
484
- keychainHintText: {
485
- fontSize: LAYOUT.fontSize - 1,
486
- color: colors.textSecondary
487
- },
488
- list: {
489
- flex: 1
490
- },
491
- listContent: {
492
- flexGrow: 1,
493
- paddingBottom: LAYOUT.fabSize + LAYOUT.padding + 20
494
- },
495
- row: {
496
- flexDirection: "row",
497
- alignItems: "center",
498
- minHeight: LAYOUT.rowMinHeight,
499
- paddingHorizontal: LAYOUT.padding,
500
- paddingVertical: 12,
501
- borderBottomWidth: reactNative.StyleSheet.hairlineWidth,
502
- borderBottomColor: colors.borderLight,
503
- backgroundColor: colors.background,
504
- marginHorizontal: LAYOUT.padding
505
- },
506
- rowKey: {
507
- flex: 1,
508
- fontSize: LAYOUT.fontSize,
509
- fontWeight: "500",
510
- color: colors.text
511
- },
512
- rowValue: {
513
- fontSize: LAYOUT.fontSize - 1,
514
- color: colors.textSecondary
515
- },
516
- rowActions: {
517
- flexDirection: "row",
518
- alignItems: "center",
519
- marginLeft: LAYOUT.iconGap,
520
- gap: LAYOUT.iconGap
521
- },
522
- rowButton: {
523
- paddingVertical: 8,
524
- paddingHorizontal: 12
525
- },
526
- rowButtonText: {
527
- fontSize: 14,
528
- fontWeight: "600",
529
- color: colors.text
530
- },
531
- rowButtonDanger: {
532
- color: colors.text
533
- },
534
- addButton: {
535
- position: "absolute",
536
- bottom: LAYOUT.padding + 16,
537
- right: LAYOUT.padding + 16,
538
- width: LAYOUT.fabSize,
539
- height: LAYOUT.fabSize,
540
- borderRadius: LAYOUT.fabSize / 2,
541
- backgroundColor: colors.text,
542
- alignItems: "center",
543
- justifyContent: "center"
544
- },
545
- addButtonText: {
546
- fontSize: 16,
547
- fontWeight: "600",
548
- color: colors.inverted
549
- },
550
- fab: {
551
- position: "absolute",
552
- bottom: LAYOUT.padding + 16,
553
- right: LAYOUT.padding + 16,
554
- width: LAYOUT.fabSize,
555
- height: LAYOUT.fabSize,
556
- borderRadius: LAYOUT.fabSize / 2,
557
- backgroundColor: colors.text,
558
- alignItems: "center",
559
- justifyContent: "center"
560
- },
561
- formOverlay: {
562
- flex: 1,
563
- backgroundColor: "rgba(0,0,0,0.5)",
564
- justifyContent: "flex-end",
565
- alignItems: "center"
566
- },
567
- formModal: {
568
- width: "100%",
569
- maxWidth: LAYOUT.screenWidth,
570
- backgroundColor: colors.background,
571
- borderTopLeftRadius: LAYOUT.modalRadius,
572
- borderTopRightRadius: LAYOUT.modalRadius,
573
- padding: LAYOUT.padding,
574
- paddingBottom: LAYOUT.padding + 34
575
- },
576
- formHeader: {
577
- flexDirection: "row",
578
- alignItems: "center",
579
- justifyContent: "space-between",
580
- marginBottom: LAYOUT.padding
581
- },
582
- formTitle: {
583
- fontSize: 17,
584
- fontWeight: "600",
585
- color: colors.text,
586
- flex: 1
587
- },
588
- formCloseButton: {
589
- width: 44,
590
- height: 44,
591
- alignItems: "flex-end",
592
- justifyContent: "center"
593
- },
594
- formStorageType: {
595
- fontSize: 13,
596
- color: colors.textSecondary,
597
- marginBottom: 12
598
- },
599
- formLabel: {
600
- fontSize: 12,
601
- fontWeight: "600",
602
- color: colors.textSecondary,
603
- marginBottom: 6
604
- },
605
- formInput: {
606
- borderWidth: 1,
607
- borderColor: colors.border,
608
- borderRadius: 10,
609
- padding: 12,
610
- fontSize: LAYOUT.fontSize,
611
- marginBottom: LAYOUT.padding,
612
- color: colors.text,
613
- backgroundColor: colors.background
614
- },
615
- formInputDisabled: {
616
- backgroundColor: colors.backgroundSecondary,
617
- color: colors.textSecondary
618
- },
619
- formActions: {
620
- flexDirection: "row",
621
- justifyContent: "flex-end",
622
- gap: 12,
623
- marginTop: 8
624
- },
625
- formButton: {
626
- paddingVertical: 12,
627
- paddingHorizontal: 20,
628
- borderRadius: 10,
629
- minWidth: 100,
630
- alignItems: "center"
631
- },
632
- formButtonCancel: {
633
- backgroundColor: "transparent",
634
- borderWidth: 1,
635
- borderColor: colors.text
636
- },
637
- formButtonSubmit: {
638
- backgroundColor: colors.text
639
- },
640
- formButtonText: {
641
- fontSize: 16,
642
- fontWeight: "600"
643
- },
644
- formButtonTextCancel: {
645
- color: colors.text
646
- },
647
- formButtonTextSubmit: {
648
- color: colors.inverted
649
- },
650
- confirmOverlay: {
651
- flex: 1,
652
- backgroundColor: "rgba(0,0,0,0.5)",
653
- justifyContent: "flex-end",
654
- alignItems: "center"
655
- },
656
- confirmModal: {
657
- width: "100%",
658
- maxWidth: LAYOUT.screenWidth,
659
- backgroundColor: colors.background,
660
- borderTopLeftRadius: LAYOUT.modalRadius,
661
- borderTopRightRadius: LAYOUT.modalRadius,
662
- padding: LAYOUT.padding,
663
- paddingBottom: LAYOUT.padding + 34
664
- },
665
- confirmHeader: {
666
- flexDirection: "row",
667
- alignItems: "center",
668
- justifyContent: "space-between",
669
- marginBottom: 12
670
- },
671
- confirmTitle: {
672
- fontSize: 17,
673
- fontWeight: "600",
674
- color: colors.text,
675
- flex: 1
676
- },
677
- confirmMessage: {
678
- fontSize: 15,
679
- color: colors.textSecondary,
680
- lineHeight: 22,
681
- marginBottom: 20
682
- },
683
- confirmActions: {
684
- flexDirection: "row",
685
- gap: 12
686
- },
687
- confirmButton: {
688
- flex: 1,
689
- paddingVertical: 14,
690
- borderRadius: 10,
691
- alignItems: "center"
692
- },
693
- confirmButtonSecondary: {
694
- backgroundColor: "transparent",
695
- borderWidth: 1,
696
- borderColor: colors.text
697
- },
698
- confirmButtonDanger: {
699
- backgroundColor: colors.text
700
- },
701
- confirmButtonText: {
702
- fontSize: 16,
703
- fontWeight: "600"
704
- },
705
- confirmButtonTextSecondary: {
706
- color: colors.text
707
- },
708
- confirmButtonTextDanger: {
709
- color: colors.inverted
710
- }
711
- });
712
315
 
713
316
  // src/components/IconButton.tsx
714
- function IconButton({
715
- name,
716
- onPress,
717
- size = LAYOUT.iconSize,
718
- tintColor = theme.colors.text,
719
- disabled = false,
720
- hitSlop = LAYOUT.hitSlop,
721
- style,
722
- activeOpacity = 0.6
723
- }) {
724
- return /* @__PURE__ */ React6__default.default.createElement(
317
+ function IconButton(props) {
318
+ const {
319
+ name,
320
+ onPress,
321
+ size = LAYOUT.iconSize,
322
+ tintColor = theme.colors.text,
323
+ disabled = false,
324
+ hitSlop = LAYOUT.hitSlop,
325
+ style,
326
+ activeOpacity = 0.6
327
+ } = props;
328
+ return /* @__PURE__ */ React7__default.default.createElement(
725
329
  reactNative.TouchableOpacity,
726
330
  {
727
331
  style: [styles2.iconButton, style],
@@ -730,7 +334,7 @@ function IconButton({
730
334
  hitSlop,
731
335
  activeOpacity
732
336
  },
733
- /* @__PURE__ */ React6__default.default.createElement(
337
+ /* @__PURE__ */ React7__default.default.createElement(
734
338
  Icon,
735
339
  {
736
340
  name,
@@ -740,18 +344,25 @@ function IconButton({
740
344
  )
741
345
  );
742
346
  }
347
+ var styles2 = reactNative.StyleSheet.create({
348
+ iconButton: {
349
+ width: LAYOUT.iconButtonSize,
350
+ height: LAYOUT.iconButtonSize,
351
+ alignItems: "center",
352
+ justifyContent: "center"
353
+ }
354
+ });
743
355
 
744
356
  // src/strings.ts
745
357
  var strings = {
746
358
  // StorageInspector
747
359
  noAdapterAvailable: "No storage adapter available. Install at least one of: react-native-mmkv, @react-native-async-storage/async-storage, react-native-keychain, expo-secure-store",
748
360
  // StorageSection
749
- keychainHint: "No generic password items yet. Add a key using + above, or pass keychainKeys for internet credentials.",
361
+ keychainHint: "No generic password items yet. Add a key using + above.",
750
362
  secureStoreHint: "Secure Store has no list API. Pass secureStoreKeys prop with known keys, or add a key using + above.",
751
363
  loading: "Loading\u2026",
752
364
  noItems: "No items",
753
365
  valueLabel: "Value",
754
- emptyValue: "(empty)",
755
366
  charCount: (n) => n === 1 ? "1 char" : `${n} chars`,
756
367
  deleteItemTitle: (key) => `Delete ${key}?`,
757
368
  deleteItemMessage: (key) => `This will permanently delete the ${key} storage item. Do you wish to continue?`,
@@ -759,7 +370,7 @@ var strings = {
759
370
  clearAllMessage: (count, name) => `This will permanently delete all ${count} ${name} items. Do you wish to continue?`,
760
371
  // StorageList
761
372
  storageNotAvailable: "This storage is not available.",
762
- keychainHintShort: "No items yet. Add a key below, or pass keychainKeys for internet credentials.",
373
+ keychainHintShort: "No items yet. Add a key below.",
763
374
  edit: "Edit",
764
375
  delete: "Delete",
765
376
  addItem: "Add item",
@@ -782,19 +393,14 @@ var strings = {
782
393
  };
783
394
 
784
395
  // src/components/ItemForm.tsx
785
- function ItemForm({
786
- visible,
787
- storageName,
788
- editingItem,
789
- onSave,
790
- onCancel
791
- }) {
792
- const [key, setKey] = React6.useState("");
793
- const [value, setValue] = React6.useState("");
794
- const [saving, setSaving] = React6.useState(false);
795
- const [error, setError] = React6.useState(null);
396
+ function ItemForm(props) {
397
+ const { visible, storageName, editingItem, onSave, onCancel } = props;
398
+ const [key, setKey] = React7.useState("");
399
+ const [value, setValue] = React7.useState("");
400
+ const [saving, setSaving] = React7.useState(false);
401
+ const [error, setError] = React7.useState(null);
796
402
  const isEdit = editingItem !== null;
797
- React6.useEffect(() => {
403
+ React7.useEffect(() => {
798
404
  if (visible) {
799
405
  setKey(editingItem?.key ?? "");
800
406
  setValue(editingItem?.value ?? "");
@@ -819,27 +425,27 @@ function ItemForm({
819
425
  }
820
426
  };
821
427
  const title = isEdit ? strings.editItemTitle(editingItem?.key ?? "") : strings.addItemTitle(storageName);
822
- return /* @__PURE__ */ React6__default.default.createElement(reactNative.Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onCancel }, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.formOverlay }, /* @__PURE__ */ React6__default.default.createElement(
428
+ return /* @__PURE__ */ React7__default.default.createElement(reactNative.Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onCancel }, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles3.formOverlay }, /* @__PURE__ */ React7__default.default.createElement(
823
429
  reactNative.TouchableOpacity,
824
430
  {
825
431
  style: { flex: 1, width: "100%" },
826
432
  activeOpacity: 1,
827
433
  onPress: onCancel
828
434
  }
829
- ), /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.formModal }, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.formHeader }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.formTitle, numberOfLines: 1 }, title), /* @__PURE__ */ React6__default.default.createElement(
435
+ ), /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles3.formModal }, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles3.formHeader }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles3.formTitle, numberOfLines: 1 }, title), /* @__PURE__ */ React7__default.default.createElement(
830
436
  IconButton,
831
437
  {
832
438
  name: "close",
833
439
  onPress: onCancel,
834
440
  size: 24,
835
441
  tintColor: theme.colors.textSecondary,
836
- style: styles2.formCloseButton,
442
+ style: styles3.formCloseButton,
837
443
  hitSlop: LAYOUT.hitSlopLarge
838
444
  }
839
- )), /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.formStorageType }, strings.storageTypeLabel(storageName)), /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.formLabel }, strings.keyLabel), /* @__PURE__ */ React6__default.default.createElement(
445
+ )), /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles3.formStorageType }, strings.storageTypeLabel(storageName)), /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles3.formLabel }, strings.keyLabel), /* @__PURE__ */ React7__default.default.createElement(
840
446
  reactNative.TextInput,
841
447
  {
842
- style: [styles2.formInput, isEdit && styles2.formInputDisabled],
448
+ style: [styles3.formInput, isEdit && styles3.formInputDisabled],
843
449
  value: key,
844
450
  onChangeText: setKey,
845
451
  placeholder: strings.enterKeyPlaceholder,
@@ -848,10 +454,10 @@ function ItemForm({
848
454
  autoCapitalize: "none",
849
455
  multiline: true
850
456
  }
851
- ), /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.formLabel }, strings.valueLabel), /* @__PURE__ */ React6__default.default.createElement(
457
+ ), /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles3.formLabel }, strings.valueLabel), /* @__PURE__ */ React7__default.default.createElement(
852
458
  reactNative.TextInput,
853
459
  {
854
- style: styles2.formInput,
460
+ style: styles3.formInput,
855
461
  value,
856
462
  onChangeText: setValue,
857
463
  placeholder: strings.enterValuePlaceholder,
@@ -859,91 +465,262 @@ function ItemForm({
859
465
  multiline: true,
860
466
  numberOfLines: 3
861
467
  }
862
- ), error ? /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: [styles2.errorText, { marginBottom: 12 }] }, error) : null, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.formActions }, /* @__PURE__ */ React6__default.default.createElement(
468
+ ), error ? /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: [styles3.errorText, { marginBottom: 12 }] }, error) : null, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles3.formActions }, /* @__PURE__ */ React7__default.default.createElement(
863
469
  reactNative.TouchableOpacity,
864
470
  {
865
- style: [styles2.formButton, styles2.formButtonCancel],
471
+ style: [styles3.formButton, styles3.formButtonCancel],
866
472
  onPress: onCancel,
867
473
  disabled: saving
868
474
  },
869
- /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: [styles2.formButtonText, styles2.formButtonTextCancel] }, strings.cancel)
870
- ), /* @__PURE__ */ React6__default.default.createElement(
475
+ /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: [styles3.formButtonText, styles3.formButtonTextCancel] }, strings.cancel)
476
+ ), /* @__PURE__ */ React7__default.default.createElement(
871
477
  reactNative.TouchableOpacity,
872
478
  {
873
- style: [styles2.formButton, styles2.formButtonSubmit],
479
+ style: [styles3.formButton, styles3.formButtonSubmit],
874
480
  onPress: handleSubmit,
875
481
  disabled: saving
876
482
  },
877
- /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: [styles2.formButtonText, styles2.formButtonTextSubmit] }, saving ? strings.saving : isEdit ? strings.save : strings.add)
483
+ /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: [styles3.formButtonText, styles3.formButtonTextSubmit] }, saving ? strings.saving : isEdit ? strings.save : strings.add)
878
484
  )))));
879
485
  }
880
- function ConfirmModal({
881
- visible,
882
- title,
883
- message,
884
- confirmLabel = strings.confirmDelete,
885
- cancelLabel = strings.cancelKeep,
886
- danger = true,
887
- onConfirm,
888
- onCancel
889
- }) {
890
- const handleConfirm = () => {
891
- void Promise.resolve(onConfirm());
892
- };
893
- return /* @__PURE__ */ React6__default.default.createElement(reactNative.Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onCancel }, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.confirmOverlay }, /* @__PURE__ */ React6__default.default.createElement(
486
+ var { colors } = theme;
487
+ var styles3 = reactNative.StyleSheet.create({
488
+ formOverlay: {
489
+ flex: 1,
490
+ backgroundColor: colors.overlayBackdrop,
491
+ justifyContent: "flex-end",
492
+ alignItems: "center"
493
+ },
494
+ formModal: {
495
+ width: "100%",
496
+ maxWidth: LAYOUT.screenWidth,
497
+ backgroundColor: colors.background,
498
+ borderTopLeftRadius: LAYOUT.modalRadius,
499
+ borderTopRightRadius: LAYOUT.modalRadius,
500
+ padding: LAYOUT.padding,
501
+ paddingBottom: LAYOUT.padding + 34
502
+ },
503
+ formHeader: {
504
+ flexDirection: "row",
505
+ alignItems: "center",
506
+ justifyContent: "space-between",
507
+ marginBottom: LAYOUT.padding
508
+ },
509
+ formTitle: {
510
+ fontSize: 17,
511
+ fontWeight: "600",
512
+ color: colors.text,
513
+ flex: 1
514
+ },
515
+ formCloseButton: {
516
+ width: 44,
517
+ height: 44,
518
+ alignItems: "flex-end",
519
+ justifyContent: "center"
520
+ },
521
+ formStorageType: {
522
+ fontSize: 13,
523
+ color: colors.textSecondary,
524
+ marginBottom: 12
525
+ },
526
+ formLabel: {
527
+ fontSize: 12,
528
+ fontWeight: "600",
529
+ color: colors.textSecondary,
530
+ marginBottom: 6
531
+ },
532
+ formInput: {
533
+ borderWidth: 1,
534
+ borderColor: colors.border,
535
+ borderRadius: 10,
536
+ padding: 12,
537
+ fontSize: LAYOUT.fontSize,
538
+ marginBottom: LAYOUT.padding,
539
+ color: colors.text,
540
+ backgroundColor: colors.background
541
+ },
542
+ formInputDisabled: {
543
+ backgroundColor: colors.backgroundSecondary,
544
+ color: colors.textSecondary
545
+ },
546
+ formActions: {
547
+ flexDirection: "row",
548
+ justifyContent: "flex-end",
549
+ gap: 12,
550
+ marginTop: 8
551
+ },
552
+ formButton: {
553
+ paddingVertical: 12,
554
+ paddingHorizontal: 20,
555
+ borderRadius: 10,
556
+ minWidth: 100,
557
+ alignItems: "center"
558
+ },
559
+ formButtonCancel: {
560
+ backgroundColor: "transparent",
561
+ borderWidth: 1,
562
+ borderColor: colors.text
563
+ },
564
+ formButtonSubmit: {
565
+ backgroundColor: colors.text
566
+ },
567
+ formButtonText: {
568
+ fontSize: 16,
569
+ fontWeight: "600"
570
+ },
571
+ formButtonTextCancel: {
572
+ color: colors.text
573
+ },
574
+ formButtonTextSubmit: {
575
+ color: colors.inverted
576
+ },
577
+ errorText: {
578
+ fontSize: LAYOUT.fontSize,
579
+ color: colors.text
580
+ }
581
+ });
582
+ function ConfirmModal(props) {
583
+ const {
584
+ visible,
585
+ title,
586
+ message,
587
+ confirmLabel = strings.confirmDelete,
588
+ cancelLabel = strings.cancelKeep,
589
+ danger = true,
590
+ onConfirm,
591
+ onCancel
592
+ } = props;
593
+ return /* @__PURE__ */ React7__default.default.createElement(reactNative.Modal, { visible, transparent: true, animationType: "slide", onRequestClose: onCancel }, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles4.confirmOverlay }, /* @__PURE__ */ React7__default.default.createElement(
894
594
  reactNative.TouchableOpacity,
895
595
  {
896
596
  style: { flex: 1, width: "100%" },
897
597
  activeOpacity: 1,
898
598
  onPress: onCancel
899
599
  }
900
- ), /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.confirmModal }, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.confirmHeader }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.confirmTitle }, title), /* @__PURE__ */ React6__default.default.createElement(
600
+ ), /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles4.confirmModal }, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles4.confirmHeader }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles4.confirmTitle }, title), /* @__PURE__ */ React7__default.default.createElement(
901
601
  IconButton,
902
602
  {
903
603
  name: "close",
904
604
  onPress: onCancel,
905
605
  size: 24,
906
606
  tintColor: theme.colors.textSecondary,
907
- style: styles2.formCloseButton,
607
+ style: styles4.formCloseButton,
908
608
  hitSlop: LAYOUT.hitSlopLarge
909
609
  }
910
- )), /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.confirmMessage }, message), /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.confirmActions }, /* @__PURE__ */ React6__default.default.createElement(
610
+ )), /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles4.confirmMessage }, message), /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles4.confirmActions }, /* @__PURE__ */ React7__default.default.createElement(
911
611
  reactNative.TouchableOpacity,
912
612
  {
913
- style: [styles2.confirmButton, styles2.confirmButtonSecondary],
613
+ style: [styles4.confirmButton, styles4.confirmButtonSecondary],
914
614
  onPress: onCancel
915
615
  },
916
- /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: [styles2.confirmButtonText, styles2.confirmButtonTextSecondary] }, cancelLabel)
917
- ), /* @__PURE__ */ React6__default.default.createElement(
616
+ /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: [styles4.confirmButtonText, styles4.confirmButtonTextSecondary] }, cancelLabel)
617
+ ), /* @__PURE__ */ React7__default.default.createElement(
918
618
  reactNative.TouchableOpacity,
919
619
  {
920
620
  style: [
921
- styles2.confirmButton,
922
- danger ? styles2.confirmButtonDanger : styles2.formButtonSubmit
621
+ styles4.confirmButton,
622
+ danger ? styles4.confirmButtonDanger : styles4.formButtonSubmit
923
623
  ],
924
- onPress: handleConfirm
624
+ onPress: onConfirm
925
625
  },
926
- /* @__PURE__ */ React6__default.default.createElement(
626
+ /* @__PURE__ */ React7__default.default.createElement(
927
627
  reactNative.Text,
928
628
  {
929
629
  style: [
930
- styles2.confirmButtonText,
931
- danger ? styles2.confirmButtonTextDanger : styles2.formButtonTextSubmit
630
+ styles4.confirmButtonText,
631
+ danger ? styles4.confirmButtonTextDanger : styles4.formButtonTextSubmit
932
632
  ]
933
633
  },
934
634
  confirmLabel
935
635
  )
936
636
  )))));
937
637
  }
938
- function ItemRowActions({
939
- item,
940
- onCopy,
941
- onEdit,
942
- onDelete,
943
- showChevron = false,
944
- chevronDirection = "down"
945
- }) {
946
- return /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.itemRowActions }, /* @__PURE__ */ React6__default.default.createElement(IconButton, { name: "copy", onPress: () => onCopy(item) }), /* @__PURE__ */ React6__default.default.createElement(IconButton, { name: "edit", onPress: () => onEdit(item) }), /* @__PURE__ */ React6__default.default.createElement(IconButton, { name: "trash", onPress: () => onDelete(item) }), showChevron && /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.iconSlot }, /* @__PURE__ */ React6__default.default.createElement(
638
+ var { colors: colors2 } = theme;
639
+ var styles4 = reactNative.StyleSheet.create({
640
+ confirmOverlay: {
641
+ flex: 1,
642
+ backgroundColor: colors2.overlayBackdrop,
643
+ justifyContent: "flex-end",
644
+ alignItems: "center"
645
+ },
646
+ confirmModal: {
647
+ width: "100%",
648
+ maxWidth: LAYOUT.screenWidth,
649
+ backgroundColor: colors2.background,
650
+ borderTopLeftRadius: LAYOUT.modalRadius,
651
+ borderTopRightRadius: LAYOUT.modalRadius,
652
+ padding: LAYOUT.padding,
653
+ paddingBottom: LAYOUT.padding + 34
654
+ },
655
+ confirmHeader: {
656
+ flexDirection: "row",
657
+ alignItems: "center",
658
+ justifyContent: "space-between",
659
+ marginBottom: 12
660
+ },
661
+ confirmTitle: {
662
+ fontSize: 17,
663
+ fontWeight: "600",
664
+ color: colors2.text,
665
+ flex: 1
666
+ },
667
+ formCloseButton: {
668
+ width: 44,
669
+ height: 44,
670
+ alignItems: "flex-end",
671
+ justifyContent: "center"
672
+ },
673
+ confirmMessage: {
674
+ fontSize: 15,
675
+ color: colors2.textSecondary,
676
+ lineHeight: 22,
677
+ marginBottom: 20
678
+ },
679
+ confirmActions: {
680
+ flexDirection: "row",
681
+ gap: 12
682
+ },
683
+ confirmButton: {
684
+ flex: 1,
685
+ paddingVertical: 14,
686
+ borderRadius: 10,
687
+ alignItems: "center"
688
+ },
689
+ confirmButtonSecondary: {
690
+ backgroundColor: "transparent",
691
+ borderWidth: 1,
692
+ borderColor: colors2.text
693
+ },
694
+ confirmButtonDanger: {
695
+ backgroundColor: colors2.text
696
+ },
697
+ formButtonSubmit: {
698
+ backgroundColor: colors2.text
699
+ },
700
+ confirmButtonText: {
701
+ fontSize: 16,
702
+ fontWeight: "600"
703
+ },
704
+ confirmButtonTextSecondary: {
705
+ color: colors2.text
706
+ },
707
+ confirmButtonTextDanger: {
708
+ color: colors2.inverted
709
+ },
710
+ formButtonTextSubmit: {
711
+ color: colors2.inverted
712
+ }
713
+ });
714
+ function ItemRowActions(props) {
715
+ const {
716
+ item,
717
+ onCopy,
718
+ onEdit,
719
+ onDelete,
720
+ showChevron = false,
721
+ chevronDirection = "down"
722
+ } = props;
723
+ return /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles5.itemRowActions }, /* @__PURE__ */ React7__default.default.createElement(IconButton, { name: "copy", onPress: () => onCopy(item) }), /* @__PURE__ */ React7__default.default.createElement(IconButton, { name: "edit", onPress: () => onEdit(item) }), /* @__PURE__ */ React7__default.default.createElement(IconButton, { name: "trash", onPress: () => onDelete(item) }), showChevron && /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles5.iconSlot }, /* @__PURE__ */ React7__default.default.createElement(
947
724
  Icon,
948
725
  {
949
726
  name: chevronDirection === "up" ? "chevronUp" : "chevronDown",
@@ -952,33 +729,144 @@ function ItemRowActions({
952
729
  }
953
730
  )));
954
731
  }
732
+ var styles5 = reactNative.StyleSheet.create({
733
+ itemRowActions: {
734
+ flexDirection: "row",
735
+ alignItems: "center",
736
+ marginLeft: LAYOUT.iconGap,
737
+ gap: LAYOUT.iconGap
738
+ },
739
+ iconSlot: {
740
+ width: LAYOUT.iconButtonSize,
741
+ height: LAYOUT.iconButtonSize,
742
+ alignItems: "center",
743
+ justifyContent: "center"
744
+ }
745
+ });
746
+
747
+ // src/components/StorageList.tsx
748
+ function StorageList(props) {
749
+ const { item, onCopy, onEdit, onDelete } = props;
750
+ const [expandedKeys, setExpandedKeys] = React7.useState(/* @__PURE__ */ new Set());
751
+ const charCount = item.value.length;
752
+ const handleToggleExpanded = () => {
753
+ setExpandedKeys((prev) => {
754
+ const next = new Set(prev);
755
+ if (next.has(item.key)) next.delete(item.key);
756
+ else next.add(item.key);
757
+ return next;
758
+ });
759
+ };
760
+ const isExpanded = expandedKeys.has(item.key);
761
+ return /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles6.itemRow }, /* @__PURE__ */ React7__default.default.createElement(reactNative.TouchableOpacity, { onPress: handleToggleExpanded, activeOpacity: 0.7 }, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles6.itemRowCollapsed }, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: { flex: 1 } }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles6.itemKey, numberOfLines: 1 }, item.key), /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles6.itemChars }, strings.charCount(charCount))), !isExpanded ? /* @__PURE__ */ React7__default.default.createElement(
762
+ ItemRowActions,
763
+ {
764
+ item,
765
+ onCopy,
766
+ onEdit,
767
+ onDelete,
768
+ showChevron: true,
769
+ chevronDirection: "down"
770
+ }
771
+ ) : /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles6.iconSlot }, /* @__PURE__ */ React7__default.default.createElement(
772
+ Icon,
773
+ {
774
+ name: "chevronUp",
775
+ size: LAYOUT.chevronSize,
776
+ tintColor: theme.colors.text
777
+ }
778
+ )))), isExpanded && /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles6.itemRowExpanded }, /* @__PURE__ */ React7__default.default.createElement(reactNative.TouchableOpacity, { onPress: () => onEdit(item), style: styles6.valueBox }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles6.valueBoxLabel }, strings.valueLabel), /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles6.valueBoxText, selectable: true }, item.value)), /* @__PURE__ */ React7__default.default.createElement(
779
+ ItemRowActions,
780
+ {
781
+ item,
782
+ onCopy,
783
+ onEdit,
784
+ onDelete
785
+ }
786
+ )));
787
+ }
788
+ var { colors: colors3 } = theme;
789
+ var styles6 = reactNative.StyleSheet.create({
790
+ itemRow: {
791
+ minHeight: LAYOUT.rowMinHeight,
792
+ paddingHorizontal: LAYOUT.padding,
793
+ paddingVertical: 12,
794
+ borderBottomWidth: reactNative.StyleSheet.hairlineWidth,
795
+ borderBottomColor: colors3.borderLight,
796
+ backgroundColor: colors3.background,
797
+ marginHorizontal: LAYOUT.padding,
798
+ marginBottom: 4
799
+ },
800
+ itemRowCollapsed: {
801
+ flexDirection: "row",
802
+ alignItems: "center",
803
+ alignSelf: "stretch"
804
+ },
805
+ itemKey: {
806
+ flex: 1,
807
+ fontSize: LAYOUT.fontSize,
808
+ fontWeight: "500",
809
+ color: colors3.text
810
+ },
811
+ itemChars: {
812
+ fontSize: 12,
813
+ color: colors3.textSecondary,
814
+ marginTop: 2
815
+ },
816
+ iconSlot: {
817
+ width: LAYOUT.iconButtonSize,
818
+ height: LAYOUT.iconButtonSize,
819
+ alignItems: "center",
820
+ justifyContent: "center"
821
+ },
822
+ itemRowExpanded: {
823
+ paddingTop: 4
824
+ },
825
+ valueBox: {
826
+ backgroundColor: colors3.backgroundSecondary,
827
+ borderRadius: 8,
828
+ padding: 12,
829
+ marginTop: 8,
830
+ marginBottom: 8,
831
+ borderWidth: reactNative.StyleSheet.hairlineWidth,
832
+ borderColor: colors3.border
833
+ },
834
+ valueBoxLabel: {
835
+ fontSize: 11,
836
+ fontWeight: "600",
837
+ color: colors3.textSecondary,
838
+ marginBottom: 4,
839
+ textTransform: "uppercase"
840
+ },
841
+ valueBoxText: {
842
+ fontSize: LAYOUT.fontSize,
843
+ color: colors3.text
844
+ }
845
+ });
955
846
 
956
847
  // src/components/StorageSection.tsx
957
- function StorageSection({
958
- adapter,
959
- keychainKeys,
960
- onKeychainKeyAdded,
961
- onSecureStoreKeyAdded,
962
- defaultExpanded = true,
963
- expanded: expandedProp,
964
- onToggleExpanded,
965
- refreshTrigger
966
- }) {
848
+ function StorageSection(props) {
849
+ const {
850
+ adapter,
851
+ defaultExpanded = true,
852
+ expanded: expandedProp,
853
+ onToggleExpanded,
854
+ refreshTrigger
855
+ } = props;
967
856
  const { items, loading, error, refresh } = useStorageItems(adapter);
968
- const [expandedInternal, setExpandedInternal] = React6.useState(defaultExpanded);
857
+ const [expandedInternal, setExpandedInternal] = React7.useState(defaultExpanded);
969
858
  const expanded = expandedProp !== void 0 ? expandedProp : expandedInternal;
970
859
  const handleToggleExpanded = () => {
971
860
  if (onToggleExpanded) onToggleExpanded();
972
861
  else setExpandedInternal((p) => !p);
973
862
  };
974
- React6.useEffect(() => {
863
+ React7.useEffect(() => {
975
864
  if (refreshTrigger !== void 0) refresh();
976
865
  }, [refreshTrigger, refresh]);
977
- const [expandedKeys, setExpandedKeys] = React6.useState(/* @__PURE__ */ new Set());
978
- const [formVisible, setFormVisible] = React6.useState(false);
979
- const [editingItem, setEditingItem] = React6.useState(null);
980
- const [deleteItem, setDeleteItem] = React6.useState(null);
981
- const [clearAllVisible, setClearAllVisible] = React6.useState(false);
866
+ const [formVisible, setFormVisible] = React7.useState(false);
867
+ const [editingItem, setEditingItem] = React7.useState(null);
868
+ const [deleteItem, setDeleteItem] = React7.useState(null);
869
+ const [clearAllVisible, setClearAllVisible] = React7.useState(false);
982
870
  const handleAdd = () => {
983
871
  setEditingItem(null);
984
872
  setFormVisible(true);
@@ -988,14 +876,7 @@ function StorageSection({
988
876
  setFormVisible(true);
989
877
  };
990
878
  const handleSave = async (key, value) => {
991
- const isNewKey = !editingItem || editingItem.key !== key;
992
879
  await adapter.setItem(key, value);
993
- if (adapter.type === "keychain" && isNewKey) {
994
- onKeychainKeyAdded?.(key);
995
- }
996
- if (adapter.type === "expo-secure-store" && isNewKey) {
997
- onSecureStoreKeyAdded?.(key);
998
- }
999
880
  await refresh();
1000
881
  };
1001
882
  const handleDeleteItem = async () => {
@@ -1023,25 +904,25 @@ function StorageSection({
1023
904
  };
1024
905
  const isKeychain = adapter.type === "keychain";
1025
906
  const isSecureStore = adapter.type === "expo-secure-store";
1026
- const showKeychainHint = isKeychain && items.length === 0 && (keychainKeys?.length ?? 0) === 0;
907
+ const showKeychainHint = isKeychain && items.length === 0;
1027
908
  const showSecureStoreHint = isSecureStore && items.length === 0;
1028
909
  if (!adapter.isAvailable()) return null;
1029
- return /* @__PURE__ */ React6__default.default.createElement(React6__default.default.Fragment, null, /* @__PURE__ */ React6__default.default.createElement(
910
+ return /* @__PURE__ */ React7__default.default.createElement(React7__default.default.Fragment, null, /* @__PURE__ */ React7__default.default.createElement(
1030
911
  reactNative.TouchableOpacity,
1031
912
  {
1032
- style: styles2.sectionHeader,
913
+ style: styles7.sectionHeader,
1033
914
  onPress: handleToggleExpanded,
1034
915
  activeOpacity: 0.7
1035
916
  },
1036
- /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.sectionHeaderLabelWrap }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.sectionHeaderLabel }, adapter.name, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.sectionHeaderCount }, " (", items.length, ")"))),
1037
- /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.storageRowActions }, /* @__PURE__ */ React6__default.default.createElement(IconButton, { name: "plus", onPress: handleAdd }), /* @__PURE__ */ React6__default.default.createElement(
917
+ /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.sectionHeaderLabelWrap }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles7.sectionHeaderLabel }, adapter.name, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles7.sectionHeaderCount }, " (", items.length, ")"))),
918
+ /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.storageRowActions }, /* @__PURE__ */ React7__default.default.createElement(IconButton, { name: "plus", onPress: handleAdd }), /* @__PURE__ */ React7__default.default.createElement(
1038
919
  IconButton,
1039
920
  {
1040
921
  name: "trash",
1041
922
  onPress: () => items.length > 0 && setClearAllVisible(true),
1042
923
  disabled: items.length === 0
1043
924
  }
1044
- ), /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.iconSlot }, /* @__PURE__ */ React6__default.default.createElement(
925
+ ), /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.iconSlot }, /* @__PURE__ */ React7__default.default.createElement(
1045
926
  Icon,
1046
927
  {
1047
928
  name: expanded ? "chevronUp" : "chevronDown",
@@ -1049,54 +930,16 @@ function StorageSection({
1049
930
  tintColor: theme.colors.text
1050
931
  }
1051
932
  )))
1052
- ), expanded && /* @__PURE__ */ React6__default.default.createElement(React6__default.default.Fragment, null, showKeychainHint ? /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.keychainHint }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.keychainHintText }, strings.keychainHint)) : null, showSecureStoreHint ? /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.keychainHint }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.keychainHintText }, strings.secureStoreHint)) : null, error ? /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.error }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.errorText }, error)) : null, loading ? /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.loading }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.loadingText }, strings.loading)) : items.map((item) => {
1053
- const isItemExpanded = expandedKeys.has(item.key);
1054
- const charCount = item.value.length;
1055
- const toggleItemExpanded = () => {
1056
- setExpandedKeys((prev) => {
1057
- const next = new Set(prev);
1058
- if (next.has(item.key)) next.delete(item.key);
1059
- else next.add(item.key);
1060
- return next;
1061
- });
1062
- };
1063
- return /* @__PURE__ */ React6__default.default.createElement(
1064
- reactNative.TouchableOpacity,
1065
- {
1066
- key: item.key,
1067
- style: styles2.itemRow,
1068
- onPress: toggleItemExpanded,
1069
- activeOpacity: 0.7
1070
- },
1071
- /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.itemRowCollapsed }, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: { flex: 1 } }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.itemKey, numberOfLines: 1 }, item.key), /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.itemChars }, strings.charCount(charCount))), !isItemExpanded ? /* @__PURE__ */ React6__default.default.createElement(
1072
- ItemRowActions,
1073
- {
1074
- item,
1075
- onCopy: handleCopy,
1076
- onEdit: handleEdit,
1077
- onDelete: setDeleteItem,
1078
- showChevron: true,
1079
- chevronDirection: "down"
1080
- }
1081
- ) : /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.iconSlot }, /* @__PURE__ */ React6__default.default.createElement(
1082
- Icon,
1083
- {
1084
- name: "chevronUp",
1085
- size: LAYOUT.chevronSize,
1086
- tintColor: theme.colors.text
1087
- }
1088
- ))),
1089
- isItemExpanded && /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.itemRowExpanded }, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.valueBox }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.valueBoxLabel }, strings.valueLabel), /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.valueBoxText, selectable: true }, item.value || strings.emptyValue)), /* @__PURE__ */ React6__default.default.createElement(
1090
- ItemRowActions,
1091
- {
1092
- item,
1093
- onCopy: handleCopy,
1094
- onEdit: handleEdit,
1095
- onDelete: setDeleteItem
1096
- }
1097
- ))
1098
- );
1099
- }), !loading && items.length === 0 && !showKeychainHint && !showSecureStoreHint ? /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.empty }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.emptyText }, strings.noItems)) : null), /* @__PURE__ */ React6__default.default.createElement(
933
+ ), expanded && /* @__PURE__ */ React7__default.default.createElement(React7__default.default.Fragment, null, showKeychainHint ? /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.keychainHint }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles7.keychainHintText }, strings.keychainHint)) : null, showSecureStoreHint ? /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.keychainHint }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles7.keychainHintText }, strings.secureStoreHint)) : null, error ? /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.error }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles7.errorText }, error)) : null, loading ? /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.loading }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles7.loadingText }, strings.loading)) : items.map((item) => /* @__PURE__ */ React7__default.default.createElement(
934
+ StorageList,
935
+ {
936
+ key: item.key,
937
+ item,
938
+ onCopy: handleCopy,
939
+ onEdit: handleEdit,
940
+ onDelete: setDeleteItem
941
+ }
942
+ )), !loading && items.length === 0 && !showKeychainHint && !showSecureStoreHint ? /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles7.empty }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles7.emptyText }, strings.noItems)) : null), /* @__PURE__ */ React7__default.default.createElement(
1100
943
  ItemForm,
1101
944
  {
1102
945
  visible: formVisible,
@@ -1108,7 +951,7 @@ function StorageSection({
1108
951
  setEditingItem(null);
1109
952
  }
1110
953
  }
1111
- ), /* @__PURE__ */ React6__default.default.createElement(
954
+ ), /* @__PURE__ */ React7__default.default.createElement(
1112
955
  ConfirmModal,
1113
956
  {
1114
957
  visible: deleteItem !== null,
@@ -1117,7 +960,7 @@ function StorageSection({
1117
960
  onConfirm: handleDeleteItem,
1118
961
  onCancel: () => setDeleteItem(null)
1119
962
  }
1120
- ), /* @__PURE__ */ React6__default.default.createElement(
963
+ ), /* @__PURE__ */ React7__default.default.createElement(
1121
964
  ConfirmModal,
1122
965
  {
1123
966
  visible: clearAllVisible,
@@ -1128,89 +971,127 @@ function StorageSection({
1128
971
  }
1129
972
  ));
1130
973
  }
974
+ var { colors: colors4 } = theme;
975
+ var styles7 = reactNative.StyleSheet.create({
976
+ sectionHeader: {
977
+ height: LAYOUT.sectionHeaderHeight,
978
+ flexDirection: "row",
979
+ alignItems: "center",
980
+ paddingHorizontal: LAYOUT.padding,
981
+ borderBottomWidth: reactNative.StyleSheet.hairlineWidth,
982
+ borderBottomColor: colors4.border,
983
+ backgroundColor: colors4.backgroundSecondary,
984
+ marginTop: LAYOUT.padding,
985
+ marginHorizontal: LAYOUT.padding,
986
+ borderRadius: LAYOUT.sectionRadius
987
+ },
988
+ sectionHeaderLabelWrap: {
989
+ flex: 1
990
+ },
991
+ sectionHeaderLabel: {
992
+ fontSize: 15,
993
+ fontWeight: "600",
994
+ color: colors4.text
995
+ },
996
+ sectionHeaderCount: {
997
+ color: colors4.textSecondary,
998
+ fontWeight: "400"
999
+ },
1000
+ storageRowActions: {
1001
+ flexDirection: "row",
1002
+ alignItems: "center",
1003
+ gap: LAYOUT.iconGap
1004
+ },
1005
+ iconSlot: {
1006
+ width: LAYOUT.iconButtonSize,
1007
+ height: LAYOUT.iconButtonSize,
1008
+ alignItems: "center",
1009
+ justifyContent: "center"
1010
+ },
1011
+ keychainHint: {
1012
+ padding: LAYOUT.padding,
1013
+ marginHorizontal: LAYOUT.padding,
1014
+ marginTop: 8,
1015
+ marginBottom: 4,
1016
+ backgroundColor: colors4.backgroundSecondary,
1017
+ borderRadius: 8
1018
+ },
1019
+ keychainHintText: {
1020
+ fontSize: LAYOUT.fontSize - 1,
1021
+ color: colors4.textSecondary
1022
+ },
1023
+ error: {
1024
+ padding: LAYOUT.padding,
1025
+ backgroundColor: colors4.backgroundTertiary,
1026
+ marginHorizontal: LAYOUT.padding,
1027
+ marginVertical: 8,
1028
+ borderRadius: 8
1029
+ },
1030
+ errorText: {
1031
+ fontSize: LAYOUT.fontSize,
1032
+ color: colors4.text
1033
+ },
1034
+ loading: {
1035
+ padding: LAYOUT.padding * 2,
1036
+ alignItems: "center",
1037
+ marginHorizontal: LAYOUT.padding
1038
+ },
1039
+ loadingText: {
1040
+ fontSize: LAYOUT.fontSize,
1041
+ color: colors4.textSecondary
1042
+ },
1043
+ empty: {
1044
+ padding: LAYOUT.padding * 2,
1045
+ alignItems: "center",
1046
+ marginHorizontal: LAYOUT.padding
1047
+ },
1048
+ emptyText: {
1049
+ fontSize: LAYOUT.fontSize,
1050
+ color: colors4.textMuted
1051
+ }
1052
+ });
1131
1053
 
1132
1054
  // src/components/StorageInspector.tsx
1133
- function StorageInspector({
1134
- mmkvInstances = [],
1135
- asyncStorageInstance,
1136
- keychainKeys: keychainKeysProp,
1137
- keychainInstance,
1138
- secureStoreKeys: secureStoreKeysProp,
1139
- secureStoreInstance,
1140
- customAdapters = []
1141
- }) {
1142
- const [keychainKeysAdded, setKeychainKeysAdded] = React6.useState([]);
1143
- const [secureStoreKeysAdded, setSecureStoreKeysAdded] = React6.useState([]);
1144
- const [refreshKey, setRefreshKey] = React6.useState(0);
1145
- const [refreshing, setRefreshing] = React6.useState(false);
1146
- const [expandedIndices, setExpandedIndices] = React6.useState(() => /* @__PURE__ */ new Set([0]));
1147
- const keychainKeys = React6.useMemo(
1148
- () => [...keychainKeysProp ?? [], ...keychainKeysAdded],
1149
- [keychainKeysProp, keychainKeysAdded]
1150
- );
1151
- const secureStoreKeys = React6.useMemo(
1152
- () => [...secureStoreKeysProp ?? [], ...secureStoreKeysAdded],
1153
- [secureStoreKeysProp, secureStoreKeysAdded]
1154
- );
1155
- const adapters = React6.useMemo(() => {
1055
+ function StorageInspector(props) {
1056
+ const { mmkvInstances = [], secureStoreKeys, customAdapters = [] } = props;
1057
+ const [refreshKey, setRefreshKey] = React7.useState(0);
1058
+ const [refreshing, setRefreshing] = React7.useState(false);
1059
+ const [expandedIndices, setExpandedIndices] = React7.useState(() => /* @__PURE__ */ new Set([0]));
1060
+ const adapters = React7.useMemo(() => {
1156
1061
  const list = [];
1157
1062
  mmkvInstances.forEach((inst, i) => {
1158
1063
  list.push(
1159
1064
  createMMKVAdapter(inst, mmkvInstances.length > 1 ? `MMKV ${i + 1}` : "MMKV")
1160
1065
  );
1161
1066
  });
1162
- const asyncAdapter = createAsyncStorageAdapter(asyncStorageInstance);
1067
+ const asyncAdapter = createAsyncStorageAdapter();
1163
1068
  if (asyncAdapter.isAvailable()) list.push(asyncAdapter);
1164
- const keychainAdapter = createKeychainAdapter(keychainKeys, keychainInstance);
1069
+ const keychainAdapter = createKeychainAdapter();
1165
1070
  if (keychainAdapter.isAvailable()) list.push(keychainAdapter);
1166
- const secureStoreAdapter = createSecureStoreAdapter(
1167
- secureStoreKeys,
1168
- secureStoreInstance
1169
- );
1071
+ const secureStoreAdapter = createSecureStoreAdapter(secureStoreKeys ?? []);
1170
1072
  if (secureStoreAdapter.isAvailable()) list.push(secureStoreAdapter);
1171
1073
  list.push(...customAdapters);
1172
1074
  return list;
1173
- }, [
1174
- mmkvInstances,
1175
- asyncStorageInstance,
1176
- keychainKeys,
1177
- keychainInstance,
1178
- secureStoreKeys,
1179
- secureStoreInstance,
1180
- customAdapters
1181
- ]);
1182
- const handleKeychainKeyAdded = (key) => {
1183
- setKeychainKeysAdded(
1184
- (prev) => prev.includes(key) ? prev : [...prev, key]
1185
- );
1186
- };
1187
- const handleSecureStoreKeyAdded = (key) => {
1188
- setSecureStoreKeysAdded(
1189
- (prev) => prev.includes(key) ? prev : [...prev, key]
1190
- );
1191
- };
1075
+ }, [mmkvInstances, secureStoreKeys, customAdapters]);
1192
1076
  const handleRefresh = () => {
1193
1077
  setRefreshing(true);
1194
1078
  setRefreshKey((k) => k + 1);
1195
1079
  setTimeout(() => setRefreshing(false), 400);
1196
1080
  };
1197
- return /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.container }, /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.content }, adapters.length > 0 ? /* @__PURE__ */ React6__default.default.createElement(React6__default.default.Fragment, null, /* @__PURE__ */ React6__default.default.createElement(
1081
+ return /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles8.container }, /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles8.content }, adapters.length > 0 ? /* @__PURE__ */ React7__default.default.createElement(React7__default.default.Fragment, null, /* @__PURE__ */ React7__default.default.createElement(
1198
1082
  reactNative.ScrollView,
1199
1083
  {
1200
- style: styles2.scroll,
1201
- contentContainerStyle: styles2.scrollContent,
1084
+ style: styles8.scroll,
1085
+ contentContainerStyle: styles8.scrollContent,
1202
1086
  keyboardShouldPersistTaps: "handled",
1203
1087
  showsVerticalScrollIndicator: true,
1204
- refreshControl: /* @__PURE__ */ React6__default.default.createElement(reactNative.RefreshControl, { refreshing, onRefresh: handleRefresh })
1088
+ refreshControl: /* @__PURE__ */ React7__default.default.createElement(reactNative.RefreshControl, { refreshing, onRefresh: handleRefresh })
1205
1089
  },
1206
- adapters.map((adapter, index) => /* @__PURE__ */ React6__default.default.createElement(
1090
+ adapters.map((adapter, index) => /* @__PURE__ */ React7__default.default.createElement(
1207
1091
  StorageSection,
1208
1092
  {
1209
1093
  key: `${adapter.type}-${index}`,
1210
1094
  adapter,
1211
- keychainKeys: keychainKeysProp,
1212
- onKeychainKeyAdded: handleKeychainKeyAdded,
1213
- onSecureStoreKeyAdded: handleSecureStoreKeyAdded,
1214
1095
  expanded: expandedIndices.has(index),
1215
1096
  onToggleExpanded: () => {
1216
1097
  setExpandedIndices((prev) => {
@@ -1223,18 +1104,57 @@ function StorageInspector({
1223
1104
  refreshTrigger: refreshKey
1224
1105
  }
1225
1106
  ))
1226
- ), /* @__PURE__ */ React6__default.default.createElement(
1107
+ ), /* @__PURE__ */ React7__default.default.createElement(
1227
1108
  IconButton,
1228
1109
  {
1229
1110
  name: "refresh",
1230
1111
  onPress: handleRefresh,
1231
1112
  size: 24,
1232
1113
  tintColor: theme.colors.inverted,
1233
- style: styles2.fab,
1114
+ style: styles8.fab,
1234
1115
  activeOpacity: 0.85
1235
1116
  }
1236
- )) : /* @__PURE__ */ React6__default.default.createElement(reactNative.View, { style: styles2.empty }, /* @__PURE__ */ React6__default.default.createElement(reactNative.Text, { style: styles2.emptyText }, strings.noAdapterAvailable))));
1117
+ )) : /* @__PURE__ */ React7__default.default.createElement(reactNative.View, { style: styles8.empty }, /* @__PURE__ */ React7__default.default.createElement(reactNative.Text, { style: styles8.emptyText }, strings.noAdapterAvailable))));
1237
1118
  }
1119
+ var { colors: colors5 } = theme;
1120
+ var styles8 = reactNative.StyleSheet.create({
1121
+ container: {
1122
+ flex: 1,
1123
+ width: "100%",
1124
+ backgroundColor: colors5.background
1125
+ },
1126
+ content: {
1127
+ flex: 1
1128
+ },
1129
+ scroll: {
1130
+ flex: 1
1131
+ },
1132
+ scrollContent: {
1133
+ flexGrow: 1,
1134
+ paddingBottom: LAYOUT.fabSize + LAYOUT.padding + 20,
1135
+ paddingTop: LAYOUT.padding
1136
+ },
1137
+ fab: {
1138
+ position: "absolute",
1139
+ bottom: LAYOUT.padding + 16,
1140
+ right: LAYOUT.padding + 16,
1141
+ width: LAYOUT.fabSize,
1142
+ height: LAYOUT.fabSize,
1143
+ borderRadius: LAYOUT.fabSize / 2,
1144
+ backgroundColor: colors5.text,
1145
+ alignItems: "center",
1146
+ justifyContent: "center"
1147
+ },
1148
+ empty: {
1149
+ padding: LAYOUT.padding * 2,
1150
+ alignItems: "center",
1151
+ marginHorizontal: LAYOUT.padding
1152
+ },
1153
+ emptyText: {
1154
+ fontSize: LAYOUT.fontSize,
1155
+ color: colors5.textMuted
1156
+ }
1157
+ });
1238
1158
 
1239
1159
  exports.StorageInspector = StorageInspector;
1240
1160
  exports.createAsyncStorageAdapter = createAsyncStorageAdapter;