@bigbinary/neetoui-rn 3.0.3 → 3.1.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/README.md +29 -1
- package/lib/typescript/src/components/BottomSheet/BottomSheet.d.ts +8 -1
- package/lib/typescript/src/components/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/components/ChatInput/AttachmentsView.d.ts.map +1 -1
- package/lib/typescript/src/components/ChatInput/ChatInput.d.ts.map +1 -1
- package/lib/typescript/src/components/CheckBox/CheckBox.d.ts +7 -1
- package/lib/typescript/src/components/CheckBox/CheckBox.d.ts.map +1 -1
- package/lib/typescript/src/components/Input/Input.d.ts +12 -11
- package/lib/typescript/src/components/Input/Input.d.ts.map +1 -1
- package/lib/typescript/src/components/Input/InputFrame.d.ts +41 -0
- package/lib/typescript/src/components/Input/InputFrame.d.ts.map +1 -0
- package/lib/typescript/src/components/Input/index.d.ts +1 -0
- package/lib/typescript/src/components/Input/index.d.ts.map +1 -1
- package/lib/typescript/src/components/NeetoUIProvider/NeetoUIProvider.d.ts.map +1 -1
- package/lib/typescript/src/components/RadioButton/RadioButton.d.ts +6 -1
- package/lib/typescript/src/components/RadioButton/RadioButton.d.ts.map +1 -1
- package/lib/typescript/src/components/SearchBar/SearchBar.d.ts.map +1 -1
- package/lib/typescript/src/components/Skeleton/Skeleton.d.ts.map +1 -1
- package/lib/typescript/src/components/Typography/Typography.d.ts +5 -0
- package/lib/typescript/src/components/Typography/Typography.d.ts.map +1 -1
- package/lib/typescript/src/components/Typography/index.d.ts +1 -1
- package/lib/typescript/src/components/Typography/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/unistyles.d.ts +28 -1
- package/lib/typescript/src/unistyles.d.ts.map +1 -1
- package/lib/typescript/src/utils/scale.d.ts +22 -0
- package/lib/typescript/src/utils/scale.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/components/Alert/Alert.tsx +51 -44
- package/src/components/BottomSheet/BottomSheet.tsx +98 -55
- package/src/components/BottomSheetMenu/BottomSheetMenu.tsx +55 -48
- package/src/components/ChatInput/AttachmentsView.tsx +32 -18
- package/src/components/ChatInput/ChatInput.tsx +148 -99
- package/src/components/ChatInput/IconButton.tsx +21 -10
- package/src/components/ChatInput/MentionsInput.tsx +34 -27
- package/src/components/CheckBox/CheckBox.tsx +54 -33
- package/src/components/EmptyView/EmptyView.tsx +27 -20
- package/src/components/Header/Header.tsx +25 -18
- package/src/components/Header/ScreenHeader.tsx +17 -10
- package/src/components/Input/Input.tsx +111 -67
- package/src/components/Input/InputFrame.tsx +261 -0
- package/src/components/Input/index.ts +1 -0
- package/src/components/NeetoUIProvider/NeetoUIProvider.tsx +2 -1
- package/src/components/OnBoarding/OnBoarding.tsx +61 -54
- package/src/components/RadioButton/RadioButton.tsx +72 -31
- package/src/components/SearchBar/SearchBar.tsx +34 -26
- package/src/components/Skeleton/Skeleton.tsx +18 -11
- package/src/components/Toast/Toast.tsx +38 -31
- package/src/components/Typography/Typography.tsx +31 -2
- package/src/components/Typography/index.ts +5 -1
- package/src/index.ts +7 -2
- package/src/unistyles-init.ts +4 -0
- package/src/unistyles.ts +52 -4
- package/src/utils/scale.ts +36 -9
- package/src/types/neeto-icons-rn.d.ts +0 -33
|
@@ -7,21 +7,19 @@ import {
|
|
|
7
7
|
type ReactNode,
|
|
8
8
|
} from "react";
|
|
9
9
|
import { type TextInput, View, type TextInputProps } from "react-native";
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
SendPlane,
|
|
21
|
-
} from "@bigbinary/neeto-icons-rn";
|
|
10
|
+
import Attachment from "@bigbinary/neeto-icons-rn/icons/Attachment";
|
|
11
|
+
import BookOpen from "@bigbinary/neeto-icons-rn/icons/BookOpen";
|
|
12
|
+
import CannedResponses from "@bigbinary/neeto-icons-rn/icons/CannedResponses";
|
|
13
|
+
import ChatBubble from "@bigbinary/neeto-icons-rn/icons/ChatBubble";
|
|
14
|
+
import Down from "@bigbinary/neeto-icons-rn/icons/Down";
|
|
15
|
+
import Expand from "@bigbinary/neeto-icons-rn/icons/Expand";
|
|
16
|
+
import Forward from "@bigbinary/neeto-icons-rn/icons/Forward";
|
|
17
|
+
import Minimize from "@bigbinary/neeto-icons-rn/icons/Minimize";
|
|
18
|
+
import Notes from "@bigbinary/neeto-icons-rn/icons/Notes";
|
|
19
|
+
import SendPlane from "@bigbinary/neeto-icons-rn/icons/SendPlane";
|
|
22
20
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
23
21
|
|
|
24
|
-
import { moderateScale } from "../../utils/scale";
|
|
22
|
+
import { moderateScale, scaleFor } from "../../utils/scale";
|
|
25
23
|
import { BottomSheet } from "../BottomSheet";
|
|
26
24
|
import { Skeleton } from "../Skeleton";
|
|
27
25
|
import { Touchable } from "../Touchable";
|
|
@@ -209,7 +207,7 @@ export const ChatInput = forwardRef<ChatInputRef, ChatInputProps>(
|
|
|
209
207
|
disabled || (isForwardSelected && toEmailsForForward.length === 0);
|
|
210
208
|
|
|
211
209
|
return (
|
|
212
|
-
<View>
|
|
210
|
+
<View style={styles.root}>
|
|
213
211
|
{isLoading && (
|
|
214
212
|
<Skeleton animated height={moderateScale(2)} variant="line" />
|
|
215
213
|
)}
|
|
@@ -267,12 +265,14 @@ export const ChatInput = forwardRef<ChatInputRef, ChatInputProps>(
|
|
|
267
265
|
/>
|
|
268
266
|
)}
|
|
269
267
|
<View style={styles.toolbarDivider} />
|
|
268
|
+
{/* isActive is the selected-option tint for the three mode
|
|
269
|
+
toggles above. These two are actions, not modes, so they
|
|
270
|
+
stay at full strength like the attachment button. */}
|
|
270
271
|
{onCannedResponse &&
|
|
271
272
|
showCannedResponsesFor.includes(selectedOption) && (
|
|
272
273
|
<IconButton
|
|
273
274
|
accessibilityLabel="Canned responses"
|
|
274
275
|
Icon={CannedResponses}
|
|
275
|
-
isActive={false}
|
|
276
276
|
onPress={onCannedResponse}
|
|
277
277
|
/>
|
|
278
278
|
)}
|
|
@@ -280,7 +280,6 @@ export const ChatInput = forwardRef<ChatInputRef, ChatInputProps>(
|
|
|
280
280
|
<IconButton
|
|
281
281
|
accessibilityLabel="Articles"
|
|
282
282
|
Icon={BookOpen}
|
|
283
|
-
isActive={false}
|
|
284
283
|
onPress={onArticles}
|
|
285
284
|
/>
|
|
286
285
|
)}
|
|
@@ -292,49 +291,59 @@ export const ChatInput = forwardRef<ChatInputRef, ChatInputProps>(
|
|
|
292
291
|
/>
|
|
293
292
|
</View>
|
|
294
293
|
<View style={styles.toolbarGroup}>
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
294
|
+
{/* Both actions share one filled pill, split by a divider, as
|
|
295
|
+
on web. The send affordance is the plane alone on a reply;
|
|
296
|
+
note and forward keep their labels. */}
|
|
297
|
+
<View
|
|
299
298
|
style={[
|
|
300
|
-
styles.
|
|
301
|
-
isActionDisabled && styles.
|
|
299
|
+
styles.sendGroup,
|
|
300
|
+
isActionDisabled && styles.sendGroupDisabled,
|
|
302
301
|
]}
|
|
303
|
-
onPress={() => handleAction()}
|
|
304
302
|
>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
size={
|
|
314
|
-
|
|
303
|
+
<Touchable
|
|
304
|
+
accessibilityLabel="Send"
|
|
305
|
+
accessibilityRole="button"
|
|
306
|
+
disabled={isActionDisabled}
|
|
307
|
+
style={styles.sendAction}
|
|
308
|
+
onPress={() => handleAction()}
|
|
309
|
+
>
|
|
310
|
+
{!!ACTION_LABELS[selectedOption] && (
|
|
311
|
+
<Typography size="m" style={styles.sendLabel}>
|
|
312
|
+
{ACTION_LABELS[selectedOption]}
|
|
313
|
+
</Typography>
|
|
314
|
+
)}
|
|
315
|
+
{isReplySelected && (
|
|
316
|
+
<SendPlane
|
|
317
|
+
color={theme.colors.text.inverse}
|
|
318
|
+
size={moderateScale(20)}
|
|
319
|
+
/>
|
|
320
|
+
)}
|
|
321
|
+
</Touchable>
|
|
322
|
+
{showReplyMenuOptions && isReplySelected && (
|
|
323
|
+
<>
|
|
324
|
+
<View style={styles.sendGroupDivider} />
|
|
325
|
+
<Touchable
|
|
326
|
+
accessibilityLabel="More reply options"
|
|
327
|
+
accessibilityRole="button"
|
|
328
|
+
disabled={disabled}
|
|
329
|
+
style={styles.sendMenu}
|
|
330
|
+
onPress={() => setIsReplyMenuVisible(true)}
|
|
331
|
+
>
|
|
332
|
+
<Down
|
|
333
|
+
color={theme.colors.text.inverse}
|
|
334
|
+
size={moderateScale(20)}
|
|
335
|
+
/>
|
|
336
|
+
</Touchable>
|
|
337
|
+
</>
|
|
315
338
|
)}
|
|
316
|
-
</
|
|
339
|
+
</View>
|
|
317
340
|
{showReplyMenuOptions && isReplySelected && (
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
onPress={() => setIsReplyMenuVisible(true)}
|
|
325
|
-
>
|
|
326
|
-
<Down
|
|
327
|
-
color={theme.colors.text.primary}
|
|
328
|
-
size={moderateScale(22)}
|
|
329
|
-
/>
|
|
330
|
-
</Touchable>
|
|
331
|
-
<BottomSheet
|
|
332
|
-
data={["Send and set as closed"]}
|
|
333
|
-
hide={() => setIsReplyMenuVisible(false)}
|
|
334
|
-
isVisible={isReplyMenuVisible}
|
|
335
|
-
onItemPress={() => handleAction({ status: "closed" })}
|
|
336
|
-
/>
|
|
337
|
-
</>
|
|
341
|
+
<BottomSheet
|
|
342
|
+
data={["Send and set as closed"]}
|
|
343
|
+
hide={() => setIsReplyMenuVisible(false)}
|
|
344
|
+
isVisible={isReplyMenuVisible}
|
|
345
|
+
onItemPress={() => handleAction({ status: "closed" })}
|
|
346
|
+
/>
|
|
338
347
|
)}
|
|
339
348
|
</View>
|
|
340
349
|
</View>
|
|
@@ -346,48 +355,88 @@ export const ChatInput = forwardRef<ChatInputRef, ChatInputProps>(
|
|
|
346
355
|
|
|
347
356
|
ChatInput.displayName = "ChatInput";
|
|
348
357
|
|
|
349
|
-
const styles = StyleSheet.create(theme =>
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
358
|
+
const styles = StyleSheet.create((theme, rt) => {
|
|
359
|
+
// Reading rt.screen registers the dependency that has this sheet
|
|
360
|
+
// recomputed on a window resize, so scaled sizes follow rotation,
|
|
361
|
+
// split-screen and foldables instead of freezing at first render.
|
|
362
|
+
const moderateScale = scaleFor(rt.screen);
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
// A caller that caps this composer's height (desk clamps it to a share
|
|
366
|
+
// of the screen) would otherwise have Yoga keep every child at its
|
|
367
|
+
// natural height and let overflow clip the last one — the toolbar.
|
|
368
|
+
// Declaring what may shrink makes the text area absorb the squeeze
|
|
369
|
+
// instead, so the actions stay reachable however tall the attachments
|
|
370
|
+
// and typed content get.
|
|
371
|
+
root: {
|
|
372
|
+
flexShrink: 1,
|
|
373
|
+
},
|
|
374
|
+
container: {
|
|
375
|
+
flexShrink: 1,
|
|
376
|
+
paddingBottom: moderateScale(5),
|
|
377
|
+
paddingHorizontal: moderateScale(16),
|
|
378
|
+
},
|
|
379
|
+
noteSurface: {
|
|
380
|
+
backgroundColor: theme.colors.background.oldLace,
|
|
381
|
+
},
|
|
382
|
+
inputRow: {
|
|
383
|
+
flexDirection: "row",
|
|
384
|
+
flexShrink: 1,
|
|
385
|
+
justifyContent: "space-between",
|
|
386
|
+
},
|
|
387
|
+
expandButton: {
|
|
388
|
+
alignSelf: "center",
|
|
389
|
+
},
|
|
390
|
+
toolbar: {
|
|
391
|
+
alignItems: "center",
|
|
392
|
+
flexDirection: "row",
|
|
393
|
+
flexShrink: 0,
|
|
394
|
+
justifyContent: "space-between",
|
|
395
|
+
marginTop: moderateScale(10),
|
|
396
|
+
},
|
|
397
|
+
toolbarGroup: {
|
|
398
|
+
alignItems: "center",
|
|
399
|
+
flexDirection: "row",
|
|
400
|
+
},
|
|
401
|
+
toolbarDivider: {
|
|
402
|
+
alignSelf: "stretch",
|
|
403
|
+
backgroundColor: theme.colors.palette.grey400,
|
|
404
|
+
marginHorizontal: moderateScale(5),
|
|
405
|
+
width: moderateScale(2),
|
|
406
|
+
},
|
|
407
|
+
sendGroup: {
|
|
408
|
+
alignItems: "center",
|
|
409
|
+
backgroundColor: theme.colors.primary,
|
|
410
|
+
borderRadius: moderateScale(8),
|
|
411
|
+
flexDirection: "row",
|
|
412
|
+
// Clips the divider to the rounded corners.
|
|
413
|
+
overflow: "hidden",
|
|
414
|
+
},
|
|
415
|
+
sendGroupDisabled: {
|
|
416
|
+
opacity: 0.5,
|
|
417
|
+
},
|
|
418
|
+
sendAction: {
|
|
419
|
+
alignItems: "center",
|
|
420
|
+
flexDirection: "row",
|
|
421
|
+
gap: moderateScale(6),
|
|
422
|
+
justifyContent: "center",
|
|
423
|
+
minHeight: moderateScale(34),
|
|
424
|
+
paddingHorizontal: moderateScale(12),
|
|
425
|
+
},
|
|
426
|
+
sendGroupDivider: {
|
|
427
|
+
alignSelf: "stretch",
|
|
428
|
+
backgroundColor: theme.colors.white,
|
|
429
|
+
opacity: 0.3,
|
|
430
|
+
width: moderateScale(1),
|
|
431
|
+
},
|
|
432
|
+
sendMenu: {
|
|
433
|
+
alignItems: "center",
|
|
434
|
+
justifyContent: "center",
|
|
435
|
+
minHeight: moderateScale(34),
|
|
436
|
+
paddingHorizontal: moderateScale(8),
|
|
437
|
+
},
|
|
438
|
+
sendLabel: {
|
|
439
|
+
color: theme.colors.text.inverse,
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
});
|
|
@@ -2,7 +2,7 @@ import { type ComponentType } from "react";
|
|
|
2
2
|
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
3
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
4
4
|
|
|
5
|
-
import { moderateScale } from "../../utils/scale";
|
|
5
|
+
import { moderateScale, scaleFor } from "../../utils/scale";
|
|
6
6
|
import { Touchable } from "../Touchable";
|
|
7
7
|
|
|
8
8
|
type IconButtonProps = {
|
|
@@ -40,13 +40,24 @@ export const IconButton = ({
|
|
|
40
40
|
);
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
const styles = StyleSheet.create({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
const styles = StyleSheet.create((_theme, rt) => {
|
|
44
|
+
// Reading rt.screen registers the dependency that has this sheet
|
|
45
|
+
// recomputed on a window resize, so scaled sizes follow rotation,
|
|
46
|
+
// split-screen and foldables instead of freezing at first render.
|
|
47
|
+
const moderateScale = scaleFor(rt.screen);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
container: {
|
|
51
|
+
alignItems: "center",
|
|
52
|
+
justifyContent: "center",
|
|
53
|
+
// Adjacent buttons each contribute their padding, so this is half the
|
|
54
|
+
// gap between two icons. Vertical padding buys back some of the touch
|
|
55
|
+
// target the tighter sides give up.
|
|
56
|
+
paddingHorizontal: moderateScale(4),
|
|
57
|
+
paddingVertical: moderateScale(4),
|
|
58
|
+
},
|
|
59
|
+
inactive: {
|
|
60
|
+
opacity: 0.5,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
52
63
|
});
|
|
@@ -3,7 +3,7 @@ import { ScrollView, TextInput, View, type TextInputProps } from "react-native";
|
|
|
3
3
|
import { useMentions } from "react-native-controlled-mentions";
|
|
4
4
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { scaleFor } from "../../utils/scale";
|
|
7
7
|
import { Avatar } from "../Avatar";
|
|
8
8
|
import { Touchable } from "../Touchable";
|
|
9
9
|
import { Typography } from "../Typography";
|
|
@@ -98,29 +98,36 @@ export const MentionsInput = ({
|
|
|
98
98
|
);
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
const styles = StyleSheet.create(theme =>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
101
|
+
const styles = StyleSheet.create((theme, rt) => {
|
|
102
|
+
// Reading rt.screen registers the dependency that has this sheet
|
|
103
|
+
// recomputed on a window resize, so scaled sizes follow rotation,
|
|
104
|
+
// split-screen and foldables instead of freezing at first render.
|
|
105
|
+
const moderateScale = scaleFor(rt.screen);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
container: {
|
|
109
|
+
flex: 1,
|
|
110
|
+
marginVertical: moderateScale(10),
|
|
111
|
+
},
|
|
112
|
+
suggestionsCard: {
|
|
113
|
+
backgroundColor: theme.colors.background.secondary,
|
|
114
|
+
borderRadius: moderateScale(10),
|
|
115
|
+
maxHeight: moderateScale(200),
|
|
116
|
+
...theme.elevation.medium,
|
|
117
|
+
},
|
|
118
|
+
suggestionRow: {
|
|
119
|
+
alignItems: "center",
|
|
120
|
+
flexDirection: "row",
|
|
121
|
+
gap: moderateScale(8),
|
|
122
|
+
height: moderateScale(50),
|
|
123
|
+
paddingHorizontal: moderateScale(10),
|
|
124
|
+
},
|
|
125
|
+
input: {
|
|
126
|
+
color: theme.colors.text.primary,
|
|
127
|
+
fontFamily: theme.fonts.regular,
|
|
128
|
+
fontSize: theme.fontSizes.m,
|
|
129
|
+
minHeight: moderateScale(50),
|
|
130
|
+
padding: 0,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
});
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
CheckboxInactive,
|
|
4
|
-
} from "@bigbinary/neeto-icons-rn";
|
|
1
|
+
import CheckboxIcon from "@bigbinary/neeto-icons-rn/icons/Checkbox";
|
|
2
|
+
import CheckboxInactive from "@bigbinary/neeto-icons-rn/icons/CheckboxInactive";
|
|
5
3
|
import { type StyleProp, type TextStyle } from "react-native";
|
|
6
4
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
7
5
|
|
|
8
|
-
import { moderateScale } from "../../utils/scale";
|
|
6
|
+
import { moderateScale, scaleFor } from "../../utils/scale";
|
|
9
7
|
import { Touchable, type TouchableProps } from "../Touchable";
|
|
10
8
|
import { Typography } from "../Typography";
|
|
11
9
|
|
|
@@ -16,6 +14,12 @@ export type CheckBoxProps = Omit<TouchableProps, "onPress"> & {
|
|
|
16
14
|
label: string;
|
|
17
15
|
labelStyle?: StyleProp<TextStyle>;
|
|
18
16
|
isRequiredLabel?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Ties the label's emphasis to the checked state: dimmed when unchecked,
|
|
19
|
+
* semibold when checked. Turn it off where the label names the field
|
|
20
|
+
* rather than the choice — an unchecked one then reads as disabled.
|
|
21
|
+
*/
|
|
22
|
+
dimsUncheckedLabel?: boolean;
|
|
19
23
|
iconSize?: number;
|
|
20
24
|
};
|
|
21
25
|
|
|
@@ -26,13 +30,17 @@ export const CheckBox = ({
|
|
|
26
30
|
label,
|
|
27
31
|
labelStyle,
|
|
28
32
|
isRequiredLabel = false,
|
|
33
|
+
dimsUncheckedLabel = true,
|
|
29
34
|
iconSize,
|
|
30
35
|
style,
|
|
31
36
|
...rest
|
|
32
37
|
}: CheckBoxProps) => {
|
|
33
38
|
const { theme } = useUnistyles();
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
const emphasis = checked ? "emphasized" : "dim";
|
|
41
|
+
const labelState = dimsUncheckedLabel ? emphasis : "plain";
|
|
42
|
+
|
|
43
|
+
styles.useVariants({ labelState, disabled });
|
|
36
44
|
|
|
37
45
|
const Icon = checked ? CheckboxIcon : CheckboxInactive;
|
|
38
46
|
|
|
@@ -45,42 +53,55 @@ export const CheckBox = ({
|
|
|
45
53
|
onPress={onSelect}
|
|
46
54
|
{...rest}
|
|
47
55
|
>
|
|
48
|
-
<Typography size="m" style={[styles.label, labelStyle]}>
|
|
49
|
-
{isRequiredLabel ? `${label}*` : label}
|
|
50
|
-
</Typography>
|
|
51
56
|
<Icon
|
|
52
57
|
color={theme.colors.text.primary}
|
|
53
58
|
size={iconSize ?? moderateScale(22)}
|
|
54
59
|
/>
|
|
60
|
+
<Typography size="m" style={[styles.label, labelStyle]}>
|
|
61
|
+
{isRequiredLabel ? `${label}*` : label}
|
|
62
|
+
</Typography>
|
|
55
63
|
</Touchable>
|
|
56
64
|
);
|
|
57
65
|
};
|
|
58
66
|
|
|
59
|
-
const styles = StyleSheet.create(theme =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
const styles = StyleSheet.create((theme, rt) => {
|
|
68
|
+
// Reading rt.screen registers the dependency that has this sheet
|
|
69
|
+
// recomputed on a window resize, so scaled sizes follow rotation,
|
|
70
|
+
// split-screen and foldables instead of freezing at first render.
|
|
71
|
+
const moderateScale = scaleFor(rt.screen);
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
container: {
|
|
75
|
+
alignItems: "center",
|
|
76
|
+
flexDirection: "row",
|
|
77
|
+
flexShrink: 1,
|
|
78
|
+
gap: moderateScale(8),
|
|
79
|
+
paddingVertical: moderateScale(8),
|
|
80
|
+
},
|
|
81
|
+
label: {
|
|
82
|
+
flex: 1,
|
|
83
|
+
lineHeight: moderateScale(22),
|
|
84
|
+
variants: {
|
|
85
|
+
labelState: {
|
|
86
|
+
emphasized: {
|
|
87
|
+
color: theme.colors.text.primary,
|
|
88
|
+
fontFamily: theme.fonts.semibold,
|
|
89
|
+
},
|
|
90
|
+
dim: {
|
|
91
|
+
color: theme.colors.palette.grey400,
|
|
92
|
+
fontFamily: theme.fonts.regular,
|
|
93
|
+
},
|
|
94
|
+
plain: {
|
|
95
|
+
color: theme.colors.text.primary,
|
|
96
|
+
fontFamily: theme.fonts.regular,
|
|
97
|
+
},
|
|
98
|
+
default: {},
|
|
74
99
|
},
|
|
75
|
-
|
|
76
|
-
color: theme.colors.palette.grey400,
|
|
77
|
-
|
|
100
|
+
disabled: {
|
|
101
|
+
true: { color: theme.colors.palette.grey400 },
|
|
102
|
+
false: {},
|
|
78
103
|
},
|
|
79
104
|
},
|
|
80
|
-
disabled: {
|
|
81
|
-
true: { color: theme.colors.palette.grey400 },
|
|
82
|
-
false: {},
|
|
83
|
-
},
|
|
84
105
|
},
|
|
85
|
-
}
|
|
86
|
-
})
|
|
106
|
+
};
|
|
107
|
+
});
|
|
@@ -2,7 +2,7 @@ import { type ComponentType, type ReactNode } from "react";
|
|
|
2
2
|
import { View, type StyleProp, type ViewStyle } from "react-native";
|
|
3
3
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
4
4
|
|
|
5
|
-
import { moderateScale } from "../../utils/scale";
|
|
5
|
+
import { moderateScale, scaleFor } from "../../utils/scale";
|
|
6
6
|
import { Button } from "../Button";
|
|
7
7
|
import { Typography } from "../Typography";
|
|
8
8
|
|
|
@@ -59,22 +59,29 @@ export const EmptyView = ({
|
|
|
59
59
|
);
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
const styles = StyleSheet.create(theme =>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
62
|
+
const styles = StyleSheet.create((theme, rt) => {
|
|
63
|
+
// Reading rt.screen registers the dependency that has this sheet
|
|
64
|
+
// recomputed on a window resize, so scaled sizes follow rotation,
|
|
65
|
+
// split-screen and foldables instead of freezing at first render.
|
|
66
|
+
const moderateScale = scaleFor(rt.screen);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
container: {
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
gap: moderateScale(16),
|
|
72
|
+
justifyContent: "center",
|
|
73
|
+
paddingHorizontal: moderateScale(24),
|
|
74
|
+
paddingVertical: moderateScale(32),
|
|
75
|
+
},
|
|
76
|
+
textBlock: {
|
|
77
|
+
alignItems: "center",
|
|
78
|
+
gap: moderateScale(4),
|
|
79
|
+
},
|
|
80
|
+
centered: {
|
|
81
|
+
textAlign: "center",
|
|
82
|
+
},
|
|
83
|
+
description: {
|
|
84
|
+
color: theme.colors.text.muted,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
});
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
type ReactNode,
|
|
6
6
|
} from "react";
|
|
7
7
|
import { View } from "react-native";
|
|
8
|
-
import
|
|
8
|
+
import LeftArrow from "@bigbinary/neeto-icons-rn/icons/LeftArrow";
|
|
9
9
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
10
10
|
|
|
11
|
-
import { moderateScale } from "../../utils/scale";
|
|
11
|
+
import { moderateScale, scaleFor } from "../../utils/scale";
|
|
12
12
|
import { Skeleton } from "../Skeleton";
|
|
13
13
|
import { Touchable } from "../Touchable";
|
|
14
14
|
import { Typography } from "../Typography";
|
|
@@ -96,19 +96,26 @@ export const Header = ({
|
|
|
96
96
|
);
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
const styles = StyleSheet.create(theme =>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
99
|
+
const styles = StyleSheet.create((theme, rt) => {
|
|
100
|
+
// Reading rt.screen registers the dependency that has this sheet
|
|
101
|
+
// recomputed on a window resize, so scaled sizes follow rotation,
|
|
102
|
+
// split-screen and foldables instead of freezing at first render.
|
|
103
|
+
const moderateScale = scaleFor(rt.screen);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
container: {
|
|
107
|
+
gap: moderateScale(8),
|
|
108
|
+
minHeight: moderateScale(48),
|
|
109
|
+
paddingHorizontal: moderateScale(16),
|
|
110
|
+
},
|
|
111
|
+
backButton: {
|
|
112
|
+
marginLeft: moderateScale(-8),
|
|
113
|
+
},
|
|
114
|
+
titleBlock: {
|
|
115
|
+
flex: 1,
|
|
116
|
+
},
|
|
117
|
+
subTitle: {
|
|
118
|
+
color: theme.colors.text.muted,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
});
|