@beppla/tapas-ui 1.5.2 → 1.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/commonjs/Alert/README.md +75 -0
  2. package/commonjs/BarChart/README.md +172 -0
  3. package/commonjs/Button/README.md +108 -0
  4. package/commonjs/Calendar/Calendar.base.js +1 -1
  5. package/commonjs/Calendar/Calendar.base.js.map +1 -1
  6. package/commonjs/Calendar/README.md +410 -0
  7. package/commonjs/Card/README.md +126 -0
  8. package/commonjs/CheckBox/README.md +147 -0
  9. package/commonjs/CircularProgress/README.md +70 -0
  10. package/commonjs/Collapsible/README.md +140 -0
  11. package/commonjs/ComboChart/README.md +124 -0
  12. package/commonjs/DashboardCard/README.md +120 -0
  13. package/commonjs/DataTable/README.md +159 -0
  14. package/commonjs/DeviceSelectionModal/README.md +124 -0
  15. package/commonjs/DraggableFlatList/README.md +35 -0
  16. package/commonjs/Drawer/README.md +175 -0
  17. package/commonjs/Dropdown/Dropdown.js +60 -30
  18. package/commonjs/Dropdown/Dropdown.js.map +1 -1
  19. package/commonjs/Dropdown/README.md +230 -0
  20. package/commonjs/ExternalLink/README.md +81 -0
  21. package/commonjs/Gantt/README.md +155 -0
  22. package/commonjs/Grid/README.md +197 -0
  23. package/commonjs/Header/README.md +109 -0
  24. package/commonjs/HelloWave/README.md +28 -0
  25. package/commonjs/Hoverable/Hoverable.js.map +1 -1
  26. package/commonjs/IconText/README.md +99 -0
  27. package/commonjs/Image/PreviewImg/README.md +100 -0
  28. package/commonjs/Image/README.md +88 -0
  29. package/commonjs/Input/Input.js +60 -4
  30. package/commonjs/Input/Input.js.map +1 -1
  31. package/commonjs/Layout/README.md +174 -0
  32. package/commonjs/LineChart/README.md +181 -0
  33. package/commonjs/ListItem/README.md +122 -0
  34. package/commonjs/MessageBox/MessageBox.js +7 -1
  35. package/commonjs/MessageBox/MessageBox.js.map +1 -1
  36. package/commonjs/MessageBox/README.md +120 -0
  37. package/commonjs/Navigation/README.md +197 -0
  38. package/commonjs/NumericInput/README.md +95 -0
  39. package/commonjs/Overlay/README.md +84 -0
  40. package/commonjs/Pagination/README.md +106 -0
  41. package/commonjs/PieChart/README.md +212 -0
  42. package/commonjs/Popover/README.md +82 -0
  43. package/commonjs/Progress/README.md +106 -0
  44. package/commonjs/RadioButton/README.md +85 -0
  45. package/commonjs/ScanButton/README.md +72 -0
  46. package/commonjs/SearchInput/SearchInput.js.map +1 -1
  47. package/commonjs/SheetTitle/README.md +89 -0
  48. package/commonjs/Shell/README.md +152 -0
  49. package/commonjs/Shell/Shell.js.map +1 -1
  50. package/commonjs/StatisticCard/README.md +129 -0
  51. package/commonjs/Status/README.md +75 -0
  52. package/commonjs/Steps/README.md +76 -0
  53. package/commonjs/Switch/Switch.js +101 -0
  54. package/commonjs/Switch/Switch.js.map +1 -0
  55. package/commonjs/Tab/README.md +161 -0
  56. package/commonjs/Tag/README.md +93 -0
  57. package/commonjs/Task/README.md +110 -0
  58. package/commonjs/Text/README.md +97 -0
  59. package/commonjs/TextArea/README.md +127 -0
  60. package/commonjs/TextArea/TextArea.js +4 -2
  61. package/commonjs/TextArea/TextArea.js.map +1 -1
  62. package/commonjs/Theme/README.md +161 -0
  63. package/commonjs/Theme/makeStyles.js +30 -0
  64. package/commonjs/Theme/makeStyles.js.map +1 -0
  65. package/commonjs/Theme/withTheme.js +91 -0
  66. package/commonjs/Theme/withTheme.js.map +1 -0
  67. package/commonjs/Timeline/README.md +111 -0
  68. package/commonjs/Toast/README.md +96 -0
  69. package/commonjs/Upload/Upload.js +126 -0
  70. package/commonjs/Upload/Upload.js.map +1 -0
  71. package/commonjs/index.js +24 -4
  72. package/commonjs/index.js.map +1 -1
  73. package/module/Alert/README.md +75 -0
  74. package/module/BarChart/README.md +172 -0
  75. package/module/Button/README.md +108 -0
  76. package/module/Calendar/Calendar.base.js +1 -1
  77. package/module/Calendar/Calendar.base.js.map +1 -1
  78. package/module/Calendar/README.md +410 -0
  79. package/module/Card/README.md +126 -0
  80. package/module/CheckBox/README.md +147 -0
  81. package/module/CircularProgress/README.md +70 -0
  82. package/module/Collapsible/README.md +140 -0
  83. package/module/ComboChart/README.md +124 -0
  84. package/module/DashboardCard/README.md +120 -0
  85. package/module/DataTable/README.md +159 -0
  86. package/module/DeviceSelectionModal/README.md +124 -0
  87. package/module/DraggableFlatList/README.md +35 -0
  88. package/module/Drawer/README.md +175 -0
  89. package/module/Dropdown/Dropdown.js +60 -30
  90. package/module/Dropdown/Dropdown.js.map +1 -1
  91. package/module/Dropdown/README.md +230 -0
  92. package/module/ExternalLink/README.md +81 -0
  93. package/module/Gantt/README.md +155 -0
  94. package/module/Grid/README.md +197 -0
  95. package/module/Header/README.md +109 -0
  96. package/module/HelloWave/README.md +28 -0
  97. package/module/Hoverable/Hoverable.js.map +1 -1
  98. package/module/IconText/README.md +99 -0
  99. package/module/Image/PreviewImg/README.md +100 -0
  100. package/module/Image/README.md +88 -0
  101. package/module/Input/Input.js +60 -4
  102. package/module/Input/Input.js.map +1 -1
  103. package/module/Layout/README.md +174 -0
  104. package/module/LineChart/README.md +181 -0
  105. package/module/ListItem/README.md +122 -0
  106. package/module/MessageBox/MessageBox.js +8 -2
  107. package/module/MessageBox/MessageBox.js.map +1 -1
  108. package/module/MessageBox/README.md +120 -0
  109. package/module/Navigation/README.md +197 -0
  110. package/module/NumericInput/README.md +95 -0
  111. package/module/Overlay/README.md +84 -0
  112. package/module/Pagination/README.md +106 -0
  113. package/module/PieChart/README.md +212 -0
  114. package/module/Popover/README.md +82 -0
  115. package/module/Progress/README.md +106 -0
  116. package/module/RadioButton/README.md +85 -0
  117. package/module/ScanButton/README.md +72 -0
  118. package/module/SearchInput/SearchInput.js.map +1 -1
  119. package/module/SheetTitle/README.md +89 -0
  120. package/module/Shell/README.md +152 -0
  121. package/module/Shell/Shell.js.map +1 -1
  122. package/module/StatisticCard/README.md +129 -0
  123. package/module/Status/README.md +75 -0
  124. package/module/Steps/README.md +76 -0
  125. package/module/Switch/Switch.js +96 -0
  126. package/module/Switch/Switch.js.map +1 -0
  127. package/module/Tab/README.md +161 -0
  128. package/module/Tag/README.md +93 -0
  129. package/module/Task/README.md +110 -0
  130. package/module/Text/README.md +97 -0
  131. package/module/TextArea/README.md +127 -0
  132. package/module/TextArea/TextArea.js +4 -2
  133. package/module/TextArea/TextArea.js.map +1 -1
  134. package/module/Theme/README.md +161 -0
  135. package/module/Theme/makeStyles.js +24 -0
  136. package/module/Theme/makeStyles.js.map +1 -0
  137. package/module/Theme/withTheme.js +82 -0
  138. package/module/Theme/withTheme.js.map +1 -0
  139. package/module/Timeline/README.md +111 -0
  140. package/module/Toast/README.md +96 -0
  141. package/module/Upload/Upload.js +121 -0
  142. package/module/Upload/Upload.js.map +1 -0
  143. package/module/index.js +11 -3
  144. package/module/index.js.map +1 -1
  145. package/package.json +1 -1
  146. package/typescript/Dropdown/Dropdown.d.ts +20 -0
  147. package/typescript/Dropdown/Dropdown.d.ts.map +1 -1
  148. package/typescript/Grid/FixedSizeGrid.d.ts +1 -3
  149. package/typescript/Grid/FixedSizeGrid.d.ts.map +1 -1
  150. package/typescript/Grid/Grid.base.d.ts +1 -3
  151. package/typescript/Grid/Grid.base.d.ts.map +1 -1
  152. package/typescript/Grid/VariableSizeGrid.d.ts +1 -3
  153. package/typescript/Grid/VariableSizeGrid.d.ts.map +1 -1
  154. package/typescript/Input/Input.d.ts +5 -0
  155. package/typescript/Input/Input.d.ts.map +1 -1
  156. package/typescript/MessageBox/MessageBox.d.ts.map +1 -1
  157. package/typescript/SearchInput/SearchInput.d.ts +4 -0
  158. package/typescript/SearchInput/SearchInput.d.ts.map +1 -1
  159. package/typescript/Switch/Switch.d.ts +15 -0
  160. package/typescript/Switch/Switch.d.ts.map +1 -0
  161. package/typescript/TextArea/TextArea.d.ts +2 -0
  162. package/typescript/TextArea/TextArea.d.ts.map +1 -1
  163. package/typescript/Theme/makeStyles.d.ts +11 -0
  164. package/typescript/Theme/makeStyles.d.ts.map +1 -0
  165. package/typescript/Theme/withTheme.d.ts +12 -0
  166. package/typescript/Theme/withTheme.d.ts.map +1 -0
  167. package/typescript/Upload/Upload.d.ts +25 -0
  168. package/typescript/Upload/Upload.d.ts.map +1 -0
  169. package/typescript/WebViewBridge/useWebViewBridge.d.ts +1 -1
  170. package/typescript/WebViewBridge/useWebViewBridge.d.ts.map +1 -1
  171. package/typescript/common/hooks/useBridgelessFix.d.ts +1 -1
  172. package/typescript/index.d.ts +8 -2
  173. package/typescript/index.d.ts.map +1 -1
