+ ) : (
+ renderTab()
)
-}
-
-export const Cascader = React.forwardRef(InternalCascader)
+})
Cascader.displayName = 'NutCascader'
diff --git a/src/packages/cascader/demo.taro.tsx b/src/packages/cascader/demo.taro.tsx
index 4227dbb103..a1e773d0e4 100644
--- a/src/packages/cascader/demo.taro.tsx
+++ b/src/packages/cascader/demo.taro.tsx
@@ -8,11 +8,13 @@ import Demo3 from './demos/taro/demo3'
import Demo4 from './demos/taro/demo4'
import Demo5 from './demos/taro/demo5'
import Demo6 from './demos/taro/demo6'
+import Demo7 from './demos/taro/demo7'
const CascaderDemo = () => {
const [translated] = useTranslate({
'zh-CN': {
basic: '基础用法',
+ uncontrolled: '基础用法-非受控',
title1: '自定义属性名称',
title2: '动态加载',
title3: '部分数据动态加载',
@@ -21,6 +23,7 @@ const CascaderDemo = () => {
},
'zh-TW': {
basic: '基础用法',
+ uncontrolled: '基础用法-非受控',
title1: '自定義屬性名稱',
title2: '動態加載',
title3: '部分數據動態加載',
@@ -29,6 +32,7 @@ const CascaderDemo = () => {
},
'en-US': {
basic: 'Basic Usage',
+ uncontrolled: 'uncontrolled',
title1: 'Custom Attribute Name',
title2: 'Async Loading',
title3: 'Async Loading Of Partial Data',
@@ -43,6 +47,8 @@ const CascaderDemo = () => {
{translated.basic}
+
{translated.uncontrolled}
+
{translated.title1}
{translated.title2}
diff --git a/src/packages/cascader/demo.tsx b/src/packages/cascader/demo.tsx
index 484170b715..268f027718 100644
--- a/src/packages/cascader/demo.tsx
+++ b/src/packages/cascader/demo.tsx
@@ -6,11 +6,13 @@ import Demo3 from './demos/h5/demo3'
import Demo4 from './demos/h5/demo4'
import Demo5 from './demos/h5/demo5'
import Demo6 from './demos/h5/demo6'
+import Demo7 from './demos/h5/demo7'
const CascaderDemo = () => {
const [translated] = useTranslate({
'zh-CN': {
basic: '基础用法',
+ uncontrolled: '基础用法-非受控',
title1: '自定义属性名称',
title2: '动态加载',
title3: '部分数据动态加载',
@@ -19,6 +21,7 @@ const CascaderDemo = () => {
},
'zh-TW': {
basic: '基础用法',
+ uncontrolled: '基础用法-非受控',
title1: '自定義屬性名稱',
title2: '動態加載',
title3: '部分數據動態加載',
@@ -27,6 +30,7 @@ const CascaderDemo = () => {
},
'en-US': {
basic: 'Basic Usage',
+ uncontrolled: 'uncontrolled',
title1: 'Custom Attribute Name',
title2: 'Async Loading',
title3: 'Async Loading Of Partial Data',
@@ -40,6 +44,8 @@ const CascaderDemo = () => {
{translated.basic}
+ {translated.uncontrolled}
+
{translated.title1}
{translated.title2}
diff --git a/src/packages/cascader/demos/h5/demo1.tsx b/src/packages/cascader/demos/h5/demo1.tsx
index 6ad63821de..ac49452f62 100644
--- a/src/packages/cascader/demos/h5/demo1.tsx
+++ b/src/packages/cascader/demos/h5/demo1.tsx
@@ -1,98 +1,106 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react'
+import React, { useEffect, useState } from 'react'
+import { Cascader, Cell, CascaderOption } from '@nutui/nutui-react'
const Demo1 = () => {
- const [isVisibleDemo1, setIsVisibleDemo1] = useState(false)
- const [value1, setValue1] = useState([])
- const [optionsDemo1] = useState([
- {
- value: '浙江',
- text: '浙江',
- children: [
- {
- value: '杭州',
- text: '杭州',
- disabled: true,
- children: [
- { value: '西湖区', text: '西湖区', disabled: true },
- { value: '余杭区', text: '余杭区' },
- ],
- },
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ const onChange = (value: any, path: any) => {
+ console.log('onchange', value, path)
+ setValue(value)
+ }
+ useEffect(() => {
+ setTimeout(() => {
+ setOptions([
{
- value: '温州',
- text: '温州',
+ value: '浙江',
+ text: '浙江',
children: [
- { value: '鹿城区', text: '鹿城区' },
- { value: '瓯海区', text: '瓯海区' },
+ {
+ value: '杭州',
+ text: '杭州',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区', disabled: true },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '湖南',
- text: '湖南',
- disabled: true,
- children: [
{
- value: '长沙',
- text: '长沙',
+ value: '湖南',
+ text: '湖南',
disabled: true,
children: [
- { value: '芙蓉区', text: '芙蓉区' },
- { value: '岳麓区', text: '岳麓区' },
+ {
+ value: '长沙',
+ text: '长沙',
+ disabled: true,
+ children: [
+ { value: '芙蓉区', text: '芙蓉区' },
+ { value: '岳麓区', text: '岳麓区' },
+ ],
+ },
+ {
+ value: '岳阳',
+ text: '岳阳',
+ children: [
+ { value: '岳阳楼区', text: '岳阳楼区' },
+ { value: '云溪区', text: '云溪区' },
+ ],
+ },
],
},
{
- value: '岳阳',
- text: '岳阳',
+ value: '福建',
+ text: '福建',
children: [
- { value: '岳阳楼区', text: '岳阳楼区' },
- { value: '云溪区', text: '云溪区' },
+ {
+ value: '福州',
+ text: '福州',
+ children: [
+ { value: '鼓楼区', text: '鼓楼区' },
+ { value: '台江区', text: '台江区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '福建',
- text: '福建',
- children: [
- {
- value: '福州',
- text: '福州',
- children: [
- { value: '鼓楼区', text: '鼓楼区' },
- { value: '台江区', text: '台江区' },
- ],
- },
- ],
- },
- ])
- const change1 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue1(value)
- }
+ ])
+ }, 300)
+ }, [])
return (
<>
{
- setIsVisibleDemo1(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo1(false)
+ setVisible(false)
+ }}
+ onChange={onChange}
+ onPathChange={(value, path) => {
+ console.log(value, path)
}}
- onChange={change1}
/>
>
)
diff --git a/src/packages/cascader/demos/h5/demo2.tsx b/src/packages/cascader/demos/h5/demo2.tsx
index 0b8059a5d8..9fd82558ab 100644
--- a/src/packages/cascader/demos/h5/demo2.tsx
+++ b/src/packages/cascader/demos/h5/demo2.tsx
@@ -1,91 +1,95 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react'
+import React, { useEffect, useState } from 'react'
+import { Cascader, CascaderOption, Cell } from '@nutui/nutui-react'
const Demo2 = () => {
- const [isVisibleDemo2, setIsVisibleDemo2] = useState(false)
- const [value2, setValue2] = useState(['福建', '福州', '台江区'])
- const [optionsDemo2] = useState([
- {
- value1: '浙江',
- text1: '浙江',
- items: [
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState(['福建', '福州', '台江区'])
+ const [options, setOptions] = useState([])
+ useEffect(() => {
+ setTimeout(() => {
+ setOptions([
{
- value1: '杭州',
- text1: '杭州',
- disabled: true,
- items: [
- { value1: '西湖区', text1: '西湖区', disabled: true },
- { value1: '余杭区', text1: '余杭区' },
- ],
- },
- {
- value1: '温州',
- text1: '温州',
+ value1: '浙江',
+ text1: '浙江',
items: [
- { value1: '鹿城区', text1: '鹿城区' },
- { value1: '瓯海区', text1: '瓯海区' },
+ {
+ value1: '杭州',
+ text1: '杭州',
+ disabled: true,
+ items: [
+ { value1: '西湖区', text1: '西湖区', disabled: true },
+ { value1: '余杭区', text1: '余杭区' },
+ ],
+ },
+ {
+ value1: '温州',
+ text1: '温州',
+ items: [
+ { value1: '鹿城区', text1: '鹿城区' },
+ { value1: '瓯海区', text1: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value1: '湖南',
- text1: '湖南',
- disabled: true,
- items: [
{
- value1: '长沙',
- text1: '长沙',
+ value1: '湖南',
+ text1: '湖南',
disabled: true,
items: [
- { value1: '芙蓉区', text1: '芙蓉区' },
- { value1: '岳麓区', text1: '岳麓区' },
- ],
- },
- {
- value1: '岳阳',
- text1: '岳阳',
- children: [
- { value1: '岳阳楼区', text1: '岳阳楼区' },
- { value1: '云溪区', text1: '云溪区' },
+ {
+ value1: '长沙',
+ text1: '长沙',
+ disabled: true,
+ items: [
+ { value1: '芙蓉区', text1: '芙蓉区' },
+ { value1: '岳麓区', text1: '岳麓区' },
+ ],
+ },
+ {
+ value1: '岳阳',
+ text1: '岳阳',
+ children: [
+ { value1: '岳阳楼区', text1: '岳阳楼区' },
+ { value1: '云溪区', text1: '云溪区' },
+ ],
+ },
],
},
- ],
- },
- {
- value1: '福建',
- text1: '福建',
- items: [
{
- value1: '福州',
- text1: '福州',
+ value1: '福建',
+ text1: '福建',
items: [
- { value1: '鼓楼区', text1: '鼓楼区' },
- { value1: '台江区', text1: '台江区' },
+ {
+ value1: '福州',
+ text1: '福州',
+ items: [
+ { value1: '鼓楼区', text1: '鼓楼区' },
+ { value1: '台江区', text1: '台江区' },
+ ],
+ },
],
},
- ],
- },
- ])
- const change2 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue2(value)
+ ])
+ }, 300)
+ }, [])
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
return (
<>
{
- setIsVisibleDemo2(true)
+ setVisible(true)
}}
/>
{
}}
closeable
onClose={() => {
- setIsVisibleDemo2(false)
+ setVisible(false)
}}
- onChange={change2}
+ onChange={onChange}
/>
>
)
diff --git a/src/packages/cascader/demos/h5/demo3.tsx b/src/packages/cascader/demos/h5/demo3.tsx
index 48387206e4..72e052eafb 100644
--- a/src/packages/cascader/demos/h5/demo3.tsx
+++ b/src/packages/cascader/demos/h5/demo3.tsx
@@ -1,57 +1,51 @@
import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react'
+import { Cascader, CascaderOption, Cell } from '@nutui/nutui-react'
const Demo3 = () => {
- const [isVisibleDemo3, setIsVisibleDemo3] = useState(false)
- const [value3, setValue3] = useState(['A0', 'A12', 'A23', 'A32'])
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState(['A11', 'A21', 'A31', 'A41'])
- const lazyLoadDemo3 = (node: any, resolve: (children: any) => void) => {
- setTimeout(() => {
- if (node.root) {
- resolve([
- { value: 'A0', text: 'A0' },
- { value: 'B0', text: 'B0' },
- { value: 'C0', text: 'C0' },
- ])
- } else {
- const { value, level } = node
- const text = value.substring(0, 1)
+ const loadCascaderItemData = (
+ node: CascaderOption,
+ level: number
+ ): Promise => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ const { value } = node
+ const text = value?.toString().substring(0, 1)
const value1 = `${text}${level + 1}1`
const value2 = `${text}${level + 1}2`
- const value3 = `${text}${level + 1}3`
resolve([
- { value: value1, text: value1, leaf: level >= 6 },
- { value: value2, text: value2, leaf: level >= 6 },
- { value: value3, text: value3, leaf: level >= 6 },
+ { value: value1, text: value1, leaf: level >= 2 },
+ { value: value2, text: value2, leaf: level >= 2 },
])
- }
- }, 2000)
+ }, 500)
+ })
}
- const change3 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue3(value)
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
return (
<>
{
- setIsVisibleDemo3(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo3(false)
+ setVisible(false)
}}
- onChange={change3}
+ onChange={onChange}
lazy
- onLoad={lazyLoadDemo3}
+ onLoad={loadCascaderItemData}
/>
>
)
diff --git a/src/packages/cascader/demos/h5/demo4.tsx b/src/packages/cascader/demos/h5/demo4.tsx
index 1cfdce0e5e..d3a89f6eb5 100644
--- a/src/packages/cascader/demos/h5/demo4.tsx
+++ b/src/packages/cascader/demos/h5/demo4.tsx
@@ -1,59 +1,67 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react'
+import React, { useEffect, useState } from 'react'
+import { Cascader, Cell, CascaderOption } from '@nutui/nutui-react'
const Demo4 = () => {
- const [isVisibleDemo4, setIsVisibleDemo4] = useState(false)
- const [value4, setValue4] = useState([])
- const [optionsDemo4] = useState([
- { value: 'A0', text: 'A0' },
- {
- value: 'B0',
- text: 'B0',
- children: [
- { value: 'B11', text: 'B11', leaf: true },
- { value: 'B12', text: 'B12' },
- ],
- },
- { value: 'C0', text: 'C0' },
- ])
-
- const lazyLoadDemo4 = (node: any, resolve: (children: any) => void) => {
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ useEffect(() => {
setTimeout(() => {
- const { value, level } = node
- const text = value.substring(0, 1)
- const value1 = `${text}${level + 1}1`
- const value2 = `${text}${level + 1}2`
- resolve([
- { value: value1, text: value1, leaf: level >= 2 },
- { value: value2, text: value2, leaf: level >= 1 },
+ setOptions([
+ { value: 'A0', text: 'A0' },
+ {
+ value: 'B0',
+ text: 'B0',
+ children: [
+ { value: 'B11', text: 'B11', leaf: true },
+ { value: 'B12', text: 'B12' },
+ ],
+ },
+ { value: 'C0', text: 'C0' },
])
- }, 500)
+ }, 300)
+ }, [])
+
+ const lazyLoadDemo4 = async (
+ node: any,
+ level: number
+ ): Promise => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ const { value } = node
+ const text = value.substring(0, 1)
+ const value1 = `${text}${level + 1}1`
+ const value2 = `${text}${level + 1}2`
+ resolve([
+ { value: value1, text: value1, leaf: level >= 2 },
+ { value: value2, text: value2, leaf: level >= 1 },
+ ])
+ }, 500)
+ })
}
const change4 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue4(value)
+ setValue(value)
}
return (
<>
{
- setIsVisibleDemo4(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo4(false)
+ setVisible(false)
}}
onChange={change4}
- lazy
onLoad={lazyLoadDemo4}
/>
>
diff --git a/src/packages/cascader/demos/h5/demo5.tsx b/src/packages/cascader/demos/h5/demo5.tsx
index 92834f7fc1..12ae9501ec 100644
--- a/src/packages/cascader/demos/h5/demo5.tsx
+++ b/src/packages/cascader/demos/h5/demo5.tsx
@@ -1,47 +1,55 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react'
+import React, { useEffect, useState } from 'react'
+import { Cascader, CascaderOption, Cell } from '@nutui/nutui-react'
const Demo5 = () => {
- const [isVisibleDemo5, setIsVisibleDemo5] = useState(false)
- const [value5, setValue5] = useState(['广东省', '广州市'])
- const [optionsDemo5] = useState([
- { value: '北京', text: '北京', id: 1, pidd: null },
- { value: '通州区', text: '通州区', id: 11, pidd: 1 },
- { value: '经海路', text: '经海路', id: 111, pidd: 11 },
- { value: '广东省', text: '广东省', id: 2, pidd: null },
- { value: '广州市', text: '广州市', id: 21, pidd: 2 },
- ])
- const [convertConfigDemo5, setConvertConfigDemo5] = useState({
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ const format = {
topId: null,
idKey: 'id',
pidKey: 'pidd',
- sortKey: '',
- })
- const change5 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue5(value)
+ }
+
+ useEffect(() => {
+ setTimeout(() => {
+ setValue(['广东省', '广州市'])
+ setOptions([
+ { value: '北京', text: '北京', id: 1, pidd: null },
+ { value: '通州区', text: '通州区', id: 11, pidd: 1, sortKey: 2 },
+ { value: '大兴区', text: '大兴区', id: 12, pidd: 1, sortKey: 1 },
+ { value: '经海路', text: '经海路', id: 111, pidd: 12, sortKey: 2 },
+ { value: '黄亦路', text: '黄亦路', id: 112, pidd: 12, sortKey: 1 },
+ { value: '广东省', text: '广东省', id: 2, pidd: null },
+ { value: '广州市', text: '广州市', id: 21, pidd: 2 },
+ ])
+ }, 300)
+ }, [])
+
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
return (
<>
{
- setIsVisibleDemo5(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo5(false)
+ setVisible(false)
}}
- onChange={change5}
+ onChange={onChange}
/>
>
)
diff --git a/src/packages/cascader/demos/h5/demo6.tsx b/src/packages/cascader/demos/h5/demo6.tsx
index b7c21c3b5a..e452791c8b 100644
--- a/src/packages/cascader/demos/h5/demo6.tsx
+++ b/src/packages/cascader/demos/h5/demo6.tsx
@@ -1,5 +1,10 @@
-import React, { useState } from 'react'
-import { Cell, Cascader, ConfigProvider } from '@nutui/nutui-react'
+import React, { useEffect, useState } from 'react'
+import {
+ Cell,
+ Cascader,
+ ConfigProvider,
+ CascaderOption,
+} from '@nutui/nutui-react'
const customTheme = {
nutuiCascaderItemHeight: '48px',
@@ -11,74 +16,78 @@ const customTheme = {
}
const Demo6 = () => {
- const [isVisibleDemo6, setIsVisibleDemo6] = useState(false)
- const [value6, setValue6] = useState([])
- const [optionsDemo6] = useState([
- {
- value: '浙江',
- text: '浙江',
- children: [
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState(['浙江', '温州', '鹿城区'])
+ const [options, setOptions] = useState([])
+ useEffect(() => {
+ setTimeout(() => {
+ setOptions([
{
- value: '杭州',
- text: '杭州',
- disabled: true,
- children: [
- { value: '西湖区', text: '西湖区', disabled: true },
- { value: '余杭区', text: '余杭区' },
- ],
- },
- {
- value: '温州',
- text: '温州',
+ value: '浙江',
+ text: '浙江',
children: [
- { value: '鹿城区', text: '鹿城区' },
- { value: '瓯海区', text: '瓯海区' },
+ {
+ value: '杭州',
+ text: '杭州',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区', disabled: true },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '湖南',
- text: '湖南',
- disabled: true,
- children: [
{
- value: '长沙',
- text: '长沙',
+ value: '湖南',
+ text: '湖南',
disabled: true,
children: [
- { value: '西湖区', text: '西湖区' },
- { value: '余杭区', text: '余杭区' },
- ],
- },
- {
- value: '温州',
- text: '温州',
- children: [
- { value: '鹿城区', text: '鹿城区' },
- { value: '瓯海区', text: '瓯海区' },
+ {
+ value: '长沙',
+ text: '长沙',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区' },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '福建',
- text: '福建',
- children: [
{
- value: '福州',
- text: '福州',
+ value: '福建',
+ text: '福建',
children: [
- { value: '鼓楼区', text: '鼓楼区' },
- { value: '台江区', text: '台江区' },
+ {
+ value: '福州',
+ text: '福州',
+ children: [
+ { value: '鼓楼区', text: '鼓楼区' },
+ { value: '台江区', text: '台江区' },
+ ],
+ },
],
},
- ],
- },
- ])
- const change6 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue6(value)
+ ])
+ }, 300)
+ }, [])
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
const onPathChange = (value: any, path: any) => {
console.log('onPathChange', value, path)
@@ -88,26 +97,26 @@ const Demo6 = () => {
<>
{
- setIsVisibleDemo6(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo6(false)
+ setVisible(false)
}}
- onChange={change6}
+ onChange={onChange}
onPathChange={onPathChange}
- />{' '}
+ />
>
)
diff --git a/src/packages/cascader/demos/h5/demo7.tsx b/src/packages/cascader/demos/h5/demo7.tsx
new file mode 100644
index 0000000000..64ff2669f6
--- /dev/null
+++ b/src/packages/cascader/demos/h5/demo7.tsx
@@ -0,0 +1,109 @@
+import React, { useEffect, useState } from 'react'
+import { Cascader, Cell, CascaderOption } from '@nutui/nutui-react'
+
+const Demo7 = () => {
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ const onChange = (value: any, path: any) => {
+ console.log('onchange', value, path)
+ setValue(value)
+ }
+ useEffect(() => {
+ setTimeout(() => {
+ setValue(['浙江', '温州', '鹿城区'])
+ setOptions([
+ {
+ value: '浙江',
+ text: '浙江',
+ children: [
+ {
+ value: '杭州',
+ text: '杭州',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区', disabled: true },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
+ ],
+ },
+ {
+ value: '湖南',
+ text: '湖南',
+ disabled: true,
+ children: [
+ {
+ value: '长沙',
+ text: '长沙',
+ disabled: true,
+ children: [
+ { value: '芙蓉区', text: '芙蓉区' },
+ { value: '岳麓区', text: '岳麓区' },
+ ],
+ },
+ {
+ value: '岳阳',
+ text: '岳阳',
+ children: [
+ { value: '岳阳楼区', text: '岳阳楼区' },
+ { value: '云溪区', text: '云溪区' },
+ ],
+ },
+ ],
+ },
+ {
+ value: '福建',
+ text: '福建',
+ children: [
+ {
+ value: '福州',
+ text: '福州',
+ children: [
+ { value: '鼓楼区', text: '鼓楼区' },
+ { value: '台江区', text: '台江区' },
+ ],
+ },
+ ],
+ },
+ ])
+ }, 300)
+ }, [])
+ return (
+ <>
+ {
+ setVisible(true)
+ }}
+ />
+ {
+ setVisible(false)
+ }}
+ onChange={onChange}
+ onPathChange={(value, path) => {
+ console.log(value, path)
+ }}
+ />
+ >
+ )
+}
+export default Demo7
diff --git a/src/packages/cascader/demos/taro/demo1.tsx b/src/packages/cascader/demos/taro/demo1.tsx
index b8dbadeafd..3f0da4da82 100644
--- a/src/packages/cascader/demos/taro/demo1.tsx
+++ b/src/packages/cascader/demos/taro/demo1.tsx
@@ -1,99 +1,102 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react-taro'
+import React, { useEffect, useState } from 'react'
+import { Cascader, Cell, CascaderOption } from '@nutui/nutui-react-taro'
const Demo1 = () => {
- const [isVisibleDemo1, setIsVisibleDemo1] = useState(false)
- const [value1, setValue1] = useState([])
- const [optionsDemo1] = useState([
- {
- value: '浙江',
- text: '浙江',
- children: [
- {
- value: '杭州',
- text: '杭州',
- disabled: true,
- children: [
- { value: '西湖区', text: '西湖区', disabled: true },
- { value: '余杭区', text: '余杭区' },
- ],
- },
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ const onChange = (value: any, path: any) => {
+ setValue(value)
+ }
+ useEffect(() => {
+ setTimeout(() => {
+ setOptions([
{
- value: '温州',
- text: '温州',
+ value: '浙江',
+ text: '浙江',
children: [
- { value: '鹿城区', text: '鹿城区' },
- { value: '瓯海区', text: '瓯海区' },
+ {
+ value: '杭州',
+ text: '杭州',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区', disabled: true },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '湖南',
- text: '湖南',
- disabled: true,
- children: [
{
- value: '长沙',
- text: '长沙',
+ value: '湖南',
+ text: '湖南',
disabled: true,
children: [
- { value: '芙蓉区', text: '芙蓉区' },
- { value: '岳麓区', text: '岳麓区' },
+ {
+ value: '长沙',
+ text: '长沙',
+ disabled: true,
+ children: [
+ { value: '芙蓉区', text: '芙蓉区' },
+ { value: '岳麓区', text: '岳麓区' },
+ ],
+ },
+ {
+ value: '岳阳',
+ text: '岳阳',
+ children: [
+ { value: '岳阳楼区', text: '岳阳楼区' },
+ { value: '云溪区', text: '云溪区' },
+ ],
+ },
],
},
{
- value: '岳阳',
- text: '岳阳',
+ value: '福建',
+ text: '福建',
children: [
- { value: '岳阳楼区', text: '岳阳楼区' },
- { value: '云溪区', text: '云溪区' },
+ {
+ value: '福州',
+ text: '福州',
+ children: [
+ { value: '鼓楼区', text: '鼓楼区' },
+ { value: '台江区', text: '台江区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '福建',
- text: '福建',
- children: [
- {
- value: '福州',
- text: '福州',
- children: [
- { value: '鼓楼区', text: '鼓楼区' },
- { value: '台江区', text: '台江区' },
- ],
- },
- ],
- },
- ])
- const change1 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue1(value)
- }
-
+ ])
+ }, 300)
+ }, [])
return (
<>
{
- setIsVisibleDemo1(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo1(false)
+ setVisible(false)
}}
- onChange={change1}
+ onChange={onChange}
/>
>
)
diff --git a/src/packages/cascader/demos/taro/demo2.tsx b/src/packages/cascader/demos/taro/demo2.tsx
index 2ad2a411a1..7c328c3ebc 100644
--- a/src/packages/cascader/demos/taro/demo2.tsx
+++ b/src/packages/cascader/demos/taro/demo2.tsx
@@ -1,91 +1,95 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react-taro'
+import React, { useEffect, useState } from 'react'
+import { Cascader, CascaderOption, Cell } from '@nutui/nutui-react-taro'
const Demo2 = () => {
- const [isVisibleDemo2, setIsVisibleDemo2] = useState(false)
- const [value2, setValue2] = useState(['福建', '福州', '台江区'])
- const [optionsDemo2] = useState([
- {
- value1: '浙江',
- text1: '浙江',
- items: [
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState(['福建', '福州', '台江区'])
+ const [options, setOptions] = useState([])
+ useEffect(() => {
+ setTimeout(() => {
+ setOptions([
{
- value1: '杭州',
- text1: '杭州',
- disabled: true,
- items: [
- { value1: '西湖区', text1: '西湖区', disabled: true },
- { value1: '余杭区', text1: '余杭区' },
- ],
- },
- {
- value1: '温州',
- text1: '温州',
+ value1: '浙江',
+ text1: '浙江',
items: [
- { value1: '鹿城区', text1: '鹿城区' },
- { value1: '瓯海区', text1: '瓯海区' },
+ {
+ value1: '杭州',
+ text1: '杭州',
+ disabled: true,
+ items: [
+ { value1: '西湖区', text1: '西湖区', disabled: true },
+ { value1: '余杭区', text1: '余杭区' },
+ ],
+ },
+ {
+ value1: '温州',
+ text1: '温州',
+ items: [
+ { value1: '鹿城区', text1: '鹿城区' },
+ { value1: '瓯海区', text1: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value1: '湖南',
- text1: '湖南',
- disabled: true,
- items: [
{
- value1: '长沙',
- text1: '长沙',
+ value1: '湖南',
+ text1: '湖南',
disabled: true,
items: [
- { value1: '芙蓉区', text1: '芙蓉区' },
- { value1: '岳麓区', text1: '岳麓区' },
- ],
- },
- {
- value1: '岳阳',
- text1: '岳阳',
- children: [
- { value1: '岳阳楼区', text1: '岳阳楼区' },
- { value1: '云溪区', text1: '云溪区' },
+ {
+ value1: '长沙',
+ text1: '长沙',
+ disabled: true,
+ items: [
+ { value1: '芙蓉区', text1: '芙蓉区' },
+ { value1: '岳麓区', text1: '岳麓区' },
+ ],
+ },
+ {
+ value1: '岳阳',
+ text1: '岳阳',
+ children: [
+ { value1: '岳阳楼区', text1: '岳阳楼区' },
+ { value1: '云溪区', text1: '云溪区' },
+ ],
+ },
],
},
- ],
- },
- {
- value1: '福建',
- text1: '福建',
- items: [
{
- value1: '福州',
- text1: '福州',
+ value1: '福建',
+ text1: '福建',
items: [
- { value1: '鼓楼区', text1: '鼓楼区' },
- { value1: '台江区', text1: '台江区' },
+ {
+ value1: '福州',
+ text1: '福州',
+ items: [
+ { value1: '鼓楼区', text1: '鼓楼区' },
+ { value1: '台江区', text1: '台江区' },
+ ],
+ },
],
},
- ],
- },
- ])
- const change2 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue2(value)
+ ])
+ }, 300)
+ }, [])
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
return (
<>
{
- setIsVisibleDemo2(true)
+ setVisible(true)
}}
/>
{
}}
closeable
onClose={() => {
- setIsVisibleDemo2(false)
+ setVisible(false)
}}
- onChange={change2}
+ onChange={onChange}
/>
>
)
diff --git a/src/packages/cascader/demos/taro/demo3.tsx b/src/packages/cascader/demos/taro/demo3.tsx
index b087ba3247..c89357afb5 100644
--- a/src/packages/cascader/demos/taro/demo3.tsx
+++ b/src/packages/cascader/demos/taro/demo3.tsx
@@ -1,56 +1,51 @@
import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react-taro'
+import { Cascader, CascaderOption, Cell } from '@nutui/nutui-react-taro'
const Demo3 = () => {
- const [isVisibleDemo3, setIsVisibleDemo3] = useState(false)
- const [value3, setValue3] = useState(['A0', 'A12', 'A23', 'A32'])
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState(['A11', 'A21', 'A31', 'A41'])
- const lazyLoadDemo3 = (node: any, resolve: (children: any) => void) => {
- setTimeout(() => {
- if (node.root) {
- resolve([
- { value: 'A0', text: 'A0' },
- { value: 'B0', text: 'B0' },
- { value: 'C0', text: 'C0' },
- ])
- } else {
- const { value, level } = node
- const text = value.substring(0, 1)
+ const loadCascaderItemData = (
+ node: CascaderOption,
+ level: number
+ ): Promise => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ const { value } = node
+ const text = value?.toString().substring(0, 1)
const value1 = `${text}${level + 1}1`
const value2 = `${text}${level + 1}2`
- const value3 = `${text}${level + 1}3`
resolve([
- { value: value1, text: value1, leaf: level >= 6 },
- { value: value2, text: value2, leaf: level >= 6 },
- { value: value3, text: value3, leaf: level >= 6 },
+ { value: value1, text: value1, leaf: level >= 2 },
+ { value: value2, text: value2, leaf: level >= 2 },
])
- }
- }, 2000)
+ }, 500)
+ })
}
- const change3 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue3(value)
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
+
return (
<>
{
- setIsVisibleDemo3(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo3(false)
+ setVisible(false)
}}
- onChange={change3}
+ onChange={onChange}
lazy
- onLoad={lazyLoadDemo3}
+ onLoad={loadCascaderItemData}
/>
>
)
diff --git a/src/packages/cascader/demos/taro/demo4.tsx b/src/packages/cascader/demos/taro/demo4.tsx
index a22c6c7aeb..225a3e9807 100644
--- a/src/packages/cascader/demos/taro/demo4.tsx
+++ b/src/packages/cascader/demos/taro/demo4.tsx
@@ -1,59 +1,67 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react-taro'
+import React, { useEffect, useState } from 'react'
+import { Cascader, Cell, CascaderOption } from '@nutui/nutui-react-taro'
const Demo4 = () => {
- const [isVisibleDemo4, setIsVisibleDemo4] = useState(false)
- const [value4, setValue4] = useState([])
- const [optionsDemo4] = useState([
- { value: 'A0', text: 'A0' },
- {
- value: 'B0',
- text: 'B0',
- children: [
- { value: 'B11', text: 'B11', leaf: true },
- { value: 'B12', text: 'B12' },
- ],
- },
- { value: 'C0', text: 'C0' },
- ])
-
- const lazyLoadDemo4 = (node: any, resolve: (children: any) => void) => {
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ useEffect(() => {
setTimeout(() => {
- const { value, level } = node
- const text = value.substring(0, 1)
- const value1 = `${text}${level + 1}1`
- const value2 = `${text}${level + 1}2`
- resolve([
- { value: value1, text: value1, leaf: level >= 2 },
- { value: value2, text: value2, leaf: level >= 1 },
+ setOptions([
+ { value: 'A0', text: 'A0' },
+ {
+ value: 'B0',
+ text: 'B0',
+ children: [
+ { value: 'B11', text: 'B11', leaf: true },
+ { value: 'B12', text: 'B12' },
+ ],
+ },
+ { value: 'C0', text: 'C0' },
])
- }, 500)
+ }, 300)
+ }, [])
+
+ const lazyLoadDemo4 = async (
+ node: any,
+ level: number
+ ): Promise => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ const { value } = node
+ const text = value.substring(0, 1)
+ const value1 = `${text}${level + 1}1`
+ const value2 = `${text}${level + 1}2`
+ resolve([
+ { value: value1, text: value1, leaf: level >= 2 },
+ { value: value2, text: value2, leaf: level >= 1 },
+ ])
+ }, 500)
+ })
}
const change4 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue4(value)
+ setValue(value)
}
return (
<>
{
- setIsVisibleDemo4(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo4(false)
+ setVisible(false)
}}
onChange={change4}
- lazy
onLoad={lazyLoadDemo4}
/>
>
diff --git a/src/packages/cascader/demos/taro/demo5.tsx b/src/packages/cascader/demos/taro/demo5.tsx
index 4df6f2023b..79ef7e20d5 100644
--- a/src/packages/cascader/demos/taro/demo5.tsx
+++ b/src/packages/cascader/demos/taro/demo5.tsx
@@ -1,47 +1,55 @@
-import React, { useState } from 'react'
-import { Cascader, Cell } from '@nutui/nutui-react-taro'
+import React, { useEffect, useState } from 'react'
+import { Cascader, CascaderOption, Cell } from '@nutui/nutui-react-taro'
const Demo5 = () => {
- const [isVisibleDemo5, setIsVisibleDemo5] = useState(false)
- const [value5, setValue5] = useState(['广东省', '广州市'])
- const [optionsDemo5] = useState([
- { value: '北京', text: '北京', id: 1, pidd: null },
- { value: '通州区', text: '通州区', id: 11, pidd: 1 },
- { value: '经海路', text: '经海路', id: 111, pidd: 11 },
- { value: '广东省', text: '广东省', id: 2, pidd: null },
- { value: '广州市', text: '广州市', id: 21, pidd: 2 },
- ])
- const [convertConfigDemo5, setConvertConfigDemo5] = useState({
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ const format = {
topId: null,
idKey: 'id',
pidKey: 'pidd',
- sortKey: '',
- })
- const change5 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue5(value)
+ }
+
+ useEffect(() => {
+ setTimeout(() => {
+ setValue(['广东省', '广州市'])
+ setOptions([
+ { value: '北京', text: '北京', id: 1, pidd: null },
+ { value: '通州区', text: '通州区', id: 11, pidd: 1, sortKey: 2 },
+ { value: '大兴区', text: '大兴区', id: 12, pidd: 1, sortKey: 1 },
+ { value: '经海路', text: '经海路', id: 111, pidd: 12, sortKey: 2 },
+ { value: '黄亦路', text: '黄亦路', id: 112, pidd: 12, sortKey: 1 },
+ { value: '广东省', text: '广东省', id: 2, pidd: null },
+ { value: '广州市', text: '广州市', id: 21, pidd: 2 },
+ ])
+ }, 300)
+ }, [])
+
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
return (
<>
{
- setIsVisibleDemo5(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo5(false)
+ setVisible(false)
}}
- onChange={change5}
+ onChange={onChange}
/>
>
)
diff --git a/src/packages/cascader/demos/taro/demo6.tsx b/src/packages/cascader/demos/taro/demo6.tsx
index 20c66f81bb..a1687fd6a4 100644
--- a/src/packages/cascader/demos/taro/demo6.tsx
+++ b/src/packages/cascader/demos/taro/demo6.tsx
@@ -1,5 +1,10 @@
-import React, { useState } from 'react'
-import { Cell, Cascader, ConfigProvider } from '@nutui/nutui-react-taro'
+import React, { useEffect, useState } from 'react'
+import {
+ Cell,
+ Cascader,
+ ConfigProvider,
+ CascaderOption,
+} from '@nutui/nutui-react-taro'
const customTheme = {
nutuiCascaderItemHeight: '48px',
@@ -11,74 +16,78 @@ const customTheme = {
}
const Demo6 = () => {
- const [isVisibleDemo6, setIsVisibleDemo6] = useState(false)
- const [value6, setValue6] = useState([])
- const [optionsDemo6] = useState([
- {
- value: '浙江',
- text: '浙江',
- children: [
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState(['浙江', '温州', '鹿城区'])
+ const [options, setOptions] = useState([])
+ useEffect(() => {
+ setTimeout(() => {
+ setOptions([
{
- value: '杭州',
- text: '杭州',
- disabled: true,
- children: [
- { value: '西湖区', text: '西湖区', disabled: true },
- { value: '余杭区', text: '余杭区' },
- ],
- },
- {
- value: '温州',
- text: '温州',
+ value: '浙江',
+ text: '浙江',
children: [
- { value: '鹿城区', text: '鹿城区' },
- { value: '瓯海区', text: '瓯海区' },
+ {
+ value: '杭州',
+ text: '杭州',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区', disabled: true },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '湖南',
- text: '湖南',
- disabled: true,
- children: [
{
- value: '长沙',
- text: '长沙',
+ value: '湖南',
+ text: '湖南',
disabled: true,
children: [
- { value: '西湖区', text: '西湖区' },
- { value: '余杭区', text: '余杭区' },
- ],
- },
- {
- value: '温州',
- text: '温州',
- children: [
- { value: '鹿城区', text: '鹿城区' },
- { value: '瓯海区', text: '瓯海区' },
+ {
+ value: '长沙',
+ text: '长沙',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区' },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
],
},
- ],
- },
- {
- value: '福建',
- text: '福建',
- children: [
{
- value: '福州',
- text: '福州',
+ value: '福建',
+ text: '福建',
children: [
- { value: '鼓楼区', text: '鼓楼区' },
- { value: '台江区', text: '台江区' },
+ {
+ value: '福州',
+ text: '福州',
+ children: [
+ { value: '鼓楼区', text: '鼓楼区' },
+ { value: '台江区', text: '台江区' },
+ ],
+ },
],
},
- ],
- },
- ])
- const change6 = (value: any, path: any) => {
- console.log('onChange', value, path)
- setValue6(value)
+ ])
+ }, 300)
+ }, [])
+ const onChange = (value: any, path: any) => {
+ setValue(value)
}
const onPathChange = (value: any, path: any) => {
console.log('onPathChange', value, path)
@@ -88,26 +97,26 @@ const Demo6 = () => {
<>
{
- setIsVisibleDemo6(true)
+ setVisible(true)
}}
/>
{
- setIsVisibleDemo6(false)
+ setVisible(false)
}}
- onChange={change6}
+ onChange={onChange}
onPathChange={onPathChange}
- />{' '}
+ />
>
)
diff --git a/src/packages/cascader/demos/taro/demo7.tsx b/src/packages/cascader/demos/taro/demo7.tsx
new file mode 100644
index 0000000000..7160f12a7d
--- /dev/null
+++ b/src/packages/cascader/demos/taro/demo7.tsx
@@ -0,0 +1,109 @@
+import React, { useEffect, useState } from 'react'
+import { Cascader, Cell, CascaderOption } from '@nutui/nutui-react-taro'
+
+const Demo7 = () => {
+ const [visible, setVisible] = useState(false)
+ const [value, setValue] = useState([])
+ const [options, setOptions] = useState([])
+ const onChange = (value: any, path: any) => {
+ console.log('onchange', value, path)
+ setValue(value)
+ }
+ useEffect(() => {
+ setTimeout(() => {
+ setValue(['浙江', '温州', '鹿城区'])
+ setOptions([
+ {
+ value: '浙江',
+ text: '浙江',
+ children: [
+ {
+ value: '杭州',
+ text: '杭州',
+ disabled: true,
+ children: [
+ { value: '西湖区', text: '西湖区', disabled: true },
+ { value: '余杭区', text: '余杭区' },
+ ],
+ },
+ {
+ value: '温州',
+ text: '温州',
+ children: [
+ { value: '鹿城区', text: '鹿城区' },
+ { value: '瓯海区', text: '瓯海区' },
+ ],
+ },
+ ],
+ },
+ {
+ value: '湖南',
+ text: '湖南',
+ disabled: true,
+ children: [
+ {
+ value: '长沙',
+ text: '长沙',
+ disabled: true,
+ children: [
+ { value: '芙蓉区', text: '芙蓉区' },
+ { value: '岳麓区', text: '岳麓区' },
+ ],
+ },
+ {
+ value: '岳阳',
+ text: '岳阳',
+ children: [
+ { value: '岳阳楼区', text: '岳阳楼区' },
+ { value: '云溪区', text: '云溪区' },
+ ],
+ },
+ ],
+ },
+ {
+ value: '福建',
+ text: '福建',
+ children: [
+ {
+ value: '福州',
+ text: '福州',
+ children: [
+ { value: '鼓楼区', text: '鼓楼区' },
+ { value: '台江区', text: '台江区' },
+ ],
+ },
+ ],
+ },
+ ])
+ }, 300)
+ }, [])
+ return (
+ <>
+ | {
+ setVisible(true)
+ }}
+ />
+ {
+ setVisible(false)
+ }}
+ onChange={onChange}
+ onPathChange={(value, path) => {
+ console.log(value, path)
+ }}
+ />
+ >
+ )
+}
+export default Demo7
diff --git a/src/packages/cascader/doc.en-US.md b/src/packages/cascader/doc.en-US.md
index e382f5d190..cf6e423f1a 100644
--- a/src/packages/cascader/doc.en-US.md
+++ b/src/packages/cascader/doc.en-US.md
@@ -20,6 +20,16 @@ Pass in the `options` list
:::
+### Basic Usage - Uncontroled
+
+Pass in the `options` list
+
+:::demo
+
+
+
+:::
+
### Custom attribute name
use `optionKey` Specify the property name.
@@ -32,7 +42,8 @@ use `optionKey` Specify the property name.
### Async loading
-Use `lazy` to identify whether data needs to be obtained dynamically. At this time, not transmitting `options` means that all data needs to be loaded through `lazyload` . The first loading is distinguished by the `root` attribute. When a non leaf node is encountered, the `lazyload` method will be called. The parameters are the current node and the `resolve` method. Note that the `resolve` method must be called. If it is not transmitted to a child node, it will be treated as a leaf node.
+The `lazy` attribute indicates that automatic data loading is enabled. Cascader implements the logic of automatic data loading through `value` and `onLoad`. The `lazy` attribute must be set at the same time as the `onLoad` attribute.
+The data type returned by the `onLoad` method is `CascaderOption[]`
:::demo
@@ -42,6 +53,9 @@ Use `lazy` to identify whether data needs to be obtained dynamically. At this ti
### Async loading of partial data
+Dynamic loading of some data means that the initial `options` has been set. For example, the data of the user's current address is first obtained and assigned to `options`. The data loading when the user switches provinces or regions is implemented through the `onLoad` method.
+**No need to set the `lazy` attribute. **
+
:::demo
@@ -88,9 +102,9 @@ Use configprovider to set custom CSS
| closeIconPosition | Cancel the button position and inherit the popup component | `string` | `top-right` |
| closeIcon | Customize the close button and inherit the popup component | `ReactNode` | `close` |
| closeable | Whether to display the close button and inherit the popup component | `boolean` | `true` |
-| onLoad | Dynamic loading callback, which takes effect when dynamic loading is enabled | `(node: any, resolve: any) => void` | `-` |
-| onChange | Triggered when the selected value changes | `(value: CascaderValue, params?: any) => void` | `-` |
-| onPathChange | Triggered when the selected item changes | `(value: CascaderValue, params: any) => void` | `-` |
+| onLoad | Dynamic loading callback, which takes effect when dynamic loading is enabled | `(node: any) => void` | `-` |
+| onChange | Triggered when the selected value changes | `(value: CascaderValue, pathNodes?: any) => void` | `-` |
+| onPathChange | Triggered when the selected item changes | `(value: CascaderValue, pathNodes: any) => void` | `-` |
### Ref
diff --git a/src/packages/cascader/doc.md b/src/packages/cascader/doc.md
index 8758db7ea1..e0c5c82c61 100644
--- a/src/packages/cascader/doc.md
+++ b/src/packages/cascader/doc.md
@@ -20,6 +20,16 @@ import { Cascader } from '@nutui/nutui-react'
:::
+### 基础用法-非受控
+
+传入`options`列表
+
+:::demo
+
+
+
+:::
+
### 自定义属性名称
可通过`optionKey` 指定属性名。
@@ -32,7 +42,8 @@ import { Cascader } from '@nutui/nutui-react'
### 动态加载
-使用`lazy`标识是否需要动态获取数据,此时不传`options`代表所有数据都需要通过`onLoad`加载,首次加载通过`root`属性区分,当遇到非叶子节点时会调用`onLoad`方法,参数为当前节点和`resolve`方法,注意`resolve`方法必须调用,不传子节点时会被当做叶子节点处理。
+`lazy` 属性表示开启数据的自动加载,Cascader 内部通过 `value` 和 `onLoad` 实现了自动加载数据的逻辑。`lazy` 属性必须和 `onLoad` 属性同时设置。
+`onLoad`方法返回的数据类型为 `CascaderOption[]`
:::demo
@@ -42,6 +53,9 @@ import { Cascader } from '@nutui/nutui-react'
### 部分数据动态加载
+部分数据动态加载是指已经设置了初始的 `options`,例如,首先获取了用户当前地址的数据,并赋值给 `options`,用户切换省份或地区的数据加载则通过 `onLoad` 方法实现。
+**无需设置 `lazy` 属性。**
+
:::demo
@@ -88,9 +102,9 @@ import { Cascader } from '@nutui/nutui-react'
| closeIconPosition | 取消按钮位置,继承 Popup 组件 | `string` | `top-right` |
| closeIcon | 自定义关闭按钮,继承 Popup 组件 | `ReactNode` | `close` |
| closeable | 是否显示关闭按钮,继承 Popup 组件 | `boolean` | `true` |
-| onLoad | 动态加载回调,开启动态加载时生效 | `(node: any, resolve: any) => void` | `-` |
-| onChange | 选中值改变时触发 | `(value: CascaderValue, params?: any) => void` | `-` |
-| onPathChange | 选中项改变时触发 | `(value: CascaderValue, params: any) => void` | `-` |
+| onLoad | 动态加载回调,开启动态加载时生效 | `(node: any) => void` | `-` |
+| onChange | 选中值改变时触发 | `(value: CascaderValue, pathNodes?: any) => void` | `-` |
+| onPathChange | 选中项改变时触发 | `(value: CascaderValue, pathNodes: any) => void` | `-` |
### Ref
diff --git a/src/packages/cascader/doc.taro.md b/src/packages/cascader/doc.taro.md
index 3d729965ff..d50fa543f3 100644
--- a/src/packages/cascader/doc.taro.md
+++ b/src/packages/cascader/doc.taro.md
@@ -20,6 +20,16 @@ import { Cascader } from '@nutui/nutui-react-taro'
:::
+### 基础用法-非受控
+
+传入`options`列表
+
+:::demo
+
+
+
+:::
+
### 自定义属性名称
可通过`textKey`、`valueKey`、`childrenKey`指定属性名。
@@ -32,7 +42,8 @@ import { Cascader } from '@nutui/nutui-react-taro'
### 动态加载
-使用`lazy`标识是否需要动态获取数据,此时不传`options`代表所有数据都需要通过`onLoad`加载,首次加载通过`root`属性区分,当遇到非叶子节点时会调用`onLoad`方法,参数为当前节点和`resolve`方法,注意`resolve`方法必须调用,不传子节点时会被当做叶子节点处理。
+`lazy` 属性表示开启数据的自动加载,Cascader 内部通过 `value` 和 `onLoad` 实现了自动加载数据的逻辑。`lazy` 属性必须和 `onLoad` 属性同时设置。
+`onLoad`方法返回的数据类型为 `CascaderOption[]`
:::demo
@@ -42,6 +53,9 @@ import { Cascader } from '@nutui/nutui-react-taro'
### 部分数据动态加载
+部分数据动态加载是指已经设置了初始的 `options`,例如,首先获取了用户当前地址的数据,并赋值给 `options`,用户切换省份或地区的数据加载则通过 `onLoad` 方法实现。
+**无需设置 `lazy` 属性。**
+
:::demo
@@ -88,9 +102,9 @@ import { Cascader } from '@nutui/nutui-react-taro'
| closeIconPosition | 取消按钮位置,继承 Popup 组件 | `string` | `top-right` |
| closeIcon | 自定义关闭按钮,继承 Popup 组件 | `ReactNode` | `close` |
| closeable | 是否显示关闭按钮,继承 Popup 组件 | `boolean` | `true` |
-| onLoad | 动态加载回调,开启动态加载时生效 | `(node: any, resolve: any) => void` | `-` |
-| onChange | 选中值改变时触发 | `(value: CascaderValue, params?: any) => void` | `-` |
-| onPathChange | 选中项改变时触发 | `(value: CascaderValue, params: any) => void` | `-` |
+| onLoad | 动态加载回调,开启动态加载时生效 | `(node: any) => void` | `-` |
+| onChange | 选中值改变时触发 | `(value: CascaderValue, pathNodes?: any) => void` | `-` |
+| onPathChange | 选中项改变时触发 | `(value: CascaderValue, pathNodes: any) => void` | `-` |
### Ref
diff --git a/src/packages/cascader/doc.zh-TW.md b/src/packages/cascader/doc.zh-TW.md
index 7ac7f7104f..21321550c5 100644
--- a/src/packages/cascader/doc.zh-TW.md
+++ b/src/packages/cascader/doc.zh-TW.md
@@ -20,6 +20,16 @@ import { Cascader } from '@nutui/nutui-react'
:::
+### 基础用法-非受控
+
+传入`options`列表
+
+:::demo
+
+
+
+:::
+
### 自定義屬性名稱
可通過`textKey`、`valueKey`、`childrenKey`指定屬性名。
@@ -32,7 +42,8 @@ import { Cascader } from '@nutui/nutui-react'
### 動態加載
-使用`lazy`標識是否需要動態獲取數據,此時不傳`options`代表所有數據都需要通過`onLoad`加載,首次加載通過`root`屬性區分,當遇到非葉子節點時會調用`onLoad`方法,參數為當前節點和`resolve`方法,註意`resolve`方法必須調用,不傳子節點時會被當做葉子節點處理。
+`lazy` 屬性表示開啟資料的自動加載,Cascader 內部透過 `value` 和 `onLoad` 實作了自動載入資料的邏輯。 `lazy` 屬性必須同時和 `onLoad` 屬性設定。
+`onLoad`方法傳回的資料類型為 `CascaderOption[]`
:::demo
@@ -42,6 +53,9 @@ import { Cascader } from '@nutui/nutui-react'
### 部分數據動態加載
+部分數據動態載入是指已經設定了初始的 `options`,例如,首先獲取了用戶當前地址的數據,並賦值給 `options`,用戶切換省份或地區的數據加載則透過 `onLoad` 方法實現。
+**無需設定 `lazy` 屬性。 **
+
:::demo
@@ -88,9 +102,9 @@ import { Cascader } from '@nutui/nutui-react'
| closeIconPosition | 取消按鈕位置,繼承 Popup 組件 | `string` | `top-right` |
| closeIcon | 自定義關閉按鈕,繼承 Popup 組件 | `ReactNode` | `close` |
| closeable | 是否顯示關閉按鈕,繼承 Popup 組件 | `boolean` | `true` |
-| onLoad | 動態加載回調,開啟動態加載時生效 | `(node: any, resolve: any) => void` | `-` |
-| onChange | 選中值改變時觸發 | `(value: CascaderValue, params?: any) => void` | `-` |
-| onPathChange | 選中項改變時觸發 | `(value: CascaderValue, params: any) => void` | `-` |
+| onLoad | 動態加載回調,開啟動態加載時生效 | `(node: any) => void` | `-` |
+| onChange | 選中值改變時觸發 | `(value: CascaderValue, pathNodes?: any) => void` | `-` |
+| onPathChange | 選中項改變時觸發 | `(value: CascaderValue, pathNodes: any) => void` | `-` |
### Ref
diff --git a/src/packages/cascader/helper.ts b/src/packages/cascader/helper.ts
deleted file mode 100644
index 2e1e14cf23..0000000000
--- a/src/packages/cascader/helper.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { CascaderOption, CascaderConfig, CascaderFormat } from './types'
-
-export const formatTree = (
- tree: CascaderOption[],
- parent: CascaderOption | null,
- config: CascaderConfig
-): CascaderOption[] =>
- tree.map((node: any) => {
- const {
- value: valueKey = 'value',
- text: textKey = 'text',
- children: childrenKey = 'children',
- } = config
- const {
- [valueKey]: value,
- [textKey]: text,
- [childrenKey]: children,
- ...others
- } = node
- const newNode: CascaderOption = {
- loading: false,
- ...others,
- level: parent ? ((parent && parent.level) || 0) + 1 : 0,
- value,
- text,
- children,
- _parent: parent,
- }
- if (newNode.children && newNode.children.length) {
- newNode.children = formatTree(newNode.children, newNode, config)
- }
- return newNode
- })
-
-export const eachTree = (
- tree: CascaderOption[],
- cb: (node: CascaderOption) => unknown
-): void => {
- let i = 0
- let node: CascaderOption
- while ((node = tree[i++])) {
- if (cb(node) === true) {
- break
- }
- if (node.children && node.children.length) {
- eachTree(node.children, cb)
- }
- }
-}
-
-const defaultConvertConfig = {
- topId: null,
- idKey: 'id',
- pidKey: 'pid',
- sortKey: '',
-}
-export const convertListToOptions = (
- list: CascaderOption[],
- options: CascaderFormat
-): CascaderOption[] => {
- const mergedOptions = {
- ...defaultConvertConfig,
- ...(options || {}),
- }
- const { topId, idKey, pidKey, sortKey } = mergedOptions
- let result: CascaderOption[] = []
- let map: any = {}
- list.forEach((node: any) => {
- node = { ...node }
- const { [idKey]: id, [pidKey]: pid } = node
- const children = (map[pid] = map[pid] || [])
- if (!result.length && pid === topId) {
- result = children
- }
- children.push(node)
- node.children = map[id] || (map[id] = [])
- })
-
- if (sortKey) {
- Object.keys(map).forEach((i) => {
- if (map[i].length > 1) {
- map[i].sort((a: any, b: any) => a[sortKey] - b[sortKey])
- }
- })
- }
- map = null
- return result
-}
diff --git a/src/packages/cascader/tree.ts b/src/packages/cascader/tree.ts
deleted file mode 100644
index a4e0ce24b2..0000000000
--- a/src/packages/cascader/tree.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import { CascaderOption, CascaderConfig, CascaderValue } from './types'
-import { formatTree, eachTree } from './helper'
-
-class Tree {
- nodes: CascaderOption[]
-
- readonly config: CascaderConfig
-
- constructor(nodes: CascaderOption[], config?: CascaderConfig) {
- this.config = {
- value: 'value',
- text: 'text',
- children: 'children',
- ...(config || {}),
- }
- this.nodes = formatTree(nodes, null, this.config)
- }
-
- updateChildren(nodes: CascaderOption[], parent: CascaderOption | null): void {
- if (!parent) {
- this.nodes = formatTree(nodes, null, this.config)
- } else {
- parent.children = formatTree(nodes, parent, this.config)
- }
- }
-
- // for test
- getNodeByValue(value: CascaderOption['value']): CascaderOption | void {
- let foundNode
- eachTree(this.nodes, (node: CascaderOption) => {
- if (node.value === value) {
- foundNode = node
- return true
- }
- return null
- })
- return foundNode
- }
-
- getPathNodesByValue(value: CascaderValue): CascaderOption[] {
- if (!value.length) {
- return []
- }
-
- const pathNodes = []
- let currentNodes: CascaderOption[] | void = this.nodes
-
- while (currentNodes && currentNodes.length) {
- const foundNode: CascaderOption | void = currentNodes.find(
- (node) => node.value === value[node.level as number]
- )
-
- if (!foundNode) {
- break
- }
-
- pathNodes.push(foundNode)
- currentNodes = foundNode.children
- }
-
- return pathNodes
- }
-
- // eslint-disable-next-line class-methods-use-this
- isLeaf = (node: CascaderOption, lazy: boolean): boolean => {
- const { leaf, children } = node
- const hasChildren = Array.isArray(children) && Boolean(children.length)
- return leaf || (!hasChildren && !lazy)
- }
-
- hasChildren = (node: CascaderOption, lazy: boolean): boolean => {
- const isLeaf = this.isLeaf(node, lazy)
-
- if (isLeaf) {
- return false
- }
-
- const { children } = node
- return Array.isArray(children) && Boolean(children.length)
- }
-}
-
-export default Tree
diff --git a/src/packages/cascader/types.ts b/src/packages/cascader/types.ts
index 008a3d07c4..3e57cfb998 100644
--- a/src/packages/cascader/types.ts
+++ b/src/packages/cascader/types.ts
@@ -11,9 +11,9 @@ export interface CascaderOption {
disabled?: boolean
children?: CascaderOption[]
leaf?: boolean
- level?: number
loading?: boolean
- root?: boolean
+
+ [key: string]: any
}
export interface CascaderConfig {
@@ -36,3 +36,8 @@ export interface CascaderFormat {
pidKey?: string
sortKey?: string
}
+
+export type CascaderActions = {
+ open: () => void
+ close: () => void
+}
diff --git a/src/packages/cascader/utils.ts b/src/packages/cascader/utils.ts
new file mode 100644
index 0000000000..872fdc7cb2
--- /dev/null
+++ b/src/packages/cascader/utils.ts
@@ -0,0 +1,61 @@
+import { CascaderOption, CascaderFormat, CascaderOptionKey } from './types'
+
+export const normalizeOptions = (
+ options: CascaderOption[],
+ keyMap: CascaderOptionKey
+): CascaderOption[] | undefined => {
+ if (!options) return undefined
+ return options.map((opt: any) => {
+ const {
+ [keyMap.textKey]: text,
+ [keyMap.valueKey]: value,
+ [keyMap.childrenKey]: children,
+ ...others
+ } = opt
+ return {
+ text,
+ value,
+ children: normalizeOptions(children, keyMap),
+ ...others,
+ } as CascaderOption
+ })
+}
+
+export const normalizeListOptions = (
+ options: CascaderOption[],
+ format: CascaderFormat
+) => {
+ const defaultConvertConfig = {
+ topId: null,
+ idKey: 'id',
+ pidKey: 'pid',
+ sortKey: 'sortKey',
+ }
+ const mergedFormat = {
+ ...defaultConvertConfig,
+ ...format,
+ }
+ const { topId, idKey, pidKey, sortKey } = mergedFormat
+ const map: { [key: string]: CascaderOption[] } = {}
+ options.forEach((opt) => {
+ const { [pidKey]: pid, [idKey]: id, ...others } = opt as any
+ const newNode: any = { pid, id, ...others }
+ if (map[pid]) {
+ map[pid].push(newNode)
+ } else {
+ map[pid] = [newNode]
+ }
+ })
+ for (const key in map) {
+ // eslint-disable-next-line no-continue
+ if (!Object.prototype.hasOwnProperty.call(map, key)) continue
+ map[key].sort((a: any, b: any) => a[sortKey] - b[sortKey])
+ map[key].forEach((option: any) => {
+ if (map[option.id]) {
+ option.children = map[option.id]
+ }
+ })
+ }
+ // @ts-ignore
+ return map[topId]
+}
diff --git a/src/utils/is-empty.ts b/src/utils/is-empty.ts
new file mode 100644
index 0000000000..c4570c2773
--- /dev/null
+++ b/src/utils/is-empty.ts
@@ -0,0 +1,6 @@
+export const isEmpty = (p: T): boolean => {
+ if (p === null || p === undefined) return true
+ if (typeof p === 'object' && Object.keys(p).length === 0) return true
+ if (Array.isArray(p) && p.length === 0) return true
+ return false
+}
| | | | | | | | | | | | | |