@momo-kits/foundation 0.169.7-beta.9 → 0.169.8
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/BottomTab/ActiveIndicator.tsx +5 -1
- package/Application/BottomTab/BottomTabBar.styles.ts +18 -1
- package/Application/BottomTab/BottomTabBar.tsx +8 -10
- package/Application/BottomTab/CurvedContainer.tsx +8 -2
- package/Application/BottomTab/CustomBottomTabItem.tsx +2 -2
- package/Application/BottomTab/DuoTabBar.tsx +15 -3
- package/Application/BottomTab/metrics.ts +23 -3
- package/Application/modalLayout.ts +3 -0
- package/Application/types.tabs.ts +0 -1
- package/Layout/Card.tsx +10 -10
- package/Layout/Item.tsx +2 -2
- package/Layout/Section.tsx +9 -8
- package/Layout/types.ts +1 -37
- package/Layout/utils.ts +8 -0
- package/Popup/PopupNotify.tsx +1 -1
- package/Popup/utils.ts +7 -4
- package/package.json +1 -1
- package/Layout/constants.ts +0 -19
- package/Layout/useGridSystem.ts +0 -49
|
@@ -5,6 +5,7 @@ import Animated, {
|
|
|
5
5
|
useSharedValue,
|
|
6
6
|
withTiming,
|
|
7
7
|
} from 'react-native-reanimated';
|
|
8
|
+
import { defaultTheme } from '../../Consts';
|
|
8
9
|
import { ApplicationContext } from '../../Context';
|
|
9
10
|
import { getIndicatorShadow, TabBarMotion } from './metrics';
|
|
10
11
|
|
|
@@ -70,7 +71,10 @@ const ActiveIndicator: React.FC<Props> = ({
|
|
|
70
71
|
styles.indicator,
|
|
71
72
|
{
|
|
72
73
|
borderRadius: radius,
|
|
73
|
-
|
|
74
|
+
// a mini app's own theme may lack `tonal`; without the fallback the indicator is transparent
|
|
75
|
+
backgroundColor:
|
|
76
|
+
theme.colors.background.tonal ??
|
|
77
|
+
defaultTheme.colors.background.tonal,
|
|
74
78
|
boxShadow: getIndicatorShadow(theme.colors.primary),
|
|
75
79
|
},
|
|
76
80
|
style,
|
|
@@ -2,6 +2,20 @@ import { StyleSheet } from 'react-native';
|
|
|
2
2
|
import { Colors, Spacing } from '../../Consts';
|
|
3
3
|
import { CTA_SHADOW, TabBarMetrics } from './metrics';
|
|
4
4
|
|
|
5
|
+
const ITEM_HEIGHT =
|
|
6
|
+
TabBarMetrics.indicatorHeight +
|
|
7
|
+
TabBarMetrics.itemIconLabelGap +
|
|
8
|
+
TabBarMetrics.labelHeight;
|
|
9
|
+
const CONTENT_HEIGHT = TabBarMetrics.height - 2 * TabBarMetrics.paddingVertical;
|
|
10
|
+
// the items are centered in the content, so their label starts this far below the content top
|
|
11
|
+
const ITEM_LABEL_TOP =
|
|
12
|
+
(CONTENT_HEIGHT - ITEM_HEIGHT) / 2 +
|
|
13
|
+
TabBarMetrics.indicatorHeight +
|
|
14
|
+
TabBarMetrics.itemIconLabelGap;
|
|
15
|
+
// the center action column is placed so its label starts on the same line as the tab labels
|
|
16
|
+
const CTA_TOP =
|
|
17
|
+
ITEM_LABEL_TOP - TabBarMetrics.ctaLabelGap - TabBarMetrics.ctaSize;
|
|
18
|
+
|
|
5
19
|
export const styles = StyleSheet.create({
|
|
6
20
|
bar: {
|
|
7
21
|
position: 'absolute',
|
|
@@ -37,7 +51,7 @@ export const styles = StyleSheet.create({
|
|
|
37
51
|
position: 'absolute',
|
|
38
52
|
left: 0,
|
|
39
53
|
right: 0,
|
|
40
|
-
top:
|
|
54
|
+
top: CTA_TOP,
|
|
41
55
|
alignItems: 'center',
|
|
42
56
|
gap: TabBarMetrics.ctaLabelGap,
|
|
43
57
|
},
|
|
@@ -46,6 +60,9 @@ export const styles = StyleSheet.create({
|
|
|
46
60
|
width: TabBarMetrics.ctaSize,
|
|
47
61
|
height: TabBarMetrics.ctaSize,
|
|
48
62
|
borderRadius: TabBarMetrics.ctaSize / 2,
|
|
63
|
+
// Figma Icon Button border: white 60% hairline
|
|
64
|
+
borderWidth: 1,
|
|
65
|
+
borderColor: `rgba(255, 255, 255, ${TabBarMetrics.ctaBorderOpacity})`,
|
|
49
66
|
alignItems: 'center',
|
|
50
67
|
justifyContent: 'center',
|
|
51
68
|
},
|
|
@@ -181,21 +181,17 @@ const HorizontalTabBar: React.FC<{
|
|
|
181
181
|
return renderItems(items);
|
|
182
182
|
};
|
|
183
183
|
|
|
184
|
-
const customContainer = withCta && floatingButton?.container;
|
|
185
|
-
|
|
186
184
|
return (
|
|
187
185
|
<View
|
|
188
186
|
style={[styles.container, { width }]}
|
|
189
187
|
accessibilityLabel={'bottom_tab_bar'}
|
|
190
188
|
>
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
/>
|
|
198
|
-
)}
|
|
189
|
+
<CurvedContainer
|
|
190
|
+
width={width}
|
|
191
|
+
height={TabBarMetrics.height}
|
|
192
|
+
radius={TabBarMetrics.height / 2}
|
|
193
|
+
notchCenterX={withCta ? width / 2 : undefined}
|
|
194
|
+
/>
|
|
199
195
|
<View style={styles.content}>
|
|
200
196
|
<ActiveIndicator
|
|
201
197
|
axis={'x'}
|
|
@@ -228,6 +224,8 @@ export default function BottomTabBar(props: Props) {
|
|
|
228
224
|
window.height,
|
|
229
225
|
insets.left,
|
|
230
226
|
insets.right,
|
|
227
|
+
state.routes.length,
|
|
228
|
+
withCta,
|
|
231
229
|
);
|
|
232
230
|
|
|
233
231
|
return (
|
|
@@ -3,7 +3,7 @@ import { StyleSheet } from 'react-native';
|
|
|
3
3
|
import Svg, { Defs, FeGaussianBlur, Filter, Path } from 'react-native-svg';
|
|
4
4
|
import { Colors } from '../../Consts';
|
|
5
5
|
import { ApplicationContext } from '../../Context';
|
|
6
|
-
import { NOTCH_CURVES, NOTCH_HALF_WIDTH } from './metrics';
|
|
6
|
+
import { NOTCH_CURVES, NOTCH_HALF_WIDTH, TabBarMetrics } from './metrics';
|
|
7
7
|
|
|
8
8
|
type Props = {
|
|
9
9
|
width: number;
|
|
@@ -139,7 +139,13 @@ const CurvedContainer: React.FC<Props> = ({
|
|
|
139
139
|
filter={'url(#keyShadow)'}
|
|
140
140
|
/>
|
|
141
141
|
)}
|
|
142
|
-
<Path
|
|
142
|
+
<Path
|
|
143
|
+
d={path}
|
|
144
|
+
fill={theme.colors.background.surface}
|
|
145
|
+
fillOpacity={TabBarMetrics.backgroundOpacity}
|
|
146
|
+
stroke={theme.colors.border.default}
|
|
147
|
+
strokeWidth={1}
|
|
148
|
+
/>
|
|
143
149
|
</Svg>
|
|
144
150
|
);
|
|
145
151
|
};
|
|
@@ -13,7 +13,7 @@ import Animated, {
|
|
|
13
13
|
import { TabBarIcon } from './TabBarIcon';
|
|
14
14
|
import { Text } from '../../Text';
|
|
15
15
|
import { MiniAppContext } from '../../Context';
|
|
16
|
-
import { Colors
|
|
16
|
+
import { Colors } from '../../Consts';
|
|
17
17
|
import { TabBarMetrics, TabBarMotion } from './metrics';
|
|
18
18
|
|
|
19
19
|
type IconRenderer = (props: {
|
|
@@ -143,7 +143,7 @@ const styles = StyleSheet.create({
|
|
|
143
143
|
minWidth: 1,
|
|
144
144
|
alignItems: 'center',
|
|
145
145
|
justifyContent: 'center',
|
|
146
|
-
gap:
|
|
146
|
+
gap: TabBarMetrics.itemIconLabelGap,
|
|
147
147
|
},
|
|
148
148
|
slot: {
|
|
149
149
|
height: TabBarMetrics.indicatorHeight,
|
|
@@ -3,7 +3,11 @@ import React from 'react';
|
|
|
3
3
|
import { useWindowDimensions, View } from 'react-native';
|
|
4
4
|
import { useScreenLayout } from '../../Layout/utils';
|
|
5
5
|
import { FloatingButtonProps } from '../types';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
getSystemIndicatorHeight,
|
|
8
|
+
hasCenterAction,
|
|
9
|
+
HorizontalTabBar,
|
|
10
|
+
} from './BottomTabBar';
|
|
7
11
|
import { getHorizontalBarWidth, TabBarMetrics } from './metrics';
|
|
8
12
|
import { getTabItems } from './tabItems';
|
|
9
13
|
import { DuoRailTabBar } from './DuoRailTabBar';
|
|
@@ -34,6 +38,7 @@ const DuoFloatingTabBar: React.FC<DuoTabBarProps> = props => {
|
|
|
34
38
|
const { insets } = useScreenLayout();
|
|
35
39
|
const { width, height } = useWindowDimensions();
|
|
36
40
|
const { floatingButton, activeTintColor, inactiveTintColor } = props;
|
|
41
|
+
const tabItems = getTabItems(props);
|
|
37
42
|
|
|
38
43
|
return (
|
|
39
44
|
<View
|
|
@@ -44,8 +49,15 @@ const DuoFloatingTabBar: React.FC<DuoTabBarProps> = props => {
|
|
|
44
49
|
]}
|
|
45
50
|
>
|
|
46
51
|
<HorizontalTabBar
|
|
47
|
-
items={
|
|
48
|
-
width={getHorizontalBarWidth(
|
|
52
|
+
items={tabItems}
|
|
53
|
+
width={getHorizontalBarWidth(
|
|
54
|
+
width,
|
|
55
|
+
height,
|
|
56
|
+
insets.left,
|
|
57
|
+
insets.right,
|
|
58
|
+
tabItems.length,
|
|
59
|
+
hasCenterAction(floatingButton, tabItems.length),
|
|
60
|
+
)}
|
|
49
61
|
floatingButton={floatingButton}
|
|
50
62
|
activeTintColor={activeTintColor}
|
|
51
63
|
inactiveTintColor={inactiveTintColor}
|
|
@@ -8,11 +8,18 @@ import { Colors, Radius, Spacing } from '../../Consts';
|
|
|
8
8
|
* iPhone Duo rail (center action under the container).
|
|
9
9
|
*/
|
|
10
10
|
const TabBarMetrics = {
|
|
11
|
-
height:
|
|
11
|
+
height: 60,
|
|
12
12
|
margin: Spacing.S,
|
|
13
|
-
paddingVertical: Spacing.
|
|
13
|
+
paddingVertical: Spacing.XS,
|
|
14
14
|
paddingHorizontal: Spacing.M,
|
|
15
|
-
itemGap:
|
|
15
|
+
itemGap: 1,
|
|
16
|
+
// gap between the icon slot and the label inside a tab (Figma: none)
|
|
17
|
+
itemIconLabelGap: 0,
|
|
18
|
+
// .Nav/Background: no backdrop blur, so use the Figma Blur=Off spec (opacity 95%, no blur) plus the 1px
|
|
19
|
+
// border — nearly solid, matching the frosted sample; surface keeps dark-mode support
|
|
20
|
+
backgroundOpacity: 0.95,
|
|
21
|
+
// white 60% hairline around the center action button (Figma Icon Button border)
|
|
22
|
+
ctaBorderOpacity: 0.6,
|
|
16
23
|
iconSize: 24,
|
|
17
24
|
// active indicator behind the icon: 24 icon + XS·M padding
|
|
18
25
|
indicatorPaddingVertical: Spacing.XS,
|
|
@@ -25,6 +32,9 @@ const TabBarMetrics = {
|
|
|
25
32
|
systemIndicatorHeight: 24,
|
|
26
33
|
foldableMinShortSide: 600,
|
|
27
34
|
foldableWidthRatio: 0.65,
|
|
35
|
+
// a 2-tab bar doesn't stretch to the full width: each item is this fixed width and the bar is
|
|
36
|
+
// sized to its content, centered (Figma Navigation · 2 Tab: item 100, bar ~225)
|
|
37
|
+
twoTabItemWidth: 100,
|
|
28
38
|
ctaSlotWidth: 92,
|
|
29
39
|
ctaSize: 48,
|
|
30
40
|
ctaIconSize: 28,
|
|
@@ -132,7 +142,17 @@ const getHorizontalBarWidth = (
|
|
|
132
142
|
height: number,
|
|
133
143
|
insetLeft: number,
|
|
134
144
|
insetRight: number,
|
|
145
|
+
itemCount: number,
|
|
146
|
+
hasCta: boolean,
|
|
135
147
|
) => {
|
|
148
|
+
// 2 tabs (no center action) stay content-sized and centered instead of filling the window
|
|
149
|
+
if (itemCount === 2 && !hasCta) {
|
|
150
|
+
return (
|
|
151
|
+
TabBarMetrics.twoTabItemWidth * 2 +
|
|
152
|
+
TabBarMetrics.paddingHorizontal * 2 +
|
|
153
|
+
TabBarMetrics.itemGap
|
|
154
|
+
);
|
|
155
|
+
}
|
|
136
156
|
const shortSide = Math.min(width, height);
|
|
137
157
|
if (shortSide >= TabBarMetrics.foldableMinShortSide) {
|
|
138
158
|
return shortSide * TabBarMetrics.foldableWidthRatio;
|
package/Layout/Card.tsx
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
2
|
import { View, ViewProps } from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
import { useGridSystem } from './useGridSystem';
|
|
3
|
+
import { useGridSystem, useScreenLayout } from './utils';
|
|
5
4
|
import { GridContextProps } from './types';
|
|
6
5
|
import { GridContext } from './index';
|
|
7
6
|
import { Image } from '../Image';
|
|
8
7
|
import { ApplicationContext } from '../Context';
|
|
9
8
|
import styles from './styles';
|
|
10
|
-
import { Radius, Shadow } from '../Consts';
|
|
9
|
+
import { Radius, Shadow, Spacing } from '../Consts';
|
|
11
10
|
|
|
12
11
|
export interface CardProps extends ViewProps {
|
|
13
12
|
/**
|
|
@@ -22,7 +21,7 @@ export interface CardProps extends ViewProps {
|
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
|
-
* Surface card across the
|
|
24
|
+
* Surface card across the content width minus 12pt margins, with its own grid for child
|
|
26
25
|
* Items; optional background image and light shadow.
|
|
27
26
|
*/
|
|
28
27
|
const Card: React.FC<CardProps> = ({
|
|
@@ -33,18 +32,19 @@ const Card: React.FC<CardProps> = ({
|
|
|
33
32
|
...props
|
|
34
33
|
}) => {
|
|
35
34
|
const { theme } = useContext(ApplicationContext);
|
|
36
|
-
const { numberOfColumns
|
|
35
|
+
const { numberOfColumns } = useGridSystem();
|
|
36
|
+
const { contentWidth } = useScreenLayout();
|
|
37
37
|
|
|
38
|
-
const gutterSize =
|
|
39
|
-
const margin =
|
|
40
|
-
const widthSection =
|
|
38
|
+
const gutterSize = 8;
|
|
39
|
+
const margin = 12;
|
|
40
|
+
const widthSection = contentWidth - margin * 2;
|
|
41
41
|
const innerWidth = widthSection - margin * 2;
|
|
42
42
|
const columnsWidth = innerWidth - gutterSize * (numberOfColumns - 1);
|
|
43
43
|
const sizePerSpan = columnsWidth / numberOfColumns - 1 / numberOfColumns;
|
|
44
44
|
|
|
45
45
|
const gridContext: GridContextProps = {
|
|
46
46
|
numberOfColumns,
|
|
47
|
-
gutterSize:
|
|
47
|
+
gutterSize: Spacing.S,
|
|
48
48
|
sizePerSpan,
|
|
49
49
|
getSizeSpan: span => {
|
|
50
50
|
return sizePerSpan * span + gutterSize * (span - 1);
|
|
@@ -63,7 +63,7 @@ const Card: React.FC<CardProps> = ({
|
|
|
63
63
|
styles.card,
|
|
64
64
|
{
|
|
65
65
|
width: widthSection,
|
|
66
|
-
marginHorizontal:
|
|
66
|
+
marginHorizontal: margin,
|
|
67
67
|
gap: gutterSize,
|
|
68
68
|
},
|
|
69
69
|
!!backgroundImage && { backgroundColor: undefined },
|
package/Layout/Item.tsx
CHANGED
|
@@ -7,12 +7,12 @@ import { SpanNumber } from './types';
|
|
|
7
7
|
|
|
8
8
|
export interface ItemProps extends ViewProps {
|
|
9
9
|
/**
|
|
10
|
-
* Width in grid columns (1-
|
|
10
|
+
* Width in grid columns (1-12). Defaults to the full row.
|
|
11
11
|
*/
|
|
12
12
|
widthSpan?: SpanNumber;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Optional. Height in grid spans (1-
|
|
15
|
+
* Optional. Height in grid spans (1-12). Unset keeps the content height.
|
|
16
16
|
*/
|
|
17
17
|
heightSpan?: SpanNumber;
|
|
18
18
|
}
|
package/Layout/Section.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, ViewProps } from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
import { useGridSystem } from './useGridSystem';
|
|
3
|
+
import { useGridSystem, useScreenLayout } from './utils';
|
|
5
4
|
import { GridContextProps } from './types';
|
|
6
5
|
import { GridContext } from './index';
|
|
7
6
|
import styles from './styles';
|
|
8
7
|
import { Image } from '../Image';
|
|
8
|
+
import { Spacing } from '../Consts';
|
|
9
9
|
|
|
10
10
|
export interface SectionProps extends ViewProps {
|
|
11
11
|
/**
|
|
@@ -37,21 +37,22 @@ const Section: React.FC<SectionProps> = ({
|
|
|
37
37
|
style,
|
|
38
38
|
...props
|
|
39
39
|
}) => {
|
|
40
|
-
const { numberOfColumns
|
|
40
|
+
const { numberOfColumns } = useGridSystem();
|
|
41
|
+
const { contentWidth } = useScreenLayout();
|
|
41
42
|
|
|
42
|
-
const gutterSize =
|
|
43
|
+
const gutterSize = 12;
|
|
43
44
|
let margin = 0;
|
|
44
45
|
if (useMargin) {
|
|
45
|
-
margin =
|
|
46
|
+
margin = 12;
|
|
46
47
|
}
|
|
47
|
-
const widthSection =
|
|
48
|
+
const widthSection = contentWidth - margin * 2;
|
|
48
49
|
|
|
49
50
|
const columnsWidth = widthSection - gutterSize * (numberOfColumns - 1);
|
|
50
51
|
const sizePerSpan = columnsWidth / numberOfColumns - 1 / numberOfColumns;
|
|
51
52
|
|
|
52
53
|
const gridContext: GridContextProps = {
|
|
53
54
|
numberOfColumns,
|
|
54
|
-
gutterSize:
|
|
55
|
+
gutterSize: Spacing.M,
|
|
55
56
|
sizePerSpan,
|
|
56
57
|
getSizeSpan: span => {
|
|
57
58
|
return span * sizePerSpan + gutterSize * (span - 1);
|
|
@@ -69,7 +70,7 @@ const Section: React.FC<SectionProps> = ({
|
|
|
69
70
|
styles.rowWrap,
|
|
70
71
|
{
|
|
71
72
|
width: widthSection,
|
|
72
|
-
marginHorizontal:
|
|
73
|
+
marginHorizontal: margin,
|
|
73
74
|
gap: gutterSize,
|
|
74
75
|
},
|
|
75
76
|
]}
|
package/Layout/types.ts
CHANGED
|
@@ -13,43 +13,7 @@ export type ScreenRef = {
|
|
|
13
13
|
*/
|
|
14
14
|
setSearchHeader: (params: SearchHeaderProps) => void;
|
|
15
15
|
};
|
|
16
|
-
export type SpanNumber =
|
|
17
|
-
| 1
|
|
18
|
-
| 2
|
|
19
|
-
| 3
|
|
20
|
-
| 4
|
|
21
|
-
| 5
|
|
22
|
-
| 6
|
|
23
|
-
| 7
|
|
24
|
-
| 8
|
|
25
|
-
| 9
|
|
26
|
-
| 10
|
|
27
|
-
| 11
|
|
28
|
-
| 12
|
|
29
|
-
| 13
|
|
30
|
-
| 14
|
|
31
|
-
| 15
|
|
32
|
-
| 16
|
|
33
|
-
| 17
|
|
34
|
-
| 18
|
|
35
|
-
| 19
|
|
36
|
-
| 20
|
|
37
|
-
| 21
|
|
38
|
-
| 22
|
|
39
|
-
| 23
|
|
40
|
-
| 24
|
|
41
|
-
| 25
|
|
42
|
-
| 26
|
|
43
|
-
| 27
|
|
44
|
-
| 28
|
|
45
|
-
| 29
|
|
46
|
-
| 30
|
|
47
|
-
| 31
|
|
48
|
-
| 32
|
|
49
|
-
| 33
|
|
50
|
-
| 34
|
|
51
|
-
| 35
|
|
52
|
-
| 36;
|
|
16
|
+
export type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
53
17
|
|
|
54
18
|
export type GridContextProps = {
|
|
55
19
|
/**
|
package/Layout/utils.ts
CHANGED
|
@@ -357,6 +357,13 @@ 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
|
+
|
|
360
367
|
export type { ScreenLayout, SideBarEdge, SideBarLayout, StatusBarClearance };
|
|
361
368
|
|
|
362
369
|
export {
|
|
@@ -365,6 +372,7 @@ export {
|
|
|
365
372
|
InnerEdgeStyles,
|
|
366
373
|
getHeaderMargin,
|
|
367
374
|
getHeaderRowOptions,
|
|
375
|
+
useGridSystem,
|
|
368
376
|
useScreenLayout,
|
|
369
377
|
useSideBarItemStyle,
|
|
370
378
|
validateChildren,
|
package/Popup/PopupNotify.tsx
CHANGED
|
@@ -150,7 +150,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
150
150
|
return text;
|
|
151
151
|
}
|
|
152
152
|
return segments.map((segment, index) => {
|
|
153
|
-
if (segment.
|
|
153
|
+
if (segment.isHighlighted) {
|
|
154
154
|
return (
|
|
155
155
|
<Text key={index} typography={'header_s_semibold'}>
|
|
156
156
|
{segment.text}
|
package/Popup/utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type HighlightSegment = { text: string;
|
|
1
|
+
type HighlightSegment = { text: string; isHighlighted: boolean };
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* True for cased-script letters, digits and `_`; caseless scripts (CJK, Thai)
|
|
@@ -46,12 +46,15 @@ const splitHighlightText = (
|
|
|
46
46
|
continue;
|
|
47
47
|
}
|
|
48
48
|
if (start > lastIndex) {
|
|
49
|
-
segments.push({
|
|
49
|
+
segments.push({
|
|
50
|
+
text: text.slice(lastIndex, start),
|
|
51
|
+
isHighlighted: false,
|
|
52
|
+
});
|
|
50
53
|
}
|
|
51
|
-
segments.push({ text: match[0],
|
|
54
|
+
segments.push({ text: match[0], isHighlighted: true });
|
|
52
55
|
lastIndex = end;
|
|
53
56
|
}
|
|
54
|
-
segments.push({ text: text.slice(lastIndex),
|
|
57
|
+
segments.push({ text: text.slice(lastIndex), isHighlighted: false });
|
|
55
58
|
return segments;
|
|
56
59
|
};
|
|
57
60
|
|
package/package.json
CHANGED
package/Layout/constants.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const GRID_MARGIN = 12;
|
|
2
|
-
const GRID_GUTTER = 12;
|
|
3
|
-
const GRID_PHONE_MAX_WIDTH = 600;
|
|
4
|
-
const GRID_TABLET_MIN_WIDTH = 800;
|
|
5
|
-
const GRID_DESKTOP_MIN_WIDTH = 1100;
|
|
6
|
-
const GRID_PHONE_COLUMNS = 12;
|
|
7
|
-
const GRID_TABLET_COLUMNS = 24;
|
|
8
|
-
const GRID_DESKTOP_COLUMNS = 36;
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
GRID_DESKTOP_COLUMNS,
|
|
12
|
-
GRID_DESKTOP_MIN_WIDTH,
|
|
13
|
-
GRID_GUTTER,
|
|
14
|
-
GRID_MARGIN,
|
|
15
|
-
GRID_PHONE_COLUMNS,
|
|
16
|
-
GRID_PHONE_MAX_WIDTH,
|
|
17
|
-
GRID_TABLET_COLUMNS,
|
|
18
|
-
GRID_TABLET_MIN_WIDTH,
|
|
19
|
-
};
|
package/Layout/useGridSystem.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
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 };
|