使用 React hooks Typescript 开发的一个 H5 移动端 组件库
其中包括了下图中的27个基础组件:
CP Design Mobile
(github地址:https://github.com/10086XIAOZHANG/CP-DESIGN)
特性
- 基于 CP Design 移动设计规范。
- 规则化的视觉样式配置,适应各类产品风格。
- 使用 TypeScript React hooks 开发,提供类型定义文件。
???? 环境支持
- Modern browsers and Internet Explorer 11+ (with polyfills)
- Server-side Rendering
- Electron
| 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>
</>
)
组件
-
Icon,
-
Button,
-
Input,
-
Row,
-
Col,
-
Affix,
-
Avatar,
-
Badge,
-
Card,
-
CheckboxGroup,
-
Checkbox,
-
Accordion,
-
Divider,
-
Modal,
-
Overlay,
-
Pagination,
-
Progress,
-
Radio,
-
Slider,
-
Step,
-
Spin,
-
Switch,
-
Tabs,
-
Tag,
-
ImagePicker,
-
Toast,
-
ActionSheet,
-
TabBar,
-
PickerPanel,
-
Picker,
-
SegmentedControl,
-
Popover,
-
NoticeBar,
-
SwipeAction
-
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
安装与使用
介绍
浏览器支持
链接
欢迎贡献
有任何建议或意见您可以进行 提问。
作者????Email
[email protected]
|
请发表评论