@terreno/ui 0.0.16 → 0.0.18

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.
Files changed (46) hide show
  1. package/dist/Button.js +7 -9
  2. package/dist/Button.js.map +1 -1
  3. package/dist/Common.d.ts +39 -0
  4. package/dist/TerrenoProvider.js +1 -1
  5. package/dist/TerrenoProvider.js.map +1 -1
  6. package/dist/Toast.js +2 -3
  7. package/dist/Toast.js.map +1 -1
  8. package/dist/ToastNotifications.d.ts +144 -0
  9. package/dist/ToastNotifications.js +387 -0
  10. package/dist/ToastNotifications.js.map +1 -0
  11. package/dist/UserInactivity.d.ts +28 -0
  12. package/dist/UserInactivity.js +100 -0
  13. package/dist/UserInactivity.js.map +1 -0
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.js +1 -0
  16. package/dist/index.js.map +1 -1
  17. package/package.json +1 -2
  18. package/src/Button.tsx +20 -37
  19. package/src/Common.ts +45 -0
  20. package/src/DateTimeActionSheet.test.tsx +53 -4
  21. package/src/MobileAddressAutoComplete.test.tsx +47 -4
  22. package/src/ModalSheet.test.tsx +37 -5
  23. package/src/PickerSelect.test.tsx +41 -5
  24. package/src/Signature.test.tsx +21 -4
  25. package/src/SignatureField.test.tsx +49 -5
  26. package/src/SplitPage.test.tsx +71 -4
  27. package/src/TerrenoProvider.tsx +1 -1
  28. package/src/Toast.tsx +2 -3
  29. package/src/ToastNotifications.test.tsx +645 -0
  30. package/src/ToastNotifications.tsx +746 -0
  31. package/src/UnifiedAddressAutoComplete.test.tsx +43 -5
  32. package/src/UserInactivity.test.tsx +96 -0
  33. package/src/UserInactivity.tsx +129 -0
  34. package/src/WebAddressAutocomplete.test.tsx +22 -4
  35. package/src/__snapshots__/Button.test.tsx.snap +0 -347
  36. package/src/__snapshots__/DateTimeActionSheet.test.tsx.snap +11 -0
  37. package/src/__snapshots__/MobileAddressAutoComplete.test.tsx.snap +230 -0
  38. package/src/__snapshots__/ModalSheet.test.tsx.snap +37 -0
  39. package/src/__snapshots__/PickerSelect.test.tsx.snap +798 -11
  40. package/src/__snapshots__/Signature.test.tsx.snap +67 -0
  41. package/src/__snapshots__/SignatureField.test.tsx.snap +129 -21
  42. package/src/__snapshots__/SplitPage.test.tsx.snap +686 -0
  43. package/src/__snapshots__/UnifiedAddressAutoComplete.test.tsx.snap +377 -0
  44. package/src/__snapshots__/UserInactivity.test.tsx.snap +108 -0
  45. package/src/__snapshots__/WebAddressAutocomplete.test.tsx.snap +238 -0
  46. package/src/index.tsx +1 -0
