@terreno/ui 0.14.0 → 0.14.2
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/ActionSheet.d.ts +1 -1
- package/dist/ActionSheet.js +17 -29
- package/dist/ActionSheet.js.map +1 -1
- package/dist/Common.d.ts +8 -2
- package/dist/Common.js +4 -4
- package/dist/Common.js.map +1 -1
- package/dist/ConsentFormScreen.js +3 -3
- package/dist/ConsentFormScreen.js.map +1 -1
- package/dist/DateUtilities.d.ts +25 -25
- package/dist/DateUtilities.js +31 -32
- package/dist/DateUtilities.js.map +1 -1
- package/dist/MarkdownView.js +20 -7
- package/dist/MarkdownView.js.map +1 -1
- package/dist/MediaQuery.d.ts +4 -4
- package/dist/MediaQuery.js +8 -8
- package/dist/MediaQuery.js.map +1 -1
- package/dist/Page.d.ts +1 -0
- package/dist/Page.js +6 -2
- package/dist/Page.js.map +1 -1
- package/dist/PickerSelect.d.ts +1 -1
- package/dist/PickerSelect.js +2 -2
- package/dist/PickerSelect.js.map +1 -1
- package/dist/TapToEdit.d.ts +1 -1
- package/dist/TapToEdit.js +2 -3
- package/dist/TapToEdit.js.map +1 -1
- package/dist/ToastNotifications.js +2 -2
- package/dist/ToastNotifications.js.map +1 -1
- package/dist/Tooltip.d.ts +24 -1
- package/dist/Tooltip.js +2 -2
- package/dist/Tooltip.js.map +1 -1
- package/dist/Unifier.d.ts +1 -1
- package/dist/Unifier.js +14 -11
- package/dist/Unifier.js.map +1 -1
- package/dist/Utilities.d.ts +8 -8
- package/dist/Utilities.js +12 -14
- package/dist/Utilities.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/signUp/PasswordRequirements.js +3 -3
- package/dist/signUp/PasswordRequirements.js.map +1 -1
- package/dist/table/TableHeaderCell.js +1 -9
- package/dist/table/TableHeaderCell.js.map +1 -1
- package/dist/table/tableContext.d.ts +1 -1
- package/dist/table/tableContext.js +2 -2
- package/dist/table/tableContext.js.map +1 -1
- package/dist/useConsentHistory.d.ts +6 -1
- package/dist/useConsentHistory.js +2 -1
- package/dist/useConsentHistory.js.map +1 -1
- package/package.json +1 -1
- package/src/ActionSheet.test.tsx +554 -0
- package/src/ActionSheet.tsx +26 -39
- package/src/Banner.test.tsx +107 -1
- package/src/Common.ts +10 -4
- package/src/ConsentFormScreen.test.tsx +22 -0
- package/src/ConsentFormScreen.tsx +9 -3
- package/src/DataTable.test.tsx +393 -1
- package/src/DateTimeField.test.tsx +716 -2
- package/src/DateUtilities.tsx +37 -38
- package/src/HeightActionSheet.test.tsx +17 -1
- package/src/HeightField.test.tsx +141 -1
- package/src/HeightFieldDesktop.test.tsx +19 -0
- package/src/MarkdownView.test.tsx +28 -0
- package/src/MarkdownView.tsx +69 -7
- package/src/MediaQuery.ts +8 -8
- package/src/MobileAddressAutoComplete.test.tsx +26 -3
- package/src/Page.test.tsx +28 -0
- package/src/Page.tsx +17 -2
- package/src/PickerSelect.test.tsx +243 -0
- package/src/PickerSelect.tsx +3 -3
- package/src/SplitPage.test.tsx +299 -43
- package/src/TapToEdit.test.tsx +44 -0
- package/src/TapToEdit.tsx +2 -3
- package/src/ToastNotifications.test.tsx +1412 -0
- package/src/ToastNotifications.tsx +2 -2
- package/src/Tooltip.test.tsx +1294 -3
- package/src/Tooltip.tsx +2 -2
- package/src/Unifier.ts +14 -11
- package/src/Utilities.tsx +14 -16
- package/src/WebAddressAutocomplete.test.tsx +237 -0
- package/src/WebDropdownMenu.test.tsx +51 -2
- package/src/__snapshots__/Banner.test.tsx.snap +125 -0
- package/src/__snapshots__/DataTable.test.tsx.snap +366 -0
- package/src/__snapshots__/MarkdownView.test.tsx.snap +284 -74
- package/src/__snapshots__/SplitPage.test.tsx.snap +698 -46
- package/src/bunSetup.ts +0 -4
- package/src/index.tsx +1 -1
- package/src/login/LoginScreen.test.tsx +35 -1
- package/src/signUp/PasswordRequirements.tsx +9 -6
- package/src/signUp/__snapshots__/PasswordRequirements.test.tsx.snap +50 -2
- package/src/signUp/__snapshots__/SignUpScreen.test.tsx.snap +25 -1
- package/src/table/TableHeaderCell.tsx +8 -11
- package/src/table/TableRow.test.tsx +31 -1
- package/src/table/__snapshots__/TableHeaderCell.test.tsx.snap +2 -0
- package/src/table/tableContext.tsx +2 -2
- package/src/useConsentHistory.test.ts +20 -13
- package/src/useConsentHistory.ts +7 -2
- package/src/useStoredState.test.tsx +47 -0
package/src/Page.test.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import {afterAll, describe, expect, it, mock} from "bun:test";
|
|
|
2
2
|
import {act, fireEvent, waitFor} from "@testing-library/react-native";
|
|
3
3
|
import React, {type ReactNode} from "react";
|
|
4
4
|
import {Pressable, Text as RNText} from "react-native";
|
|
5
|
+
import {SafeAreaView} from "react-native-safe-area-context";
|
|
5
6
|
|
|
6
7
|
// Override the IconButton mock so the inline onClick arrows fire when pressed.
|
|
7
8
|
mock.module("./IconButton", () => ({
|
|
@@ -273,6 +274,33 @@ describe("Page", () => {
|
|
|
273
274
|
expect(routerBack).toHaveBeenCalled();
|
|
274
275
|
});
|
|
275
276
|
|
|
277
|
+
it("wraps content in SafeAreaView when safeArea is true", () => {
|
|
278
|
+
const {UNSAFE_root} = renderWithTheme(
|
|
279
|
+
<Page navigation={mockNavigation} safeArea>
|
|
280
|
+
<Text>Content</Text>
|
|
281
|
+
</Page>
|
|
282
|
+
);
|
|
283
|
+
expect(UNSAFE_root.findAllByType(SafeAreaView).length).toBeGreaterThan(0);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it("does not wrap content in SafeAreaView when safeArea is omitted", () => {
|
|
287
|
+
const {UNSAFE_root} = renderWithTheme(
|
|
288
|
+
<Page navigation={mockNavigation}>
|
|
289
|
+
<Text>Content</Text>
|
|
290
|
+
</Page>
|
|
291
|
+
);
|
|
292
|
+
expect(UNSAFE_root.findAllByType(SafeAreaView)).toHaveLength(0);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("does not wrap content in SafeAreaView when safeArea is false", () => {
|
|
296
|
+
const {UNSAFE_root} = renderWithTheme(
|
|
297
|
+
<Page navigation={mockNavigation} safeArea={false}>
|
|
298
|
+
<Text>Content</Text>
|
|
299
|
+
</Page>
|
|
300
|
+
);
|
|
301
|
+
expect(UNSAFE_root.findAllByType(SafeAreaView)).toHaveLength(0);
|
|
302
|
+
});
|
|
303
|
+
|
|
276
304
|
it("safely handles a missing rightButtonOnClick callback", async () => {
|
|
277
305
|
const {getByText} = renderWithTheme(
|
|
278
306
|
<Page navigation={mockNavigation} rightButton="Go" title="Page">
|
package/src/Page.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {router} from "expo-router";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import {SafeAreaView} from "react-native-safe-area-context";
|
|
3
4
|
|
|
4
5
|
import {Box} from "./Box";
|
|
5
6
|
import {Button} from "./Button";
|
|
@@ -58,9 +59,9 @@ export class Page extends React.Component<PageProps, {}> {
|
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
renderBody() {
|
|
62
63
|
return (
|
|
63
|
-
|
|
64
|
+
<>
|
|
64
65
|
<Box
|
|
65
66
|
alignSelf="center"
|
|
66
67
|
avoidKeyboard
|
|
@@ -112,6 +113,20 @@ export class Page extends React.Component<PageProps, {}> {
|
|
|
112
113
|
{this.props.footer}
|
|
113
114
|
</Box>
|
|
114
115
|
)}
|
|
116
|
+
</>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
render() {
|
|
121
|
+
return (
|
|
122
|
+
<ErrorBoundary onError={this.props.onError}>
|
|
123
|
+
{this.props.safeArea ? (
|
|
124
|
+
<SafeAreaView edges={["top", "bottom"]} style={{flex: 1}}>
|
|
125
|
+
{this.renderBody()}
|
|
126
|
+
</SafeAreaView>
|
|
127
|
+
) : (
|
|
128
|
+
this.renderBody()
|
|
129
|
+
)}
|
|
115
130
|
</ErrorBoundary>
|
|
116
131
|
);
|
|
117
132
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// biome-ignore-all lint/suspicious/noExplicitAny: test mock typing
|
|
1
2
|
import {describe, expect, it, mock} from "bun:test";
|
|
2
3
|
import {act, fireEvent} from "@testing-library/react-native";
|
|
3
4
|
|
|
@@ -160,6 +161,248 @@ describe("PickerSelect", () => {
|
|
|
160
161
|
expect(toJSON()).toBeTruthy();
|
|
161
162
|
});
|
|
162
163
|
|
|
164
|
+
describe("web rendering (Platform.OS === 'web')", () => {
|
|
165
|
+
const PlatformModule = require("react-native").Platform;
|
|
166
|
+
let savedOS: any;
|
|
167
|
+
|
|
168
|
+
let hadDocument = false;
|
|
169
|
+
let savedDocument: any;
|
|
170
|
+
|
|
171
|
+
const ensureDocument = () => {
|
|
172
|
+
hadDocument = "document" in globalThis;
|
|
173
|
+
savedDocument = (globalThis as any).document;
|
|
174
|
+
if (typeof (globalThis as any).HTMLElement === "undefined") {
|
|
175
|
+
(globalThis as any).HTMLElement = class HTMLElement {};
|
|
176
|
+
}
|
|
177
|
+
const el = new (globalThis as any).HTMLElement();
|
|
178
|
+
el.blur = () => {};
|
|
179
|
+
(globalThis as any).document = {activeElement: el};
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const restoreDocument = () => {
|
|
183
|
+
if (hadDocument) {
|
|
184
|
+
(globalThis as any).document = savedDocument;
|
|
185
|
+
} else {
|
|
186
|
+
delete (globalThis as any).document;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
it("renders web dropdown with display label", () => {
|
|
191
|
+
ensureDocument();
|
|
192
|
+
savedOS = PlatformModule.OS;
|
|
193
|
+
try {
|
|
194
|
+
PlatformModule.OS = "web";
|
|
195
|
+
const {getByTestId} = renderWithTheme(<RNPickerSelect {...defaultProps} value="2" />);
|
|
196
|
+
expect(getByTestId("text_input")).toBeTruthy();
|
|
197
|
+
} finally {
|
|
198
|
+
PlatformModule.OS = savedOS;
|
|
199
|
+
restoreDocument();
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("renders web dropdown and opens on press", async () => {
|
|
204
|
+
ensureDocument();
|
|
205
|
+
savedOS = PlatformModule.OS;
|
|
206
|
+
try {
|
|
207
|
+
PlatformModule.OS = "web";
|
|
208
|
+
const onOpen = mock(() => {});
|
|
209
|
+
const {getByTestId} = renderWithTheme(
|
|
210
|
+
<RNPickerSelect {...defaultProps} onOpen={onOpen} value="1" />
|
|
211
|
+
);
|
|
212
|
+
await act(async () => {
|
|
213
|
+
fireEvent.press(getByTestId("web_picker"));
|
|
214
|
+
});
|
|
215
|
+
expect(onOpen).toHaveBeenCalled();
|
|
216
|
+
} finally {
|
|
217
|
+
PlatformModule.OS = savedOS;
|
|
218
|
+
restoreDocument();
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it("does not open web menu when disabled", async () => {
|
|
223
|
+
ensureDocument();
|
|
224
|
+
savedOS = PlatformModule.OS;
|
|
225
|
+
try {
|
|
226
|
+
PlatformModule.OS = "web";
|
|
227
|
+
const onOpen = mock(() => {});
|
|
228
|
+
const {getByTestId} = renderWithTheme(
|
|
229
|
+
<RNPickerSelect {...defaultProps} disabled onOpen={onOpen} />
|
|
230
|
+
);
|
|
231
|
+
await act(async () => {
|
|
232
|
+
fireEvent.press(getByTestId("web_picker"));
|
|
233
|
+
});
|
|
234
|
+
expect(onOpen).not.toHaveBeenCalled();
|
|
235
|
+
} finally {
|
|
236
|
+
PlatformModule.OS = savedOS;
|
|
237
|
+
restoreDocument();
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it("calls onClose when closing web menu", async () => {
|
|
242
|
+
ensureDocument();
|
|
243
|
+
savedOS = PlatformModule.OS;
|
|
244
|
+
try {
|
|
245
|
+
PlatformModule.OS = "web";
|
|
246
|
+
const onClose = mock(() => {});
|
|
247
|
+
const onOpen = mock(() => {});
|
|
248
|
+
const {getByTestId} = renderWithTheme(
|
|
249
|
+
<RNPickerSelect {...defaultProps} onClose={onClose} onOpen={onOpen} value="1" />
|
|
250
|
+
);
|
|
251
|
+
await act(async () => {
|
|
252
|
+
fireEvent.press(getByTestId("web_picker"));
|
|
253
|
+
});
|
|
254
|
+
expect(onOpen).toHaveBeenCalled();
|
|
255
|
+
await act(async () => {
|
|
256
|
+
fireEvent.press(getByTestId("web_dropdown_backdrop"));
|
|
257
|
+
});
|
|
258
|
+
expect(onClose).toHaveBeenCalled();
|
|
259
|
+
} finally {
|
|
260
|
+
PlatformModule.OS = savedOS;
|
|
261
|
+
restoreDocument();
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it("renders disabled web dropdown with correct styling", () => {
|
|
266
|
+
ensureDocument();
|
|
267
|
+
savedOS = PlatformModule.OS;
|
|
268
|
+
try {
|
|
269
|
+
PlatformModule.OS = "web";
|
|
270
|
+
const {getByTestId} = renderWithTheme(<RNPickerSelect {...defaultProps} disabled />);
|
|
271
|
+
expect(getByTestId("web_picker")).toBeTruthy();
|
|
272
|
+
} finally {
|
|
273
|
+
PlatformModule.OS = savedOS;
|
|
274
|
+
restoreDocument();
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("renders web dropdown with inputLabel when available", () => {
|
|
279
|
+
ensureDocument();
|
|
280
|
+
savedOS = PlatformModule.OS;
|
|
281
|
+
try {
|
|
282
|
+
PlatformModule.OS = "web";
|
|
283
|
+
const items = [
|
|
284
|
+
{inputLabel: "Opt 1 short", label: "Option 1 long", value: "1"},
|
|
285
|
+
{label: "Option 2", value: "2"},
|
|
286
|
+
];
|
|
287
|
+
const {getByTestId} = renderWithTheme(
|
|
288
|
+
<RNPickerSelect {...defaultProps} items={items} value="1" />
|
|
289
|
+
);
|
|
290
|
+
expect(getByTestId("text_input")).toBeTruthy();
|
|
291
|
+
} finally {
|
|
292
|
+
PlatformModule.OS = savedOS;
|
|
293
|
+
restoreDocument();
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("renders web dropdown with no placeholder (empty object)", () => {
|
|
298
|
+
ensureDocument();
|
|
299
|
+
savedOS = PlatformModule.OS;
|
|
300
|
+
try {
|
|
301
|
+
PlatformModule.OS = "web";
|
|
302
|
+
const {getByTestId} = renderWithTheme(
|
|
303
|
+
<RNPickerSelect {...defaultProps} placeholder={{}} value="1" />
|
|
304
|
+
);
|
|
305
|
+
expect(getByTestId("web_picker")).toBeTruthy();
|
|
306
|
+
} finally {
|
|
307
|
+
PlatformModule.OS = savedOS;
|
|
308
|
+
restoreDocument();
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
describe("android rendering", () => {
|
|
314
|
+
const PlatformModule = require("react-native").Platform;
|
|
315
|
+
let savedOS: any;
|
|
316
|
+
|
|
317
|
+
it("renders android headless when useNativeAndroidPickerStyle is false", () => {
|
|
318
|
+
savedOS = PlatformModule.OS;
|
|
319
|
+
try {
|
|
320
|
+
PlatformModule.OS = "android";
|
|
321
|
+
const {getByTestId} = renderWithTheme(
|
|
322
|
+
<RNPickerSelect {...defaultProps} useNativeAndroidPickerStyle={false} value="1" />
|
|
323
|
+
);
|
|
324
|
+
expect(getByTestId("android_touchable_wrapper")).toBeTruthy();
|
|
325
|
+
} finally {
|
|
326
|
+
PlatformModule.OS = savedOS;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("renders android headless with fixAndroidTouchableBug", () => {
|
|
331
|
+
savedOS = PlatformModule.OS;
|
|
332
|
+
try {
|
|
333
|
+
PlatformModule.OS = "android";
|
|
334
|
+
const {getByTestId} = renderWithTheme(
|
|
335
|
+
<RNPickerSelect
|
|
336
|
+
{...defaultProps}
|
|
337
|
+
fixAndroidTouchableBug
|
|
338
|
+
useNativeAndroidPickerStyle={false}
|
|
339
|
+
value="1"
|
|
340
|
+
/>
|
|
341
|
+
);
|
|
342
|
+
expect(getByTestId("android_touchable_wrapper")).toBeTruthy();
|
|
343
|
+
} finally {
|
|
344
|
+
PlatformModule.OS = savedOS;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("renders android headless with children", () => {
|
|
349
|
+
savedOS = PlatformModule.OS;
|
|
350
|
+
try {
|
|
351
|
+
PlatformModule.OS = "android";
|
|
352
|
+
const {getByTestId} = renderWithTheme(
|
|
353
|
+
<RNPickerSelect {...defaultProps} value="1">
|
|
354
|
+
<>Custom child</>
|
|
355
|
+
</RNPickerSelect>
|
|
356
|
+
);
|
|
357
|
+
expect(getByTestId("android_touchable_wrapper")).toBeTruthy();
|
|
358
|
+
} finally {
|
|
359
|
+
PlatformModule.OS = savedOS;
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("renders native android picker style", () => {
|
|
364
|
+
savedOS = PlatformModule.OS;
|
|
365
|
+
try {
|
|
366
|
+
PlatformModule.OS = "android";
|
|
367
|
+
const {getByTestId} = renderWithTheme(<RNPickerSelect {...defaultProps} value="1" />);
|
|
368
|
+
expect(getByTestId("android_picker")).toBeTruthy();
|
|
369
|
+
} finally {
|
|
370
|
+
PlatformModule.OS = savedOS;
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it("renders native android picker disabled", () => {
|
|
375
|
+
savedOS = PlatformModule.OS;
|
|
376
|
+
try {
|
|
377
|
+
PlatformModule.OS = "android";
|
|
378
|
+
const {getByTestId} = renderWithTheme(
|
|
379
|
+
<RNPickerSelect {...defaultProps} disabled value="1" />
|
|
380
|
+
);
|
|
381
|
+
expect(getByTestId("android_picker")).toBeTruthy();
|
|
382
|
+
} finally {
|
|
383
|
+
PlatformModule.OS = savedOS;
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it("calls onValueChange on android native picker change", async () => {
|
|
388
|
+
savedOS = PlatformModule.OS;
|
|
389
|
+
try {
|
|
390
|
+
PlatformModule.OS = "android";
|
|
391
|
+
const mockOnValueChange = mock(() => {});
|
|
392
|
+
const {getByTestId} = renderWithTheme(
|
|
393
|
+
<RNPickerSelect {...defaultProps} onValueChange={mockOnValueChange} value="1" />
|
|
394
|
+
);
|
|
395
|
+
const picker = getByTestId("android_picker");
|
|
396
|
+
await act(async () => {
|
|
397
|
+
picker.props.onValueChange?.("2", 1);
|
|
398
|
+
});
|
|
399
|
+
expect(mockOnValueChange).toHaveBeenCalledWith("2", 1);
|
|
400
|
+
} finally {
|
|
401
|
+
PlatformModule.OS = savedOS;
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
|
|
163
406
|
describe("interactions on iOS", () => {
|
|
164
407
|
it("fires onOpen when the iOS wrapper is pressed and onClose when Done is pressed", async () => {
|
|
165
408
|
const onOpen = mock(() => {});
|
package/src/PickerSelect.tsx
CHANGED
|
@@ -114,7 +114,7 @@ export interface RNPickerSelectProps {
|
|
|
114
114
|
InputAccessoryView?: ComponentType<{testID?: string}>;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
export
|
|
117
|
+
export const RNPickerSelect = ({
|
|
118
118
|
onValueChange,
|
|
119
119
|
value,
|
|
120
120
|
items,
|
|
@@ -136,7 +136,7 @@ export function RNPickerSelect({
|
|
|
136
136
|
touchableWrapperProps,
|
|
137
137
|
|
|
138
138
|
InputAccessoryView,
|
|
139
|
-
}: RNPickerSelectProps) {
|
|
139
|
+
}: RNPickerSelectProps) => {
|
|
140
140
|
const [showPicker, setShowPicker] = useState<boolean>(false);
|
|
141
141
|
const [animationType, setAnimationType] = useState<ModalProps["animationType"]>(undefined);
|
|
142
142
|
const [orientation, setOrientation] = useState<"portrait" | "landscape">("portrait");
|
|
@@ -683,4 +683,4 @@ export function RNPickerSelect({
|
|
|
683
683
|
};
|
|
684
684
|
|
|
685
685
|
return render();
|
|
686
|
-
}
|
|
686
|
+
};
|