@terreno/ui 0.13.3 → 0.14.1
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 +5 -5
- package/dist/ActionSheet.js +2 -2
- package/dist/ActionSheet.js.map +1 -1
- package/dist/Avatar.js +1 -1
- package/dist/Avatar.js.map +1 -1
- package/dist/Banner.js.map +1 -1
- package/dist/Box.js +2 -0
- package/dist/Box.js.map +1 -1
- package/dist/Button.d.ts +2 -2
- package/dist/Button.js +35 -23
- package/dist/Button.js.map +1 -1
- package/dist/Common.d.ts +16 -4
- 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/ConsentNavigator.d.ts +1 -1
- package/dist/ConsentNavigator.js +2 -1
- package/dist/ConsentNavigator.js.map +1 -1
- package/dist/CustomSelectField.js +3 -1
- package/dist/CustomSelectField.js.map +1 -1
- package/dist/DataTable.js +1 -1
- package/dist/DataTable.js.map +1 -1
- package/dist/DateTimeActionSheet.js +2 -1
- package/dist/DateTimeActionSheet.js.map +1 -1
- package/dist/DateTimeField.js +3 -2
- package/dist/DateTimeField.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/HeightField.js.map +1 -1
- package/dist/Hyperlink.js +19 -9
- package/dist/Hyperlink.js.map +1 -1
- package/dist/IconButton.js.map +1 -1
- package/dist/ImageBackground.d.ts +2 -5
- package/dist/ImageBackground.js +1 -1
- package/dist/ImageBackground.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/ModalSheet.d.ts +3 -2
- package/dist/ModalSheet.js +1 -1
- package/dist/ModalSheet.js.map +1 -1
- package/dist/OfflineBanner.d.ts +21 -0
- package/dist/OfflineBanner.js +25 -0
- package/dist/OfflineBanner.js.map +1 -0
- package/dist/OpenAPIContext.js +1 -1
- package/dist/OpenAPIContext.js.map +1 -1
- package/dist/Page.d.ts +1 -0
- package/dist/Page.js +7 -2
- package/dist/Page.js.map +1 -1
- package/dist/Pagination.js.map +1 -1
- package/dist/Permissions.js +3 -0
- package/dist/Permissions.js.map +1 -1
- package/dist/PickerSelect.d.ts +1 -1
- package/dist/PickerSelect.js +9 -6
- package/dist/PickerSelect.js.map +1 -1
- package/dist/SelectField.js +1 -1
- package/dist/SelectField.js.map +1 -1
- package/dist/SplitPage.js +7 -2
- package/dist/SplitPage.js.map +1 -1
- package/dist/SplitPage.native.js +4 -1
- package/dist/SplitPage.native.js.map +1 -1
- package/dist/TapToEdit.d.ts +1 -1
- package/dist/TapToEdit.js +12 -14
- package/dist/TapToEdit.js.map +1 -1
- package/dist/Toast.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 +3 -3
- package/dist/Unifier.js +15 -12
- package/dist/Unifier.js.map +1 -1
- package/dist/Utilities.d.ts +12 -8
- package/dist/Utilities.js +13 -15
- package/dist/Utilities.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -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/package.json +2 -1
- package/src/ActionSheet.test.tsx +1 -0
- package/src/ActionSheet.tsx +8 -6
- package/src/Avatar.tsx +9 -2
- package/src/Badge.test.tsx +1 -0
- package/src/Banner.test.tsx +71 -0
- package/src/Banner.tsx +1 -1
- package/src/Box.test.tsx +1 -0
- package/src/Box.tsx +10 -6
- package/src/Button.test.tsx +35 -0
- package/src/Button.tsx +65 -34
- package/src/Common.ts +42 -19
- package/src/ConsentFormScreen.test.tsx +124 -0
- package/src/ConsentFormScreen.tsx +18 -6
- package/src/ConsentNavigator.test.tsx +1 -0
- package/src/ConsentNavigator.tsx +5 -3
- package/src/CustomSelectField.tsx +3 -1
- package/src/DataTable.test.tsx +218 -0
- package/src/DataTable.tsx +1 -1
- package/src/DateTimeActionSheet.tsx +7 -3
- package/src/DateTimeField.test.tsx +1 -0
- package/src/DateTimeField.tsx +3 -2
- package/src/DateUtilities.test.ts +111 -0
- package/src/DateUtilities.tsx +43 -44
- package/src/DecimalRangeActionSheet.test.tsx +28 -0
- package/src/ErrorBoundary.test.tsx +1 -0
- package/src/HeightActionSheet.test.tsx +16 -0
- package/src/HeightField.test.tsx +106 -1
- package/src/HeightField.tsx +2 -1
- package/src/Hyperlink.tsx +83 -52
- package/src/IconButton.tsx +1 -1
- package/src/ImageBackground.tsx +5 -6
- package/src/MediaQuery.ts +8 -8
- package/src/MobileAddressAutoComplete.test.tsx +20 -1
- package/src/ModalSheet.test.tsx +1 -5
- package/src/ModalSheet.tsx +15 -6
- package/src/NumberField.test.tsx +14 -0
- package/src/OfflineBanner.test.tsx +70 -0
- package/src/OfflineBanner.tsx +54 -0
- package/src/OpenAPIContext.tsx +3 -2
- package/src/Page.test.tsx +28 -0
- package/src/Page.tsx +18 -2
- package/src/Pagination.tsx +1 -1
- package/src/Permissions.ts +3 -0
- package/src/PickerSelect.tsx +20 -17
- package/src/SelectBadge.test.tsx +1 -0
- package/src/SelectField.tsx +1 -1
- package/src/Signature.test.tsx +1 -0
- package/src/SplitPage.native.tsx +2 -0
- package/src/SplitPage.tsx +6 -1
- package/src/TapToEdit.test.tsx +48 -0
- package/src/TapToEdit.tsx +13 -14
- package/src/Toast.tsx +1 -1
- package/src/ToastNotifications.test.tsx +738 -0
- package/src/ToastNotifications.tsx +3 -6
- package/src/Tooltip.test.tsx +586 -8
- package/src/Tooltip.tsx +2 -2
- package/src/Unifier.ts +20 -16
- package/src/Utilities.tsx +20 -19
- package/src/WebAddressAutocomplete.test.tsx +138 -0
- package/src/WebDropdownMenu.test.tsx +23 -0
- package/src/__snapshots__/AddressField.test.tsx.snap +3 -1
- package/src/__snapshots__/Button.test.tsx.snap +92 -50
- package/src/__snapshots__/CustomSelectField.test.tsx.snap +21 -7
- package/src/__snapshots__/DecimalRangeActionSheet.test.tsx.snap +14 -8
- package/src/__snapshots__/ErrorPage.test.tsx.snap +7 -4
- package/src/__snapshots__/Field.test.tsx.snap +18 -6
- package/src/__snapshots__/HeightActionSheet.test.tsx.snap +14 -8
- package/src/__snapshots__/HeightField.test.tsx.snap +35 -20
- package/src/__snapshots__/InfoModalIcon.test.tsx.snap +28 -16
- package/src/__snapshots__/Modal.test.tsx.snap +19 -10
- package/src/__snapshots__/ModalSheet.test.tsx.snap +0 -1
- package/src/__snapshots__/NumberPickerActionSheet.test.tsx.snap +14 -8
- package/src/__snapshots__/Page.test.tsx.snap +7 -4
- package/src/__snapshots__/SelectField.test.tsx.snap +18 -6
- package/src/__snapshots__/TerrenoProvider.test.tsx.snap +0 -2
- package/src/__snapshots__/TimezonePicker.test.tsx.snap +18 -6
- package/src/bunSetup.ts +25 -2
- package/src/index.tsx +2 -1
- package/src/login/LoginScreen.test.tsx +23 -1
- package/src/login/__snapshots__/LoginScreen.test.tsx.snap +15 -6
- 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 +35 -5
- package/src/table/TableHeaderCell.tsx +8 -11
- package/src/table/TableRow.test.tsx +31 -1
- package/src/table/__snapshots__/TableBadge.test.tsx.snap +3 -1
- package/src/table/__snapshots__/TableHeaderCell.test.tsx.snap +2 -0
- package/src/table/tableContext.tsx +2 -2
- package/src/types/react-native-swiper-flatlist.d.ts +1 -0
- package/src/useStoredState.test.tsx +47 -0
package/src/Unifier.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {requestPermissions} from "./Permissions";
|
|
|
8
8
|
|
|
9
9
|
declare global {
|
|
10
10
|
interface Window {
|
|
11
|
+
// biome-ignore lint/suspicious/noExplicitAny: Google Maps JS SDK global type is loaded dynamically and not bundled as a typed dependency
|
|
11
12
|
google: any;
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -17,15 +18,20 @@ export type PlatformOS = "ios" | "android" | "web";
|
|
|
17
18
|
type Luminance = "light" | "lighter" | "dark" | "darker";
|
|
18
19
|
|
|
19
20
|
// Changes a color luminance
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
export const changeColorLuminance = (hex: string, luminanceChange: Luminance) => {
|
|
22
|
+
let normalizedHex = String(hex).replace(/[^0-9a-f]/gi, "");
|
|
23
|
+
if (normalizedHex.length === 3) {
|
|
24
|
+
normalizedHex =
|
|
25
|
+
normalizedHex[0] +
|
|
26
|
+
normalizedHex[0] +
|
|
27
|
+
normalizedHex[1] +
|
|
28
|
+
normalizedHex[1] +
|
|
29
|
+
normalizedHex[2] +
|
|
30
|
+
normalizedHex[2];
|
|
31
|
+
} else if (normalizedHex.length !== 6) {
|
|
32
|
+
throw new Error(`Invalid color hex: ${normalizedHex}`);
|
|
27
33
|
}
|
|
28
|
-
let luminance;
|
|
34
|
+
let luminance: number;
|
|
29
35
|
switch (luminanceChange) {
|
|
30
36
|
case "light":
|
|
31
37
|
luminance = -0.2;
|
|
@@ -43,19 +49,17 @@ export function changeColorLuminance(hex: string, luminanceChange: Luminance) {
|
|
|
43
49
|
throw new Error(`Cannot change luminance to ${luminanceChange}`);
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
// Convert to decimal and change luminosity
|
|
47
52
|
let rgb = "#";
|
|
48
53
|
for (let i = 0; i < 3; i++) {
|
|
49
|
-
const decimal = parseInt(
|
|
54
|
+
const decimal = parseInt(normalizedHex.substr(i * 2, 2), 16);
|
|
50
55
|
const appliedLuminance = Math.round(
|
|
51
56
|
Math.min(Math.max(0, decimal + decimal * luminance), 255)
|
|
52
57
|
).toString(16);
|
|
53
|
-
// 0 pad, if necessary.
|
|
54
58
|
rgb += `00${appliedLuminance}`.substr(appliedLuminance.length);
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
return rgb;
|
|
58
|
-
}
|
|
62
|
+
};
|
|
59
63
|
|
|
60
64
|
class UnifierClass {
|
|
61
65
|
private _web = false;
|
|
@@ -127,7 +131,7 @@ class UnifierClass {
|
|
|
127
131
|
};
|
|
128
132
|
|
|
129
133
|
storage = {
|
|
130
|
-
getItem: async (key: string, defaultValue?:
|
|
134
|
+
getItem: async (key: string, defaultValue?: unknown) => {
|
|
131
135
|
try {
|
|
132
136
|
const jsonValue = await AsyncStorage.getItem(key);
|
|
133
137
|
if (jsonValue) {
|
|
@@ -147,13 +151,13 @@ class UnifierClass {
|
|
|
147
151
|
return defaultValue || null;
|
|
148
152
|
}
|
|
149
153
|
},
|
|
150
|
-
setItem: async (key: string, item:
|
|
154
|
+
setItem: async (key: string, item: unknown) => {
|
|
151
155
|
try {
|
|
152
156
|
const jsonValue = JSON.stringify(item);
|
|
153
157
|
await AsyncStorage.setItem(key, jsonValue);
|
|
154
|
-
} catch (error:
|
|
158
|
+
} catch (error: unknown) {
|
|
155
159
|
console.error(`[storage] Error storing ${key}`, item, error);
|
|
156
|
-
throw new Error(error);
|
|
160
|
+
throw new Error(error instanceof Error ? error.message : String(error));
|
|
157
161
|
}
|
|
158
162
|
},
|
|
159
163
|
};
|
package/src/Utilities.tsx
CHANGED
|
@@ -6,7 +6,10 @@ import {Platform} from "react-native";
|
|
|
6
6
|
import type {APIError, BaseProfile, IconSize} from "./Common";
|
|
7
7
|
import {COUNTY_AND_COUNTY_EQUIVALENT_ENTITIES} from "./Constants";
|
|
8
8
|
|
|
9
|
-
export
|
|
9
|
+
export const mergeInlineStyles = (
|
|
10
|
+
inlineStyle?: {__style?: Record<string, unknown>} | undefined,
|
|
11
|
+
newStyle?: Record<string, unknown> | undefined
|
|
12
|
+
) => {
|
|
10
13
|
const inline = get(inlineStyle, "__style");
|
|
11
14
|
return {
|
|
12
15
|
__style: {
|
|
@@ -14,14 +17,14 @@ export function mergeInlineStyles(inlineStyle?: any, newStyle?: any) {
|
|
|
14
17
|
...newStyle,
|
|
15
18
|
},
|
|
16
19
|
};
|
|
17
|
-
}
|
|
20
|
+
};
|
|
18
21
|
|
|
19
|
-
export
|
|
22
|
+
export const isTestUser = (profile?: BaseProfile) => {
|
|
20
23
|
return (
|
|
21
24
|
profile?.email &&
|
|
22
25
|
(profile.email.indexOf("nang.io") > -1 || profile.email.indexOf("example.com") > -1)
|
|
23
26
|
);
|
|
24
|
-
}
|
|
27
|
+
};
|
|
25
28
|
|
|
26
29
|
export const iconNumberToSize = (size = 16): IconSize => {
|
|
27
30
|
let iconSize: IconSize;
|
|
@@ -104,7 +107,7 @@ export const toProps = ({
|
|
|
104
107
|
className,
|
|
105
108
|
inlineStyle,
|
|
106
109
|
}: Style): {className: string; style: InlineStyle} => {
|
|
107
|
-
const props:
|
|
110
|
+
const props: {className?: string; style?: InlineStyle} = {};
|
|
108
111
|
|
|
109
112
|
if (className.size > 0) {
|
|
110
113
|
// Sorting here ensures that classNames are always stable, reducing diff
|
|
@@ -117,7 +120,7 @@ export const toProps = ({
|
|
|
117
120
|
props.style = inlineStyle;
|
|
118
121
|
}
|
|
119
122
|
|
|
120
|
-
return props;
|
|
123
|
+
return props as {className: string; style: InlineStyle};
|
|
121
124
|
};
|
|
122
125
|
|
|
123
126
|
/*
|
|
@@ -167,17 +170,17 @@ export const rangeWithoutZero =
|
|
|
167
170
|
// Binds a string classname to the value in an object. Useful when interacting
|
|
168
171
|
// with ranges that need to come dynamically from a style object. This is
|
|
169
172
|
// similar to the NPM package 'classnames/bind'.
|
|
170
|
-
export
|
|
173
|
+
export const bind = <T,>(
|
|
171
174
|
fn: Functor<T>,
|
|
172
175
|
scope:
|
|
173
176
|
| {
|
|
174
177
|
readonly [key: string]: string;
|
|
175
178
|
}
|
|
176
|
-
|
|
|
177
|
-
): (val: T) => Style {
|
|
179
|
+
| Record<string, string>
|
|
180
|
+
): ((val: T) => Style) => {
|
|
178
181
|
const map = mapClassName((name) => scope[name]);
|
|
179
182
|
return (val: T): Style => map(fn(val));
|
|
180
|
-
}
|
|
183
|
+
};
|
|
181
184
|
|
|
182
185
|
// This takes a series of the previously defined functors, runs them all
|
|
183
186
|
// against a value and returns the set of their classnames.
|
|
@@ -291,15 +294,13 @@ export const isValidGoogleApiKey = (apiKey: string): boolean => {
|
|
|
291
294
|
return true;
|
|
292
295
|
};
|
|
293
296
|
|
|
294
|
-
export
|
|
295
|
-
// Remove whitespace and convert to lowercase for comparison
|
|
297
|
+
export const formattedCountyCode = (state: string, countyName: string): string => {
|
|
296
298
|
const stateKey = state
|
|
297
299
|
.replace(/\s+/g, "")
|
|
298
300
|
.toLowerCase() as keyof typeof COUNTY_AND_COUNTY_EQUIVALENT_ENTITIES;
|
|
299
301
|
|
|
300
302
|
const stateData = COUNTY_AND_COUNTY_EQUIVALENT_ENTITIES[stateKey];
|
|
301
303
|
|
|
302
|
-
// Remove whitespace, periods, apostrophes, and dashes for comparison
|
|
303
304
|
const countyKey = countyName
|
|
304
305
|
.trim()
|
|
305
306
|
.toLowerCase()
|
|
@@ -314,16 +315,16 @@ export function formattedCountyCode(state: string, countyName: string): string {
|
|
|
314
315
|
}
|
|
315
316
|
|
|
316
317
|
return `${countyData.stateFP}${countyData.countyFP}`;
|
|
317
|
-
}
|
|
318
|
+
};
|
|
318
319
|
|
|
319
|
-
export
|
|
320
|
-
return error?.data?.title;
|
|
321
|
-
}
|
|
320
|
+
export const isAPIError = (error: unknown): error is APIError => {
|
|
321
|
+
return Boolean((error as {data?: {title?: unknown}} | null | undefined)?.data?.title);
|
|
322
|
+
};
|
|
322
323
|
|
|
323
|
-
export
|
|
324
|
+
export const printAPIError = (error: APIError, details = true): string => {
|
|
324
325
|
let message = error.data?.title;
|
|
325
326
|
if (error.data?.detail && details) {
|
|
326
327
|
message = `${message}: ${error.data?.detail}`;
|
|
327
328
|
}
|
|
328
329
|
return message;
|
|
329
|
-
}
|
|
330
|
+
};
|
|
@@ -313,5 +313,143 @@ describe("WebAddressAutocomplete", () => {
|
|
|
313
313
|
// The .catch path warns and falls back to plain TextField.
|
|
314
314
|
expect(warnings.length).toBeGreaterThan(0);
|
|
315
315
|
});
|
|
316
|
+
|
|
317
|
+
it("cleans up the global callback on unmount", async () => {
|
|
318
|
+
const {unmount} = renderWithTheme(
|
|
319
|
+
<WebAddressAutocomplete
|
|
320
|
+
googleMapsApiKey="my-api-key"
|
|
321
|
+
handleAddressChange={() => {}}
|
|
322
|
+
handleAutoCompleteChange={() => {}}
|
|
323
|
+
inputValue=""
|
|
324
|
+
/>
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
const win = testGlobal.window as GoogleMapsWindow;
|
|
328
|
+
expect(win.initAutocomplete).toBeDefined();
|
|
329
|
+
|
|
330
|
+
unmount();
|
|
331
|
+
|
|
332
|
+
expect(win.initAutocomplete).toBeNull();
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it("re-runs effect when googleMapsApiKey changes", async () => {
|
|
336
|
+
const handleAutoCompleteChange = mock((_arg: AddressInterface) => {});
|
|
337
|
+
|
|
338
|
+
renderWithTheme(
|
|
339
|
+
<WebAddressAutocomplete
|
|
340
|
+
googleMapsApiKey="key-1"
|
|
341
|
+
handleAddressChange={() => {}}
|
|
342
|
+
handleAutoCompleteChange={handleAutoCompleteChange}
|
|
343
|
+
inputValue=""
|
|
344
|
+
/>
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
expect(appendedScripts.length).toBe(1);
|
|
348
|
+
|
|
349
|
+
// Simulate successful load for the second key
|
|
350
|
+
const win = testGlobal.window as GoogleMapsWindow;
|
|
351
|
+
const autocompleteConstructor = mock((_input: unknown, _opts: unknown) => ({
|
|
352
|
+
addListener: () => {},
|
|
353
|
+
getPlace: () => null,
|
|
354
|
+
}));
|
|
355
|
+
win.google = {
|
|
356
|
+
maps: {
|
|
357
|
+
places: {
|
|
358
|
+
Autocomplete: autocompleteConstructor,
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
await act(async () => {
|
|
364
|
+
(win.initAutocomplete as () => void)?.();
|
|
365
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
expect(autocompleteConstructor).toHaveBeenCalled();
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
it("processes address components with includeCounty", async () => {
|
|
372
|
+
const handleAutoCompleteChange = mock((_arg: AddressInterface) => {});
|
|
373
|
+
let placeChangedCb: (() => void) | undefined;
|
|
374
|
+
let localPlaceResult: PlaceResult | null = null;
|
|
375
|
+
|
|
376
|
+
const autocompleteConstructor = mock((_input: unknown, _opts: unknown) => ({
|
|
377
|
+
addListener: (event: string, cb: () => void) => {
|
|
378
|
+
if (event === "place_changed") {
|
|
379
|
+
placeChangedCb = cb;
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
getPlace: () => localPlaceResult,
|
|
383
|
+
}));
|
|
384
|
+
|
|
385
|
+
testGlobal.window = {
|
|
386
|
+
google: {
|
|
387
|
+
maps: {
|
|
388
|
+
places: {
|
|
389
|
+
Autocomplete: autocompleteConstructor,
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
renderWithTheme(
|
|
396
|
+
<WebAddressAutocomplete
|
|
397
|
+
googleMapsApiKey="test-key"
|
|
398
|
+
handleAddressChange={() => {}}
|
|
399
|
+
handleAutoCompleteChange={handleAutoCompleteChange}
|
|
400
|
+
includeCounty
|
|
401
|
+
inputValue=""
|
|
402
|
+
/>
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
await act(async () => {
|
|
406
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
localPlaceResult = {
|
|
410
|
+
address_components: [
|
|
411
|
+
{long_name: "10", short_name: "10", types: ["street_number"]},
|
|
412
|
+
{long_name: "Main St", short_name: "Main St", types: ["route"]},
|
|
413
|
+
{long_name: "Springfield", short_name: "Springfield", types: ["locality"]},
|
|
414
|
+
{
|
|
415
|
+
long_name: "Sangamon County",
|
|
416
|
+
short_name: "Sangamon County",
|
|
417
|
+
types: ["administrative_area_level_2"],
|
|
418
|
+
},
|
|
419
|
+
{long_name: "Illinois", short_name: "IL", types: ["administrative_area_level_1"]},
|
|
420
|
+
{long_name: "62701", short_name: "62701", types: ["postal_code"]},
|
|
421
|
+
],
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
await act(async () => {
|
|
425
|
+
placeChangedCb?.();
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
expect(handleAutoCompleteChange).toHaveBeenCalled();
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
describe("no API key behavior", () => {
|
|
433
|
+
it("sets scriptLoaded to false and renders plain TextField", async () => {
|
|
434
|
+
const handleAddressChange = mock(() => {});
|
|
435
|
+
const {UNSAFE_getAllByType} = renderWithTheme(
|
|
436
|
+
<WebAddressAutocomplete
|
|
437
|
+
handleAddressChange={handleAddressChange}
|
|
438
|
+
handleAutoCompleteChange={() => {}}
|
|
439
|
+
inputValue="test"
|
|
440
|
+
/>
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
await act(async () => {
|
|
444
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
const {TextInput} = require("react-native");
|
|
448
|
+
const inputs = UNSAFE_getAllByType(TextInput);
|
|
449
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
450
|
+
const {fireEvent: fe} = require("@testing-library/react-native");
|
|
451
|
+
fe.changeText(inputs[0], "new value");
|
|
452
|
+
expect(handleAddressChange).toHaveBeenCalledWith("new value");
|
|
453
|
+
});
|
|
316
454
|
});
|
|
317
455
|
});
|
|
@@ -141,6 +141,29 @@ describe("WebDropdownMenu", () => {
|
|
|
141
141
|
expect(getByText("Placeholder").props.style.fontWeight).toBe("400");
|
|
142
142
|
expect(getByText("Real").props.style.fontWeight).toBe("400");
|
|
143
143
|
});
|
|
144
|
+
|
|
145
|
+
it("applies dynamic background via the Pressable style callback", () => {
|
|
146
|
+
const {getByTestId} = renderWithTheme(
|
|
147
|
+
<WebDropdownMenu
|
|
148
|
+
anchor={anchor}
|
|
149
|
+
onClose={() => {}}
|
|
150
|
+
onSelect={() => {}}
|
|
151
|
+
options={options}
|
|
152
|
+
selectedValue="b"
|
|
153
|
+
visible
|
|
154
|
+
/>
|
|
155
|
+
);
|
|
156
|
+
const optionPressable = getByTestId("web_dropdown_option_a");
|
|
157
|
+
const styleFn = optionPressable.props.style;
|
|
158
|
+
expect(typeof styleFn).toBe("function");
|
|
159
|
+
const defaultStyle = styleFn({hovered: false, pressed: false});
|
|
160
|
+
const hoveredStyle = styleFn({hovered: true, pressed: false});
|
|
161
|
+
const pressedStyle = styleFn({hovered: false, pressed: true});
|
|
162
|
+
expect(defaultStyle.paddingHorizontal).toBe(12);
|
|
163
|
+
expect(defaultStyle.paddingVertical).toBe(10);
|
|
164
|
+
expect(hoveredStyle.backgroundColor).toBeDefined();
|
|
165
|
+
expect(pressedStyle.backgroundColor).toBeDefined();
|
|
166
|
+
});
|
|
144
167
|
});
|
|
145
168
|
|
|
146
169
|
describe("useWebDropdownAnchor", () => {
|
|
@@ -45,9 +45,12 @@ exports[`Button renders correctly with default props 1`] = `
|
|
|
45
45
|
],
|
|
46
46
|
"props": {
|
|
47
47
|
"accessibilityHint": "Press to perform action",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
48
|
+
"accessibilityLabel": "Click me",
|
|
49
|
+
"accessibilityRole": "button",
|
|
50
|
+
"accessibilityState": {
|
|
51
|
+
"disabled": false,
|
|
52
|
+
},
|
|
53
|
+
"disabled": false,
|
|
51
54
|
"onPress": [Function: debounced],
|
|
52
55
|
"style": {
|
|
53
56
|
"alignItems": "center",
|
|
@@ -64,7 +67,7 @@ exports[`Button renders correctly with default props 1`] = `
|
|
|
64
67
|
},
|
|
65
68
|
"testID": undefined,
|
|
66
69
|
},
|
|
67
|
-
"type": "
|
|
70
|
+
"type": "PressableScale",
|
|
68
71
|
}
|
|
69
72
|
`;
|
|
70
73
|
|
|
@@ -113,9 +116,12 @@ exports[`Button renders primary variant 1`] = `
|
|
|
113
116
|
],
|
|
114
117
|
"props": {
|
|
115
118
|
"accessibilityHint": "Press to perform action",
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
+
"accessibilityLabel": "Primary",
|
|
120
|
+
"accessibilityRole": "button",
|
|
121
|
+
"accessibilityState": {
|
|
122
|
+
"disabled": false,
|
|
123
|
+
},
|
|
124
|
+
"disabled": false,
|
|
119
125
|
"onPress": [Function: debounced],
|
|
120
126
|
"style": {
|
|
121
127
|
"alignItems": "center",
|
|
@@ -132,7 +138,7 @@ exports[`Button renders primary variant 1`] = `
|
|
|
132
138
|
},
|
|
133
139
|
"testID": undefined,
|
|
134
140
|
},
|
|
135
|
-
"type": "
|
|
141
|
+
"type": "PressableScale",
|
|
136
142
|
}
|
|
137
143
|
`;
|
|
138
144
|
|
|
@@ -181,9 +187,12 @@ exports[`Button renders secondary variant 1`] = `
|
|
|
181
187
|
],
|
|
182
188
|
"props": {
|
|
183
189
|
"accessibilityHint": "Press to perform action",
|
|
184
|
-
"
|
|
185
|
-
"
|
|
186
|
-
"
|
|
190
|
+
"accessibilityLabel": "Secondary",
|
|
191
|
+
"accessibilityRole": "button",
|
|
192
|
+
"accessibilityState": {
|
|
193
|
+
"disabled": false,
|
|
194
|
+
},
|
|
195
|
+
"disabled": false,
|
|
187
196
|
"onPress": [Function: debounced],
|
|
188
197
|
"style": {
|
|
189
198
|
"alignItems": "center",
|
|
@@ -200,7 +209,7 @@ exports[`Button renders secondary variant 1`] = `
|
|
|
200
209
|
},
|
|
201
210
|
"testID": undefined,
|
|
202
211
|
},
|
|
203
|
-
"type": "
|
|
212
|
+
"type": "PressableScale",
|
|
204
213
|
}
|
|
205
214
|
`;
|
|
206
215
|
|
|
@@ -249,9 +258,12 @@ exports[`Button renders muted variant 1`] = `
|
|
|
249
258
|
],
|
|
250
259
|
"props": {
|
|
251
260
|
"accessibilityHint": "Press to perform action",
|
|
252
|
-
"
|
|
253
|
-
"
|
|
254
|
-
"
|
|
261
|
+
"accessibilityLabel": "Muted",
|
|
262
|
+
"accessibilityRole": "button",
|
|
263
|
+
"accessibilityState": {
|
|
264
|
+
"disabled": false,
|
|
265
|
+
},
|
|
266
|
+
"disabled": false,
|
|
255
267
|
"onPress": [Function: debounced],
|
|
256
268
|
"style": {
|
|
257
269
|
"alignItems": "center",
|
|
@@ -268,7 +280,7 @@ exports[`Button renders muted variant 1`] = `
|
|
|
268
280
|
},
|
|
269
281
|
"testID": undefined,
|
|
270
282
|
},
|
|
271
|
-
"type": "
|
|
283
|
+
"type": "PressableScale",
|
|
272
284
|
}
|
|
273
285
|
`;
|
|
274
286
|
|
|
@@ -317,9 +329,12 @@ exports[`Button renders outline variant 1`] = `
|
|
|
317
329
|
],
|
|
318
330
|
"props": {
|
|
319
331
|
"accessibilityHint": "Press to perform action",
|
|
320
|
-
"
|
|
321
|
-
"
|
|
322
|
-
"
|
|
332
|
+
"accessibilityLabel": "Outline",
|
|
333
|
+
"accessibilityRole": "button",
|
|
334
|
+
"accessibilityState": {
|
|
335
|
+
"disabled": false,
|
|
336
|
+
},
|
|
337
|
+
"disabled": false,
|
|
323
338
|
"onPress": [Function: debounced],
|
|
324
339
|
"style": {
|
|
325
340
|
"alignItems": "center",
|
|
@@ -336,7 +351,7 @@ exports[`Button renders outline variant 1`] = `
|
|
|
336
351
|
},
|
|
337
352
|
"testID": undefined,
|
|
338
353
|
},
|
|
339
|
-
"type": "
|
|
354
|
+
"type": "PressableScale",
|
|
340
355
|
}
|
|
341
356
|
`;
|
|
342
357
|
|
|
@@ -385,9 +400,12 @@ exports[`Button renders destructive variant 1`] = `
|
|
|
385
400
|
],
|
|
386
401
|
"props": {
|
|
387
402
|
"accessibilityHint": "Press to perform action",
|
|
388
|
-
"
|
|
389
|
-
"
|
|
390
|
-
"
|
|
403
|
+
"accessibilityLabel": "Delete",
|
|
404
|
+
"accessibilityRole": "button",
|
|
405
|
+
"accessibilityState": {
|
|
406
|
+
"disabled": false,
|
|
407
|
+
},
|
|
408
|
+
"disabled": false,
|
|
391
409
|
"onPress": [Function: debounced],
|
|
392
410
|
"style": {
|
|
393
411
|
"alignItems": "center",
|
|
@@ -404,7 +422,7 @@ exports[`Button renders destructive variant 1`] = `
|
|
|
404
422
|
},
|
|
405
423
|
"testID": undefined,
|
|
406
424
|
},
|
|
407
|
-
"type": "
|
|
425
|
+
"type": "PressableScale",
|
|
408
426
|
}
|
|
409
427
|
`;
|
|
410
428
|
|
|
@@ -453,8 +471,11 @@ exports[`Button renders disabled state 1`] = `
|
|
|
453
471
|
],
|
|
454
472
|
"props": {
|
|
455
473
|
"accessibilityHint": "Press to perform action",
|
|
456
|
-
"
|
|
457
|
-
"
|
|
474
|
+
"accessibilityLabel": "Disabled",
|
|
475
|
+
"accessibilityRole": "button",
|
|
476
|
+
"accessibilityState": {
|
|
477
|
+
"disabled": true,
|
|
478
|
+
},
|
|
458
479
|
"disabled": true,
|
|
459
480
|
"onPress": [Function: debounced],
|
|
460
481
|
"style": {
|
|
@@ -521,8 +542,11 @@ exports[`Button applies disabled styles when disabled 1`] = `
|
|
|
521
542
|
],
|
|
522
543
|
"props": {
|
|
523
544
|
"accessibilityHint": "Press to perform action",
|
|
524
|
-
"
|
|
525
|
-
"
|
|
545
|
+
"accessibilityLabel": "Disabled",
|
|
546
|
+
"accessibilityRole": "button",
|
|
547
|
+
"accessibilityState": {
|
|
548
|
+
"disabled": true,
|
|
549
|
+
},
|
|
526
550
|
"disabled": true,
|
|
527
551
|
"onPress": [Function: debounced],
|
|
528
552
|
"style": {
|
|
@@ -612,8 +636,11 @@ exports[`Button renders loading state 1`] = `
|
|
|
612
636
|
],
|
|
613
637
|
"props": {
|
|
614
638
|
"accessibilityHint": "Press to perform action",
|
|
615
|
-
"
|
|
616
|
-
"
|
|
639
|
+
"accessibilityLabel": "Loading",
|
|
640
|
+
"accessibilityRole": "button",
|
|
641
|
+
"accessibilityState": {
|
|
642
|
+
"disabled": true,
|
|
643
|
+
},
|
|
617
644
|
"disabled": true,
|
|
618
645
|
"onPress": [Function: debounced],
|
|
619
646
|
"style": {
|
|
@@ -680,9 +707,12 @@ exports[`Button renders fullWidth button 1`] = `
|
|
|
680
707
|
],
|
|
681
708
|
"props": {
|
|
682
709
|
"accessibilityHint": "Press to perform action",
|
|
683
|
-
"
|
|
684
|
-
"
|
|
685
|
-
"
|
|
710
|
+
"accessibilityLabel": "Full Width",
|
|
711
|
+
"accessibilityRole": "button",
|
|
712
|
+
"accessibilityState": {
|
|
713
|
+
"disabled": false,
|
|
714
|
+
},
|
|
715
|
+
"disabled": false,
|
|
686
716
|
"onPress": [Function: debounced],
|
|
687
717
|
"style": {
|
|
688
718
|
"alignItems": "center",
|
|
@@ -699,7 +729,7 @@ exports[`Button renders fullWidth button 1`] = `
|
|
|
699
729
|
},
|
|
700
730
|
"testID": undefined,
|
|
701
731
|
},
|
|
702
|
-
"type": "
|
|
732
|
+
"type": "PressableScale",
|
|
703
733
|
}
|
|
704
734
|
`;
|
|
705
735
|
|
|
@@ -761,9 +791,12 @@ exports[`Button renders with icon on left 1`] = `
|
|
|
761
791
|
],
|
|
762
792
|
"props": {
|
|
763
793
|
"accessibilityHint": "Press to perform action",
|
|
764
|
-
"
|
|
765
|
-
"
|
|
766
|
-
"
|
|
794
|
+
"accessibilityLabel": "With Icon",
|
|
795
|
+
"accessibilityRole": "button",
|
|
796
|
+
"accessibilityState": {
|
|
797
|
+
"disabled": false,
|
|
798
|
+
},
|
|
799
|
+
"disabled": false,
|
|
767
800
|
"onPress": [Function: debounced],
|
|
768
801
|
"style": {
|
|
769
802
|
"alignItems": "center",
|
|
@@ -780,7 +813,7 @@ exports[`Button renders with icon on left 1`] = `
|
|
|
780
813
|
},
|
|
781
814
|
"testID": undefined,
|
|
782
815
|
},
|
|
783
|
-
"type": "
|
|
816
|
+
"type": "PressableScale",
|
|
784
817
|
}
|
|
785
818
|
`;
|
|
786
819
|
|
|
@@ -842,9 +875,12 @@ exports[`Button renders with icon on right 1`] = `
|
|
|
842
875
|
],
|
|
843
876
|
"props": {
|
|
844
877
|
"accessibilityHint": "Press to perform action",
|
|
845
|
-
"
|
|
846
|
-
"
|
|
847
|
-
"
|
|
878
|
+
"accessibilityLabel": "Next",
|
|
879
|
+
"accessibilityRole": "button",
|
|
880
|
+
"accessibilityState": {
|
|
881
|
+
"disabled": false,
|
|
882
|
+
},
|
|
883
|
+
"disabled": false,
|
|
848
884
|
"onPress": [Function: debounced],
|
|
849
885
|
"style": {
|
|
850
886
|
"alignItems": "center",
|
|
@@ -861,7 +897,7 @@ exports[`Button renders with icon on right 1`] = `
|
|
|
861
897
|
},
|
|
862
898
|
"testID": undefined,
|
|
863
899
|
},
|
|
864
|
-
"type": "
|
|
900
|
+
"type": "PressableScale",
|
|
865
901
|
}
|
|
866
902
|
`;
|
|
867
903
|
|
|
@@ -910,9 +946,12 @@ exports[`Button renders with confirmation modal props 1`] = `
|
|
|
910
946
|
],
|
|
911
947
|
"props": {
|
|
912
948
|
"accessibilityHint": "Opens a confirmation dialog",
|
|
913
|
-
"
|
|
914
|
-
"
|
|
915
|
-
"
|
|
949
|
+
"accessibilityLabel": "Delete",
|
|
950
|
+
"accessibilityRole": "button",
|
|
951
|
+
"accessibilityState": {
|
|
952
|
+
"disabled": false,
|
|
953
|
+
},
|
|
954
|
+
"disabled": false,
|
|
916
955
|
"onPress": [Function: debounced],
|
|
917
956
|
"style": {
|
|
918
957
|
"alignItems": "center",
|
|
@@ -929,7 +968,7 @@ exports[`Button renders with confirmation modal props 1`] = `
|
|
|
929
968
|
},
|
|
930
969
|
"testID": undefined,
|
|
931
970
|
},
|
|
932
|
-
"type": "
|
|
971
|
+
"type": "PressableScale",
|
|
933
972
|
}
|
|
934
973
|
`;
|
|
935
974
|
|
|
@@ -978,9 +1017,12 @@ exports[`Button renders with tooltip on desktop (wrapped in Tooltip) 1`] = `
|
|
|
978
1017
|
],
|
|
979
1018
|
"props": {
|
|
980
1019
|
"accessibilityHint": "Press to perform action",
|
|
981
|
-
"
|
|
982
|
-
"
|
|
983
|
-
"
|
|
1020
|
+
"accessibilityLabel": "Hover me",
|
|
1021
|
+
"accessibilityRole": "button",
|
|
1022
|
+
"accessibilityState": {
|
|
1023
|
+
"disabled": false,
|
|
1024
|
+
},
|
|
1025
|
+
"disabled": false,
|
|
984
1026
|
"onPress": [Function: debounced],
|
|
985
1027
|
"style": {
|
|
986
1028
|
"alignItems": "center",
|
|
@@ -997,6 +1039,6 @@ exports[`Button renders with tooltip on desktop (wrapped in Tooltip) 1`] = `
|
|
|
997
1039
|
},
|
|
998
1040
|
"testID": undefined,
|
|
999
1041
|
},
|
|
1000
|
-
"type": "
|
|
1042
|
+
"type": "PressableScale",
|
|
1001
1043
|
}
|
|
1002
1044
|
`;
|