Skip to content

Commit dda6416

Browse files
committed
feat(Navbar): support zIndex and placeholder props
1 parent be8c952 commit dda6416

File tree

6 files changed

+101
-46
lines changed

6 files changed

+101
-46
lines changed

src/navbar/Navbar.tsx

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import React, { useCallback, useMemo } from 'react';
1+
import React, { useMemo } from 'react';
22
import type { CSSProperties } from 'react';
33
import { ChevronLeftIcon } from 'tdesign-icons-react';
4-
import ClassNames from 'classnames';
4+
import classNames from 'classnames';
55
import { usePrefixClass } from '../hooks/useClass';
66
import { StyledProps } from '../common';
77
import { TdNavbarProps } from './type';
@@ -26,23 +26,26 @@ const Navbar: React.FC<NavbarProps> = (originProps) => {
2626
right,
2727
fixed,
2828
animation,
29+
placeholder,
30+
zIndex,
2931
className,
32+
safeAreaInsetTop,
3033
style,
3134
onLeftClick,
3235
onRightClick,
3336
} = props;
34-
const prefix = usePrefixClass('navbar');
37+
const prefixClass = usePrefixClass();
38+
const navbarClass = usePrefixClass('navbar');
3539
const animationSuffix = useMemo(() => (animation ? '-animation' : ''), [animation]);
3640

37-
const cls = useCallback((name?: string) => (name ? `${prefix}__${name}` : prefix), [prefix]);
38-
3941
// 左侧胶囊区域
40-
const leftCapsuleContent = useMemo(() => {
41-
if (!capsule) {
42+
const renderCapsule = () => {
43+
const capsuleContent = parseTNode(capsule);
44+
if (!capsuleContent) {
4245
return null;
4346
}
44-
return <div className={cls('capsule')}>{capsule}</div>;
45-
}, [capsule, cls]);
47+
return <div className={`${navbarClass}__capsule`}>{capsuleContent}</div>;
48+
};
4649

4750
const titleChildren = useMemo(() => {
4851
let titleNode = children || title;
@@ -56,49 +59,70 @@ const Navbar: React.FC<NavbarProps> = (originProps) => {
5659
}
5760
}
5861

59-
return isStringTitle ? <span className={cls('center-title')}>{parseTNode(titleNode)}</span> : parseTNode(titleNode);
60-
}, [children, cls, title, titleMaxLength]);
62+
return isStringTitle ? (
63+
<span className={`${navbarClass}__center-title`}>{parseTNode(titleNode)}</span>
64+
) : (
65+
parseTNode(titleNode)
66+
);
67+
}, [children, navbarClass, title, titleMaxLength]);
6168

6269
// 右侧icon
63-
const rightContent = useMemo(
64-
() =>
65-
right ? (
66-
<div className={cls('right')} onClick={onRightClick}>
67-
{parseTNode(right)}
68-
</div>
69-
) : null,
70-
[cls, right, onRightClick],
71-
);
70+
const renderRight = () =>
71+
right ? (
72+
<div className={`${navbarClass}__right`} onClick={onRightClick}>
73+
{parseTNode(right)}
74+
</div>
75+
) : null;
7276

