CP Design
使用 React hooks Typescript 开发的一个 H5 移动端 组件库
其中包括了下图中的27个基础组件:
CP Design Mobile
(github地址:https://github.com/10086XIAOZHANG/CP-DESIGN)
特性
- 基于 CP Design 移动设计规范。
- 规则化的视觉样式配置,适应各类产品风格。
- 使用 TypeScript React hooks 开发,提供类型定义文件。
?? 环境支持
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
?? 安装
npm install cp-design --save
yarn add cp-design
? 注意
在组件库中使用了 SASS,在安装的时候记得安装 node-sass
npm install node-sass --save-dev
yarn add node-sass -D
?? 使用
import { Button } from ‘cp-design‘
const App = () => (
<>
<Button type="primary">PRESS ME</Button>
</>
)
组件
- [x] Icon,
- [x] Button,
- [x] Input,
- [x] Row,
- [x] Col,
- [x] Affix,
- [x] Avatar,
- [x] Badge,
- [x] Card,
- [x] CheckboxGroup,
- [x] Checkbox,
- [x] Accordion,
- [x] Divider,
- [x] Modal,
- [x] Overlay,
- [x] Pagination,
- [x] Progress,
- [x] Radio,
- [x] Slider,
- [x] Step,
- [x] Spin,
- [x] Switch,
- [x] Tabs,
- [x] Tag,
- [x] ImagePicker,
- [x] Toast,
- [x] ActionSheet,
- [x] TabBar,
- [x] PickerPanel,
- [x] Picker,
- [x] SegmentedControl,
- [x] Popover,
- [x] NoticeBar,
- [x] SwipeAction
- [x] ListView
部分组件使用
Button 按钮
按钮的展示
引入组件
import * as React from ‘react‘
import { Button, Row, Col } from ‘cp-design‘
Demo 代码
export default function ButtonDemo() {
const onClick = () => {}
return (
<div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button onClick={onClick}>default</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button disabled>default disabled</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button type="primary" onClick={onClick}>
primary
</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button type="primary" onClick={onClick} disabled>
primary disabled
</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button onClick={onClick} type="warning">
warning
</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button onClick={onClick} type="warning" disabled>
warning disabled
</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button onClick={onClick} loading>
loading button
</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button>with icon</Button>
</Col>
</Row>
</div>
)
}
Badge 徽标数
徽标数的展示
引入组件
import * as React from ‘react‘
import { Badge, Row, Col } from ‘cp-design‘
Demo 代码
export default function BadgeDemo() {
return (
<div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Badge dot status="default">
<span
style={{ width: ‘26px‘, height: ‘26px‘, background: ‘#ddd‘, display: ‘inline-block‘ }}
/>
</Badge>
<span
style={{
marginLeft: 12,
height: ‘26px‘,
lineHeight: ‘26px‘,
display: ‘inline-block‘,
verticalAlign: ‘top‘
}}
>
Dot badge
</span>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Badge dot status="success">
<span
style={{ width: ‘26px‘, height: ‘26px‘, background: ‘#ddd‘, display: ‘inline-block‘ }}
/>
</Badge>
<span
style={{
marginLeft: 12,
height: ‘26px‘,
lineHeight: ‘26px‘,
display: ‘inline-block‘,
verticalAlign: ‘top‘
}}
>
Dot badge Success
</span>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Badge text={‘券1‘} overflowCount={121}></Badge>
<Badge
text={‘NEW‘}
overflowCount={121}
style={{
marginLeft: 12,
padding: ‘0 3px‘,
backgroundColor: ‘#21b68a‘,
borderRadius: 2
}}
></Badge>
<Badge
text="自动缴费"
style={{
marginLeft: 12,
padding: ‘0 3px‘,
backgroundColor: ‘#fff‘,
borderRadius: 2,
color: ‘#f19736‘,
border: ‘1px solid #f19736‘
}}
/>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col
span={24}
style={{
border: ‘1px solid #999‘,
height: 42,
overflow: ‘hidden‘
}}
>
<Badge corner text={‘促‘} outStyle={{ height: 42, lineHeight: ‘42px‘ }}>
<span
style={{
marginLeft: 12,
display: ‘inline-block‘
}}
>
Dot badge Success
</span>
</Badge>
</Col>
</Row>
</div>
)
}
属性 | 说明 | 类型 | 默认值 | 可选 |
---|---|---|---|---|
text | 展示的数字或文案,当为数字时候,大于 overflowCount 时显示为 ${overflowCount}+,为 0 时隐藏 | string | -- | -- |
corner | 置于角落 | boolean | -- | -- |
disabled | 设置禁用 | boolean | -- | -- |
dot | 不展示数字,只有一个小红点 | string/React.Element | -- | -- |
overflowCount | 展示封顶的数字值 | number | -- | -- |
status | status 状态点 这个值对 dot 生效 | ‘success‘, ‘default‘ , ‘process‘ , ‘warning‘ , ‘error‘ | -- | -- |
style | 自定义样式(样式) | Object | -- | -- |
outStyle | 外围自定义样式(样式) | Object | -- | -- |
hot | 营销样式 | boolean | -- | -- |
Api
属性 | 说明 | 类型 | 默认值 | 可选 |
---|---|---|---|---|
type | 按钮类型,可选值为 primary/ghost/warning 或者不设 | string | -- | -- |
size | 按钮大小,可选值为 large、small | string | large | -- |
disabled | 设置禁用 | boolean | -- | -- |
icon | 可以是 Icon 组件里内置的某个 icon 的 type 值,也可以是任意合法的 ReactElement (注意: loading 设置后此项设置失效) | string/React.Element | -- | -- |
prefixCls | class 前缀 默认 cp-ui-btn | string | -- | -- |
className | 样式类名 | fun():void | -- | -- |
onClick | 点击按钮的点击回调函数 | fun() : void | -- | -- |
style | 自定义样式 | Object | -- | -- |
loading | 是否出现正在加载 | boolean | -- | -- |
Icon 图标
图标的展示
引入组件
import * as React from ‘react‘
import { Icon, Row, Col } from ‘cp-design‘
Demo 代码
export default function IconDemo() {
const list = [
‘check-circle‘,
‘check‘,
‘caret-up‘,
‘delete‘,
‘eye-close‘,
‘eye‘,
‘up‘,
‘down‘,
‘left‘,
‘right‘,
‘message-fill‘,
‘link‘
]
const data = list.map(item => ({
icon: <Icon type={item} />,
text: item
}))
return (
<div>
<h3>基本</h3>
{data.map((item, index) => {
if (index !== 0 && (index + 1) % 3 === 0) {
return (
<Row style={{ marginBottom: ‘1rem‘, textAlign: ‘center‘ }} key={index}>
<Col span={8}>
{data[index - 2].icon}
<p>{data[index - 2].text}</p>
</Col>
<Col span={8}>
{data[index - 1].icon}
<p>{data[index - 1].text}</p>
</Col>
<Col span={8}>
{item.icon}
<p>{data[index].text}</p>
</Col>
</Row>
)
}
return null
})}
<h3>大小</h3>
<Row style={{ marginBottom: ‘1rem‘, textAlign: ‘center‘ }}>
<Col span={8}>
<Icon type={‘camera-retro‘} size={8} />
</Col>
<Col span={8}>
<Icon type={‘camera-retro‘} size={16} />
</Col>
<Col span={8}>
<Icon type={‘camera-retro‘} size={24} />
</Col>
<Col span={8}>
<Icon type={‘camera-retro‘} size={32} />
</Col>
</Row>
<h3>颜色</h3>
<Row style={{ marginBottom: ‘1rem‘, textAlign: ‘center‘ }}>
<Col span={8}>
<Icon type={‘camera-retro‘} color="rgb(44, 167, 241)" />
</Col>
<Col span={8}>
<Icon type={‘camera-retro‘} color="rgb(234, 32, 152)" />
</Col>
<Col span={8}>
<Icon type={‘camera-retro‘} color="rgb(21, 239, 218)" />
</Col>
<Col span={8}>
<Icon type={‘camera-retro‘} color="rgb(95, 25, 220)" />
</Col>
</Row>
</div>
)
}
Api
属性 | 说明 | 类型 | 默认值 | 可选 |
---|---|---|---|---|
type | 内置 icon 名称 | string | -- | -- |
size | 图标大小 | string,number | -- | -- |
color | 图标颜色 | Color | ‘#000‘ | -- |
rotate | 是否旋转 | boolean | -- | -- |
rotateDegree | 和 rotate 一起配置生效 | 0 ,90 ,180, 270 , 360 | -- | -- |
flip | 是否翻转 | boolean | -- | -- |
flipOrder | 和 flip 一起配置生效 | ‘horizontal‘ , ‘vertical‘ | -- | -- |
Modal 弹窗
弹窗的展示
引入组件
import * as React from ‘react‘
import { Modal, Button, Row, Col } from ‘cp-design‘
Demo 代码
const { useState } = React
export default function ModalDemo() {
const [modal1, setModal1] = useState(false)
const [modal2, setModal2] = useState(false)
const showModal1 = (e: React.MouseEvent) => {
e.preventDefault()
setModal1(true)
}
const showModal2 = (e: React.MouseEvent) => {
e.preventDefault()
setModal2(true)
}
return (
<div>
<Modal
visible={modal1}
title="Title1"
closable={false}
cancelText={null}
onOk={() => {
setModal1(false)
}}
>
<div style={{ height: 100, overflowY: ‘scroll‘ }}>
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
</div>
</Modal>
<Modal
visible={modal2}
title="Title2"
closable={false}
onCancel={() => {
setModal2(false)
}}
onOk={() => {
alert(‘afterOK‘)
setModal2(false)
}}
>
<div style={{ height: 100, overflowY: ‘scroll‘ }}>
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
scoll content...
<br />
</div>
</Modal>
<h1>Modal 对话框</h1>
<h3>基本</h3>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button onClick={showModal1}>basic</Button>
</Col>
</Row>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Button onClick={showModal2}>confirm</Button>
</Col>
</Row>
</div>
)
}
Api
属性 | 说明 | 类型 | 默认值 | 可选 |
---|---|---|---|---|
cancelText | 取消按钮自定义 | React.ReactNode,string | -- | -- |
okText | 确定按钮自定义 | React.ReactNode,string | large | -- |
visible | 是否可见 | boolean | -- | -- |
title | Modal 弹窗标题 | string/React.Element | -- | -- |
children | Modal 自定义内容区域 | string/React.Element | -- | -- |
prefixCls | class 前缀 默认 cp-ui-modal | string | -- | -- |
className | 样式类名 | fun():void | -- | -- |
maskClassName | 弹出层样式类名 | fun():void | -- | -- |
onOk | 点击确定回调函数 | fun() : void | -- | -- |
onCancel | 点击取消回调函数 | fun() : void | -- | -- |
style | 自定义样式 | Object | -- | -- |
maskClosable | 点击浮层是否允许关闭 | boolean | true | -- |
closable | 是否显示右上角关闭图标 | boolean | true | -- |
closeIcon | 自定义右上角关闭图标 | React.ReactNode | -- | -- |
destroy | 是否销毁(关闭后自动销毁) | boolean | true | -- |
maskAnimationName | 弹出层动画类名 | string | fade | -- |
说明
icon 图标遵循fontawesome规则
Input 输入框
输入框的展示
引入组件
import * as React from ‘react‘
import { useForm, Controller } from ‘react-hook-form‘
import { Input, Button, Icon, Row, Col } from ‘cp-design‘
Demo 代码
const { useRef } = React
export default function ButtonDemo() {
const inputRef = (useRef < HTMLInputElement) | (null > null)
const { handleSubmit, control, errors } = useForm() // initialise the hook
const onSubmit = (data: any) => {
console.log(data)
}
const getInputRef = (ele: HTMLInputElement) => {
inputRef.current = ele
}
const handleFocus = (e: React.MouseEvent) => {
e.preventDefault()
if (!!inputRef.current) inputRef.current.focus()
}
const btnStyle = {
background: ‘linear-gradient(316deg, #f75cff 0%, rgb(236, 9, 51) 100%)‘,
opacity: 0.5,
display: ‘block‘,
margin: ‘0 auto‘,
height: ‘2.8rem‘,
borderRadius: ‘0.6rem‘,
textAlign: ‘center‘,
lineHeight: ‘2.8rem‘,
fontSize: ‘0.88rem‘,
color: ‘#fff‘
}
return (
<div>
<h1>Input 输入框</h1>
<h3>基本</h3>
<form onSubmit={handleSubmit(onSubmit)}>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>标题</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
placeholder="auto focus"
style={{ height: ‘2.5rem‘ }}
error={errors.title0 && <span style={{ color: ‘red‘ }}>This is required.</span>}
/>
}
name="title0"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>标题</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
addonBefore={
<div
style={{
width: ‘100%‘,
color: ‘rgb(16, 142, 233)‘,
textAlign: ‘center‘,
float: ‘right‘,
height: ‘2.33rem‘
}}
onClick={handleFocus}
>
click to focus
</div>
}
getInputRef={getInputRef}
placeholder="auto focus"
style={{ height: ‘2.5rem‘ }}
error={
errors.title1 && (
<span style={{ color: ‘red‘, paddingLeft: ‘8rem‘ }}>This is required.</span>
)
}
/>
}
name="title1"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>自定义前缀</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
prefix={<Icon type={‘user‘} style={{ lineHeight: ‘2.5rem‘ }} />}
placeholder="auto focus"
style={{ height: ‘2.5rem‘ }}
error={
errors.title2 && (
<span style={{ color: ‘red‘, paddingLeft: ‘1rem‘ }}>This is required.</span>
)
}
/>
}
name="title2"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>自定义内部前缀</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
inlinePrefix={<Icon type={‘user‘} style={{ lineHeight: ‘2.5rem‘ }} />}
placeholder="auto focus"
style={{ height: ‘2.5rem‘ }}
error={
errors.title3 && (
<span style={{ color: ‘red‘, paddingLeft: ‘1.4rem‘ }}>This is required.</span>
)
}
/>
}
name="title3"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>价格</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
inlineSuffix={<Icon type={‘cny‘} style={{ lineHeight: ‘2.5rem‘ }} />}
placeholder="0.00"
style={{ height: ‘2.5rem‘ }}
error={
errors.title4 && (
<span style={{ color: ‘red‘, paddingLeft: ‘1.4rem‘ }}>This is required.</span>
)
}
/>
}
name="title4"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<h3>Format</h3>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>银行卡</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
type="bankCard"
placeholder="请输入银行卡"
style={{ height: ‘2.5rem‘ }}
error={errors.bankCard && <span style={{ color: ‘red‘ }}>This is required.</span>}
/>
}
name="bankCard"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>手机号码</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
type="mobile"
placeholder="请输入手机号码"
style={{ height: ‘2.5rem‘ }}
error={errors.mobile && <span style={{ color: ‘red‘ }}>This is required.</span>}
/>
}
name="mobile"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>密码</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
type="password"
placeholder="请输入密码"
style={{ height: ‘2.5rem‘ }}
error={errors.password && <span style={{ color: ‘red‘ }}>This is required.</span>}
/>
}
name="password"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<div style={{ color: ‘#777575‘, marginBottom: ‘0.01rem‘ }}>数字键盘</div>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={
<Input
clear
type="number"
placeholder="数字键盘"
style={{ height: ‘2.5rem‘ }}
error={errors.number && <span style={{ color: ‘red‘ }}>This is required.</span>}
/>
}
name="number"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<h3>禁用</h3>
<Row style={{ marginBottom: ‘1rem‘ }}>
<Col span={24}>
<Controller
as={<Input clear disabled placeholder="不能输入" style={{ height: ‘2.5rem‘ }} />}
name="number"
control={control}
rules={{ required: true }}
/>
</Col>
</Row>
<Row justify={‘center‘}>
<Col span={18}>
<Button htmlType="submit" onClick={handleSubmit(onSubmit)} style={btnStyle}>
Submit
</Button>
</Col>
</Row>
</form>
</div>
)
}
Api
属性 | 说明 | 类型 | 默认值 | 可选 |
---|---|---|---|---|
type | 可以是银行卡 bankCard; 手机号 phone(此时最大长度固定为 11,maxLength 设置无效); 密码 password;类型:InputType | string | "text" | -- |
addonBefore | 前置点击 | React.ReactNode | -- | -- |
addonAfter | 后置点击 | React.ReactNode | -- | -- |
error | 错误提示 | string/React.Element | -- | -- |
clear | 是否显示清除 | boolean | false | -- |
className | 样式类名 | fun():void | -- | -- |
getInputRef | 获取元素组件的 ref | (ele: HTMLInputElement) => void | -- | -- |
style | 自定义样式 | Object | -- | -- |
disabled | 是否禁用 | boolean | -- | -- |
inlinePrefix | 内嵌 input 前缀 | React.ReactNode | -- | -- |
inlineSuffix | 内嵌 input 前缀 | React.ReactNode | -- | -- |
prefix | input 外前缀 | React.ReactNode | -- | -- |
suffix | input 外后缀 | React.ReactNode | -- | -- |
prefix | input 外前缀 | string | -- | -- |
value | value 值(受控与否参考 react-hook-form) | string | -- | -- |
defaultValue | 默认 value 值(受控与否参考 react-hook-form) | string | -- | -- |
InputType
(‘text‘ ,‘number‘ , ‘mobile‘ ,‘bankCard‘ , ‘password‘)
案例
mobile web demo
https://10086xiaozhang.github.io/CP-DESIGN
安装与使用
浏览器支持
iOS
Android 4.0+
链接
欢迎贡献
有任何建议或意见您可以进行 提问。
作者??Email
fcj_zhang@163.com