@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,230 @@
1
+ # Dropdown / CustomDropdown / InputDropdown
2
+
3
+ 下拉选择组件系列。Dropdown 是主组件,支持普通下拉和 Modal 弹出两种模式;CustomDropdown 是底层下拉容器;InputDropdown 是带搜索输入框的下拉组件。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 两种模式:CustomDropdown 弹出模式和 Modal 弹出模式
8
+ - ✅ 支持搜索过滤选项
9
+ - ✅ 响应式定位,自动检测上下空间选择弹出方向
10
+ - ✅ 移动端自动切换为 BottomSheet 样式
11
+ - ✅ 支持自定义按钮(customButton)
12
+ - ✅ 支持自定义弹出内容(customPopoverContent)
13
+ - ✅ 浮动标签动画(Modal 模式)
14
+ - ✅ 错误状态和状态消息显示
15
+ - ✅ 支持必填标识
16
+ - ✅ InputDropdown 支持输入搜索、清空、只读模式
17
+ - ✅ 支持扩展按钮(extendBtn)
18
+ - ✅ 多种定位方式:left、center、right、upLeft、upRight、upCenter、auto
19
+
20
+ ## 安装使用
21
+
22
+ ```tsx
23
+ import Dropdown from '@beppla/tapas-ui/components/Dropdown/Dropdown';
24
+ import CustomDropdown from '@beppla/tapas-ui/components/Dropdown/CustomDropdown';
25
+ import InputDropdown from '@beppla/tapas-ui/components/Dropdown/InputDropdown';
26
+ ```
27
+
28
+ ## Props
29
+
30
+ ### Dropdown Props(核心属性)
31
+
32
+ | 属性 | 类型 | 默认值 | 说明 |
33
+ |------|------|--------|------|
34
+ | options | `ItemProps[]` | - | 选项列表 |
35
+ | value | `ItemProps` | - | 当前选中值 |
36
+ | onChange | `(value: ItemProps) => void` | - | 选中变化回调 |
37
+ | prefix | `string` | `''` | 显示值前缀 |
38
+ | width | `number` | - | 按钮宽度 |
39
+ | subWidth | `number` | - | 弹出框宽度 |
40
+ | subHeight | `number` | `150` | 弹出框高度 |
41
+ | type | `'button' \| 'option'` | `'option'` | 类型,button 模式不更新选中值 |
42
+ | onClose | `() => void` | - | 关闭回调 |
43
+ | onPress | `() => void` | - | 按钮点击回调 |
44
+ | onItemPress | `(value: string \| number) => void` | - | button 类型下的选项点击回调 |
45
+ | disabled | `boolean` | - | 是否禁用 |
46
+ | showSearchBar | `boolean` | - | 是否显示搜索栏 |
47
+ | placeholder | `string` | - | 搜索栏占位文字 |
48
+ | onSearchChange | `(value: string) => void` | - | 搜索内容变化回调 |
49
+ | testID | `string` | - | 测试标识 |
50
+
51
+ ### Dropdown Modal 模式属性
52
+
53
+ | 属性 | 类型 | 默认值 | 说明 |
54
+ |------|------|--------|------|
55
+ | useModal | `boolean` | `false` | 是否使用 Modal 弹出模式 |
56
+ | dropdownItems | `TapasDropDownItem[]` | `[]` | Modal 模式下的选项列表 |
57
+ | selected | `string` | - | 选中项的 key |
58
+ | showSelectedValue | `boolean` | `false` | 是否显示选中值文字 |
59
+ | dropdownType | `'clear' \| 'solid'` | `'clear'` | 下拉按钮类型 |
60
+ | arrowIcon | `boolean` | `false` | 是否显示箭头图标 |
61
+ | onSelect | `(item: TapasDropDownItem) => void` | - | Modal 模式选择回调 |
62
+ | label | `string` | - | 标签文字 |
63
+ | required | `boolean` | - | 是否必填 |
64
+ | state | `'normal' \| 'error'` | `'normal'` | 状态 |
65
+ | stateMsg | `string` | - | 状态消息 |
66
+ | showStateMsg | `boolean` | `false` | 是否显示状态消息 |
67
+ | showCheckedStatusInList | `boolean` | `false` | 列表中是否高亮选中项 |
68
+ | noLabelAnim | `boolean` | `false` | 是否禁用标签动画 |
69
+ | radius | `number` | `12` | 圆角半径 |
70
+ | backgroundColor | `string` | - | 背景颜色 |
71
+ | labelColor | `string` | - | 标签颜色 |
72
+ | emptyText | `string` | `'No options'` | 空列表提示文字 |
73
+ | extendBtn | `string` | - | 扩展按钮文字 |
74
+ | extendBtnIcon | `string` | - | 扩展按钮图标 |
75
+ | onExtendBtnPress | `() => void` | - | 扩展按钮回调 |
76
+ | customPopoverContent | `React.ReactNode` | - | 自定义弹出内容 |
77
+ | modalVisible | `boolean` | - | 控制 Modal 可见性 |
78
+ | setModalVisible | `(val: boolean) => void` | - | 设置 Modal 可见性回调 |
79
+ | iconStyle | `ViewStyle \| TextStyle` | - | 图标样式 |
80
+ | offsetWidth | `number` | `0` | 偏移宽度 |
81
+
82
+ ### CustomDropdown Props
83
+
84
+ | 属性 | 类型 | 默认值 | 说明 |
85
+ |------|------|--------|------|
86
+ | children | `React.ReactNode` | - | 弹出框内容 |
87
+ | value | `string` | - | 按钮显示文字 |
88
+ | onPress | `() => void` | - | 按钮点击回调 |
89
+ | onClose | `() => void` | - | 关闭回调 |
90
+ | isVisible | `boolean` | - | 是否展开 |
91
+ | width | `number` | `80` | 按钮宽度 |
92
+ | subWidth | `number` | `250` | 弹出框宽度 |
93
+ | subHeight | `number` | `258` | 弹出框高度 |
94
+ | icon | `any` | - | 自定义图标 |
95
+ | subContainerPosition | `TDropdownPosition` | `'left'` | 弹出位置 |
96
+ | subContainerTop | `number` | - | 自定义 top 值(优先级最高) |
97
+ | subContainerLeft | `number` | - | 自定义 left 值(优先级最高) |
98
+ | customButton | `React.ReactNode` | - | 自定义触发按钮 |
99
+ | dropdownButtonStyle | `StyleProp<ViewStyle>` | - | 按钮样式 |
100
+ | dropdownButtonSelectedStyle | `StyleProp<ViewStyle>` | - | 选中时按钮样式 |
101
+ | dropdownButtonHoverStyle | `StyleProp<ViewStyle>` | - | hover 时按钮样式 |
102
+ | sheetTitlePros | `SheetTileProps` | - | 移动端 BottomSheet 标题配置 |
103
+ | dropdownBackgroundColor | `string` | - | 自定义弹出框背景色 |
104
+
105
+ ### InputDropdown Props
106
+
107
+ | 属性 | 类型 | 默认值 | 说明 |
108
+ |------|------|--------|------|
109
+ | label | `string` | - | 输入框标签(必填) |
110
+ | value | `ItemProps` | - | 当前选中值 |
111
+ | options | `ItemProps[]` | - | 选项列表 |
112
+ | onChange | `(value?: ItemProps) => void` | - | 选中变化回调 |
113
+ | onSearch | `(value: string) => void` | - | 搜索回调 |
114
+ | required | `boolean` | - | 是否必填 |
115
+ | readOnly | `boolean` | - | 是否只读 |
116
+ | clearable | `boolean` | - | 是否可清空 |
117
+ | disabled | `boolean` | - | 是否禁用 |
118
+ | defaultShowLabel | `boolean` | - | 默认是否显示标签 |
119
+ | labelBg | `string` | - | 标签背景色 |
120
+ | labelColor | `string` | - | 标签颜色 |
121
+ | allCreate | `boolean` | - | 是否允许自定义输入值 |
122
+ | labelPosition | `'top' \| 'middle'` | - | 标签位置 |
123
+ | children | `React.ReactNode` | - | 自定义下拉内容 |
124
+
125
+ ### TapasDropDownItem 数据类型
126
+
127
+ | 属性 | 类型 | 说明 |
128
+ |------|------|------|
129
+ | key | `string \| number` | 选项唯一标识 |
130
+ | value | `string` | 选项显示文字 |
131
+ | secondaryValue | `string` | 次要显示文字(可选) |
132
+
133
+ ## 使用示例
134
+
135
+ ### 基础下拉
136
+
137
+ ```tsx
138
+ const [isVisible, setIsVisible] = useState(false);
139
+ const [value, setValue] = useState(options[0]);
140
+
141
+ <Dropdown
142
+ title="Name"
143
+ options={options}
144
+ value={value}
145
+ width={150}
146
+ subWidth={150}
147
+ onChange={(val) => { setValue(val); setIsVisible(false); }}
148
+ isVisible={isVisible}
149
+ onClose={() => setIsVisible(false)}
150
+ onPress={() => setIsVisible(!isVisible)}
151
+ />
152
+ ```
153
+
154
+ ### 带搜索的下拉
155
+
156
+ ```tsx
157
+ <Dropdown
158
+ title="Name"
159
+ options={options}
160
+ value={value}
161
+ showSearchBar={true}
162
+ subWidth={200}
163
+ onSearchChange={(val) => console.log(val)}
164
+ isVisible={isVisible}
165
+ onClose={() => setIsVisible(false)}
166
+ onPress={() => setIsVisible(!isVisible)}
167
+ onChange={(val) => setValue(val)}
168
+ />
169
+ ```
170
+
171
+ ### InputDropdown(可搜索输入下拉)
172
+
173
+ ```tsx
174
+ <InputDropdown
175
+ label="选择名称"
176
+ options={options}
177
+ value={selectedValue}
178
+ clearable
179
+ labelBg="#fff"
180
+ isVisible={isVisible}
181
+ onClose={() => setIsVisible(false)}
182
+ onPress={() => setIsVisible(!isVisible)}
183
+ onChange={(val) => setValue(val)}
184
+ />
185
+ ```
186
+
187
+ ### 自定义按钮
188
+
189
+ ```tsx
190
+ <Dropdown
191
+ options={options}
192
+ value={value}
193
+ customButton={
194
+ <View style={{ width: 48, height: 40, justifyContent: 'center', alignItems: 'center' }}>
195
+ <Icon name="more_vert" size={20} />
196
+ </View>
197
+ }
198
+ isVisible={isVisible}
199
+ onClose={() => setIsVisible(false)}
200
+ onPress={() => setIsVisible(!isVisible)}
201
+ onChange={(val) => setValue(val)}
202
+ />
203
+ ```
204
+
205
+ ### Modal 模式
206
+
207
+ ```tsx
208
+ <Dropdown
209
+ useModal={true}
210
+ dropdownItems={[
211
+ { key: '1', value: '选项一' },
212
+ { key: '2', value: '选项二' },
213
+ ]}
214
+ selected="1"
215
+ showSelectedValue={true}
216
+ dropdownType="solid"
217
+ label="选择"
218
+ onSelect={(item) => console.log(item)}
219
+ />
220
+ ```
221
+
222
+ ## 注意事项
223
+
224
+ - 普通模式下需要手动管理 `isVisible` 状态
225
+ - Web 端点击外部会自动关闭弹出框(通过 document click 事件)
226
+ - 移动端自动使用 BottomSheet 展示
227
+ - `subContainerTop` 和 `subContainerLeft` 优先级高于 `subContainerPosition`
228
+ - Modal 模式下弹出位置会自动检测屏幕空间,优先向下展示
229
+ - `type="button"` 时点击选项不会更新选中值,仅触发 `onItemPress`
230
+ - InputDropdown 在 `allCreate` 为 false 时,失焦后会恢复为选中值
@@ -0,0 +1,81 @@
1
+ # ExternalLink
2
+
3
+ 外部链接组件,用于打开外部 URL。自动适配 Web(window.open)和移动端(Linking.openURL)平台差异,提供统一的外链交互体验。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 跨平台链接打开:Web 新标签页、移动端外部浏览器
8
+ - ✅ 移动端自动检测 URL 可用性(Linking.canOpenURL)
9
+ - ✅ 支持自定义点击行为(onPress 覆盖默认行为)
10
+ - ✅ 文本子元素自动包装 Text 组件
11
+ - ✅ 自定义链接和文本样式
12
+ - ✅ 默认下划线链接样式
13
+ - ✅ 主题色适配(primary 色)
14
+
15
+ ## 安装使用
16
+
17
+ ```tsx
18
+ import { ExternalLink } from '@beppla/tapas-ui';
19
+ ```
20
+
21
+ ## Props
22
+
23
+ | 属性 | 类型 | 默认值 | 说明 |
24
+ |------|------|--------|------|
25
+ | href | `string` | - | 目标 URL(必填) |
26
+ | children | `React.ReactNode` | - | 链接内容(必填) |
27
+ | style | `any` | - | 外层容器样式 |
28
+ | textStyle | `any` | - | 文本样式 |
29
+ | onPress | `() => void` | - | 自定义点击行为(覆盖默认打开链接) |
30
+
31
+ ## 使用示例
32
+
33
+ ### 基础用法
34
+
35
+ ```tsx
36
+ <ExternalLink href="https://beppla.com">
37
+ Visit BEPPLA
38
+ </ExternalLink>
39
+ ```
40
+
41
+ ### 自定义样式
42
+
43
+ ```tsx
44
+ <ExternalLink
45
+ href="https://docs.beppla.com"
46
+ textStyle={{ color: '#895F38', fontSize: 14 }}
47
+ >
48
+ Documentation
49
+ </ExternalLink>
50
+ ```
51
+
52
+ ### ReactNode 子元素
53
+
54
+ ```tsx
55
+ <ExternalLink href="https://support.beppla.com">
56
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
57
+ <TapasIcon name="help" size={16} />
58
+ <Text style={{ marginLeft: 4 }}>Help Center</Text>
59
+ </View>
60
+ </ExternalLink>
61
+ ```
62
+
63
+ ### 自定义点击行为
64
+
65
+ ```tsx
66
+ <ExternalLink
67
+ href="https://example.com"
68
+ onPress={() => trackLinkClick('example')}
69
+ >
70
+ Custom handler
71
+ </ExternalLink>
72
+ ```
73
+
74
+ ## 注意事项
75
+
76
+ - 字符串类型的 children 自动包装为 Text 组件并应用 textStyle
77
+ - 非字符串类型的 children 直接渲染,textStyle 不生效
78
+ - 移动端打开前会检查 `Linking.canOpenURL`,不支持的 URL 会在控制台警告
79
+ - `onPress` 存在时不会打开 href 链接
80
+ - 默认文本样式:主题 primary 色、下划线、fontSize 16
81
+ - 需在 `ThemeProvider` 内使用
@@ -0,0 +1,155 @@
1
+ # Gantt 甘特图组件
2
+
3
+ 功能强大的甘特图组件,用于可视化展示时间序列数据和项目/任务计划。支持多种时间粒度(年 / 月 / 周 / 天 / 小时 / 半小时),自动滚动到当前时间,并提供灵活的事件卡片渲染。基于 VariableSizeGrid 虚拟滚动引擎构建,可处理大量时间段数据。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 六种时间粒度:YEAR / MONTH / WEEK / DAY / HOUR / HELF(半小时)
8
+ - ✅ 自动计算列数:根据时间范围和粒度自动生成列
9
+ - ✅ 自动滚动到当前时间点
10
+ - ✅ 实时时间指示线
11
+ - ✅ 粘性列头:时间刻度固定在顶部
12
+ - ✅ 日期切换回调(滚动时自动触发 attachSwitchDay)
13
+ - ✅ 自定义任务卡片渲染
14
+ - ✅ 卡片点击事件(attachPressCard)
15
+ - ✅ GanttContext 上下文共享:子组件可访问完整网格信息
16
+ - ✅ 基于虚拟滚动的高性能渲染
17
+ - ✅ 主题色适配
18
+
19
+ ## 安装使用
20
+
21
+ ```tsx
22
+ import { Gantt } from '@beppla/tapas-ui';
23
+ ```
24
+
25
+ ## GanttProps
26
+
27
+ | 属性 | 类型 | 默认值 | 说明 |
28
+ |------|------|--------|------|
29
+ | width | `number` | - | 容器宽度(必填) |
30
+ | height | `number` | - | 容器高度(必填) |
31
+ | data | `any[]` | - | 任务数据数组(必填),每项包含 startTime/endTime |
32
+ | children | `RenderComponent<any>` | - | 自定义卡片渲染组件(必填) |
33
+ | range | `string[]` | 当天 00:00-23:59 | 时间范围 [startISO, endISO] |
34
+ | unit | `DateUnit` | `DateUnit.HELF` | 时间粒度 |
35
+ | columnWidth | `number` | `165` | 列宽(像素) |
36
+ | rowHeight | `number` | `88` | 行高(像素,实际会 +8 间距) |
37
+ | columnHeaderHeight | `number` | `24` | 列头高度 |
38
+ | columnHeaderBackgroundColor | `string` | - | 列头背景色 |
39
+ | columnHeaderBorder | `{ top?: boolean; left?: boolean; right?: boolean; bottom?: boolean }` | - | 列头边框配置 |
40
+ | attachSwitchDay | `(date?: Date) => void` | - | 滚动切换日期时回调 |
41
+ | attachPressCard | `(info: PressCardProps) => void` | - | 卡片点击回调 |
42
+ | style | `Object` | - | 自定义样式 |
43
+
44
+ ### DateUnit 枚举
45
+
46
+ ```tsx
47
+ enum DateUnit {
48
+ YEAR = 365 * 24 * 60 * 60 * 1000,
49
+ MONTH = 31 * 24 * 60 * 60 * 1000,
50
+ WEEK = 7 * 24 * 60 * 60 * 1000,
51
+ DAY = 24 * 60 * 60 * 1000,
52
+ HOUR = 60 * 60 * 1000,
53
+ HELF = 30 * 60 * 1000, // 半小时
54
+ }
55
+ ```
56
+
57
+ ### PressCardProps
58
+
59
+ ```tsx
60
+ interface PressCardProps {
61
+ columnIndex?: number;
62
+ rowIndex?: number;
63
+ dataIndex: number;
64
+ }
65
+ ```
66
+
67
+ ### GanttContextType
68
+
69
+ 通过 `GanttContext` 共享的上下文信息:
70
+
71
+ | 字段 | 类型 | 说明 |
72
+ |------|------|------|
73
+ | columnCount | `number` | 列总数 |
74
+ | rowCount | `number` | 行总数 |
75
+ | columnWidth | `number` | 列宽 |
76
+ | rowHeight | `number` | 行高 |
77
+ | width / height | `number` | 容器尺寸 |
78
+ | startDate / endDate | `Date` | 时间范围 |
79
+ | rangeVal | `Date[]` | 原始时间范围 |
80
+ | unit | `DateUnit` | 时间粒度 |
81
+ | now | `Date` | 当前时间 |
82
+ | gridDataMap | `GridDataMap` | 网格数据映射 |
83
+ | gridRef / headerRef | `Ref` | Grid 实例引用 |
84
+
85
+ ## 辅助模块
86
+
87
+ - **Accessories.tsx**:ColumnHeaderCon(列头渲染)、GanttCellRender(单元格渲染)、GanttItemWrapper(单元格包装器)
88
+ - **helper.ts**:calculateRoundedColumnCount、calculateTotalRows、calculateCurrentColumnIndex、scrollToCurrentTime、getDefualtDateTimeRange
89
+ - **GanttInnerElementType.tsx**:自定义 Grid innerElement,包含列头和时间线
90
+
91
+ ## 使用示例
92
+
93
+ ### 基础用法
94
+
95
+ ```tsx
96
+ import { Gantt, DateUnit } from '@beppla/tapas-ui';
97
+
98
+ const tasks = [
99
+ { startTime: '2026-04-01T09:00:00', endTime: '2026-04-01T11:30:00' },
100
+ { startTime: '2026-04-01T13:00:00', endTime: '2026-04-01T15:00:00' },
101
+ ];
102
+
103
+ <Gantt
104
+ width={800}
105
+ height={400}
106
+ data={tasks}
107
+ unit={DateUnit.HELF}
108
+ range={['2026-04-01T00:00:00', '2026-04-01T23:59:59']}
109
+ attachSwitchDay={(date) => console.log('Date:', date)}
110
+ attachPressCard={(info) => console.log('Card:', info)}
111
+ >
112
+ {TaskCardComponent}
113
+ </Gantt>
114
+ ```
115
+
116
+ ### 天级粒度(多日视图)
117
+
118
+ ```tsx
119
+ <Gantt
120
+ width={1200}
121
+ height={500}
122
+ data={projectTasks}
123
+ unit={DateUnit.DAY}
124
+ range={['2026-04-01', '2026-04-30']}
125
+ columnWidth={80}
126
+ rowHeight={60}
127
+ >
128
+ {ProjectTaskCard}
129
+ </Gantt>
130
+ ```
131
+
132
+ ### 自定义列头高度和颜色
133
+
134
+ ```tsx
135
+ <Gantt
136
+ width={800}
137
+ height={400}
138
+ data={tasks}
139
+ columnHeaderHeight={32}
140
+ columnHeaderBackgroundColor="#F5F0E6"
141
+ >
142
+ {TaskCard}
143
+ </Gantt>
144
+ ```
145
+
146
+ ## 注意事项
147
+
148
+ - 数据项需包含 `startTime` 和 `endTime` 字段(ISO 字符串)
149
+ - 数据项可携带 `now` 字段覆盖当前时间(服务器时间同步场景)
150
+ - 组件会自动排序任务并计算行分配(避免重叠)
151
+ - 滚动到当前时间使用 `requestAnimationFrame` 延迟执行
152
+ - 日期切换回调使用 RAF 节流,避免频繁触发
153
+ - `range` 默认为当天 00:00:00 到 23:59:59
154
+ - 基于 Web DOM 实现,仅适用于 `Platform.OS === 'web'`
155
+ - 需在 `ThemeProvider` 内使用
@@ -0,0 +1,197 @@
1
+ # Grid 虚拟滚动网格组件
2
+
3
+ 高性能虚拟滚动网格组件,支持固定尺寸和可变尺寸的行列,可处理数千行列的大型数据集。包含三个变体:**StaticFixedSizeGrid**(粘性列 + 列头)、**FixedSizeGrid**(等宽等高)、**VariableSizeGrid**(动态行列尺寸),满足从简单表格到复杂数据面板的各种场景。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 虚拟滚动渲染:仅渲染可视区域内的单元格,支持数千行列
8
+ - ✅ 三种 Grid 变体:StaticFixedSizeGrid / FixedSizeGrid / VariableSizeGrid
9
+ - ✅ 粘性列(Sticky Columns):指定列固定在右侧,水平滚动时不跟随
10
+ - ✅ 粘性列头(Sticky Headers):列头固定在顶部,垂直滚动时不跟随
11
+ - ✅ 可变行高和列宽:VariableSizeGrid 支持通过函数动态返回尺寸
12
+ - ✅ 滚动同步:多个 Grid 实例间的滚动联动
13
+ - ✅ 滚动阴影指示器:左右边缘滚动时显示阴影
14
+ - ✅ RTL(右到左)布局支持
15
+ - ✅ Overscan 预渲染:提前渲染可视区外的行列,减少滚动白屏
16
+ - ✅ scrollTo / scrollToItem 命令式滚动 API
17
+ - ✅ 自定义边框和圆角控制
18
+ - ✅ hasActions 支持:特定单元格允许 overflow visible(下拉菜单不被裁切)
19
+
20
+ ## 安装使用
21
+
22
+ ```tsx
23
+ import {
24
+ StaticFixedSizeGrid,
25
+ FixedSizeGrid,
26
+ VariableSizeGrid,
27
+ } from '@beppla/tapas-ui';
28
+ ```
29
+
30
+ ## StaticFixedSizeGrid Props
31
+
32
+ | 属性 | 类型 | 默认值 | 说明 |
33
+ |------|------|--------|------|
34
+ | columnCount | `number` | - | 总列数(必填) |
35
+ | columnWidth | `(index: number) => number` | - | 列宽函数(必填) |
36
+ | rowCount | `number` | - | 总行数(必填) |
37
+ | rowHeight | `(index: number) => number` | - | 行高函数(必填) |
38
+ | width | `number` | - | 容器宽度(必填) |
39
+ | height | `number` | - | 容器高度(必填) |
40
+ | children | `(props: ChildrenProps) => ReactNode` | - | 单元格渲染函数(必填) |
41
+ | headersRender | `(props: ChildrenProps) => JSX.Element` | - | 列头渲染函数 |
42
+ | columnHeaderHeight | `number` | `40` | 列头高度 |
43
+ | columnHeaderBackgroundColor | `string` | 主题 grey4 | 列头背景色 |
44
+ | stickyColumnIndices | `number[]` | - | 粘性列索引数组 |
45
+ | border | `boolean` | `false` | 是否显示边框 |
46
+ | onScroll | `(event) => void` | - | 滚动回调 |
47
+ | hideBorder | `string[]` | - | 隐藏指定方向边框(top/bottom/left/right) |
48
+ | hideborderRadius | `string[]` | - | 隐藏指定角的圆角(topLeft/topRight) |
49
+ | hasActions | `(columnIndex, rowIndex) => boolean` | - | 判断单元格是否有下拉操作菜单 |
50
+ | gridRef | `React.MutableRefObject<any>` | - | Grid 实例引用 |
51
+ | style | `Object` | - | 自定义容器样式 |
52
+
53
+ ### ChildrenProps
54
+
55
+ ```tsx
56
+ interface ChildrenProps {
57
+ columnIndex: number;
58
+ rowIndex: number;
59
+ style: CSSProperties;
60
+ }
61
+ ```
62
+
63
+ ## FixedSizeGrid Props
64
+
65
+ | 属性 | 类型 | 默认值 | 说明 |
66
+ |------|------|--------|------|
67
+ | columnCount | `number` | - | 总列数(必填) |
68
+ | columnWidth | `number` | - | 固定列宽(必填) |
69
+ | rowCount | `number` | - | 总行数(必填) |
70
+ | rowHeight | `number` | - | 固定行高(必填) |
71
+ | width | `number` | - | 容器宽度(必填) |
72
+ | height | `number` | - | 容器高度(必填) |
73
+ | children | `RenderComponent<T>` | - | 单元格渲染组件(必填) |
74
+ | itemData | `T` | - | 传递给子组件的数据 |
75
+ | direction | `'ltr' \| 'rtl'` | `'ltr'` | 文本方向 |
76
+ | overscanColumnCount | `number` | `1` | 列预渲染数量 |
77
+ | overscanRowCount | `number` | `1` | 行预渲染数量 |
78
+ | onScroll | `OnScrollCallback` | - | 滚动回调 |
79
+ | onItemsRendered | `OnItemsRenderedCallback` | - | 可见区域变化回调 |
80
+
81
+ ## VariableSizeGrid Props
82
+
83
+ 与 FixedSizeGrid 相同,但 `columnWidth` 和 `rowHeight` 为函数类型:
84
+
85
+ | 属性 | 类型 | 说明 |
86
+ |------|------|------|
87
+ | columnWidth | `(index: number) => number` | 根据索引返回列宽 |
88
+ | rowHeight | `(index: number) => number` | 根据索引返回行高 |
89
+
90
+ ## 使用示例
91
+
92
+ ### StaticFixedSizeGrid(粘性列 + 列头)
93
+
94
+ ```tsx
95
+ const columnWidths = [100, 150, 200, 120, 80];
96
+
97
+ const Cell = ({ columnIndex, rowIndex, style }: ChildrenProps) => (
98
+ <div style={style}>
99
+ Item {rowIndex},{columnIndex}
100
+ </div>
101
+ );
102
+
103
+ const ColumnHeaders = ({ columnIndex, style }: ChildrenProps) => (
104
+ <div style={style}>Header {columnIndex}</div>
105
+ );
106
+
107
+ <StaticFixedSizeGrid
108
+ columnCount={5}
109
+ columnWidth={(index) => columnWidths[index]}
110
+ rowCount={1000}
111
+ rowHeight={() => 56}
112
+ width={650}
113
+ height={400}
114
+ border={true}
115
+ headersRender={ColumnHeaders}
116
+ stickyColumnIndices={[4]}
117
+ >
118
+ {Cell}
119
+ </StaticFixedSizeGrid>
120
+ ```
121
+
122
+ ### FixedSizeGrid(等宽等高)
123
+
124
+ ```tsx
125
+ <FixedSizeGrid
126
+ columnCount={1000}
127
+ columnWidth={75}
128
+ rowCount={1000}
129
+ rowHeight={40}
130
+ width={300}
131
+ height={300}
132
+ >
133
+ {Cell}
134
+ </FixedSizeGrid>
135
+ ```
136
+
137
+ ### VariableSizeGrid(动态尺寸)
138
+
139
+ ```tsx
140
+ <VariableSizeGrid
141
+ columnCount={1000}
142
+ columnWidth={(index) => 75 + Math.round(Math.random() * 50)}
143
+ rowCount={1000}
144
+ rowHeight={(index) => (index % 2 === 0 ? 40 : 56)}
145
+ width={300}
146
+ height={300}
147
+ >
148
+ {Cell}
149
+ </VariableSizeGrid>
150
+ ```
151
+
152
+ ### 多 Grid 滚动联动
153
+
154
+ ```tsx
155
+ const gridRef = useRef(null);
156
+
157
+ <StaticFixedSizeGrid
158
+ columnCount={20}
159
+ columnWidth={(i) => widths[i]}
160
+ rowCount={100}
161
+ rowHeight={() => 56}
162
+ width={650}
163
+ height={400}
164
+ onScroll={(event) => {
165
+ gridRef.current?.scrollTo({
166
+ ...event,
167
+ scrollTop: gridRef.current.state.scrollTop,
168
+ });
169
+ }}
170
+ headersRender={Headers}
171
+ >
172
+ {Cell}
173
+ </StaticFixedSizeGrid>
174
+
175
+ <StaticFixedSizeGrid
176
+ gridRef={gridRef}
177
+ columnCount={20}
178
+ columnWidth={(i) => widths[i]}
179
+ rowCount={50}
180
+ rowHeight={() => 56}
181
+ width={650}
182
+ height={300}
183
+ >
184
+ {Cell}
185
+ </StaticFixedSizeGrid>
186
+ ```
187
+
188
+ ## 注意事项
189
+
190
+ - StaticFixedSizeGrid 内部基于 VariableSizeGrid + StickyListContext 实现
191
+ - 粘性列通过独立的 VariableSizeGrid 实例渲染,使用 `position: sticky` 固定
192
+ - 滚动同步使用 RAF(requestAnimationFrame)节流优化性能
193
+ - `hasActions` 为 true 的单元格设置 `overflow: visible` 允许下拉菜单溢出
194
+ - 列头同步滚动通过 `headerRef.scrollTo()` 实现
195
+ - FixedSizeGrid 的 `columnWidth` 和 `rowHeight` 必须是 number 类型
196
+ - VariableSizeGrid 的 `columnWidth` 和 `rowHeight` 必须是函数类型
197
+ - 组件基于 Web DOM(div),仅适用于 `Platform.OS === 'web'`