diff --git a/packages/nutui-taro-demo-rn/scripts/taro/adapted.js b/packages/nutui-taro-demo-rn/scripts/taro/adapted.js
index 0829e85635..23dc22bb7e 100644
--- a/packages/nutui-taro-demo-rn/scripts/taro/adapted.js
+++ b/packages/nutui-taro-demo-rn/scripts/taro/adapted.js
@@ -26,6 +26,7 @@ exports = module.exports = [
'hoverbutton',
'safearea',
'hoverbuttonitem',
+ 'range',
'avatar',
'avatargroup',
'inputnumber',
diff --git a/packages/nutui-taro-demo-rn/src/app.config.ts b/packages/nutui-taro-demo-rn/src/app.config.ts
index 8c9e8edcfd..c1eadf265b 100644
--- a/packages/nutui-taro-demo-rn/src/app.config.ts
+++ b/packages/nutui-taro-demo-rn/src/app.config.ts
@@ -124,7 +124,7 @@ const subPackages = [
}
];
-export default defineAppConfig ({
+export default defineAppConfig({
pages: ['pages/index/index'],
subPackages,
window: {
diff --git a/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.config.ts b/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.config.ts
index 6cdf97238b..780d4febe6 100644
--- a/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.config.ts
+++ b/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.config.ts
@@ -1,3 +1,3 @@
export default {
- navigationBarTitleText: 'Range',
+ navigationBarTitleText: 'Range'
}
\ No newline at end of file
diff --git a/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.tsx b/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.tsx
index 039e05e8ec..c90590d54f 100644
--- a/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.tsx
+++ b/packages/nutui-taro-demo-rn/src/dentry1/pages/range/index.tsx
@@ -1 +1,2 @@
-export default <>button>;
\ No newline at end of file
+import Demo from '@/packages/range/demo.taro';
+export default Demo;
\ No newline at end of file
diff --git a/src/config.json b/src/config.json
index eea840b99e..f2478c0ade 100644
--- a/src/config.json
+++ b/src/config.json
@@ -610,7 +610,7 @@
"author": "oasis"
},
{
- "version": "2.0.0",
+ "version": "3.0.0",
"name": "Range",
"type": "component",
"cName": "区间选择器",
diff --git a/src/packages/range/demos/h5/demo11.tsx b/src/packages/range/demos/h5/demo11.tsx
index c8c55228d2..07adbe4284 100644
--- a/src/packages/range/demos/h5/demo11.tsx
+++ b/src/packages/range/demos/h5/demo11.tsx
@@ -13,6 +13,7 @@ const Demo11 = () => {
button={
{
textAlign: 'center',
backgroundColor: 'red',
borderRadius: '10px',
+ top: '50%',
+ left: '50%',
+ transform: 'translate(-50%, -50%)',
}}
>
{value}
diff --git a/src/packages/range/demos/taro/demo1.tsx b/src/packages/range/demos/taro/demo1.tsx
index f926c615d7..65544fd703 100644
--- a/src/packages/range/demos/taro/demo1.tsx
+++ b/src/packages/range/demos/taro/demo1.tsx
@@ -1,10 +1,22 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useMemo, useState } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo1 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -12,7 +24,7 @@ const Demo1 = () => {
setShow(true)
}
return (
- <>
+
showToast(`${val}`)} />
|
@@ -26,15 +38,15 @@ const Demo1 = () => {
onEnd={(val) => showToast(`${val}`)}
/>
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo1
diff --git a/src/packages/range/demos/taro/demo10.tsx b/src/packages/range/demos/taro/demo10.tsx
index edec554041..0de7a26c85 100644
--- a/src/packages/range/demos/taro/demo10.tsx
+++ b/src/packages/range/demos/taro/demo10.tsx
@@ -1,10 +1,22 @@
-import React from 'react'
+import React, { useMemo } from 'react'
import { Range, ConfigProvider, Cell } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo10 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
+
return (
{
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
+
+ const buttonNativeStyle = useMemo(() => {
+ if (rn()) {
+ return {
+ transform: [
+ { translateX: pxTransform(-13) },
+ { translateY: pxTransform(3) },
+ ],
+ }
+ }
+ return {}
+ }, [])
const [value, setValue] = useState(60)
- const cellStyle = {
- padding: '40px 18px',
- }
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -14,38 +37,63 @@ const Demo11 = () => {
setShow(true)
}
return (
- <>
+
|
- {value}
+
+ {value}
+
|
}
onChange={(val: any) => setValue(val)}
onEnd={(val) => showToast(`${val}`)}
/>
|
-
{
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo11
diff --git a/src/packages/range/demos/taro/demo12.tsx b/src/packages/range/demos/taro/demo12.tsx
index 4bb7c4ab08..8c7f5e939a 100644
--- a/src/packages/range/demos/taro/demo12.tsx
+++ b/src/packages/range/demos/taro/demo12.tsx
@@ -1,12 +1,28 @@
-import React, { useState } from 'react'
+import React, { useMemo, useState } from 'react'
import { View } from '@tarojs/components'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo12 = () => {
- const verticalStyle = {
- height: '180px',
- padding: '10px',
- }
+ const verticalStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ height: pxTransform(180),
+ paddingTop: pxTransform(10),
+ paddingBottom: pxTransform(10),
+ paddingLeft: pxTransform(10),
+ paddingRight: pxTransform(10),
+ }
+ : {
+ height: '180px',
+ padding: '10px',
+ }
+ }, [])
+ const viewStyle = useMemo(
+ () => ({ width: pxTransform(150), height: '100%' }),
+ []
+ )
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -14,16 +30,16 @@ const Demo12 = () => {
setShow(true)
}
return (
- <>
+
-
+
showToast(`${val}`)}
/>
-
+
{
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo12
diff --git a/src/packages/range/demos/taro/demo13.tsx b/src/packages/range/demos/taro/demo13.tsx
index 0f852ee94f..35ccd90766 100644
--- a/src/packages/range/demos/taro/demo13.tsx
+++ b/src/packages/range/demos/taro/demo13.tsx
@@ -1,7 +1,36 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useMemo, useState } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo13 = () => {
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
+ const verticalStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ height: pxTransform(180),
+ paddingTop: pxTransform(10),
+ paddingBottom: pxTransform(10),
+ paddingLeft: pxTransform(10),
+ paddingRight: pxTransform(10),
+ }
+ : {
+ height: '180px',
+ padding: '10px',
+ }
+ }, [])
const [marks] = useState({
0: 'Start',
20: 20,
@@ -10,13 +39,6 @@ const Demo13 = () => {
80: 80,
100: 'End',
})
- const cellStyle = {
- padding: '40px 18px',
- }
- const verticalStyle = {
- height: '180px',
- padding: '10px',
- }
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -24,7 +46,7 @@ const Demo13 = () => {
setShow(true)
}
return (
- <>
+
{
minDescription={null}
marks={marks}
onEnd={(val) => showToast(`${val}`)}
+ style={{ flex: 1 }}
/>
{
marks={marks}
range
onEnd={(val) => showToast(`${val}`)}
+ style={{ flex: 1 }}
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo13
diff --git a/src/packages/range/demos/taro/demo2.tsx b/src/packages/range/demos/taro/demo2.tsx
index 39b43f0626..cf7b1b1090 100644
--- a/src/packages/range/demos/taro/demo2.tsx
+++ b/src/packages/range/demos/taro/demo2.tsx
@@ -1,11 +1,22 @@
-import React, { useState } from 'react'
+import React, { useMemo, useState } from 'react'
import { Range, Cell } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo2 = () => {
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [value, setValue] = useState(40)
- const cellStyle = {
- padding: '40px 18px',
- }
return (
setValue(val)} />
diff --git a/src/packages/range/demos/taro/demo3.tsx b/src/packages/range/demos/taro/demo3.tsx
index e693325781..f9dc0eb7f3 100644
--- a/src/packages/range/demos/taro/demo3.tsx
+++ b/src/packages/range/demos/taro/demo3.tsx
@@ -1,10 +1,22 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useMemo, useState } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo3 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -12,7 +24,7 @@ const Demo3 = () => {
setShow(true)
}
return (
- <>
+
|
{
onEnd={(val) => showToast(`${val}`)}
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo3
diff --git a/src/packages/range/demos/taro/demo4.tsx b/src/packages/range/demos/taro/demo4.tsx
index 3a76b2e934..8a153f9423 100644
--- a/src/packages/range/demos/taro/demo4.tsx
+++ b/src/packages/range/demos/taro/demo4.tsx
@@ -1,10 +1,22 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useState, useMemo } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo4 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -12,7 +24,7 @@ const Demo4 = () => {
setShow(true)
}
return (
- <>
+
{
onEnd={(val) => showToast(`${val}`)}
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo4
diff --git a/src/packages/range/demos/taro/demo5.tsx b/src/packages/range/demos/taro/demo5.tsx
index c8c2d62920..5537ebf2e2 100644
--- a/src/packages/range/demos/taro/demo5.tsx
+++ b/src/packages/range/demos/taro/demo5.tsx
@@ -1,10 +1,22 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useMemo, useState } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo5 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -12,7 +24,7 @@ const Demo5 = () => {
setShow(true)
}
return (
- <>
+
{
onEnd={(val) => showToast(`${val}`)}
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo5
diff --git a/src/packages/range/demos/taro/demo6.tsx b/src/packages/range/demos/taro/demo6.tsx
index d27cd52b36..dae93f0ff1 100644
--- a/src/packages/range/demos/taro/demo6.tsx
+++ b/src/packages/range/demos/taro/demo6.tsx
@@ -1,10 +1,22 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useMemo, useState } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo6 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -12,7 +24,7 @@ const Demo6 = () => {
setShow(true)
}
return (
- <>
+
{
onEnd={(val) => showToast(`${val}`)}
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo6
diff --git a/src/packages/range/demos/taro/demo7.tsx b/src/packages/range/demos/taro/demo7.tsx
index eb5de5905d..70cc958525 100644
--- a/src/packages/range/demos/taro/demo7.tsx
+++ b/src/packages/range/demos/taro/demo7.tsx
@@ -1,10 +1,22 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useMemo, useState } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo7 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -12,7 +24,7 @@ const Demo7 = () => {
setShow(true)
}
return (
- <>
+
{
onEnd={(val) => showToast(`${val}`)}
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo7
diff --git a/src/packages/range/demos/taro/demo8.tsx b/src/packages/range/demos/taro/demo8.tsx
index 69fdf767d6..40d7a2ed9d 100644
--- a/src/packages/range/demos/taro/demo8.tsx
+++ b/src/packages/range/demos/taro/demo8.tsx
@@ -1,10 +1,22 @@
-import React, { useState } from 'react'
-import { Range, Cell, Toast } from '@nutui/nutui-react-taro'
+import React, { useMemo, useState } from 'react'
+import { View } from '@tarojs/components'
+import { Range, Cell /* , Toast */ } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo8 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
const [show, setShow] = useState(false)
const [msg, setMsg] = useState('')
const showToast = (msg: string) => {
@@ -12,7 +24,7 @@ const Demo8 = () => {
setShow(true)
}
return (
- <>
+
{
onEnd={(val) => showToast(`${val}`)}
/>
|
- {
setShow(false)
}}
- />
- >
+ /> */}
+
)
}
export default Demo8
diff --git a/src/packages/range/demos/taro/demo9.tsx b/src/packages/range/demos/taro/demo9.tsx
index 69cf9574ce..19bab8cb58 100644
--- a/src/packages/range/demos/taro/demo9.tsx
+++ b/src/packages/range/demos/taro/demo9.tsx
@@ -1,10 +1,22 @@
-import React from 'react'
+import React, { useMemo } from 'react'
import { Range, Cell } from '@nutui/nutui-react-taro'
+import pxTransform from '@/utils/px-transform'
+import { harmonyAndRn } from '@/utils/platform-taro'
const Demo9 = () => {
- const cellStyle = {
- padding: '40px 18px',
- }
+ const cellStyle = useMemo(() => {
+ return harmonyAndRn()
+ ? {
+ paddingTop: pxTransform(40),
+ paddingBottom: pxTransform(40),
+ paddingLeft: pxTransform(18),
+ paddingRight: pxTransform(18),
+ }
+ : {
+ padding: '40px 18px',
+ }
+ }, [])
+
return (
diff --git a/src/packages/range/range.harmony.css b/src/packages/range/range.harmony.css
index d82abcd79e..7c15129047 100644
--- a/src/packages/range/range.harmony.css
+++ b/src/packages/range/range.harmony.css
@@ -1,240 +1,265 @@
.nut-range-container {
display: flex;
+ flex-direction: row;
position: relative;
width: 100%;
height: 4px;
align-items: center;
+ justify-content: space-between;
}
-.nut-range-container .min {
- font-size: 12px;
- color: #1A1A1A;
- user-select: none;
+.nut-range-container-native {
+ height: auto;
}
-.nut-range-container .max {
- font-size: 12px;
- color: #1A1A1A;
- user-select: none;
-}
-.nut-range-container .nut-range {
+
+.nut-range {
display: block;
position: relative;
- width: 100%;
height: 4px;
margin: 0 15px;
- background-color: #FFEBF1;
+ background-color: #ffebf1;
border-radius: 2px;
+ flex: 1;
cursor: pointer;
}
-.nut-range-container .nut-range::before {
+.nut-range::before {
position: absolute;
inset-block: -8px;
inset-inline: 0;
content: "";
}
-.nut-range-container .nut-range-bar {
+.nut-range-min {
+ font-size: 12px;
+ color: #1a1a1a;
+ user-select: none;
+}
+.nut-range-max {
+ font-size: 12px;
+ color: #1a1a1a;
+ user-select: none;
+}
+.nut-range-bar {
display: block;
position: relative;
width: 100%;
height: 100%;
- background: #FF0F23;
- border-radius: inherit;
+ background: #ff0f23;
+ border-radius: 2px;
transition: all 0.2s;
}
-.nut-range-container .nut-range-button {
- display: block;
+.nut-range-button {
+ position: absolute;
+ display: flex;
width: 24px;
height: 24px;
background: #ffffff;
border-radius: 50%;
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15);
- border: 1px solid #FF0F23;
+ border: 1px solid #ff0f23;
outline: none;
+ align-items: center;
+ top: 50%;
+ left: 50%;
+}
+.nut-range-button-wrapper {
+ width: 24px;
+ height: 24px;
+}
+.nut-range-button-wrapper-right {
+ width: 24px;
+ height: 24px;
}
-.nut-range-container .nut-range-button-wrapper, .nut-range-container .nut-range-button-wrapper-right {
+.nut-range-button-wrapper-left {
+ width: 24px;
+ height: 24px;
+}
+.nut-range-button-wrapper, .nut-range-button-wrapper-right {
touch-action: none;
position: absolute;
top: 50%;
- right: 0;
- transform: translate3d(50%, -50%, 0);
+ left: 100%;
cursor: grab;
outline: none;
}
-.nut-range-container .nut-range-button-wrapper-left {
+.nut-range-button-wrapper-left {
position: absolute;
top: 50%;
left: 0;
- transform: translate3d(-50%, -50%, 0);
cursor: grab;
outline: none;
touch-action: none;
}
-.nut-range-container .nut-range-button .number {
- width: 100%;
- height: 100%;
+.nut-range-button-number {
+ position: relative;
+ width: 200%;
+ height: 24px;
+ line-height: 14px;
+ padding: 5px 0;
+ left: 50%;
display: flex;
align-items: center;
justify-content: center;
user-select: none;
font-size: 12px;
- color: #1A1A1A;
- transform: translate3d(0, -100%, 0);
+ color: #1a1a1a;
+ text-align: center;
+ vertical-align: center;
+ box-sizing: border-box;
}
-.nut-range-container .nut-range-disabled {
+.nut-range-disabled {
cursor: not-allowed;
opacity: 0.54;
}
-.nut-range-container .nut-range-disabled .nut-range-button-wrapper,
-.nut-range-container .nut-range-disabled .nut-range-button-wrapper-left,
-.nut-range-container .nut-range-disabled .nut-range-button-wrapper-right {
+.nut-range-disabled .nut-range-button-wrapper,
+.nut-range-disabled .nut-range-button-wrapper-left,
+.nut-range-disabled .nut-range-button-wrapper-right {
cursor: not-allowed;
}
-.nut-range-container .nut-range-mark {
+.nut-range-mark {
position: absolute;
width: 100%;
+ height: 14px;
overflow: visible;
top: 50%;
- font-size: 12px;
- padding-top: 14px;
}
-.nut-range-container .nut-range-mark-text {
+.nut-range-mark-text-wrapper {
position: absolute;
+ height: 100%;
+ top: 14px;
display: inline-block;
+ transform: translateX(-10px);
+}
+.nut-range-mark-text {
+ position: absolute;
line-height: 16px;
+ font-size: 12px;
color: #999;
text-align: center;
word-break: keep-all;
user-select: none;
- transform: translateX(-10px);
}
-.nut-range-container .nut-range-tick {
+.nut-range-tick {
position: absolute;
top: -20px;
width: 11px;
height: 11px;
left: 0px;
- border-radius: 50%;
- background: #FFEBF1;
+ border-radius: 6px;
+ background: #ffebf1;
}
-.nut-range-container .nut-range-tick.active {
- background: #FF0F23;
+.nut-range-tick-active {
+ background: #ff0f23;
}
-.nut-range-container-vertical {
+
+.nut-range-vertical-container {
height: 100%;
flex-direction: column;
padding: 0px 15px;
}
-.nut-range-container-vertical .nut-range {
+
+.nut-range-vertical {
width: 4px;
- height: 100%;
+ margin: 15px 0px;
}
-.nut-range-container-vertical .nut-range-button-wrapper, .nut-range-container-vertical .nut-range-button-wrapper-right {
+.nut-range-vertical-button-wrapper, .nut-range-vertical-button-wrapper-right {
position: absolute;
top: initial;
- bottom: 0px;
+ top: 100%;
left: 50%;
right: initial;
- transform: translate3d(-50%, 50%, 0);
}
-.nut-range-container-vertical .nut-range-button-wrapper-left {
+.nut-range-vertical-button-wrapper-left {
top: 0px;
left: 50%;
right: initial;
- transform: translate3d(-50%, -50%, 0);
}
-.nut-range-container-vertical .nut-range .number {
- transform: translate3d(100%, 0, 0);
-}
-.nut-range-container-vertical .nut-range-vertical {
- margin: 15px 0px;
+.nut-range-vertical-button-number {
+ left: 0px;
+ top: 50%;
}
-.nut-range-container-vertical .nut-range-mark {
+.nut-range-vertical-mark {
position: absolute;
- width: 100%;
+ width: 36px;
+ height: 100%;
+ top: initial;
right: 50%;
overflow: visible;
font-size: 12px;
- height: 100%;
- top: initial;
- width: 36px;
padding: 0px;
}
-.nut-range-container-vertical .nut-range-mark-text {
- width: 20px;
+.nut-range-vertical-mark-hm {
+ left: -34px;
+}
+.nut-range-vertical-mark-text-wrapper {
+ height: 16px;
position: absolute;
display: inline-block;
+ user-select: none;
+ transform: translateY(-11px);
+}
+.nut-range-vertical-mark-text {
+ height: 100%;
line-height: 16px;
color: #999;
text-align: center;
word-break: keep-all;
- user-select: none;
- transform: translateY(-11px);
}
-.nut-range-container-vertical .nut-range-tick {
+.nut-range-vertical-tick {
position: absolute;
- top: 0px;
- left: 30px;
- width: 11px;
- height: 11px;
- border-radius: 50%;
- background: #FFEBF1;
+ top: 2px;
+ left: 31px;
+ width: 10px;
+ height: 10px;
+ border-radius: 5px;
+ background: #ffebf1;
}
-.nut-range-container-vertical .nut-range-tick.active {
- background: #FF0F23;
+.nut-range-vertical-tick-active {
+ background: #ff0f23;
}
-[dir=rtl] .nut-range-container-vertical .nut-range-button-wrapper, [dir=rtl] .nut-range-container-vertical .nut-range-button-wrapper-right,
-.nut-rtl .nut-range-container-vertical .nut-range-button-wrapper,
-.nut-rtl .nut-range-container-vertical .nut-range-button-wrapper-right {
- right: 50%;
+[dir=rtl] .nut-range-button-wrapper, [dir=rtl] .nut-range-button-wrapper-right,
+.rtl-nut-range-button-wrapper,
+.rtl-nut-range-button-wrapper-right {
+ left: 0;
+ right: initial;
+}
+[dir=rtl] .nut-range-button-wrapper-left,
+.rtl-nut-range-button-wrapper-left {
+ right: 0;
left: initial;
- transform: translate3d(50%, 50%, 0);
}
-[dir=rtl] .nut-range-container-vertical .nut-range-button-wrapper-left,
-.nut-rtl .nut-range-container-vertical .nut-range-button-wrapper-left {
+[dir=rtl] .nut-range-tick,
+.rtl-nut-range-tick {
+ right: 0px;
+ left: initial;
+}
+[dir=rtl] .nut-range-mark-text,
+.rtl-nut-range-mark-text {
+ transform: translateX(10px);
+}
+[dir=rtl] .nut-range-vertical-button-wrapper, [dir=rtl] .nut-range-vertical-button-wrapper-right,
+.rtl-nut-range-vertical-button-wrapper,
+.rtl-nut-range-vertical-button-wrapper-right {
right: 50%;
left: initial;
- transform: translate3d(50%, -50%, 0);
}
-[dir=rtl] .nut-range-container-vertical .nut-range .number,
-.nut-rtl .nut-range-container-vertical .nut-range .number {
- transform: translate3d(-100%, 0, 0);
+[dir=rtl] .nut-range-vertical-button-wrapper-left,
+.rtl-nut-range-vertical-button-wrapper-left {
+ right: 50%;
+ left: initial;
}
-[dir=rtl] .nut-range-container-vertical .nut-range-mark,
-.nut-rtl .nut-range-container-vertical .nut-range-mark {
+[dir=rtl] .nut-range-vertical-mark,
+.rtl-nut-range-vertical-mark {
right: auto;
left: 50%;
}
-[dir=rtl] .nut-range-container-vertical .nut-range-tick,
-.nut-rtl .nut-range-container-vertical .nut-range-tick {
+[dir=rtl] .nut-range-vertical-tick,
+.rtl-nut-range-vertical-tick {
left: auto;
right: 30px;
margin-left: 0;
margin-right: 0px;
}
-[dir=rtl] .nut-range-container-vertical .nut-range-mark-text,
-.nut-rtl .nut-range-container-vertical .nut-range-mark-text {
+[dir=rtl] .nut-range-vertical-mark-text-wrapper,
+.rtl-nut-range-vertical-mark-text-wrapper {
transform: translateY(-11px);
-}
-
-[dir=rtl] .nut-range-button-wrapper, [dir=rtl] .nut-range-button-wrapper-right,
-.nut-rtl .nut-range-button-wrapper,
-.nut-rtl .nut-range-button-wrapper-right {
- left: 0;
- right: initial;
- transform: translate3d(-50%, -50%, 0);
-}
-[dir=rtl] .nut-range-button-wrapper-left,
-.nut-rtl .nut-range-button-wrapper-left {
- right: 0;
- left: initial;
- transform: translate3d(50%, -50%, 0);
-}
-[dir=rtl] .nut-range-tick,
-.nut-rtl .nut-range-tick {
- right: 0px;
- left: initial;
-}
-[dir=rtl] .nut-range-mark-text,
-.nut-rtl .nut-range-mark-text {
- transform: translateX(10px);
}
\ No newline at end of file
diff --git a/src/packages/range/range.scss b/src/packages/range/range.scss
index a338087494..d63484a13b 100644
--- a/src/packages/range/range.scss
+++ b/src/packages/range/range.scss
@@ -1,266 +1,263 @@
.nut-range-container {
display: flex;
+ flex-direction: row;
position: relative;
width: 100%;
height: $range-height;
align-items: center;
+ justify-content: space-between;
- .min,
- .max {
+ &-native {
+ height: auto;
+ }
+}
+
+.nut-range {
+ display: block;
+ position: relative;
+ // width: 100%;
+ height: $range-height;
+ margin: 0 $range-margin;
+ background-color: $range-inactive-color;
+ border-radius: 2px;
+ flex: 1;
+ cursor: pointer;
+
+ &::before {
+ position: absolute;
+ inset-block: -8px;
+ inset-inline: 0;
+ content: '';
+ }
+
+ &-min,
+ &-max {
font-size: $font-size-small;
color: $range-color;
user-select: none;
}
- .nut-range {
+ &-bar {
display: block;
position: relative;
width: 100%;
- height: $range-height;
- margin: 0 $range-margin;
- background-color: $range-inactive-color;
+ height: 100%;
+ background: $range-active-color;
border-radius: 2px;
- cursor: pointer;
-
- &::before {
- position: absolute;
- inset-block: -8px;
- inset-inline: 0;
- content: '';
- }
+ transition: all 0.2s;
+ }
- &-bar {
- display: block;
- position: relative;
- width: 100%;
- height: 100%;
- background: $range-active-color;
- border-radius: inherit;
- transition: all 0.2s;
- }
+ &-button {
+ position: absolute;
+ display: flex;
+ width: $range-button-width;
+ height: $range-button-height;
+ background: $range-button-background;
+ border-radius: 50%;
+ box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15);
+ border: $range-button-border;
+ outline: none;
+ align-items: center;
+ top: 50%;
+ left: 50%;
- &-button {
- display: block;
+ &-wrapper,
+ &-wrapper-right,
+ &-wrapper-left {
width: $range-button-width;
height: $range-button-height;
- background: $range-button-background;
- border-radius: 50%;
- box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.15);
- border: $range-button-border;
- outline: none;
-
- &-wrapper,
- &-wrapper-right {
- touch-action: none;
- position: absolute;
- top: 50%;
- right: 0;
- transform: translate3d(50%, -50%, 0);
- cursor: grab;
- outline: none;
- }
-
- &-wrapper-left {
- position: absolute;
- top: 50%;
- left: 0;
- transform: translate3d(-50%, -50%, 0);
- cursor: grab;
- outline: none;
- touch-action: none;
- }
-
- .number {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- user-select: none;
- font-size: $font-size-small;
- color: $range-color;
- transform: translate3d(0, -100%, 0);
- }
}
- &-disabled {
- cursor: not-allowed;
- opacity: 0.54;
-
- .nut-range-button-wrapper,
- .nut-range-button-wrapper-left,
- .nut-range-button-wrapper-right {
- cursor: not-allowed;
- }
+ &-wrapper,
+ &-wrapper-right {
+ touch-action: none;
+ position: absolute;
+ top: 50%;
+ left: 100%;
+ // right: 0;
+ // transform: translate3d(-50%, -50%, 0);
+ cursor: grab;
+ outline: none;
}
- &-mark {
+ &-wrapper-left {
position: absolute;
- width: 100%;
- overflow: visible;
top: 50%;
- font-size: 12px;
- padding-top: 14px;
+ left: 0;
+ // transform: translate3d(-50%, -50%, 0);
+ cursor: grab;
+ outline: none;
+ touch-action: none;
}
- &-mark-text {
- position: absolute;
- display: inline-block;
- line-height: 16px;
- color: #999;
- text-align: center;
- word-break: keep-all;
+ &-number {
+ position: relative;
+ width: 200%;
+ height: 24px;
+ line-height: 14px;
+ padding: 5px 0;
+ left: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
user-select: none;
- transform: translateX(-10px);
+ font-size: $font-size-small;
+ color: $range-color;
+ text-align: center;
+ vertical-align: center;
+ box-sizing: border-box;
+ // transform: translate3d(0, -100%, 0);
}
+ }
- &-tick {
- position: absolute;
- top: -20px;
- width: 11px;
- height: 11px;
- left: 0px;
- border-radius: 50%;
- background: $range-inactive-color;
+ &-disabled {
+ cursor: not-allowed;
+ // 鸿蒙端在外层设置的透明度会分发到所有子图层上,导致样式与其他端不一致
+ opacity: 0.54;
- &.active {
- background: $range-active-color;
- }
+ .nut-range-button-wrapper,
+ .nut-range-button-wrapper-left,
+ .nut-range-button-wrapper-right {
+ cursor: not-allowed;
}
}
- &-vertical {
+ &-mark {
+ position: absolute;
+ width: 100%;
+ height: 14px;
+ overflow: visible;
+ top: 50%;
+ }
+
+ &-mark-text-wrapper {
+ position: absolute;
height: 100%;
- flex-direction: column;
- padding: 0px 15px;
-
- .nut-range {
- width: $range-height;
- height: 100%;
-
- &-button {
- &-wrapper,
- &-wrapper-right {
- position: absolute;
- top: initial;
- bottom: 0px;
- left: 50%;
- right: initial;
- transform: translate3d(-50%, 50%, 0);
- }
-
- &-wrapper-left {
- top: 0px;
- left: 50%;
- right: initial;
- transform: translate3d(-50%, -50%, 0);
- }
- }
+ top: 14px;
+ display: inline-block;
+ transform: translateX(-10px);
+ }
- .number {
- transform: translate3d(100%, 0, 0);
- }
+ &-mark-text {
+ position: absolute;
+ line-height: 16px;
+ font-size: 12px;
+ color: #999;
+ text-align: center;
+ word-break: keep-all;
+ user-select: none;
+ }
- &-vertical {
- margin: $range-margin 0px;
- }
+ &-tick {
+ position: absolute;
+ top: -20px;
+ width: 11px;
+ height: 11px;
+ left: 0px;
+ border-radius: 6px;
+ background: $range-inactive-color;
+
+ &-active {
+ background: $range-active-color;
+ }
+ }
+}
- &-mark {
- position: absolute;
- width: 100%;
- right: 50%;
- overflow: visible;
- font-size: 12px;
- height: 100%;
- top: initial;
- width: 36px;
- padding: 0px;
- }
+.nut-range-vertical-container {
+ height: 100%;
+ flex-direction: column;
+ padding: 0px 15px;
+}
- &-mark-text {
- width: 20px;
- position: absolute;
- display: inline-block;
- line-height: 16px;
- color: #999;
- text-align: center;
- word-break: keep-all;
- user-select: none;
- transform: translateY(-11px);
- }
+.nut-range-vertical {
+ width: $range-height;
+ margin: $range-margin 0px;
- &-tick {
- position: absolute;
- top: 0px;
- left: 30px;
- width: 11px;
- height: 11px;
- border-radius: 50%;
- background: $range-inactive-color;
-
- &.active {
- background: $range-active-color;
- }
- }
+ &-button {
+ &-wrapper,
+ &-wrapper-right {
+ position: absolute;
+ top: initial;
+ top: 100%;
+ left: 50%;
+ right: initial;
+ // transform: translate3d(-50%, -50%, 0);
+ }
+
+ &-wrapper-left {
+ top: 0px;
+ left: 50%;
+ right: initial;
+ // transform: translate3d(-50%, -50%, 0);
+ }
+
+ &-number {
+ left: 0px;
+ top: 50%;
+ // transform: translate3d(100%, 0, 0);
}
}
-}
-[dir='rtl'] .nut-range-container,
-.nut-rtl .nut-range-container {
- &-vertical {
- .nut-range {
- &-button {
- &-wrapper,
- &-wrapper-right {
- right: 50%;
- left: initial;
- transform: translate3d(50%, 50%, 0);
- }
-
- &-wrapper-left {
- right: 50%;
- left: initial;
- transform: translate3d(50%, -50%, 0);
- }
- }
+ &-mark {
+ position: absolute;
+ width: 36px;
+ height: 100%;
+ top: initial;
+ right: 50%;
+ overflow: visible;
+ font-size: 12px;
+ padding: 0px;
+ }
- .number {
- transform: translate3d(-100%, 0, 0);
- }
+ &-mark-hm {
+ left: -34px;
+ }
- &-mark {
- right: auto;
- left: 50%;
- }
+ &-mark-text-wrapper {
+ // width: 20px;
+ height: 16px;
+ position: absolute;
+ display: inline-block;
+ user-select: none;
+ transform: translateY(-11px);
+ }
- &-tick {
- left: auto;
- right: 30px;
- margin-left: 0;
- margin-right: -0px;
- }
+ &-mark-text {
+ height: 100%;
+ line-height: 16px;
+ color: #999;
+ text-align: center;
+ word-break: keep-all;
+ }
- &-mark-text {
- transform: translateY(-11px);
- }
+ &-tick {
+ position: absolute;
+ top: 2px;
+ left: 31px;
+ width: 10px;
+ height: 10px;
+ border-radius: 5px;
+ background: $range-inactive-color;
+
+ &-active {
+ background: $range-active-color;
}
}
}
[dir='rtl'] .nut-range,
-.nut-rtl .nut-range {
+.rtl-nut-range {
&-button {
&-wrapper,
&-wrapper-right {
left: 0;
right: initial;
- transform: translate3d(-50%, -50%, 0);
+ // transform: translate3d(-50%, -50%, 0);
}
&-wrapper-left {
right: 0;
left: initial;
- transform: translate3d(50%, -50%, 0);
+ // transform: translate3d(50%, -50%, 0);
}
}
@@ -272,4 +269,41 @@
&-mark-text {
transform: translateX(10px);
}
+
+ &-vertical {
+ &-button {
+ &-wrapper,
+ &-wrapper-right {
+ right: 50%;
+ left: initial;
+ // transform: translate3d(50%, 50%, 0);
+ }
+
+ &-wrapper-left {
+ right: 50%;
+ left: initial;
+ // transform: translate3d(50%, -50%, 0);
+ }
+
+ &-number {
+ // transform: translate3d(-100%, 0, 0);
+ }
+ }
+
+ &-mark {
+ right: auto;
+ left: 50%;
+ }
+
+ &-tick {
+ left: auto;
+ right: 30px;
+ margin-left: 0;
+ margin-right: -0px;
+ }
+
+ &-mark-text-wrapper {
+ transform: translateY(-11px);
+ }
+ }
}
diff --git a/src/packages/range/range.taro.tsx b/src/packages/range/range.taro.tsx
index f5186f4ad0..7d5ef81324 100644
--- a/src/packages/range/range.taro.tsx
+++ b/src/packages/range/range.taro.tsx
@@ -5,15 +5,18 @@ import React, {
useRef,
useCallback,
ReactNode,
+ useMemo,
} from 'react'
+import { pxTransform } from '@tarojs/taro'
import classNames from 'classnames'
-import { View } from '@tarojs/components'
+import { View, Text } from '@tarojs/components'
import { useTouch } from '@/utils/use-touch'
import { BasicComponent, ComponentDefaults } from '@/utils/typings'
import { usePropsValue } from '@/utils/use-props-value'
import { getRectByTaro } from '@/utils/get-rect-by-taro'
import { RangeMark, RangeValue } from './types'
import { useRtl } from '../configprovider/index.taro'
+import { harmony, harmonyAndRn, rn } from '@/utils/platform-taro'
export interface RangeProps extends BasicComponent {
value: RangeValue
@@ -44,6 +47,23 @@ const defaultProps = {
marks: {},
} as RangeProps
+const isRn = rn()
+const isHm = harmony()
+const isNative = harmonyAndRn()
+const classPrefix = 'nut-range'
+const verticalClassPrefix = `${classPrefix}-vertical`
+
+const isSameValue = (newValue: RangeValue, oldValue: RangeValue) => {
+ return JSON.stringify(newValue) === JSON.stringify(oldValue)
+}
+
+const handleOverlap = (value: number[]) => {
+ if (value[0] > value[1]) {
+ return value.slice(0).reverse()
+ }
+ return value
+}
+
export const Range: FunctionComponent<
Partial &
Omit<
@@ -54,6 +74,7 @@ export const Range: FunctionComponent<
const rtl = useRtl()
const {
className,
+ style,
range,
disabled,
button,
@@ -72,7 +93,10 @@ export const Range: FunctionComponent<
defaultValue,
} = { ...defaultProps, ...props }
- const classPrefix = 'nut-range'
+ const rtlClassPrefix = useMemo(
+ () => `rtl-${vertical ? verticalClassPrefix : classPrefix}`,
+ [vertical]
+ )
const [buttonIndex, setButtonIndex] = useState(0)
const [dragStatus, setDragStatus] = useState('start' || 'draging' || '')
const touch = useTouch()
@@ -80,6 +104,7 @@ export const Range: FunctionComponent<
const [marksList, setMarksList] = useState([])
const [startValue, setStartValue] = useState(0)
+ const scope = useMemo(() => max - min, [max, min])
const handleChange = (value: RangeValue) => {
onChange && onChange(value)
@@ -91,7 +116,7 @@ export const Range: FunctionComponent<
onChange: handleChange,
})
- const [exactValue, setEaxctValue] = useState(
+ const [exactValue, setExactValue] = useState(
() => value || defaultValue || 0
)
const marksRef = useRef<{ [key: string]: any }>({})
@@ -116,28 +141,12 @@ export const Range: FunctionComponent<
setMarksList(list)
}
}
- }, [marks])
-
- const scope = () => {
- return max - min
- }
-
- const classes = classNames(classPrefix, {
- [`${classPrefix}-disabled`]: disabled,
- [`${classPrefix}-vertical`]: vertical,
- })
-
- const containerClasses = classNames(
- `${classPrefix}-container`,
- {
- [`${classPrefix}-container-vertical`]: vertical,
- },
- className
- )
+ }, [marks, max, min])
const markClassName = useCallback(
(mark: any) => {
const classPrefix = 'nut-range-mark'
+ const verticalClassPrefix = 'nut-range-vertical-mark'
let lowerBound = min
let upperBound = max
if (range && Array.isArray(current)) {
@@ -147,35 +156,50 @@ export const Range: FunctionComponent<
upperBound = current as number
}
const isActive = mark <= upperBound && mark >= lowerBound
- return [
- `${classPrefix}-text`,
- `${isActive ? `${classPrefix}-text-active` : ''}`,
- ].join(' ')
+ const classNames = [
+ `${classPrefix}-text-wrapper`,
+ `${isActive ? `${classPrefix}-text-wrapper-active` : ''}`,
+ ]
+
+ if (vertical) {
+ classNames.push(`${verticalClassPrefix}-text-wrapper`)
+ isActive &&
+ classNames.push(`${verticalClassPrefix}-text-wrapper-active`)
+ }
+
+ if (rtl) {
+ classNames.push(`${rtlClassPrefix}-mark-text-wrapper`)
+ }
+
+ return classNames.join(' ')
},
- [range, current, min, max]
+ [min, max, range, current, vertical, rtl, rtlClassPrefix]
)
- const isRange = (val: any) => {
- return !!range && Array.isArray(val)
- }
+ const isRange = useCallback(
+ (val: any) => {
+ return !!range && Array.isArray(val)
+ },
+ [range]
+ )
- const calcMainAxis = () => {
+ const calcMainAxis = useCallback(() => {
const modelVal = current as any
if (isRange(modelVal)) {
- return `${((modelVal[1] - modelVal[0]) * 100) / scope()}%`
+ return `${((modelVal[1] - modelVal[0]) * 100) / scope}%`
}
- return `${((modelVal - min) * 100) / scope()}%`
- }
+ return `${((modelVal - min) * 100) / scope}%`
+ }, [current, isRange, min, scope])
- const calcOffset = () => {
+ const calcOffset = useCallback(() => {
const modelVal = current as any
if (isRange(modelVal)) {
- return `${((modelVal[0] - min) * 100) / scope()}%`
+ return `${((modelVal[0] - min) * 100) / scope}%`
}
return `0%`
- }
+ }, [current, isRange, min, scope])
- const barStyle = () => {
+ const barStyle = useCallback(() => {
if (vertical) {
return {
height: calcMainAxis(),
@@ -189,238 +213,449 @@ export const Range: FunctionComponent<
[dir]: calcOffset(),
transition: dragStatus ? 'none' : undefined,
}
- }
+ }, [calcMainAxis, calcOffset, dragStatus, rtl, vertical])
- const marksStyle = (mark: any) => {
- const dir = rtl ? 'right' : 'left'
- let style: any = {
- [dir]: `${((mark - min) / scope()) * 100}%`,
- }
- if (vertical) {
- style = {
- top: `${((mark - min) / scope()) * 100}%`,
+ const marksStyle = useCallback(
+ (mark: any) => {
+ const dir = rtl ? 'right' : 'left'
+ let style: any = {
+ [dir]: `${((mark - min) / scope) * 100}%`,
}
- }
- return style
- }
+ if (vertical) {
+ style = {
+ top: `${((mark - min) / scope) * 100}%`,
+ }
+ }
+ return style
+ },
+ [min, rtl, scope, vertical]
+ )
- const tickClass = (mark: any) => {
- if (range && Array.isArray(current)) {
- return mark <= current[1] && mark >= current[0]
- }
- return mark <= current
- }
+ const tickClass = useCallback(
+ (mark: any) => {
+ if (range && Array.isArray(current)) {
+ return mark <= current[1] && mark >= current[0]
+ }
+ return mark <= current
+ },
+ [current, range]
+ )
- const format = (value: number) => {
- value = Math.max(+min, Math.min(value, +max))
- return Math.round(value / +step) * +step
- }
+ const format = useCallback(
+ (value: number) => {
+ value = Math.max(+min, Math.min(value, +max))
+ return Math.round(value / +step) * +step
+ },
+ [max, min, step]
+ )
- const isSameValue = (newValue: RangeValue, oldValue: RangeValue) => {
- return JSON.stringify(newValue) === JSON.stringify(oldValue)
- }
+ const updateValue = useCallback(
+ (value: any, end?: boolean) => {
+ if (isRange(value)) {
+ value = handleOverlap(value).map(format)
+ } else {
+ value = format(value)
+ }
+ if (!isSameValue(value, current)) {
+ setCurrent(value)
+ }
+ end && onEnd && onEnd(value)
+ },
+ [current, format, isRange, onEnd, setCurrent]
+ )
- const handleOverlap = (value: number[]) => {
- if (value[0] > value[1]) {
- return value.slice(0).reverse()
- }
- return value
- }
- const updateValue = (value: any, end?: boolean) => {
- if (isRange(value)) {
- value = handleOverlap(value).map(format)
- } else {
- value = format(value)
- }
- if (!isSameValue(value, current)) {
- setCurrent(value)
- }
- end && onEnd && onEnd(value)
- }
+ const click = useCallback(
+ async (event: any) => {
+ if (disabled || !root.current) {
+ return
+ }
+ setDragStatus('')
+ const rect = await getRectByTaro(root.current)
+ let x =
+ typeof event.detail?.x !== 'undefined' ? event.detail.x : event.clientX
+ if (isHm) x = parseFloat(pxTransform(event.windowX))
+ let delta = x - rect.left
+ let total = rect.width
+
+ if (vertical) {
+ let y =
+ typeof event.detail?.y !== 'undefined'
+ ? event.detail.y
+ : event.clientY
+ if (isHm) y = parseFloat(pxTransform(event.windowY))
+ delta = y - rect.top
+ total = rect.height
+ }
+ const value = min + (delta / total) * scope
+ setExactValue(current)
+ if (isRange(current)) {
+ const [left, right] = current as any
+ const middle = (left + right) / 2
+ if (value <= middle) {
+ updateValue([value, right], true)
+ } else {
+ updateValue([left, value], true)
+ }
+ } else {
+ updateValue(value, true)
+ }
+ },
+ [current, disabled, isRange, min, scope, updateValue, vertical]
+ )
- const click = async (event: any) => {
- if (disabled || !root.current) {
- return
- }
- setDragStatus('')
- const rect = await getRectByTaro(root.current)
- let delta = (event.detail.x ? event.detail.x : event.clientX) - rect.left
- let total = rect.width
- if (vertical) {
- delta = (event.detail.y ? event.detail.y : event.clientY) - rect.top
- total = rect.height
- }
- const value = min + (delta / total) * scope()
- setEaxctValue(current)
- if (isRange(current)) {
- const [left, right] = current as any
- const middle = (left + right) / 2
- if (value <= middle) {
- updateValue([value, right], true)
+ const onTouchStart = useCallback(
+ (event: any) => {
+ if (disabled) {
+ return
+ }
+ touch.start(event)
+ setExactValue(current)
+ if (isRange(current)) {
+ setStartValue((current as number[]).map(format))
} else {
- updateValue([left, value], true)
+ setStartValue(format(current as number))
}
- } else {
- updateValue(value, true)
- }
- }
- const onTouchStart = (event: any) => {
+ setDragStatus('start')
+ },
+ [current, disabled, format, isRange, touch]
+ )
+
+ const onTouchMove = useCallback(
+ async (event: any) => {
+ // @TODO RN、鸿蒙端垂直滑动时,页面会一同滑动,待解决
+ if (disabled || !root.current) {
+ return
+ }
+ if (dragStatus === 'start') {
+ onStart && onStart()
+ }
+
+ touch.move(isRn ? event.nativeEvent : event)
+ // console.log(JSON.stringify(event.touches[0]))
+
+ setDragStatus('draging')
+
+ const rect = await getRectByTaro(root.current)
+ if (!rect) return
+ let delta = isHm
+ ? parseFloat(pxTransform(touch.deltaX.current))
+ : touch.deltaX.current
+ let total = rect.width
+ // console.log(pxTransform(delta), total)
+ let diff = (delta / total) * scope
+ diff = rtl ? -diff : diff
+ if (vertical) {
+ delta = isHm
+ ? parseFloat(pxTransform(touch.deltaY.current))
+ : touch.deltaY.current
+ total = rect.height
+ diff = (delta / total) * scope
+ }
+
+ let newValue
+ if (isRange(startValue)) {
+ newValue = (exactValue as number[]).slice()
+ newValue[buttonIndex] = startValue[buttonIndex] + diff
+ } else {
+ newValue = startValue + diff
+ }
+ setExactValue(newValue)
+ updateValue(newValue)
+ },
+ [
+ buttonIndex,
+ disabled,
+ dragStatus,
+ exactValue,
+ isRange,
+ onStart,
+ rtl,
+ scope,
+ startValue,
+ touch,
+ updateValue,
+ vertical,
+ ]
+ )
+
+ const onTouchEnd = useCallback(() => {
if (disabled) {
return
}
- touch.start(event)
- setEaxctValue(current)
- if (isRange(current)) {
- setStartValue((current as number[]).map(format))
- } else {
- setStartValue(format(current as number))
+ if (dragStatus === 'draging') {
+ updateValue(current, true)
}
+ setDragStatus('')
+ }, [current, disabled, dragStatus, updateValue])
- setDragStatus('start')
- }
+ const curValue = useCallback(
+ (idx?: number) => {
+ const modelVal = current as any
+ const value = typeof idx === 'number' ? modelVal[idx] : modelVal
+ return value
+ },
+ [current]
+ )
- const onTouchMove = async (event: any) => {
- if (disabled || !root.current) {
- return
- }
- if (dragStatus === 'start') {
- onStart && onStart()
+ const buttonTransform = useMemo(() => {
+ const borderRadis = { borderRadius: pxTransform(13) }
+ const transform = {
+ transform: 'translate(-50%, -50%)',
}
- touch.move(event)
+ if (isRn) {
+ // @TODO 支持变量
+ return {
+ ...borderRadis,
+ transform: [{ translateX: pxTransform(-12) }],
+ }
+ }
+ if (isHm) {
+ return {
+ ...borderRadis,
+ ...transform,
+ }
+ }
+ return {
+ ...transform,
+ }
+ }, [])
+ const buttonNumberTransform = useMemo(() => {
+ if (isRn) {
+ // @TODO 支持变量
+ return [
+ { translateX: pxTransform(vertical ? 26 : -12) },
+ { translateY: pxTransform(vertical ? -12 : -26) },
+ ]
+ }
- setDragStatus('draging')
+ return vertical ? 'translate(100%, -50%)' : 'translate(-50%, -100%)'
+ }, [vertical])
- const rect = await getRectByTaro(root.current)
- if (!rect) return
- let delta = touch.deltaX.current
- let total = rect.width
- let diff = (delta / total) * scope()
- diff = rtl ? -diff : diff
- if (vertical) {
- delta = touch.deltaY.current
- total = rect.height
- diff = (delta / total) * scope()
- }
+ const renderButton = useCallback(
+ (index?: number) => {
+ return (
+
+ {button || (
+
+ {currentDescription !== null && (
+
+ {currentDescription
+ ? currentDescription(curValue(index))
+ : curValue(index)}
+
+ )}
+
+ )}
+
+ )
+ },
+ [
+ button,
+ buttonNumberTransform,
+ buttonTransform,
+ curValue,
+ currentDescription,
+ rtl,
+ rtlClassPrefix,
+ vertical,
+ ]
+ )
- let newValue
- if (isRange(startValue)) {
- newValue = (exactValue as number[]).slice()
- newValue[buttonIndex] = startValue[buttonIndex] + diff
- } else {
- newValue = startValue + diff
- }
- setEaxctValue(newValue)
- updateValue(newValue)
- }
+ const renderMarks = useCallback(() => {
+ if (marksList.length <= 0) return null
- const onTouchEnd = () => {
- if (disabled) {
- return
- }
- if (dragStatus === 'draging') {
- updateValue(current, true)
+ return (
+
+ {marksList.map((mark: any) => {
+ return (
+
+
+ {Array.isArray(marks) ? marksRef.current[mark] : marks[mark]}
+
+
+
+ )
+ })}
+
+ )
+ }, [
+ markClassName,
+ marks,
+ marksList,
+ marksStyle,
+ rtl,
+ rtlClassPrefix,
+ tickClass,
+ vertical,
+ ])
+
+ const wrapperTransform = useMemo(() => {
+ // @TODO 支持变量
+ const wrapperTransformRN = [
+ { translateX: pxTransform(vertical ? -12 : -13) },
+ { translateY: pxTransform(-12) },
+ ]
+ const wrapperTransform = 'translate(-50%, -50%)'
+
+ return isRn ? wrapperTransformRN : wrapperTransform
+ }, [vertical])
+ const rangeWrapperTransform = useMemo(() => {
+ if (isRn) {
+ // @TODO 支持变量
+ return [
+ {
+ translateX: pxTransform(-12),
+ },
+ {
+ translateY: pxTransform(-13),
+ },
+ ]
}
- setDragStatus('')
- }
- const curValue = (idx?: number) => {
- const modelVal = current as any
- const value = typeof idx === 'number' ? modelVal[idx] : modelVal
- return value
- }
+ return 'translate(-50%, -50%)'
+ }, [])
+
+ const renderButtonWrapper = useCallback(() => {
+ if (range)
+ return [0, 1].map((item, index) => {
+ const isLeft = index === 0
+ const suffix = isLeft ? 'left' : 'right'
+
+ return (
+ {
+ if (typeof index === 'number') {
+ // 实时更新当前拖动的按钮索引
+ setButtonIndex(index)
+ }
+ onTouchStart(e)
+ }}
+ onTouchMove={(e) => onTouchMove(e)}
+ onTouchEnd={onTouchEnd}
+ onTouchCancel={onTouchEnd}
+ onClick={(e) => !isRn && e.stopPropagation()}
+ >
+ {renderButton(index)}
+
+ )
+ })
- const renderButton = (index?: number) => {
return (
- <>
- {button || (
-
- {currentDescription !== null && (
-
- {currentDescription
- ? currentDescription(curValue(index))
- : curValue(index)}
-
- )}
-
- )}
- >
+ onTouchStart(e)}
+ onTouchMove={(e) => onTouchMove(e)}
+ onTouchEnd={onTouchEnd}
+ onTouchCancel={onTouchEnd}
+ onClick={(e) => !isRn && e.stopPropagation()}
+ >
+ {renderButton()}
+
)
- }
+ }, [
+ onTouchEnd,
+ onTouchMove,
+ onTouchStart,
+ range,
+ rangeWrapperTransform,
+ renderButton,
+ rtl,
+ rtlClassPrefix,
+ vertical,
+ wrapperTransform,
+ ])
return (
-
+
{minDescription !== null && (
- {minDescription || min}
+ {minDescription || min}
)}
- click(e)}>
- {marksList.length > 0 && (
-
- {marksList.map((mark: any) => {
- return (
-
- {Array.isArray(marks) ? marksRef.current[mark] : marks[mark]}
-
-
- )
- })}
-
- )}
-
-
- {range ? (
- [0, 1].map((item, index) => {
- return (
- {
- if (typeof index === 'number') {
- // 实时更新当前拖动的按钮索引
- setButtonIndex(index)
- }
- onTouchStart(e)
- }}
- onTouchMove={(e) => onTouchMove(e)}
- onTouchEnd={onTouchEnd}
- onTouchCancel={onTouchEnd}
- onClick={(e) => e.stopPropagation()}
- >
- {renderButton(index)}
-
- )
- })
- ) : (
- onTouchStart(e)}
- onTouchMove={(e) => onTouchMove(e)}
- onTouchEnd={onTouchEnd}
- onTouchCancel={onTouchEnd}
- onClick={(e) => e.stopPropagation()}
- >
- {renderButton()}
-
- )}
-
-
+ click(e)}
+ >
+ {renderMarks()}
+
+
+ {renderButtonWrapper()}
+
+
{maxDescription !== null && (
- {maxDescription || max}
+ {maxDescription || max}
)}
-
+
)
}
diff --git a/src/packages/range/range.tsx b/src/packages/range/range.tsx
index 328a2d6dc6..a118ebd273 100644
--- a/src/packages/range/range.tsx
+++ b/src/packages/range/range.tsx
@@ -4,6 +4,7 @@ import React, {
useState,
useRef,
useCallback,
+ useMemo,
ReactNode,
} from 'react'
import type { TouchEvent } from 'react'
@@ -44,6 +45,20 @@ const defaultProps = {
marks: {},
} as RangeProps
+const classPrefix = 'nut-range'
+const verticalClassPrefix = `${classPrefix}-vertical`
+
+const isSameValue = (newValue: RangeValue, oldValue: RangeValue) => {
+ return JSON.stringify(newValue) === JSON.stringify(oldValue)
+}
+
+const handleOverlap = (value: number[]) => {
+ if (value[0] > value[1]) {
+ return value.slice(0).reverse()
+ }
+ return value
+}
+
export const Range: FunctionComponent<
Partial &
Omit<
@@ -54,6 +69,7 @@ export const Range: FunctionComponent<
const rtl = useRtl()
const {
className,
+ style,
range,
disabled,
button,
@@ -72,7 +88,10 @@ export const Range: FunctionComponent<
defaultValue,
} = { ...defaultProps, ...props }
- const classPrefix = 'nut-range'
+ const rtlClassPrefix = useMemo(
+ () => `rtl-${vertical ? verticalClassPrefix : classPrefix}`,
+ [vertical]
+ )
const [buttonIndex, setButtonIndex] = useState(0)
const [dragStatus, setDragStatus] = useState('start' || 'draging' || '')
const touch = useTouch()
@@ -80,6 +99,7 @@ export const Range: FunctionComponent<
const [marksList, setMarksList] = useState([])
const [startValue, setStartValue] = useState(0)
+ const scope = useMemo(() => max - min, [max, min])
const handleChange = (value: RangeValue) => {
onChange && onChange(value)
@@ -91,7 +111,7 @@ export const Range: FunctionComponent<
onChange: handleChange,
})
- const [exactValue, setEaxctValue] = useState(
+ const [exactValue, setExactValue] = useState(
() => value || defaultValue || 0
)
const marksRef = useRef<{ [key: string]: any }>({})
@@ -116,28 +136,12 @@ export const Range: FunctionComponent<
setMarksList(list)
}
}
- }, [marks])
-
- const scope = () => {
- return max - min
- }
-
- const classes = classNames(classPrefix, {
- [`${classPrefix}-disabled`]: disabled,
- [`${classPrefix}-vertical`]: vertical,
- })
-
- const containerClasses = classNames(
- `${classPrefix}-container`,
- {
- [`${classPrefix}-container-vertical`]: vertical,
- },
- className
- )
+ }, [marks, max, min])
const markClassName = useCallback(
(mark: any) => {
const classPrefix = 'nut-range-mark'
+ const verticalClassPrefix = 'nut-range-vertical-mark'
let lowerBound = min
let upperBound = max
if (range && Array.isArray(current)) {
@@ -147,35 +151,50 @@ export const Range: FunctionComponent<
upperBound = current as number
}
const isActive = mark <= upperBound && mark >= lowerBound
- return [
- `${classPrefix}-text`,
- `${isActive ? `${classPrefix}-text-active` : ''}`,
- ].join(' ')
+ const classNames = [
+ `${classPrefix}-text-wrapper`,
+ `${isActive ? `${classPrefix}-text-wrapper-active` : ''}`,
+ ]
+
+ if (vertical) {
+ classNames.push(`${verticalClassPrefix}-text-wrapper`)
+ isActive &&
+ classNames.push(`${verticalClassPrefix}-text-active-wrapper`)
+ }
+
+ if (rtl) {
+ classNames.push(`${rtlClassPrefix}-mark-text-wrapper`)
+ }
+
+ return classNames.join(' ')
},
- [range, current, min, max]
+ [min, max, range, current, vertical, rtl, rtlClassPrefix]
)
- const isRange = (val: any) => {
- return !!range && Array.isArray(val)
- }
+ const isRange = useCallback(
+ (val: any) => {
+ return !!range && Array.isArray(val)
+ },
+ [range]
+ )
- const calcMainAxis = () => {
+ const calcMainAxis = useCallback(() => {
const modelVal = current as any
if (isRange(modelVal)) {
- return `${((modelVal[1] - modelVal[0]) * 100) / scope()}%`
+ return `${((modelVal[1] - modelVal[0]) * 100) / scope}%`
}
- return `${((modelVal - min) * 100) / scope()}%`
- }
+ return `${((modelVal - min) * 100) / scope}%`
+ }, [current, isRange, min, scope])
- const calcOffset = () => {
+ const calcOffset = useCallback(() => {
const modelVal = current as any
if (isRange(modelVal)) {
- return `${((modelVal[0] - min) * 100) / scope()}%`
+ return `${((modelVal[0] - min) * 100) / scope}%`
}
return `0%`
- }
+ }, [current, isRange, min, scope])
- const barStyle = () => {
+ const barStyle = useCallback(() => {
if (vertical) {
return {
height: calcMainAxis(),
@@ -189,129 +208,153 @@ export const Range: FunctionComponent<
[dir]: calcOffset(),
transition: dragStatus ? 'none' : undefined,
}
- }
+ }, [calcMainAxis, calcOffset, dragStatus, rtl, vertical])
- const marksStyle = (mark: any) => {
- const dir = rtl ? 'right' : 'left'
- let style: any = {
- [dir]: `${((mark - min) / scope()) * 100}%`,
- }
- if (vertical) {
- style = {
- top: `${((mark - min) / scope()) * 100}%`,
+ const marksStyle = useCallback(
+ (mark: any) => {
+ const dir = rtl ? 'right' : 'left'
+ let style: any = {
+ [dir]: `${((mark - min) / scope) * 100}%`,
}
- }
- return style
- }
-
- const tickClass = (mark: any) => {
- if (range && Array.isArray(current)) {
- return mark <= current[1] && mark >= current[0]
- }
- return mark <= current
- }
+ if (vertical) {
+ style = {
+ top: `${((mark - min) / scope) * 100}%`,
+ }
+ }
+ return style
+ },
+ [min, rtl, scope, vertical]
+ )
- const format = (value: number) => {
- value = Math.max(+min, Math.min(value, +max))
- return Math.round(value / +step) * +step
- }
+ const tickClass = useCallback(
+ (mark: any) => {
+ if (range && Array.isArray(current)) {
+ return mark <= current[1] && mark >= current[0]
+ }
+ return mark <= current
+ },
+ [current, range]
+ )
- const isSameValue = (newValue: RangeValue, oldValue: RangeValue) => {
- return JSON.stringify(newValue) === JSON.stringify(oldValue)
- }
+ const format = useCallback(
+ (value: number) => {
+ value = Math.max(+min, Math.min(value, +max))
+ return Math.round(value / +step) * +step
+ },
+ [max, min, step]
+ )
- const handleOverlap = (value: number[]) => {
- if (value[0] > value[1]) {
- return value.slice(0).reverse()
- }
- return value
- }
- const updateValue = (value: any, end?: boolean) => {
- if (isRange(value)) {
- value = handleOverlap(value).map(format)
- } else {
- value = format(value)
- }
- if (!isSameValue(value, current)) {
- setCurrent(value)
- }
- end && onEnd && onEnd(value)
- }
+ const updateValue = useCallback(
+ (value: any, end?: boolean) => {
+ if (isRange(value)) {
+ value = handleOverlap(value).map(format)
+ } else {
+ value = format(value)
+ }
+ if (!isSameValue(value, current)) {
+ setCurrent(value)
+ }
+ end && onEnd && onEnd(value)
+ },
+ [current, format, isRange, onEnd, setCurrent]
+ )
- const click = (event: any) => {
- if (disabled || !root.current) {
- return
- }
- setDragStatus('')
- const rect = getRect(root.current)
- let delta = event.clientX - rect.left
- let total = rect.width
- if (vertical) {
- delta = event.clientY - rect.top
- total = rect.height
- }
- const value = min + (delta / total) * scope()
- setEaxctValue(current)
- if (isRange(current)) {
- const [left, right] = current as any
- const middle = (left + right) / 2
- if (value <= middle) {
- updateValue([value, right], true)
+ const click = useCallback(
+ (event: any) => {
+ if (disabled || !root.current) {
+ return
+ }
+ setDragStatus('')
+ const rect = getRect(root.current)
+ let delta = event.clientX - rect.left
+ let total = rect.width
+ if (vertical) {
+ delta = event.clientY - rect.top
+ total = rect.height
+ }
+ const value = min + (delta / total) * scope
+ setExactValue(current)
+ if (isRange(current)) {
+ const [left, right] = current as any
+ const middle = (left + right) / 2
+ if (value <= middle) {
+ updateValue([value, right], true)
+ } else {
+ updateValue([left, value], true)
+ }
} else {
- updateValue([left, value], true)
+ updateValue(value, true)
}
- } else {
- updateValue(value, true)
- }
- }
+ },
+ [current, disabled, isRange, min, scope, updateValue, vertical]
+ )
- const onTouchStart = (event: TouchEvent) => {
- if (disabled) {
- return
- }
- touch.start(event)
- setEaxctValue(current)
- if (isRange(current)) {
- setStartValue((current as number[]).map(format))
- } else {
- setStartValue(format(current as number))
- }
+ const onTouchStart = useCallback(
+ (event: any) => {
+ if (disabled) {
+ return
+ }
+ touch.start(event)
+ setExactValue(current)
+ if (isRange(current)) {
+ setStartValue((current as number[]).map(format))
+ } else {
+ setStartValue(format(current as number))
+ }
- setDragStatus('start')
- }
+ setDragStatus('start')
+ },
+ [current, disabled, format, isRange, touch]
+ )
- const onTouchMove = (event: TouchEvent) => {
- event.stopPropagation()
- if (disabled || !root.current) {
- return
- }
- if (dragStatus === 'start') {
- onStart && onStart()
- }
- touch.move(event)
- setDragStatus('draging')
- const rect = getRect(root.current)
- let delta = touch.deltaX.current
- let total = rect.width
- let diff = (delta / total) * scope()
- diff = rtl ? -diff : diff
- if (vertical) {
- delta = touch.deltaY.current
- total = rect.height
- diff = (delta / total) * scope()
- }
- let newValue
- if (isRange(startValue)) {
- newValue = (exactValue as number[]).slice()
- newValue[buttonIndex] = startValue[buttonIndex] + diff
- } else {
- newValue = startValue + diff
- }
- setEaxctValue(newValue)
- updateValue(newValue)
- }
+ const onTouchMove = useCallback(
+ (event: TouchEvent) => {
+ event.stopPropagation()
+ if (disabled || !root.current) {
+ return
+ }
+ if (dragStatus === 'start') {
+ onStart && onStart()
+ }
+ touch.move(event)
+ setDragStatus('draging')
+ const rect = getRect(root.current)
+ let delta = touch.deltaX.current
+ let total = rect.width
+ let diff = (delta / total) * scope
+ diff = rtl ? -diff : diff
+ if (vertical) {
+ delta = touch.deltaY.current
+ total = rect.height
+ diff = (delta / total) * scope
+ }
+ let newValue
+ if (isRange(startValue)) {
+ newValue = (exactValue as number[]).slice()
+ newValue[buttonIndex] = startValue[buttonIndex] + diff
+ } else {
+ newValue = startValue + diff
+ }
+ setExactValue(newValue)
+ updateValue(newValue)
+ },
+ [
+ buttonIndex,
+ disabled,
+ dragStatus,
+ exactValue,
+ isRange,
+ onStart,
+ rtl,
+ scope,
+ startValue,
+ touch,
+ updateValue,
+ vertical,
+ ]
+ )
- const onTouchEnd = () => {
+ const onTouchEnd = useCallback(() => {
if (disabled) {
return
}
@@ -319,101 +362,209 @@ export const Range: FunctionComponent<
updateValue(current, true)
}
setDragStatus('')
- }
+ }, [current, disabled, dragStatus, updateValue])
- const curValue = (idx?: number) => {
- const modelVal = current as any
- const value = typeof idx === 'number' ? modelVal[idx] : modelVal
- return value
- }
+ const curValue = useCallback(
+ (idx?: number) => {
+ const modelVal = current as any
+ const value = typeof idx === 'number' ? modelVal[idx] : modelVal
+ return value
+ },
+ [current]
+ )
+
+ const renderButton = useCallback(
+ (index?: number) => {
+ const buttonNumberTransform = vertical
+ ? 'translate(100%, -50%)'
+ : 'translate(-50%, -100%)'
+
+ return (
+ <>
+ {button || (
+
+ {currentDescription !== null && (
+
+ {currentDescription
+ ? currentDescription(curValue(index))
+ : curValue(index)}
+
+ )}
+
+ )}
+ >
+ )
+ },
+ [button, curValue, currentDescription, rtl, rtlClassPrefix, vertical]
+ )
+
+ const renderMarks = useCallback(() => {
+ if (marksList.length <= 0) return null
- const renderButton = (index?: number) => {
return (
- <>
- {button || (
-
- {currentDescription !== null && (
-
- {currentDescription
- ? currentDescription(curValue(index))
- : curValue(index)}
-
- )}
+
+ {marksList.map((mark: any) => {
+ return (
+
+
+ {Array.isArray(marks) ? marksRef.current[mark] : marks[mark]}
+
+
+
+ )
+ })}
+
+ )
+ }, [
+ markClassName,
+ marks,
+ marksList,
+ marksStyle,
+ rtl,
+ rtlClassPrefix,
+ tickClass,
+ vertical,
+ ])
+
+ const getWrapperTransform = useCallback(() => {
+ const wrapperTransform = 'translate(-50%, -50%)'
+
+ return wrapperTransform
+ }, [])
+
+ const renderButtonWrapper = useCallback(() => {
+ if (range)
+ return [0, 1].map((item, index) => {
+ const isLeft = index === 0
+ const suffix = isLeft ? 'left' : 'right'
+
+ const transform = 'translate(-50%, -50%)'
+
+ return (
+ {
+ if (typeof index === 'number') {
+ // 实时更新当前拖动的按钮索引
+ setButtonIndex(index)
+ }
+ onTouchStart(e)
+ }}
+ onTouchMove={(e) => onTouchMove(e)}
+ onTouchEnd={onTouchEnd}
+ onTouchCancel={onTouchEnd}
+ onClick={(e) => e.stopPropagation()}
+ >
+ {renderButton(index)}
- )}
- >
+ )
+ })
+
+ return (
+ onTouchStart(e)}
+ onTouchMove={(e) => onTouchMove(e)}
+ onTouchEnd={onTouchEnd}
+ onTouchCancel={onTouchEnd}
+ onClick={(e) => e.stopPropagation()}
+ >
+ {renderButton()}
+
)
- }
+ }, [
+ getWrapperTransform,
+ onTouchEnd,
+ onTouchMove,
+ onTouchStart,
+ range,
+ renderButton,
+ rtl,
+ rtlClassPrefix,
+ vertical,
+ ])
return (
-
+
{minDescription !== null && (
- {minDescription || min}
+ {minDescription || min}
)}
- click(e)}>
- {marksList.length > 0 && (
-
- {marksList.map((mark: any) => {
- return (
-
- {Array.isArray(marks) ? marksRef.current[mark] : marks[mark]}
-
-
- )
- })}
-
- )}
+ click(e)}
+ >
+ {renderMarks()}
-
- {range ? (
- [0, 1].map((item, index) => {
- return (
- {
- if (typeof index === 'number') {
- // 实时更新当前拖动的按钮索引
- setButtonIndex(index)
- }
- onTouchStart(e)
- }}
- onTouchMove={(e) => onTouchMove(e)}
- onTouchEnd={onTouchEnd}
- onTouchCancel={onTouchEnd}
- onClick={(e) => e.stopPropagation()}
- >
- {renderButton(index)}
-
- )
- })
- ) : (
- onTouchStart(e)}
- onTouchMove={(e) => onTouchMove(e)}
- onTouchEnd={onTouchEnd}
- onTouchCancel={onTouchEnd}
- onClick={(e) => e.stopPropagation()}
- >
- {renderButton()}
-
- )}
+
+ {renderButtonWrapper()}
{maxDescription !== null && (
- {maxDescription || max}
+ {maxDescription || max}
)}
)
diff --git a/src/utils/use-touch.ts b/src/utils/use-touch.ts
index 8653eea888..b3484987b5 100644
--- a/src/utils/use-touch.ts
+++ b/src/utils/use-touch.ts
@@ -52,10 +52,7 @@ export function useTouch() {
typeof touch.pageX !== 'undefined'
)
return touch.pageX
- if (typeof touch.clientX !== 'undefined') return touch.clientX
- if (typeof touch.pageX !== 'undefined') return touch.pageX
- if (typeof touch.screenX !== 'undefined') return touch.screenX
- return 0
+ return touch.screenX ?? touch.pageX ?? touch.clientX ?? 0
}
const getY = (touch: React.Touch) => {
@@ -64,10 +61,7 @@ export function useTouch() {
typeof touch.pageY !== 'undefined'
)
return touch.pageY
- if (typeof touch.clientY !== 'undefined') return touch.clientY
- if (typeof touch.pageY !== 'undefined') return touch.pageY
- if (typeof touch.screenY !== 'undefined') return touch.screenY
- return 0
+ return touch.screenY ?? touch.pageY ?? touch.clientY ?? 0
}
const start = (event: React.TouchEvent ) => {
| |