提交 9eaf2ce0 编写于 作者: O oasis-cloud

# Conflicts:

#	.gitignore
#	src/packages/inputnumber/doc.md
#	src/packages/inputnumber/inputnumber.tsx
上级 b97bca14
name: sync to docs
# name: sync to docs
on:
push:
branches:
- main
paths:
- '.github/workflows/**'
- 'src/**'
- 'package.json'
# on:
# push:
# branches:
# - main
# paths:
# - '.github/workflows/**'
# - 'src/**'
# - 'package.json'
jobs:
copy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm i fs-extra --force
- run: node scripts/copy-docs.js
- name : Sync
uses : JamesIves/github-pages-deploy-action@4.1.7
with :
branch : master # action 应该部署到的分支 。
folder : site_docs #操作应该部署的文件夹 。
clean: false
repository-name: jdf2e/nutui-docs
token: ${{ secrets.GIT_ACTION }}
target-folder: src/docs_react
# jobs:
# copy:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - run: npm i fs-extra --force
# - run: node scripts/copy-docs.js
# - name : Sync
# uses : JamesIves/github-pages-deploy-action@4.1.7
# with :
# branch : master # action 应该部署到的分支 。
# folder : site_docs #操作应该部署的文件夹 。
# clean: false
# repository-name: jdf2e/nutui-docs
# token: ${{ secrets.GIT_ACTION }}
# target-folder: src/docs_react
# v1.4.13
`2023-03-29`
* :bug: fix(dialog): 修复Dialog.confirm弹框关闭后dom没有移除问题 (#851) @拧巴的猫
* :bug: fix(Elevator): 组件瘦身+taro h5适配 (#858) @拧巴的猫
* :bug: fix(picker): 修复taro版本滚动报错问题 (#852) @拧巴的猫
* :bug: fix(range): 修复 a11y 属性并补全组件的单元测试 (#849) @AnteeHub
* :bug: fix: taro-v3.6.12 complier @junjun666
* :bug: fix: 修复input 的errorMessage显隐导致input失焦问题 (#827) @Penguin-Lin
* 📖 docs: imagepreview 组件增加点击缩略图切换示例 (#854) @oasis-cloud
# v1.4.12
`2023-03-22`
* :sparkles: feat: 文档Demo示例touch兼容 (#830) @Song
* :bug: fix(calendar): 修复自定义 title 失效问题 (#839) @eiinu
* :bug: fix: ellipsis 组件动态设置内容无效问题 (#823) @刘正午
* :bug: fix: picker 组件在小程序端触发滚动后,页面(有滚动条的情况下)也一起滚动 (#829) @xianyu
* :bug: fix: tag 组件动态切换 className 不生效 (#820) @刘正午
* :bug: fix: 修复 button 组件的样式通过最外层标签设置 (#840) @oasis-cloud
* :bug: fix: 修复 calendar 组件中当 defaultValue 为空时,如果月份列表包含当月,则默认定位到当月 (#813) @刘正午
* :bug: fix: 修改 input 文档示例代码change 改为 onChange (#832) @Song
* :bug: fix: 修复cell文案左右相互挤压和长字符不换行的问题 (#836) @junjun666
* :bug: fix: 添加项目依赖 #802 (#816) @eiinu
* :bug: fix: 修复下拉刷新报错 #761 (#817) @eiinu
* :bug: fix:Form提交数据中缺少默认选中的radio值 (#834) @junjun666
* 🔨 chore: 移除 node engines (#843) @oasis-cloud
* 📖 docs: 更新 README.md (#838) @AnteeHub
# v1.4.11
`2023-03-15`
......
{
"name": "@nutui/nutui-react-taro",
"version": "1.4.11",
"version": "1.4.13",
"style": "dist/style.css",
"main": "dist/nutui.react.umd.js",
"module": "dist/esm/nutui-react.es.js",
......
import React, { FunctionComponent, useState, useEffect, useRef } from 'react'
import Picker from '@/packages/picker/index.taro'
import { useConfig } from '@/packages/configprovider'
import { View } from '@tarojs/components'
export interface PickerOption {
text: string | number
......@@ -398,10 +399,11 @@ export const DatePicker: FunctionComponent<
}, [currentDate])
return (
<div
<View
className={`nut-datepicker ${className || ''}`}
style={style}
{...rest}
{...(rest as any)}
catchMove
>
{listData.length > 0 && (
<Picker
......@@ -422,7 +424,7 @@ export const DatePicker: FunctionComponent<
ref={pickerRef}
/>
)}
</div>
</View>
)
}
......
import React from 'react'
import ReactDOM from 'react-dom'
import { Dialog } from './dialog'
import { destroyList, ConfirmProps } from './config'
import { render as reactRender } from '@/utils/render'
import { render as reactRender, unmount } from '@/utils/render'
function ConfirmDialog(props: ConfirmProps) {
return <Dialog {...props}>{props.content}</Dialog>
......@@ -32,9 +32,9 @@ function confirm(
) {
const div = document.createElement('div')
document.body.appendChild(div)
function render(props: ConfirmProps) {
function render(props: ConfirmProps, callback?: () => any) {
reactRender(<ConfirmDialog {...props} onCancel={onCancel} />, div)
callback && callback()
}
const renderFunction = renderFunc || render
......@@ -73,8 +73,8 @@ function confirm(
renderFunction(dialogConfig)
function destroy() {
const unmountEle = ReactDOM.unmountComponentAtNode(div)
if (unmountEle && div.parentNode) {
unmount(div)
if (div?.parentNode) {
div.parentNode.removeChild(div)
}
for (let i = 0; i < destroyList.length; i++) {
......@@ -91,9 +91,10 @@ function confirm(
dialogConfig.visible = false
dialogConfig.onClosed = () => {
config.onClosed && config.onClosed()
destroy()
}
renderFunction(dialogConfig)
renderFunction(dialogConfig, () => {
destroy()
})
}
function update(newConfig: ConfirmProps) {
......
......@@ -65,14 +65,12 @@ export const Elevator: FunctionComponent<
listHeight: [] as number[],
listGroup: [] as any[],
scrollY: 0,
diff: -1,
fixedTop: 0,
}
const touchState = useRef({
y1: 0,
y2: 0,
})
const [scrollY, setScrollY] = useState(0)
const [currentData, setCurrentData] = useState<ElevatorData>(
{} as ElevatorData
)
......@@ -196,13 +194,12 @@ export const Elevator: FunctionComponent<
const target = e.target as Element
const { scrollTop } = target
state.current.scrollY = Math.floor(scrollTop)
setScrollY(scrollTop)
setScrollTop(scrollTop)
for (let i = 0; i < listHeight.length - 1; i++) {
const height1 = listHeight[i]
const height2 = listHeight[i + 1]
if (state.current.scrollY >= height1 && state.current.scrollY < height2) {
setCurrentIndex(i)
state.current.diff = height2 - state.current.scrollY
return
}
}
......@@ -218,20 +215,9 @@ export const Elevator: FunctionComponent<
}
}, [listview])
useEffect(() => {
const { listHeight, diff, scrollY } = state.current
let fixedTop = diff > 0 && diff < titleHeight ? diff - titleHeight : 0
if (scrollY + clientHeight() === listHeight[listHeight.length - 1]) {
if (fixedTop !== 0) {
fixedTop = 0
}
}
if (state.current.fixedTop === fixedTop) return
state.current.fixedTop = fixedTop
}, [state.current.diff, titleHeight])
return (
<div className={`${b()} ${className} `} {...rest}>
{isSticky && scrollY > 0 ? (
{isSticky && scrollTop > 0 ? (
<div className={b('list__fixed')}>
<span className="fixed-title">
{indexList[currentIndex][acceptKey]}
......
......@@ -64,8 +64,6 @@ export const Elevator: FunctionComponent<
listHeight: [] as number[],
listGroup: [] as Element[],
scrollY: 0,
diff: -1,
fixedTop: 0,
}
const touchState = useRef({
y1: 0,
......@@ -185,7 +183,6 @@ export const Elevator: FunctionComponent<
const height2 = listHeight[i + 1]
if (state.current.scrollY >= height1 && state.current.scrollY < height2) {
setCurrentIndex(i)
state.current.diff = height2 - state.current.scrollY
return
}
}
......@@ -200,18 +197,6 @@ export const Elevator: FunctionComponent<
}
}, [listview])
useEffect(() => {
const { listHeight, diff, scrollY } = state.current
let fixedTop = diff > 0 && diff < titleHeight ? diff - titleHeight : 0
if (scrollY + clientHeight() === listHeight[listHeight.length - 1]) {
if (fixedTop !== 0) {
fixedTop = 0
}
}
if (state.current.fixedTop === fixedTop) return
state.current.fixedTop = fixedTop
}, [state.current.diff, titleHeight])
return (
<div className={`${b()} ${className}`} {...rest}>
{isSticky && scrollY > 0 ? (
......
import React, { useState } from 'react'
import Taro from '@tarojs/taro'
import { Cell, ImagePreview } from '@/packages/nutui.react.taro'
import { useTranslate } from '@/sites/assets/locale/taro'
import Header from '@/sites/components/header'
import Taro from '@tarojs/taro'
interface T {
basic: string
......@@ -10,6 +10,7 @@ interface T {
withInitNo: string
withPagination: string
withVideos: string
thumb: string
}
const images = [
......@@ -35,6 +36,7 @@ const ImagePreviewDemo = () => {
withInitNo: '设置初始页码',
withPagination: '设置轮播指示器及颜色',
withVideos: '视频、图片预览',
thumb: '点击缩略图切换',
},
'en-US': {
basic: 'Basic usage',
......@@ -42,6 +44,7 @@ const ImagePreviewDemo = () => {
withInitNo: 'With Init No',
withPagination: 'With Pagination',
withVideos: 'With Videos',
thumb: 'Click image to switch',
},
})
......@@ -73,6 +76,7 @@ const ImagePreviewDemo = () => {
setShowPreview3(false)
}
const [init, setInit] = useState<any>(0)
return (
<>
<Header />
......@@ -80,6 +84,24 @@ const ImagePreviewDemo = () => {
<h2>{translated.basic}</h2>
<ImagePreview images={images} show={showPreview1} onClose={hideFn1} />
<Cell title={translated.showPreview} isLink onClick={showFn1} />
<h2>{translated.thumb}</h2>
<Cell style={{ position: 'relative', zIndex: 10000 }}>
{images.map((image, index) => (
<span
key={image.src}
onClick={() => setInit(index + 1)}
style={{ marginRight: '10px' }}
>
<img width="30px" height="30px" src={image.src} alt={image.src} />
</span>
))}
</Cell>
<ImagePreview
images={images}
show={init}
initNo={init}
onClose={hideFn2}
/>
<h2>{translated.withInitNo}</h2>
<ImagePreview
images={images}
......
......@@ -9,6 +9,7 @@ interface T {
withInitNo: string
withPagination: string
withVideos: string
thumb: string
}
const images = [
......@@ -57,6 +58,7 @@ const ImagePreviewDemo = () => {
withInitNo: '设置初始页码',
withPagination: '设置轮播指示器及颜色',
withVideos: '视频、图片预览',
thumb: '点击缩略图切换',
},
'en-US': {
basic: 'Basic usage',
......@@ -64,6 +66,7 @@ const ImagePreviewDemo = () => {
withInitNo: 'With Init No',
withPagination: 'With Pagination',
withVideos: 'With Videos',
thumb: 'Click image to switch',
},
})
......@@ -103,21 +106,46 @@ const ImagePreviewDemo = () => {
const hideFn4 = () => {
setShowPreview4(false)
}
const [init, setInit] = useState<any>(0)
return (
<>
<div className="demo">
<h2>{translated.basic}</h2>
<ImagePreview images={images} show={showPreview1} onClose={hideFn1} />
<Cell title={translated.showPreview} isLink onClick={showFn1} />
<h2>{translated.thumb}</h2>
<Cell style={{ position: 'relative', zIndex: 10000 }}>
{images.map((image, index) => (
<span
key={image.src}
onClick={() => setInit(index + 1)}
style={{ marginRight: '10px' }}
>
<img width={30} height={30} src={image.src} alt={image.src} />
</span>
))}
</Cell>
<ImagePreview
images={images}
show={init}
initNo={init}
onClose={hideFn2}
/>
<h2>{translated.withInitNo}</h2>
<ImagePreview
images={images}
show={showPreview2}
initNo={3}
initNo={init}
onClose={hideFn2}
/>
<Cell title={translated.withInitNo} isLink onClick={showFn2} />
<Cell
title={translated.withInitNo}
isLink
onClick={() => {
showFn2()
setTimeout(() => setInit(1), 3000)
}}
/>
<h2>{translated.withPagination}</h2>
<ImagePreview
images={images}
......
......@@ -58,6 +58,63 @@ export default App;
```
:::
### Click on the thumbnail to switch
:::demo
```tsx
import React, { useState } from 'react';
import { ImagePreview, Cell } from '@nutui/nutui-react';
const App = () => {
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [init, setInit] = useState(0);
return (
<>
<Cell style={{ position: 'relative', zIndex: 10000 }}>
{images.map((image, index) =>
(<span
key={image.src}
onClick={() => setInit(index + 1)}
style={{ marginRight: '10px' }}
>
<img width={30}
height={30}
src={image.src}
alt={image.src}
/>
</span>)
)}
</Cell>
<ImagePreview
images={images}
show={init}
initNo={init}
onClose={hideFn2}
/>
</>
);
};
export default App;
```
:::
### With Init No
:::demo
......
# ImagePreview组件
# ImagePreview组件
### 介绍
......@@ -6,7 +6,6 @@
### 安装
```ts
// react
import { ImagePreview } from '@nutui/nutui-react'
......@@ -17,199 +16,264 @@ import { ImagePreview } from '@nutui/nutui-react'
### 基础用法
:::demo
```tsx
import React, { useState } from 'react';
import { ImagePreview, Cell } from '@nutui/nutui-react';
const App = () => {
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [showPreview1, setShowPreview1] = useState(false);
const showFn1 = () => {
setShowPreview1(true)
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [showPreview1, setShowPreview1] = useState(false);
const showFn1 = () => {
setShowPreview1(true)
}
const hideFn1 = () => {
setShowPreview1(false)
}
return (
<>
<ImagePreview images={images} show={showPreview1} onClose={hideFn1} />
<Cell title="展示图片预览" isLink onClick={showFn1} />
</>
);
};
export default App;
```
:::
### 点击缩略图切换
:::demo
```tsx
import React, { useState } from 'react';
import { ImagePreview, Cell } from '@nutui/nutui-react';
const hideFn1 =() => {
setShowPreview1(false)
const App = () => {
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [init, setInit] = useState(0);
return (
<>
<ImagePreview images={images} show={showPreview1} onClose={hideFn1} />
<Cell title="展示图片预览" isLink onClick={showFn1} />
<Cell style={{ position: 'relative', zIndex: 10000 }}>
{images.map((image, index) =>
(<span
key={image.src}
onClick={() => setInit(index + 1)}
style={{ marginRight: '10px' }}
>
<img width={30}
height={30}
src={image.src}
alt={image.src}
/>
</span>)
)}
</Cell>
<ImagePreview
images={images}
show={init}
initNo={init}
onClose={hideFn2}
/>
</>
);
};
export default App;
```
:::
### 设置初始页码
:::demo
```tsx
import React, { useState } from 'react';
import { ImagePreview, Cell } from '@nutui/nutui-react';
const App = () => {
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [showPreview2, setShowPreview2] = useState(false);
const showFn2 = () => {
setShowPreview2(true)
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [showPreview2, setShowPreview2] = useState(false);
const hideFn2 =() => {
setShowPreview2(false)
}
const showFn2 = () => {
setShowPreview2(true)
}
const hideFn2 = () => {
setShowPreview2(false)
}
return (
<>
<ImagePreview images={images} initNo={3} show={showPreview2} onClose={hideFn2} />
<Cell title="设置初始页码" isLink onClick={showFn2} />
<ImagePreview images={images} initNo={3} show={showPreview2}
onClose={hideFn2} />
<Cell title="设置初始页码" isLink onClick={showFn2} />
</>
);
};
export default App;
```
:::
### 设置轮播指示器及颜色
:::demo
```tsx
import React, { useState } from 'react';
import { ImagePreview, Cell } from '@nutui/nutui-react';
const App = () => {
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [showPreview3, setShowPreview3] = useState(false);
const showFn3 = () => {
setShowPreview3(true)
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [showPreview3, setShowPreview3] = useState(false);
const hideFn3 =() => {
setShowPreview3(false)
}
const showFn3 = () => {
setShowPreview3(true)
}
const hideFn3 = () => {
setShowPreview3(false)
}
return (
<>
<ImagePreview images={images} show={showPreview3} paginationVisible paginationColor="red" onClose={hideFn3} />
<Cell title="设置轮播指示器及颜色" isLink onClick={showFn3} />
<ImagePreview images={images} show={showPreview3} paginationVisible
paginationColor="red" onClose={hideFn3} />
<Cell title="设置轮播指示器及颜色" isLink onClick={showFn3} />
</>
);
};
export default App;
```
:::
### 视频、图片预览
:::demo
```tsx
import React, { useState } from 'react';
import { ImagePreview, Cell } from '@nutui/nutui-react';
const App = () => {
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const videos = [
{
source: {
src: 'https://storage.jd.com/about/big-final.mp4?Expires=3730193075&AccessKey=3LoYX1dQWa6ZXzQl&Signature=ViMFjz%2BOkBxS%2FY1rjtUVqbopbJI%3D',
type: 'video/mp4'
},
options: {
muted: true,
controls: true
}
},
{
source: {
src: 'https://storage.jd.com/about/big-final.mp4?Expires=3730193075&AccessKey=3LoYX1dQWa6ZXzQl&Signature=ViMFjz%2BOkBxS%2FY1rjtUVqbopbJI%3D',
type: 'video/mp4'
},
options: {
muted: true,
controls: true
}
}
]
const [showPreview4, setShowPreview4] = useState(false);
const showFn4 = () => {
setShowPreview4(true)
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
const hideFn4 =() => {
setShowPreview4(false)
];
const videos = [
{
source: {
src: 'https://storage.jd.com/about/big-final.mp4?Expires=3730193075&AccessKey=3LoYX1dQWa6ZXzQl&Signature=ViMFjz%2BOkBxS%2FY1rjtUVqbopbJI%3D',
type: 'video/mp4'
},
options: {
muted: true,
controls: true
}
},
{
source: {
src: 'https://storage.jd.com/about/big-final.mp4?Expires=3730193075&AccessKey=3LoYX1dQWa6ZXzQl&Signature=ViMFjz%2BOkBxS%2FY1rjtUVqbopbJI%3D',
type: 'video/mp4'
},
options: {
muted: true,
controls: true
}
}
]
const [showPreview4, setShowPreview4] = useState(false);
const showFn4 = () => {
setShowPreview4(true)
}
const hideFn4 = () => {
setShowPreview4(false)
}
return (
<>
<ImagePreview images={images} videos={videos} show={showPreview4} onClose={hideFn4} />
<Cell title="视频、图片预览" isLink onClick={showFn4} />
<ImagePreview images={images} videos={videos} show={showPreview4}
onClose={hideFn4} />
<Cell title="视频、图片预览" isLink onClick={showFn4} />
</>
);
};
export default App;
```
:::
:::
## API
......
......@@ -55,6 +55,63 @@ const App = () => {
};
export default App;
```
:::
### 点击缩略图切换
:::demo
```tsx
import React, { useState } from 'react';
import { ImagePreview, Cell } from '@nutui/nutui-react-taro';
const App = () => {
const images = [
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/18629/34/3378/144318/5c263f64Ef0e2bff0/0d650e0aa2e852ee.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/26597/30/4870/174583/5c35c5d2Ed55eedc6/50e27870c25e7a82.png'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/9542/17/12873/201687/5c3c4362Ea9eb757d/60026b40a9d60d85.jpg'
},
{
src: '//m.360buyimg.com/mobilecms/s750x366_jfs/t1/30042/36/427/82951/5c3bfdabE3faf2f66/9adca782661c988c.jpg'
}
];
const [init, setInit] = useState(0);
return (
<>
<Cell style={{ position: 'relative', zIndex: 10000 }}>
{images.map((image, index) =>
(<span
key={image.src}
onClick={() => setInit(index + 1)}
style={{ marginRight: '10px' }}
>
<img width={30}
height={30}
src={image.src}
alt={image.src}
/>
</span>)
)}
</Cell>
<ImagePreview
images={images}
show={init}
initNo={init}
onClose={hideFn2}
/>
</>
);
};
export default App;
```
:::
### 设置初始页码
......
......@@ -12,6 +12,7 @@ interface Idata {
number: string
digit: string
tel: string
nickname: string
readonly: string
disabled: string
showIcon: string
......@@ -47,6 +48,7 @@ const InputDemo = () => {
number: '数字',
digit: '整数',
tel: '手机号',
nickname: '昵称',
readonly: '只读',
disabled: '禁用',
icon: '显示图标',
......@@ -84,6 +86,7 @@ const InputDemo = () => {
number: 'Number',
digit: 'Digit',
tel: 'Tel',
nickname: 'Nickname',
readonly: 'Readonly',
disabled: 'Disabled',
icon: 'Show Icon',
......@@ -210,6 +213,13 @@ const InputDemo = () => {
defaultValue={state.tel}
type="tel"
/>
<Input
name="nickname"
label={translated.nickname}
placeholder={translated.nickname}
type="nickname"
onChange={(val) => console.log('onChange', val)}
/>
<h2>{translated.title2}</h2>
<Input
label={translated.text}
......
......@@ -85,6 +85,13 @@ const App = () => {
defaultValue={state.tel}
type="tel"
/>
<Input
name="nickname"
label="昵称"
placeholder="昵称(仅支持小程序)"
type="nickname"
onChange={(val) => console.log('onChange', val)}
/>
</>
)
}
......
......@@ -271,7 +271,7 @@ export const Input: FunctionComponent<
if (maxlength && val.length > Number(maxlength)) {
val = val.slice(0, Number(maxlength))
}
updateValue(getModelValue(), 'onBlur')
updateValue(val, 'onBlur')
onBlur && onBlur(val, event)
}
......@@ -462,7 +462,9 @@ export const Input: FunctionComponent<
>
{errorMessage}
</div>
) : null}
) : (
<div />
)}
</div>
</>
)}
......
......@@ -272,7 +272,7 @@ export const Input: FunctionComponent<
if (maxlength && val.length > Number(maxlength)) {
val = val.slice(0, Number(maxlength))
}
updateValue(getModelValue(), 'onBlur')
updateValue(val, 'onBlur')
onBlur && onBlur(val, event)
}
......@@ -463,7 +463,9 @@ export const Input: FunctionComponent<
>
{errorMessage}
</div>
) : null}
) : (
<div />
)}
</div>
</>
)}
......
.format-width {
input,
.nut-number-input {
--nutui-inputnumber-input-width: 60px;
}
}
......@@ -4,6 +4,7 @@ import { InputNumber } from './inputnumber'
import ConfigProvider from '@/packages/configprovider'
import Cell from '@/packages/cell'
import Toast from '@/packages/toast'
import './demo.scss'
interface ValState {
val1: number | string
......@@ -29,6 +30,7 @@ interface T {
'3a42134b': string
'65bafb1d': string
'7e2394ae': string
'7e2394be': string
}
const customTheme = {
......@@ -63,6 +65,7 @@ const InputNumberDemo = () => {
'3a42134b': '支持小数点',
'65bafb1d': '支持异步修改',
'7e2394ae': '自定义按钮大小',
'7e2394be': '支持formatter',
},
'zh-TW': {
'6333c786': '超出限制事件觸發',
......@@ -77,6 +80,7 @@ const InputNumberDemo = () => {
'3a42134b': '支持小數點',
'65bafb1d': '支持異步修改',
'7e2394ae': '自定義按鈕大小',
'7e2394be': '支持formatter',
},
'en-US': {
'6333c786': 'Exceeded limit event triggered',
......@@ -91,6 +95,7 @@ const InputNumberDemo = () => {
'3a42134b': 'support decimal point',
'65bafb1d': 'Support for asynchronous modification',
'7e2394ae': 'custom button size',
'7e2394be': 'support formatter',
},
})
......@@ -181,6 +186,28 @@ const InputNumberDemo = () => {
inputWidth="150px"
/>
</Cell>
<h2>支持formatter</h2>
<Cell>
<InputNumber
className="format-width"
modelValue="1000"
min={10}
max={15020}
formatter={(value) =>
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
/>
</Cell>
<Cell>
<InputNumber
className="format-width"
modelValue="100"
min={0}
max={100}
formatter={(value) => `${value}%`}
/>
</Cell>
</div>
</>
)
......
......@@ -204,6 +204,39 @@ export default App;
```
:::
### support formatter
:::demo
```tsx
import React from "react";
import { InputNumber } from '@nutui/nutui-react';
const App = () => {
return (
<>
<InputNumber
style={{"--nutui-inputnumber-input-width": "60px"}}
modelValue="1000"
min={10}
max={15020}
formatter={(value) =>
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
/>
<InputNumber
style={{"--nutui-inputnumber-input-width": "60px"}}
modelValue="100"
min={0}
max={100}
formatter={(value) => `${value}%`}
/>
</>
)
}
export default App;
```
:::
## API
### Props
......@@ -220,6 +253,7 @@ export default App;
| disabled | Disable all features | boolean | `false` |
| readonly | Read only status disables input box operation behavior | boolean | `false` |
| isAsync | Support for asynchronous modification | boolean | `false` |
| formatter`v1.4.14` | Specifies the format of the value displayed in the input box | function(value: number | string): string | - |
### Events
......
......@@ -9,7 +9,6 @@
``` ts
// react
import { InputNumber } from '@nutui/nutui-react';
```
### 基础用法
......@@ -214,7 +213,7 @@ const App = () => {
const onChange = (value: string | number) => {
Toast.loading('异步演示 2 秒后更改')
setTimeout(() => {
inputState.val7 = number(value)
inputState.val7 = Number(value)
setInputState({ ...inputState })
Toast.hide()
}, 2000)
......@@ -250,22 +249,56 @@ export default App;
```
:::
### 支持formatter
:::demo
```tsx
import React from "react";
import { InputNumber } from '@nutui/nutui-react';
const App = () => {
return (
<>
<InputNumber
style={{"--nutui-inputnumber-input-width": "60px"}}
modelValue="1000"
min={10}
max={15020}
formatter={(value) =>
`$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
/>
<InputNumber
style={{"--nutui-inputnumber-input-width": "60px"}}
modelValue="100"
min={0}
max={100}
formatter={(value) => `${value}%`}
/>
</>
)
}
export default App;
```
:::
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
|----------------|----------------------------|----------------|------------|
| modelValue | 初始值 | stringnumber | - |
| modelValue | 初始值 | string \| number | - |
| inputWidth | 输入框宽度 | string | `40px` |
| buttonSize | 操作符+、-尺寸 | string | `20px` |
| min | 最小值限制 | string、number | `1` |
| max | 最大值限制 | string、number | `9999` |
| step | 步长 | string、number | `1` |
| decimalPlaces | 设置保留的小数位 | string、number | `0` |
| disabled | 禁用所有功能 | boolean | false |
| readonly | 只读状态禁用输入框操作行为 | boolean | false |
| isAsync | 支持异步修改 | boolean | false |
| min | 最小值限制 | string \| number | `1` |
| max | 最大值限制 | string \| number | `9999` |
| step | 步长 | string \| number | `1` |
| decimalPlaces | 设置保留的小数位 | string \| number | `0` |
| disabled | 禁用所有功能 | boolean | `false` |
| readonly | 只读状态禁用输入框操作行为 | boolean | `false` |
| isAsync | 支持异步修改 | boolean | `false` |
| formatter`v1.4.14` | 指定输入框展示值的格式 | function(value: number | string): string | - |
### Events
......
import React, {
useState,
useEffect,
useRef,
FunctionComponent,
ChangeEvent,
FocusEvent,
......@@ -24,6 +25,16 @@ export interface InputNumberProps extends BasicComponent {
isAsync: boolean
className: string
style: React.CSSProperties
formatter?: (displayValue: string | number) => string
add: (e: MouseEvent) => void
reduce: (e: MouseEvent) => void
overlimit: (e: MouseEvent) => void
blur: (e: ChangeEvent<HTMLInputElement>) => void
focus: (e: FocusEvent<HTMLInputElement>) => void
change: (
param: string | number,
e: MouseEvent | ChangeEvent<HTMLInputElement>
) => void
onAdd: (e: MouseEvent) => void
onReduce: (e: MouseEvent) => void
onOverlimit: (e: MouseEvent) => void
......@@ -71,6 +82,13 @@ export const InputNumber: FunctionComponent<
isAsync,
className,
style,
formatter,
add,
reduce,
change,
overlimit,
blur,
focus,
onAdd,
onReduce,
onOverlimit,
......@@ -83,9 +101,15 @@ export const InputNumber: FunctionComponent<
...props,
}
const [inputValue, setInputValue] = useState(modelValue)
const inputRef = useRef('')
useEffect(() => {
setInputValue(modelValue)
}, [modelValue])
if (formatter) {
inputRef.current = formatter(modelValue)
setInputValue(formatter(modelValue))
} else {
setInputValue(modelValue)
}
}, [modelValue, formatter])
const b = bem('inputnumber')
const classes = classNames(
......@@ -100,6 +124,10 @@ export const InputNumber: FunctionComponent<
...style,
}
const addAllow = (value = inputValue) => {
if (formatter) {
const numValue = String(value).replace(/[^0-9|\.]/gi, '')
return Number(numValue) < Number(max) && !disabled
}
if (value || typeof value === 'number') {
return value < Number(max) && !disabled
}
......@@ -107,6 +135,10 @@ export const InputNumber: FunctionComponent<
}
const reduceAllow = (value = inputValue) => {
if (formatter) {
const numValue = String(value).replace(/[^0-9|\.]/gi, '')
return Number(numValue) > Number(min) && !disabled
}
if (value || typeof value === 'number') {
return value > Number(min) && !disabled
}
......@@ -133,11 +165,17 @@ export const InputNumber: FunctionComponent<
onChange && onChange(outputValue, e)
if (!isAsync) {
if (Number(outputValue) < Number(min)) {
setInputValue(Number(min))
formatter
? setInputValue(formatter(Number(min)))
: setInputValue(Number(min))
} else if (Number(outputValue) > Number(max)) {
setInputValue(Number(max))
formatter
? setInputValue(formatter(Number(max)))
: setInputValue(Number(max))
} else {
setInputValue(outputValue)
formatter
? setInputValue(formatter(outputValue))
: setInputValue(outputValue)
}
}
}
......@@ -145,8 +183,15 @@ export const InputNumber: FunctionComponent<
const reduceNumber = (e: MouseEvent) => {
onReduce && onReduce(e)
if (reduceAllow()) {
const outputValue = Number(inputValue) - Number(step)
emitChange(outputValue, e)
if (formatter) {
const numValue = String(inputValue).replace(/[^0-9|\.]/gi, '')
const outputValue = Number(numValue) - Number(step)
inputRef.current = formatter(outputValue)
emitChange(outputValue, e)
} else {
const outputValue = Number(inputValue) - Number(step)
emitChange(outputValue, e)
}
} else {
onOverlimit && onOverlimit(e)
}
......@@ -155,8 +200,15 @@ export const InputNumber: FunctionComponent<
const addNumber = (e: MouseEvent) => {
onAdd && onAdd(e)
if (addAllow()) {
const outputValue = Number(inputValue) + Number(step)
emitChange(outputValue, e)
if (formatter) {
const numValue = String(inputValue).replace(/[^0-9|\.]/gi, '')
const outputValue = Number(numValue) + Number(step)
inputRef.current = formatter(outputValue)
emitChange(outputValue, e)
} else {
const outputValue = Number(inputValue) + Number(step)
emitChange(outputValue, e)
}
} else {
onOverlimit && onOverlimit(e)
}
......@@ -174,6 +226,48 @@ export const InputNumber: FunctionComponent<
}
}
const changeFormatValue = (e: ChangeEvent<HTMLInputElement>) => {
const input = e.target.value
const numReg = new RegExp('^[0-9]*$')
const numValue = input.replace(/[^0-9|\.]/gi, '')
if (formatter) {
if (!numReg.test(input[0]) && numValue) {
setInputValue(formatter(numValue))
} else if (!numReg.test(input[0]) && !numValue) {
setInputValue(input)
} else if (numReg.test(input[0])) {
console.log('inputRef.current', inputRef.current)
console.log('formatter(numValue)', formatter(numValue))
// 针对于100%这种尾字符例子,直接删除会进行匹配
if (formatter(numValue) === inputRef.current) {
setInputValue(numValue)
} else {
setInputValue(formatter(numValue))
inputRef.current = formatter(numValue)
}
}
}
}
const burFormatValue = (e: ChangeEvent<HTMLInputElement>) => {
const input = e.target.value
const numReg = new RegExp('^[0-9]*$')
const numValue = input.replace(/[^0-9|\.]/gi, '')
if (formatter) {
if (formatter(numValue) === input) {
emitChange(numValue, e)
return
}
if (!numReg.test(input) || !input) {
setInputValue(formatter(''))
}
}
}
const focusValue = (e: FocusEvent<HTMLInputElement>) => {
if (disabled) return
if (readonly) return
......@@ -203,18 +297,35 @@ export const InputNumber: FunctionComponent<
height={buttonSize}
/>
</div>
<input
type="number"
min={min}
max={max}
style={{ width: pxCheck(inputWidth) }}
disabled={disabled}
readOnly={readonly}
value={inputValue}
onInput={changeValue}
onBlur={burValue}
onFocus={focusValue}
/>
<>
{formatter ? (
<input
type="text"
min={min}
max={max}
style={{ width: pxCheck(inputWidth) }}
disabled={disabled}
readOnly={readonly}
value={inputValue}
onInput={changeFormatValue}
onBlur={burFormatValue}
onFocus={focusValue}
/>
) : (
<input
type="number"
min={min}
max={max}
style={{ width: pxCheck(inputWidth) }}
disabled={disabled}
readOnly={readonly}
value={inputValue}
onInput={changeValue}
onBlur={burValue}
onFocus={focusValue}
/>
)}
</>
<div className="nut-input-add">
<Plus
className={iconAddClasses}
......
......@@ -8,6 +8,7 @@ import React, {
import { PickerOption } from './picker.taro'
import { useTouch } from '../../utils/useTouch'
import { getRectByTaro } from '@/utils/useClientRect'
import { passiveSupported } from '@/utils/supports-passive'
interface PickerSlotProps {
keyIndex?: number
......@@ -211,7 +212,10 @@ const InternalPickerSlot: ForwardRefRenderFunction<
isStopPropagation?: boolean
) => {
/* istanbul ignore else */
if (typeof event.cancelable !== 'boolean' || event.cancelable) {
if (
!passiveSupported &&
(typeof event.cancelable !== 'boolean' || event.cancelable)
) {
event.preventDefault()
}
......
import * as React from 'react'
import '@testing-library/jest-dom'
import { render, fireEvent } from '@testing-library/react'
import { render, screen } from '@testing-library/react'
import Range from '@/packages/range'
test('range props test', () => {
......@@ -37,16 +37,9 @@ test('range props test', () => {
})
test('range max and min test', () => {
const handleChange = jest.fn()
const { container } = render(
<Range modelValue={0} max={10} min={-10} onChange={handleChange} />
)
const { container } = render(<Range modelValue={0} max={10} min={-10} />)
expect(container.querySelector('.min')?.innerHTML).toBe('-10')
expect(container.querySelector('.max')?.innerHTML).toBe('10')
fireEvent.click(container)
setTimeout(() => {
expect(handleChange).toBeCalled()
}, 300)
})
test('range test', () => {
......@@ -54,14 +47,12 @@ test('range test', () => {
value0: [30, 60],
}
const { container } = render(<Range range modelValue={state.value0} />)
setTimeout(() => {
expect(
container.querySelector('nut-range-button-wrapper-left')
).toHaveAttribute('aria-valuenow', '30')
expect(
container.querySelector('nut-range-button-wrapper-right')
).toHaveAttribute('aria-valuenow', '60')
}, 300)
expect(
container.querySelector('.nut-range-button-wrapper-left')
).toHaveAttribute('aria-valuenow', '30')
expect(
container.querySelector('.nut-range-button-wrapper-right')
).toHaveAttribute('aria-valuenow', '60')
})
test('range description test', () => {
......@@ -78,15 +69,14 @@ test('disabled test', () => {
value0: 50,
}
const { container } = render(<Range disabled modelValue={state.value0} />)
setTimeout(() => {
expect(container.querySelector('nut-range')).toHaveClass(
'nut-range-disabled'
)
expect(container.querySelector('nut-range-button-wrapper')).toHaveAttribute(
'aria-valuenow',
'50'
)
}, 300)
expect(container.querySelector('.nut-range-button-wrapper')).toHaveAttribute(
'aria-valuenow',
'50'
)
expect(container.querySelector('.nut-range')).toHaveClass(
'nut-range-disabled'
)
expect(screen.queryByRole('slider')).toHaveAttribute('tabindex', '-1')
})
test('hiddenRange test', () => {
......@@ -94,8 +84,8 @@ test('hiddenRange test', () => {
value0: 40,
}
const { container } = render(<Range hiddenRange modelValue={state.value0} />)
expect(container.querySelector('max')).not.toBeTruthy
expect(container.querySelector('min')).not.toBeTruthy
expect(container.querySelector('max')).not.toBeTruthy()
expect(container.querySelector('min')).not.toBeTruthy()
})
test('hiddenTag test', () => {
......@@ -113,11 +103,14 @@ test('vertical test', () => {
value0: 40,
}
const { container } = render(<Range vertical modelValue={state.value0} />)
setTimeout(() => {
expect(container.querySelector('nut-range-container')).toHaveClass(
'nut-range-container-vertical'
)
}, 300)
expect(screen.queryByRole('slider')).toHaveAttribute('tabindex', '0')
expect(screen.queryByRole('slider')).toHaveAttribute(
'aria-orientation',
'vertical'
)
expect(container.querySelector('.nut-range-container')).toHaveClass(
'nut-range-container-vertical'
)
})
test('marks test', () => {
......@@ -135,10 +128,13 @@ test('marks test', () => {
const { container } = render(
<Range marks={state.marks} modelValue={state.value0} />
)
expect(container.querySelector('nut-range-mark')).toBeTruthy
expect(container.querySelector('.nut-range-mark')).toBeTruthy()
expect(container.querySelectorAll('.nut-range-mark-text')?.length).toEqual(
Object.keys(state.marks).length
)
})
test('button test', () => {
test('custom-button test', () => {
const state = {
value0: 40,
}
......@@ -148,5 +144,35 @@ test('button test', () => {
modelValue={state.value0}
/>
)
expect(container.querySelector('range-custom-button')).toBeTruthy
expect(container.querySelector('.range-custom-button')).toBeTruthy()
expect(container.querySelector('.range-custom-button')?.innerHTML).toBe('40')
expect(container.querySelector('.nut-range-button-wrapper')).toHaveAttribute(
'aria-valuenow',
'40'
)
})
test('desc test', () => {
const state = {
value0: 40,
minDesc: 'min',
maxDesc: 'max',
curValueDesc: 'value',
}
const { container } = render(
<Range
modelValue={state.value0}
minDesc={state.minDesc}
maxDesc={state.maxDesc}
curValueDesc={state.curValueDesc}
/>
)
expect(container.querySelector('.nut-range-button-wrapper')).toHaveAttribute(
'aria-valuenow',
'40'
)
expect(container.querySelector('.min')?.innerHTML).toBe(state.minDesc)
expect(container.querySelector('.max')?.innerHTML).toBe(state.maxDesc)
expect(container.querySelector('.number')?.innerHTML).toBe(state.curValueDesc)
})
......@@ -417,7 +417,7 @@ export const Range: FunctionComponent<
aria-valuemin={+min}
aria-valuenow={curValue(index)}
aria-valuemax={+max}
aria-orientation="horizontal"
aria-orientation={vertical ? 'vertical' : 'horizontal'}
onTouchStart={(e: any) => {
if (typeof index === 'number') {
// 实时更新当前拖动的按钮索引
......@@ -458,7 +458,7 @@ export const Range: FunctionComponent<
aria-valuemin={+min}
aria-valuenow={curValue()}
aria-valuemax={+max}
aria-orientation="horizontal"
aria-orientation={vertical ? 'vertical' : 'horizontal'}
onTouchStart={(e) => {
onTouchStart(e)
}}
......
......@@ -410,7 +410,7 @@ export const Range: FunctionComponent<
aria-valuemin={+min}
aria-valuenow={curValue(index)}
aria-valuemax={+max}
aria-orientation="horizontal"
aria-orientation={vertical ? 'vertical' : 'horizontal'}
onTouchStart={(e: any) => {
if (typeof index === 'number') {
// 实时更新当前拖动的按钮索引
......@@ -451,7 +451,7 @@ export const Range: FunctionComponent<
aria-valuemin={+min}
aria-valuenow={curValue()}
aria-valuemax={+max}
aria-orientation="horizontal"
aria-orientation={vertical ? 'vertical' : 'horizontal'}
onTouchStart={(e) => {
onTouchStart(e)
}}
......
......@@ -97,6 +97,7 @@ const config = {
url: {
enable: true,
config: {
url: 'inline',
limit: 1024, // 设定转换尺寸上限
},
},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册