@hsu-react/ui 0.0.2 → 0.0.4

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 (78) hide show
  1. package/README.md +2 -0
  2. package/es/components/ChainGraph/_components/SearchSelect/index.js +13 -10
  3. package/es/components/ChainGraph/_components/SearchSelect/index.module.less +8 -2
  4. package/es/components/DatePicker/index.module.less +1 -0
  5. package/es/components/FormItem/FormInput/FormPasswordStrength/index.js +2 -2
  6. package/es/components/FormItem/FormInput/FormPasswordStrength/index.module.less +12 -0
  7. package/es/components/Input/Range/index.module.less +4 -4
  8. package/es/components/Input/index.module.less +3 -0
  9. package/es/components/Panel/ListPanel/index.d.ts +2 -0
  10. package/es/components/Panel/ListPanel/index.js +3 -2
  11. package/es/components/Select/_utils/getElementPosition.d.ts +6 -2
  12. package/es/components/Select/_utils/getElementPosition.js +8 -6
  13. package/es/components/Select/index.module.less +3 -0
  14. package/es/components/Slider/index.module.less +1 -0
  15. package/es/components/Switch/index.js +12 -8
  16. package/es/components/Switch/index.module.less +7 -0
  17. package/lib/components/ChainGraph/_components/SearchSelect/index.js +10 -7
  18. package/lib/components/ChainGraph/_components/SearchSelect/index.module.less +8 -2
  19. package/lib/components/DatePicker/index.module.less +1 -0
  20. package/lib/components/FormItem/FormInput/FormPasswordStrength/index.js +2 -1
  21. package/lib/components/FormItem/FormInput/FormPasswordStrength/index.module.less +12 -0
  22. package/lib/components/Input/Range/index.module.less +4 -4
  23. package/lib/components/Input/index.module.less +3 -0
  24. package/lib/components/Panel/ListPanel/index.d.ts +2 -0
  25. package/lib/components/Panel/ListPanel/index.js +4 -1
  26. package/lib/components/Select/_utils/getElementPosition.d.ts +6 -2
  27. package/lib/components/Select/_utils/getElementPosition.js +8 -6
  28. package/lib/components/Select/index.module.less +3 -0
  29. package/lib/components/Slider/index.module.less +1 -0
  30. package/lib/components/Switch/index.js +8 -4
  31. package/lib/components/Switch/index.module.less +7 -0
  32. package/package.json +1 -1
  33. package/src/components/Button/index.md +18 -1
  34. package/src/components/ChainGraph/_components/SearchSelect/index.module.less +8 -2
  35. package/src/components/ChainGraph/_components/SearchSelect/index.tsx +18 -16
  36. package/src/components/ChainGraph/index.md +2 -1
  37. package/src/components/Chart/index.md +290 -17
  38. package/src/components/Chat/index.md +44 -1
  39. package/src/components/Checkbox/index.md +33 -1
  40. package/src/components/CodeMirror/index.md +1 -1
  41. package/src/components/Copy/index.md +1 -1
  42. package/src/components/DatePicker/index.md +41 -2
  43. package/src/components/DatePicker/index.module.less +1 -0
  44. package/src/components/Descriptions/index.md +1 -1
  45. package/src/components/Editor/index.md +1 -1
  46. package/src/components/FileCol/index.md +1 -1
  47. package/src/components/FilePreview/index.md +1 -1
  48. package/src/components/FlexFill/index.md +1 -1
  49. package/src/components/Form/index.md +88 -1
  50. package/src/components/FormItem/FormInput/FormPasswordStrength/index.module.less +12 -0
  51. package/src/components/FormItem/FormInput/FormPasswordStrength/index.tsx +2 -2
  52. package/src/components/FormItem/index.md +147 -92
  53. package/src/components/Icon/index.md +3 -1
  54. package/src/components/Input/Range/index.module.less +4 -4
  55. package/src/components/Input/index.md +115 -2
  56. package/src/components/Input/index.module.less +3 -0
  57. package/src/components/Markdown/index.md +3 -1
  58. package/src/components/Modal/index.md +1 -1
  59. package/src/components/Operate/index.md +1 -1
  60. package/src/components/Panel/ListPanel/index.tsx +6 -0
  61. package/src/components/Panel/index.md +68 -21
  62. package/src/components/Search/index.md +184 -9
  63. package/src/components/SecondConf/index.md +1 -1
  64. package/src/components/Select/_utils/getElementPosition.ts +8 -6
  65. package/src/components/Select/index.md +1 -1
  66. package/src/components/Select/index.module.less +3 -0
  67. package/src/components/Slider/index.md +1 -2
  68. package/src/components/Slider/index.module.less +1 -0
  69. package/src/components/Spreadsheet/index.md +1 -1
  70. package/src/components/Switch/index.md +1 -1
  71. package/src/components/Switch/index.module.less +7 -0
  72. package/src/components/Switch/index.tsx +14 -11
  73. package/src/components/TabBar/index.md +28 -11
  74. package/src/components/Table/index.md +1 -1
  75. package/src/components/Tags/index.md +1 -1
  76. package/src/components/TextEllipsis/index.md +1 -1
  77. package/src/components/Tree/index.md +1 -1
  78. package/src/components/Upload/index.md +1 -1
