@momo-kits/foundation 0.169.7-beta.7 → 0.169.7-beta.9
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/Components/HeaderAnimated.tsx +13 -37
- package/Application/Components/HeaderBackground.tsx +3 -16
- package/Application/Components/HeaderExtendHeader.tsx +28 -41
- package/Application/Components/HeaderLeft.tsx +18 -4
- package/Application/Components/HeaderRight.styles.ts +13 -15
- package/Application/Components/HeaderTitle.shared.ts +11 -10
- package/Application/Components/HeaderToolkitAction.tsx +37 -12
- package/Application/Components/NavigationButton.tsx +6 -9
- package/Application/Components/SearchHeader.tsx +7 -20
- package/Application/StackScreen.tsx +0 -9
- package/Application/index.ts +1 -11
- package/Application/navigationOptions.tsx +15 -6
- package/Application/types.header.ts +2 -7
- package/Application/types.ts +0 -7
- package/Input/InputSearch.tsx +2 -18
- package/Input/index.tsx +1 -7
- package/Layout/Card.tsx +10 -10
- package/Layout/Item.tsx +2 -2
- package/Layout/Screen.tsx +0 -3
- package/Layout/Section.tsx +8 -9
- package/Layout/constants.ts +19 -0
- package/Layout/screenHeader.tsx +52 -55
- package/Layout/screenTypes.ts +2 -10
- package/Layout/types.ts +37 -1
- package/Layout/useGridSystem.ts +49 -0
- package/Layout/utils.ts +0 -8
- package/package.json +1 -1
- package/Application/headerLayout.ts +0 -158
|
@@ -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
|
@@ -357,13 +357,6 @@ const useSideBarItemStyle = (
|
|
|
357
357
|
};
|
|
358
358
|
};
|
|
359
359
|
|
|
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
360
|
export type { ScreenLayout, SideBarEdge, SideBarLayout, StatusBarClearance };
|
|
368
361
|
|
|
369
362
|
export {
|
|
@@ -372,7 +365,6 @@ export {
|
|
|
372
365
|
InnerEdgeStyles,
|
|
373
366
|
getHeaderMargin,
|
|
374
367
|
getHeaderRowOptions,
|
|
375
|
-
useGridSystem,
|
|
376
368
|
useScreenLayout,
|
|
377
369
|
useSideBarItemStyle,
|
|
378
370
|
validateChildren,
|
package/package.json
CHANGED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { useWindowDimensions, type ViewStyle } from 'react-native';
|
|
3
|
-
import type { StackNavigationOptions } from '@react-navigation/stack';
|
|
4
|
-
import { Spacing } from '../Consts';
|
|
5
|
-
import { getHeaderMargin } from '../Layout/utils';
|
|
6
|
-
import { FOLDABLE_MIN_WIDTH } from './modalLayout';
|
|
7
|
-
import { isIPhoneDuo } from './utils';
|
|
8
|
-
|
|
9
|
-
// Top navigation spec, shared with the Compose / SwiftUI kits
|
|
10
|
-
const HEADER_FRAME_MAX_WIDTH = 600;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Top navigation geometry on every device
|
|
14
|
-
* - buttonSize / iconSize: round back and shortcut buttons, icons inside them and the pill
|
|
15
|
-
* - pillWidth / pillHeight: help center | home capsule
|
|
16
|
-
* - clusterWidth: shortcut, gap and pill on the right of the bar
|
|
17
|
-
* - searchHeight: search field inside the header
|
|
18
|
-
* - titleGap: space between back and the title, and the title and the right cluster
|
|
19
|
-
* - sidePadding: bar edge to back and to the right cluster
|
|
20
|
-
* - gradientHeight: header gradient, kept at the phone height on wide windows
|
|
21
|
-
* - bannerWidth: animated banner image, kept at the phone width on wide windows
|
|
22
|
-
*/
|
|
23
|
-
const HeaderBarMetrics = {
|
|
24
|
-
buttonSize: 32,
|
|
25
|
-
iconSize: 20,
|
|
26
|
-
pillWidth: 72,
|
|
27
|
-
pillHeight: 32,
|
|
28
|
-
clusterWidth: 112,
|
|
29
|
-
searchHeight: 32,
|
|
30
|
-
titleGap: Spacing.S,
|
|
31
|
-
sidePadding: Spacing.M,
|
|
32
|
-
gradientHeight: 154,
|
|
33
|
-
bannerWidth: 375,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* `grid` keeps the header row at the bar edges, `stretch` centers it in a 600pt
|
|
38
|
-
* frame on wide windows. Background and status bar always span the window.
|
|
39
|
-
*/
|
|
40
|
-
type HeaderContentLayout = 'grid' | 'stretch';
|
|
41
|
-
|
|
42
|
-
type HeaderLayout = typeof HeaderBarMetrics & {
|
|
43
|
-
/**
|
|
44
|
-
* Window whose short side is at least 600 (Galaxy Z Fold / Pixel Fold inner
|
|
45
|
-
* display, tablets), iPhone Duo excluded. Phones, landscape included, are not.
|
|
46
|
-
*/
|
|
47
|
-
isWide: boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Window edge to back and to the right cluster: `sidePadding`, or centering the
|
|
50
|
-
* row in the 600pt frame with `stretch` on a wide window.
|
|
51
|
-
*/
|
|
52
|
-
frameInset: number;
|
|
53
|
-
/**
|
|
54
|
-
* Header row width between the two `frameInset`s.
|
|
55
|
-
*/
|
|
56
|
-
frameWidth: number;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
type HeaderLayoutInput = {
|
|
60
|
-
width: number;
|
|
61
|
-
height: number;
|
|
62
|
-
isDuo: boolean;
|
|
63
|
-
contentLayout?: HeaderContentLayout;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Header geometry for a window, pure so it can be tested without a device.
|
|
68
|
-
*/
|
|
69
|
-
const getHeaderLayout = ({
|
|
70
|
-
width,
|
|
71
|
-
height,
|
|
72
|
-
isDuo,
|
|
73
|
-
contentLayout = 'grid',
|
|
74
|
-
}: HeaderLayoutInput): HeaderLayout => {
|
|
75
|
-
const { sidePadding } = HeaderBarMetrics;
|
|
76
|
-
const isWide = !isDuo && Math.min(width, height) >= FOLDABLE_MIN_WIDTH;
|
|
77
|
-
let frameInset = sidePadding;
|
|
78
|
-
if (isWide && contentLayout === 'stretch') {
|
|
79
|
-
const centered = (width - HEADER_FRAME_MAX_WIDTH) / 2;
|
|
80
|
-
frameInset = Math.max(sidePadding, centered);
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
...HeaderBarMetrics,
|
|
84
|
-
isWide,
|
|
85
|
-
frameInset,
|
|
86
|
-
frameWidth: width - frameInset * 2,
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Widest a title can be between back and the right cluster of the header row.
|
|
92
|
-
*/
|
|
93
|
-
const getTitleBudget = (layout: HeaderLayout) => {
|
|
94
|
-
const { buttonSize, titleGap, clusterWidth } = layout;
|
|
95
|
-
return layout.frameWidth - buttonSize - titleGap * 2 - clusterWidth;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Header geometry for the current window; follows fold, unfold and rotation.
|
|
100
|
-
*/
|
|
101
|
-
const useHeaderLayout = (contentLayout?: HeaderContentLayout): HeaderLayout => {
|
|
102
|
-
const { width, height } = useWindowDimensions();
|
|
103
|
-
const isDuo = isIPhoneDuo();
|
|
104
|
-
return useMemo(() => {
|
|
105
|
-
return getHeaderLayout({ width, height, isDuo, contentLayout });
|
|
106
|
-
}, [width, height, isDuo, contentLayout]);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const TITLE_CONTAINER_RESET: ViewStyle = {
|
|
110
|
-
marginLeft: 0,
|
|
111
|
-
marginEnd: 0,
|
|
112
|
-
marginStart: 0,
|
|
113
|
-
marginHorizontal: 0,
|
|
114
|
-
marginVertical: 0,
|
|
115
|
-
margin: 0,
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* React Navigation container styles that keep back, title and the right cluster
|
|
120
|
-
* in the `stretch` frame. `undefined` for `grid`, and on iPhone Duo, which keeps
|
|
121
|
-
* its own header row.
|
|
122
|
-
*/
|
|
123
|
-
const useHeaderFrameOptions = (
|
|
124
|
-
contentLayout?: HeaderContentLayout,
|
|
125
|
-
): StackNavigationOptions | undefined => {
|
|
126
|
-
const layout = useHeaderLayout(contentLayout);
|
|
127
|
-
const { width } = useWindowDimensions();
|
|
128
|
-
const isDuo = isIPhoneDuo();
|
|
129
|
-
return useMemo(() => {
|
|
130
|
-
if (contentLayout !== 'stretch' || isDuo) {
|
|
131
|
-
return undefined;
|
|
132
|
-
}
|
|
133
|
-
// the header content row already sits this far in on large iOS windows
|
|
134
|
-
const shift = layout.frameInset - layout.sidePadding;
|
|
135
|
-
const containerShift = Math.max(0, shift - getHeaderMargin(width));
|
|
136
|
-
return {
|
|
137
|
-
headerLeftContainerStyle: { paddingLeft: containerShift },
|
|
138
|
-
headerRightContainerStyle: { paddingRight: containerShift },
|
|
139
|
-
headerTitleContainerStyle: {
|
|
140
|
-
...TITLE_CONTAINER_RESET,
|
|
141
|
-
left: layout.titleGap,
|
|
142
|
-
maxWidth: getTitleBudget(layout),
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
}, [contentLayout, isDuo, layout, width]);
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export type { HeaderContentLayout, HeaderLayout };
|
|
149
|
-
|
|
150
|
-
export {
|
|
151
|
-
HeaderBarMetrics,
|
|
152
|
-
HEADER_FRAME_MAX_WIDTH,
|
|
153
|
-
TITLE_CONTAINER_RESET,
|
|
154
|
-
getHeaderLayout,
|
|
155
|
-
getTitleBudget,
|
|
156
|
-
useHeaderLayout,
|
|
157
|
-
useHeaderFrameOptions,
|
|
158
|
-
};
|