@momo-kits/foundation 0.169.6 → 0.169.7-beta.10
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 +37 -40
- package/Application/BottomTab/ActiveIndicator.tsx +14 -15
- package/Application/BottomTab/BottomTabBar.tsx +62 -49
- package/Application/BottomTab/BottomTabInset.tsx +4 -8
- package/Application/BottomTab/CurvedContainer.tsx +12 -14
- package/Application/BottomTab/CustomBottomTabItem.tsx +13 -13
- package/Application/BottomTab/DuoBarCompression.tsx +19 -13
- package/Application/BottomTab/DuoRailTabBar.tsx +24 -20
- package/Application/BottomTab/DuoTabBar.tsx +10 -8
- package/Application/BottomTab/TabBarIcon.tsx +29 -15
- package/Application/BottomTab/TabScreen.tsx +5 -1
- package/Application/BottomTab/index.tsx +30 -33
- package/Application/BottomTab/metrics.ts +23 -23
- 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/KitAdoption/AdoptionBadge.tsx +119 -0
- package/Application/KitAdoption/AdoptionProbe.tsx +166 -0
- package/Application/KitAdoption/AdoptionStore.ts +80 -0
- package/Application/KitAdoption/Authorship/utils.ts +137 -0
- package/Application/KitAdoption/Slots/utils.ts +68 -0
- package/Application/KitAdoption/constants.ts +120 -0
- package/Application/KitAdoption/index.ts +12 -0
- package/Application/KitAdoption/styles.ts +55 -0
- package/Application/KitAdoption/types.ts +61 -0
- package/Application/KitAdoption/utils.ts +376 -0
- package/Application/Localize.ts +0 -7
- package/Application/ModalScreen.tsx +10 -10
- package/Application/Navigation.ts +16 -14
- package/Application/NavigationContainer.tsx +18 -19
- package/Application/Navigator.ts +48 -20
- package/Application/ScaleSizeProvider.tsx +6 -13
- package/Application/StackScreen.tracking.ts +33 -11
- package/Application/StackScreen.tsx +54 -10
- package/Application/TooltipPortal.tsx +5 -12
- package/Application/WidgetContainer.tsx +4 -10
- package/Application/__tests__/KitAdoption.integration.test.tsx +253 -0
- package/Application/__tests__/KitAdoption.test.ts +283 -0
- package/Application/__tests__/KitAdoptionAuthorship.test.ts +132 -0
- package/Application/__tests__/KitAdoptionStore.test.ts +110 -0
- package/Application/__tests__/KitAdoptionStructural.test.ts +193 -0
- package/Application/__tests__/modalLayout.test.ts +128 -0
- package/Application/modalLayout.ts +14 -13
- package/Application/navigationOptions.tsx +17 -21
- 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 +1 -5
- 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 +13 -16
- 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 +13 -17
- package/Layout/TrackingScope.tsx +0 -1
- package/Layout/constants.ts +19 -0
- 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 +41 -3
- package/Layout/useGridSystem.ts +49 -0
- package/Layout/utils.ts +37 -38
- 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 +4 -20
- package/Title/index.tsx +32 -41
- package/ViewBoundary/index.tsx +2 -4
- package/index.ts +6 -0
- package/package.json +1 -1
package/Layout/screenHeader.tsx
CHANGED
|
@@ -31,10 +31,6 @@ type ScreenHeaderParams = {
|
|
|
31
31
|
layoutOffset: number;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
/**
|
|
35
|
-
* Applies the Screen's navigation header (plain, extended, animated banner or search) and
|
|
36
|
-
* re-applies it when those props change. Returns the search header setter and the tint.
|
|
37
|
-
*/
|
|
38
34
|
export const useScreenHeader = ({
|
|
39
35
|
navigation,
|
|
40
36
|
layout,
|
|
@@ -52,7 +48,10 @@ export const useScreenHeader = ({
|
|
|
52
48
|
const currentTint = useRef<string | undefined>(undefined);
|
|
53
49
|
const appliedHeaderMode = useRef<string | undefined>(undefined);
|
|
54
50
|
|
|
55
|
-
|
|
51
|
+
/**
|
|
52
|
+
* export options for screen
|
|
53
|
+
* @param type
|
|
54
|
+
*/
|
|
56
55
|
const setHeaderType = useCallback(
|
|
57
56
|
(type: HeaderType, keepTitle = false) => {
|
|
58
57
|
let options: StackNavigationOptions;
|
|
@@ -70,12 +69,10 @@ export const useScreenHeader = ({
|
|
|
70
69
|
...quickReturnOptions,
|
|
71
70
|
headerShown: true,
|
|
72
71
|
headerTransparent: true,
|
|
73
|
-
headerBackground: () =>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return <DuoGlassBackground animatedValue={sharedValue} />;
|
|
78
|
-
},
|
|
72
|
+
headerBackground: () =>
|
|
73
|
+
hasSideBar ? (
|
|
74
|
+
<DuoGlassBackground animatedValue={sharedValue} />
|
|
75
|
+
) : null,
|
|
79
76
|
headerTitle: (props: any) => <HeaderTitle {...props} />,
|
|
80
77
|
};
|
|
81
78
|
if (inputSearchProps) {
|
|
@@ -163,7 +160,10 @@ export const useScreenHeader = ({
|
|
|
163
160
|
],
|
|
164
161
|
);
|
|
165
162
|
|
|
166
|
-
|
|
163
|
+
/**
|
|
164
|
+
* export animatedHeader options for screen
|
|
165
|
+
* @param nextAnimatedHeader
|
|
166
|
+
*/
|
|
167
167
|
const setAnimatedHeader = useCallback(
|
|
168
168
|
(nextAnimatedHeader: AnimatedHeader) => {
|
|
169
169
|
let options: StackNavigationOptions;
|
|
@@ -175,16 +175,13 @@ export const useScreenHeader = ({
|
|
|
175
175
|
...quickReturnOptions,
|
|
176
176
|
headerTintColor: currentTint.current ?? Colors.black_17,
|
|
177
177
|
headerTransparent: true,
|
|
178
|
-
headerBackground: (props: any) =>
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
return (
|
|
178
|
+
headerBackground: (props: any) =>
|
|
179
|
+
hasSideBar ? (
|
|
180
|
+
<DuoGlassBackground
|
|
181
|
+
animatedValue={sharedValue}
|
|
182
|
+
bannerBottom={ANIMATED_BANNER_HEIGHT + layoutOffset}
|
|
183
|
+
/>
|
|
184
|
+
) : (
|
|
188
185
|
<HeaderBackground
|
|
189
186
|
{...props}
|
|
190
187
|
animatedValue={sharedValue}
|
|
@@ -193,8 +190,7 @@ export const useScreenHeader = ({
|
|
|
193
190
|
headerBackground={headerBackground}
|
|
194
191
|
gradientColor={gradientColor}
|
|
195
192
|
/>
|
|
196
|
-
)
|
|
197
|
-
},
|
|
193
|
+
),
|
|
198
194
|
headerTitle: (props: any) => {
|
|
199
195
|
return <HeaderTitle {...props} />;
|
|
200
196
|
},
|
|
@@ -221,6 +217,9 @@ export const useScreenHeader = ({
|
|
|
221
217
|
],
|
|
222
218
|
);
|
|
223
219
|
|
|
220
|
+
/**
|
|
221
|
+
* export animatedHeader options for screen
|
|
222
|
+
*/
|
|
224
223
|
const setAnimatedSearch = useCallback(() => {
|
|
225
224
|
const options: StackNavigationOptions = {
|
|
226
225
|
headerShown: true,
|
|
@@ -241,7 +240,9 @@ export const useScreenHeader = ({
|
|
|
241
240
|
navigation?.instance?.setOptions({ header: undefined, ...options });
|
|
242
241
|
}, [navigation?.instance, sharedValue]);
|
|
243
242
|
|
|
244
|
-
|
|
243
|
+
/**
|
|
244
|
+
* export search header
|
|
245
|
+
*/
|
|
245
246
|
const setSearchHeader = (params: SearchHeaderProps) => {
|
|
246
247
|
let searchWidth = layout.width - 24;
|
|
247
248
|
let searchLeft = Spacing.M;
|
|
@@ -249,9 +250,9 @@ export const useScreenHeader = ({
|
|
|
249
250
|
searchWidth = layout.contentWidth - Spacing.M * 2;
|
|
250
251
|
searchLeft = Spacing.M - getHeaderMargin(layout.width);
|
|
251
252
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
if (layout.statusBarClearance) {
|
|
254
|
+
searchWidth -=
|
|
255
|
+
layout.statusBarClearance.left + layout.statusBarClearance.right;
|
|
255
256
|
}
|
|
256
257
|
const options: StackNavigationOptions = {
|
|
257
258
|
headerRight: undefined,
|
|
@@ -266,12 +267,8 @@ export const useScreenHeader = ({
|
|
|
266
267
|
margin: 0,
|
|
267
268
|
left: searchLeft,
|
|
268
269
|
},
|
|
269
|
-
headerLeft: (props: any) =>
|
|
270
|
-
|
|
271
|
-
return null;
|
|
272
|
-
}
|
|
273
|
-
return <HeaderLeft {...props} floating />;
|
|
274
|
-
},
|
|
270
|
+
headerLeft: (props: any) =>
|
|
271
|
+
params?.hiddenBack ? null : <HeaderLeft {...props} floating />,
|
|
275
272
|
headerTitle: () => (
|
|
276
273
|
<SearchHeader {...params} animatedValue={sharedValue} />
|
|
277
274
|
),
|
|
@@ -8,10 +8,6 @@ import {
|
|
|
8
8
|
} from 'react-native-reanimated';
|
|
9
9
|
import { DuoQuickReturnHeader } from '../Application/Components/DuoQuickReturnHeader';
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* iPhone Duo quick return header: it slides out while the content scrolls down and back
|
|
13
|
-
* on scroll up. Returns the header options and a snap to call when scrolling ends.
|
|
14
|
-
*/
|
|
15
11
|
export const useScreenQuickReturn = (
|
|
16
12
|
sharedValue: SharedValue<number>,
|
|
17
13
|
useQuickReturn: boolean,
|
|
@@ -37,22 +33,29 @@ export const useScreenQuickReturn = (
|
|
|
37
33
|
[useQuickReturn, heightHeader],
|
|
38
34
|
);
|
|
39
35
|
|
|
40
|
-
const quickReturnOptions: StackNavigationOptions = useMemo(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
const quickReturnOptions: StackNavigationOptions = useMemo(
|
|
37
|
+
() =>
|
|
38
|
+
useQuickReturn
|
|
39
|
+
? {
|
|
40
|
+
header: (props: any) => (
|
|
41
|
+
<DuoQuickReturnHeader {...props} offset={headerHide} />
|
|
42
|
+
),
|
|
43
|
+
}
|
|
44
|
+
: { header: undefined },
|
|
45
|
+
[useQuickReturn, headerHide],
|
|
46
|
+
);
|
|
50
47
|
|
|
51
|
-
|
|
48
|
+
/**
|
|
49
|
+
* a half-shown quick return header settles fully in or out
|
|
50
|
+
*/
|
|
52
51
|
const snapQuickReturnHeader = (offsetY: number) => {
|
|
53
52
|
const hide = headerHide.value;
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
if (
|
|
54
|
+
!useQuickReturn ||
|
|
55
|
+
offsetY < heightHeader ||
|
|
56
|
+
hide <= 0 ||
|
|
57
|
+
hide >= heightHeader
|
|
58
|
+
) {
|
|
56
59
|
return;
|
|
57
60
|
}
|
|
58
61
|
headerHide.value = withTiming(hide > heightHeader / 2 ? heightHeader : 0, {
|
package/Layout/screenScroll.ts
CHANGED
|
@@ -25,10 +25,6 @@ type ScrollHandlerParams = {
|
|
|
25
25
|
ref: any;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* Scroll handlers for Screen: feed the header animated values, retint an animated header
|
|
30
|
-
* past 50pt, snap the quick return header and reset a search screen scrolled under 100pt.
|
|
31
|
-
*/
|
|
32
28
|
export const createScrollHandlers = ({
|
|
33
29
|
scrollable,
|
|
34
30
|
animatedValue,
|
|
@@ -43,6 +39,9 @@ export const createScrollHandlers = ({
|
|
|
43
39
|
}: ScrollHandlerParams) => {
|
|
44
40
|
let handleScroll;
|
|
45
41
|
|
|
42
|
+
/**
|
|
43
|
+
* animated when use scroll && animated value
|
|
44
|
+
*/
|
|
46
45
|
if (scrollable) {
|
|
47
46
|
handleScroll = Animated.event(
|
|
48
47
|
[
|
|
@@ -81,6 +80,10 @@ export const createScrollHandlers = ({
|
|
|
81
80
|
);
|
|
82
81
|
}
|
|
83
82
|
|
|
83
|
+
/**
|
|
84
|
+
* handle scroll end
|
|
85
|
+
* @param e
|
|
86
|
+
*/
|
|
84
87
|
const handleMomentumScrollEnd = (
|
|
85
88
|
e: NativeSyntheticEvent<NativeScrollEvent>,
|
|
86
89
|
) => {
|
package/Layout/screenTypes.ts
CHANGED
|
@@ -38,7 +38,7 @@ export interface ScreenProps extends ViewProps {
|
|
|
38
38
|
headerType?: HeaderType;
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* Optional.
|
|
41
|
+
* Optional. Props for the animated component or bool used top navigation animated.
|
|
42
42
|
*/
|
|
43
43
|
animatedHeader?: AnimatedHeader;
|
|
44
44
|
|
|
@@ -71,8 +71,7 @@ export interface ScreenProps extends ViewProps {
|
|
|
71
71
|
backgroundColor?: string;
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* Optional.
|
|
75
|
-
* values overlap the banner.
|
|
74
|
+
* Optional. layout card offset overlap header banner.
|
|
76
75
|
*/
|
|
77
76
|
layoutOffset?: -8 | -24 | -56 | number;
|
|
78
77
|
|
package/Layout/types.ts
CHANGED
|
@@ -4,16 +4,54 @@ export type HeaderType = 'default' | 'extended' | 'none';
|
|
|
4
4
|
|
|
5
5
|
export type ScreenRef = {
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Set options for screen
|
|
8
|
+
* @param params
|
|
8
9
|
*/
|
|
9
10
|
setOptions: (params: NavigationOptions) => void;
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* Show search header
|
|
14
|
+
* @param params
|
|
13
15
|
*/
|
|
14
16
|
setSearchHeader: (params: SearchHeaderProps) => void;
|
|
15
17
|
};
|
|
16
|
-
export type SpanNumber =
|
|
18
|
+
export type SpanNumber =
|
|
19
|
+
| 1
|
|
20
|
+
| 2
|
|
21
|
+
| 3
|
|
22
|
+
| 4
|
|
23
|
+
| 5
|
|
24
|
+
| 6
|
|
25
|
+
| 7
|
|
26
|
+
| 8
|
|
27
|
+
| 9
|
|
28
|
+
| 10
|
|
29
|
+
| 11
|
|
30
|
+
| 12
|
|
31
|
+
| 13
|
|
32
|
+
| 14
|
|
33
|
+
| 15
|
|
34
|
+
| 16
|
|
35
|
+
| 17
|
|
36
|
+
| 18
|
|
37
|
+
| 19
|
|
38
|
+
| 20
|
|
39
|
+
| 21
|
|
40
|
+
| 22
|
|
41
|
+
| 23
|
|
42
|
+
| 24
|
|
43
|
+
| 25
|
|
44
|
+
| 26
|
|
45
|
+
| 27
|
|
46
|
+
| 28
|
|
47
|
+
| 29
|
|
48
|
+
| 30
|
|
49
|
+
| 31
|
|
50
|
+
| 32
|
|
51
|
+
| 33
|
|
52
|
+
| 34
|
|
53
|
+
| 35
|
|
54
|
+
| 36;
|
|
17
55
|
|
|
18
56
|
export type GridContextProps = {
|
|
19
57
|
/**
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GRID_DESKTOP_COLUMNS,
|
|
3
|
+
GRID_DESKTOP_MIN_WIDTH,
|
|
4
|
+
GRID_PHONE_COLUMNS,
|
|
5
|
+
GRID_PHONE_MAX_WIDTH,
|
|
6
|
+
GRID_TABLET_COLUMNS,
|
|
7
|
+
GRID_TABLET_MIN_WIDTH,
|
|
8
|
+
} from './constants';
|
|
9
|
+
import { useScreenLayout } from './utils';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Column count for a content width: 12 below 800pt, 24 below 1100pt, 36 from there
|
|
13
|
+
*/
|
|
14
|
+
const getGridColumns = (width: number) => {
|
|
15
|
+
if (width >= GRID_DESKTOP_MIN_WIDTH) {
|
|
16
|
+
return GRID_DESKTOP_COLUMNS;
|
|
17
|
+
}
|
|
18
|
+
if (width >= GRID_TABLET_MIN_WIDTH) {
|
|
19
|
+
return GRID_TABLET_COLUMNS;
|
|
20
|
+
}
|
|
21
|
+
return GRID_PHONE_COLUMNS;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Grid width for a content width: the 12-column grid stops at 600pt and is centered,
|
|
26
|
+
* the wider grids fill the content
|
|
27
|
+
*/
|
|
28
|
+
const getGridWidth = (width: number) => {
|
|
29
|
+
if (width < GRID_TABLET_MIN_WIDTH) {
|
|
30
|
+
return Math.min(width, GRID_PHONE_MAX_WIDTH);
|
|
31
|
+
}
|
|
32
|
+
return width;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Grid for the current content width: column count, grid width and the horizontal
|
|
37
|
+
* offset that centers a grid narrower than the content
|
|
38
|
+
*/
|
|
39
|
+
const useGridSystem = () => {
|
|
40
|
+
const { contentWidth } = useScreenLayout();
|
|
41
|
+
const gridWidth = getGridWidth(contentWidth);
|
|
42
|
+
return {
|
|
43
|
+
numberOfColumns: getGridColumns(contentWidth),
|
|
44
|
+
gridWidth,
|
|
45
|
+
gridOffset: (contentWidth - gridWidth) / 2,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { useGridSystem };
|
package/Layout/utils.ts
CHANGED
|
@@ -15,8 +15,9 @@ import {
|
|
|
15
15
|
import { ReservedRegion, ReservedRegionsContext } from './ReservedRegions';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
* children
|
|
18
|
+
* validate children type
|
|
19
|
+
* @param children
|
|
20
|
+
* @param childrenTypes
|
|
20
21
|
*/
|
|
21
22
|
const validateChildren = (
|
|
22
23
|
children: React.ReactNode | React.ReactNode[],
|
|
@@ -53,20 +54,20 @@ const validateChildren = (
|
|
|
53
54
|
const NO_INSETS: EdgeInsets = { top: 0, right: 0, bottom: 0, left: 0 };
|
|
54
55
|
|
|
55
56
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* furthest from the top
|
|
57
|
+
* how far system regions reach into a side strip from its top and from its bottom end
|
|
58
|
+
* (e.g. the camera, which sits at either end depending on the rotation), and the center
|
|
59
|
+
* y of the region reaching furthest from the top
|
|
59
60
|
*/
|
|
60
61
|
const getStripOcclusion = (
|
|
61
62
|
regions: ReservedRegion[],
|
|
62
63
|
stripLeft: number,
|
|
63
64
|
stripRight: number,
|
|
64
65
|
windowHeight: number,
|
|
65
|
-
) =>
|
|
66
|
-
|
|
66
|
+
) =>
|
|
67
|
+
regions.reduce(
|
|
67
68
|
(occlusion, region) => {
|
|
68
|
-
const
|
|
69
|
-
|
|
69
|
+
const overlapsStrip =
|
|
70
|
+
region.x < stripRight && region.x + region.width > stripLeft;
|
|
70
71
|
if (!overlapsStrip) {
|
|
71
72
|
return occlusion;
|
|
72
73
|
}
|
|
@@ -83,11 +84,10 @@ const getStripOcclusion = (
|
|
|
83
84
|
},
|
|
84
85
|
{ top: 0, topCenter: 0, bottom: 0 },
|
|
85
86
|
);
|
|
86
|
-
};
|
|
87
87
|
|
|
88
88
|
/**
|
|
89
|
-
*
|
|
90
|
-
* each side. `undefined` without reserved regions there
|
|
89
|
+
* how far the clock and battery clusters of a status bar on the top edge reach in from
|
|
90
|
+
* each side. `undefined` without reserved regions there
|
|
91
91
|
*/
|
|
92
92
|
const getStatusBarClusters = (
|
|
93
93
|
regions: ReservedRegion[],
|
|
@@ -95,11 +95,12 @@ const getStatusBarClusters = (
|
|
|
95
95
|
topInset: number,
|
|
96
96
|
) => {
|
|
97
97
|
const midX = windowWidth / 2;
|
|
98
|
-
const clusters = regions.filter(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
const clusters = regions.filter(
|
|
99
|
+
region =>
|
|
100
|
+
region.y < topInset &&
|
|
101
|
+
region.y + region.height <= topInset &&
|
|
102
|
+
(region.x + region.width <= midX || region.x >= midX),
|
|
103
|
+
);
|
|
103
104
|
if (!clusters.length) {
|
|
104
105
|
return undefined;
|
|
105
106
|
}
|
|
@@ -117,10 +118,8 @@ const getStatusBarClusters = (
|
|
|
117
118
|
);
|
|
118
119
|
};
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return Platform.OS === 'ios' && Platform.constants.interfaceIdiom === 'phone';
|
|
123
|
-
};
|
|
121
|
+
const isIPhone = () =>
|
|
122
|
+
Platform.OS === 'ios' && Platform.constants.interfaceIdiom === 'phone';
|
|
124
123
|
|
|
125
124
|
/**
|
|
126
125
|
* Header height and the room it keeps above the bar row for the status bar. On iPhone the
|
|
@@ -142,7 +141,7 @@ const getHeaderLayout = (topInset: number) => {
|
|
|
142
141
|
|
|
143
142
|
/**
|
|
144
143
|
* Header whose bar row is centered on a window y, at least iPhoneMinHeight tall and
|
|
145
|
-
* reaching 8pt below a side bar control centered there
|
|
144
|
+
* reaching 8pt below a side bar control centered there
|
|
146
145
|
*/
|
|
147
146
|
const getCenteredHeaderLayout = (centerY: number) => {
|
|
148
147
|
const headerHeight = Math.max(
|
|
@@ -222,7 +221,8 @@ const useScreenLayout = (): ScreenLayout => {
|
|
|
222
221
|
if (sideInset >= DuoMetrics.controlSize + Spacing.M) {
|
|
223
222
|
const edge = insets.right >= insets.left ? 'right' : 'left';
|
|
224
223
|
const stripLeft = edge === 'right' ? width - sideInset : 0;
|
|
225
|
-
// clear the camera and status bar cluster
|
|
224
|
+
// keep controls clear of the camera and of the status bar cluster, which grows for
|
|
225
|
+
// calls and Live Activities. Region frames already include the system's margin
|
|
226
226
|
const occlusion = getStripOcclusion(
|
|
227
227
|
reservedRegions,
|
|
228
228
|
stripLeft,
|
|
@@ -242,7 +242,8 @@ const useScreenLayout = (): ScreenLayout => {
|
|
|
242
242
|
} else if (height >= DuoMetrics.innerMinHeight) {
|
|
243
243
|
top = DuoMetrics.firstItemTopLandscape;
|
|
244
244
|
} else {
|
|
245
|
-
// outer landscape:
|
|
245
|
+
// outer display in landscape: no status bar in the strip, the title row centers
|
|
246
|
+
// on the camera when it sits at the top end, otherwise on the back button
|
|
246
247
|
top = DuoMetrics.edgeInset;
|
|
247
248
|
const cameraAtTop = occlusion.top > top;
|
|
248
249
|
const backCenterY = top + DuoMetrics.controlSize / 2;
|
|
@@ -284,7 +285,7 @@ const useScreenLayout = (): ScreenLayout => {
|
|
|
284
285
|
|
|
285
286
|
/**
|
|
286
287
|
* Header row options for react-navigation: its height, the room for the status bar, and
|
|
287
|
-
* on iPhone Duo inner portrait the buttons kept clear of the clock and battery clusters
|
|
288
|
+
* on iPhone Duo inner portrait the buttons kept clear of the clock and battery clusters
|
|
288
289
|
*/
|
|
289
290
|
const getHeaderRowOptions = ({
|
|
290
291
|
headerHeight,
|
|
@@ -304,7 +305,9 @@ const getHeaderRowOptions = ({
|
|
|
304
305
|
};
|
|
305
306
|
};
|
|
306
307
|
|
|
307
|
-
/**
|
|
308
|
+
/**
|
|
309
|
+
* Side margin @react-navigation/elements Header adds to its content row
|
|
310
|
+
*/
|
|
308
311
|
const getHeaderMargin = (width: number) => {
|
|
309
312
|
if (Platform.OS === 'ios' && width >= HeaderMetrics.largeWidth) {
|
|
310
313
|
return HeaderMetrics.largeMargin;
|
|
@@ -318,9 +321,11 @@ const InnerEdgeStyles: Record<SideBarEdge, ViewStyle> = {
|
|
|
318
321
|
};
|
|
319
322
|
|
|
320
323
|
/**
|
|
321
|
-
* Absolute style
|
|
322
|
-
*
|
|
324
|
+
* Absolute style that floats a header item into the side bar, relative to the header
|
|
325
|
+
* container (left or right) rendering it, 12pt from the strip's inner edge.
|
|
323
326
|
* `undefined` while there is no side bar.
|
|
327
|
+
* @param container header container rendering the item
|
|
328
|
+
* @param slot position in the side bar, 0 for back, 1 for the toolkit below it
|
|
324
329
|
*/
|
|
325
330
|
const useSideBarItemStyle = (
|
|
326
331
|
container: 'left' | 'right',
|
|
@@ -333,8 +338,10 @@ const useSideBarItemStyle = (
|
|
|
333
338
|
|
|
334
339
|
const margin = getHeaderMargin(width);
|
|
335
340
|
const columnLeft = sideBar.edge === 'left' ? 0 : width - sideBar.width;
|
|
336
|
-
const
|
|
337
|
-
|
|
341
|
+
const top =
|
|
342
|
+
sideBar.top -
|
|
343
|
+
headerStatusBarHeight +
|
|
344
|
+
slot * (DuoMetrics.controlSize + Spacing.M);
|
|
338
345
|
const innerEdgeStyle = InnerEdgeStyles[sideBar.edge];
|
|
339
346
|
|
|
340
347
|
if (container === 'left') {
|
|
@@ -357,13 +364,6 @@ const useSideBarItemStyle = (
|
|
|
357
364
|
};
|
|
358
365
|
};
|
|
359
366
|
|
|
360
|
-
/** Column count of the content grid: 24 on content wider than 600pt, otherwise 12. */
|
|
361
|
-
const useGridSystem = () => {
|
|
362
|
-
const { contentWidth } = useScreenLayout();
|
|
363
|
-
const numberOfColumns = contentWidth > 600 ? 24 : 12;
|
|
364
|
-
return { numberOfColumns };
|
|
365
|
-
};
|
|
366
|
-
|
|
367
367
|
export type { ScreenLayout, SideBarEdge, SideBarLayout, StatusBarClearance };
|
|
368
368
|
|
|
369
369
|
export {
|
|
@@ -372,7 +372,6 @@ export {
|
|
|
372
372
|
InnerEdgeStyles,
|
|
373
373
|
getHeaderMargin,
|
|
374
374
|
getHeaderRowOptions,
|
|
375
|
-
useGridSystem,
|
|
376
375
|
useScreenLayout,
|
|
377
376
|
useSideBarItemStyle,
|
|
378
377
|
validateChildren,
|
package/Loader/DotLoader.tsx
CHANGED
|
@@ -6,10 +6,6 @@ import { ApplicationContext } from '../Context';
|
|
|
6
6
|
import { hexToRGBA } from './utils';
|
|
7
7
|
import { LoaderProps } from './types';
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Three-dot Lottie loader recolored to `color` (theme primary by default).
|
|
11
|
-
* Recoloring mutates the shared animation JSON, so `Loader` remounts on change.
|
|
12
|
-
*/
|
|
13
9
|
const DotLoader: FC<LoaderProps> = ({ color, style }) => {
|
|
14
10
|
const { theme } = useContext(ApplicationContext);
|
|
15
11
|
|
package/Loader/Loader.tsx
CHANGED
|
@@ -3,10 +3,6 @@ import {LoaderProps} from './types';
|
|
|
3
3
|
import DotLoader from './DotLoader';
|
|
4
4
|
import Spinner from './Spinner';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Dot (default) or spinner loader. Keyed by `color` so a color change remounts
|
|
8
|
-
* the Lottie view with the recolored source.
|
|
9
|
-
*/
|
|
10
6
|
const Loader: FC<LoaderProps> = ({type = 'dot', ...props}) => {
|
|
11
7
|
if (type === 'spinner') {
|
|
12
8
|
return <Spinner {...props} key={props.color} />;
|
package/Loader/ProgressBar.tsx
CHANGED
|
@@ -9,7 +9,6 @@ import styles from './styles';
|
|
|
9
9
|
import { ProgressBarProps } from './types';
|
|
10
10
|
import { ApplicationContext } from '../Context';
|
|
11
11
|
|
|
12
|
-
/** Full-width bar that animates its fill to `percent`, clamped to 0–100. */
|
|
13
12
|
const ProgressBar: FC<ProgressBarProps> = ({ percent = 0, style }) => {
|
|
14
13
|
const { theme } = useContext(ApplicationContext);
|
|
15
14
|
const animation = useSharedValue(0);
|
package/Loader/Spinner.tsx
CHANGED
|
@@ -6,10 +6,6 @@ import { hexToRGBA } from './utils';
|
|
|
6
6
|
import { ApplicationContext } from '../Context';
|
|
7
7
|
import { LoaderProps } from './types';
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Lottie spinner recolored to `color` (theme primary by default).
|
|
11
|
-
* Recoloring mutates the shared animation JSON, so `Loader` remounts on change.
|
|
12
|
-
*/
|
|
13
9
|
const Spinner: FC<LoaderProps> = ({ color, style }) => {
|
|
14
10
|
const { theme } = useContext(ApplicationContext);
|
|
15
11
|
|
package/Loader/utils.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Converts `#rgb`/`#rrggbb` (the `#` is optional) to Lottie's `[r, g, b]` in
|
|
3
|
-
* 0–1, rounded to 3 decimals. Throws on an invalid hex.
|
|
4
|
-
*/
|
|
5
1
|
export const hexToRGBA = (hex: string) => {
|
|
6
2
|
const normalizedHex = hex.startsWith('#') ? hex.slice(1) : hex;
|
|
7
3
|
|
|
@@ -9,13 +5,13 @@ export const hexToRGBA = (hex: string) => {
|
|
|
9
5
|
throw new Error('Invalid HEX color.');
|
|
10
6
|
}
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
const expandedHex =
|
|
9
|
+
normalizedHex.length === 3
|
|
10
|
+
? normalizedHex
|
|
11
|
+
.split('')
|
|
12
|
+
.map(val => val + val)
|
|
13
|
+
.join('')
|
|
14
|
+
: normalizedHex;
|
|
19
15
|
|
|
20
16
|
const hexMatch = expandedHex.match(/.{2}/g);
|
|
21
17
|
|
package/Pagination/Dot.tsx
CHANGED
|
@@ -4,10 +4,6 @@ import styles from './styles';
|
|
|
4
4
|
import { DotProps } from './types';
|
|
5
5
|
import { ApplicationContext } from '../Context';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* One pagination dot: a wide bar in the caller's color when active, otherwise
|
|
9
|
-
* a small dot in the theme pressed color.
|
|
10
|
-
*/
|
|
11
7
|
const Dot: FC<DotProps> = ({ active, style }) => {
|
|
12
8
|
const { theme } = useContext(ApplicationContext);
|
|
13
9
|
const pressedColor = theme.colors.background.pressed;
|
|
@@ -6,7 +6,6 @@ import styles from './styles';
|
|
|
6
6
|
import { Spacing } from '../Consts';
|
|
7
7
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
8
8
|
|
|
9
|
-
/** Row of primary-color dots with the `activeIndex` dot widened. */
|
|
10
9
|
const PaginationDot: FC<ChildPaginationProps> = ({
|
|
11
10
|
dataLength = 2,
|
|
12
11
|
activeIndex = 0,
|
|
@@ -6,7 +6,6 @@ import { Text } from '../Text';
|
|
|
6
6
|
import { Colors } from '../Consts';
|
|
7
7
|
import { MiniAppContext } from '../Context';
|
|
8
8
|
|
|
9
|
-
/** `n/total` counter on a translucent dark pill. */
|
|
10
9
|
const PaginationNumber: FC<ChildPaginationProps> = ({
|
|
11
10
|
activeIndex = 0,
|
|
12
11
|
dataLength = 2,
|
|
@@ -15,16 +14,15 @@ const PaginationNumber: FC<ChildPaginationProps> = ({
|
|
|
15
14
|
const context = useContext<any>(MiniAppContext);
|
|
16
15
|
|
|
17
16
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
18
|
-
const pageLabel = `${activeIndex + 1}/${dataLength}`;
|
|
19
17
|
|
|
20
18
|
return (
|
|
21
19
|
<View
|
|
22
20
|
style={[style, styles.row, showBaseLineDebug && styles.debugBaseLine]}
|
|
23
21
|
>
|
|
24
22
|
<View style={styles.paginationNumberContainer}>
|
|
25
|
-
<Text color={Colors.black_01} typography={'label_default_medium'}>
|
|
26
|
-
|
|
27
|
-
</Text>
|
|
23
|
+
<Text color={Colors.black_01} typography={'label_default_medium'}>{`${
|
|
24
|
+
activeIndex + 1
|
|
25
|
+
}/${dataLength}`}</Text>
|
|
28
26
|
</View>
|
|
29
27
|
</View>
|
|
30
28
|
);
|
|
@@ -13,11 +13,6 @@ import { ApplicationContext, MiniAppContext } from '../Context';
|
|
|
13
13
|
|
|
14
14
|
const INDICATOR_WIDTH = 24;
|
|
15
15
|
const INDICATOR_CONTAINER_WIDTH = 72;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Horizontal scroll view with a small indicator that tracks the scroll offset.
|
|
19
|
-
* The indicator shows only when the content is wider than the view.
|
|
20
|
-
*/
|
|
21
16
|
const PaginationScroll: FC<ScrollIndicatorProps> = ({
|
|
22
17
|
style,
|
|
23
18
|
children,
|
|
@@ -6,7 +6,6 @@ import Dot from './Dot';
|
|
|
6
6
|
import { Colors, Spacing } from '../Consts';
|
|
7
7
|
import { MiniAppContext } from '../Context';
|
|
8
8
|
|
|
9
|
-
/** Pagination dots on a translucent dark pill, for use over images. */
|
|
10
9
|
const PaginationWhiteDot: FC<ChildPaginationProps> = ({
|
|
11
10
|
dataLength = 2,
|
|
12
11
|
activeIndex = 0,
|