7377
const navClass = useMemo<string>(
7478
() =>
75-
ClassNames(
76-
prefix,
77-
{ [`${prefix}--fixed`]: fixed },
78-
visible ? `${prefix}--visible${animationSuffix}` : `${prefix}--hide${animationSuffix}`,
79+
classNames(
80+
navbarClass,
81+
{ [`${navbarClass}--fixed`]: fixed, [`${prefixClass}-safe-area-top `]: safeAreaInsetTop },
82+
visible ? `${navbarClass}--visible${animationSuffix}` : `${navbarClass}--hide${animationSuffix}`,
7983
),
80-
[prefix, fixed, visible, animationSuffix],
84+
[navbarClass, prefixClass, fixed, visible, animationSuffix, safeAreaInsetTop],
8185
);
8286

8387
const navStyle = useMemo<CSSProperties>(
8488
() => ({
85-
position: fixed ? 'fixed' : 'relative',
89+
zIndex,
8690
...style,
8791
}),
88-
[fixed, style],
92+
[zIndex, style],
93+
);
94+
95+
const renderLeftArrow = () => {
96+
if (leftArrow) {
97+
return <ChevronLeftIcon className={`${navbarClass}__left-arrow`} />;
98+
}
99+
return null;
100+
};
101+
102+
const renderLeft = () => (
103+
<div className={`${navbarClass}__left`} onClick={onLeftClick}>
104+
{renderLeftArrow()}
105+
{parseTNode(left)}
106+
{renderCapsule()}
107+
</div>
89108
);
90109

110+
const renderCenter = () => <div className={`${navbarClass}__center`}>{titleChildren}</div>;
111+
112+
const renderPlaceholder = () => {
113+
if (fixed && placeholder) {
114+
return <div className={`${navbarClass}__placeholder`}></div>;
115+
}
116+
return null;
117+
};
118+
91119
return (
92-
<div className={ClassNames(navClass, className)} style={navStyle}>
93-
{fixed && <div className={cls('placeholder')}></div>}
94-
<div className={cls(`content`)}>
95-
<div className={cls(`left`)} onClick={onLeftClick}>
96-
{leftArrow && <ChevronLeftIcon className={cls('left-arrow')} />}
97-
{parseTNode(left)}
98-
{leftCapsuleContent}
99-
</div>
100-
<div className={cls(`center`)}>{titleChildren}</div>
101-
{rightContent}
120+
<div className={classNames(navClass, className)} style={navStyle}>
121+
{renderPlaceholder()}
122+
<div className={`${navbarClass}__content`}>
123+
{renderLeft()}
124+
{renderCenter()}
125+
{renderRight()}
102126
</div>
103127
</div>
104128
);

src/navbar/defaultProps.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,12 @@
44

55
import { TdNavbarProps } from './type';
66

7-
export const navbarDefaultProps: TdNavbarProps = { animation: true, fixed: true, leftArrow: false, visible: true };
7+
export const navbarDefaultProps: TdNavbarProps = {
8+
animation: true,
9+
fixed: true,
10+
leftArrow: false,
11+
placeholder: false,
12+
safeAreaInsetTop: true,
13+
visible: true,
14+
zIndex: 1,
15+
};

src/navbar/navbar.en-US.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,27 @@
22

33
## API
44

5-
65
### Navbar Props
76

87
name | type | default | description | required
98
-- | -- | -- | -- | --
109
className | String | - | className of component | N
11-
style | Object | - | CSS(Cascading Style Sheets),Typescript`React.CSSProperties` | N
10+
style | Object | - | CSS(Cascading Style Sheets),Typescript: `React.CSSProperties` | N
1211
animation | Boolean | true | \- | N
1312
background | String | - | `deprecated`。background | N
14-
capsule | TElement | - | Typescript`TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
13+
capsule | TElement | - | Typescript: `TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
1514
fixed | Boolean | true | \- | N
16-
left | TNode | - | Typescript`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
15+
left | TNode | - | Typescript: `string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
1716
leftArrow | Boolean | false | \- | N
18-
right | TNode | - | Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
19-
title | TNode | - | page title。Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
17+
placeholder | Boolean | false | `0.21.1` | N
18+
right | TNode | - | Typescript: `string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
19+
safeAreaInsetTop | Boolean | true | \- | N
20+
title | TNode | - | page title。Typescript: `string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
2021
titleMaxLength | Number | - | \- | N
2122
visible | Boolean | true | \- | N
22-
onLeftClick | Function | | Typescript:`() => void`<br/> | N
23-
onRightClick | Function | | Typescript:`() => void`<br/> | N
23+
zIndex | Number | 1 | \- | N
24+
onLeftClick | Function | | Typescript: `() => void`<br/> | N
25+
onRightClick | Function | | Typescript: `() => void`<br/> | N
2426

2527
### CSS Variables
2628

src/navbar/navbar.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
:: BASE_DOC ::
22

33
## API
4+
45
### Navbar Props
56

67
名称 | 类型 | 默认值 | 描述 | 必传
@@ -13,10 +14,13 @@ capsule | TElement | - | 左侧胶囊区域。TS 类型:`TNode`。[通用类
1314
fixed | Boolean | true | 是否固定在顶部 | N
1415
left | TNode | - | 左侧区域。值为 `string` 表示文本,为其他表示自定义内容。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
1516
leftArrow | Boolean | false | 是否展示左侧箭头 | N
17+
placeholder | Boolean | false | `0.21.1`。固定在顶部时是否开启占位 | N
1618
right | TNode | - | 右侧区域。值为 `string` 表示文本,为其他表示自定义内容。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
19+
safeAreaInsetTop | Boolean | true | 是否开启顶部安全区适配 | N
1720
title | TNode | - | 页面标题。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
1821
titleMaxLength | Number | - | 标题文字最大长度,超出的范围使用 `...` 表示 | N
1922
visible | Boolean | true | 是否显示 | N
23+
zIndex | Number | 1 | 导航条层级 | N
2024
onLeftClick | Function | | TS 类型:`() => void`<br/>点击左侧区域时触发 | N
2125
onRightClick | Function | | TS 类型:`() => void`<br/>点击右侧区域时触发 | N
2226

src/navbar/type.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,20 @@ export interface TdNavbarProps {
3030
* @default false
3131
*/
3232
leftArrow?: boolean;
33+
/**
34+
* 固定在顶部时是否开启占位
35+
* @default false
36+
*/
37+
placeholder?: boolean;
3338
/**
3439
* 右侧区域。值为 `string` 表示文本,为其他表示自定义内容
3540
*/
3641
right?: TNode;
42+
/**
43+
* 是否开启顶部安全区适配
44+
* @default true
45+
*/
46+
safeAreaInsetTop?: boolean;
3747
/**
3848
* 页面标题
3949
*/
@@ -47,6 +57,11 @@ export interface TdNavbarProps {
4757
* @default true
4858
*/
4959
visible?: boolean;
60+
/**
61+
* 导航条层级
62+
* @default 1
63+
*/
64+
zIndex?: number;
5065
/**
5166
* 点击左侧区域时触发
5267
*/

src/style/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
import '../_common/style/mobile/_global.less';
2+
13
import '../_common/style/mobile/theme/_index.less';

0 commit comments

Comments
 (0)