-
Notifications
You must be signed in to change notification settings - Fork 753
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(image-picker): 新增 image-picker 组件
- Loading branch information
Showing
9 changed files
with
484 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
src/components/image-picker/__snapshots__/index.test.js.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`AtImagePicker Snap render AtImagePicker -- props className 1`] = `"<div class=\\"at-image-picker test\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; | ||
exports[`AtImagePicker Snap render AtImagePicker -- props customStyle 1`] = `"<div style=\\"color: red\\" class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; | ||
exports[`AtImagePicker Snap render AtImagePicker -- props files 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; | ||
exports[`AtImagePicker Snap render AtImagePicker -- props length 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; | ||
exports[`AtImagePicker Snap render AtImagePicker -- props mode 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; | ||
exports[`AtImagePicker Snap render AtImagePicker -- props multiple 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"multiple\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; | ||
exports[`AtImagePicker Snap render AtImagePicker -- props showAddBtn 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; | ||
exports[`AtImagePicker Snap render initial AtImagePicker 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
/* eslint-disable no-nested-ternary */ | ||
import Taro from '@tarojs/taro' | ||
import { View, Input, Image } from '@tarojs/components' | ||
import PropTypes from 'prop-types' | ||
import classNames from 'classnames' | ||
|
||
import AtComponent from '../../common/component' | ||
import AtIcon from '../../components/icon/index' | ||
import './index.scss' | ||
|
||
// 生成 jsx 二维矩阵 | ||
const generateMatrix = (files, col, showAddBtn) => { | ||
const matrix = [] | ||
const length = showAddBtn ? files.length + 1 : files.length | ||
const row = Math.ceil(length / col) | ||
for (let i = 0; i < row; i++) { | ||
if (i === row - 1) { | ||
// 最后一行数据加上添加按钮 | ||
const lastArr = files.slice(i * col) | ||
if (lastArr.length < col) { | ||
if (showAddBtn) { | ||
lastArr.push({ type: 'btn' }) | ||
} | ||
// 填补剩下的空列 | ||
for (let j = lastArr.length; j < col; j++) { | ||
lastArr.push({ type: 'blank' }) | ||
} | ||
} | ||
matrix.push(lastArr) | ||
} else { | ||
matrix.push(files.slice(i * col, (i + 1) * col)) | ||
} | ||
} | ||
return matrix | ||
} | ||
|
||
const defaultFunc = () => {} | ||
|
||
export default class AtImagePicker extends AtComponent { | ||
static defaultProps = { | ||
className: '', | ||
customStyle: '', | ||
files: [], | ||
mode: 'scaleToFill', | ||
showAddBtn: true, | ||
multiple: false, | ||
length: 4, | ||
onChange: defaultFunc, | ||
onImageClick: defaultFunc, | ||
onFail: defaultFunc | ||
} | ||
|
||
static propTypes = { | ||
className: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.array | ||
]), | ||
customStyle: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.object | ||
]), | ||
files: PropTypes.array, | ||
showAddBtn: PropTypes.number, | ||
multiple: PropTypes.bool, | ||
length: PropTypes.number, | ||
onChange: PropTypes.func, | ||
onImageClick: PropTypes.func, | ||
onFail: PropTypes.func | ||
} | ||
|
||
chooseFile () { | ||
const { onChange, files, onFail, multiple } = this.props | ||
const env = Taro.getEnv() | ||
if (env === Taro.ENV_TYPE.WEB) { | ||
this.fileInput.vnode.dom.click() | ||
} else if (env === Taro.ENV_TYPE.WEAPP) { | ||
// 微信小程序图片选择逻辑 | ||
Taro.chooseImage({ | ||
count: multiple ? 99 : 1 | ||
}).then(res => { | ||
const targetFiles = res.tempFilePaths.map((path, i) => ( | ||
{ | ||
url: path, | ||
file: res.tempFiles[i] | ||
} | ||
)) | ||
onChange(files.concat(targetFiles), 'add') | ||
}).catch(onFail) | ||
} | ||
} | ||
|
||
handleImgChoose (event) { | ||
// h5 图片监听逻辑 | ||
const { onChange, files, onFail } = this.props | ||
const targetFiles = event.target.files | ||
if (targetFiles) { | ||
for (let i = 0; i < targetFiles.length; i++) { | ||
const reader = new FileReader() | ||
reader.onload = function (e) { | ||
if (!e.target.result) { | ||
onFail(`Fail to get the ${i} image`) | ||
} | ||
files.push({ url: e.target.result, file: targetFiles[i] }) | ||
onChange(files, 'add') | ||
} | ||
reader.readAsDataURL(targetFiles[i]) | ||
} | ||
} | ||
} | ||
|
||
handleImageClick (i) { | ||
const { onImageClick, files } = this.props | ||
onImageClick(i, files[i]) | ||
} | ||
|
||
handleRemoveImg (i) { | ||
const { onChange, files } = this.props | ||
files.splice(i, 1) | ||
onChange(files, 'remove', i) | ||
} | ||
|
||
refFileInput = node => { | ||
this.fileInput = node | ||
} | ||
|
||
render () { | ||
const { | ||
className, | ||
customStyle, | ||
files, | ||
mode, | ||
multiple, | ||
length, | ||
showAddBtn | ||
} = this.props | ||
// 行数 | ||
const matrix = generateMatrix(files, length, showAddBtn) | ||
|
||
return ( | ||
<View | ||
className={ | ||
classNames('at-image-picker', className) | ||
} | ||
style={customStyle} | ||
> | ||
{ | ||
matrix.map((row, i) => ( | ||
<View | ||
key={i} | ||
className='at-image-picker__flex-box' | ||
> | ||
{ | ||
row.map((item, j) => ( | ||
item.url | ||
? <View | ||
className='at-image-picker__flex-item' | ||
key={item} | ||
> | ||
<View className='at-image-picker__item'> | ||
<View | ||
className='at-image-picker__remove-btn' | ||
onClick={this.handleRemoveImg.bind(this, (i * length) + j)} | ||
> | ||
<AtIcon value='close' size='14' color='#fff' /> | ||
</View> | ||
<Image | ||
mode={mode} | ||
onClick={this.handleImageClick.bind(this, (i * length) + j)} | ||
className='at-image-picker__preview-img' | ||
src={item.url} | ||
/> | ||
</View> | ||
</View> | ||
: item.type === 'blank' | ||
? <View | ||
className='at-image-picker__flex-item' | ||
key={item} | ||
> | ||
</View> | ||
: <View | ||
className='at-image-picker__flex-item' | ||
onClick={this.chooseFile.bind(this)} | ||
> | ||
<View className='at-image-picker__item at-image-picker__choose-btn'> | ||
<AtIcon value='add' size='30' /> | ||
<Input | ||
className='at-image-picker__file-input' | ||
ref={this.refFileInput} | ||
type='file' | ||
accept='image/*' | ||
multiple={multiple ? 'multiple' : ''} | ||
onChange={this.handleImgChoose.bind(this)} | ||
/> | ||
</View> | ||
</View> | ||
)) | ||
} | ||
</View> | ||
)) | ||
} | ||
</View> | ||
) | ||
} | ||
} |
Oops, something went wrong.