ferns-ui 1.10.0 → 1.11.0
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/Accordion.js +1 -1
- package/dist/Accordion.js.map +1 -1
- package/dist/Accordion.test.d.ts +1 -0
- package/dist/Accordion.test.js +71 -0
- package/dist/Accordion.test.js.map +1 -0
- package/dist/AddressField.test.d.ts +1 -0
- package/dist/AddressField.test.js +65 -0
- package/dist/AddressField.test.js.map +1 -0
- package/dist/Avatar.js +2 -2
- package/dist/Avatar.js.map +1 -1
- package/dist/Avatar.test.d.ts +1 -0
- package/dist/Avatar.test.js +131 -0
- package/dist/Avatar.test.js.map +1 -0
- package/dist/Badge.d.ts +1 -1
- package/dist/Badge.js +3 -3
- package/dist/Badge.js.map +1 -1
- package/dist/Badge.test.d.ts +1 -0
- package/dist/Badge.test.js +76 -0
- package/dist/Badge.test.js.map +1 -0
- package/dist/Box.test.d.ts +1 -0
- package/dist/Box.test.js +528 -0
- package/dist/Box.test.js.map +1 -0
- package/dist/Common.d.ts +100 -1
- package/dist/Common.js.map +1 -1
- package/dist/DateTimeField.js +15 -2
- package/dist/DateTimeField.js.map +1 -1
- package/dist/InfoModalIcon.js +1 -1
- package/dist/InfoModalIcon.js.map +1 -1
- package/dist/Slider.d.ts +3 -0
- package/dist/Slider.js +94 -0
- package/dist/Slider.js.map +1 -0
- package/dist/Text.js +2 -0
- package/dist/Text.js.map +1 -1
- package/dist/TextField.test.js +9 -9
- package/dist/TextField.test.js.map +1 -1
- package/dist/Tooltip.js +2 -0
- package/dist/Tooltip.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/setupTests.js +40 -2
- package/dist/setupTests.js.map +1 -1
- package/dist/test-utils.js.map +1 -1
- package/package.json +2 -1
- package/src/Accordion.test.tsx +104 -0
- package/src/Accordion.tsx +1 -0
- package/src/AddressField.test.tsx +89 -0
- package/src/Avatar.test.tsx +163 -0
- package/src/Avatar.tsx +2 -0
- package/src/Badge.test.tsx +116 -0
- package/src/Badge.tsx +3 -1
- package/src/Box.test.tsx +665 -0
- package/src/Common.ts +114 -1
- package/src/DateTimeField.tsx +15 -2
- package/src/InfoModalIcon.tsx +1 -0
- package/src/Slider.tsx +205 -0
- package/src/Text.tsx +2 -0
- package/src/TextField.test.tsx +59 -71
- package/src/Tooltip.tsx +2 -0
- package/src/__snapshots__/Accordion.test.tsx.snap +120 -0
- package/src/__snapshots__/AddressField.test.tsx.snap +464 -0
- package/src/__snapshots__/Avatar.test.tsx.snap +78 -0
- package/src/__snapshots__/Badge.test.tsx.snap +44 -0
- package/src/__snapshots__/Box.test.tsx.snap +159 -0
- package/src/__snapshots__/TextArea.test.tsx.snap +12 -0
- package/src/__snapshots__/TextField.test.tsx.snap +38 -1
- package/src/index.tsx +1 -0
- package/src/setupTests.ts +45 -2
- package/src/test-utils.tsx +1 -0
package/src/Box.test.tsx
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
import {act, fireEvent} from "@testing-library/react-native";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
import {Box} from "./Box";
|
|
5
|
+
import {Text} from "./Text";
|
|
6
|
+
import {renderWithTheme} from "./test-utils";
|
|
7
|
+
|
|
8
|
+
// Mock the mediaQueryLargerThan function
|
|
9
|
+
jest.mock("./MediaQuery", () => ({
|
|
10
|
+
mediaQueryLargerThan: jest.fn(() => false),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
describe("Box", () => {
|
|
14
|
+
describe("basic rendering", () => {
|
|
15
|
+
it("should render with default props", () => {
|
|
16
|
+
const {root} = renderWithTheme(<Box />);
|
|
17
|
+
expect(root).toBeTruthy();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should render children", () => {
|
|
21
|
+
const {getByText} = renderWithTheme(
|
|
22
|
+
<Box>
|
|
23
|
+
<Text>Test Content</Text>
|
|
24
|
+
</Box>
|
|
25
|
+
);
|
|
26
|
+
expect(getByText("Test Content")).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should apply testID", () => {
|
|
30
|
+
const {getByTestId} = renderWithTheme(<Box testID="test-box" />);
|
|
31
|
+
expect(getByTestId("test-box")).toBeTruthy();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("layout props", () => {
|
|
36
|
+
it("should apply direction prop", () => {
|
|
37
|
+
const {root} = renderWithTheme(<Box direction="column" />);
|
|
38
|
+
const view = root.findByType("View");
|
|
39
|
+
expect(view.props.style).toMatchObject({
|
|
40
|
+
flexDirection: "column",
|
|
41
|
+
display: "flex"
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should apply responsive direction props", () => {
|
|
46
|
+
const {root} = renderWithTheme(<Box smDirection="row" />);
|
|
47
|
+
expect(root).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("should apply flex grow", () => {
|
|
51
|
+
const {root} = renderWithTheme(<Box flex="grow" />);
|
|
52
|
+
const view = root.findByType("View");
|
|
53
|
+
expect(view.props.style).toMatchObject({
|
|
54
|
+
flexGrow: 1,
|
|
55
|
+
flexShrink: 1,
|
|
56
|
+
display: "flex"
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should apply flex shrink", () => {
|
|
61
|
+
const {root} = renderWithTheme(<Box flex="shrink" />);
|
|
62
|
+
const view = root.findByType("View");
|
|
63
|
+
expect(view.props.style).toMatchObject({
|
|
64
|
+
flexShrink: 1,
|
|
65
|
+
display: "flex"
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should apply flex none", () => {
|
|
70
|
+
const {root} = renderWithTheme(<Box flex="none" />);
|
|
71
|
+
const view = root.findByType("View");
|
|
72
|
+
expect(view.props.style).toMatchObject({
|
|
73
|
+
flex: 0,
|
|
74
|
+
display: "flex"
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("should apply justifyContent", () => {
|
|
79
|
+
const {root} = renderWithTheme(<Box justifyContent="center" />);
|
|
80
|
+
const view = root.findByType("View");
|
|
81
|
+
expect(view.props.style).toMatchObject({
|
|
82
|
+
justifyContent: "center"
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should apply alignItems", () => {
|
|
87
|
+
const {root} = renderWithTheme(<Box alignItems="center" />);
|
|
88
|
+
const view = root.findByType("View");
|
|
89
|
+
expect(view.props.style).toMatchObject({
|
|
90
|
+
alignItems: "center"
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should apply alignContent", () => {
|
|
95
|
+
const {root} = renderWithTheme(<Box alignContent="center" />);
|
|
96
|
+
const view = root.findByType("View");
|
|
97
|
+
expect(view.props.style).toMatchObject({
|
|
98
|
+
alignContent: "center"
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("should apply alignSelf", () => {
|
|
103
|
+
const {root} = renderWithTheme(<Box alignSelf="center" />);
|
|
104
|
+
const view = root.findByType("View");
|
|
105
|
+
expect(view.props.style).toMatchObject({
|
|
106
|
+
alignSelf: "center"
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should apply wrap", () => {
|
|
111
|
+
const {root} = renderWithTheme(<Box wrap />);
|
|
112
|
+
const view = root.findByType("View");
|
|
113
|
+
expect(view.props.style).toMatchObject({
|
|
114
|
+
flexWrap: "wrap",
|
|
115
|
+
alignItems: "flex-start"
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("should apply gap", () => {
|
|
120
|
+
const {root} = renderWithTheme(<Box gap={4} />);
|
|
121
|
+
const view = root.findByType("View");
|
|
122
|
+
expect(view.props.style).toMatchObject({
|
|
123
|
+
gap: 16
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe("spacing props", () => {
|
|
129
|
+
it("should apply padding", () => {
|
|
130
|
+
const {root} = renderWithTheme(<Box padding={4} />);
|
|
131
|
+
const view = root.findByType("View");
|
|
132
|
+
expect(view.props.style).toMatchObject({
|
|
133
|
+
padding: 16
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("should apply paddingX", () => {
|
|
138
|
+
const {root} = renderWithTheme(<Box paddingX={2} />);
|
|
139
|
+
const view = root.findByType("View");
|
|
140
|
+
expect(view.props.style).toMatchObject({
|
|
141
|
+
paddingLeft: 8,
|
|
142
|
+
paddingRight: 8
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("should apply paddingY", () => {
|
|
147
|
+
const {root} = renderWithTheme(<Box paddingY={3} />);
|
|
148
|
+
const view = root.findByType("View");
|
|
149
|
+
expect(view.props.style).toMatchObject({
|
|
150
|
+
paddingTop: 12,
|
|
151
|
+
paddingBottom: 12
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("should apply margin", () => {
|
|
156
|
+
const {root} = renderWithTheme(<Box margin={4} />);
|
|
157
|
+
const view = root.findByType("View");
|
|
158
|
+
expect(view.props.style).toMatchObject({
|
|
159
|
+
margin: 16
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("should apply marginTop", () => {
|
|
164
|
+
const {root} = renderWithTheme(<Box marginTop={2} />);
|
|
165
|
+
const view = root.findByType("View");
|
|
166
|
+
expect(view.props.style).toMatchObject({
|
|
167
|
+
marginTop: 8
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("should apply marginBottom", () => {
|
|
172
|
+
const {root} = renderWithTheme(<Box marginBottom={2} />);
|
|
173
|
+
const view = root.findByType("View");
|
|
174
|
+
expect(view.props.style).toMatchObject({
|
|
175
|
+
marginBottom: 8
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("should apply marginLeft", () => {
|
|
180
|
+
const {root} = renderWithTheme(<Box marginLeft={2} />);
|
|
181
|
+
const view = root.findByType("View");
|
|
182
|
+
expect(view.props.style).toMatchObject({
|
|
183
|
+
marginLeft: 8
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("should apply marginRight", () => {
|
|
188
|
+
const {root} = renderWithTheme(<Box marginRight={2} />);
|
|
189
|
+
const view = root.findByType("View");
|
|
190
|
+
expect(view.props.style).toMatchObject({
|
|
191
|
+
marginRight: 8
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
describe("sizing props", () => {
|
|
197
|
+
it("should apply width", () => {
|
|
198
|
+
const {root} = renderWithTheme(<Box width={100} />);
|
|
199
|
+
const view = root.findByType("View");
|
|
200
|
+
expect(view.props.style).toMatchObject({
|
|
201
|
+
width: 100
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("should apply height", () => {
|
|
206
|
+
const {root} = renderWithTheme(<Box height={100} />);
|
|
207
|
+
const view = root.findByType("View");
|
|
208
|
+
expect(view.props.style).toMatchObject({
|
|
209
|
+
height: 100
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("should apply string width", () => {
|
|
214
|
+
const {root} = renderWithTheme(<Box width="50%" />);
|
|
215
|
+
const view = root.findByType("View");
|
|
216
|
+
expect(view.props.style).toMatchObject({
|
|
217
|
+
width: "50%"
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("should apply string height", () => {
|
|
222
|
+
const {root} = renderWithTheme(<Box height="50%" />);
|
|
223
|
+
const view = root.findByType("View");
|
|
224
|
+
expect(view.props.style).toMatchObject({
|
|
225
|
+
height: "50%"
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
describe("position props", () => {
|
|
231
|
+
it("should apply position absolute", () => {
|
|
232
|
+
const {root} = renderWithTheme(<Box position="absolute" />);
|
|
233
|
+
const view = root.findByType("View");
|
|
234
|
+
expect(view.props.style).toMatchObject({
|
|
235
|
+
position: "absolute"
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("should apply top", () => {
|
|
240
|
+
const {root} = renderWithTheme(<Box top />);
|
|
241
|
+
const view = root.findByType("View");
|
|
242
|
+
expect(view.props.style).toMatchObject({
|
|
243
|
+
top: 0
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("should apply bottom", () => {
|
|
248
|
+
const {root} = renderWithTheme(<Box bottom />);
|
|
249
|
+
const view = root.findByType("View");
|
|
250
|
+
expect(view.props.style).toMatchObject({
|
|
251
|
+
bottom: 0
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("should apply left", () => {
|
|
256
|
+
const {root} = renderWithTheme(<Box left />);
|
|
257
|
+
const view = root.findByType("View");
|
|
258
|
+
expect(view.props.style).toMatchObject({
|
|
259
|
+
left: 0
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it("should apply right", () => {
|
|
264
|
+
const {root} = renderWithTheme(<Box right />);
|
|
265
|
+
const view = root.findByType("View");
|
|
266
|
+
expect(view.props.style).toMatchObject({
|
|
267
|
+
right: 0
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("should apply zIndex", () => {
|
|
272
|
+
const {root} = renderWithTheme(<Box zIndex={10} />);
|
|
273
|
+
const view = root.findByType("View");
|
|
274
|
+
expect(view.props.style).toMatchObject({
|
|
275
|
+
zIndex: 10
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
describe("color and surface props", () => {
|
|
281
|
+
it("should apply background color", () => {
|
|
282
|
+
const {root} = renderWithTheme(<Box color="primary" />);
|
|
283
|
+
const view = root.findByType("View");
|
|
284
|
+
expect(view.props.style.backgroundColor).toBeDefined();
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
describe("border props", () => {
|
|
289
|
+
it("should apply border", () => {
|
|
290
|
+
const {root} = renderWithTheme(<Box border="default" />);
|
|
291
|
+
const view = root.findByType("View");
|
|
292
|
+
expect(view.props.style.borderColor).toBeDefined();
|
|
293
|
+
expect(view.props.style.borderWidth).toBe(1);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("should apply borderTop", () => {
|
|
297
|
+
const {root} = renderWithTheme(<Box borderTop="default" />);
|
|
298
|
+
const view = root.findByType("View");
|
|
299
|
+
expect(view.props.style.borderTopColor).toBeDefined();
|
|
300
|
+
expect(view.props.style.borderTopWidth).toBe(1);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("should apply borderBottom", () => {
|
|
304
|
+
const {root} = renderWithTheme(<Box borderBottom="default" />);
|
|
305
|
+
const view = root.findByType("View");
|
|
306
|
+
expect(view.props.style.borderBottomColor).toBeDefined();
|
|
307
|
+
expect(view.props.style.borderBottomWidth).toBe(1);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it("should apply borderLeft", () => {
|
|
311
|
+
const {root} = renderWithTheme(<Box borderLeft="default" />);
|
|
312
|
+
const view = root.findByType("View");
|
|
313
|
+
expect(view.props.style.borderLeftColor).toBeDefined();
|
|
314
|
+
expect(view.props.style.borderLeftWidth).toBe(1);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it("should apply borderRight", () => {
|
|
318
|
+
const {root} = renderWithTheme(<Box borderRight="default" />);
|
|
319
|
+
const view = root.findByType("View");
|
|
320
|
+
expect(view.props.style.borderRightColor).toBeDefined();
|
|
321
|
+
expect(view.props.style.borderRightWidth).toBe(1);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it("should adjust width for border", () => {
|
|
325
|
+
const {root} = renderWithTheme(<Box border="default" width={100} />);
|
|
326
|
+
const view = root.findByType("View");
|
|
327
|
+
expect(view.props.style.width).toBe(104); // 100 + 2*2 for border
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("should adjust height for border", () => {
|
|
331
|
+
const {root} = renderWithTheme(<Box border="default" height={100} />);
|
|
332
|
+
const view = root.findByType("View");
|
|
333
|
+
expect(view.props.style.height).toBe(104); // 100 + 2*2 for border
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
describe("rounding props", () => {
|
|
338
|
+
it("should apply rounding", () => {
|
|
339
|
+
const {root} = renderWithTheme(<Box rounding="md" />);
|
|
340
|
+
const view = root.findByType("View");
|
|
341
|
+
expect(view.props.style.borderRadius).toBe(4);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
it("should apply circle rounding with width", () => {
|
|
345
|
+
const {root} = renderWithTheme(<Box rounding="circle" width={50} />);
|
|
346
|
+
const view = root.findByType("View");
|
|
347
|
+
expect(view.props.style.borderRadius).toBe(50);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it("should apply circle rounding with height", () => {
|
|
351
|
+
const {root} = renderWithTheme(<Box rounding="circle" height={50} />);
|
|
352
|
+
const view = root.findByType("View");
|
|
353
|
+
expect(view.props.style.borderRadius).toBe(50);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it("should warn when using circle without dimensions", () => {
|
|
357
|
+
const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
|
|
358
|
+
renderWithTheme(<Box rounding="circle" />);
|
|
359
|
+
expect(consoleSpy).toHaveBeenCalledWith("Cannot use Box rounding='circle' without height or width.");
|
|
360
|
+
consoleSpy.mockRestore();
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
describe("display props", () => {
|
|
365
|
+
it("should apply display none", () => {
|
|
366
|
+
const {root} = renderWithTheme(<Box display="none" />);
|
|
367
|
+
const view = root.findByType("View");
|
|
368
|
+
expect(view.props.style).toMatchObject({
|
|
369
|
+
display: "none"
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it("should apply display flex", () => {
|
|
374
|
+
const {root} = renderWithTheme(<Box display="flex" />);
|
|
375
|
+
const view = root.findByType("View");
|
|
376
|
+
expect(view.props.style).toMatchObject({
|
|
377
|
+
flex: undefined
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it("should apply display block", () => {
|
|
382
|
+
const {root} = renderWithTheme(<Box display="block" />);
|
|
383
|
+
const view = root.findByType("View");
|
|
384
|
+
expect(view.props.style).toMatchObject({
|
|
385
|
+
flex: 0,
|
|
386
|
+
flexDirection: "row"
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
describe("overflow props", () => {
|
|
392
|
+
it("should apply overflow scroll", () => {
|
|
393
|
+
const {root} = renderWithTheme(<Box overflow="scroll" />);
|
|
394
|
+
const view = root.findByType("View");
|
|
395
|
+
expect(view.props.style).toMatchObject({
|
|
396
|
+
overflow: "scroll"
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it("should apply overflow scrollY", () => {
|
|
401
|
+
const {root} = renderWithTheme(<Box overflow="scrollY" />);
|
|
402
|
+
const view = root.findByType("View");
|
|
403
|
+
expect(view.props.style).toMatchObject({
|
|
404
|
+
overflow: "scroll"
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it("should apply overflow hidden", () => {
|
|
409
|
+
const {root} = renderWithTheme(<Box overflow="hidden" />);
|
|
410
|
+
const view = root.findByType("View");
|
|
411
|
+
expect(view.props.style).toMatchObject({
|
|
412
|
+
overflow: "hidden"
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
describe("shadow props", () => {
|
|
418
|
+
it("should apply shadow", () => {
|
|
419
|
+
const {root} = renderWithTheme(<Box shadow />);
|
|
420
|
+
const view = root.findByType("View");
|
|
421
|
+
expect(view.props.style).toBeDefined();
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
describe("clickable behavior", () => {
|
|
426
|
+
it("should render as Pressable when onClick is provided", () => {
|
|
427
|
+
const mockOnClick = jest.fn();
|
|
428
|
+
const {root} = renderWithTheme(
|
|
429
|
+
<Box onClick={mockOnClick} accessibilityLabel="Click me" accessibilityHint="Tap to trigger action">
|
|
430
|
+
<Text>Clickable content</Text>
|
|
431
|
+
</Box>
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
expect(root).toBeTruthy();
|
|
435
|
+
// Just verify the component renders without error when onClick is provided
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
it("should call onClick when pressed", async () => {
|
|
439
|
+
const mockOnClick = jest.fn();
|
|
440
|
+
const {getByTestId} = renderWithTheme(
|
|
441
|
+
<Box
|
|
442
|
+
onClick={mockOnClick}
|
|
443
|
+
testID="clickable-box"
|
|
444
|
+
accessibilityLabel="Click me"
|
|
445
|
+
accessibilityHint="Tap to trigger action"
|
|
446
|
+
/>
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
const pressable = getByTestId("clickable-box-clickable");
|
|
450
|
+
await act(async () => {
|
|
451
|
+
fireEvent.press(pressable);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
expect(mockOnClick).toHaveBeenCalledTimes(1);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it("should apply accessibility props to Pressable", () => {
|
|
458
|
+
const mockOnClick = jest.fn();
|
|
459
|
+
const {getByTestId} = renderWithTheme(
|
|
460
|
+
<Box
|
|
461
|
+
onClick={mockOnClick}
|
|
462
|
+
testID="accessible-box"
|
|
463
|
+
accessibilityLabel="Click me"
|
|
464
|
+
accessibilityHint="Tap to trigger action"
|
|
465
|
+
/>
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
const pressable = getByTestId("accessible-box-clickable");
|
|
469
|
+
expect(pressable).toBeTruthy();
|
|
470
|
+
// Basic check that accessibility props are being applied
|
|
471
|
+
expect(pressable.props).toBeDefined();
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
describe("scroll behavior", () => {
|
|
476
|
+
it("should render ScrollView when scroll is enabled", () => {
|
|
477
|
+
const {root} = renderWithTheme(<Box scroll />);
|
|
478
|
+
expect(root).toBeTruthy();
|
|
479
|
+
// Just verify the component renders without error when scroll is enabled
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it("should enable horizontal scrolling when overflow is scrollX", () => {
|
|
483
|
+
const {root} = renderWithTheme(<Box scroll overflow="scrollX" />);
|
|
484
|
+
expect(root).toBeTruthy();
|
|
485
|
+
// Just verify the component renders without error when horizontal scroll is enabled
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
it("should call onScroll callback", () => {
|
|
489
|
+
const mockOnScroll = jest.fn();
|
|
490
|
+
const {root} = renderWithTheme(<Box scroll onScroll={mockOnScroll} />);
|
|
491
|
+
expect(root).toBeTruthy();
|
|
492
|
+
// Just verify the component renders without error when onScroll is provided
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
describe("keyboard avoidance", () => {
|
|
497
|
+
it("should render KeyboardAvoidingView when avoidKeyboard is enabled", () => {
|
|
498
|
+
const {root} = renderWithTheme(<Box avoidKeyboard />);
|
|
499
|
+
expect(root).toBeTruthy();
|
|
500
|
+
// Just verify the component renders without error when avoidKeyboard is enabled
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it("should apply keyboard offset", () => {
|
|
504
|
+
const {root} = renderWithTheme(<Box avoidKeyboard keyboardOffset={20} />);
|
|
505
|
+
expect(root).toBeTruthy();
|
|
506
|
+
// Just verify the component renders without error when keyboard offset is provided
|
|
507
|
+
});
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
describe("hover events", () => {
|
|
511
|
+
it("should call onHoverStart", async () => {
|
|
512
|
+
const mockOnHoverStart = jest.fn();
|
|
513
|
+
const {getByTestId} = renderWithTheme(
|
|
514
|
+
<Box onHoverStart={mockOnHoverStart} testID="hover-box" />
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
const view = getByTestId("hover-box");
|
|
518
|
+
await act(async () => {
|
|
519
|
+
fireEvent(view, "pointerEnter");
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
expect(mockOnHoverStart).toHaveBeenCalledTimes(1);
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
it("should call onHoverEnd", async () => {
|
|
526
|
+
const mockOnHoverEnd = jest.fn();
|
|
527
|
+
const {getByTestId} = renderWithTheme(
|
|
528
|
+
<Box onHoverEnd={mockOnHoverEnd} testID="hover-box" />
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
const view = getByTestId("hover-box");
|
|
532
|
+
await act(async () => {
|
|
533
|
+
fireEvent(view, "pointerLeave");
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
expect(mockOnHoverEnd).toHaveBeenCalledTimes(1);
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
describe("ref forwarding", () => {
|
|
541
|
+
it("should expose scrollToEnd method", () => {
|
|
542
|
+
const ref = React.createRef<any>();
|
|
543
|
+
renderWithTheme(<Box ref={ref} scroll />);
|
|
544
|
+
|
|
545
|
+
expect(ref.current).toBeTruthy();
|
|
546
|
+
expect(typeof ref.current.scrollToEnd).toBe("function");
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
it("should expose scrollTo method", () => {
|
|
550
|
+
const ref = React.createRef<any>();
|
|
551
|
+
renderWithTheme(<Box ref={ref} scroll />);
|
|
552
|
+
|
|
553
|
+
expect(ref.current).toBeTruthy();
|
|
554
|
+
expect(typeof ref.current.scrollTo).toBe("function");
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
describe("dangerous inline styles", () => {
|
|
559
|
+
it("should apply dangerouslySetInlineStyle", () => {
|
|
560
|
+
const {root} = renderWithTheme(
|
|
561
|
+
<Box dangerouslySetInlineStyle={{ __style: { backgroundColor: "red" } }} />
|
|
562
|
+
);
|
|
563
|
+
const view = root.findByType("View");
|
|
564
|
+
expect(view.props.style).toMatchObject({
|
|
565
|
+
backgroundColor: "red"
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
describe("warnings", () => {
|
|
571
|
+
it("should warn when using wrap and alignItems together", () => {
|
|
572
|
+
const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
|
|
573
|
+
renderWithTheme(<Box wrap alignItems="center" />);
|
|
574
|
+
expect(consoleSpy).toHaveBeenCalledWith("React Native doesn't support wrap and alignItems together.");
|
|
575
|
+
consoleSpy.mockRestore();
|
|
576
|
+
});
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
describe("edge cases", () => {
|
|
580
|
+
it("should handle undefined children", () => {
|
|
581
|
+
const {root} = renderWithTheme(<Box>{undefined}</Box>);
|
|
582
|
+
expect(root).toBeTruthy();
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
it("should handle null children", () => {
|
|
586
|
+
const {root} = renderWithTheme(<Box>{null}</Box>);
|
|
587
|
+
expect(root).toBeTruthy();
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
it("should handle multiple children", () => {
|
|
591
|
+
const {getByText} = renderWithTheme(
|
|
592
|
+
<Box>
|
|
593
|
+
<Text>First</Text>
|
|
594
|
+
<Text>Second</Text>
|
|
595
|
+
</Box>
|
|
596
|
+
);
|
|
597
|
+
expect(getByText("First")).toBeTruthy();
|
|
598
|
+
expect(getByText("Second")).toBeTruthy();
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it("should handle zero values", () => {
|
|
602
|
+
const {root} = renderWithTheme(<Box padding={0} margin={0} gap={0} />);
|
|
603
|
+
const view = root.findByType("View");
|
|
604
|
+
expect(view.props.style).toMatchObject({
|
|
605
|
+
padding: 0,
|
|
606
|
+
margin: 0,
|
|
607
|
+
gap: 0
|
|
608
|
+
});
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
describe("snapshots", () => {
|
|
613
|
+
it("should match snapshot with default props", () => {
|
|
614
|
+
const component = renderWithTheme(<Box />);
|
|
615
|
+
expect(component.toJSON()).toMatchSnapshot();
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
it("should match snapshot with layout props", () => {
|
|
619
|
+
const component = renderWithTheme(
|
|
620
|
+
<Box
|
|
621
|
+
direction="column"
|
|
622
|
+
flex="grow"
|
|
623
|
+
justifyContent="center"
|
|
624
|
+
alignItems="center"
|
|
625
|
+
padding={4}
|
|
626
|
+
margin={2}
|
|
627
|
+
/>
|
|
628
|
+
);
|
|
629
|
+
expect(component.toJSON()).toMatchSnapshot();
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
it("should match snapshot with clickable props", () => {
|
|
633
|
+
const component = renderWithTheme(
|
|
634
|
+
<Box
|
|
635
|
+
onClick={jest.fn()}
|
|
636
|
+
accessibilityLabel="Click me"
|
|
637
|
+
accessibilityHint="Tap to trigger action"
|
|
638
|
+
/>
|
|
639
|
+
);
|
|
640
|
+
expect(component.toJSON()).toMatchSnapshot();
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
it("should match snapshot with scroll enabled", () => {
|
|
644
|
+
const component = renderWithTheme(<Box scroll />);
|
|
645
|
+
expect(component.toJSON()).toMatchSnapshot();
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
it("should match snapshot with keyboard avoidance", () => {
|
|
649
|
+
const component = renderWithTheme(<Box avoidKeyboard />);
|
|
650
|
+
expect(component.toJSON()).toMatchSnapshot();
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
it("should match snapshot with border and rounding", () => {
|
|
654
|
+
const component = renderWithTheme(
|
|
655
|
+
<Box
|
|
656
|
+
border="default"
|
|
657
|
+
rounding="md"
|
|
658
|
+
color="primary"
|
|
659
|
+
shadow
|
|
660
|
+
/>
|
|
661
|
+
);
|
|
662
|
+
expect(component.toJSON()).toMatchSnapshot();
|
|
663
|
+
});
|
|
664
|
+
});
|
|
665
|
+
});
|