@momo-kits/foundation 0.169.7-beta.2 → 0.169.7-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 -16
- 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 +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 +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/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,12 +4,14 @@ 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
|
};
|
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,7 +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
367
|
const useGridSystem = () => {
|
|
362
368
|
const { contentWidth } = useScreenLayout();
|
|
363
369
|
const numberOfColumns = contentWidth > 600 ? 24 : 12;
|
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,
|
package/Pagination/index.tsx
CHANGED
|
@@ -5,10 +5,6 @@ import PaginationDot from './PaginationDot';
|
|
|
5
5
|
import PaginationNumber from './PaginationNumber';
|
|
6
6
|
import PaginationScroll from './PaginationScroll';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Page indicator: `type` picks plain dots, dots on a dark pill or an `n/total`
|
|
10
|
-
* counter. `PaginationScroll` is the separate scroll-indicator variant.
|
|
11
|
-
*/
|
|
12
8
|
const Pagination: FC<PaginationProps> = props => {
|
|
13
9
|
const {type} = props;
|
|
14
10
|
|
package/Pagination/types.ts
CHANGED
|
@@ -5,9 +5,9 @@ export type PaginationProps = {
|
|
|
5
5
|
/**
|
|
6
6
|
* Optional. Defines the visual style of the Pagination component.
|
|
7
7
|
* - 'default': Represents the default style.
|
|
8
|
-
* - 'black_white': Represents
|
|
8
|
+
* - 'black_white': Represents a pagination that have black background.
|
|
9
9
|
* - 'number': Represents a style where pages are represented by numbers.
|
|
10
|
-
* - 'scroll':
|
|
10
|
+
* - 'scroll': Represents a scrollable style.
|
|
11
11
|
*/
|
|
12
12
|
type?: 'default' | 'black_white' | 'number' | 'scroll';
|
|
13
13
|
|
package/Popup/PopupNotify.tsx
CHANGED
|
@@ -11,13 +11,6 @@ import { useModalLayout } from '../Application/modalLayout';
|
|
|
11
11
|
import { ModalIconButton } from '../Application/ModalIconButton';
|
|
12
12
|
import { splitHighlightText } from './utils';
|
|
13
13
|
|
|
14
|
-
const MAX_ROW_TITLE_LENGTH = 12;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Notify popup body: optional image, title, description, error code and one or
|
|
18
|
-
* two actions. Actions close via `onRequestClose` if given, else pop the modal
|
|
19
|
-
* and then run the callback.
|
|
20
|
-
*/
|
|
21
14
|
const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
22
15
|
image,
|
|
23
16
|
title = 'Title',
|
|
@@ -50,6 +43,10 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
50
43
|
descriptionStyle = { maxHeight: scaledMaxHeight };
|
|
51
44
|
}
|
|
52
45
|
|
|
46
|
+
/**
|
|
47
|
+
* on action popup
|
|
48
|
+
* @param callback
|
|
49
|
+
*/
|
|
53
50
|
const onAction = (callback?: () => void) => {
|
|
54
51
|
if (typeof onRequestClose === 'function') {
|
|
55
52
|
onRequestClose?.(callback);
|
|
@@ -59,6 +56,9 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
59
56
|
}
|
|
60
57
|
};
|
|
61
58
|
|
|
59
|
+
/**
|
|
60
|
+
* build main action of popup
|
|
61
|
+
*/
|
|
62
62
|
const buildAction = () => {
|
|
63
63
|
const renderRow = () => {
|
|
64
64
|
return (
|
|
@@ -126,13 +126,10 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
126
126
|
};
|
|
127
127
|
|
|
128
128
|
if (buttonDirection === 'auto') {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const isLongSecondary = secondaryTitle.length > MAX_ROW_TITLE_LENGTH;
|
|
134
|
-
const isLongPrimary = primary.title.length > MAX_ROW_TITLE_LENGTH;
|
|
135
|
-
if (isLongSecondary || isLongPrimary) {
|
|
129
|
+
if (
|
|
130
|
+
secondary?.title &&
|
|
131
|
+
(secondary.title.length > 12 || primary.title.length > 12)
|
|
132
|
+
) {
|
|
136
133
|
return renderColumn();
|
|
137
134
|
}
|
|
138
135
|
return renderRow();
|
|
@@ -143,7 +140,9 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
143
140
|
return renderColumn();
|
|
144
141
|
};
|
|
145
142
|
|
|
146
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* build description text, highlighted keywords keep size/lineHeight and use weight 600
|
|
145
|
+
*/
|
|
147
146
|
const renderDescription = (text: string) => {
|
|
148
147
|
const segments = splitHighlightText(text, highlightText);
|
|
149
148
|
if (!segments) {
|
|
@@ -161,6 +160,9 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
161
160
|
});
|
|
162
161
|
};
|
|
163
162
|
|
|
163
|
+
/**
|
|
164
|
+
* build close action
|
|
165
|
+
*/
|
|
164
166
|
const buildCloseIcon = () => {
|
|
165
167
|
if (typeof onIconClose !== 'function') {
|
|
166
168
|
return null;
|
|
@@ -178,44 +180,48 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
178
180
|
);
|
|
179
181
|
};
|
|
180
182
|
|
|
181
|
-
const hasCloseIcon = typeof onIconClose === 'function';
|
|
182
|
-
// keeps the title clear of the close button on a text only popup
|
|
183
|
-
const titleStyle = !image && hasCloseIcon && styles.titleClearClose;
|
|
184
|
-
|
|
185
|
-
let descriptionContent: React.ReactNode = description;
|
|
186
|
-
if (typeof description === 'string') {
|
|
187
|
-
descriptionContent = (
|
|
188
|
-
<Text
|
|
189
|
-
accessibilityLabel={'description_popup_notify'}
|
|
190
|
-
typography={'body_default_regular'}
|
|
191
|
-
onTextLayout={({ nativeEvent: { lines } }) => {
|
|
192
|
-
const enableScroll = lines.length > 8.5;
|
|
193
|
-
if (enableScroll !== scrollContent) {
|
|
194
|
-
setScrollContent(enableScroll);
|
|
195
|
-
}
|
|
196
|
-
}}
|
|
197
|
-
>
|
|
198
|
-
{renderDescription(description)}
|
|
199
|
-
</Text>
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
183
|
const body = (
|
|
204
184
|
<>
|
|
205
185
|
{!!image && (
|
|
206
|
-
<Image
|
|
186
|
+
<Image
|
|
187
|
+
source={{ uri: image }}
|
|
188
|
+
style={[
|
|
189
|
+
styles.image,
|
|
190
|
+
{ borderTopLeftRadius: radius, borderTopRightRadius: radius },
|
|
191
|
+
]}
|
|
192
|
+
/>
|
|
207
193
|
)}
|
|
208
194
|
<View style={[styles.content, isFoldable && styles.shrink]}>
|
|
209
195
|
<Text
|
|
210
196
|
typography={'header_default_bold'}
|
|
211
|
-
numberOfLines={
|
|
197
|
+
numberOfLines={3}
|
|
212
198
|
accessibilityLabel={'title_popup_notify'}
|
|
213
|
-
|
|
199
|
+
// keeps the title clear of the close button on a text only popup
|
|
200
|
+
style={
|
|
201
|
+
!image &&
|
|
202
|
+
typeof onIconClose === 'function' &&
|
|
203
|
+
styles.titleClearClose
|
|
204
|
+
}
|
|
214
205
|
>
|
|
215
206
|
{title}
|
|
216
207
|
</Text>
|
|
217
208
|
<Description style={[styles.description, descriptionStyle]}>
|
|
218
|
-
{
|
|
209
|
+
{typeof description === 'string' ? (
|
|
210
|
+
<Text
|
|
211
|
+
accessibilityLabel={'description_popup_notify'}
|
|
212
|
+
typography={'body_default_regular'}
|
|
213
|
+
onTextLayout={({ nativeEvent: { lines } }) => {
|
|
214
|
+
const enableScroll = lines.length > 8.5;
|
|
215
|
+
if (enableScroll !== scrollContent) {
|
|
216
|
+
setScrollContent(enableScroll);
|
|
217
|
+
}
|
|
218
|
+
}}
|
|
219
|
+
>
|
|
220
|
+
{renderDescription(description)}
|
|
221
|
+
</Text>
|
|
222
|
+
) : (
|
|
223
|
+
description
|
|
224
|
+
)}
|
|
219
225
|
</Description>
|
|
220
226
|
{!!error && (
|
|
221
227
|
<View style={styles.information}>
|
|
@@ -244,7 +250,6 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
244
250
|
width: popupWidth,
|
|
245
251
|
maxHeight,
|
|
246
252
|
},
|
|
247
|
-
styles.card,
|
|
248
253
|
showBaseLineDebug && styles.debugBaseLine,
|
|
249
254
|
]}
|
|
250
255
|
>
|
|
@@ -257,10 +262,9 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
257
262
|
|
|
258
263
|
const styles = StyleSheet.create({
|
|
259
264
|
debugBaseLine: { borderWidth: 1, borderColor: Colors.green_06 },
|
|
260
|
-
// clips the image and content to the card radius
|
|
261
|
-
card: { overflow: 'hidden' },
|
|
262
265
|
image: {
|
|
263
266
|
aspectRatio: 1.7777,
|
|
267
|
+
overflow: 'hidden',
|
|
264
268
|
},
|
|
265
269
|
shrink: { flexShrink: 1 },
|
|
266
270
|
content: { padding: Spacing.XL },
|
package/Popup/PopupPromotion.tsx
CHANGED
|
@@ -12,10 +12,6 @@ const ICON_CLOSE_SIZE = 20;
|
|
|
12
12
|
// close button row under the image: marginTop + vertical padding + icon
|
|
13
13
|
const CLOSE_ROW_HEIGHT = Spacing.S * 3 + ICON_CLOSE_SIZE;
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* Promotion popup body: a tappable portrait image with a close button under it.
|
|
17
|
-
* Both close the popup first, then call `onActionClick` / `onIconClose`.
|
|
18
|
-
*/
|
|
19
15
|
const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
20
16
|
image,
|
|
21
17
|
onIconClose,
|
|
@@ -37,6 +33,10 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
37
33
|
|
|
38
34
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
39
35
|
|
|
36
|
+
/**
|
|
37
|
+
* on action popup
|
|
38
|
+
* @param callback
|
|
39
|
+
*/
|
|
40
40
|
const onAction = (callback?: () => void) => {
|
|
41
41
|
if (typeof onRequestClose === 'function') {
|
|
42
42
|
onRequestClose?.(callback);
|
|
@@ -46,6 +46,9 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* build close action
|
|
51
|
+
*/
|
|
49
52
|
const buildCloseIcon = () => {
|
|
50
53
|
return (
|
|
51
54
|
<View style={styles.iconCloseContainer}>
|
package/Popup/types.ts
CHANGED
|
@@ -56,7 +56,7 @@ export type PopupNotifyProps = {
|
|
|
56
56
|
onIconClose?: () => void;
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
* onRequestClose on request close for modal
|
|
60
60
|
*/
|
|
61
61
|
onRequestClose?: (callback?: () => void) => void;
|
|
62
62
|
};
|
|
@@ -73,17 +73,17 @@ export type PopupPromotionProps = {
|
|
|
73
73
|
image: string;
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
|
-
* `
|
|
76
|
+
* `onClose`: Optional. A callback function that is called when the PopupPromotion component is closed.
|
|
77
77
|
*/
|
|
78
78
|
onIconClose?: () => void;
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* `onActionClick`: Optional. A callback function that is called
|
|
81
|
+
* `onActionClick`: Optional. A callback function that is called when the PopupPromotion component is closed.
|
|
82
82
|
*/
|
|
83
83
|
onActionClick?: () => void;
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
*
|
|
86
|
+
* onRequestClose on request close for modal
|
|
87
87
|
*/
|
|
88
88
|
onRequestClose?: (callback?: () => void) => void;
|
|
89
89
|
};
|
package/Popup/utils.ts
CHANGED
package/Radio/index.tsx
CHANGED
|
@@ -11,10 +11,6 @@ import {
|
|
|
11
11
|
MiniAppContext,
|
|
12
12
|
} from '../Context';
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* Radio button, selected when `value === groupValue`. `onChange` is called on
|
|
16
|
-
* press without arguments; the parent updates `groupValue`.
|
|
17
|
-
*/
|
|
18
14
|
const Radio: FC<RadioProps> = ({
|
|
19
15
|
value,
|
|
20
16
|
groupValue,
|