ferns-ui 2.0.0-beta.2 → 2.0.0-beta.4
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 +7 -2
- package/dist/Accordion.js.map +1 -1
- package/dist/ActionSheet.js +14 -11
- package/dist/ActionSheet.js.map +1 -1
- package/dist/AddressField.js +1 -1
- package/dist/AddressField.js.map +1 -1
- package/dist/Badge.js +1 -1
- package/dist/Badge.js.map +1 -1
- package/dist/Banner.js +1 -1
- package/dist/Banner.js.map +1 -1
- package/dist/Box.js +3 -3
- package/dist/Box.js.map +1 -1
- package/dist/Button.js +0 -1
- package/dist/Button.js.map +1 -1
- package/dist/CheckBox.js.map +1 -1
- package/dist/Common.d.ts +13 -9
- package/dist/Common.js.map +1 -1
- package/dist/DataTable.js +1 -2
- package/dist/DataTable.js.map +1 -1
- package/dist/DateTimeField.js +22 -22
- package/dist/DateTimeField.js.map +1 -1
- package/dist/EmailField.js +17 -37
- package/dist/EmailField.js.map +1 -1
- package/dist/FernsProvider.js +1 -1
- package/dist/FernsProvider.js.map +1 -1
- package/dist/Heading.js +3 -1
- package/dist/Heading.js.map +1 -1
- package/dist/Hyperlink.js +1 -1
- package/dist/Hyperlink.js.map +1 -1
- package/dist/IconButton.js +1 -1
- package/dist/IconButton.js.map +1 -1
- package/dist/Image.js.map +1 -1
- package/dist/MarkdownView.d.ts +5 -0
- package/dist/MarkdownView.js +44 -0
- package/dist/MarkdownView.js.map +1 -0
- package/dist/MobileAddressAutoComplete.js +1 -1
- package/dist/MobileAddressAutoComplete.js.map +1 -1
- package/dist/Modal.d.ts +1 -1
- package/dist/Modal.js +35 -15
- package/dist/Modal.js.map +1 -1
- package/dist/NumberField.js +10 -4
- package/dist/NumberField.js.map +1 -1
- package/dist/NumberPickerActionSheet.d.ts +1 -3
- package/dist/NumberPickerActionSheet.js +0 -3
- package/dist/NumberPickerActionSheet.js.map +1 -1
- package/dist/Page.js +1 -1
- package/dist/Page.js.map +1 -1
- package/dist/Pagination.js +2 -2
- package/dist/Pagination.js.map +1 -1
- package/dist/Permissions.d.ts +1 -1
- package/dist/Permissions.js +2 -2
- package/dist/Permissions.js.map +1 -1
- package/dist/PickerSelect.js +1 -1
- package/dist/PickerSelect.js.map +1 -1
- package/dist/SectionDivider.js +1 -1
- package/dist/SectionDivider.js.map +1 -1
- package/dist/SegmentedControl.js.map +1 -1
- package/dist/Signature.native.js +2 -2
- package/dist/Signature.native.js.map +1 -1
- package/dist/SignatureField.js +2 -2
- package/dist/SignatureField.js.map +1 -1
- package/dist/Slider.js +3 -3
- package/dist/Slider.js.map +1 -1
- package/dist/SplitPage.js +7 -7
- package/dist/SplitPage.js.map +1 -1
- package/dist/SplitPage.native.js +4 -6
- package/dist/SplitPage.native.js.map +1 -1
- package/dist/TapToEdit.js +3 -3
- package/dist/TapToEdit.js.map +1 -1
- package/dist/Text.js +1 -1
- package/dist/Text.js.map +1 -1
- package/dist/TextFieldNumberActionSheet.d.ts +2 -4
- package/dist/TextFieldNumberActionSheet.js +1 -4
- package/dist/TextFieldNumberActionSheet.js.map +1 -1
- package/dist/Tooltip.js +37 -19
- package/dist/Tooltip.js.map +1 -1
- package/dist/Unifier.d.ts +0 -1
- package/dist/Unifier.js.map +1 -1
- package/dist/Utilities.d.ts +1 -1
- package/dist/Utilities.js +2 -3
- package/dist/Utilities.js.map +1 -1
- package/dist/WebAddressAutocomplete.js +2 -1
- package/dist/WebAddressAutocomplete.js.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/table/Table.js +14 -15
- package/dist/table/Table.js.map +1 -1
- package/dist/table/TableHeaderCell.js +2 -2
- package/dist/table/TableHeaderCell.js.map +1 -1
- package/dist/useStoredState.js +4 -2
- package/dist/useStoredState.js.map +1 -1
- package/package.json +5 -64
- package/src/Accordion.tsx +7 -1
- package/src/ActionSheet.tsx +26 -22
- package/src/AddressField.tsx +1 -1
- package/src/Badge.tsx +1 -1
- package/src/Banner.tsx +1 -1
- package/src/Box.test.tsx +71 -70
- package/src/Box.tsx +21 -9
- package/src/Button.tsx +0 -1
- package/src/CheckBox.tsx +7 -1
- package/src/Common.ts +14 -21
- package/src/DataTable.tsx +1 -2
- package/src/DateTimeField.tsx +22 -22
- package/src/EmailField.tsx +22 -42
- package/src/FernsProvider.tsx +1 -4
- package/src/Heading.tsx +3 -1
- package/src/Hyperlink.tsx +1 -1
- package/src/IconButton.tsx +2 -2
- package/src/Image.tsx +1 -0
- package/src/MarkdownView.tsx +67 -0
- package/src/MobileAddressAutoComplete.tsx +1 -1
- package/src/Modal.tsx +58 -21
- package/src/NumberField.tsx +10 -4
- package/src/NumberPickerActionSheet.tsx +1 -5
- package/src/Page.tsx +1 -1
- package/src/Pagination.tsx +2 -11
- package/src/Permissions.ts +2 -2
- package/src/PickerSelect.tsx +1 -1
- package/src/SectionDivider.tsx +1 -1
- package/src/SegmentedControl.tsx +3 -1
- package/src/Signature.native.tsx +2 -2
- package/src/SignatureField.tsx +2 -2
- package/src/Slider.tsx +10 -17
- package/src/SplitPage.native.tsx +2 -4
- package/src/SplitPage.tsx +4 -4
- package/src/TapToEdit.tsx +3 -7
- package/src/Text.tsx +1 -1
- package/src/TextArea.test.tsx +27 -43
- package/src/TextField.test.tsx +3 -4
- package/src/TextFieldNumberActionSheet.tsx +3 -7
- package/src/Tooltip.tsx +41 -19
- package/src/Unifier.ts +1 -3
- package/src/Utilities.tsx +3 -4
- package/src/WebAddressAutocomplete.tsx +1 -1
- package/src/index.tsx +11 -10
- package/src/table/Table.tsx +34 -36
- package/src/table/TableHeaderCell.tsx +2 -2
- package/src/useStoredState.ts +13 -11
package/src/Box.test.tsx
CHANGED
|
@@ -38,7 +38,7 @@ describe("Box", () => {
|
|
|
38
38
|
const view = root.findByType("View");
|
|
39
39
|
expect(view.props.style).toMatchObject({
|
|
40
40
|
flexDirection: "column",
|
|
41
|
-
display: "flex"
|
|
41
|
+
display: "flex",
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -53,7 +53,7 @@ describe("Box", () => {
|
|
|
53
53
|
expect(view.props.style).toMatchObject({
|
|
54
54
|
flexGrow: 1,
|
|
55
55
|
flexShrink: 1,
|
|
56
|
-
display: "flex"
|
|
56
|
+
display: "flex",
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
|
|
@@ -62,7 +62,7 @@ describe("Box", () => {
|
|
|
62
62
|
const view = root.findByType("View");
|
|
63
63
|
expect(view.props.style).toMatchObject({
|
|
64
64
|
flexShrink: 1,
|
|
65
|
-
display: "flex"
|
|
65
|
+
display: "flex",
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
68
|
|
|
@@ -71,7 +71,7 @@ describe("Box", () => {
|
|
|
71
71
|
const view = root.findByType("View");
|
|
72
72
|
expect(view.props.style).toMatchObject({
|
|
73
73
|
flex: 0,
|
|
74
|
-
display: "flex"
|
|
74
|
+
display: "flex",
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
77
|
|
|
@@ -79,7 +79,7 @@ describe("Box", () => {
|
|
|
79
79
|
const {root} = renderWithTheme(<Box justifyContent="center" />);
|
|
80
80
|
const view = root.findByType("View");
|
|
81
81
|
expect(view.props.style).toMatchObject({
|
|
82
|
-
justifyContent: "center"
|
|
82
|
+
justifyContent: "center",
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
85
|
|
|
@@ -87,7 +87,7 @@ describe("Box", () => {
|
|
|
87
87
|
const {root} = renderWithTheme(<Box alignItems="center" />);
|
|
88
88
|
const view = root.findByType("View");
|
|
89
89
|
expect(view.props.style).toMatchObject({
|
|
90
|
-
alignItems: "center"
|
|
90
|
+
alignItems: "center",
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
|
|
@@ -95,7 +95,7 @@ describe("Box", () => {
|
|
|
95
95
|
const {root} = renderWithTheme(<Box alignContent="center" />);
|
|
96
96
|
const view = root.findByType("View");
|
|
97
97
|
expect(view.props.style).toMatchObject({
|
|
98
|
-
alignContent: "center"
|
|
98
|
+
alignContent: "center",
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
101
|
|
|
@@ -103,7 +103,7 @@ describe("Box", () => {
|
|
|
103
103
|
const {root} = renderWithTheme(<Box alignSelf="center" />);
|
|
104
104
|
const view = root.findByType("View");
|
|
105
105
|
expect(view.props.style).toMatchObject({
|
|
106
|
-
alignSelf: "center"
|
|
106
|
+
alignSelf: "center",
|
|
107
107
|
});
|
|
108
108
|
});
|
|
109
109
|
|
|
@@ -112,7 +112,7 @@ describe("Box", () => {
|
|
|
112
112
|
const view = root.findByType("View");
|
|
113
113
|
expect(view.props.style).toMatchObject({
|
|
114
114
|
flexWrap: "wrap",
|
|
115
|
-
alignItems: "flex-start"
|
|
115
|
+
alignItems: "flex-start",
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
118
|
|
|
@@ -120,7 +120,7 @@ describe("Box", () => {
|
|
|
120
120
|
const {root} = renderWithTheme(<Box gap={4} />);
|
|
121
121
|
const view = root.findByType("View");
|
|
122
122
|
expect(view.props.style).toMatchObject({
|
|
123
|
-
gap: 16
|
|
123
|
+
gap: 16,
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
126
|
});
|
|
@@ -130,7 +130,7 @@ describe("Box", () => {
|
|
|
130
130
|
const {root} = renderWithTheme(<Box padding={4} />);
|
|
131
131
|
const view = root.findByType("View");
|
|
132
132
|
expect(view.props.style).toMatchObject({
|
|
133
|
-
padding: 16
|
|
133
|
+
padding: 16,
|
|
134
134
|
});
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -139,7 +139,7 @@ describe("Box", () => {
|
|
|
139
139
|
const view = root.findByType("View");
|
|
140
140
|
expect(view.props.style).toMatchObject({
|
|
141
141
|
paddingLeft: 8,
|
|
142
|
-
paddingRight: 8
|
|
142
|
+
paddingRight: 8,
|
|
143
143
|
});
|
|
144
144
|
});
|
|
145
145
|
|
|
@@ -148,7 +148,7 @@ describe("Box", () => {
|
|
|
148
148
|
const view = root.findByType("View");
|
|
149
149
|
expect(view.props.style).toMatchObject({
|
|
150
150
|
paddingTop: 12,
|
|
151
|
-
paddingBottom: 12
|
|
151
|
+
paddingBottom: 12,
|
|
152
152
|
});
|
|
153
153
|
});
|
|
154
154
|
|
|
@@ -156,7 +156,7 @@ describe("Box", () => {
|
|
|
156
156
|
const {root} = renderWithTheme(<Box margin={4} />);
|
|
157
157
|
const view = root.findByType("View");
|
|
158
158
|
expect(view.props.style).toMatchObject({
|
|
159
|
-
margin: 16
|
|
159
|
+
margin: 16,
|
|
160
160
|
});
|
|
161
161
|
});
|
|
162
162
|
|
|
@@ -164,7 +164,7 @@ describe("Box", () => {
|
|
|
164
164
|
const {root} = renderWithTheme(<Box marginTop={2} />);
|
|
165
165
|
const view = root.findByType("View");
|
|
166
166
|
expect(view.props.style).toMatchObject({
|
|
167
|
-
marginTop: 8
|
|
167
|
+
marginTop: 8,
|
|
168
168
|
});
|
|
169
169
|
});
|
|
170
170
|
|
|
@@ -172,7 +172,7 @@ describe("Box", () => {
|
|
|
172
172
|
const {root} = renderWithTheme(<Box marginBottom={2} />);
|
|
173
173
|
const view = root.findByType("View");
|
|
174
174
|
expect(view.props.style).toMatchObject({
|
|
175
|
-
marginBottom: 8
|
|
175
|
+
marginBottom: 8,
|
|
176
176
|
});
|
|
177
177
|
});
|
|
178
178
|
|
|
@@ -180,7 +180,7 @@ describe("Box", () => {
|
|
|
180
180
|
const {root} = renderWithTheme(<Box marginLeft={2} />);
|
|
181
181
|
const view = root.findByType("View");
|
|
182
182
|
expect(view.props.style).toMatchObject({
|
|
183
|
-
marginLeft: 8
|
|
183
|
+
marginLeft: 8,
|
|
184
184
|
});
|
|
185
185
|
});
|
|
186
186
|
|
|
@@ -188,7 +188,7 @@ describe("Box", () => {
|
|
|
188
188
|
const {root} = renderWithTheme(<Box marginRight={2} />);
|
|
189
189
|
const view = root.findByType("View");
|
|
190
190
|
expect(view.props.style).toMatchObject({
|
|
191
|
-
marginRight: 8
|
|
191
|
+
marginRight: 8,
|
|
192
192
|
});
|
|
193
193
|
});
|
|
194
194
|
});
|
|
@@ -198,7 +198,7 @@ describe("Box", () => {
|
|
|
198
198
|
const {root} = renderWithTheme(<Box width={100} />);
|
|
199
199
|
const view = root.findByType("View");
|
|
200
200
|
expect(view.props.style).toMatchObject({
|
|
201
|
-
width: 100
|
|
201
|
+
width: 100,
|
|
202
202
|
});
|
|
203
203
|
});
|
|
204
204
|
|
|
@@ -206,7 +206,7 @@ describe("Box", () => {
|
|
|
206
206
|
const {root} = renderWithTheme(<Box height={100} />);
|
|
207
207
|
const view = root.findByType("View");
|
|
208
208
|
expect(view.props.style).toMatchObject({
|
|
209
|
-
height: 100
|
|
209
|
+
height: 100,
|
|
210
210
|
});
|
|
211
211
|
});
|
|
212
212
|
|
|
@@ -214,7 +214,7 @@ describe("Box", () => {
|
|
|
214
214
|
const {root} = renderWithTheme(<Box width="50%" />);
|
|
215
215
|
const view = root.findByType("View");
|
|
216
216
|
expect(view.props.style).toMatchObject({
|
|
217
|
-
width: "50%"
|
|
217
|
+
width: "50%",
|
|
218
218
|
});
|
|
219
219
|
});
|
|
220
220
|
|
|
@@ -222,7 +222,7 @@ describe("Box", () => {
|
|
|
222
222
|
const {root} = renderWithTheme(<Box height="50%" />);
|
|
223
223
|
const view = root.findByType("View");
|
|
224
224
|
expect(view.props.style).toMatchObject({
|
|
225
|
-
height: "50%"
|
|
225
|
+
height: "50%",
|
|
226
226
|
});
|
|
227
227
|
});
|
|
228
228
|
});
|
|
@@ -232,7 +232,7 @@ describe("Box", () => {
|
|
|
232
232
|
const {root} = renderWithTheme(<Box position="absolute" />);
|
|
233
233
|
const view = root.findByType("View");
|
|
234
234
|
expect(view.props.style).toMatchObject({
|
|
235
|
-
position: "absolute"
|
|
235
|
+
position: "absolute",
|
|
236
236
|
});
|
|
237
237
|
});
|
|
238
238
|
|
|
@@ -240,7 +240,7 @@ describe("Box", () => {
|
|
|
240
240
|
const {root} = renderWithTheme(<Box top />);
|
|
241
241
|
const view = root.findByType("View");
|
|
242
242
|
expect(view.props.style).toMatchObject({
|
|
243
|
-
top: 0
|
|
243
|
+
top: 0,
|
|
244
244
|
});
|
|
245
245
|
});
|
|
246
246
|
|
|
@@ -248,7 +248,7 @@ describe("Box", () => {
|
|
|
248
248
|
const {root} = renderWithTheme(<Box bottom />);
|
|
249
249
|
const view = root.findByType("View");
|
|
250
250
|
expect(view.props.style).toMatchObject({
|
|
251
|
-
bottom: 0
|
|
251
|
+
bottom: 0,
|
|
252
252
|
});
|
|
253
253
|
});
|
|
254
254
|
|
|
@@ -256,7 +256,7 @@ describe("Box", () => {
|
|
|
256
256
|
const {root} = renderWithTheme(<Box left />);
|
|
257
257
|
const view = root.findByType("View");
|
|
258
258
|
expect(view.props.style).toMatchObject({
|
|
259
|
-
left: 0
|
|
259
|
+
left: 0,
|
|
260
260
|
});
|
|
261
261
|
});
|
|
262
262
|
|
|
@@ -264,7 +264,7 @@ describe("Box", () => {
|
|
|
264
264
|
const {root} = renderWithTheme(<Box right />);
|
|
265
265
|
const view = root.findByType("View");
|
|
266
266
|
expect(view.props.style).toMatchObject({
|
|
267
|
-
right: 0
|
|
267
|
+
right: 0,
|
|
268
268
|
});
|
|
269
269
|
});
|
|
270
270
|
|
|
@@ -272,7 +272,7 @@ describe("Box", () => {
|
|
|
272
272
|
const {root} = renderWithTheme(<Box zIndex={10} />);
|
|
273
273
|
const view = root.findByType("View");
|
|
274
274
|
expect(view.props.style).toMatchObject({
|
|
275
|
-
zIndex: 10
|
|
275
|
+
zIndex: 10,
|
|
276
276
|
});
|
|
277
277
|
});
|
|
278
278
|
});
|
|
@@ -356,7 +356,9 @@ describe("Box", () => {
|
|
|
356
356
|
it("should warn when using circle without dimensions", () => {
|
|
357
357
|
const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
|
|
358
358
|
renderWithTheme(<Box rounding="circle" />);
|
|
359
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
359
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
360
|
+
"Cannot use Box rounding='circle' without height or width."
|
|
361
|
+
);
|
|
360
362
|
consoleSpy.mockRestore();
|
|
361
363
|
});
|
|
362
364
|
});
|
|
@@ -366,7 +368,7 @@ describe("Box", () => {
|
|
|
366
368
|
const {root} = renderWithTheme(<Box display="none" />);
|
|
367
369
|
const view = root.findByType("View");
|
|
368
370
|
expect(view.props.style).toMatchObject({
|
|
369
|
-
display: "none"
|
|
371
|
+
display: "none",
|
|
370
372
|
});
|
|
371
373
|
});
|
|
372
374
|
|
|
@@ -374,7 +376,7 @@ describe("Box", () => {
|
|
|
374
376
|
const {root} = renderWithTheme(<Box display="flex" />);
|
|
375
377
|
const view = root.findByType("View");
|
|
376
378
|
expect(view.props.style).toMatchObject({
|
|
377
|
-
flex: undefined
|
|
379
|
+
flex: undefined,
|
|
378
380
|
});
|
|
379
381
|
});
|
|
380
382
|
|
|
@@ -383,7 +385,7 @@ describe("Box", () => {
|
|
|
383
385
|
const view = root.findByType("View");
|
|
384
386
|
expect(view.props.style).toMatchObject({
|
|
385
387
|
flex: 0,
|
|
386
|
-
flexDirection: "row"
|
|
388
|
+
flexDirection: "row",
|
|
387
389
|
});
|
|
388
390
|
});
|
|
389
391
|
});
|
|
@@ -393,7 +395,7 @@ describe("Box", () => {
|
|
|
393
395
|
const {root} = renderWithTheme(<Box overflow="scroll" />);
|
|
394
396
|
const view = root.findByType("View");
|
|
395
397
|
expect(view.props.style).toMatchObject({
|
|
396
|
-
overflow: "scroll"
|
|
398
|
+
overflow: "scroll",
|
|
397
399
|
});
|
|
398
400
|
});
|
|
399
401
|
|
|
@@ -401,7 +403,7 @@ describe("Box", () => {
|
|
|
401
403
|
const {root} = renderWithTheme(<Box overflow="scrollY" />);
|
|
402
404
|
const view = root.findByType("View");
|
|
403
405
|
expect(view.props.style).toMatchObject({
|
|
404
|
-
overflow: "scroll"
|
|
406
|
+
overflow: "scroll",
|
|
405
407
|
});
|
|
406
408
|
});
|
|
407
409
|
|
|
@@ -409,7 +411,7 @@ describe("Box", () => {
|
|
|
409
411
|
const {root} = renderWithTheme(<Box overflow="hidden" />);
|
|
410
412
|
const view = root.findByType("View");
|
|
411
413
|
expect(view.props.style).toMatchObject({
|
|
412
|
-
overflow: "hidden"
|
|
414
|
+
overflow: "hidden",
|
|
413
415
|
});
|
|
414
416
|
});
|
|
415
417
|
});
|
|
@@ -426,11 +428,15 @@ describe("Box", () => {
|
|
|
426
428
|
it("should render as Pressable when onClick is provided", () => {
|
|
427
429
|
const mockOnClick = jest.fn();
|
|
428
430
|
const {root} = renderWithTheme(
|
|
429
|
-
<Box
|
|
431
|
+
<Box
|
|
432
|
+
onClick={mockOnClick}
|
|
433
|
+
accessibilityLabel="Click me"
|
|
434
|
+
accessibilityHint="Tap to trigger action"
|
|
435
|
+
>
|
|
430
436
|
<Text>Clickable content</Text>
|
|
431
437
|
</Box>
|
|
432
438
|
);
|
|
433
|
-
|
|
439
|
+
|
|
434
440
|
expect(root).toBeTruthy();
|
|
435
441
|
// Just verify the component renders without error when onClick is provided
|
|
436
442
|
});
|
|
@@ -438,33 +444,33 @@ describe("Box", () => {
|
|
|
438
444
|
it("should call onClick when pressed", async () => {
|
|
439
445
|
const mockOnClick = jest.fn();
|
|
440
446
|
const {getByTestId} = renderWithTheme(
|
|
441
|
-
<Box
|
|
442
|
-
onClick={mockOnClick}
|
|
447
|
+
<Box
|
|
448
|
+
onClick={mockOnClick}
|
|
443
449
|
testID="clickable-box"
|
|
444
|
-
accessibilityLabel="Click me"
|
|
450
|
+
accessibilityLabel="Click me"
|
|
445
451
|
accessibilityHint="Tap to trigger action"
|
|
446
452
|
/>
|
|
447
453
|
);
|
|
448
|
-
|
|
454
|
+
|
|
449
455
|
const pressable = getByTestId("clickable-box-clickable");
|
|
450
456
|
await act(async () => {
|
|
451
457
|
fireEvent.press(pressable);
|
|
452
458
|
});
|
|
453
|
-
|
|
459
|
+
|
|
454
460
|
expect(mockOnClick).toHaveBeenCalledTimes(1);
|
|
455
461
|
});
|
|
456
462
|
|
|
457
463
|
it("should apply accessibility props to Pressable", () => {
|
|
458
464
|
const mockOnClick = jest.fn();
|
|
459
465
|
const {getByTestId} = renderWithTheme(
|
|
460
|
-
<Box
|
|
466
|
+
<Box
|
|
461
467
|
onClick={mockOnClick}
|
|
462
468
|
testID="accessible-box"
|
|
463
469
|
accessibilityLabel="Click me"
|
|
464
470
|
accessibilityHint="Tap to trigger action"
|
|
465
471
|
/>
|
|
466
472
|
);
|
|
467
|
-
|
|
473
|
+
|
|
468
474
|
const pressable = getByTestId("accessible-box-clickable");
|
|
469
475
|
expect(pressable).toBeTruthy();
|
|
470
476
|
// Basic check that accessibility props are being applied
|
|
@@ -513,26 +519,24 @@ describe("Box", () => {
|
|
|
513
519
|
const {getByTestId} = renderWithTheme(
|
|
514
520
|
<Box onHoverStart={mockOnHoverStart} testID="hover-box" />
|
|
515
521
|
);
|
|
516
|
-
|
|
522
|
+
|
|
517
523
|
const view = getByTestId("hover-box");
|
|
518
524
|
await act(async () => {
|
|
519
525
|
fireEvent(view, "pointerEnter");
|
|
520
526
|
});
|
|
521
|
-
|
|
527
|
+
|
|
522
528
|
expect(mockOnHoverStart).toHaveBeenCalledTimes(1);
|
|
523
529
|
});
|
|
524
530
|
|
|
525
531
|
it("should call onHoverEnd", async () => {
|
|
526
532
|
const mockOnHoverEnd = jest.fn();
|
|
527
|
-
const {getByTestId} = renderWithTheme(
|
|
528
|
-
|
|
529
|
-
);
|
|
530
|
-
|
|
533
|
+
const {getByTestId} = renderWithTheme(<Box onHoverEnd={mockOnHoverEnd} testID="hover-box" />);
|
|
534
|
+
|
|
531
535
|
const view = getByTestId("hover-box");
|
|
532
536
|
await act(async () => {
|
|
533
537
|
fireEvent(view, "pointerLeave");
|
|
534
538
|
});
|
|
535
|
-
|
|
539
|
+
|
|
536
540
|
expect(mockOnHoverEnd).toHaveBeenCalledTimes(1);
|
|
537
541
|
});
|
|
538
542
|
});
|
|
@@ -541,7 +545,7 @@ describe("Box", () => {
|
|
|
541
545
|
it("should expose scrollToEnd method", () => {
|
|
542
546
|
const ref = React.createRef<any>();
|
|
543
547
|
renderWithTheme(<Box ref={ref} scroll />);
|
|
544
|
-
|
|
548
|
+
|
|
545
549
|
expect(ref.current).toBeTruthy();
|
|
546
550
|
expect(typeof ref.current.scrollToEnd).toBe("function");
|
|
547
551
|
});
|
|
@@ -549,7 +553,7 @@ describe("Box", () => {
|
|
|
549
553
|
it("should expose scrollTo method", () => {
|
|
550
554
|
const ref = React.createRef<any>();
|
|
551
555
|
renderWithTheme(<Box ref={ref} scroll />);
|
|
552
|
-
|
|
556
|
+
|
|
553
557
|
expect(ref.current).toBeTruthy();
|
|
554
558
|
expect(typeof ref.current.scrollTo).toBe("function");
|
|
555
559
|
});
|
|
@@ -558,11 +562,11 @@ describe("Box", () => {
|
|
|
558
562
|
describe("dangerous inline styles", () => {
|
|
559
563
|
it("should apply dangerouslySetInlineStyle", () => {
|
|
560
564
|
const {root} = renderWithTheme(
|
|
561
|
-
<Box dangerouslySetInlineStyle={{
|
|
565
|
+
<Box dangerouslySetInlineStyle={{__style: {backgroundColor: "red"}}} />
|
|
562
566
|
);
|
|
563
567
|
const view = root.findByType("View");
|
|
564
568
|
expect(view.props.style).toMatchObject({
|
|
565
|
-
backgroundColor: "red"
|
|
569
|
+
backgroundColor: "red",
|
|
566
570
|
});
|
|
567
571
|
});
|
|
568
572
|
});
|
|
@@ -571,7 +575,9 @@ describe("Box", () => {
|
|
|
571
575
|
it("should warn when using wrap and alignItems together", () => {
|
|
572
576
|
const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
|
|
573
577
|
renderWithTheme(<Box wrap alignItems="center" />);
|
|
574
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
578
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
579
|
+
"React Native doesn't support wrap and alignItems together."
|
|
580
|
+
);
|
|
575
581
|
consoleSpy.mockRestore();
|
|
576
582
|
});
|
|
577
583
|
});
|
|
@@ -604,7 +610,7 @@ describe("Box", () => {
|
|
|
604
610
|
expect(view.props.style).toMatchObject({
|
|
605
611
|
padding: 0,
|
|
606
612
|
margin: 0,
|
|
607
|
-
gap: 0
|
|
613
|
+
gap: 0,
|
|
608
614
|
});
|
|
609
615
|
});
|
|
610
616
|
});
|
|
@@ -617,11 +623,11 @@ describe("Box", () => {
|
|
|
617
623
|
|
|
618
624
|
it("should match snapshot with layout props", () => {
|
|
619
625
|
const component = renderWithTheme(
|
|
620
|
-
<Box
|
|
621
|
-
direction="column"
|
|
622
|
-
flex="grow"
|
|
623
|
-
justifyContent="center"
|
|
624
|
-
alignItems="center"
|
|
626
|
+
<Box
|
|
627
|
+
direction="column"
|
|
628
|
+
flex="grow"
|
|
629
|
+
justifyContent="center"
|
|
630
|
+
alignItems="center"
|
|
625
631
|
padding={4}
|
|
626
632
|
margin={2}
|
|
627
633
|
/>
|
|
@@ -631,7 +637,7 @@ describe("Box", () => {
|
|
|
631
637
|
|
|
632
638
|
it("should match snapshot with clickable props", () => {
|
|
633
639
|
const component = renderWithTheme(
|
|
634
|
-
<Box
|
|
640
|
+
<Box
|
|
635
641
|
onClick={jest.fn()}
|
|
636
642
|
accessibilityLabel="Click me"
|
|
637
643
|
accessibilityHint="Tap to trigger action"
|
|
@@ -652,14 +658,9 @@ describe("Box", () => {
|
|
|
652
658
|
|
|
653
659
|
it("should match snapshot with border and rounding", () => {
|
|
654
660
|
const component = renderWithTheme(
|
|
655
|
-
<Box
|
|
656
|
-
border="default"
|
|
657
|
-
rounding="md"
|
|
658
|
-
color="primary"
|
|
659
|
-
shadow
|
|
660
|
-
/>
|
|
661
|
+
<Box border="default" rounding="md" color="primary" shadow />
|
|
661
662
|
);
|
|
662
663
|
expect(component.toJSON()).toMatchSnapshot();
|
|
663
664
|
});
|
|
664
665
|
});
|
|
665
|
-
});
|
|
666
|
+
});
|
package/src/Box.tsx
CHANGED
|
@@ -58,7 +58,7 @@ const isValidPercentage = (value: string): boolean => {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
const isValidWidthHeight = (value: number | string): boolean => {
|
|
61
|
-
return typeof value ===
|
|
61
|
+
return typeof value === "number" || !Number.isNaN(Number(value)) || isValidPercentage(value);
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
// eslint-disable-next-line react/display-name
|
|
@@ -153,10 +153,12 @@ export const Box = React.forwardRef((props: BoxProps, ref) => {
|
|
|
153
153
|
gap: (value) => ({gap: getSpacing(value)}),
|
|
154
154
|
height: (value) => {
|
|
155
155
|
if (!isValidWidthHeight(value)) {
|
|
156
|
-
console.warn(
|
|
156
|
+
console.warn(
|
|
157
|
+
`Box: height prop must be a number or percentage string (e.g., "50%"), received: ${value}`
|
|
158
|
+
);
|
|
157
159
|
return {};
|
|
158
160
|
}
|
|
159
|
-
if (props.border && !isNaN(Number(value))) {
|
|
161
|
+
if (props.border && !Number.isNaN(Number(value))) {
|
|
160
162
|
return {height: Number(value) + 2 * 2};
|
|
161
163
|
} else {
|
|
162
164
|
return {height: value};
|
|
@@ -210,10 +212,12 @@ export const Box = React.forwardRef((props: BoxProps, ref) => {
|
|
|
210
212
|
top: (top) => ({top: top ? 0 : undefined}),
|
|
211
213
|
width: (value) => {
|
|
212
214
|
if (!isValidWidthHeight(value)) {
|
|
213
|
-
console.warn(
|
|
215
|
+
console.warn(
|
|
216
|
+
`Box: width prop must be a number or percentage string (e.g., "50%"), received: ${value}`
|
|
217
|
+
);
|
|
214
218
|
return {};
|
|
215
219
|
}
|
|
216
|
-
if (props.border && !isNaN(Number(value))) {
|
|
220
|
+
if (props.border && !Number.isNaN(Number(value))) {
|
|
217
221
|
return {width: Number(value) + 2 * 2};
|
|
218
222
|
} else {
|
|
219
223
|
return {width: value};
|
|
@@ -221,28 +225,36 @@ export const Box = React.forwardRef((props: BoxProps, ref) => {
|
|
|
221
225
|
},
|
|
222
226
|
maxHeight: (value) => {
|
|
223
227
|
if (!isValidWidthHeight(value)) {
|
|
224
|
-
console.warn(
|
|
228
|
+
console.warn(
|
|
229
|
+
`Box: maxHeight prop must be a number or percentage string (e.g., "50%"), received: ${value}`
|
|
230
|
+
);
|
|
225
231
|
return {};
|
|
226
232
|
}
|
|
227
233
|
return {maxHeight: value};
|
|
228
234
|
},
|
|
229
235
|
maxWidth: (value) => {
|
|
230
236
|
if (!isValidWidthHeight(value)) {
|
|
231
|
-
console.warn(
|
|
237
|
+
console.warn(
|
|
238
|
+
`Box: maxWidth prop must be a number or percentage string (e.g., "50%"), received: ${value}`
|
|
239
|
+
);
|
|
232
240
|
return {};
|
|
233
241
|
}
|
|
234
242
|
return {maxWidth: value};
|
|
235
243
|
},
|
|
236
244
|
minHeight: (value) => {
|
|
237
245
|
if (!isValidWidthHeight(value)) {
|
|
238
|
-
console.warn(
|
|
246
|
+
console.warn(
|
|
247
|
+
`Box: minHeight prop must be a number or percentage string (e.g., "50%"), received: ${value}`
|
|
248
|
+
);
|
|
239
249
|
return {};
|
|
240
250
|
}
|
|
241
251
|
return {minHeight: value};
|
|
242
252
|
},
|
|
243
253
|
minWidth: (value) => {
|
|
244
254
|
if (!isValidWidthHeight(value)) {
|
|
245
|
-
console.warn(
|
|
255
|
+
console.warn(
|
|
256
|
+
`Box: minWidth prop must be a number or percentage string (e.g., "50%"), received: ${value}`
|
|
257
|
+
);
|
|
246
258
|
return {};
|
|
247
259
|
}
|
|
248
260
|
return {minWidth: value};
|
package/src/Button.tsx
CHANGED
package/src/CheckBox.tsx
CHANGED
|
@@ -32,7 +32,13 @@ export const CheckBox: FC<CheckBoxProps> = ({selected, size = "md", bgColor = "d
|
|
|
32
32
|
}}
|
|
33
33
|
>
|
|
34
34
|
{selected ? (
|
|
35
|
-
<FontAwesome6
|
|
35
|
+
<FontAwesome6
|
|
36
|
+
color={theme.surface.base}
|
|
37
|
+
name="check"
|
|
38
|
+
size={px[size].icon}
|
|
39
|
+
solid
|
|
40
|
+
selectable={undefined}
|
|
41
|
+
/>
|
|
36
42
|
) : null}
|
|
37
43
|
</View>
|
|
38
44
|
);
|
package/src/Common.ts
CHANGED
|
@@ -64,6 +64,11 @@ export interface AccordionProps extends InfoModalIconProps {
|
|
|
64
64
|
* The title of the accordion.
|
|
65
65
|
*/
|
|
66
66
|
title: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* * Callback fired when the accordion is toggled.
|
|
70
|
+
* */
|
|
71
|
+
onToggle?: (isCollapse: boolean) => void;
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
export interface BaseProfile {
|
|
@@ -303,18 +308,6 @@ export type TextColor = keyof TextTheme;
|
|
|
303
308
|
export type SurfaceColor = keyof SurfaceTheme;
|
|
304
309
|
export type BorderColor = keyof BorderTheme;
|
|
305
310
|
export type StatusColor = keyof StatusTheme;
|
|
306
|
-
// TODO: Remove ButtonColor. Buttons no longer have colors, only types (called style in Figma)
|
|
307
|
-
export type ButtonColor =
|
|
308
|
-
| "blue"
|
|
309
|
-
| "gray"
|
|
310
|
-
| "red"
|
|
311
|
-
// | "transparent"
|
|
312
|
-
| "white"
|
|
313
|
-
| "primary"
|
|
314
|
-
| "secondary"
|
|
315
|
-
| "accent"
|
|
316
|
-
| "tertiary"
|
|
317
|
-
| string;
|
|
318
311
|
|
|
319
312
|
// TODO: we may want/need to expand icon color options from just text colors.
|
|
320
313
|
export type IconColor = TextColor;
|
|
@@ -432,11 +425,11 @@ export const iconSizeToNumber = (size?: IconSize) => {
|
|
|
432
425
|
|
|
433
426
|
export type TextSize = "sm" | "md" | "lg" | "xl" | "2xl";
|
|
434
427
|
|
|
435
|
-
export
|
|
428
|
+
export interface ValueMappingItem {
|
|
436
429
|
value: number;
|
|
437
430
|
label: string;
|
|
438
431
|
size?: IconSize;
|
|
439
|
-
}
|
|
432
|
+
}
|
|
440
433
|
|
|
441
434
|
export type IconPrefix = "far" | "fas";
|
|
442
435
|
|
|
@@ -738,7 +731,7 @@ export interface HeadingProps {
|
|
|
738
731
|
children?: React.ReactNode;
|
|
739
732
|
color?: TextColor;
|
|
740
733
|
overflow?: "normal" | "breakWord"; // default "breakWord"
|
|
741
|
-
size?: "sm" | "md" | "lg" | "xl"; // default "sm"
|
|
734
|
+
size?: "sm" | "md" | "lg" | "xl" | "2xl"; // default "sm"
|
|
742
735
|
truncate?: boolean; // default false
|
|
743
736
|
testID?: string;
|
|
744
737
|
}
|
|
@@ -770,11 +763,6 @@ export interface ImageProps {
|
|
|
770
763
|
style?: any;
|
|
771
764
|
}
|
|
772
765
|
|
|
773
|
-
export interface SearchButtonProps {
|
|
774
|
-
color: ButtonColor;
|
|
775
|
-
onClick: () => void;
|
|
776
|
-
}
|
|
777
|
-
|
|
778
766
|
export interface BackButtonInterface {
|
|
779
767
|
onBack: () => void;
|
|
780
768
|
}
|
|
@@ -1786,6 +1774,11 @@ export interface ModalProps {
|
|
|
1786
1774
|
* The content of the modal.
|
|
1787
1775
|
*/
|
|
1788
1776
|
children?: React.ReactElement;
|
|
1777
|
+
/**
|
|
1778
|
+
* If true, the modal will be closed when the background is clicked.
|
|
1779
|
+
* @default false
|
|
1780
|
+
*/
|
|
1781
|
+
persistOnBackgroundClick?: boolean;
|
|
1789
1782
|
/**
|
|
1790
1783
|
* If true, the primary button will be disabled.
|
|
1791
1784
|
* @default false
|
|
@@ -2139,7 +2132,7 @@ export interface TableContextType {
|
|
|
2139
2132
|
}
|
|
2140
2133
|
|
|
2141
2134
|
export interface TableContextProviderProps extends TableContextType {
|
|
2142
|
-
children: React.
|
|
2135
|
+
children: React.ReactNode;
|
|
2143
2136
|
}
|
|
2144
2137
|
|
|
2145
2138
|
export interface TextProps {
|
package/src/DataTable.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {FontAwesome6} from "@expo/vector-icons";
|
|
2
2
|
import React, {FC, useCallback, useMemo, useRef, useState} from "react";
|
|
3
3
|
import {NativeScrollEvent, NativeSyntheticEvent, Pressable, ScrollView, View} from "react-native";
|
|
4
|
-
// @ts-ignore
|
|
5
4
|
import Markdown from "react-native-markdown-display";
|
|
6
5
|
|
|
7
6
|
import {Box} from "./Box";
|
|
@@ -18,9 +17,9 @@ import {Icon} from "./Icon";
|
|
|
18
17
|
import {InfoModalIcon} from "./InfoModalIcon";
|
|
19
18
|
import {Modal} from "./Modal";
|
|
20
19
|
import {Pagination} from "./Pagination";
|
|
21
|
-
import {TableTitle} from "./table/TableTitle";
|
|
22
20
|
import {Text} from "./Text";
|
|
23
21
|
import {useTheme} from "./Theme";
|
|
22
|
+
import {TableTitle} from "./table/TableTitle";
|
|
24
23
|
|
|
25
24
|
// TODO: Add permanent horizontal scroll bar so users with only a mouse can scroll left/right
|
|
26
25
|
// easily.
|