@@ -0,0 +1,645 @@
1
+ import {beforeAll, describe, expect, it, mock} from "bun:test";
2
+ import {act, render, waitFor} from "@testing-library/react-native";
3
+ import React from "react";
4
+ import {Text} from "react-native";
5
+
6
+ import {
7
+ GlobalToast,
8
+ type ToastContainerRef,
9
+ type ToastOptions,
10
+ type ToastProps,
11
+ ToastProvider,
12
+ type ToastType,
13
+ useToastNotifications,
14
+ } from "./ToastNotifications";
15
+
16
+ // Mock requestAnimationFrame for test environment
17
+ beforeAll(() => {
18
+ global.requestAnimationFrame = (callback: FrameRequestCallback) => {
19
+ return setTimeout(() => callback(Date.now()), 0) as unknown as number;
20
+ };
21
+ global.cancelAnimationFrame = (id: number) => {
22
+ clearTimeout(id);
23
+ };
24
+ });
25
+
26
+ describe("ToastNotifications", () => {
27
+ describe("ToastProvider", () => {
28
+ it("should render children", () => {
29
+ const {getByText} = render(
30
+ <ToastProvider>
31
+ <Text>Test Content</Text>
32
+ </ToastProvider>
33
+ );
34
+ expect(getByText("Test Content")).toBeTruthy();
35
+ });
36
+
37
+ it("should render without crashing", () => {
38
+ const {root} = render(
39
+ <ToastProvider>
40
+ <Text>App</Text>
41
+ </ToastProvider>
42
+ );
43
+ expect(root).toBeTruthy();
44
+ });
45
+
46
+ it("should accept custom props", () => {
47
+ const {root} = render(
48
+ <ToastProvider duration={3000} offset={20} placement="top" swipeEnabled={false}>
49
+ <Text>App</Text>
50
+ </ToastProvider>
51
+ );
52
+ expect(root).toBeTruthy();
53
+ });
54
+ });
55
+
56
+ describe("useToastNotifications hook", () => {
57
+ it("should return toast methods from context", () => {
58
+ let toastRef: ToastType | null = null;
59
+
60
+ const TestComponent = () => {
61
+ const toast = useToastNotifications();
62
+ toastRef = toast;
63
+ return <Text>Test</Text>;
64
+ };
65
+
66
+ render(
67
+ <ToastProvider>
68
+ <TestComponent />
69
+ </ToastProvider>
70
+ );
71
+
72
+ expect(toastRef).toBeTruthy();
73
+ });
74
+
75
+ it("should have show method available after mount", async () => {
76
+ let toastRef: ToastType | null = null;
77
+
78
+ const TestComponent = () => {
79
+ const toast = useToastNotifications();
80
+ toastRef = toast;
81
+ return <Text>Test</Text>;
82
+ };
83
+
84
+ render(
85
+ <ToastProvider>
86
+ <TestComponent />
87
+ </ToastProvider>
88
+ );
89
+
90
+ await waitFor(() => {
91
+ expect(toastRef?.show).toBeDefined();
92
+ });
93
+ });
94
+
95
+ it("should have hide method available after mount", async () => {
96
+ let toastRef: ToastType | null = null;
97
+
98
+ const TestComponent = () => {
99
+ const toast = useToastNotifications();
100
+ toastRef = toast;
101
+ return <Text>Test</Text>;
102
+ };
103
+
104
+ render(
105
+ <ToastProvider>
106
+ <TestComponent />
107
+ </ToastProvider>
108
+ );
109
+
110
+ await waitFor(() => {
111
+ expect(toastRef?.hide).toBeDefined();
112
+ });
113
+ });
114
+
115
+ it("should have hideAll method available after mount", async () => {
116
+ let toastRef: ToastType | null = null;
117
+
118
+ const TestComponent = () => {
119
+ const toast = useToastNotifications();
120
+ toastRef = toast;
121
+ return <Text>Test</Text>;
122
+ };
123
+
124
+ render(
125
+ <ToastProvider>
126
+ <TestComponent />
127
+ </ToastProvider>
128
+ );
129
+
130
+ await waitFor(() => {
131
+ expect(toastRef?.hideAll).toBeDefined();
132
+ });
133
+ });
134
+
135
+ it("should have update method available after mount", async () => {
136
+ let toastRef: ToastType | null = null;
137
+
138
+ const TestComponent = () => {
139
+ const toast = useToastNotifications();
140
+ toastRef = toast;
141
+ return <Text>Test</Text>;
142
+ };
143
+
144
+ render(
145
+ <ToastProvider>
146
+ <TestComponent />
147
+ </ToastProvider>
148
+ );
149
+
150
+ await waitFor(() => {
151
+ expect(toastRef?.update).toBeDefined();
152
+ });
153
+ });
154
+
155
+ it("should have isOpen method available after mount", async () => {
156
+ let toastRef: ToastType | null = null;
157
+
158
+ const TestComponent = () => {
159
+ const toast = useToastNotifications();
160
+ toastRef = toast;
161
+ return <Text>Test</Text>;
162
+ };
163
+
164
+ render(
165
+ <ToastProvider>
166
+ <TestComponent />
167
+ </ToastProvider>
168
+ );
169
+
170
+ await waitFor(() => {
171
+ expect(toastRef?.isOpen).toBeDefined();
172
+ });
173
+ });
174
+ });
175
+
176
+ describe("GlobalToast", () => {
177
+ it("should be set after ToastProvider mounts", async () => {
178
+ render(
179
+ <ToastProvider>
180
+ <Text>App</Text>
181
+ </ToastProvider>
182
+ );
183
+
184
+ await waitFor(() => {
185
+ expect(GlobalToast).toBeDefined();
186
+ });
187
+ });
188
+ });
189
+
190
+ describe("Toast functionality", () => {
191
+ it("should show a toast and return an id", async () => {
192
+ let toastRef: ToastType | null = null;
193
+
194
+ const TestComponent = () => {
195
+ const toast = useToastNotifications();
196
+ toastRef = toast;
197
+ return <Text>Test</Text>;
198
+ };
199
+
200
+ render(
201
+ <ToastProvider swipeEnabled={false}>
202
+ <TestComponent />
203
+ </ToastProvider>
204
+ );
205
+
206
+ await waitFor(() => {
207
+ expect(toastRef?.show).toBeDefined();
208
+ });
209
+
210
+ let toastId: string | undefined;
211
+ await act(async () => {
212
+ toastId = toastRef?.show("Test message");
213
+ });
214
+
215
+ expect(toastId).toBeDefined();
216
+ expect(typeof toastId).toBe("string");
217
+ });
218
+
219
+ it("should show a toast with custom id", async () => {
220
+ let toastRef: ToastType | null = null;
221
+
222
+ const TestComponent = () => {
223
+ const toast = useToastNotifications();
224
+ toastRef = toast;
225
+ return <Text>Test</Text>;
226
+ };
227
+
228
+ render(
229
+ <ToastProvider swipeEnabled={false}>
230
+ <TestComponent />
231
+ </ToastProvider>
232
+ );
233
+
234
+ await waitFor(() => {
235
+ expect(toastRef?.show).toBeDefined();
236
+ });
237
+
238
+ let toastId: string | undefined;
239
+ await act(async () => {
240
+ toastId = toastRef?.show("Test message", {id: "custom-id"});
241
+ });
242
+
243
+ expect(toastId).toBe("custom-id");
244
+ });
245
+
246
+ it("should have isOpen method that returns false for non-existent toast", async () => {
247
+ let toastRef: ToastType | null = null;
248
+
249
+ const TestComponent = () => {
250
+ const toast = useToastNotifications();
251
+ toastRef = toast;
252
+ return <Text>Test</Text>;
253
+ };
254
+
255
+ render(
256
+ <ToastProvider swipeEnabled={false}>
257
+ <TestComponent />
258
+ </ToastProvider>
259
+ );
260
+
261
+ await waitFor(() => {
262
+ expect(toastRef?.isOpen).toBeDefined();
263
+ });
264
+
265
+ expect(toastRef?.isOpen("non-existent")).toBe(false);
266
+ });
267
+
268
+ it("should have hide method available", async () => {
269
+ let toastRef: ToastType | null = null;
270
+
271
+ const TestComponent = () => {
272
+ const toast = useToastNotifications();
273
+ toastRef = toast;
274
+ return <Text>Test</Text>;
275
+ };
276
+
277
+ render(
278
+ <ToastProvider swipeEnabled={false}>
279
+ <TestComponent />
280
+ </ToastProvider>
281
+ );
282
+
283
+ await waitFor(() => {
284
+ expect(toastRef?.hide).toBeDefined();
285
+ });
286
+
287
+ expect(typeof toastRef?.hide).toBe("function");
288
+ });
289
+
290
+ it("should have hideAll method available", async () => {
291
+ let toastRef: ToastType | null = null;
292
+
293
+ const TestComponent = () => {
294
+ const toast = useToastNotifications();
295
+ toastRef = toast;
296
+ return <Text>Test</Text>;
297
+ };
298
+
299
+ render(
300
+ <ToastProvider swipeEnabled={false}>
301
+ <TestComponent />
302
+ </ToastProvider>
303
+ );
304
+
305
+ await waitFor(() => {
306
+ expect(toastRef?.hideAll).toBeDefined();
307
+ });
308
+
309
+ expect(typeof toastRef?.hideAll).toBe("function");
310
+ });
311
+
312
+ it("should have update method available", async () => {
313
+ let toastRef: ToastType | null = null;
314
+
315
+ const TestComponent = () => {
316
+ const toast = useToastNotifications();
317
+ toastRef = toast;
318
+ return <Text>Test</Text>;
319
+ };
320
+
321
+ render(
322
+ <ToastProvider swipeEnabled={false}>
323
+ <TestComponent />
324
+ </ToastProvider>
325
+ );
326
+
327
+ await waitFor(() => {
328
+ expect(toastRef?.update).toBeDefined();
329
+ });
330
+
331
+ expect(typeof toastRef?.update).toBe("function");
332
+ });
333
+ });
334
+
335
+ describe("Toast types", () => {
336
+ it("should show success toast", async () => {
337
+ let toastRef: ToastType | null = null;
338
+
339
+ const TestComponent = () => {
340
+ const toast = useToastNotifications();
341
+ toastRef = toast;
342
+ return <Text>Test</Text>;
343
+ };
344
+
345
+ render(
346
+ <ToastProvider swipeEnabled={false}>
347
+ <TestComponent />
348
+ </ToastProvider>
349
+ );
350
+
351
+ await waitFor(() => {
352
+ expect(toastRef?.show).toBeDefined();
353
+ });
354
+
355
+ let toastId: string | undefined;
356
+ await act(async () => {
357
+ toastId = toastRef?.show("Success!", {type: "success"});
358
+ });
359
+
360
+ expect(toastId).toBeDefined();
361
+ });
362
+
363
+ it("should show danger toast", async () => {
364
+ let toastRef: ToastType | null = null;
365
+
366
+ const TestComponent = () => {
367
+ const toast = useToastNotifications();
368
+ toastRef = toast;
369
+ return <Text>Test</Text>;
370
+ };
371
+
372
+ render(
373
+ <ToastProvider swipeEnabled={false}>
374
+ <TestComponent />
375
+ </ToastProvider>
376
+ );
377
+
378
+ await waitFor(() => {
379
+ expect(toastRef?.show).toBeDefined();
380
+ });
381
+
382
+ let toastId: string | undefined;
383
+ await act(async () => {
384
+ toastId = toastRef?.show("Error!", {type: "danger"});
385
+ });
386
+
387
+ expect(toastId).toBeDefined();
388
+ });
389
+
390
+ it("should show warning toast", async () => {
391
+ let toastRef: ToastType | null = null;
392
+
393
+ const TestComponent = () => {
394
+ const toast = useToastNotifications();
395
+ toastRef = toast;
396
+ return <Text>Test</Text>;
397
+ };
398
+
399
+ render(
400
+ <ToastProvider swipeEnabled={false}>
401
+ <TestComponent />
402
+ </ToastProvider>
403
+ );
404
+
405
+ await waitFor(() => {
406
+ expect(toastRef?.show).toBeDefined();
407
+ });
408
+
409
+ let toastId: string | undefined;
410
+ await act(async () => {
411
+ toastId = toastRef?.show("Warning!", {type: "warning"});
412
+ });
413
+
414
+ expect(toastId).toBeDefined();
415
+ });
416
+ });
417
+
418
+ describe("Toast placement", () => {
419
+ it("should accept top placement", () => {
420
+ const {root} = render(
421
+ <ToastProvider placement="top">
422
+ <Text>App</Text>
423
+ </ToastProvider>
424
+ );
425
+ expect(root).toBeTruthy();
426
+ });
427
+
428
+ it("should accept bottom placement", () => {
429
+ const {root} = render(
430
+ <ToastProvider placement="bottom">
431
+ <Text>App</Text>
432
+ </ToastProvider>
433
+ );
434
+ expect(root).toBeTruthy();
435
+ });
436
+
437
+ it("should accept center placement", () => {
438
+ const {root} = render(
439
+ <ToastProvider placement="center">
440
+ <Text>App</Text>
441
+ </ToastProvider>
442
+ );
443
+ expect(root).toBeTruthy();
444
+ });
445
+ });
446
+
447
+ describe("Toast options", () => {
448
+ it("should accept custom duration", async () => {
449
+ let toastRef: ToastType | null = null;
450
+
451
+ const TestComponent = () => {
452
+ const toast = useToastNotifications();
453
+ toastRef = toast;
454
+ return <Text>Test</Text>;
455
+ };
456
+
457
+ render(
458
+ <ToastProvider swipeEnabled={false}>
459
+ <TestComponent />
460
+ </ToastProvider>
461
+ );
462
+
463
+ await waitFor(() => {
464
+ expect(toastRef?.show).toBeDefined();
465
+ });
466
+
467
+ let toastId: string | undefined;
468
+ await act(async () => {
469
+ toastId = toastRef?.show("Test", {duration: 1000});
470
+ });
471
+
472
+ expect(toastId).toBeDefined();
473
+ });
474
+
475
+ it("should accept duration of 0 for persistent toast", async () => {
476
+ let toastRef: ToastType | null = null;
477
+
478
+ const TestComponent = () => {
479
+ const toast = useToastNotifications();
480
+ toastRef = toast;
481
+ return <Text>Test</Text>;
482
+ };
483
+
484
+ render(
485
+ <ToastProvider swipeEnabled={false}>
486
+ <TestComponent />
487
+ </ToastProvider>
488
+ );
489
+
490
+ await waitFor(() => {
491
+ expect(toastRef?.show).toBeDefined();
492
+ });
493
+
494
+ let toastId: string | undefined;
495
+ await act(async () => {
496
+ toastId = toastRef?.show("Persistent toast", {duration: 0});
497
+ });
498
+
499
+ expect(toastId).toBeDefined();
500
+ });
501
+
502
+ it("should call onClose callback when toast is hidden", async () => {
503
+ let toastRef: ToastType | null = null;
504
+ const onCloseMock = mock(() => {});
505
+
506
+ const TestComponent = () => {
507
+ const toast = useToastNotifications();
508
+ toastRef = toast;
509
+ return <Text>Test</Text>;
510
+ };
511
+
512
+ render(
513
+ <ToastProvider swipeEnabled={false}>
514
+ <TestComponent />
515
+ </ToastProvider>
516
+ );
517
+
518
+ await waitFor(() => {
519
+ expect(toastRef?.show).toBeDefined();
520
+ });
521
+
522
+ await act(async () => {
523
+ toastRef?.show("Test", {id: "callback-toast", onClose: onCloseMock});
524
+ });
525
+
526
+ await act(async () => {
527
+ toastRef?.hide("callback-toast");
528
+ });
529
+ });
530
+
531
+ it("should accept custom animation duration", async () => {
532
+ let toastRef: ToastType | null = null;
533
+
534
+ const TestComponent = () => {
535
+ const toast = useToastNotifications();
536
+ toastRef = toast;
537
+ return <Text>Test</Text>;
538
+ };
539
+
540
+ render(
541
+ <ToastProvider animationDuration={500} swipeEnabled={false}>
542
+ <TestComponent />
543
+ </ToastProvider>
544
+ );
545
+
546
+ await waitFor(() => {
547
+ expect(toastRef?.show).toBeDefined();
548
+ });
549
+
550
+ let toastId: string | undefined;
551
+ await act(async () => {
552
+ toastId = toastRef?.show("Test");
553
+ });
554
+
555
+ expect(toastId).toBeDefined();
556
+ });
557
+
558
+ it("should accept zoom-in animation type", () => {
559
+ const {root} = render(
560
+ <ToastProvider animationType="zoom-in">
561
+ <Text>App</Text>
562
+ </ToastProvider>
563
+ );
564
+ expect(root).toBeTruthy();
565
+ });
566
+
567
+ it("should accept slide-in animation type", () => {
568
+ const {root} = render(
569
+ <ToastProvider animationType="slide-in">
570
+ <Text>App</Text>
571
+ </ToastProvider>
572
+ );
573
+ expect(root).toBeTruthy();
574
+ });
575
+ });
576
+
577
+ describe("Toast with React elements", () => {
578
+ it("should accept React element as message", async () => {
579
+ let toastRef: ToastType | null = null;
580
+
581
+ const TestComponent = () => {
582
+ const toast = useToastNotifications();
583
+ toastRef = toast;
584
+ return <Text>Test</Text>;
585
+ };
586
+
587
+ render(
588
+ <ToastProvider swipeEnabled={false}>
589
+ <TestComponent />
590
+ </ToastProvider>
591
+ );
592
+
593
+ await waitFor(() => {
594
+ expect(toastRef?.show).toBeDefined();
595
+ });
596
+
597
+ let toastId: string | undefined;
598
+ await act(async () => {
599
+ toastId = toastRef?.show(<Text>Custom Element</Text>);
600
+ });
601
+
602
+ expect(toastId).toBeDefined();
603
+ });
604
+ });
605
+
606
+ describe("Type exports", () => {
607
+ it("should export ToastOptions type", () => {
608
+ const options: ToastOptions = {
609
+ duration: 3000,
610
+ id: "test",
611
+ placement: "top",
612
+ type: "success",
613
+ };
614
+ expect(options).toBeDefined();
615
+ });
616
+
617
+ it("should export ToastProps type", () => {
618
+ const props: Partial<ToastProps> = {
619
+ id: "test",
620
+ message: "Test message",
621
+ open: true,
622
+ };
623
+ expect(props).toBeDefined();
624
+ });
625
+
626
+ it("should export ToastContainerRef type", () => {
627
+ const ref: Partial<ToastContainerRef> = {
628
+ hide: () => {},
629
+ hideAll: () => {},
630
+ isOpen: () => false,
631
+ show: () => "id",
632
+ update: () => {},
633
+ };
634
+ expect(ref).toBeDefined();
635
+ });
636
+
637
+ it("should export ToastType type", () => {
638
+ const toastType: Partial<ToastType> = {
639
+ hide: () => {},
640
+ show: () => "id",
641
+ };
642
+ expect(toastType).toBeDefined();
643
+ });
644
+ });
645
+ });