@momo-kits/foundation 0.169.5 → 0.169.6-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Application/BottomSheet.hooks.ts +8 -8
- package/Application/BottomSheet.parts.tsx +34 -44
- package/Application/BottomSheet.tsx +26 -35
- package/Application/BottomTab/ActiveIndicator.tsx +14 -15
- package/Application/BottomTab/BottomTabBar.styles.ts +18 -1
- package/Application/BottomTab/BottomTabBar.tsx +40 -63
- package/Application/BottomTab/BottomTabInset.tsx +4 -8
- package/Application/BottomTab/CurvedContainer.tsx +20 -16
- package/Application/BottomTab/CustomBottomTabItem.tsx +13 -16
- package/Application/BottomTab/DuoBarCompression.tsx +19 -13
- package/Application/BottomTab/DuoRailTabBar.tsx +13 -17
- package/Application/BottomTab/DuoTabBar.tsx +24 -12
- package/Application/BottomTab/TabBarIcon.tsx +8 -13
- package/Application/BottomTab/TabScreen.tsx +5 -1
- package/Application/BottomTab/index.tsx +30 -38
- package/Application/BottomTab/metrics.ts +46 -24
- package/Application/BottomTab/tabItems.ts +1 -1
- package/Application/BottomTab/usePressLift.ts +2 -2
- package/Application/Components/BackgroundImageView.tsx +0 -4
- package/Application/Components/DuoGlassBackground.tsx +4 -5
- package/Application/Components/HeaderAnimated.tsx +0 -4
- package/Application/Components/HeaderBackground.tsx +0 -4
- package/Application/Components/HeaderExtendHeader.tsx +10 -11
- package/Application/Components/HeaderLeft.tsx +1 -2
- package/Application/Components/HeaderRight.tsx +1 -2
- package/Application/Components/HeaderTitle.shared.ts +9 -11
- package/Application/Components/HeaderTitle.tsx +3 -4
- package/Application/Components/HeaderToolkitAction.tsx +20 -17
- package/Application/Components/NavigationButton.tsx +1 -2
- package/Application/Components/SearchHeader.tsx +10 -17
- package/Application/Components/TitleJourney.tsx +2 -2
- package/Application/Components/TitleLocation.tsx +2 -2
- package/Application/Components/TitleUser.tsx +2 -2
- package/Application/Components/useToolkitActions.tsx +32 -17
- package/Application/Localize.ts +0 -7
- package/Application/ModalScreen.tsx +3 -9
- package/Application/Navigation.ts +16 -14
- package/Application/NavigationContainer.tsx +16 -19
- package/Application/Navigator.ts +48 -20
- package/Application/StackScreen.tracking.ts +26 -11
- package/Application/StackScreen.tsx +35 -8
- package/Application/TooltipPortal.tsx +5 -12
- package/Application/WidgetContainer.tsx +4 -10
- package/Application/__tests__/modalLayout.test.ts +128 -0
- package/Application/modalLayout.ts +14 -13
- package/Application/navigationOptions.tsx +17 -21
- package/Application/types.tabs.ts +0 -1
- package/Badge/Badge.tsx +0 -5
- package/Badge/BadgeDot.tsx +0 -1
- package/Badge/BadgeDotAnimation.tsx +7 -15
- package/Badge/BadgeRibbon.tsx +38 -46
- package/Badge/Shape.tsx +0 -2
- package/Badge/types.ts +2 -2
- package/Button/index.tsx +16 -5
- package/Button/utils.ts +15 -9
- package/CheckBox/index.tsx +0 -4
- package/Consts/theme.ts +10 -10
- package/Context/index.ts +0 -1
- package/Divider/DashDivider.tsx +0 -1
- package/Divider/index.tsx +0 -4
- package/FoundationList/index.tsx +0 -4
- package/Icon/index.tsx +6 -6
- package/Icon/types.ts +1 -1
- package/IconButton/index.tsx +12 -4
- package/Image/index.tsx +7 -9
- package/Input/Input.tsx +9 -8
- package/Input/InputDropDown.tsx +12 -10
- package/Input/InputMoney.tsx +8 -12
- package/Input/InputMoneyView.tsx +7 -14
- package/Input/InputOTP.tsx +33 -35
- package/Input/InputPhoneNumber.tsx +9 -8
- package/Input/InputSearch.tsx +6 -4
- package/Input/InputTextArea.tsx +0 -4
- package/Input/SearchTextTyping.tsx +0 -4
- package/Input/SystemTextInput.tsx +2 -7
- package/Input/TextTyping.tsx +0 -4
- package/Input/common.tsx +12 -26
- package/Input/index.tsx +20 -17
- package/Input/moneyUtils.ts +4 -10
- package/Input/styles.ts +5 -0
- package/Input/utils.ts +12 -14
- package/Layout/Card.tsx +4 -7
- package/Layout/FloatingButton.tsx +0 -4
- package/Layout/Item.tsx +2 -6
- package/Layout/ItemList.tsx +7 -9
- package/Layout/ItemSectionList.tsx +1 -2
- package/Layout/ReservedRegions.tsx +25 -25
- package/Layout/Screen.tsx +58 -56
- package/Layout/Section.tsx +5 -8
- package/Layout/TrackingScope.tsx +0 -1
- package/Layout/screenContent.tsx +2 -4
- package/Layout/screenFooter.tsx +18 -28
- package/Layout/screenHeader.tsx +31 -34
- package/Layout/screenQuickReturn.tsx +20 -17
- package/Layout/screenScroll.ts +7 -4
- package/Layout/screenTypes.ts +2 -3
- package/Layout/types.ts +4 -2
- package/Layout/utils.ts +37 -31
- package/Loader/DotLoader.tsx +0 -4
- package/Loader/Loader.tsx +0 -4
- package/Loader/ProgressBar.tsx +0 -1
- package/Loader/Spinner.tsx +0 -4
- package/Loader/utils.ts +7 -11
- package/Pagination/Dot.tsx +0 -4
- package/Pagination/PaginationDot.tsx +0 -1
- package/Pagination/PaginationNumber.tsx +3 -5
- package/Pagination/PaginationScroll.tsx +0 -5
- package/Pagination/PaginationWhiteDot.tsx +0 -1
- package/Pagination/index.tsx +0 -4
- package/Pagination/types.ts +2 -2
- package/Popup/PopupNotify.tsx +48 -44
- package/Popup/PopupPromotion.tsx +7 -4
- package/Popup/types.ts +4 -4
- package/Popup/utils.ts +0 -4
- package/Radio/index.tsx +0 -4
- package/Skeleton/index.tsx +0 -8
- package/Switch/index.tsx +0 -1
- package/Tag/index.tsx +1 -5
- package/Tag/types.ts +3 -3
- package/Text/index.tsx +3 -14
- package/Text/styles.ts +1 -1
- package/Text/types.ts +6 -1
- package/Text/utils.ts +0 -9
- package/Title/index.tsx +32 -41
- package/ViewBoundary/index.tsx +2 -4
- package/index.ts +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// document/__mocks__ shadows react-native with react-native-web for the doc site
|
|
2
|
+
jest.mock('react-native', () => jest.requireActual('react-native'));
|
|
3
|
+
|
|
4
|
+
import { getModalLayout } from '../modalLayout';
|
|
5
|
+
|
|
6
|
+
const NO_INSETS = { top: 0, right: 0, bottom: 0, left: 0 };
|
|
7
|
+
|
|
8
|
+
describe('getModalLayout', () => {
|
|
9
|
+
it('keeps the phone look', () => {
|
|
10
|
+
const layout = getModalLayout({
|
|
11
|
+
width: 390,
|
|
12
|
+
height: 844,
|
|
13
|
+
insets: { top: 47, right: 0, bottom: 34, left: 0 },
|
|
14
|
+
isDuo: false,
|
|
15
|
+
});
|
|
16
|
+
expect(layout.isFoldable).toBe(false);
|
|
17
|
+
expect(layout.popup.width).toBe(342);
|
|
18
|
+
expect(layout.popup.maxHeight).toBeUndefined();
|
|
19
|
+
expect(layout.popup.radius).toBe(16);
|
|
20
|
+
expect(layout.sheet.width).toBeUndefined();
|
|
21
|
+
expect(layout.sheet.maxHeight).toBeUndefined();
|
|
22
|
+
expect(layout.sheet.radius).toBe(12);
|
|
23
|
+
expect(layout.scrimOpacity).toBe(0.6);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('keeps the phone look in landscape', () => {
|
|
27
|
+
const layout = getModalLayout({
|
|
28
|
+
width: 844,
|
|
29
|
+
height: 390,
|
|
30
|
+
insets: { top: 0, right: 47, bottom: 21, left: 47 },
|
|
31
|
+
isDuo: false,
|
|
32
|
+
});
|
|
33
|
+
expect(layout.isFoldable).toBe(false);
|
|
34
|
+
expect(layout.popup.width).toBe(844 - 48);
|
|
35
|
+
expect(layout.popup.maxHeight).toBeUndefined();
|
|
36
|
+
expect(layout.popup.radius).toBe(16);
|
|
37
|
+
expect(layout.sheet.width).toBeUndefined();
|
|
38
|
+
expect(layout.scrimOpacity).toBe(0.6);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('caps popup and sheet on a wide foldable window', () => {
|
|
42
|
+
const layout = getModalLayout({
|
|
43
|
+
width: 884,
|
|
44
|
+
height: 1104,
|
|
45
|
+
insets: { top: 24, right: 0, bottom: 20, left: 0 },
|
|
46
|
+
isDuo: false,
|
|
47
|
+
});
|
|
48
|
+
expect(layout.isFoldable).toBe(true);
|
|
49
|
+
expect(layout.popup).toMatchObject({
|
|
50
|
+
width: 450,
|
|
51
|
+
minWidth: 280,
|
|
52
|
+
maxWidth: 450,
|
|
53
|
+
maxHeight: 600,
|
|
54
|
+
margin: 24,
|
|
55
|
+
radius: 24,
|
|
56
|
+
});
|
|
57
|
+
expect(layout.sheet).toMatchObject({
|
|
58
|
+
width: 653,
|
|
59
|
+
maxHeight: 1104 - 24 - 12,
|
|
60
|
+
minHeight: 230,
|
|
61
|
+
margin: 12,
|
|
62
|
+
radius: 24,
|
|
63
|
+
});
|
|
64
|
+
expect(layout.scrimOpacity).toBe(0.2);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('limits popup height to the safe area minus 48', () => {
|
|
68
|
+
const layout = getModalLayout({
|
|
69
|
+
width: 900,
|
|
70
|
+
height: 600,
|
|
71
|
+
insets: { top: 24, right: 0, bottom: 20, left: 0 },
|
|
72
|
+
isDuo: false,
|
|
73
|
+
});
|
|
74
|
+
expect(layout.popup.maxHeight).toBe(600 - 24 - 20 - 48);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('places modals left of the control column on the iPhone Duo outer display', () => {
|
|
78
|
+
const layout = getModalLayout({
|
|
79
|
+
width: 420,
|
|
80
|
+
height: 760,
|
|
81
|
+
insets: { top: 0, right: 64, bottom: 20, left: 0 },
|
|
82
|
+
isDuo: true,
|
|
83
|
+
});
|
|
84
|
+
expect(layout.isFoldable).toBe(true);
|
|
85
|
+
expect(layout.placement).toEqual({ x: 0, y: 0, width: 356, height: 740 });
|
|
86
|
+
expect(layout.popup.margin).toBe(12);
|
|
87
|
+
expect(layout.popup.width).toBe(356 - 24);
|
|
88
|
+
expect(layout.sheet.width).toBe(356 - 24);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('never grows past the margins when the space is under the min width', () => {
|
|
92
|
+
const layout = getModalLayout({
|
|
93
|
+
width: 300,
|
|
94
|
+
height: 600,
|
|
95
|
+
insets: NO_INSETS,
|
|
96
|
+
isDuo: true,
|
|
97
|
+
});
|
|
98
|
+
expect(layout.popup.width).toBe(300 - 24);
|
|
99
|
+
expect(layout.popup.minWidth).toBe(300 - 24);
|
|
100
|
+
expect(layout.sheet.width).toBe(300 - 24);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('moves to the right half when iPhone Duo is half folded', () => {
|
|
104
|
+
const layout = getModalLayout({
|
|
105
|
+
width: 1000,
|
|
106
|
+
height: 800,
|
|
107
|
+
insets: NO_INSETS,
|
|
108
|
+
isDuo: true,
|
|
109
|
+
hinge: { x: 495, y: 0, width: 10, height: 800 },
|
|
110
|
+
});
|
|
111
|
+
expect(layout.placement).toEqual({ x: 505, y: 0, width: 495, height: 800 });
|
|
112
|
+
expect(layout.popup.margin).toBe(12);
|
|
113
|
+
expect(layout.popup.width).toBe(450);
|
|
114
|
+
expect(layout.sheet.width).toBe(495 - 24);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('ignores a division off the iPhone Duo', () => {
|
|
118
|
+
const layout = getModalLayout({
|
|
119
|
+
width: 1000,
|
|
120
|
+
height: 800,
|
|
121
|
+
insets: NO_INSETS,
|
|
122
|
+
isDuo: false,
|
|
123
|
+
hinge: { x: 495, y: 0, width: 10, height: 800 },
|
|
124
|
+
});
|
|
125
|
+
expect(layout.placement.x).toBe(0);
|
|
126
|
+
expect(layout.popup.margin).toBe(24);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -73,12 +73,11 @@ type ModalLayoutInput = {
|
|
|
73
73
|
hinge?: ReservedRegion;
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
const clamp = (value: number, min: number, max: number) =>
|
|
77
|
-
|
|
78
|
-
};
|
|
76
|
+
const clamp = (value: number, min: number, max: number) =>
|
|
77
|
+
Math.min(Math.max(value, min), max);
|
|
79
78
|
|
|
80
79
|
/**
|
|
81
|
-
* Modal geometry for a window, pure so it can be tested without a device
|
|
80
|
+
* Modal geometry for a window, pure so it can be tested without a device
|
|
82
81
|
*/
|
|
83
82
|
const getModalLayout = ({
|
|
84
83
|
width,
|
|
@@ -92,9 +91,8 @@ const getModalLayout = ({
|
|
|
92
91
|
const isFoldable = isDuo || shortSide >= FOLDABLE_MIN_WIDTH;
|
|
93
92
|
const isDuoOuter = isDuo && shortSide < FOLDABLE_MIN_WIDTH;
|
|
94
93
|
const hingeRight = hinge ? hinge.x + hinge.width : 0;
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const isHalfFolded = isDuo && hasHinge && isHingeInWindow;
|
|
94
|
+
const isHalfFolded =
|
|
95
|
+
isDuo && !!hinge && hinge.x > 0 && hingeRight < width - insets.right;
|
|
98
96
|
|
|
99
97
|
const safeLeft = isHalfFolded ? hingeRight : insets.left;
|
|
100
98
|
const placement = {
|
|
@@ -114,9 +112,9 @@ const getModalLayout = ({
|
|
|
114
112
|
minWidth: popupWidth,
|
|
115
113
|
maxWidth: popupWidth,
|
|
116
114
|
margin: Spacing.XL,
|
|
117
|
-
radius: Radius.
|
|
115
|
+
radius: Radius.L,
|
|
118
116
|
},
|
|
119
|
-
sheet: { margin: 0, radius: Radius.
|
|
117
|
+
sheet: { margin: 0, radius: Radius.M },
|
|
120
118
|
scrimOpacity: SCRIM_OPACITY,
|
|
121
119
|
};
|
|
122
120
|
}
|
|
@@ -127,7 +125,6 @@ const getModalLayout = ({
|
|
|
127
125
|
|
|
128
126
|
const sheetMargin = Spacing.M;
|
|
129
127
|
const sheetSpace = placement.width - sheetMargin * 2;
|
|
130
|
-
const sheetMinWidth = Math.min(SHEET_MIN_WIDTH, sheetSpace);
|
|
131
128
|
const sheetMaxHeight = height - insets.top - Spacing.M;
|
|
132
129
|
|
|
133
130
|
return {
|
|
@@ -142,7 +139,11 @@ const getModalLayout = ({
|
|
|
142
139
|
radius: Radius.XL,
|
|
143
140
|
},
|
|
144
141
|
sheet: {
|
|
145
|
-
width: clamp(
|
|
142
|
+
width: clamp(
|
|
143
|
+
sheetSpace,
|
|
144
|
+
Math.min(SHEET_MIN_WIDTH, sheetSpace),
|
|
145
|
+
SHEET_MAX_WIDTH,
|
|
146
|
+
),
|
|
146
147
|
maxHeight: sheetMaxHeight,
|
|
147
148
|
minHeight: Math.min(SHEET_MIN_HEIGHT, sheetMaxHeight),
|
|
148
149
|
margin: sheetMargin,
|
|
@@ -153,8 +154,8 @@ const getModalLayout = ({
|
|
|
153
154
|
};
|
|
154
155
|
|
|
155
156
|
/**
|
|
156
|
-
* Modal geometry for the current window
|
|
157
|
-
*
|
|
157
|
+
* Modal geometry for the current window, follows fold, unfold, rotation and the
|
|
158
|
+
* iPhone Duo hinge
|
|
158
159
|
*/
|
|
159
160
|
const useModalLayout = (): ModalLayout => {
|
|
160
161
|
const { width, height } = useWindowDimensions();
|
|
@@ -133,15 +133,13 @@ const exportHeaderTitle = (
|
|
|
133
133
|
};
|
|
134
134
|
} else if (typeof params.headerTitle === 'string') {
|
|
135
135
|
return {
|
|
136
|
-
headerTitle: (props: any) =>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
);
|
|
144
|
-
},
|
|
136
|
+
headerTitle: (props: any) => (
|
|
137
|
+
<HeaderTitle
|
|
138
|
+
{...props}
|
|
139
|
+
children={params.headerTitle}
|
|
140
|
+
animatedValue={animatedValue}
|
|
141
|
+
/>
|
|
142
|
+
),
|
|
145
143
|
};
|
|
146
144
|
}
|
|
147
145
|
return {};
|
|
@@ -158,17 +156,15 @@ const getOptions = (
|
|
|
158
156
|
let options: StackNavigationOptions = {};
|
|
159
157
|
|
|
160
158
|
if (hasCustomHeaderLeft(params)) {
|
|
161
|
-
let headerLeft: any = (props: any) =>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
);
|
|
171
|
-
};
|
|
159
|
+
let headerLeft: any = (props: any) => (
|
|
160
|
+
<HeaderLeft
|
|
161
|
+
{...props}
|
|
162
|
+
preventBack={params.preventBack}
|
|
163
|
+
onPressLeftHeader={params.onPressLeftHeader}
|
|
164
|
+
onBackHandler={params.onBackHandler}
|
|
165
|
+
floating
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
172
168
|
if (params.hiddenBack) {
|
|
173
169
|
headerLeft = null;
|
|
174
170
|
options.headerTitleContainerStyle = {
|
|
@@ -207,7 +203,7 @@ const getOptions = (
|
|
|
207
203
|
};
|
|
208
204
|
}
|
|
209
205
|
|
|
210
|
-
//
|
|
206
|
+
// only ever turns swipe back off, screens opt in via gestureEnabled
|
|
211
207
|
if (params.gestureEnabled === undefined && hasCustomBackHandling(params)) {
|
|
212
208
|
options.gestureEnabled = false;
|
|
213
209
|
}
|
package/Badge/Badge.tsx
CHANGED
|
@@ -7,11 +7,6 @@ import { BadgeProps } from './types';
|
|
|
7
7
|
import { Colors, Radius, Spacing } from '../Consts';
|
|
8
8
|
import { Text, useScaleSize } from '../Text';
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
* Label or count badge; counts over 99 show "99+". Counts use the error color,
|
|
12
|
-
* labels the warning color, and `backgroundColor` applies only if it's a
|
|
13
|
-
* `Colors.*_03` token.
|
|
14
|
-
*/
|
|
15
10
|
const Badge: FC<BadgeProps> = ({
|
|
16
11
|
label = '',
|
|
17
12
|
style,
|
package/Badge/BadgeDot.tsx
CHANGED
|
@@ -4,7 +4,6 @@ import { BadgeDotProps } from './types';
|
|
|
4
4
|
import styles from './styles';
|
|
5
5
|
import { MiniAppContext } from '../Context';
|
|
6
6
|
|
|
7
|
-
/** Static red notification dot with a white ring, `large` or `small`. */
|
|
8
7
|
const BadgeDot: FC<BadgeDotProps> = ({ size = 'large', style }) => {
|
|
9
8
|
const context = useContext<any>(MiniAppContext);
|
|
10
9
|
let dotStyle;
|
|
@@ -14,10 +14,6 @@ import styles from './styles';
|
|
|
14
14
|
|
|
15
15
|
const DURATION = 500;
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
* Red notification dot that pulses with a spring and emits an expanding,
|
|
19
|
-
* fading wave ring, looping until unmounted.
|
|
20
|
-
*/
|
|
21
17
|
const BadgeDotAnimation = ({ size, style }: BadgeDotProps) => {
|
|
22
18
|
const scaleAnim = useSharedValue(1);
|
|
23
19
|
const waveScaleAnim = useSharedValue(1);
|
|
@@ -61,18 +57,14 @@ const BadgeDotAnimation = ({ size, style }: BadgeDotProps) => {
|
|
|
61
57
|
};
|
|
62
58
|
}, [scaleAnim, waveOpacityAnim, waveScaleAnim]);
|
|
63
59
|
|
|
64
|
-
const waveAnimatedStyle = useAnimatedStyle(() => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
});
|
|
60
|
+
const waveAnimatedStyle = useAnimatedStyle(() => ({
|
|
61
|
+
transform: [{ scale: waveScaleAnim.value }],
|
|
62
|
+
opacity: waveOpacityAnim.value,
|
|
63
|
+
}));
|
|
70
64
|
|
|
71
|
-
const dotAnimatedStyle = useAnimatedStyle(() => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
};
|
|
75
|
-
});
|
|
65
|
+
const dotAnimatedStyle = useAnimatedStyle(() => ({
|
|
66
|
+
transform: [{ scale: scaleAnim.value }],
|
|
67
|
+
}));
|
|
76
68
|
|
|
77
69
|
return (
|
|
78
70
|
<View style={[styles.dotAnimationContainer, style]}>
|
package/Badge/BadgeRibbon.tsx
CHANGED
|
@@ -8,10 +8,6 @@ import { Text } from '../Text';
|
|
|
8
8
|
import { Colors } from '../Consts';
|
|
9
9
|
import { Image } from '../Image';
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* Corner ribbon label in the warning color, skewed or `isRound`. Right-corner
|
|
13
|
-
* ribbons are rotated 180deg with the text counter-rotated to stay upright.
|
|
14
|
-
*/
|
|
15
11
|
const BadgeRibbon: FC<BadgeRibbonProps> = ({
|
|
16
12
|
position = 'top_right',
|
|
17
13
|
label = 'Label',
|
|
@@ -37,16 +33,39 @@ const BadgeRibbon: FC<BadgeRibbonProps> = ({
|
|
|
37
33
|
const textTransform = useMemo(() => [{ rotateZ: textRotate }], [textRotate]);
|
|
38
34
|
|
|
39
35
|
const ribbonTail = isUpTail ? <UpTail /> : <DownTail />;
|
|
40
|
-
const renderRoundContent = () =>
|
|
41
|
-
|
|
36
|
+
const renderRoundContent = () => (
|
|
37
|
+
<View
|
|
38
|
+
collapsable={false}
|
|
39
|
+
style={[
|
|
40
|
+
styles.ribbonContent,
|
|
41
|
+
{
|
|
42
|
+
backgroundColor: theme.colors.warning.primary,
|
|
43
|
+
marginTop: textMargin,
|
|
44
|
+
},
|
|
45
|
+
]}
|
|
46
|
+
>
|
|
47
|
+
<View
|
|
48
|
+
collapsable={false}
|
|
49
|
+
style={[styles.ribbonLabelWrapper, { transform: textTransform }]}
|
|
50
|
+
>
|
|
51
|
+
<Text
|
|
52
|
+
style={styles.ribbonLabel}
|
|
53
|
+
color={Colors.black_01}
|
|
54
|
+
typography="label_xs_medium"
|
|
55
|
+
>
|
|
56
|
+
{label}
|
|
57
|
+
</Text>
|
|
58
|
+
</View>
|
|
59
|
+
</View>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const renderSkewContent = () => (
|
|
63
|
+
<View style={[styles.ribbonSkewRow, { marginTop: skewMargin }]}>
|
|
42
64
|
<View
|
|
43
65
|
collapsable={false}
|
|
44
66
|
style={[
|
|
45
|
-
styles.
|
|
46
|
-
{
|
|
47
|
-
backgroundColor: theme.colors.warning.primary,
|
|
48
|
-
marginTop: textMargin,
|
|
49
|
-
},
|
|
67
|
+
styles.ribbonSkewContent,
|
|
68
|
+
{ backgroundColor: theme.colors.warning.primary },
|
|
50
69
|
]}
|
|
51
70
|
>
|
|
52
71
|
<View
|
|
@@ -62,41 +81,14 @@ const BadgeRibbon: FC<BadgeRibbonProps> = ({
|
|
|
62
81
|
</Text>
|
|
63
82
|
</View>
|
|
64
83
|
</View>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
style={[
|
|
74
|
-
styles.ribbonSkewContent,
|
|
75
|
-
{ backgroundColor: theme.colors.warning.primary },
|
|
76
|
-
]}
|
|
77
|
-
>
|
|
78
|
-
<View
|
|
79
|
-
collapsable={false}
|
|
80
|
-
style={[styles.ribbonLabelWrapper, { transform: textTransform }]}
|
|
81
|
-
>
|
|
82
|
-
<Text
|
|
83
|
-
style={styles.ribbonLabel}
|
|
84
|
-
color={Colors.black_01}
|
|
85
|
-
typography="label_xs_medium"
|
|
86
|
-
>
|
|
87
|
-
{label}
|
|
88
|
-
</Text>
|
|
89
|
-
</View>
|
|
90
|
-
</View>
|
|
91
|
-
<Image
|
|
92
|
-
source={{
|
|
93
|
-
uri: 'https://static.momocdn.net/app/img/kits/utils/Tail_4x.png',
|
|
94
|
-
}}
|
|
95
|
-
style={styles.skew}
|
|
96
|
-
/>
|
|
97
|
-
</View>
|
|
98
|
-
);
|
|
99
|
-
};
|
|
84
|
+
<Image
|
|
85
|
+
source={{
|
|
86
|
+
uri: 'https://static.momocdn.net/app/img/kits/utils/Tail_4x.png',
|
|
87
|
+
}}
|
|
88
|
+
style={styles.skew}
|
|
89
|
+
/>
|
|
90
|
+
</View>
|
|
91
|
+
);
|
|
100
92
|
|
|
101
93
|
const content = isRound ? renderRoundContent() : renderSkewContent();
|
|
102
94
|
|
package/Badge/Shape.tsx
CHANGED
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import styles from './styles';
|
|
3
3
|
import {Image} from '../Image';
|
|
4
4
|
|
|
5
|
-
/** Ribbon tail image pointing up (the down tail rotated 180deg). */
|
|
6
5
|
const UpTail = () => {
|
|
7
6
|
return (
|
|
8
7
|
<Image
|
|
@@ -15,7 +14,6 @@ const UpTail = () => {
|
|
|
15
14
|
);
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
/** Ribbon tail image pointing down. */
|
|
19
17
|
const DownTail = () => {
|
|
20
18
|
return (
|
|
21
19
|
<Image
|
package/Badge/types.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {ViewStyle} from 'react-native';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Props for a Badge component. It
|
|
4
|
+
* Props for a general Badge component. It can display a wide range of badges including simple labels, numbers, or dots.
|
|
5
5
|
*/
|
|
6
6
|
export type BadgeProps = {
|
|
7
7
|
/**
|
|
@@ -20,7 +20,7 @@ export type BadgeProps = {
|
|
|
20
20
|
backgroundColor?: string;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
*
|
|
24
24
|
*/
|
|
25
25
|
accessibilityLabel?: string;
|
|
26
26
|
};
|
package/Button/index.tsx
CHANGED
|
@@ -63,11 +63,6 @@ export interface ButtonProps extends TouchableOpacityProps {
|
|
|
63
63
|
params?: any;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
/**
|
|
67
|
-
* Design-system button: `type` sets the colors, `size` the height and text,
|
|
68
|
-
* and `loading` swaps an icon slot for a spinner. Primary buttons use the mini
|
|
69
|
-
* app gradient from `config.navigationBar.buttonColors` when set.
|
|
70
|
-
*/
|
|
71
66
|
const Button: FC<ButtonProps> = ({
|
|
72
67
|
type = 'primary',
|
|
73
68
|
size = 'large',
|
|
@@ -95,21 +90,33 @@ const Button: FC<ButtonProps> = ({
|
|
|
95
90
|
rest.accessibilityLabel,
|
|
96
91
|
);
|
|
97
92
|
|
|
93
|
+
/**
|
|
94
|
+
* animate press in (Reanimated)
|
|
95
|
+
*/
|
|
98
96
|
const animateIn = (event: GestureResponderEvent) => {
|
|
99
97
|
rest?.onPressIn?.(event);
|
|
100
98
|
pressAnim.value = withTiming(1, { duration: 100 });
|
|
101
99
|
};
|
|
102
100
|
|
|
101
|
+
/**
|
|
102
|
+
* animate press out (Reanimated)
|
|
103
|
+
*/
|
|
103
104
|
const animateOut = (event: GestureResponderEvent) => {
|
|
104
105
|
rest?.onPressOut?.(event);
|
|
105
106
|
pressAnim.value = withTiming(0, { duration: 100 });
|
|
106
107
|
};
|
|
107
108
|
|
|
109
|
+
/**
|
|
110
|
+
* export size style
|
|
111
|
+
*/
|
|
108
112
|
const getSizeStyle = () => {
|
|
109
113
|
const styleSheet: { [key: string]: any } = styles;
|
|
110
114
|
return styleSheet[size ?? 'small'];
|
|
111
115
|
};
|
|
112
116
|
|
|
117
|
+
/**
|
|
118
|
+
* render title
|
|
119
|
+
*/
|
|
113
120
|
const renderTitle = () => {
|
|
114
121
|
const typography = getTypography(size);
|
|
115
122
|
const textColor = getTextColor(type, theme, color);
|
|
@@ -120,6 +127,10 @@ const Button: FC<ButtonProps> = ({
|
|
|
120
127
|
);
|
|
121
128
|
};
|
|
122
129
|
|
|
130
|
+
/**
|
|
131
|
+
* render icon
|
|
132
|
+
* @param position
|
|
133
|
+
*/
|
|
123
134
|
const renderIcon = (position: 'left' | 'right') => {
|
|
124
135
|
const iconSize = getIconSize(size);
|
|
125
136
|
const space = getIconSpace(size);
|
package/Button/utils.ts
CHANGED
|
@@ -4,8 +4,10 @@ import { Typography } from '../Text/types';
|
|
|
4
4
|
import { ButtonProps } from './index';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* determine loading position
|
|
8
|
+
* @param left
|
|
9
|
+
* @param right
|
|
10
|
+
* @param isLeft
|
|
9
11
|
*/
|
|
10
12
|
export const shouldShowLoading = (
|
|
11
13
|
left?: string,
|
|
@@ -21,8 +23,7 @@ export const shouldShowLoading = (
|
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
|
-
*
|
|
25
|
-
* overrides the outline border.
|
|
26
|
+
* export type style
|
|
26
27
|
*/
|
|
27
28
|
export const getTypeStyle = (
|
|
28
29
|
type: ButtonProps['type'],
|
|
@@ -63,7 +64,9 @@ export const getTypeStyle = (
|
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
66
|
|
|
66
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* export icon size
|
|
69
|
+
*/
|
|
67
70
|
export const getIconSize = (size: ButtonProps['size']) => {
|
|
68
71
|
switch (size) {
|
|
69
72
|
case 'large':
|
|
@@ -76,7 +79,9 @@ export const getIconSize = (size: ButtonProps['size']) => {
|
|
|
76
79
|
}
|
|
77
80
|
};
|
|
78
81
|
|
|
79
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* export icon space
|
|
84
|
+
*/
|
|
80
85
|
export const getIconSpace = (size: ButtonProps['size']) => {
|
|
81
86
|
switch (size) {
|
|
82
87
|
case 'large':
|
|
@@ -89,7 +94,9 @@ export const getIconSpace = (size: ButtonProps['size']) => {
|
|
|
89
94
|
}
|
|
90
95
|
};
|
|
91
96
|
|
|
92
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* export typography style
|
|
99
|
+
*/
|
|
93
100
|
export const getTypography = (size: ButtonProps['size']): Typography => {
|
|
94
101
|
switch (size) {
|
|
95
102
|
case 'large':
|
|
@@ -104,8 +111,7 @@ export const getTypography = (size: ButtonProps['size']): Typography => {
|
|
|
104
111
|
};
|
|
105
112
|
|
|
106
113
|
/**
|
|
107
|
-
*
|
|
108
|
-
* overrides the outline and text types.
|
|
114
|
+
* export text color
|
|
109
115
|
*/
|
|
110
116
|
export const getTextColor = (
|
|
111
117
|
type: ButtonProps['type'],
|
package/CheckBox/index.tsx
CHANGED
|
@@ -11,10 +11,6 @@ import {
|
|
|
11
11
|
import { Text } from '../Text';
|
|
12
12
|
import { Icon } from '../Icon';
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* Checkbox with an optional label. `indeterminate` shows a minus icon and is
|
|
16
|
-
* styled and announced as checked.
|
|
17
|
-
*/
|
|
18
14
|
const CheckBox: FC<CheckBoxProps> = ({
|
|
19
15
|
value,
|
|
20
16
|
disabled = false,
|
package/Consts/theme.ts
CHANGED
|
@@ -62,22 +62,22 @@ const defaultDarkTheme: Theme = {
|
|
|
62
62
|
secondary: Colors.pink_08,
|
|
63
63
|
gradient: '#FDCADE',
|
|
64
64
|
background: {
|
|
65
|
-
default: '#121212',
|
|
66
|
-
surface: '#1e1e1e',
|
|
65
|
+
default: '#121212', // Dark background
|
|
66
|
+
surface: '#1e1e1e', // Slightly lighter surface background
|
|
67
67
|
tonal: Colors.pink_10,
|
|
68
|
-
pressed: '#1a1a1a',
|
|
68
|
+
pressed: '#1a1a1a', // Pressed state background
|
|
69
69
|
selected: Colors.pink_11,
|
|
70
|
-
disable: '#303030',
|
|
70
|
+
disable: '#303030', // Disabled state background
|
|
71
71
|
},
|
|
72
72
|
text: {
|
|
73
|
-
default: '#ffffff',
|
|
74
|
-
secondary: '#b0b0b0',
|
|
75
|
-
hint: '#727272',
|
|
76
|
-
disable: '#505050',
|
|
73
|
+
default: '#ffffff', // White text for better contrast
|
|
74
|
+
secondary: '#b0b0b0', // Light gray secondary text
|
|
75
|
+
hint: '#727272', // Hint text color
|
|
76
|
+
disable: '#505050', // Disabled text color
|
|
77
77
|
},
|
|
78
78
|
border: {
|
|
79
|
-
default: '#2a2a2a',
|
|
80
|
-
disable: '#242424',
|
|
79
|
+
default: '#2a2a2a', // Darker borders
|
|
80
|
+
disable: '#242424', // Disabled state border color
|
|
81
81
|
},
|
|
82
82
|
success: {
|
|
83
83
|
primary: Colors.green_03,
|
package/Context/index.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { defaultContext } from '../Consts';
|
|
|
5
5
|
const Context = createContext({});
|
|
6
6
|
const ApplicationContext = createContext(defaultContext);
|
|
7
7
|
|
|
8
|
-
// Shared by the host app via `Platform`; standalone falls back to a local one.
|
|
9
8
|
const MiniAppContext = (Platform as any).MiniAppContext ?? Context;
|
|
10
9
|
const ScreenContext = (Platform as any).ScreenContext ?? Context;
|
|
11
10
|
const ComponentContext = (Platform as any).ComponentContext ?? Context;
|
package/Divider/DashDivider.tsx
CHANGED
|
@@ -11,7 +11,6 @@ export interface DashDividerProps {
|
|
|
11
11
|
style?: ViewStyle;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/** 1px dashed horizontal line in the default border color. */
|
|
15
14
|
const DashDivider: React.FC<DashDividerProps> = ({ style }) => {
|
|
16
15
|
const { theme } = useContext(ApplicationContext);
|
|
17
16
|
const borderColor = theme.colors.border.default;
|
package/Divider/index.tsx
CHANGED
|
@@ -18,10 +18,6 @@ export interface DividerProps {
|
|
|
18
18
|
type?: 'dash' | 'default';
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
* 1px horizontal line in the default border color. `type='dash'` renders
|
|
23
|
-
* `DashDivider`, which always has a 4px vertical margin.
|
|
24
|
-
*/
|
|
25
21
|
const Divider: React.FC<DividerProps> = ({
|
|
26
22
|
style,
|
|
27
23
|
useMargin = true,
|
package/FoundationList/index.tsx
CHANGED
|
@@ -5,10 +5,6 @@ import { FlatListProps } from 'react-native';
|
|
|
5
5
|
type CombinedListProps<ItemT> = FlatListProps<ItemT> &
|
|
6
6
|
Partial<FlashListProps<ItemT>>;
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* FlashList typed to also accept FlatList props, so FlatList call sites can
|
|
10
|
-
* switch to it without type changes.
|
|
11
|
-
*/
|
|
12
8
|
const FoundationList = <ItemT,>(props: CombinedListProps<ItemT>) => {
|
|
13
9
|
return <FlashList {...props} />;
|
|
14
10
|
};
|