@@ -0,0 +1,124 @@
1
+ # DeviceSelectionModal
2
+
3
+ 设备选择模态对话框组件,用于从设备列表中选择一个设备。支持加载状态、错误处理、重试机制和文本国际化,适合打印机选择、终端绑定等硬件设备关联场景。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 单选设备列表(Radio Button 样式)
8
+ - ✅ 加载中状态展示(ActivityIndicator)
9
+ - ✅ 错误状态展示 + 重试按钮
10
+ - ✅ 空列表提示
11
+ - ✅ 设备描述信息展示
12
+ - ✅ 未选择时确认按钮自动禁用
13
+ - ✅ 关闭时恢复原始选中状态
14
+ - ✅ 全部文本支持国际化(i18n props)
15
+ - ✅ 淡入淡出动画
16
+ - ✅ 主题色适配
17
+
18
+ ## 安装使用
19
+
20
+ ```tsx
21
+ import { DeviceSelectionModal } from '@beppla/tapas-ui';
22
+ ```
23
+
24
+ ## Props
25
+
26
+ | 属性 | 类型 | 默认值 | 说明 |
27
+ |------|------|--------|------|
28
+ | visible | `boolean` | - | 是否显示(必填) |
29
+ | devices | `Device[]` | - | 设备列表(必填) |
30
+ | selectedDeviceId | `string` | - | 当前选中的设备 ID |
31
+ | onClose | `() => void` | - | 关闭回调(必填) |
32
+ | onConfirm | `(deviceId: string) => void` | - | 确认选择回调(必填) |
33
+ | title | `string` | - | 对话框标题 |
34
+ | isLoading | `boolean` | `false` | 是否加载中 |
35
+ | error | `string \| null` | `null` | 错误信息 |
36
+ | onRetry | `() => void` | - | 重试按钮回调 |
37
+ | selectDeviceText | `string` | `'Select Device'` | 标题文本 |
38
+ | pleaseSelectDeviceText | `string` | `'Please select a device'` | 副标题文本 |
39
+ | loadingDevicesText | `string` | `'Loading devices...'` | 加载中文本 |
40
+ | noDevicesAvailableText | `string` | `'No devices available'` | 空列表文本 |
41
+ | closeText | `string` | `'Close'` | 关闭按钮文本 |
42
+ | confirmText | `string` | `'Confirm'` | 确认按钮文本 |
43
+ | retryText | `string` | `'Retry'` | 重试按钮文本 |
44
+ | testID | `string` | - | 测试标识 |
45
+
46
+ ### Device 接口
47
+
48
+ ```tsx
49
+ interface Device {
50
+ id: string;
51
+ name: string;
52
+ description?: string;
53
+ }
54
+ ```
55
+
56
+ ## 使用示例
57
+
58
+ ### 基础用法
59
+
60
+ ```tsx
61
+ const [visible, setVisible] = useState(false);
62
+ const devices = [
63
+ { id: '1', name: 'Printer A', description: 'Kitchen printer' },
64
+ { id: '2', name: 'Printer B', description: 'Receipt printer' },
65
+ ];
66
+
67
+ <DeviceSelectionModal
68
+ visible={visible}
69
+ devices={devices}
70
+ onClose={() => setVisible(false)}
71
+ onConfirm={(deviceId) => {
72
+ console.log('Selected:', deviceId);
73
+ setVisible(false);
74
+ }}
75
+ />
76
+ ```
77
+
78
+ ### 加载状态
79
+
80
+ ```tsx
81
+ <DeviceSelectionModal
82
+ visible={true}
83
+ devices={[]}
84
+ isLoading={true}
85
+ onClose={() => setVisible(false)}
86
+ onConfirm={() => {}}
87
+ />
88
+ ```
89
+
90
+ ### 错误状态 + 重试
91
+
92
+ ```tsx
93
+ <DeviceSelectionModal
94
+ visible={true}
95
+ devices={[]}
96
+ error="Failed to load devices"
97
+ onRetry={() => fetchDevices()}
98
+ onClose={() => setVisible(false)}
99
+ onConfirm={() => {}}
100
+ />
101
+ ```
102
+
103
+ ### 国际化
104
+
105
+ ```tsx
106
+ <DeviceSelectionModal
107
+ visible={true}
108
+ devices={devices}
109
+ selectDeviceText="Select Printer"
110
+ pleaseSelectDeviceText="Choose a printer for this station"
111
+ confirmText="Bind"
112
+ closeText="Cancel"
113
+ onClose={() => setVisible(false)}
114
+ onConfirm={handleConfirm}
115
+ />
116
+ ```
117
+
118
+ ## 注意事项
119
+
120
+ - 关闭对话框时会将内部选中状态恢复为 `selectedDeviceId`(即取消未确认的选择)
121
+ - 未选中设备时确认按钮禁用(灰色样式)
122
+ - 对话框最大宽度 400px,设备列表最大高度 300px
123
+ - `title` 和 `selectDeviceText` 同时存在时,`title` 优先
124
+ - 需在 `ThemeProvider` 内使用
@@ -0,0 +1,35 @@
1
+ # DraggableFlatList
2
+
3
+ 可拖拽列表组件占位符。当前为空实现,预留用于后续开发支持拖拽排序的列表功能。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 组件骨架已搭建,导出可用
8
+ - (待开发) 拖拽排序
9
+ - (待开发) 拖拽动画
10
+ - (待开发) 自定义渲染
11
+
12
+ ## 安装使用
13
+
14
+ ```tsx
15
+ import { DraggableFlatList } from '@beppla/tapas-ui';
16
+ ```
17
+
18
+ ## Props
19
+
20
+ | 属性 | 类型 | 默认值 | 说明 |
21
+ |------|------|--------|------|
22
+ | testID | `string` | - | 测试标识 |
23
+
24
+ ## 使用示例
25
+
26
+ ### 基础用法
27
+
28
+ ```tsx
29
+ <DraggableFlatList testID="draggable-list" />
30
+ ```
31
+
32
+ ## 注意事项
33
+
34
+ - 当前为空 View 占位实现,无实际拖拽功能
35
+ - 后续计划集成 `react-native-draggable-flatlist` 或自定义实现
@@ -0,0 +1,175 @@
1
+ # Drawer
2
+
3
+ 抽屉面板组件,从屏幕右侧滑出的浮层面板,支持自定义头部、内容区域和页脚,常用于筛选、详情展示等场景。
4
+
5
+ ## 功能特性
6
+
7
+ - 从右侧滑出的 Overlay 抽屉面板
8
+ - 响应式宽度(桌面端 55%,移动端 100%)
9
+ - 可自定义标题、标题图标和状态标签(Status 组件)
10
+ - 支持 showHeader / showFooter 控制头部和页脚显示
11
+ - 支持自定义 headerComponent 和 footerComponent 完全替换
12
+ - 点击背景遮罩自动关闭(onBackdropPress)
13
+ - 内容区域自动 ScrollView 滚动
14
+ - 移动端自动适配 Safe Area(useSafeAreaInsets)
15
+ - 页脚包含左侧文本按钮和右侧主按钮
16
+
17
+ ## 安装使用
18
+
19
+ ```tsx
20
+ import { Drawer } from '@beppla/tapas-ui';
21
+ ```
22
+
23
+ ## Props
24
+
25
+ | 属性 | 类型 | 默认值 | 说明 |
26
+ |------|------|--------|------|
27
+ | visible | `boolean` | `false` | 抽屉是否可见 |
28
+ | title | `string` | - | 抽屉标题 |
29
+ | titleIcon | `string` | - | 标题左侧图标名称 |
30
+ | titleIconOnPress | `() => void` | - | 标题图标点击回调 |
31
+ | titleStatus | `string` | - | 状态标签文本 |
32
+ | statusType | `STATUS_TYPE` | `'unavailable'` | 状态类型(success/warning/unavailable 等) |
33
+ | showHeader | `boolean` | `true` | 是否显示头部 |
34
+ | showFooter | `boolean` | `false` | 是否显示页脚 |
35
+ | onClose | `() => void` | - | 关闭回调(背景遮罩点击时触发) |
36
+ | onClear | `() => void` | - | 清空按钮回调(未设时回退到 onClose) |
37
+ | clearText | `string` | - | 清空按钮文本 |
38
+ | clearDisable | `boolean` | `true` | 清空按钮是否禁用 |
39
+ | overlayStyle | `StyleProp<ViewStyle>` | - | 抽屉覆盖层自定义样式 |
40
+ | middleSectionStyle | `StyleProp<ViewStyle>` | - | 内容区域自定义样式 |
41
+ | leftButtonText | `string` | - | 页脚左侧按钮文本 |
42
+ | leftButtonTextStyle | `StyleProp<ViewStyle>` | - | 页脚左侧按钮文本样式 |
43
+ | leftButtonOnPress | `() => void` | - | 页脚左侧按钮回调 |
44
+ | rightButtonText | `string` | - | 页脚右侧按钮文本 |
45
+ | rightButtonStyle | `StyleProp<ViewStyle>` | - | 页脚右侧按钮样式 |
46
+ | rightButtonOnPress | `() => void` | - | 页脚右侧按钮回调 |
47
+ | component | `React.ReactNode` | - | 内容组件(渲染在 children 之前) |
48
+ | children | `React.ReactNode` | - | 内容子组件 |
49
+ | headerComponent | `React.ReactNode` | - | 自定义头部组件(替换默认头部) |
50
+ | footerComponent | `React.ReactNode` | - | 自定义页脚组件(额外渲染在 showFooter 之后) |
51
+ | testID | `string` | - | 测试 ID |
52
+
53
+ ## 使用示例
54
+
55
+ ### 基础用法
56
+
57
+ ```tsx
58
+ import { Drawer } from '@beppla/tapas-ui';
59
+ import { useState } from 'react';
60
+ import { Text, Button } from 'react-native';
61
+
62
+ export default function App() {
63
+ const [visible, setVisible] = useState(false);
64
+
65
+ return (
66
+ <>
67
+ <Button title="Open Drawer" onPress={() => setVisible(true)} />
68
+ <Drawer
69
+ visible={visible}
70
+ title="Filters"
71
+ onClose={() => setVisible(false)}
72
+ >
73
+ <Text>Drawer content here</Text>
74
+ </Drawer>
75
+ </>
76
+ );
77
+ }
78
+ ```
79
+
80
+ ### 带状态标签和图标
81
+
82
+ ```tsx
83
+ <Drawer
84
+ visible={visible}
85
+ title="Order Details"
86
+ titleIcon="back"
87
+ titleIconOnPress={() => setVisible(false)}
88
+ titleStatus="Active"
89
+ statusType="success"
90
+ onClose={() => setVisible(false)}
91
+ >
92
+ <Text>Order information</Text>
93
+ </Drawer>
94
+ ```
95
+
96
+ ### 完整功能(头部 + 内容 + 页脚)
97
+
98
+ ```tsx
99
+ <Drawer
100
+ visible={visible}
101
+ title="Filters"
102
+ titleIcon="back"
103
+ titleIconOnPress={() => setVisible(false)}
104
+ clearText="Clear"
105
+ clearDisable={false}
106
+ onClear={() => resetFilters()}
107
+ onClose={() => setVisible(false)}
108
+ showFooter={true}
109
+ leftButtonText="Close"
110
+ leftButtonOnPress={() => setVisible(false)}
111
+ rightButtonText="Show all results"
112
+ rightButtonOnPress={() => applyFilters()}
113
+ >
114
+ <Text>Filter options here</Text>
115
+ </Drawer>
116
+ ```
117
+
118
+ ### 自定义头部和页脚
119
+
120
+ ```tsx
121
+ <Drawer
122
+ visible={visible}
123
+ headerComponent={
124
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between', padding: 16 }}>
125
+ <Text style={{ fontSize: 18, fontWeight: 'bold' }}>Custom Header</Text>
126
+ <Button title="X" onPress={() => setVisible(false)} />
127
+ </View>
128
+ }
129
+ footerComponent={
130
+ <View style={{ flexDirection: 'row', justifyContent: 'flex-end', gap: 8 }}>
131
+ <Button title="Cancel" onPress={() => setVisible(false)} />
132
+ <Button title="Save" onPress={() => handleSave()} />
133
+ </View>
134
+ }
135
+ onClose={() => setVisible(false)}
136
+ >
137
+ <Text>Content with custom header and footer</Text>
138
+ </Drawer>
139
+ ```
140
+
141
+ ### 通过 DrawerContext 使用
142
+
143
+ ```tsx
144
+ import { useContext } from 'react';
145
+ import { DrawerContext } from '@beppla/tapas-ui/components/Layout/DrawerContext';
146
+
147
+ function MyComponent() {
148
+ const { open, close } = useContext(DrawerContext);
149
+
150
+ const showDrawer = () => {
151
+ open({
152
+ title: 'Dynamic Drawer',
153
+ component: <Text>Dynamic content</Text>,
154
+ showFooter: true,
155
+ rightButtonText: 'Confirm',
156
+ rightButtonOnPress: () => {
157
+ handleConfirm();
158
+ close();
159
+ },
160
+ });
161
+ };
162
+
163
+ return <Button title="Open" onPress={showDrawer} />;
164
+ }
165
+ ```
166
+
167
+ ## 注意事项
168
+
169
+ - 桌面端抽屉宽度为屏幕的 55%,移动端为 100%
170
+ - `clearDisable` 默认为 `true`(禁用状态),需显式设为 `false` 才能启用清空按钮
171
+ - `onClear` 未设置时,清空按钮会回退使用 `onClose` 回调
172
+ - `showFooter` 默认为 `false`,需显式设为 `true` 以显示页脚按钮区域
173
+ - `footerComponent` 独立于 `showFooter`,即使 `showFooter=false`,`footerComponent` 仍会渲染
174
+ - 内容区域使用 ScrollView 包裹,`contentContainerStyle` 设置了 `flexGrow: 1`
175
+ - 移动端会通过 `useSafeAreaInsets` 自动添加顶部安全区域间距
@@ -235,6 +235,7 @@ const Dropdown = ({
235
235
  dropdownType = "clear",
236
236
  arrowIcon: _arrowIcon = false,
237
237
  onSelect,
238
+ attachSelect,
238
239
  backgroundColor,
239
240
  labelColor,
240
241
  state = "normal",
@@ -246,17 +247,34 @@ const Dropdown = ({
246
247
  extendBtnIcon,
247
248
  emptyText,
248
249
  onExtendBtnPress,
250
+ attachExtendBtn,
249
251
  noLabelAnim = false,
250
252
  radius = 12,
251
253
  modalVisible,
252
254
  customPopoverContent,
253
255
  setModalVisible,
256
+ visible,
257
+ setVisible,
258
+ dropdownSubWidth,
259
+ dropdownSubHeight,
260
+ empytText,
261
+ leftIcon,
262
+ marginTopOffset = 0,
263
+ height,
254
264
  iconStyle,
255
265
  label,
256
266
  required,
257
267
  testID,
258
268
  ...props
259
269
  }) => {
270
+ // 向下兼容:deprecated props 优先级低于新 props
271
+ const resolvedOnSelect = onSelect ?? attachSelect;
272
+ const resolvedOnExtendBtnPress = onExtendBtnPress ?? attachExtendBtn;
273
+ const resolvedModalVisible = modalVisible ?? visible;
274
+ const resolvedSetModalVisible = setModalVisible ?? setVisible;
275
+ const resolvedSubWidth = subWidth ?? dropdownSubWidth;
276
+ const resolvedSubHeight = subHeight ?? dropdownSubHeight;
277
+ const resolvedEmptyText = emptyText ?? empytText;
260
278
  const styles = useStyles(props);
261
279
  const theme = (0, _themed.useTheme)();
262
280
  const [selected_old, selectedItem] = _react.default.useState(value);
@@ -269,7 +287,7 @@ const Dropdown = ({
269
287
  top: 0,
270
288
  left: 0
271
289
  });
272
- const [dropdownWidthCalc, setDropdownWidthCalc] = (0, _react.useState)(subWidth ?? 151);
290
+ const [dropdownWidthCalc, setDropdownWidthCalc] = (0, _react.useState)(resolvedSubWidth ?? 151);
273
291
  const [selectedItemKey, setSelectedItemKey] = (0, _react.useState)(selected ?? "");
274
292
  const [top, setTop] = (0, _react.useState)(18);
275
293
  const [optionListHeight, setOptionListHeight] = (0, _react.useState)(0);
@@ -286,17 +304,17 @@ const Dropdown = ({
286
304
  setSelectedItemKey(selected ?? "");
287
305
  }, [selected]);
288
306
  (0, _react.useEffect)(() => {
289
- if (typeof modalVisible === "boolean" && modalVisible !== undefined) {
290
- setInternalModalVisible(modalVisible);
307
+ if (typeof resolvedModalVisible === "boolean" && resolvedModalVisible !== undefined) {
308
+ setInternalModalVisible(resolvedModalVisible);
291
309
  }
292
- }, [modalVisible]);
310
+ }, [resolvedModalVisible]);
293
311
 
294
312
  // 动态更新下拉容器宽度(支持运行时宽度变化)
295
313
  (0, _react.useEffect)(() => {
296
- if (subWidth && internalModalVisible) {
297
- setDropdownWidthCalc(subWidth);
314
+ if (resolvedSubWidth && internalModalVisible) {
315
+ setDropdownWidthCalc(resolvedSubWidth);
298
316
  }
299
- }, [subWidth, internalModalVisible]);
317
+ }, [resolvedSubWidth, internalModalVisible]);
300
318
 
301
319
  // 标签动画效果
302
320
  (0, _react.useEffect)(() => {
@@ -326,8 +344,8 @@ const Dropdown = ({
326
344
  if (buttonRef.current) {
327
345
  buttonRef.current.measure((_fx, _fy, width, height, px, py) => {
328
346
  const window = _reactNative.Dimensions.get("window");
329
- const dropdownHeight = subHeight ?? Math.min(40 * dropdownItems.length + 24, 224);
330
- const dropdownWidth = Math.max(width, subWidth ?? 151);
347
+ const dropdownHeight = resolvedSubHeight ?? Math.min(40 * dropdownItems.length + 24, 224);
348
+ const dropdownWidth = Math.max(width, resolvedSubWidth ?? 151);
331
349
  setDropdownWidthCalc(dropdownWidth);
332
350
 
333
351
  // 计算显示位置
@@ -341,8 +359,8 @@ const Dropdown = ({
341
359
  top,
342
360
  left
343
361
  });
344
- if (setModalVisible) {
345
- setModalVisible(true);
362
+ if (resolvedSetModalVisible) {
363
+ resolvedSetModalVisible(true);
346
364
  } else {
347
365
  setInternalModalVisible(true);
348
366
  }
@@ -350,8 +368,8 @@ const Dropdown = ({
350
368
  }
351
369
  };
352
370
  const closeModal = () => {
353
- if (setModalVisible) {
354
- setModalVisible(false);
371
+ if (resolvedSetModalVisible) {
372
+ resolvedSetModalVisible(false);
355
373
  } else {
356
374
  setInternalModalVisible(false);
357
375
  }
@@ -369,8 +387,10 @@ const Dropdown = ({
369
387
  style: [styles.modalContainer, width ? {
370
388
  width: width
371
389
  } : null, {
372
- minHeight: 40 + (label ? 7 : 0) + (showStateMsg ? 15 : 0)
373
- }],
390
+ minHeight: (height || 40) + (label ? 7 : 0) + (showStateMsg ? 15 : 0)
391
+ }, height ? {
392
+ maxHeight: height + (label ? 7 : 0) + (showStateMsg ? 15 : 0)
393
+ } : null],
374
394
  children: [label && !noLabelAnim && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
375
395
  style: [styles.labelCon, {
376
396
  top: topAnim
@@ -402,22 +422,32 @@ const Dropdown = ({
402
422
  borderRadius: radius
403
423
  } : null,
404
424
  // 统一主体容器的位置,无论是否使用 customPopoverContent
405
- label && !noLabelAnim ? {
406
- marginTop: 7
425
+ label ? {
426
+ marginTop: 7 + marginTopOffset
407
427
  } : null, noLabelAnim && label && backgroundColor ? {
408
428
  backgroundColor
409
429
  } : null, state === "error" ? {
410
430
  borderColor: theme.theme.colors.error
411
431
  } : null, props.disabled ? {
412
432
  borderColor: theme.theme.colors.grey3
413
- } : null,
433
+ } : null, leftIcon && {
434
+ gap: 8,
435
+ paddingLeft: 8,
436
+ paddingRight: 12
437
+ },
414
438
  // 确保主体容器始终有统一的垂直对齐
415
439
  {
416
440
  alignItems: "center"
417
441
  }],
418
442
  disabled: props.disabled,
419
443
  onPress: openDropdown,
420
- children: [showSelectedValue ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
444
+ children: [leftIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_TapasIcon.default, {
445
+ size: 20,
446
+ style: [styles.alignCenter, styles.modalIcon, props.disabled && {
447
+ color: theme.theme.colors.grey3
448
+ }],
449
+ name: leftIcon
450
+ }), showSelectedValue ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
421
451
  style: [styles.alignCenter, {
422
452
  flexGrow: 1,
423
453
  marginRight: 12
@@ -471,8 +501,8 @@ const Dropdown = ({
471
501
  top: dropdownPosition.top,
472
502
  left: dropdownPosition.left,
473
503
  width: dropdownWidthCalc
474
- }, subHeight ? {
475
- maxHeight: subHeight
504
+ }, resolvedSubHeight ? {
505
+ maxHeight: resolvedSubHeight
476
506
  } : null],
477
507
  onLayout: handleConLayout,
478
508
  children: customPopoverContent ? customPopoverContent : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
@@ -506,8 +536,8 @@ const Dropdown = ({
506
536
  } : null],
507
537
  onPress: () => {
508
538
  closeModal();
509
- if (onSelect) {
510
- onSelect(item);
539
+ if (resolvedOnSelect) {
540
+ resolvedOnSelect(item);
511
541
  } else {
512
542
  setSelectedItemKey(item.key);
513
543
  }
@@ -553,7 +583,7 @@ const Dropdown = ({
553
583
  numberOfLines: 1,
554
584
  ellipsizeMode: "tail",
555
585
  style: [styles.modalOptionText, styles.modalNoOptions],
556
- children: emptyText || "No options"
586
+ children: resolvedEmptyText || "No options"
557
587
  })
558
588
  })
559
589
  })
@@ -561,7 +591,7 @@ const Dropdown = ({
561
591
  onPress: () => {
562
592
  closeModal();
563
593
  setTimeout(() => {
564
- onExtendBtnPress?.();
594
+ resolvedOnExtendBtnPress?.();
565
595
  }, 300);
566
596
  },
567
597
  style: [styles.extendBtnCon, {
@@ -590,8 +620,8 @@ const Dropdown = ({
590
620
  value: `${prefix}${selected_old?.name}`,
591
621
  isVisible: isVisible,
592
622
  width: width,
593
- subWidth: subWidth,
594
- subHeight: subHeight,
623
+ subWidth: resolvedSubWidth,
624
+ subHeight: resolvedSubHeight,
595
625
  testID: testID,
596
626
  ...props,
597
627
  onClose: () => {
@@ -615,7 +645,7 @@ const Dropdown = ({
615
645
  borderEndWidth: 1,
616
646
  borderTopWidth: 0,
617
647
  borderRightWidth: 0,
618
- width: subWidth
648
+ width: resolvedSubWidth
619
649
  },
620
650
  inputContainerStyle: styles.inputContainer,
621
651
  placeholder: props.placeholder,
@@ -645,8 +675,8 @@ const Dropdown = ({
645
675
  })
646
676
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
647
677
  style: {
648
- width: subWidth,
649
- height: subHeight
678
+ width: resolvedSubWidth,
679
+ height: resolvedSubHeight
650
680
  },
651
681
  keyboardShouldPersistTaps: "handled",
652
682
  keyboardDismissMode: "none",