feat: add page header (#1250)
* feat: add page-header component * update site: page-header * ts definition update: page-header * get page-header props with getComponentFromProp func * optimize page-header * doc: add page-header actions.md responsive.md * breadcrumb itemRender add pure function supportpull/1790/head
parent
db7f0efce5
commit
4fdf0f0cb1
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* Wrap of sub component which need use as Button capacity (like Icon component).
|
||||
* This helps accessibility reader to tread as a interactive button to operation.
|
||||
*/
|
||||
import KeyCode from './KeyCode';
|
||||
import PropTypes from './vue-types';
|
||||
|
||||
const inlineStyle = {
|
||||
border: 0,
|
||||
background: 'transparent',
|
||||
padding: 0,
|
||||
lineHeight: 'inherit',
|
||||
display: 'inline-block',
|
||||
};
|
||||
|
||||
const TransButton = {
|
||||
props: {
|
||||
noStyle: PropTypes.bool,
|
||||
},
|
||||
|
||||
methods: {
|
||||
onKeyDown(event) {
|
||||
const { keyCode } = event;
|
||||
if (keyCode === KeyCode.ENTER) {
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
onKeyUp(event) {
|
||||
const { keyCode } = event;
|
||||
if (keyCode === KeyCode.ENTER) {
|
||||
this.$emit('click', event);
|
||||
}
|
||||
},
|
||||
|
||||
setRef(btn) {
|
||||
this.div = btn;
|
||||
},
|
||||
|
||||
focus() {
|
||||
if (this.div) {
|
||||
this.div.focus();
|
||||
}
|
||||
},
|
||||
|
||||
blur() {
|
||||
if (this.div) {
|
||||
this.div.blur();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { noStyle } = this.$props;
|
||||
|
||||
return (
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
{...{
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: this.setRef,
|
||||
},
|
||||
],
|
||||
on: {
|
||||
...this.$listeners,
|
||||
keydown: this.onKeyDown,
|
||||
keyup: this.onKeyUp,
|
||||
},
|
||||
}}
|
||||
style={{ ...(!noStyle ? inlineStyle : null) }}
|
||||
>
|
||||
{this.$slots.default}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default TransButton;
|
|
@ -65,7 +65,7 @@ export default {
|
|||
}
|
||||
return (
|
||||
<BreadcrumbItem separator={separator} key={route.breadcrumbName || path}>
|
||||
{itemRender({ route, params, routes, paths })}
|
||||
{itemRender({ route, params, routes, paths, h })}
|
||||
</BreadcrumbItem>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
| Property | Description | Type | Optional | Default |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| itemRender | Custom item renderer, slot="itemRender" and slot-scope="{route, params, routes, paths}" | ({route, params, routes, paths}) => vNode | | - |
|
||||
| itemRender | Custom item renderer, slot="itemRender" and slot-scope="{route, params, routes, paths}" | ({route, params, routes, paths, h}) => vNode | | - |
|
||||
| params | Routing parameters | object | | - |
|
||||
| routes | The routing stack information of router | object\[] | | - |
|
||||
| separator | Custom separator | string\|slot | | `/` |
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| itemRender | 自定义链接函数,和 vue-router 配置使用, 也可使用 slot="itemRender" 和 slot-scope="props" | ({route, params, routes, paths}) => vNode | | - |
|
||||
| itemRender | 自定义链接函数,和 vue-router 配置使用, 也可使用 slot="itemRender" 和 slot-scope="props" | ({route, params, routes, paths, h}) => vNode | | - |
|
||||
| params | 路由的参数 | object | | - |
|
||||
| routes | router 的路由栈信息 | object\[] | | - |
|
||||
| separator | 分隔符自定义 | string\|slot | | '/' |
|
||||
|
|
|
@ -140,6 +140,7 @@ import { default as Empty } from './empty';
|
|||
import { default as Result } from './result';
|
||||
|
||||
import { default as Descriptions } from './descriptions';
|
||||
import { default as PageHeader } from './page-header';
|
||||
|
||||
const components = [
|
||||
Base,
|
||||
|
@ -201,6 +202,7 @@ const components = [
|
|||
Empty,
|
||||
Result,
|
||||
Descriptions,
|
||||
PageHeader,
|
||||
];
|
||||
|
||||
const install = function(Vue) {
|
||||
|
@ -287,6 +289,7 @@ export {
|
|||
Empty,
|
||||
Result,
|
||||
Descriptions,
|
||||
PageHeader,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
@ -47,4 +47,7 @@ export default {
|
|||
Icon: {
|
||||
icon: 'icon',
|
||||
},
|
||||
PageHeader: {
|
||||
back: 'Back',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -39,4 +39,7 @@ export default {
|
|||
Empty: {
|
||||
description: 'No hay datos',
|
||||
},
|
||||
PageHeader: {
|
||||
back: 'volver',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -39,4 +39,7 @@ export default {
|
|||
Empty: {
|
||||
description: 'Нет данных',
|
||||
},
|
||||
PageHeader: {
|
||||
back: 'назад',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -47,4 +47,7 @@ export default {
|
|||
Icon: {
|
||||
icon: '图标',
|
||||
},
|
||||
PageHeader: {
|
||||
back: '返回',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -39,4 +39,7 @@ export default {
|
|||
Empty: {
|
||||
description: '無此資料',
|
||||
},
|
||||
PageHeader: {
|
||||
back: '返回',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,896 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/page-header/demo/actions.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-page-header"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-heading"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-back"
|
||||
>
|
||||
<div
|
||||
aria-label="Back"
|
||||
class="ant-page-header-back-button"
|
||||
role="button"
|
||||
style="border: 0px; background: transparent; padding: 0px; line-height: inherit; display: inline-block;"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: arrow-left"
|
||||
class="anticon anticon-arrow-left"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="arrow-left"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 0 0 0 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-page-header-heading-title"
|
||||
>
|
||||
Title
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-sub-title"
|
||||
>
|
||||
This is a subtitle
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-page-header-content"
|
||||
>
|
||||
|
||||
<div
|
||||
class="ant-descriptions ant-descriptions-small"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-view"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Created
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
Lili Qu
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Association
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
<a>
|
||||
421421
|
||||
</a>
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Creation Time
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
2017-01-10
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Effective Time
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
2017-10-10
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="2"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Remarks
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
|
||||
Gonghu Road, Xihu District, Hangzhou, Zhejiang, China
|
||||
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div
|
||||
class="ant-page-header"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-heading"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-back"
|
||||
>
|
||||
<div
|
||||
aria-label="Back"
|
||||
class="ant-page-header-back-button"
|
||||
role="button"
|
||||
style="border: 0px; background: transparent; padding: 0px; line-height: inherit; display: inline-block;"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: arrow-left"
|
||||
class="anticon anticon-arrow-left"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="arrow-left"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 0 0 0 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-page-header-heading-title"
|
||||
>
|
||||
Title
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-sub-title"
|
||||
>
|
||||
This is a subtitle
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-tags"
|
||||
>
|
||||
<div
|
||||
class="ant-tag ant-tag-blue"
|
||||
>
|
||||
Running
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-page-header-content"
|
||||
>
|
||||
|
||||
<div
|
||||
class="ant-row-flex"
|
||||
>
|
||||
<div
|
||||
class="ant-statistic"
|
||||
>
|
||||
<div
|
||||
class="ant-statistic-title"
|
||||
>
|
||||
Status
|
||||
</div>
|
||||
<div
|
||||
class="ant-statistic-content"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-value"
|
||||
>
|
||||
Pending
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="ant-statistic"
|
||||
style="margin: 0px 32px;"
|
||||
>
|
||||
<div
|
||||
class="ant-statistic-title"
|
||||
>
|
||||
Price
|
||||
</div>
|
||||
<div
|
||||
class="ant-statistic-content"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-prefix"
|
||||
>
|
||||
$
|
||||
</span>
|
||||
<span
|
||||
class="ant-statistic-content-value"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-value-int"
|
||||
>
|
||||
568
|
||||
</span>
|
||||
<span
|
||||
class="ant-statistic-content-value-decimal"
|
||||
>
|
||||
.08
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="ant-statistic"
|
||||
>
|
||||
<div
|
||||
class="ant-statistic-title"
|
||||
>
|
||||
Balance
|
||||
</div>
|
||||
<div
|
||||
class="ant-statistic-content"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-prefix"
|
||||
>
|
||||
$
|
||||
</span>
|
||||
<span
|
||||
class="ant-statistic-content-value"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-value-int"
|
||||
>
|
||||
3,345
|
||||
</span>
|
||||
<span
|
||||
class="ant-statistic-content-value-decimal"
|
||||
>
|
||||
.08
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/page-header/demo/basic.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-page-header"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-heading"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-back"
|
||||
>
|
||||
<div
|
||||
aria-label="Back"
|
||||
class="ant-page-header-back-button"
|
||||
role="button"
|
||||
style="border: 0px; background: transparent; padding: 0px; line-height: inherit; display: inline-block;"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: arrow-left"
|
||||
class="anticon anticon-arrow-left"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="arrow-left"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 0 0 0 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-page-header-heading-title"
|
||||
>
|
||||
Title
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-sub-title"
|
||||
>
|
||||
This is a subtitle
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/page-header/demo/breadcrumb.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-page-header has-breadcrumb"
|
||||
>
|
||||
<div
|
||||
class="ant-breadcrumb"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
<a
|
||||
href="#/index"
|
||||
>
|
||||
First-level Menu
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
<a
|
||||
href="#/index/first"
|
||||
>
|
||||
Second-level Menu
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
<span>
|
||||
Third-level Menu
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
/
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-page-header-heading"
|
||||
>
|
||||
<span
|
||||
class="ant-page-header-heading-title"
|
||||
>
|
||||
Title
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-sub-title"
|
||||
>
|
||||
This is a subtitle
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/page-header/demo/responsive.md correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="ant-page-header has-footer"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-heading"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-back"
|
||||
>
|
||||
<div
|
||||
aria-label="Back"
|
||||
class="ant-page-header-back-button"
|
||||
role="button"
|
||||
style="border: 0px; background: transparent; padding: 0px; line-height: inherit; display: inline-block;"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: arrow-left"
|
||||
class="anticon anticon-arrow-left"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="arrow-left"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 0 0 0 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-page-header-heading-title"
|
||||
>
|
||||
Title
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-sub-title"
|
||||
>
|
||||
This is a subtitle
|
||||
</span>
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-page-header-content"
|
||||
>
|
||||
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<div
|
||||
class="main"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions ant-descriptions-small"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-view"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Created
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
Lili Qu
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Association
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
<a>
|
||||
421421
|
||||
</a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Creation Time
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
2017-01-10
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Effective Time
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
2017-10-10
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="2"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
>
|
||||
Remarks
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
|
||||
Gonghu Road, Xihu District, Hangzhou, Zhejiang, China
|
||||
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="extra"
|
||||
>
|
||||
<div
|
||||
style="display: flex; justify-content: flex-end;"
|
||||
>
|
||||
<div
|
||||
class="ant-statistic"
|
||||
style="margin-right: 32px;"
|
||||
>
|
||||
<div
|
||||
class="ant-statistic-title"
|
||||
>
|
||||
Status
|
||||
</div>
|
||||
<div
|
||||
class="ant-statistic-content"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-value"
|
||||
>
|
||||
Pending
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="ant-statistic"
|
||||
>
|
||||
<div
|
||||
class="ant-statistic-title"
|
||||
>
|
||||
Price
|
||||
</div>
|
||||
<div
|
||||
class="ant-statistic-content"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-prefix"
|
||||
>
|
||||
$
|
||||
</span>
|
||||
<span
|
||||
class="ant-statistic-content-value"
|
||||
>
|
||||
<span
|
||||
class="ant-statistic-content-value-int"
|
||||
>
|
||||
568
|
||||
</span>
|
||||
<span
|
||||
class="ant-statistic-content-value-decimal"
|
||||
>
|
||||
.08
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-page-header-footer"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top ant-tabs-line"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-bar ant-tabs-top-bar"
|
||||
role="tablist"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-container"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-prev ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-prev-icon"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: left"
|
||||
class="ant-tabs-tab-prev-icon-target anticon anticon-left"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="left"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tabs-tab-next ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-next-icon"
|
||||
>
|
||||
<i
|
||||
aria-label="icon: right"
|
||||
class="ant-tabs-tab-next-icon-target anticon anticon-right"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</i>
|
||||
</span>
|
||||
</span>
|
||||
<div
|
||||
class="ant-tabs-nav-wrap"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-scroll"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav ant-tabs-nav-animated"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-active ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
Details
|
||||
</div>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class=" ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
Rule
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
|
||||
style="display: block; transform: translate3d(0px,0,0); webkit-transform: translate3d(0px,0,0); width: 0px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
role="presentation"
|
||||
style="width: 0px; height: 0px; overflow: hidden; position: absolute;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
class="ant-tabs-content ant-tabs-content-animated ant-tabs-top-content"
|
||||
style="margin-left: 0%;"
|
||||
>
|
||||
<div
|
||||
aria-hidden="false"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||
role="tabpanel"
|
||||
>
|
||||
<div
|
||||
role="presentation"
|
||||
style="width: 0px; height: 0px; overflow: hidden; position: absolute;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
role="presentation"
|
||||
style="width: 0px; height: 0px; overflow: hidden; position: absolute;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-inactive"
|
||||
role="tabpanel"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
role="presentation"
|
||||
style="width: 0px; height: 0px; overflow: hidden; position: absolute;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,23 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PageHeader pageHeader should not render blank dom 1`] = `
|
||||
<div
|
||||
class="ant-page-header"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`PageHeader pageHeader should support class 1`] = `
|
||||
<div
|
||||
class="ant-page-header not-works"
|
||||
>
|
||||
<div
|
||||
class="ant-page-header-heading"
|
||||
>
|
||||
<span
|
||||
class="ant-page-header-heading-title"
|
||||
>
|
||||
Page Title
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,3 @@
|
|||
import demoTest from '../../../tests/shared/demoTest';
|
||||
|
||||
demoTest('page-header', { getDomFromElement: true });
|
|
@ -0,0 +1,133 @@
|
|||
import { createLocalVue, mount } from '@vue/test-utils';
|
||||
import PageHeader from '..';
|
||||
import ref from 'vue-ref';
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(ref, { name: 'ant-ref' });
|
||||
|
||||
describe('PageHeader', () => {
|
||||
it('pageHeader should not contain back it back', () => {
|
||||
const routes = [
|
||||
{
|
||||
path: 'index',
|
||||
breadcrumbName: 'First-level Menu',
|
||||
},
|
||||
{
|
||||
path: 'first',
|
||||
breadcrumbName: 'Second-level Menu',
|
||||
},
|
||||
{
|
||||
path: 'second',
|
||||
breadcrumbName: 'Third-level Menu',
|
||||
},
|
||||
];
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return <PageHeader title="Page Title" breadcrumb={{ props: { routes } }} />;
|
||||
},
|
||||
});
|
||||
expect(wrapper.findAll('.ant-page-header-back')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('pageHeader should have breadcrumb', () => {
|
||||
const routes = [
|
||||
{
|
||||
path: 'index',
|
||||
breadcrumbName: 'First-level Menu',
|
||||
},
|
||||
];
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return <PageHeader title="Page Title" breadcrumb={{ props: { routes } }} />;
|
||||
},
|
||||
});
|
||||
expect(wrapper.findAll('.ant-breadcrumb')).toHaveLength(1);
|
||||
expect(wrapper.findAll('.ant-page-header-back')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('pageHeader should no contain back', () => {
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return <PageHeader title="Page Title" backIcon={false} />;
|
||||
},
|
||||
});
|
||||
expect(wrapper.findAll('.ant-page-header-back')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('pageHeader should contain back it back', () => {
|
||||
const callback = jest.fn(() => true);
|
||||
const wrapper = mount(
|
||||
{
|
||||
render() {
|
||||
return <PageHeader title="Page Title" onBack={callback} />;
|
||||
},
|
||||
},
|
||||
{ localVue },
|
||||
);
|
||||
expect(wrapper.findAll('.ant-page-header-back')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('pageHeader onBack transfer', () => {
|
||||
const callback = jest.fn(() => true);
|
||||
const wrapper = mount(
|
||||
{
|
||||
render() {
|
||||
return <PageHeader title="Page Title" onBack={callback} />;
|
||||
},
|
||||
},
|
||||
{ localVue },
|
||||
);
|
||||
wrapper.find('div.ant-page-header-back-button').trigger('click');
|
||||
expect(callback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('pageHeader should support class', () => {
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return <PageHeader title="Page Title" class="not-works" backIcon={false} />;
|
||||
},
|
||||
});
|
||||
expect(wrapper.element).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('pageHeader should not render blank dom', () => {
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return <PageHeader title={false} />;
|
||||
},
|
||||
});
|
||||
expect(wrapper.element).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('breadcrumbs and back icon can coexist', () => {
|
||||
const routes = [
|
||||
{
|
||||
path: 'index',
|
||||
breadcrumbName: 'First-level Menu',
|
||||
},
|
||||
{
|
||||
path: 'first',
|
||||
breadcrumbName: 'Second-level Menu',
|
||||
},
|
||||
{
|
||||
path: 'second',
|
||||
breadcrumbName: 'Third-level Menu',
|
||||
},
|
||||
];
|
||||
const wrapper = mount({
|
||||
render() {
|
||||
return <PageHeader title="Title" breadcrumb={{ props: { routes } }} />;
|
||||
},
|
||||
});
|
||||
expect(wrapper.findAll('.ant-breadcrumb')).toHaveLength(1);
|
||||
|
||||
const wrapperBack = mount(
|
||||
{
|
||||
render() {
|
||||
return <PageHeader title="Title" breadcrumb={{ props: { routes } }} onBack={() => {}} />;
|
||||
},
|
||||
},
|
||||
{ localVue },
|
||||
);
|
||||
expect(wrapperBack.findAll('.ant-breadcrumb')).toHaveLength(1);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,74 @@
|
|||
<cn>
|
||||
#### 多种形态的 PageHeader
|
||||
使用操作区,并自定义子节点,适合使用在需要展示一些复杂的信息,帮助用户快速了解这个页面的信息和操作。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Various forms of PageHeader
|
||||
Use the operating area and customize the sub-nodes, suitable for use in the need to display some complex information to help users quickly understand the information and operations of this page.
|
||||
</us>
|
||||
|
||||
```tpl
|
||||
<template>
|
||||
<div>
|
||||
<a-page-header
|
||||
@back="() => $router.go(-1)"
|
||||
title="Title"
|
||||
subTitle="This is a subtitle"
|
||||
>
|
||||
<template slot="extra">
|
||||
<a-button key="3">Operation</a-button>
|
||||
<a-button key="2">Operation</a-button>
|
||||
<a-button key="1" type="primary">
|
||||
Primary
|
||||
</a-button>
|
||||
</template>
|
||||
<a-descriptions size="small" :column="3">
|
||||
<a-descriptions-item label="Created">Lili Qu</a-descriptions-item>
|
||||
<a-descriptions-item label="Association">
|
||||
<a>421421</a>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="Creation Time">2017-01-10</a-descriptions-item>
|
||||
<a-descriptions-item label="Effective Time">2017-10-10</a-descriptions-item>
|
||||
<a-descriptions-item label="Remarks">
|
||||
Gonghu Road, Xihu District, Hangzhou, Zhejiang, China
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-page-header>
|
||||
<br />
|
||||
<a-page-header
|
||||
@back="() => $router.go(-1)"
|
||||
title="Title"
|
||||
subTitle="This is a subtitle"
|
||||
>
|
||||
<template slot="tags">
|
||||
<a-tag color="blue">Running</a-tag>
|
||||
</template>
|
||||
<template slot="extra">
|
||||
<a-button key="3">Operation</a-button>
|
||||
<a-button key="2">Operation</a-button>
|
||||
<a-button key="1" type="primary">
|
||||
Primary
|
||||
</a-button>
|
||||
</template>
|
||||
<a-row type="flex">
|
||||
<a-statistic title="Status" value="Pending" />
|
||||
<a-statistic
|
||||
title="Price"
|
||||
prefix="$"
|
||||
:value="568.08"
|
||||
:style="{
|
||||
margin: '0 32px',
|
||||
}"
|
||||
/>
|
||||
<a-statistic title="Balance" prefix="$" :value="3345.08" />
|
||||
</a-row>
|
||||
</a-page-header>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
tr:last-child td {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
<cn>
|
||||
#### 标准样式
|
||||
标准页头,适合使用在需要简单描述的场景。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Basic Page Header
|
||||
Standard header, suitable for use in scenarios that require a brief description.
|
||||
</us>
|
||||
|
||||
```tpl
|
||||
<template>
|
||||
<a-page-header @back="() => null" title="Title" subTitle="This is a subtitle" />
|
||||
</template>
|
||||
<style>
|
||||
.code-box-demo .ant-page-header {
|
||||
border: 1px solid rgb(235, 237, 240);
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,37 @@
|
|||
<cn>
|
||||
#### 带面包屑页头
|
||||
带面包屑页头,适合层级比较深的页面,让用户可以快速导航。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Use with breadcrumbs
|
||||
With breadcrumbs, it is suitable for deeper pages, allowing users to navigate quickly.
|
||||
</us>
|
||||
|
||||
```tpl
|
||||
<template>
|
||||
<a-page-header title="Title" :breadcrumb="{ props: { routes } }" subTitle="This is a subtitle" />
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
routes: [
|
||||
{
|
||||
path: 'index',
|
||||
breadcrumbName: 'First-level Menu',
|
||||
},
|
||||
{
|
||||
path: 'first',
|
||||
breadcrumbName: 'Second-level Menu',
|
||||
},
|
||||
{
|
||||
path: 'second',
|
||||
breadcrumbName: 'Third-level Menu',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,57 @@
|
|||
<script>
|
||||
import Basic from './basic';
|
||||
import Breadcrumb from './breadcrumb';
|
||||
import Actions from './actions';
|
||||
import Responsive from './responsive';
|
||||
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
|
||||
import '../style';
|
||||
|
||||
const md = {
|
||||
cn: `# PageHeader 页头
|
||||
|
||||
页头位于页容器中,页容器顶部,起到了内容概览和引导页级操作的作用。包括由面包屑、标题、页面内容简介、页面级操作等、页面级导航组成。
|
||||
|
||||
## 何时使用
|
||||
|
||||
当需要使用户快速理解当前页是什么以及方便用户使用页面功能时使用,通常也可被用作页面间导航。
|
||||
|
||||
## 代码演示
|
||||
`,
|
||||
us: `# PageHeader
|
||||
|
||||
The header can be used to declare the page topic, display important information about the page that the user is interested in, and carry the action items related to the current page (including page-level operations, inter-page navigation, etc.)
|
||||
|
||||
## When To Use
|
||||
|
||||
It can also be used as inter-page navigation when it is needed to make the user quickly understand what the current page is and to facilitate the user to use the page function.
|
||||
|
||||
## Examples
|
||||
`,
|
||||
};
|
||||
|
||||
export default {
|
||||
category: 'Components',
|
||||
subtitle: '页头',
|
||||
type: 'Navigation',
|
||||
title: 'PageHeader',
|
||||
cols: 1,
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<Basic />
|
||||
<Breadcrumb />
|
||||
<Actions />
|
||||
<Responsive />
|
||||
<api>
|
||||
<CN slot="cn" />
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,88 @@
|
|||
<cn>
|
||||
#### 响应式
|
||||
在不同大小的屏幕下,应该有不同的表现
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### responsive
|
||||
Under different screen sizes, there should be different performance
|
||||
</us>
|
||||
|
||||
```tpl
|
||||
<template>
|
||||
<div>
|
||||
<a-page-header @back="() => $router.go(-1)" title="Title" subTitle="This is a subtitle">
|
||||
<template slot="extra">
|
||||
<a-button key="3">Operation</a-button>
|
||||
<a-button key="2">Operation</a-button>
|
||||
<a-button key="1" type="primary">
|
||||
Primary
|
||||
</a-button>
|
||||
</template>
|
||||
<template slot="footer">
|
||||
<a-tabs defaultActiveKey="1">
|
||||
<a-tab-pane tab="Details" key="1" />
|
||||
<a-tab-pane tab="Rule" key="2" />
|
||||
</a-tabs>
|
||||
</template>
|
||||
<div class="content">
|
||||
<div class="main">
|
||||
<a-descriptions size="small" :column="2">
|
||||
<a-descriptions-item label="Created">Lili Qu</a-descriptions-item>
|
||||
<a-descriptions-item label="Association">
|
||||
<a>421421</a>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="Creation Time">2017-01-10</a-descriptions-item>
|
||||
<a-descriptions-item label="Effective Time">2017-10-10</a-descriptions-item>
|
||||
<a-descriptions-item label="Remarks">
|
||||
Gonghu Road, Xihu District, Hangzhou, Zhejiang, China
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
<div class="extra">
|
||||
<div
|
||||
:style="{
|
||||
display: 'flex',
|
||||
width: 'max-content',
|
||||
justifyContent: 'flex-end',
|
||||
}"
|
||||
>
|
||||
<a-statistic
|
||||
title="Status"
|
||||
value="Pending"
|
||||
:style="{
|
||||
marginRight: '32px',
|
||||
}"
|
||||
/>
|
||||
<a-statistic title="Price" prefix="$" :value="568.08" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-page-header>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
tr:last-child td {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
#components-page-header-demo-responsive .content {
|
||||
display: flex;
|
||||
}
|
||||
@media (max-width: 576px) {
|
||||
#components-page-header-demo-responsive .content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#components-page-header-demo-responsive .main {
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
#components-page-header-demo-responsive .extra {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,18 @@
|
|||
## API
|
||||
|
||||
| Param | Description | Type | Default value |
|
||||
| --- | --- | --- | --- |
|
||||
| title | custom title text | string\|slot | - |
|
||||
| subTitle | custom subTitle text | string\|slot | - |
|
||||
| avatar | Avatar next to the title bar | [avatar props](/components/avatar/) | - |
|
||||
| backIcon | custom back icon, if false the back icon will not be displayed | string\|slot | `<Icon type="arrow-left" />` |
|
||||
| tags | Tag list next to title | [Tag](/components/tag/)[] \| [Tag](/components/tag/) | - |
|
||||
| extra | Operating area, at the end of the line of the title line | string\|slot | - |
|
||||
| breadcrumb | breadcrumb config | [breadcrumb](/components/breadcrumb/) | - |
|
||||
| footer | PageHeader's footer, generally used to render TabBar | string\|slot | - |
|
||||
|
||||
### Events
|
||||
|
||||
| Events Name | Description | Arguments |
|
||||
| ------------- | -------------------------------------- | ----------------- |
|
||||
| back | back icon click event | function(e) |
|
|
@ -0,0 +1,128 @@
|
|||
import PropTypes from '../_util/vue-types';
|
||||
import { getComponentFromProp } from '../_util/props-util';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
import Icon from '../icon';
|
||||
import Breadcrumb from '../breadcrumb';
|
||||
import Avatar from '../avatar';
|
||||
import TransButton from '../_util/transButton';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import Base from '../base';
|
||||
|
||||
export const PageHeaderProps = {
|
||||
backIcon: PropTypes.any,
|
||||
prefixCls: PropTypes.string,
|
||||
title: PropTypes.any,
|
||||
subTitle: PropTypes.any,
|
||||
breadcrumb: PropTypes.object,
|
||||
tags: PropTypes.any,
|
||||
footer: PropTypes.any,
|
||||
extra: PropTypes.any,
|
||||
avatar: PropTypes.object,
|
||||
};
|
||||
|
||||
const renderBack = (instance, prefixCls, backIcon, onBack) => {
|
||||
const h = instance.$createElement;
|
||||
if (!backIcon || !onBack) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<LocaleReceiver componentName="PageHeader">
|
||||
{({ back }) => (
|
||||
<div class={`${prefixCls}-back`}>
|
||||
<TransButton
|
||||
onClick={e => {
|
||||
instance.$emit('back', e);
|
||||
}}
|
||||
class={`${prefixCls}-back-button`}
|
||||
aria-label={back}
|
||||
>
|
||||
{backIcon}
|
||||
</TransButton>
|
||||
</div>
|
||||
)}
|
||||
</LocaleReceiver>
|
||||
);
|
||||
};
|
||||
|
||||
const renderBreadcrumb = (h, breadcrumb) => {
|
||||
return <Breadcrumb {...breadcrumb } />;
|
||||
};
|
||||
|
||||
const renderTitle = (h, prefixCls, instance) => {
|
||||
const {
|
||||
avatar,
|
||||
} = instance;
|
||||
const title = getComponentFromProp(instance, 'title');
|
||||
const subTitle = getComponentFromProp(instance, 'subTitle');
|
||||
const tags = getComponentFromProp(instance, 'tags');
|
||||
const extra = getComponentFromProp(instance, 'extra');
|
||||
const backIcon = getComponentFromProp(instance, 'backIcon') || <Icon type="arrow-left" />;
|
||||
const onBack = instance.$listeners.back;
|
||||
const headingPrefixCls = `${prefixCls}-heading`;
|
||||
if (title || subTitle || tags || extra) {
|
||||
const backIconDom = renderBack(instance, prefixCls, backIcon, onBack);
|
||||
return (
|
||||
<div class={headingPrefixCls}>
|
||||
{backIconDom}
|
||||
{avatar && <Avatar {...avatar } />}
|
||||
{title && <span class={`${headingPrefixCls}-title`}>{title}</span>}
|
||||
{subTitle && <span class={`${headingPrefixCls}-sub-title`}>{subTitle}</span>}
|
||||
{tags && <span class={`${headingPrefixCls}-tags`}>{tags}</span>}
|
||||
{extra && <span class={`${headingPrefixCls}-extra`}>{extra}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const renderFooter = (h, prefixCls, footer) => {
|
||||
if (footer) {
|
||||
return <div class={`${prefixCls}-footer`}>{footer}</div>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const renderChildren = (h, prefixCls, children) => {
|
||||
return <div class={`${prefixCls}-content`}>{children}</div>;
|
||||
};
|
||||
|
||||
const PageHeader = {
|
||||
name: 'APageHeader',
|
||||
props: PageHeaderProps,
|
||||
inject: {
|
||||
configProvider: { default: () => ConfigConsumerProps },
|
||||
},
|
||||
render(h) {
|
||||
const { getPrefixCls } = this.configProvider;
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
breadcrumb,
|
||||
} = this.$props;
|
||||
const footer = getComponentFromProp(this, 'footer');
|
||||
const children = this.$slots.default;
|
||||
|
||||
const prefixCls = getPrefixCls('page-header', customizePrefixCls);
|
||||
const breadcrumbDom = breadcrumb && breadcrumb.props && breadcrumb.props.routes ? renderBreadcrumb(h, breadcrumb) : null;
|
||||
const className = [prefixCls, {
|
||||
'has-breadcrumb': breadcrumbDom,
|
||||
'has-footer': footer,
|
||||
}];
|
||||
|
||||
return (
|
||||
<div class={className}>
|
||||
{breadcrumbDom}
|
||||
{renderTitle(h, prefixCls, this)}
|
||||
{children && renderChildren(h, prefixCls, children)}
|
||||
{renderFooter(h, prefixCls, footer)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
PageHeader.install = function(Vue) {
|
||||
Vue.use(Base);
|
||||
Vue.component(PageHeader.name, PageHeader);
|
||||
};
|
||||
|
||||
export default PageHeader;
|
|
@ -0,0 +1,18 @@
|
|||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| title | 自定义标题文字 | string\|slot | - |
|
||||
| subTitle | 自定义的二级标题文字 | string\|slot | - |
|
||||
| avatar | 标题栏旁的头像 | [avatar props](/components/avatar-cn/) | - |
|
||||
| backIcon | 自定义 back icon ,如果为 false 不渲染 back icon | string\|slot | `<Icon type="arrow-left" />` |
|
||||
| tags | title 旁的 tag 列表 | [Tag](/components/tag-cn/)[] \| [Tag](/components/tag-cn/) | - |
|
||||
| extra | 操作区,位于 title 行的行尾 | string\|slot | - |
|
||||
| breadcrumb | 面包屑的配置 | [breadcrumb](/components/breadcrumb-cn/) | - |
|
||||
| footer | PageHeader 的页脚,一般用于渲染 TabBar | string\|slot | - |
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
| ------------- | -------------------------------------- | ----------------- |
|
||||
| back | 返回按钮的点击事件 | function(e) |
|
|
@ -0,0 +1,5 @@
|
|||
import './index.less';
|
||||
|
||||
// style dependencies
|
||||
import '../../breadcrumb/style';
|
||||
import '../../avatar/style';
|
|
@ -0,0 +1,115 @@
|
|||
@import '../../style/themes/default';
|
||||
@import '../../style/mixins/index';
|
||||
|
||||
@pageheader-prefix-cls: ~'@{ant-prefix}-page-header';
|
||||
|
||||
.@{pageheader-prefix-cls} {
|
||||
.reset-component;
|
||||
|
||||
position: relative;
|
||||
padding: @page-header-padding;
|
||||
|
||||
&.has-breadcrumb {
|
||||
padding-top: @page-header-padding-breadcrumb;
|
||||
}
|
||||
|
||||
&.has-footer {
|
||||
padding-bottom: @page-header-padding-vertical;
|
||||
}
|
||||
|
||||
&-back {
|
||||
float: left;
|
||||
margin: 6px 0;
|
||||
margin-right: 16px;
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
&-button {
|
||||
.operation-unit();
|
||||
color: @page-header-back-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.@{ant-prefix}-divider-vertical {
|
||||
height: 14px;
|
||||
margin: 0 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.@{ant-prefix}-breadcrumb + &-heading {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
&-heading {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
&-title {
|
||||
display: block;
|
||||
float: left;
|
||||
margin-bottom: 0;
|
||||
padding-right: 12px;
|
||||
color: @heading-color;
|
||||
font-weight: 600;
|
||||
font-size: @heading-3-size;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.@{ant-prefix}-avatar {
|
||||
float: left;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
&-sub-title {
|
||||
float: left;
|
||||
margin: 5px 0;
|
||||
margin-right: 12px;
|
||||
color: @text-color-secondary;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
&-tags {
|
||||
float: left;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
&-extra {
|
||||
float: right;
|
||||
> * {
|
||||
margin-left: 8px;
|
||||
}
|
||||
> *:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
padding-top: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
margin-top: 16px;
|
||||
.@{ant-prefix}-tabs-bar {
|
||||
margin-bottom: 1px;
|
||||
border-bottom: 0;
|
||||
.@{ant-prefix}-tabs-nav .@{ant-prefix}-tabs-tab {
|
||||
padding: 8px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: @screen-sm) {
|
||||
&-heading {
|
||||
&-extra {
|
||||
display: block;
|
||||
float: unset;
|
||||
width: 100%;
|
||||
padding-top: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,3 +57,4 @@ import './empty/style';
|
|||
import './statistic/style';
|
||||
import './result/style';
|
||||
import './descriptions/style';
|
||||
import './page-header/style';
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
@import 'iconfont';
|
||||
@import 'motion';
|
||||
@import 'reset';
|
||||
@import 'operation-unit';
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
@import '../../style/themes/default';
|
||||
|
||||
.operation-unit() {
|
||||
color: @link-color;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: @link-hover-color;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: @link-active-color;
|
||||
}
|
||||
}
|
|
@ -54,6 +54,10 @@
|
|||
@font-size-base: 14px;
|
||||
@font-size-lg: @font-size-base + 2px;
|
||||
@font-size-sm: 12px;
|
||||
@heading-1-size: ceil(@font-size-base * 2.71);
|
||||
@heading-2-size: ceil(@font-size-base * 2.14);
|
||||
@heading-3-size: ceil(@font-size-base * 1.71);
|
||||
@heading-4-size: ceil(@font-size-base * 1.42);
|
||||
@line-height-base: 1.5;
|
||||
@border-radius-base: 4px;
|
||||
@border-radius-sm: 2px;
|
||||
|
@ -492,6 +496,13 @@
|
|||
@pagination-font-family: Arial;
|
||||
@pagination-font-weight-active: 500;
|
||||
|
||||
// PageHeader
|
||||
// ---
|
||||
@page-header-padding: 24px;
|
||||
@page-header-padding-vertical: 16px;
|
||||
@page-header-padding-breadcrumb: 12px;
|
||||
@page-header-back-color: #000;
|
||||
|
||||
// Breadcrumb
|
||||
// ---
|
||||
@breadcrumb-base-color: @text-color-secondary;
|
||||
|
|
|
@ -63,6 +63,7 @@ import {
|
|||
Base,
|
||||
Result,
|
||||
Descriptions,
|
||||
PageHeader,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
Vue.prototype.$message = message;
|
||||
|
@ -134,6 +135,7 @@ Vue.use(ConfigProvider);
|
|||
Vue.use(Empty);
|
||||
Vue.use(Result);
|
||||
Vue.use(Descriptions);
|
||||
Vue.use(PageHeader);
|
||||
|
||||
/* v1.1.2 registration methods */
|
||||
// Vue.component(Affix.name, Affix) // a-affix
|
||||
|
|
|
@ -93,6 +93,13 @@ export default {
|
|||
title: 'Pagination',
|
||||
cols: 1,
|
||||
},
|
||||
pageHeader: {
|
||||
category: 'Components',
|
||||
subtitle: '页头',
|
||||
type: 'Navigation',
|
||||
title: 'PageHeader',
|
||||
cols: 1,
|
||||
},
|
||||
popconfirm: {
|
||||
category: 'Components',
|
||||
subtitle: '气泡确认框',
|
||||
|
|
|
@ -470,5 +470,11 @@ export default [
|
|||
{
|
||||
path: 'descriptions-cn',
|
||||
component: () => import('../components/descriptions/demo/index.vue'),
|
||||
path: 'page-header',
|
||||
component: () => import('../components/page-header/demo/index.vue'),
|
||||
},
|
||||
{
|
||||
path: 'page-header-cn',
|
||||
component: () => import('../components/page-header/demo/index.vue'),
|
||||
},
|
||||
];
|
||||
|
|
|
@ -65,6 +65,7 @@ Array [
|
|||
"Empty",
|
||||
"Result",
|
||||
"Descriptions",
|
||||
"PageHeader",
|
||||
"default",
|
||||
]
|
||||
`;
|
||||
|
|
|
@ -20,7 +20,11 @@ export default function demoTest(component, options = {}) {
|
|||
const demo = require(`../.${file}`).default || require(`../.${file}`); // eslint-disable-line global-require, import/no-dynamic-require
|
||||
const wrapper = mount(demo, { sync: false });
|
||||
Vue.nextTick(() => {
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
// should get dom from element
|
||||
// snap files copy from antd does not need to change
|
||||
// or just change a little
|
||||
const dom = options.getDomFromElement ? wrapper.element : wrapper.html();
|
||||
expect(dom).toMatchSnapshot();
|
||||
MockDate.reset();
|
||||
wrapper.destroy();
|
||||
done();
|
||||
|
|
|
@ -63,6 +63,7 @@ import { Tooltip } from './tootip/tooltip';
|
|||
import { Upload } from './upload';
|
||||
import { Result } from './result';
|
||||
import { Descriptions } from './descriptions/descriptions'
|
||||
import { PageHeader } from './page-header';
|
||||
|
||||
/**
|
||||
* Install all ant-design-vue components into Vue.
|
||||
|
@ -133,4 +134,5 @@ export {
|
|||
Skeleton,
|
||||
Result,
|
||||
Descriptions,
|
||||
PageHeader,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// Project: https://github.com/vueComponent/ant-design-vue
|
||||
// Definitions by: drafish <https://github.com/drafish>
|
||||
// Definitions: https://github.com/vueComponent/ant-design-vue/types
|
||||
|
||||
import { AntdComponent } from './component';
|
||||
|
||||
export declare class PageHeader extends AntdComponent {
|
||||
|
||||
/**
|
||||
* Custom backIcon
|
||||
* @default <Icon type="arrow-left" />
|
||||
* @type any (string | slot)
|
||||
*/
|
||||
backIcon: any;
|
||||
|
||||
/**
|
||||
* Custom prefixCls
|
||||
* @type string
|
||||
*/
|
||||
prefixCls: string;
|
||||
|
||||
/**
|
||||
* Custom title
|
||||
* @type any (string | slot)
|
||||
*/
|
||||
title: any;
|
||||
|
||||
/**
|
||||
* Custom subTitle
|
||||
* @type any (string | slot)
|
||||
*/
|
||||
subTitle: any;
|
||||
|
||||
breadcrumb: object;
|
||||
|
||||
/**
|
||||
* Custom tags
|
||||
* @type any (string | slot)
|
||||
*/
|
||||
tags: any;
|
||||
|
||||
/**
|
||||
* Custom footer
|
||||
* @type any (string | slot)
|
||||
*/
|
||||
footer: any;
|
||||
|
||||
/**
|
||||
* Custom extra
|
||||
* @type any (string | slot)
|
||||
*/
|
||||
extra: any;
|
||||
|
||||
avatar: object;
|
||||
|
||||
/**
|
||||
* Specify a callback that will be called when a user clicks backIcon.
|
||||
*/
|
||||
back(): void;
|
||||
}
|
Loading…
Reference in New Issue