Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(List): finish List component #13

Merged
merged 1 commit into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/List/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useState } from 'react';
import { IListItemPropsType } from '@/List/PropsType';
import Icon from '@/Icon';
import Touchable from '@ant-design/mobile-touchable';
import classNames from 'classnames';

const prefixCls = 'h-list-item';

const ListItem: React.FC<IListItemPropsType> = props => {
const { arrow, extra, thumb, subtitle, children, onPress } = props;

const createThumb = (thumb: IListItemPropsType['thumb']) => {
if (!thumb) return null;
if (typeof thumb === 'string') {
return (
<div className={`${prefixCls}-thumb`}>
<img src={thumb} alt="" />
</div>
);
} else {
return <div className={`${prefixCls}-thumb`}>{thumb}</div>;
}
};

const [active, setActive] = useState<boolean>(false);

const innerCls = classNames(prefixCls, {
[`${prefixCls}-active`]: active && arrow !== 'none',
});

return (
<Touchable
onPressIn={() => {
setActive(true);
}}
onPress={onPress}
onPressOut={() => {
setActive(false);
}}
>
<div className={innerCls}>
<div className={`${prefixCls}-line`}>
{createThumb(thumb)}
<div className={`${prefixCls}-wrap`}>
<div className={`${prefixCls}-title`}>{children}</div>
{subtitle ? (
<div className={`${prefixCls}-subtitle`}>{subtitle}</div>
) : null}
</div>
{extra ? <div className={`${prefixCls}-extra`}>{extra}</div> : null}
{arrow !== 'none' ? (
<div className={`${prefixCls}-arrow`}>
<Icon
type={`arrow-${arrow === 'horizontal' ? 'right' : arrow}`}
/>
</div>
) : null}
</div>
</div>
</Touchable>
);
};

ListItem.defaultProps = {
subtitle: '',
extra: '',
showAll: false,
arrow: 'none',
};

export default ListItem;
75 changes: 75 additions & 0 deletions src/List/PropsType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { ReactElement, SyntheticEvent } from 'react';

type renderType = string | ReactElement;
type listRenderFn = () => renderType;
type listRender = listRenderFn | renderType;
type listItemArrowType = 'up' | 'down' | 'horizontal' | 'none';

/**
* List properties
*/
export interface IListPropsType {
/**
* @description 是否设置列表圆角
* @default false
*/
radius?: boolean;
/**
* @description 列表头部内容
* @default ""
* @type string | ReactElement | () => void | string | ReactElement
*/
renderHeader?: listRender;
/**
* @description 列表尾部内容
* @default ""
* @type string | ReactElement | () => void | string | ReactElement
*/
renderFooter?: listRender;
}

/**
* ListItem properties
*/
export interface IListItemPropsType {
/**
* @description 列表副标题 此属性会在原本列表信息下方以多行的形式展示
* @default ""
* @type string | React.ReactElement
*/
subtitle?: renderType;
/**
* @description 列表额外内容
* @default ""
* @type string | React.ReactElement
*/
extra?: renderType;
/**
* @description 列表额外内容是否换行显示全部内容
* @default false
*/
showAll?: boolean;
/**
* @description 列表尾端箭头方向 设置none时不显示
* @default "none"
* @type "up" | "down" | "horizontal" | "none"
*/
arrow?: listItemArrowType;
/**
* @description 缩略图 当传入字符串时需要
* @default ""
* @type string | React.ReactElement
*/
thumb?: renderType;
/**
* @description 列表项点触事件
* @default null
*/
onPress?: (e: SyntheticEvent) => void;
}

const List = (props: IListPropsType) => {};

const ListItem = (props: IListItemPropsType) => {};

export { List, ListItem };
64 changes: 64 additions & 0 deletions src/List/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: List
nav:
title: 组件
path: /components
---

## 基础使用

### type

通过 type 属性切换 Button 组件样式

```tsx
import React from 'react';
import { List } from 'hugSun-UI';

const { Item } = List;

export default () => {
return (
<>
<List renderHeader={() => 'Basic Type'}>
<Item>Title</Item>
<Item arrow="horizontal">Title</Item>
<Item extra="extra content" arrow="horizontal">
Title
</Item>
<Item
thumb={require('../../public/images/logo.png')}
arrow="horizontal"
>
Title
</Item>
</List>

<List renderHeader={() => 'Subtitle'}>
<Item subtitle="subtitle" arrow="horizontal">
Title
</Item>
<Item
thumb={require('../../public/images/logo.png')}
subtitle="subtitle"
arrow="horizontal"
>
Title
</Item>
<Item
thumb={require('../../public/images/logo.png')}
subtitle="subtitle"
extra="extra content"
arrow="horizontal"
>
Title
</Item>
</List>
</>
);
};
```

## API

<API src="./PropsType.ts" exports='["List", "ListItem"]'></API>
64 changes: 64 additions & 0 deletions src/List/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.h-list {
.h-list-header {
padding: 30 * $rpx;
color: #888;
font-size: 32 * $rpx;
}
.h-list-item {
min-height: 88 * $rpx;
padding: 0 30 * $rpx;
background-color: #fff;
transition: background-color .2s;
&.h-list-item-active {
background-color: #ddd;
}
.h-list-item-line {
min-height: 88 * $rpx;
border-bottom: 1px solid #ddd;
padding: 14 * $rpx 0;
display: flex;
align-items: center;
vertical-align: middle;
overflow: hidden;
}
.h-list-item-thumb {
line-height: 0;
img {
width: 44 * $rpx;
height: 44 * $rpx;
vertical-align: middle;
}
& + .h-list-item-wrap {
margin-left: 20 * $rpx;
}
}
.h-list-item-wrap {
font-size: 34 * $rpx;
flex-grow: 1;
.h-list-item-title {
line-height: 1.5;
}
.h-list-item-subtitle {
color: #888;
font-size: 30 * $rpx;
}
}
.h-list-item-extra {
font-size: 32 * $rpx;
width: auto;
color: #888;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: right;
flex-basis: 36%;
}
.h-list-item-arrow {
color: #ccc;
font-size: 50 * $rpx;
}
}
.h-list-item:nth-last-child(1) .h-list-item-line {
border: none;
}
}
36 changes: 36 additions & 0 deletions src/List/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { IListPropsType } from './PropsType';
import ListItem from '@/List/ListItem';
import './index.scss';

const prefixCls = 'h-list';

const List: React.FC<IListPropsType> & { Item: typeof ListItem } = props => {
const { renderHeader, renderFooter } = props;
return (
<div className={prefixCls}>
<div className={`${prefixCls}-wrap`}>
{renderHeader && (
<div className={`${prefixCls}-header`}>
{typeof renderHeader === 'function' ? renderHeader() : renderHeader}
</div>
)}
{props.children}
{renderFooter && (
<div className={`${prefixCls}-footer`}>
{typeof renderFooter === 'function' ? renderFooter() : renderFooter}
</div>
)}
</div>
</div>
);
};

List.Item = ListItem;
List.defaultProps = {
radius: false,
renderHeader: '',
renderFooter: '',
};

export default List;
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as Button } from './Button';
export { default as List } from './List';
export { default as Icon } from './Icon';