@@ -16,7 +16,7 @@ title: Input 输入框
16
16
  import { Input } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 输入框
20
20
 
21
21
  ```tsx
22
22
  import React from "react";
@@ -29,7 +29,120 @@ export default () => {
29
29
  <div style={{ display: "flex", flexDirection: "column", gap: 12, width: 240 }}>
30
30
  <Input placeholder="请输入" value={value} onChange={setValue} />
31
31
  <Input placeholder="禁用状态" disabled />
32
- <div>当前值:{value}</div>
32
+ </div>
33
+ );
34
+ };
35
+ ```
36
+
37
+ ## 数字输入框
38
+
39
+ 数字输入框,`onChange` 返回字符串,内置 `allowClear`、`controls={false}` 与 `stringMode`。
40
+
41
+ ```tsx
42
+ import React from "react";
43
+ import { Input } from "@hsu-react/ui";
44
+
45
+ export default () => {
46
+ const [value, setValue] = React.useState("");
47
+
48
+ return (
49
+ <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
50
+ <Input.Number placeholder="请输入数字" value={value} onChange={setValue} />
51
+ <Input.Number placeholder="带单位" addonAfter="元" />
52
+ </div>
53
+ );
54
+ };
55
+ ```
56
+
57
+ ## 密码框
58
+
59
+ 密码输入框,支持显示/隐藏切换,`onChange` 返回纯字符串。
60
+
61
+ ```tsx
62
+ import React from "react";
63
+ import { Input } from "@hsu-react/ui";
64
+
65
+ export default () => {
66
+ const [value, setValue] = React.useState("");
67
+
68
+ return (
69
+ <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
70
+ <Input.Password placeholder="请输入密码" value={value} onChange={setValue} />
71
+ <Input.Password placeholder="禁用状态" disabled />
72
+ </div>
73
+ );
74
+ };
75
+ ```
76
+
77
+ ## 范围输入
78
+
79
+ 范围输入框,`type` 支持 `"NUMBER"` 或 `"INPUT"`,`onChange` 返回 `[起, 止]` 元组。
80
+
81
+ ```tsx
82
+ import React from "react";
83
+ import { Input } from "@hsu-react/ui";
84
+
85
+ export default () => {
86
+ const [value, setValue] = React.useState();
87
+
88
+ return (
89
+ <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
90
+ <Input.Range
91
+ type="NUMBER"
92
+ value={value}
93
+ onChange={setValue}
94
+ placeholder={["最小值", "最大值"]}
95
+ allowClear
96
+ />
97
+ </div>
98
+ );
99
+ };
100
+ ```
101
+
102
+ ## 搜索框
103
+
104
+ 搜索输入框,支持 `onSearch` 回调与搜索按钮,`onChange` 返回纯字符串。
105
+
106
+ ```tsx
107
+ import React from "react";
108
+ import { Input } from "@hsu-react/ui";
109
+
110
+ export default () => {
111
+ const [value, setValue] = React.useState("");
112
+
113
+ return (
114
+ <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
115
+ <Input.Search
116
+ placeholder="请输入关键字"
117
+ value={value}
118
+ onChange={setValue}
119
+ enterButton
120
+ onSearch={(v) => console.log("search:", v)}
121
+ />
122
+ </div>
123
+ );
124
+ };
125
+ ```
126
+
127
+ ## 多行文本框
128
+
129
+ 多行文本输入框,`onChange` 返回纯字符串,支持 `autoSize`、`prefix` / `suffix`。
130
+
131
+ ```tsx
132
+ import React from "react";
133
+ import { Input } from "@hsu-react/ui";
134
+
135
+ export default () => {
136
+ const [value, setValue] = React.useState("");
137
+
138
+ return (
139
+ <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
140
+ <Input.TextArea
141
+ placeholder="请输入内容"
142
+ value={value}
143
+ onChange={setValue}
144
+ autoSize={{ minRows: 2, maxRows: 4 }}
145
+ />
33
146
  </div>
34
147
  );
35
148
  };
@@ -1,6 +1,9 @@
1
1
  .antdInput {
2
2
  width: 100%;
3
3
  height: 100%;
4
+ // 父级未给定高度时(height:100% 解析为 auto),保证最小高度,避免输入框被压扁;
5
+ // 内部 .ant-input-wrapper / .ant-input 通过 min-height: inherit 继承该值。
6
+ min-height: 32px;
4
7
 
5
8
  :global(.ant-input-clear-icon) {
6
9
  font-size: 14px;
@@ -16,7 +16,7 @@ Markdown 渲染与编辑组件,`Markdown.Views` 用于渲染展示(支持 GF
16
16
  import { Markdown } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## Markdown 展示
20
20
 
21
21
  `Markdown.Views` 渲染(依赖 KaTeX / highlight.js / Mermaid 等样式,建议在应用环境内使用):
22
22
 
@@ -41,6 +41,8 @@ const b = a + 1;
41
41
  export default () => <Markdown.Views>{content}</Markdown.Views>;
42
42
  ```
