@ecohouse/ui 0.1.59 → 0.1.61
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/index.cjs +665 -468
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -12
- package/dist/index.d.ts +33 -12
- package/dist/index.js +558 -366
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Button/Button.tsx +6 -2
- package/src/components/CommentCard/CommentCard.tsx +3 -0
- package/src/components/Counter/Counter.tsx +5 -3
- package/src/components/DatePicker/DatePicker.tsx +98 -40
- package/src/components/Range/Range.tsx +1 -1
- package/src/components/VerificationCodeInput/VerificationCodeInput.tsx +28 -4
- package/src/icons/Backspace/BackspaceIcon.test.ts +9 -0
- package/src/icons/Backspace/BackspaceIcon.tsx +20 -0
- package/src/icons/Backspace/BackspaceIcon.web.tsx +26 -0
- package/src/icons/Backspace/backspacePath.ts +3 -0
- package/src/icons/Backspace/index.ts +1 -0
- package/src/icons/Fingerprint/FingerprintIcon.test.ts +9 -0
- package/src/icons/Fingerprint/FingerprintIcon.tsx +23 -0
- package/src/icons/Fingerprint/FingerprintIcon.web.tsx +29 -0
- package/src/icons/Fingerprint/fingerprintPaths.ts +6 -0
- package/src/icons/Fingerprint/index.ts +1 -0
- package/src/icons/GoogleBrand/GoogleBrandIcon.test.ts +14 -0
- package/src/icons/GoogleBrand/GoogleBrandIcon.tsx +15 -0
- package/src/icons/GoogleBrand/GoogleBrandIcon.web.tsx +21 -0
- package/src/icons/GoogleBrand/googleBrandPaths.ts +18 -0
- package/src/icons/GoogleBrand/index.ts +1 -0
- package/src/icons/PaymentCard/PaymentCardIcon.tsx +14 -0
- package/src/icons/PaymentCard/PaymentCardIcon.web.tsx +13 -0
- package/src/icons/PaymentCard/index.ts +1 -0
- package/src/icons/PaymentCard/paymentCardPath.ts +3 -0
- package/src/icons/Receipt/ReceiptIcon.tsx +14 -0
- package/src/icons/Receipt/ReceiptIcon.web.tsx +13 -0
- package/src/icons/Receipt/index.ts +1 -0
- package/src/icons/Receipt/receiptPath.ts +3 -0
- package/src/icons/index.ts +5 -0
- package/src/icons/registry.ts +13 -1
- package/src/index.ts +5 -0
- package/src/theme/typography.ts +8 -8
- package/src/utils/dateUtils.ts +7 -4
package/package.json
CHANGED
|
@@ -259,9 +259,13 @@ const styles = StyleSheet.create({
|
|
|
259
259
|
contentWithoutIcon: {
|
|
260
260
|
justifyContent: "center",
|
|
261
261
|
},
|
|
262
|
-
label: {
|
|
262
|
+
label: {
|
|
263
|
+
flexShrink: 0,
|
|
264
|
+
overflow: "visible",
|
|
265
|
+
paddingRight: 4,
|
|
266
|
+
},
|
|
263
267
|
labelAndroid: {
|
|
264
|
-
includeFontPadding:
|
|
268
|
+
includeFontPadding: true,
|
|
265
269
|
},
|
|
266
270
|
labelCentered: {
|
|
267
271
|
textAlign: "center",
|
|
@@ -29,6 +29,7 @@ export interface CommentCardProps extends Omit<ViewProps, "style" | "children">
|
|
|
29
29
|
onExpandedChange?: (expanded: boolean) => void;
|
|
30
30
|
style?: StyleProp<ViewStyle>;
|
|
31
31
|
commentStyle?: StyleProp<TextStyle>;
|
|
32
|
+
actionStyle?: StyleProp<TextStyle>;
|
|
32
33
|
className?: string;
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -51,6 +52,7 @@ export const CommentCard = forwardRef<ComponentRef<typeof View>, CommentCardProp
|
|
|
51
52
|
onExpandedChange,
|
|
52
53
|
style,
|
|
53
54
|
commentStyle,
|
|
55
|
+
actionStyle,
|
|
54
56
|
className,
|
|
55
57
|
...rest
|
|
56
58
|
},
|
|
@@ -128,6 +130,7 @@ export const CommentCard = forwardRef<ComponentRef<typeof View>, CommentCardProp
|
|
|
128
130
|
<Text
|
|
129
131
|
style={[
|
|
130
132
|
styles.actionText,
|
|
133
|
+
actionStyle,
|
|
131
134
|
expanded && styles.closeActionText,
|
|
132
135
|
actionHovered &&
|
|
133
136
|
(expanded ? styles.closeActionTextHovered : styles.openActionTextHovered),
|
|
@@ -91,7 +91,7 @@ export const Counter = forwardRef<ComponentRef<typeof View>, CounterProps>(funct
|
|
|
91
91
|
accessibilityState={{ disabled: decrementDisabled }}
|
|
92
92
|
style={[styles.button, webBlurStyle, decrementDisabled && styles.buttonDisabled]}
|
|
93
93
|
>
|
|
94
|
-
<MinusIcon />
|
|
94
|
+
<MinusIcon color={colors.white} strokeWidth={2} />
|
|
95
95
|
</Pressable>
|
|
96
96
|
);
|
|
97
97
|
const increment = (
|
|
@@ -104,7 +104,7 @@ export const Counter = forwardRef<ComponentRef<typeof View>, CounterProps>(funct
|
|
|
104
104
|
accessibilityState={{ disabled: incrementDisabled }}
|
|
105
105
|
style={[styles.button, webBlurStyle, incrementDisabled && styles.buttonDisabled]}
|
|
106
106
|
>
|
|
107
|
-
<PlusIcon />
|
|
107
|
+
<PlusIcon color={colors.white} strokeWidth={2} />
|
|
108
108
|
</Pressable>
|
|
109
109
|
);
|
|
110
110
|
const valueNode = (
|
|
@@ -141,7 +141,7 @@ const styles = StyleSheet.create({
|
|
|
141
141
|
flexDirection: "row",
|
|
142
142
|
alignItems: "center",
|
|
143
143
|
alignSelf: "flex-start",
|
|
144
|
-
gap:
|
|
144
|
+
gap: 16,
|
|
145
145
|
},
|
|
146
146
|
valueFirst: {
|
|
147
147
|
alignSelf: "stretch",
|
|
@@ -153,9 +153,11 @@ const styles = StyleSheet.create({
|
|
|
153
153
|
height: BUTTON_SIZE,
|
|
154
154
|
alignItems: "center",
|
|
155
155
|
justifyContent: "center",
|
|
156
|
+
padding: 8,
|
|
156
157
|
borderWidth: 1,
|
|
157
158
|
borderColor: colors.whiteAlpha10,
|
|
158
159
|
borderRadius: 39,
|
|
160
|
+
opacity: 1,
|
|
159
161
|
},
|
|
160
162
|
buttonDisabled: {
|
|
161
163
|
opacity: 0.25,
|
|
@@ -75,6 +75,8 @@ const EMPTY_RANGE: DateRange = { start: null, end: null };
|
|
|
75
75
|
|
|
76
76
|
type DatePickerBaseProps = Omit<ViewProps, "style" | "children"> & {
|
|
77
77
|
placeholder?: string;
|
|
78
|
+
/** Color for the trigger label when no date is selected. Defaults to grey100. */
|
|
79
|
+
placeholderTextColor?: string;
|
|
78
80
|
/** Trigger presentation. Range variants display separate start/end fields. */
|
|
79
81
|
variant?: DatePickerVariant;
|
|
80
82
|
/** Labels shown above the start/end values in range trigger variants. */
|
|
@@ -116,7 +118,10 @@ type DatePickerBaseProps = Omit<ViewProps, "style" | "children"> & {
|
|
|
116
118
|
formatValue?: (date: Date) => string;
|
|
117
119
|
/** First day of the week column (0 = Sunday, 1 = Monday). Defaults to Monday. */
|
|
118
120
|
weekStartsOn?: 0 | 1;
|
|
119
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Styles the calendar popup independently from the trigger width.
|
|
123
|
+
* With `hideTrigger`, `width: "100%"` stretches the day grid to the host.
|
|
124
|
+
*/
|
|
120
125
|
calendarStyle?: StyleProp<ViewStyle>;
|
|
121
126
|
/**
|
|
122
127
|
* When true, only the calendar panel is rendered (no field/trigger).
|
|
@@ -144,8 +149,7 @@ export type DatePickerRangeProps = DatePickerBaseProps & {
|
|
|
144
149
|
export type DatePickerProps = DatePickerSingleProps | DatePickerRangeProps;
|
|
145
150
|
|
|
146
151
|
const DEFAULT_WIDTH = 320;
|
|
147
|
-
const
|
|
148
|
-
const MENU_CONTENT_WIDTH = 296;
|
|
152
|
+
const MENU_CONTENT_WIDTH = 308;
|
|
149
153
|
const RANGE_TRIGGER_WIDTH = 382;
|
|
150
154
|
const TRIGGER_HEIGHT = 44;
|
|
151
155
|
const TRIGGER_RADIUS = 60;
|
|
@@ -157,10 +161,10 @@ const HEADER_HEIGHT = 36;
|
|
|
157
161
|
const WEEKDAY_ROW_HEIGHT = 44;
|
|
158
162
|
const WEEKDAY_ROW_GAP = 8;
|
|
159
163
|
const WEEK_ROW_GAP = 16;
|
|
160
|
-
const DAY_CELL_WIDTH =
|
|
164
|
+
const DAY_CELL_WIDTH = 44;
|
|
161
165
|
const DAY_CELL_HEIGHT = 44;
|
|
162
|
-
const
|
|
163
|
-
const
|
|
166
|
+
const DAY_CIRCLE_SIZE = 44;
|
|
167
|
+
const DAY_CELL_RADIUS = 22;
|
|
164
168
|
|
|
165
169
|
function RangeTriggerField({
|
|
166
170
|
label,
|
|
@@ -193,6 +197,7 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
193
197
|
function DatePicker(props, forwardedRef) {
|
|
194
198
|
const {
|
|
195
199
|
placeholder = "Select date",
|
|
200
|
+
placeholderTextColor = colors.grey100,
|
|
196
201
|
variant = "default",
|
|
197
202
|
startLabel = "Start",
|
|
198
203
|
endLabel = "End",
|
|
@@ -457,11 +462,16 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
457
462
|
: isOpen
|
|
458
463
|
? colors.primaryMuted
|
|
459
464
|
: colors.grey700;
|
|
460
|
-
const triggerTextColor = hasValue ? colors.white :
|
|
465
|
+
const triggerTextColor = hasValue || isOpen ? colors.white : placeholderTextColor;
|
|
466
|
+
const triggerIconColor = isOpen ? colors.white : colors.grey150;
|
|
461
467
|
const startValue = rangeValue.start ? formatValue(rangeValue.start) : startPlaceholder;
|
|
462
468
|
const endValue = rangeValue.end ? formatValue(rangeValue.end) : endPlaceholder;
|
|
463
469
|
|
|
464
470
|
const resolvedAccessibilityLabel = accessibilityLabel ?? placeholder;
|
|
471
|
+
const stretchCalendar =
|
|
472
|
+
hideTrigger &&
|
|
473
|
+
(StyleSheet.flatten(calendarStyle)?.width === "100%" ||
|
|
474
|
+
StyleSheet.flatten(style)?.width === "100%");
|
|
465
475
|
|
|
466
476
|
return (
|
|
467
477
|
<View
|
|
@@ -471,13 +481,20 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
471
481
|
styles.root,
|
|
472
482
|
usesRangeTrigger && styles.rangeRoot,
|
|
473
483
|
hideTrigger && styles.rootHideTrigger,
|
|
484
|
+
stretchCalendar && styles.rootFullWidth,
|
|
474
485
|
isOpen && styles.rootOpen,
|
|
475
486
|
disabled && styles.disabled,
|
|
476
487
|
style,
|
|
477
488
|
]}
|
|
478
489
|
accessibilityState={{ disabled, expanded: isOpen }}
|
|
479
490
|
>
|
|
480
|
-
<View
|
|
491
|
+
<View
|
|
492
|
+
style={[
|
|
493
|
+
styles.triggerWrap,
|
|
494
|
+
isOpen && styles.triggerWrapOpen,
|
|
495
|
+
stretchCalendar && styles.triggerWrapFullWidth,
|
|
496
|
+
]}
|
|
497
|
+
>
|
|
481
498
|
{hideTrigger ? null : (
|
|
482
499
|
<Pressable
|
|
483
500
|
ref={triggerRef}
|
|
@@ -517,7 +534,7 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
517
534
|
{triggerLabel}
|
|
518
535
|
</Text>
|
|
519
536
|
<View style={styles.iconSlot}>
|
|
520
|
-
<CalendarOutlineIcon size={ICON_SIZE} color={
|
|
537
|
+
<CalendarOutlineIcon size={ICON_SIZE} color={triggerIconColor} />
|
|
521
538
|
</View>
|
|
522
539
|
</>
|
|
523
540
|
)}
|
|
@@ -531,14 +548,17 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
531
548
|
usesRangeTrigger && styles.rangeMenu,
|
|
532
549
|
hideTrigger
|
|
533
550
|
? styles.menuInline
|
|
534
|
-
: menuAlignEnd
|
|
551
|
+
: Platform.OS !== "web" || menuAlignEnd
|
|
535
552
|
? styles.menuAlignEnd
|
|
536
553
|
: styles.menuAlignStart,
|
|
537
|
-
calendarStyle,
|
|
538
554
|
styles.menuFitContent,
|
|
555
|
+
stretchCalendar && styles.menuFullWidth,
|
|
556
|
+
calendarStyle,
|
|
539
557
|
]}
|
|
540
558
|
>
|
|
541
|
-
<View
|
|
559
|
+
<View
|
|
560
|
+
style={[styles.calendarHeader, stretchCalendar && styles.calendarSectionFullWidth]}
|
|
561
|
+
>
|
|
542
562
|
<Pressable
|
|
543
563
|
onPress={handlePrevMonth}
|
|
544
564
|
hitSlop={8}
|
|
@@ -566,10 +586,17 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
566
586
|
</Pressable>
|
|
567
587
|
</View>
|
|
568
588
|
|
|
569
|
-
<View
|
|
570
|
-
|
|
589
|
+
<View
|
|
590
|
+
style={[styles.calendarGrid, stretchCalendar && styles.calendarSectionFullWidth]}
|
|
591
|
+
>
|
|
592
|
+
<View
|
|
593
|
+
style={[styles.weekdayRow, stretchCalendar && styles.calendarSectionFullWidth]}
|
|
594
|
+
>
|
|
571
595
|
{weekdayLabels.map((weekdayLabel, index) => (
|
|
572
|
-
<View
|
|
596
|
+
<View
|
|
597
|
+
key={`${weekdayLabel}-${index}`}
|
|
598
|
+
style={[styles.weekdayCell, stretchCalendar && styles.dayCellFullWidth]}
|
|
599
|
+
>
|
|
573
600
|
<Text style={styles.weekdayText}>{weekdayLabel}</Text>
|
|
574
601
|
</View>
|
|
575
602
|
))}
|
|
@@ -590,21 +617,9 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
590
617
|
if (rangeIndices.length > 0) {
|
|
591
618
|
const first = rangeIndices[0];
|
|
592
619
|
const last = rangeIndices[rangeIndices.length - 1];
|
|
593
|
-
const startsHere = isSameDay(week[first], rangeValue.start);
|
|
594
|
-
const endsHere = isSameDay(week[last], rangeValue.end);
|
|
595
|
-
// Tuck past the circle center so the highlight's rounded cap
|
|
596
|
-
// sits under the endpoint circle instead of leaving a gap.
|
|
597
620
|
const cellPct = 100 / 7;
|
|
598
|
-
const
|
|
599
|
-
const
|
|
600
|
-
let leftPct = first * cellPct;
|
|
601
|
-
let rightPct = (last + 1) * cellPct;
|
|
602
|
-
if (startsHere) {
|
|
603
|
-
leftPct += halfCellPct - tuckPct;
|
|
604
|
-
}
|
|
605
|
-
if (endsHere) {
|
|
606
|
-
rightPct -= halfCellPct - tuckPct;
|
|
607
|
-
}
|
|
621
|
+
const leftPct = first * cellPct;
|
|
622
|
+
const rightPct = (last + 1) * cellPct;
|
|
608
623
|
const widthPct = rightPct - leftPct;
|
|
609
624
|
// Same-day range: only the circle, no connector bar.
|
|
610
625
|
if (widthPct > 0) {
|
|
@@ -619,7 +634,11 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
619
634
|
return (
|
|
620
635
|
<View
|
|
621
636
|
key={weekIndex}
|
|
622
|
-
style={[
|
|
637
|
+
style={[
|
|
638
|
+
styles.weekRow,
|
|
639
|
+
weekIndex > 0 && styles.weekRowSpaced,
|
|
640
|
+
stretchCalendar && styles.calendarSectionFullWidth,
|
|
641
|
+
]}
|
|
623
642
|
>
|
|
624
643
|
{rangeHighlightStyle ? (
|
|
625
644
|
<View
|
|
@@ -658,6 +677,7 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
658
677
|
return (
|
|
659
678
|
<Pressable
|
|
660
679
|
key={dayIndex}
|
|
680
|
+
android_ripple={{ borderless: true, color: "transparent", radius: 22 }}
|
|
661
681
|
onPress={() => handleDayPress(day)}
|
|
662
682
|
disabled={dayDisabled || dayBlocked}
|
|
663
683
|
onHoverIn={() => setHoveredDayKey(dayKey)}
|
|
@@ -668,7 +688,7 @@ export const DatePicker = forwardRef<ComponentRef<typeof View>, DatePickerProps>
|
|
|
668
688
|
onPressOut={() =>
|
|
669
689
|
setHoveredDayKey((current) => (current === dayKey ? null : current))
|
|
670
690
|
}
|
|
671
|
-
style={styles.dayCellWrap}
|
|
691
|
+
style={[styles.dayCellWrap, stretchCalendar && styles.dayCellFullWidth]}
|
|
672
692
|
accessibilityRole="button"
|
|
673
693
|
accessibilityLabel={
|
|
674
694
|
dayUnavailable
|
|
@@ -726,6 +746,10 @@ const styles = StyleSheet.create({
|
|
|
726
746
|
width: "auto",
|
|
727
747
|
gap: 0,
|
|
728
748
|
},
|
|
749
|
+
rootFullWidth: {
|
|
750
|
+
width: "100%",
|
|
751
|
+
alignSelf: "stretch",
|
|
752
|
+
},
|
|
729
753
|
rootOpen: {
|
|
730
754
|
zIndex: 30,
|
|
731
755
|
},
|
|
@@ -742,6 +766,10 @@ const styles = StyleSheet.create({
|
|
|
742
766
|
triggerWrapOpen: {
|
|
743
767
|
zIndex: 20,
|
|
744
768
|
},
|
|
769
|
+
triggerWrapFullWidth: {
|
|
770
|
+
width: "100%",
|
|
771
|
+
alignSelf: "stretch",
|
|
772
|
+
},
|
|
745
773
|
trigger: {
|
|
746
774
|
height: TRIGGER_HEIGHT,
|
|
747
775
|
borderRadius: TRIGGER_RADIUS,
|
|
@@ -832,7 +860,7 @@ const styles = StyleSheet.create({
|
|
|
832
860
|
position: "absolute",
|
|
833
861
|
top: "100%",
|
|
834
862
|
alignSelf: "flex-start",
|
|
835
|
-
height:
|
|
863
|
+
height: "auto",
|
|
836
864
|
marginTop: 8,
|
|
837
865
|
zIndex: 10,
|
|
838
866
|
borderRadius: MENU_RADIUS,
|
|
@@ -840,7 +868,7 @@ const styles = StyleSheet.create({
|
|
|
840
868
|
gap: 0,
|
|
841
869
|
opacity: 1,
|
|
842
870
|
backgroundColor: colors.grey700,
|
|
843
|
-
overflow: "
|
|
871
|
+
overflow: "visible",
|
|
844
872
|
...Platform.select({
|
|
845
873
|
web: {
|
|
846
874
|
boxShadow: `0 8px 24px ${colors.black}73`,
|
|
@@ -855,6 +883,7 @@ const styles = StyleSheet.create({
|
|
|
855
883
|
right: "auto",
|
|
856
884
|
},
|
|
857
885
|
menuAlignEnd: {
|
|
886
|
+
alignSelf: "flex-end",
|
|
858
887
|
left: "auto",
|
|
859
888
|
right: 0,
|
|
860
889
|
},
|
|
@@ -865,16 +894,34 @@ const styles = StyleSheet.create({
|
|
|
865
894
|
right: "auto",
|
|
866
895
|
marginTop: 0,
|
|
867
896
|
},
|
|
897
|
+
menuFullWidth: {
|
|
898
|
+
width: "100%",
|
|
899
|
+
maxWidth: "100%",
|
|
900
|
+
alignSelf: "stretch",
|
|
901
|
+
alignItems: "stretch",
|
|
902
|
+
},
|
|
903
|
+
calendarSectionFullWidth: {
|
|
904
|
+
width: "100%",
|
|
905
|
+
alignSelf: "stretch",
|
|
906
|
+
},
|
|
907
|
+
dayCellFullWidth: {
|
|
908
|
+
width: 0,
|
|
909
|
+
flexGrow: 1,
|
|
910
|
+
flexShrink: 1,
|
|
911
|
+
minWidth: 0,
|
|
912
|
+
},
|
|
868
913
|
rangeMenu: {},
|
|
869
914
|
menuFitContent: {
|
|
870
915
|
width: MENU_CONTENT_WIDTH + MENU_PADDING * 2,
|
|
871
916
|
maxWidth: MENU_CONTENT_WIDTH + MENU_PADDING * 2,
|
|
917
|
+
height: "auto",
|
|
872
918
|
alignSelf: "flex-start",
|
|
873
919
|
alignItems: "flex-start",
|
|
874
920
|
...(Platform.select({
|
|
875
921
|
web: {
|
|
876
922
|
width: "fit-content",
|
|
877
923
|
maxWidth: "fit-content",
|
|
924
|
+
height: "fit-content",
|
|
878
925
|
},
|
|
879
926
|
default: {},
|
|
880
927
|
}) as ViewStyle),
|
|
@@ -882,16 +929,18 @@ const styles = StyleSheet.create({
|
|
|
882
929
|
calendarGrid: {
|
|
883
930
|
width: MENU_CONTENT_WIDTH,
|
|
884
931
|
alignSelf: "flex-start",
|
|
932
|
+
overflow: "visible",
|
|
885
933
|
},
|
|
886
934
|
calendarHeader: {
|
|
887
935
|
width: MENU_CONTENT_WIDTH,
|
|
888
|
-
|
|
936
|
+
minHeight: HEADER_HEIGHT,
|
|
889
937
|
paddingTop: 8,
|
|
890
938
|
paddingBottom: 8,
|
|
891
939
|
flexDirection: "row",
|
|
892
940
|
alignItems: "center",
|
|
893
941
|
justifyContent: "space-between",
|
|
894
942
|
opacity: 1,
|
|
943
|
+
overflow: "visible",
|
|
895
944
|
},
|
|
896
945
|
navButton: {
|
|
897
946
|
width: HEADER_HEIGHT,
|
|
@@ -905,6 +954,9 @@ const styles = StyleSheet.create({
|
|
|
905
954
|
monthHeading: {
|
|
906
955
|
...datePickerTypography.monthHeading,
|
|
907
956
|
color: colors.white,
|
|
957
|
+
flexShrink: 0,
|
|
958
|
+
includeFontPadding: true,
|
|
959
|
+
overflow: "visible",
|
|
908
960
|
textAlign: "center",
|
|
909
961
|
},
|
|
910
962
|
weekdayRow: {
|
|
@@ -931,7 +983,9 @@ const styles = StyleSheet.create({
|
|
|
931
983
|
},
|
|
932
984
|
weekRow: {
|
|
933
985
|
width: MENU_CONTENT_WIDTH,
|
|
986
|
+
height: DAY_CELL_HEIGHT,
|
|
934
987
|
flexDirection: "row",
|
|
988
|
+
overflow: "visible",
|
|
935
989
|
position: "relative",
|
|
936
990
|
},
|
|
937
991
|
weekRowSpaced: {
|
|
@@ -940,7 +994,7 @@ const styles = StyleSheet.create({
|
|
|
940
994
|
rangeHighlight: {
|
|
941
995
|
position: "absolute",
|
|
942
996
|
top: 0,
|
|
943
|
-
|
|
997
|
+
height: DAY_CELL_HEIGHT,
|
|
944
998
|
borderRadius: DAY_CELL_RADIUS,
|
|
945
999
|
backgroundColor: colors.primaryHover,
|
|
946
1000
|
},
|
|
@@ -952,21 +1006,25 @@ const styles = StyleSheet.create({
|
|
|
952
1006
|
alignItems: "center",
|
|
953
1007
|
justifyContent: "center",
|
|
954
1008
|
opacity: 1,
|
|
1009
|
+
overflow: "visible",
|
|
955
1010
|
},
|
|
956
1011
|
dayCircle: {
|
|
957
|
-
width:
|
|
958
|
-
height:
|
|
959
|
-
borderRadius:
|
|
960
|
-
|
|
961
|
-
gap: 10,
|
|
1012
|
+
width: DAY_CIRCLE_SIZE,
|
|
1013
|
+
height: DAY_CIRCLE_SIZE,
|
|
1014
|
+
borderRadius: 22,
|
|
1015
|
+
overflow: "hidden",
|
|
962
1016
|
alignItems: "center",
|
|
963
1017
|
justifyContent: "center",
|
|
964
1018
|
},
|
|
965
1019
|
dayCircleSelected: {
|
|
966
1020
|
backgroundColor: colors.primary,
|
|
1021
|
+
borderRadius: 22,
|
|
1022
|
+
overflow: "hidden",
|
|
967
1023
|
},
|
|
968
1024
|
dayCircleBooked: {
|
|
969
1025
|
backgroundColor: colors.grey700,
|
|
1026
|
+
borderRadius: 22,
|
|
1027
|
+
overflow: "hidden",
|
|
970
1028
|
},
|
|
971
1029
|
dayTextBooked: {
|
|
972
1030
|
textDecorationLine: "line-through",
|
|
@@ -28,7 +28,7 @@ const DEFAULT_LENGTH = 6;
|
|
|
28
28
|
const DESKTOP_CELL_WIDTH = 54.333335876464844;
|
|
29
29
|
const MOBILE_CELL_WIDTH = 45.16666793823242;
|
|
30
30
|
const DESKTOP_CELL_HEIGHT = 68;
|
|
31
|
-
const MOBILE_CELL_HEIGHT =
|
|
31
|
+
const MOBILE_CELL_HEIGHT = 68;
|
|
32
32
|
const DESKTOP_GAP = 12;
|
|
33
33
|
const MOBILE_GAP = 12;
|
|
34
34
|
const MOBILE_BREAKPOINT = 1024;
|
|
@@ -172,8 +172,18 @@ export const VerificationCodeInput = forwardRef<
|
|
|
172
172
|
const showErrorMessage = Boolean(error && errorMessage);
|
|
173
173
|
|
|
174
174
|
return (
|
|
175
|
-
<View
|
|
176
|
-
|
|
175
|
+
<View
|
|
176
|
+
{...viewProps}
|
|
177
|
+
ref={rootRef}
|
|
178
|
+
style={[styles.wrapper, disabled && styles.disabled, mobile && styles.wrapperFill, style]}
|
|
179
|
+
>
|
|
180
|
+
<View
|
|
181
|
+
style={[
|
|
182
|
+
styles.row,
|
|
183
|
+
mobile ? styles.rowFill : { width: rowWidth, maxWidth: "100%" },
|
|
184
|
+
{ gap: cellGap },
|
|
185
|
+
]}
|
|
186
|
+
>
|
|
177
187
|
{Array.from({ length: safeLength }, (_, index) => {
|
|
178
188
|
const active = focusedIndex === index;
|
|
179
189
|
const borderColor = error ? colors.red : active ? colors.primary : colors.grey600;
|
|
@@ -203,8 +213,8 @@ export const VerificationCodeInput = forwardRef<
|
|
|
203
213
|
selectTextOnFocus
|
|
204
214
|
style={[
|
|
205
215
|
styles.cell,
|
|
216
|
+
mobile ? styles.cellFill : { width: cellWidth },
|
|
206
217
|
{
|
|
207
|
-
width: cellWidth,
|
|
208
218
|
height: cellHeight,
|
|
209
219
|
borderColor,
|
|
210
220
|
color: error ? colors.red : colors.white,
|
|
@@ -235,11 +245,25 @@ const styles = StyleSheet.create({
|
|
|
235
245
|
alignItems: "center",
|
|
236
246
|
gap: 12,
|
|
237
247
|
},
|
|
248
|
+
wrapperFill: {
|
|
249
|
+
alignSelf: "stretch",
|
|
250
|
+
width: "100%",
|
|
251
|
+
},
|
|
238
252
|
row: {
|
|
239
253
|
minWidth: 0,
|
|
240
254
|
flexDirection: "row",
|
|
241
255
|
justifyContent: "center",
|
|
242
256
|
},
|
|
257
|
+
rowFill: {
|
|
258
|
+
maxWidth: "100%",
|
|
259
|
+
width: "100%",
|
|
260
|
+
},
|
|
261
|
+
cellFill: {
|
|
262
|
+
flexBasis: 0,
|
|
263
|
+
flexGrow: 1,
|
|
264
|
+
flexShrink: 1,
|
|
265
|
+
width: undefined,
|
|
266
|
+
},
|
|
243
267
|
disabled: {
|
|
244
268
|
opacity: 0.6,
|
|
245
269
|
},
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { BACKSPACE_PATH } from "./backspacePath";
|
|
3
|
+
|
|
4
|
+
describe("BackspaceIcon", () => {
|
|
5
|
+
it("uses the approved 20px path", () => {
|
|
6
|
+
expect(BACKSPACE_PATH).toContain("M14.1667 7.49992");
|
|
7
|
+
expect(BACKSPACE_PATH).toMatch(/2\.26667 10\.7999Z$/);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Svg, { Path } from "react-native-svg";
|
|
2
|
+
import { colors } from "../../theme";
|
|
3
|
+
import type { IconProps } from "../types";
|
|
4
|
+
import { BACKSPACE_PATH } from "./backspacePath";
|
|
5
|
+
|
|
6
|
+
export { BACKSPACE_PATH } from "./backspacePath";
|
|
7
|
+
|
|
8
|
+
export function BackspaceIcon({ size = 20, color = colors.white, strokeWidth = 2 }: IconProps) {
|
|
9
|
+
return (
|
|
10
|
+
<Svg width={size} height={size} viewBox="0 0 20 20" fill="none">
|
|
11
|
+
<Path
|
|
12
|
+
d={BACKSPACE_PATH}
|
|
13
|
+
stroke={color}
|
|
14
|
+
strokeWidth={strokeWidth}
|
|
15
|
+
strokeLinecap="round"
|
|
16
|
+
strokeLinejoin="round"
|
|
17
|
+
/>
|
|
18
|
+
</Svg>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { colors } from "../../theme";
|
|
2
|
+
import type { IconProps } from "../types";
|
|
3
|
+
import { BACKSPACE_PATH } from "./backspacePath";
|
|
4
|
+
|
|
5
|
+
export function BackspaceIcon({ size = 20, color = colors.white, strokeWidth = 2 }: IconProps) {
|
|
6
|
+
return (
|
|
7
|
+
<svg
|
|
8
|
+
width={size}
|
|
9
|
+
height={size}
|
|
10
|
+
viewBox="0 0 20 20"
|
|
11
|
+
fill="none"
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
aria-hidden
|
|
14
|
+
>
|
|
15
|
+
<path
|
|
16
|
+
d={BACKSPACE_PATH}
|
|
17
|
+
stroke={color}
|
|
18
|
+
strokeWidth={strokeWidth}
|
|
19
|
+
strokeLinecap="round"
|
|
20
|
+
strokeLinejoin="round"
|
|
21
|
+
/>
|
|
22
|
+
</svg>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { BACKSPACE_PATH } from "./backspacePath";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Backspace / delete path — 20×20 viewBox. */
|
|
2
|
+
export const BACKSPACE_PATH =
|
|
3
|
+
"M14.1667 7.49992L9.16667 12.4999M9.16667 7.49992L14.1667 12.4999M2.26667 10.7999L5.86667 15.5999C6.16 15.991 6.30667 16.1866 6.49254 16.3276C6.65717 16.4525 6.8436 16.5458 7.04231 16.6025C7.26667 16.6666 7.51111 16.6666 8 16.6666H14.3333C15.7335 16.6666 16.4335 16.6666 16.9683 16.3941C17.4387 16.1544 17.8212 15.772 18.0609 15.3016C18.3333 14.7668 18.3333 14.0667 18.3333 12.6666V7.33325C18.3333 5.93312 18.3333 5.23306 18.0609 4.69828C17.8212 4.22787 17.4387 3.84542 16.9683 3.60574C16.4335 3.33325 15.7335 3.33325 14.3333 3.33325H8C7.51111 3.33325 7.26667 3.33325 7.04231 3.39733C6.8436 3.45408 6.65717 3.54729 6.49254 3.67221C6.30667 3.81325 6.16 4.00881 5.86667 4.39992L2.26667 9.19992C2.05151 9.4868 1.94392 9.63024 1.90245 9.78778C1.86585 9.92684 1.86585 10.073 1.90245 10.2121C1.94392 10.3696 2.05151 10.513 2.26667 10.7999Z";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BackspaceIcon, BACKSPACE_PATH } from "./BackspaceIcon";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { FINGERPRINT_PATHS } from "./fingerprintPaths";
|
|
3
|
+
|
|
4
|
+
describe("FingerprintIcon", () => {
|
|
5
|
+
it("uses the approved 20px paths", () => {
|
|
6
|
+
expect(FINGERPRINT_PATHS).toHaveLength(4);
|
|
7
|
+
expect(FINGERPRINT_PATHS[0]).toContain("M6.75365 17.6842");
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Svg, { Path } from "react-native-svg";
|
|
2
|
+
import { colors } from "../../theme";
|
|
3
|
+
import type { IconProps } from "../types";
|
|
4
|
+
import { FINGERPRINT_PATHS } from "./fingerprintPaths";
|
|
5
|
+
|
|
6
|
+
export { FINGERPRINT_PATHS } from "./fingerprintPaths";
|
|
7
|
+
|
|
8
|
+
export function FingerprintIcon({ size = 20, color = colors.white, strokeWidth = 2 }: IconProps) {
|
|
9
|
+
return (
|
|
10
|
+
<Svg width={size} height={size} viewBox="0 0 20 20" fill="none">
|
|
11
|
+
{FINGERPRINT_PATHS.map((d) => (
|
|
12
|
+
<Path
|
|
13
|
+
key={d}
|
|
14
|
+
d={d}
|
|
15
|
+
stroke={color}
|
|
16
|
+
strokeWidth={strokeWidth}
|
|
17
|
+
strokeLinecap="round"
|
|
18
|
+
strokeLinejoin="round"
|
|
19
|
+
/>
|
|
20
|
+
))}
|
|
21
|
+
</Svg>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { colors } from "../../theme";
|
|
2
|
+
import type { IconProps } from "../types";
|
|
3
|
+
import { FINGERPRINT_PATHS } from "./fingerprintPaths";
|
|
4
|
+
|
|
5
|
+
export function FingerprintIcon({ size = 20, color = colors.white, strokeWidth = 2 }: IconProps) {
|
|
6
|
+
return (
|
|
7
|
+
<svg
|
|
8
|
+
width={size}
|
|
9
|
+
height={size}
|
|
10
|
+
viewBox="0 0 20 20"
|
|
11
|
+
fill="none"
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
aria-hidden
|
|
14
|
+
>
|
|
15
|
+
{FINGERPRINT_PATHS.map((d) => (
|
|
16
|
+
<path
|
|
17
|
+
key={d}
|
|
18
|
+
d={d}
|
|
19
|
+
stroke={color}
|
|
20
|
+
strokeWidth={strokeWidth}
|
|
21
|
+
strokeLinecap="round"
|
|
22
|
+
strokeLinejoin="round"
|
|
23
|
+
/>
|
|
24
|
+
))}
|
|
25
|
+
</svg>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { FINGERPRINT_PATHS } from "./fingerprintPaths";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const FINGERPRINT_PATHS = [
|
|
2
|
+
"M6.75365 17.6842C5.59542 16.0313 4.91406 14.0203 4.91406 11.8489C4.91406 9.03693 7.19233 6.75781 10.0026 6.75781C12.8129 6.75781 15.0912 9.03693 15.0912 11.8489",
|
|
3
|
+
"M15.3626 16.9267C15.271 16.9317 15.1811 16.9402 15.0886 16.9402C12.2783 16.9402 10 14.6611 10 11.8491",
|
|
4
|
+
"M11.0569 18.3334C8.89484 16.9851 7.4549 14.5855 7.4549 11.8491C7.4549 10.4431 8.59446 9.30351 9.99961 9.30351C11.4048 9.30351 12.5443 10.4431 12.5443 11.8491C12.5443 13.2551 13.6839 14.3946 15.089 14.3946C16.4942 14.3946 17.6337 13.2551 17.6337 11.8491C17.6337 7.63108 14.2159 4.2124 10.0005 4.2124C5.78502 4.2124 2.36719 7.63108 2.36719 11.8491C2.36719 12.7892 2.4724 13.7048 2.66587 14.5872",
|
|
5
|
+
"M17.1077 4.88578C15.3725 2.91467 12.8354 1.6665 10.0031 1.6665C7.17073 1.6665 4.63366 2.91467 2.89844 4.88578",
|
|
6
|
+
] as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FingerprintIcon, FINGERPRINT_PATHS } from "./FingerprintIcon";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { GOOGLE_BRAND_PATHS } from "./googleBrandPaths";
|
|
3
|
+
|
|
4
|
+
describe("GoogleBrandIcon", () => {
|
|
5
|
+
it("uses the approved brand-colored paths", () => {
|
|
6
|
+
expect(GOOGLE_BRAND_PATHS).toHaveLength(4);
|
|
7
|
+
expect(GOOGLE_BRAND_PATHS.map((path) => path.fill)).toEqual([
|
|
8
|
+
"#4285F4",
|
|
9
|
+
"#34A853",
|
|
10
|
+
"#FBBC05",
|
|
11
|
+
"#A63E3E",
|
|
12
|
+
]);
|
|
13
|
+
});
|
|
14
|
+
});
|