mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:39:05 +08:00
feat:锚点导航支持水平样式 (#2930)
This commit is contained in:
parent
bf6f5e2681
commit
bbfad03de4
@ -105,6 +105,100 @@ order: 68
|
||||
|
||||
默认想要显示多少锚点导航配置多少个 `links` 成员即可。
|
||||
|
||||
## 水平导航
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "anchor-nav",
|
||||
"direction": "horizontal",
|
||||
"links": [
|
||||
{
|
||||
"title": "基本信息",
|
||||
"body": [
|
||||
{
|
||||
"type": "form",
|
||||
"title": "基本信息",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "name",
|
||||
"label": "姓名:"
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"type": "input-email",
|
||||
"label": "邮箱:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "工作信息",
|
||||
"body": [
|
||||
{
|
||||
"type": "form",
|
||||
"title": "工作信息",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "cname",
|
||||
"label": "公司名称:"
|
||||
},
|
||||
{
|
||||
"name": "caddress",
|
||||
"type": "input-text",
|
||||
"label": "公司地址:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "兴趣爱好",
|
||||
"body": [
|
||||
{
|
||||
"type": "form",
|
||||
"title": "兴趣爱好",
|
||||
"body": [
|
||||
{
|
||||
"type": "input-text",
|
||||
"name": "interest1",
|
||||
"label": "兴趣爱好1:"
|
||||
},
|
||||
{
|
||||
"name": "interest2",
|
||||
"type": "input-text",
|
||||
"label": "兴趣爱好2:"
|
||||
},
|
||||
{
|
||||
"name": "interest3",
|
||||
"type": "input-text",
|
||||
"label": "兴趣爱好3:"
|
||||
},
|
||||
{
|
||||
"name": "interest4",
|
||||
"type": "input-text",
|
||||
"label": "兴趣爱好4:"
|
||||
},
|
||||
{
|
||||
"name": "interest5",
|
||||
"type": "input-text",
|
||||
"label": "兴趣爱好5:"
|
||||
},
|
||||
{
|
||||
"name": "interest6",
|
||||
"type": "input-text",
|
||||
"label": "兴趣爱好6:"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 默认定位到某个区域
|
||||
|
||||
主要配置`active`属性来实现该效果,共有下面两种方法:
|
||||
@ -304,15 +398,16 @@ order: 68
|
||||
|
||||
## 属性表
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ------------------ | --------------------------------- | ----------------------------------- | ----------------------- |
|
||||
| type | `string` | `"anchor-nav"` | 指定为 AnchorNav 渲染器 |
|
||||
| className | `string` | | 外层 Dom 的类名 |
|
||||
| linkClassName | `string` | | 导航 Dom 的类名 |
|
||||
| sectionClassName | `string` | | 锚点区域 Dom 的类名 |
|
||||
| links | `Array` | | links 内容 |
|
||||
| active | `string` | | 需要定位的区域 |
|
||||
| links[x].title | `string` | | 区域 标题 |
|
||||
| links[x].href | `string` | | 区域 标识 |
|
||||
| links[x].body | [SchemaNode](../types/schemanode) | | 区域 内容区 |
|
||||
| links[x].className | `string` | `"bg-white b-l b-r b-b wrapper-md"` | 区域成员 样式 |
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ------------------ | --------------------------------- | ----------------------------------- | -------------------------------------------------------------------------- |
|
||||
| type | `string` | `"anchor-nav"` | 指定为 AnchorNav 渲染器 |
|
||||
| className | `string` | | 外层 Dom 的类名 |
|
||||
| linkClassName | `string` | | 导航 Dom 的类名 |
|
||||
| sectionClassName | `string` | | 锚点区域 Dom 的类名 |
|
||||
| links | `Array` | | links 内容 |
|
||||
| direction | `string` | `"vertical"` | 可以配置导航水平展示还是垂直展示。对应的配置项分别是:vertical、horizontal |
|
||||
| active | `string` | | 需要定位的区域 |
|
||||
| links[x].title | `string` | | 区域 标题 |
|
||||
| links[x].href | `string` | | 区域 标识 |
|
||||
| links[x].body | [SchemaNode](../types/schemanode) | | 区域 内容区 |
|
||||
| links[x].className | `string` | `"bg-white b-l b-r b-b wrapper-md"` | 区域成员 样式 |
|
||||
|
@ -2,40 +2,99 @@
|
||||
display: flex;
|
||||
height: px2rem(400px);
|
||||
|
||||
&-link-wrap {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: var(--Tabs--vertical-width);
|
||||
border-right: var(--AnchorNav-links-container-borderRight);
|
||||
padding-bottom: px2rem(60px);
|
||||
&--vertical {
|
||||
.#{$ns}AnchorNav-link-wrap {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: var(--Tabs--vertical-width);
|
||||
border-right: var(--AnchorNav-links-container-borderRight);
|
||||
padding-bottom: px2rem(60px);
|
||||
|
||||
> .#{$ns}AnchorNav-link {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
||||
> a {
|
||||
> .#{$ns}AnchorNav-link {
|
||||
position: relative;
|
||||
display: block;
|
||||
border: var(--Tabs-borderWidth) solid transparent;
|
||||
border-width: var(--AnchorNav-onActive-borderWidth);
|
||||
color: var(--Tabs-color);
|
||||
padding: var(--Tabs-linkPadding);
|
||||
font-size: var(--Tabs-linkFontSize);
|
||||
outline: none;
|
||||
text-align: right;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary);
|
||||
> a {
|
||||
display: block;
|
||||
border: var(--Tabs-borderWidth) solid transparent;
|
||||
border-width: var(--AnchorNav-onActive-borderWidth);
|
||||
color: var(--Tabs-color);
|
||||
padding: var(--Tabs-linkPadding);
|
||||
font-size: var(--Tabs-linkFontSize);
|
||||
outline: none;
|
||||
text-align: right;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
> a,
|
||||
> a:hover {
|
||||
color: var(--Tabs--vertical-onActive-color);
|
||||
border-color: var(--Tabs--vertical-onActive-border);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
> a,
|
||||
> a:hover {
|
||||
color: var(--Tabs--vertical-onActive-color);
|
||||
border-color: var(--Tabs--vertical-onActive-border);
|
||||
&--horizontal {
|
||||
flex-direction: column;
|
||||
.#{$ns}AnchorNav-link-wrap {
|
||||
user-select: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border-bottom: var(--Tabs-borderWidth) solid var(--Tabs-borderColor);
|
||||
list-style: none;
|
||||
|
||||
> .#{$ns}AnchorNav-link {
|
||||
margin-bottom: calc(var(--Tabs-borderWidth) * -1);
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
> a:first-child {
|
||||
font-size: var(--Tabs-linkFontSize);
|
||||
outline: 0;
|
||||
border: var(--Tabs-borderWidth) solid transparent;
|
||||
border-width: 0 0 var(--Tabs--line-borderWidth) 0;
|
||||
border-top-left-radius: var(--Tabs-borderRadius);
|
||||
border-top-right-radius: var(--Tabs-borderRadius);
|
||||
color: var(--Tabs-color);
|
||||
margin: var(--Tabs-linkMargin);
|
||||
padding: var(--Tabs-linkPadding);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: var(--primary);
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
> a {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
> a:first-child,
|
||||
> a:first-child:hover,
|
||||
> a:first-child:focus {
|
||||
font-size: var(--Tabs-linkFontSize);
|
||||
border-width: 0 0 var(--Tabs--line-borderWidth) 0;
|
||||
border-color: var(--Tabs--line-onHover-borderColor);
|
||||
color: var(--Tabs--line-onHover-color);
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ export interface AnchorNavProps extends ThemeProps {
|
||||
props?: AnchorNavProps
|
||||
) => JSX.Element; // 锚点区域渲染器
|
||||
onSelect?: (key: string | number) => void; // 选中回调方法
|
||||
direction?: 'vertical' | 'horizontal'; // 导航方向
|
||||
}
|
||||
|
||||
export interface AnchorNavState {
|
||||
@ -56,10 +57,11 @@ export interface AnchorNavState {
|
||||
export class AnchorNav extends React.Component<AnchorNavProps, AnchorNavState> {
|
||||
static defaultProps: Pick<
|
||||
AnchorNavProps,
|
||||
'linkClassName' | 'sectionClassName'
|
||||
'linkClassName' | 'sectionClassName' | 'direction'
|
||||
> = {
|
||||
linkClassName: '',
|
||||
sectionClassName: ''
|
||||
sectionClassName: '',
|
||||
direction: 'vertical'
|
||||
};
|
||||
|
||||
// 滚动区域DOM
|
||||
@ -214,7 +216,8 @@ export class AnchorNav extends React.Component<AnchorNavProps, AnchorNavState> {
|
||||
className,
|
||||
linkClassName,
|
||||
sectionClassName,
|
||||
children
|
||||
children,
|
||||
direction
|
||||
} = this.props;
|
||||
|
||||
if (!Array.isArray(children)) {
|
||||
@ -222,7 +225,15 @@ export class AnchorNav extends React.Component<AnchorNavProps, AnchorNavState> {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cx(`AnchorNav`, className)}>
|
||||
<div
|
||||
className={cx(
|
||||
'AnchorNav',
|
||||
{
|
||||
[`AnchorNav--${direction}`]: direction
|
||||
},
|
||||
className
|
||||
)}
|
||||
>
|
||||
<ul
|
||||
className={cx('AnchorNav-link-wrap', linkClassName)}
|
||||
role="anchorlist"
|
||||
|
@ -65,6 +65,8 @@ export interface AnchorNavSchema extends BaseSchema {
|
||||
* 楼层样式名
|
||||
*/
|
||||
sectionClassName?: SchemaClassName;
|
||||
|
||||
direction?: 'vertical' | 'horizontal';
|
||||
}
|
||||
|
||||
export interface AnchorNavProps
|
||||
@ -148,6 +150,7 @@ export default class AnchorNav extends React.Component<
|
||||
className,
|
||||
linkClassName,
|
||||
sectionClassName,
|
||||
direction,
|
||||
sectionRender,
|
||||
render,
|
||||
data
|
||||
@ -187,6 +190,7 @@ export default class AnchorNav extends React.Component<
|
||||
sectionClassName={sectionClassName}
|
||||
onSelect={this.handleSelect}
|
||||
active={this.state.active}
|
||||
direction={direction}
|
||||
>
|
||||
{children}
|
||||
</CAnchorNav>
|
||||
|
Loading…
Reference in New Issue
Block a user