43
43
 
44
+ ## Markdown 编辑器
45
+
44
46
  `Markdown.Editor` 编辑:
45
47
 
46
48
  ```tsx
@@ -16,7 +16,7 @@ title: Modal 对话框
16
16
  import { Modal } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 对话框
20
20
 
21
21
  通过 `open` 受控显隐,配合 `Button` 切换状态。默认弹窗可按住标题栏拖动。
22
22
 
@@ -16,7 +16,7 @@ title: Operate 操作
16
16
  import { Operate } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 操作
20
20
 
21
21
  ```tsx
22
22
  import React from "react";
@@ -36,6 +36,8 @@ interface TableTools {
36
36
  }
37
37
 
38
38
  export interface ListPanelTabelProps extends Omit<TableProps, "title"> {
39
+ /** 透传给内部 Table 的 key,用于在异构列集切换时强制重挂载表格 */
40
+ key?: React.Key;
39
41
  title?: string;
40
42
  buttonGroup?: ButtonProps[];
41
43
  tabBarProps?: TabBarProps;
@@ -127,6 +129,9 @@ const ListPanel: ListPanelFC = (props) => {
127
129
  tableContainerClassName,
128
130
  tips,
129
131
  otherTool,
132
+ // 异构列集切换时用于强制重挂载表格的 key;显式提取,避免随 ...tableConfig
133
+ // 展开进 JSX 触发 React "key prop being spread" 警告
134
+ key: tableInstanceKey,
130
135
  ...tableConfig
131
136
  } = tableProps;
132
137
  const { className: treeClassName, ...treeConfig } = treeProps;
@@ -435,6 +440,7 @@ const ListPanel: ListPanelFC = (props) => {
435
440
  otherTool={otherTool}
436
441
  />
437
442
  <Table
443
+ key={tableInstanceKey}
438
444
  className={`${styles.table} ${tableClassName ?? ""}`}
439
445
  {...{
440
446
  scroll: true,
@@ -16,7 +16,7 @@ title: Panel 页面容器
16
16
  import { Panel } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 子组件
19
+ ## 子组件一览
20
20
 
21
21
  | 组件 | 说明 |
22
22
  | --- | --- |
@@ -25,24 +25,14 @@ import { Panel } from "@hsu-react/ui";
25
25
  | `Panel.Iframe` | iframe 内容容器,带加载态与全屏按钮 |
26
26
  | `Panel.Default` | 通用内容容器,可选左侧树与面包屑 |
27
27
 
28
- ## 基础用法
29
-
30
- ### Panel.List 列表页
28
+ ## 列表页
31
29
 
32
30
  `Panel.List` 通过 `searchProps`(搜索区)、`tableProps`(表格区)组合出标准增删改查列表页。下方为可交互示例:输入姓名搜索会实时过滤行,点击「新增」「编辑」有反馈。
33
31
 
34
- > 注意:`Panel.List` / `Search` 内部用到 `Button.Chakra`,需要在外层包一层 `ChakraProvider`(真实项目通常在入口统一提供)。
35
-
36
32
  ```tsx
37
33
  import React, { useState } from "react";
38
34
  import { Panel, Button } from "@hsu-react/ui";
39
35
  import { message } from "antd";
40
- import { ChakraProvider, createSystem, defaultConfig } from "@chakra-ui/react";
41
-
42
- const system = createSystem(defaultConfig, {
43
- disableLayers: true,
44
- preflight: false,
45
- });
46
36
 
47
37
  const ALL = [
48
38
  { id: 1, name: "张三", role: "管理员", status: "启用" },
@@ -69,9 +59,13 @@ export default () => {
69
59
  ];
70
60
 
71
61
  return (
72
- <ChakraProvider value={system}>
73
- <div style={{ height: 380 }}>
62
+ // Panel.List 为页面级宽组件;窄屏时外层横向滚动,避免溢出预览框。
63
+ // overflowY:hidden 去掉垂直滚动条;wrapperClassName 放开组件内层
64
+ // ListPanelWrapper 的 overflow:hidden(否则搜索区右侧约 24px 会被裁)。
65
+ <div style={{ overflowX: "auto", overflowY: "hidden" }}>
66
+ <div style={{ minWidth: 1000, height: 300 }}>
74
67
  <Panel.List
68
+ wrapperClassName="hsu-demo-panel-wrapper"
75
69
  searchProps={{
76
70
  searchItems: [{ type: "INPUT", name: "name", label: "姓名" }],
77
71
  onSearch: (v) =>
@@ -90,30 +84,35 @@ export default () => {
90
84
  dataSource: data,
91
85
  rowKey: "id",
92
86
  pagination: false,
87
+ scrollAutoHeight: false,
93
88
  }}
94
89
  />
95
90
  </div>
96
- </ChakraProvider>
91
+ </div>
97
92
  );
98
93
  };
99
94
  ```
100
95
 
101
- ### Panel.Default 内容页
96
+ ## 内容页
102
97
 
103
98
  ```tsx
104
99
  import React from "react";
105
100
  import { Panel } from "@hsu-react/ui";
106
101
 
107
102
  export default () => (
108
- <div style={{ height: 200 }}>
109
- <Panel.Default>
110
- <div style={{ padding: 16 }}>这里是通用内容区域</div>
111
- </Panel.Default>
103
+ // 与列表页一致:外层 overflowX 横向滚动 + overflowY:hidden 去垂直滚动条;
104
+ // wrapperClassName 放开 DefaultPanel 内层的 overflow:hidden。
105
+ <div style={{ overflowX: "auto", overflowY: "hidden" }}>
106
+ <div style={{ minWidth: 1000, height: 200 }}>
107
+ <Panel.Default wrapperClassName="hsu-demo-panel-wrapper">
108
+ <div style={{ padding: 16 }}>这里是通用内容区域(窄屏时可横向滚动查看)</div>
109
+ </Panel.Default>
110
+ </div>
112
111
  </div>
113
112
  );
114
113
  ```
115
114
 
116
- ### Panel.Iframe 内嵌页
115
+ ## 内嵌页
117
116
 
118
117
  `Panel.Iframe` 用于内嵌外部页面,带加载态与全屏按钮(外部站点受 X-Frame-Options 限制,此处仅示意用法):
119
118
 
@@ -124,6 +123,54 @@ import { Panel } from "@hsu-react/ui";
124
123
  export default () => <Panel.Iframe src="https://example.com" fullBtn />;
125
124
  ```
126
125
 
126
+ ## 弹窗内列表
127
+
128
+ `Panel.List.Modal` 在 `Modal` 内复用列表布局,本身继承 `ModalProps`(`open` / `onClose` 等),并通过 `searchProps`、`tableProps` 配置搜索区与表格区。常用于从某条记录弹出其关联子列表。
129
+
130
+ ```tsx
131
+ import React, { useState } from "react";
132
+ import { Panel, Button } from "@hsu-react/ui";
133
+
134
+ const ALL = [
135
+ { id: 1, name: "明细一", status: "启用" },
136
+ { id: 2, name: "明细二", status: "禁用" },
137
+ ];
138
+
139
+ export default () => {
140
+ const [open, setOpen] = useState(false);
141
+ const [data, setData] = useState(ALL);
142
+
143
+ return (
144
+ <>
145
+ <Button type="primary" onClick={() => setOpen(true)}>
146
+ 打开子列表
147
+ </Button>
148
+ <Panel.List.Modal
149
+ open={open}
150
+ onCancel={() => setOpen(false)}
151
+ title="关联明细"
152
+ footer={null}
153
+ searchProps={{
154
+ searchItems: [{ type: "INPUT", name: "name", label: "名称" }],
155
+ onSearch: (v) =>
156
+ setData(ALL.filter((x) => !v.name || x.name.includes(v.name))),
157
+ onReset: () => setData(ALL),
158
+ }}
159
+ tableProps={{
160
+ columns: [
161
+ { title: "名称", dataIndex: "name" },
162
+ { title: "状态", dataIndex: "status" },
163
+ ],
164
+ dataSource: data,
165
+ rowKey: "id",
166
+ pagination: false,
167
+ }}
168
+ />
169
+ </>
170
+ );
171
+ };
172
+ ```
173
+
127
174
  ## API
128
175
 
129
176
  ### Panel.List(ListPanelProps)
@@ -16,23 +16,17 @@ title: Search 搜索
16
16
  import { Search } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 搜索
20
20
 
21
21
  `Search` 通过 `searchItems`(复用 `FormItem` 的配置)定义搜索项,`onSearch` / `onReset` 接收回调:
22
22
 
23
23
  ```tsx
24
24
  import React from "react";
25
25
  import { Search } from "@hsu-react/ui";
26
- import { ChakraProvider, createSystem, defaultConfig } from "@chakra-ui/react";
27
-
28
- const system = createSystem(defaultConfig, {
29
- disableLayers: true,
30
- preflight: false,
31
- });
32
26
 
33
27
  export default () => {
34
28
  return (
35
- <ChakraProvider value={system}>
29
+ <>
36
30
  <Search
37
31
  columnNum={3}
38
32
  searchItems={[
@@ -53,11 +47,192 @@ export default () => {
53
47
  onSearch={(data) => console.log("search", data)}
54
48
  onReset={() => console.log("reset")}
55
49
  />
56
- </ChakraProvider>
50
+ </>
57
51
  );
58
52
  };
59
53
  ```
60
54
 
55
+ `Search` 在基础形态外,额外提供多种搜索形态。除 `Search.Card` 使用 `options` 配置外,其余均复用 `searchItems`(`FormItemProps[]`)+ `onSearch` / `onReset`。
56
+
57
+ ## 高级筛选
58
+
59
+ 不显示标签,通过抽屉承载更多筛选项;配合 `setFilter` 可显示筛选项下拉。
60
+
61
+ ```tsx
62
+ import React from "react";
63
+ import { Search } from "@hsu-react/ui";
64
+
65
+ export default () => (
66
+ <>
67
+ <Search.Advanced
68
+ columnNum={3}
69
+ setFilter
70
+ searchItems={[
71
+ { type: "INPUT", name: "name", label: "姓名" },
72
+ {
73
+ type: "SELECT",
74
+ name: "status",
75
+ label: "状态",
76
+ componentProps: {
77
+ options: [
78
+ { label: "启用", value: 1 },
79
+ { label: "禁用", value: 0 },
80
+ ],
81
+ },
82
+ },
83
+ ]}
84
+ moreSearchItems={[{ type: "INPUT", name: "remark", label: "备注" }]}
85
+ onSearch={(data) => console.log("search", data)}
86
+ onReset={() => console.log("reset")}
87
+ />
88
+ </>
89
+ );
90
+ ```
91
+
92
+ ## 可折叠搜索
93
+
94
+ 整块搜索区可折叠 / 展开,通过 `defaultExpanded` 控制初始状态,`onCollapseToggle` 监听折叠变化。
95
+
96
+ ```tsx
97
+ import React from "react";
98
+ import { Search } from "@hsu-react/ui";
99
+
100
+ export default () => (
101
+ <>
102
+ <Search.Collapsible
103
+ columnNum={3}
104
+ defaultExpanded
105
+ searchItems={[
106
+ { type: "INPUT", name: "name", label: "姓名" },
107
+ {
108
+ type: "SELECT",
109
+ name: "status",
110
+ label: "状态",
111
+ componentProps: {
112
+ options: [
113
+ { label: "启用", value: 1 },
114
+ { label: "禁用", value: 0 },
115
+ ],
116
+ },
117
+ },
118
+ ]}
119
+ onCollapseToggle={(c) => console.log("collapse", c)}
120
+ onSearch={(data) => console.log("search", data)}
121
+ onReset={() => console.log("reset")}
122
+ />
123
+ </>
124
+ );
125
+ ```
126
+
127
+ ## 带筛选器搜索
128
+
129
+ 在按钮组旁内置筛选下拉,允许用户动态勾选要显示的搜索项,`onFilterChange` 接收勾选变化。
130
+
131
+ ```tsx
132
+ import React from "react";
133
+ import { Search } from "@hsu-react/ui";
134
+
135
+ export default () => (
136
+ <>
137
+ <Search.WithFilter
138
+ columnNum={3}
139
+ searchItems={[
140
+ { type: "INPUT", name: "name", label: "姓名" },
141
+ {
142
+ type: "SELECT",
143
+ name: "status",
144
+ label: "状态",
145
+ componentProps: {
146
+ options: [
147
+ { label: "启用", value: 1 },
148
+ { label: "禁用", value: 0 },
149
+ ],
150
+ },
151
+ },
152
+ { type: "INPUT", name: "phone", label: "电话" },
153
+ ]}
154
+ onFilterChange={(items) => console.log("filter", items)}
155
+ onSearch={(data) => console.log("search", data)}
156
+ onReset={() => console.log("reset")}
157
+ />
158
+ </>
159
+ );
160
+ ```
161
+
162
+ ## 带更多项搜索
163
+
164
+ 把搜索项分为基础项(`searchItems`)与更多项(`moreSearchItems`,必填),始终展示全部并提供展开收起。
165
+
166
+ ```tsx
167
+ import React from "react";
168
+ import { Search } from "@hsu-react/ui";
169
+
170
+ export default () => (
171
+ <>
172
+ <Search.WithMore
173
+ columnNum={3}
174
+ searchItems={[
175
+ { type: "INPUT", name: "name", label: "姓名" },
176
+ {
177
+ type: "SELECT",
178
+ name: "status",
179
+ label: "状态",
180
+ componentProps: {
181
+ options: [
182
+ { label: "启用", value: 1 },
183
+ { label: "禁用", value: 0 },
184
+ ],
185
+ },
186
+ },
187
+ ]}
188
+ moreSearchItems={[
189
+ { type: "INPUT", name: "phone", label: "电话" },
190
+ { type: "INPUT", name: "remark", label: "备注" },
191
+ ]}
192
+ onSearch={(data) => console.log("search", data)}
193
+ onReset={() => console.log("reset")}
194
+ />
195
+ </>
196
+ );
197
+ ```
198
+
199
+ ## 卡片式搜索
200
+
201
+ 标签式快捷筛选,使用 `options`(`SearchCardOption[]`)而非 `searchItems`,`onChange` 返回当前选中值;支持 `multiple` 多选与 `showSearchBox` 搜索框。
202
+
203
+ ```tsx
204
+ import React from "react";
205
+ import { Search } from "@hsu-react/ui";
206
+
207
+ export default () => (
208
+ <>
209
+ <Search.Card
210
+ options={[
211
+ {
212
+ label: "状态",
213
+ name: "status",
214
+ items: [
215
+ { label: "启用", value: 1 },
216
+ { label: "禁用", value: 0 },
217
+ ],
218
+ },
219
+ {
220
+ label: "类型",
221
+ name: "type",
222
+ multiple: true,
223
+ items: [
224
+ { label: "普通", value: "normal" },
225
+ { label: "重要", value: "important" },
226
+ { label: "紧急", value: "urgent" },
227
+ ],
228
+ },
229
+ ]}
230
+ onChange={(data) => console.log("change", data)}
231
+ />
232
+ </>
233
+ );
234
+ ```
235
+
61
236
  ## API
62
237
 
63
238
  `SearchProps` 继承自 `BaseSearchProps`:
@@ -16,7 +16,7 @@ title: SecondConf 二次确认
16
16
  import { SecondConf } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 二次确认
20
20
 
21
21
  ```tsx
22
22
  import React, { useState } from "react";
@@ -1,16 +1,18 @@
1
1
  /**
2
- * 获取元素相对于文档的顶部位置
2
+ * 获取元素相对于视口的顶部位置。
3
+ * 下拉框为 position: fixed(相对视口定位),故此处必须返回视口坐标,
4
+ * 不能叠加 document.scrollTop——否则当文档本身可滚动时(如文档站长页面),
5
+ * 下拉框会被定位到 scrollTop 像素之外而“消失”。
6
+ * 在固定布局(document 不滚动,scrollTop=0)下与原行为一致。
3
7
  */
4
8
  export function getElementTop(element: HTMLDivElement): number {
5
- const rect = element.getBoundingClientRect();
6
- return rect.top + document.documentElement.scrollTop;
9
+ return element.getBoundingClientRect().top;
7
10
  }
8
11
 
9
12
  /**
10
- * 获取元素相对于文档的左侧位置
13
+ * 获取元素相对于视口的左侧位置(同上,配合 position: fixed)。
11
14
  */
12
15
  export function getElementLeft(element: HTMLDivElement): number {
13
- const rect = element.getBoundingClientRect();
14
- return rect.left + document.documentElement.scrollLeft;
16
+ return element.getBoundingClientRect().left;
15
17
  }
16
18
 
@@ -16,7 +16,7 @@ title: Select 选择器
16
16
  import { Select } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 选择器
20
20
 
21
21
  ```tsx
22
22
  import React from "react";
@@ -6,6 +6,9 @@
6
6
 
7
7
  width: 100%;
8
8
  height: 100%;
9
+ // 父级未给定高度时(height:100% 解析为 auto),保证最小高度,
10
+ // 与 Input 等录入控件高度一致,避免被压扁或在搜索行中高度异常。
11
+ min-height: 32px;
9
12
  padding: 0px 11px;
10
13
 
11
14
  // CF 风格:随外观切换的描边输入控件
@@ -16,7 +16,7 @@ title: Slider 滑动输入
16
16
  import { Slider } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 滑动输入
20
20
 
21
21
  ```tsx
22
22
  import React from "react";
@@ -28,7 +28,6 @@ export default () => {
28
28
  return (
29
29
  <div style={{ width: 240 }}>
30
30
  <Slider value={value} onChange={setValue} />
31
- <div style={{ marginTop: 12 }}>当前值:{value}</div>
32
31
  </div>
33
32
  );
34
33
  };
@@ -1,4 +1,5 @@
1
1
  .slider {
2
+ width: 100%;
2
3
  height: 32px;
3
4
  margin: 0px;
4
5
  padding-block: 0px;
@@ -16,7 +16,7 @@ title: Spreadsheet 电子表格
16
16
  import { Spreadsheet } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 电子表格
20
20
 
21
21
  ```tsx
22
22
  import React from "react";
@@ -16,7 +16,7 @@ title: Switch 开关
16
16
  import { Switch } from "@hsu-react/ui";
17
17
  ```
18
18
 
19
- ## 基础用法
19
+ ## 开关
20
20
 
21
21
  ```tsx
22
22
  import React from "react";
@@ -0,0 +1,7 @@
1
+ // 让开关在表单/录入场景中与 Input、Select 等控件保持一致的 32px 最小高度。
2
+ // 开关本体(pill)保持原始尺寸,由该容器居中占位,故不会被拉大。
3
+ .SwitchWrapper {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ min-height: 32px;
7
+ }