@kne/react-modal 0.1.11 → 0.1.13
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.
- package/README.md +157 -330
- package/dist/index.css +7 -4
- package/dist/index.css.map +1 -1
- package/dist/index.js +237 -128
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +239 -133
- package/dist/index.modern.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ npm i --save @kne/react-modal
|
|
|
22
22
|
|
|
23
23
|
#### 主要特性
|
|
24
24
|
|
|
25
|
-
- 声明式 / 命令式同一套 props 与 UI(Modal `useModal
|
|
25
|
+
- 声明式 / 命令式同一套 props 与 UI(Modal `useModal` + `ModalContextHolder`,多层就近 LayerHolder;Drawer `useDrawer` + `DrawerContextHolder`;确认框 `useConfirmModal`)
|
|
26
26
|
- `footer` + `footerButtons`(`ButtonComponent` / `display` / `autoClose`)
|
|
27
27
|
- title / footer 固定在滚动外,body 默认 SimpleBar
|
|
28
28
|
- `--kne-modal-*` / `--kne-drawer-*` CSS 变量管理高度链
|
|
@@ -254,7 +254,7 @@ npm i --save @kne/react-modal
|
|
|
254
254
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
255
255
|
|
|
256
256
|
```jsx
|
|
257
|
-
const { default: Modal, Drawer, DrawerContextHolder } = _ReactModal;
|
|
257
|
+
const { default: Modal, Drawer, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
258
258
|
const { Button, Space, message, Typography, Radio, App } = antd;
|
|
259
259
|
const { useState, useEffect } = React;
|
|
260
260
|
|
|
@@ -311,9 +311,7 @@ const BasicExample = () => {
|
|
|
311
311
|
<Button type="primary" onClick={() => setOpen(true)}>
|
|
312
312
|
保存评估备注
|
|
313
313
|
</Button>
|
|
314
|
-
<Text type="secondary">
|
|
315
|
-
最简受控弹层:切换 Modal / Drawer 对比同一套 props;异步 onConfirm 带 loading。
|
|
316
|
-
</Text>
|
|
314
|
+
<Text type="secondary">最简受控弹层:切换 Modal / Drawer 对比同一套 props;异步 onConfirm 带 loading。</Text>
|
|
317
315
|
{isDrawer ? (
|
|
318
316
|
<Drawer {...overlayProps} size="default">
|
|
319
317
|
{content}
|
|
@@ -327,6 +325,7 @@ const BasicExample = () => {
|
|
|
327
325
|
|
|
328
326
|
render(
|
|
329
327
|
<App>
|
|
328
|
+
<ModalContextHolder />
|
|
330
329
|
<DrawerContextHolder />
|
|
331
330
|
<BasicExample />
|
|
332
331
|
</App>
|
|
@@ -339,7 +338,7 @@ render(
|
|
|
339
338
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
340
339
|
|
|
341
340
|
```jsx
|
|
342
|
-
const { default: Modal, Drawer, DrawerContextHolder } = _ReactModal;
|
|
341
|
+
const { default: Modal, Drawer, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
343
342
|
const { Button, Space, Radio, Tag, message, Typography, App } = antd;
|
|
344
343
|
const { useState, useEffect } = React;
|
|
345
344
|
|
|
@@ -399,14 +398,8 @@ const FooterButtonsExample = () => {
|
|
|
399
398
|
</Space>
|
|
400
399
|
</div>
|
|
401
400
|
<div className="demo-job-preview-body">
|
|
402
|
-
<Paragraph style={{ marginTop: 0 }}>
|
|
403
|
-
|
|
404
|
-
</Paragraph>
|
|
405
|
-
<Paragraph style={{ marginBottom: 0 }}>
|
|
406
|
-
{noPadding
|
|
407
|
-
? 'noPadding=true:预览卡片应贴齐内容区边缘。'
|
|
408
|
-
: 'noPadding=false:预览卡片四周保留默认内边距。'}
|
|
409
|
-
</Paragraph>
|
|
401
|
+
<Paragraph style={{ marginTop: 0 }}>负责招聘中台、候选人评估等 B 端产品的前端交付;要求熟悉 React、工程化与组件库协作。</Paragraph>
|
|
402
|
+
<Paragraph style={{ marginBottom: 0 }}>{noPadding ? 'noPadding=true:预览卡片应贴齐内容区边缘。' : 'noPadding=false:预览卡片四周保留默认内边距。'}</Paragraph>
|
|
410
403
|
</div>
|
|
411
404
|
</div>
|
|
412
405
|
);
|
|
@@ -447,17 +440,14 @@ const FooterButtonsExample = () => {
|
|
|
447
440
|
noPadding={String(noPadding)}
|
|
448
441
|
</Button>
|
|
449
442
|
</Space>
|
|
450
|
-
{isDrawer ?
|
|
451
|
-
<Drawer {...overlayProps}>{content}</Drawer>
|
|
452
|
-
) : (
|
|
453
|
-
<Modal {...overlayProps}>{content}</Modal>
|
|
454
|
-
)}
|
|
443
|
+
{isDrawer ? <Drawer {...overlayProps}>{content}</Drawer> : <Modal {...overlayProps}>{content}</Modal>}
|
|
455
444
|
</Space>
|
|
456
445
|
);
|
|
457
446
|
};
|
|
458
447
|
|
|
459
448
|
render(
|
|
460
449
|
<App>
|
|
450
|
+
<ModalContextHolder />
|
|
461
451
|
<DrawerContextHolder />
|
|
462
452
|
<FooterButtonsExample />
|
|
463
453
|
</App>
|
|
@@ -470,7 +460,7 @@ render(
|
|
|
470
460
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
471
461
|
|
|
472
462
|
```jsx
|
|
473
|
-
const { useModal, useDrawer, DrawerContextHolder } = _ReactModal;
|
|
463
|
+
const { useModal, useDrawer, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
474
464
|
const { Button, Space, message, Descriptions, Tag, Typography, Radio, App } = antd;
|
|
475
465
|
const { useState } = React;
|
|
476
466
|
|
|
@@ -499,8 +489,7 @@ const CommandExample = () => {
|
|
|
499
489
|
</Descriptions.Item>
|
|
500
490
|
</Descriptions>
|
|
501
491
|
<Paragraph type="secondary" style={{ marginBottom: 12 }}>
|
|
502
|
-
命令式 {isDrawer ? 'Drawer' : 'Modal'} 适用于列表页「快速查看」;children 为函数时可调用
|
|
503
|
-
<Text code>close()</Text> 主动关闭。
|
|
492
|
+
命令式 {isDrawer ? 'Drawer' : 'Modal'} 适用于列表页「快速查看」;children 为函数时可调用 <Text code>close()</Text> 主动关闭。
|
|
504
493
|
</Paragraph>
|
|
505
494
|
<Button size="small" onClick={() => close()}>
|
|
506
495
|
关闭
|
|
@@ -531,15 +520,14 @@ const CommandExample = () => {
|
|
|
531
520
|
<Button type="primary" onClick={openDetail}>
|
|
532
521
|
从列表打开候选人快览
|
|
533
522
|
</Button>
|
|
534
|
-
<Text type="secondary">
|
|
535
|
-
Drawer 模式需挂载 DrawerContextHolder;Modal 使用 antd App 内置 useModal。
|
|
536
|
-
</Text>
|
|
523
|
+
<Text type="secondary">须挂载 ModalContextHolder(内容弹窗 useModal)与 DrawerContextHolder(useDrawer);确认框仍用 useConfirmModal。</Text>
|
|
537
524
|
</Space>
|
|
538
525
|
);
|
|
539
526
|
};
|
|
540
527
|
|
|
541
528
|
render(
|
|
542
529
|
<App>
|
|
530
|
+
<ModalContextHolder />
|
|
543
531
|
<DrawerContextHolder />
|
|
544
532
|
<CommandExample />
|
|
545
533
|
</App>
|
|
@@ -657,7 +645,7 @@ render(<BaseExample />);
|
|
|
657
645
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
658
646
|
|
|
659
647
|
```jsx
|
|
660
|
-
const { default: Modal, Drawer, DrawerContextHolder } = _ReactModal;
|
|
648
|
+
const { default: Modal, Drawer, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
661
649
|
const { Button, Space, Typography, Divider, Radio, App } = antd;
|
|
662
650
|
const { useState, useEffect } = React;
|
|
663
651
|
|
|
@@ -666,24 +654,15 @@ const { Title, Paragraph, Text } = Typography;
|
|
|
666
654
|
const EVAL_SECTIONS = [
|
|
667
655
|
{
|
|
668
656
|
title: '沟通表达',
|
|
669
|
-
items: [
|
|
670
|
-
'表达结构清晰,能准确复述业务目标与技术约束。',
|
|
671
|
-
'对追问能够给出有层次的回答,而非堆砌名词。'
|
|
672
|
-
]
|
|
657
|
+
items: ['表达结构清晰,能准确复述业务目标与技术约束。', '对追问能够给出有层次的回答,而非堆砌名词。']
|
|
673
658
|
},
|
|
674
659
|
{
|
|
675
660
|
title: '专业深度',
|
|
676
|
-
items: [
|
|
677
|
-
'熟悉 React 渲染机制,能说明列表虚拟化方案选型理由。',
|
|
678
|
-
'了解前端监控与错误边界在生产环境的实践。'
|
|
679
|
-
]
|
|
661
|
+
items: ['熟悉 React 渲染机制,能说明列表虚拟化方案选型理由。', '了解前端监控与错误边界在生产环境的实践。']
|
|
680
662
|
},
|
|
681
663
|
{
|
|
682
664
|
title: '项目复杂度',
|
|
683
|
-
items: [
|
|
684
|
-
'参与过多团队协同的中台项目,承担核心模块 Owner。',
|
|
685
|
-
'能描述需求变更下的架构演进与风险控制。'
|
|
686
|
-
]
|
|
665
|
+
items: ['参与过多团队协同的中台项目,承担核心模块 Owner。', '能描述需求变更下的架构演进与风险控制。']
|
|
687
666
|
},
|
|
688
667
|
{
|
|
689
668
|
title: '协作推进',
|
|
@@ -757,24 +736,10 @@ const LongContentExample = () => {
|
|
|
757
736
|
</Button>
|
|
758
737
|
<Button onClick={() => setOpenSelfScroll(true)}>自管滚动(bodyScroll=false)</Button>
|
|
759
738
|
</Space>
|
|
760
|
-
<Overlay
|
|
761
|
-
title="陈思远 · 面试评估纪要"
|
|
762
|
-
open={open}
|
|
763
|
-
onClose={() => setOpen(false)}
|
|
764
|
-
onConfirm={() => {}}
|
|
765
|
-
confirmText="保存纪要"
|
|
766
|
-
size={isDrawer ? 'default' : undefined}
|
|
767
|
-
>
|
|
739
|
+
<Overlay title="陈思远 · 面试评估纪要" open={open} onClose={() => setOpen(false)} onConfirm={() => {}} confirmText="保存纪要" size={isDrawer ? 'default' : undefined}>
|
|
768
740
|
<EvaluationContent />
|
|
769
741
|
</Overlay>
|
|
770
|
-
<Overlay
|
|
771
|
-
title="自管滚动示例"
|
|
772
|
-
open={openSelfScroll}
|
|
773
|
-
onClose={() => setOpenSelfScroll(false)}
|
|
774
|
-
bodyScroll={false}
|
|
775
|
-
footer={null}
|
|
776
|
-
size={isDrawer ? 'large' : undefined}
|
|
777
|
-
>
|
|
742
|
+
<Overlay title="自管滚动示例" open={openSelfScroll} onClose={() => setOpenSelfScroll(false)} bodyScroll={false} footer={null} size={isDrawer ? 'large' : undefined}>
|
|
778
743
|
<div
|
|
779
744
|
style={{
|
|
780
745
|
height: `var(${contentHeightVar})`,
|
|
@@ -798,6 +763,7 @@ const LongContentExample = () => {
|
|
|
798
763
|
|
|
799
764
|
render(
|
|
800
765
|
<App>
|
|
766
|
+
<ModalContextHolder />
|
|
801
767
|
<DrawerContextHolder />
|
|
802
768
|
<LongContentExample />
|
|
803
769
|
</App>
|
|
@@ -810,7 +776,7 @@ render(
|
|
|
810
776
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
811
777
|
|
|
812
778
|
```jsx
|
|
813
|
-
const { default: Modal, Drawer, DrawerContextHolder } = _ReactModal;
|
|
779
|
+
const { default: Modal, Drawer, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
814
780
|
const { Button, Space, Switch, Tag, Descriptions, Radio, Typography, App } = antd;
|
|
815
781
|
const { useState, useEffect } = React;
|
|
816
782
|
|
|
@@ -927,20 +893,14 @@ const HeightVarsExample = () => {
|
|
|
927
893
|
/>
|
|
928
894
|
</Space>
|
|
929
895
|
<Space wrap align="center">
|
|
930
|
-
<Switch
|
|
931
|
-
checked={customVars}
|
|
932
|
-
onChange={setCustomVars}
|
|
933
|
-
checkedChildren="自定义变量"
|
|
934
|
-
unCheckedChildren="默认变量"
|
|
935
|
-
/>
|
|
896
|
+
<Switch checked={customVars} onChange={setCustomVars} checkedChildren="自定义变量" unCheckedChildren="默认变量" />
|
|
936
897
|
<Button type="primary" onClick={() => setOpen(true)}>
|
|
937
898
|
打开弹层对比高度
|
|
938
899
|
</Button>
|
|
939
900
|
<Tag color={customVars ? 'blue' : 'default'}>{customVars ? '已覆盖 CSS 变量' : '库内默认值'}</Tag>
|
|
940
901
|
</Space>
|
|
941
902
|
<div style={{ color: 'rgba(0,0,0,0.45)', maxWidth: 640 }}>
|
|
942
|
-
通过 <code>style</code> 覆盖 {chrome.varPrefix}-* 变量。Drawer 无 viewport-gutter;Modal 可加大 gutter
|
|
943
|
-
使 body 明显变矮。色块绑定 <code>{chrome.contentHeightVar}</code>。
|
|
903
|
+
通过 <code>style</code> 覆盖 {chrome.varPrefix}-* 变量。Drawer 无 viewport-gutter;Modal 可加大 gutter 使 body 明显变矮。色块绑定 <code>{chrome.contentHeightVar}</code>。
|
|
944
904
|
</div>
|
|
945
905
|
<HeightProbe open={open} revision={revision} mode={mode} />
|
|
946
906
|
<Overlay
|
|
@@ -965,9 +925,7 @@ const HeightVarsExample = () => {
|
|
|
965
925
|
}}
|
|
966
926
|
>
|
|
967
927
|
<div style={{ padding: 12 }}>
|
|
968
|
-
<p style={{ marginTop: 0, fontWeight: 600 }}>
|
|
969
|
-
色块 height = var({chrome.contentHeightVar})。切换「自定义/默认」与 Modal/Drawer 后重新打开对比。
|
|
970
|
-
</p>
|
|
928
|
+
<p style={{ marginTop: 0, fontWeight: 600 }}>色块 height = var({chrome.contentHeightVar})。切换「自定义/默认」与 Modal/Drawer 后重新打开对比。</p>
|
|
971
929
|
{fillLines.map(text => (
|
|
972
930
|
<p key={text} style={{ margin: '4px 0' }}>
|
|
973
931
|
{text}
|
|
@@ -982,6 +940,7 @@ const HeightVarsExample = () => {
|
|
|
982
940
|
|
|
983
941
|
render(
|
|
984
942
|
<App>
|
|
943
|
+
<ModalContextHolder />
|
|
985
944
|
<DrawerContextHolder />
|
|
986
945
|
<HeightVarsExample />
|
|
987
946
|
</App>
|
|
@@ -994,7 +953,7 @@ render(
|
|
|
994
953
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
995
954
|
|
|
996
955
|
```jsx
|
|
997
|
-
const { default: Modal, Drawer, DrawerContextHolder } = _ReactModal;
|
|
956
|
+
const { default: Modal, Drawer, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
998
957
|
const { Button, Space, Switch, Radio, Tag, Descriptions, Typography, App } = antd;
|
|
999
958
|
const { useState, useEffect } = React;
|
|
1000
959
|
|
|
@@ -1130,12 +1089,7 @@ const ChromeHeightExample = () => {
|
|
|
1130
1089
|
<span>title</span>
|
|
1131
1090
|
<Switch checked={hasTitle} onChange={setHasTitle} checkedChildren="有" unCheckedChildren="空" />
|
|
1132
1091
|
<span>bodyScroll</span>
|
|
1133
|
-
<Switch
|
|
1134
|
-
checked={bodyScroll}
|
|
1135
|
-
onChange={setBodyScroll}
|
|
1136
|
-
checkedChildren="true"
|
|
1137
|
-
unCheckedChildren="false"
|
|
1138
|
-
/>
|
|
1092
|
+
<Switch checked={bodyScroll} onChange={setBodyScroll} checkedChildren="true" unCheckedChildren="false" />
|
|
1139
1093
|
</Space>
|
|
1140
1094
|
<div>
|
|
1141
1095
|
<div style={{ marginBottom: 8 }}>footer</div>
|
|
@@ -1185,9 +1139,7 @@ const ChromeHeightExample = () => {
|
|
|
1185
1139
|
}}
|
|
1186
1140
|
>
|
|
1187
1141
|
<div style={{ padding: 12 }}>
|
|
1188
|
-
<p style={{ marginTop: 0, fontWeight: 600 }}>
|
|
1189
|
-
滚动宿主 height: var({chrome.contentHeightVar})。footer=null 时 footer 变量应为 0。
|
|
1190
|
-
</p>
|
|
1142
|
+
<p style={{ marginTop: 0, fontWeight: 600 }}>滚动宿主 height: var({chrome.contentHeightVar})。footer=null 时 footer 变量应为 0。</p>
|
|
1191
1143
|
{lines.map(text => (
|
|
1192
1144
|
<p key={text}>{text}</p>
|
|
1193
1145
|
))}
|
|
@@ -1217,6 +1169,7 @@ const ChromeHeightExample = () => {
|
|
|
1217
1169
|
|
|
1218
1170
|
render(
|
|
1219
1171
|
<App>
|
|
1172
|
+
<ModalContextHolder />
|
|
1220
1173
|
<DrawerContextHolder />
|
|
1221
1174
|
<ChromeHeightExample />
|
|
1222
1175
|
</App>
|
|
@@ -1229,7 +1182,7 @@ render(
|
|
|
1229
1182
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
1230
1183
|
|
|
1231
1184
|
```jsx
|
|
1232
|
-
const { default: Modal, useModal, DrawerContextHolder } = _ReactModal;
|
|
1185
|
+
const { default: Modal, useModal, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
1233
1186
|
const { Button, Space, Radio, Typography, App } = antd;
|
|
1234
1187
|
const { useState } = React;
|
|
1235
1188
|
|
|
@@ -1274,7 +1227,7 @@ const LimitedHeightExample = () => {
|
|
|
1274
1227
|
size="small"
|
|
1275
1228
|
options={[
|
|
1276
1229
|
{ label: '声明式 Modal', value: 'declarative' },
|
|
1277
|
-
{ label: 'useModal
|
|
1230
|
+
{ label: 'useModal(命令式)', value: 'imperative' }
|
|
1278
1231
|
]}
|
|
1279
1232
|
onChange={e => setMode(e.target.value)}
|
|
1280
1233
|
/>
|
|
@@ -1294,9 +1247,7 @@ const LimitedHeightExample = () => {
|
|
|
1294
1247
|
>
|
|
1295
1248
|
打开高度受限弹窗
|
|
1296
1249
|
</Button>
|
|
1297
|
-
<Text type="secondary">
|
|
1298
|
-
useModal 走 antd modal.info,已覆盖 <code>.ant-modal-confirm-paragraph</code> 的 12px 宽度扣减。
|
|
1299
|
-
</Text>
|
|
1250
|
+
<Text type="secondary">useModal 走声明式 Modal(经 ModalContextHolder 就近 patch),与声明式同一套 chrome。</Text>
|
|
1300
1251
|
{mode === 'declarative' ? (
|
|
1301
1252
|
<Modal {...overlayProps} open={open}>
|
|
1302
1253
|
{content}
|
|
@@ -1308,6 +1259,7 @@ const LimitedHeightExample = () => {
|
|
|
1308
1259
|
|
|
1309
1260
|
render(
|
|
1310
1261
|
<App>
|
|
1262
|
+
<ModalContextHolder />
|
|
1311
1263
|
<DrawerContextHolder />
|
|
1312
1264
|
<LimitedHeightExample />
|
|
1313
1265
|
</App>
|
|
@@ -1320,30 +1272,8 @@ render(
|
|
|
1320
1272
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
1321
1273
|
|
|
1322
1274
|
```jsx
|
|
1323
|
-
const {
|
|
1324
|
-
|
|
1325
|
-
Drawer,
|
|
1326
|
-
DrawerContextHolder,
|
|
1327
|
-
TabsLayout,
|
|
1328
|
-
ColumnsLayout,
|
|
1329
|
-
ScrollRegion,
|
|
1330
|
-
modalClassNames
|
|
1331
|
-
} = _ReactModal;
|
|
1332
|
-
const {
|
|
1333
|
-
Button,
|
|
1334
|
-
Space,
|
|
1335
|
-
Splitter,
|
|
1336
|
-
Input,
|
|
1337
|
-
Avatar,
|
|
1338
|
-
Tag,
|
|
1339
|
-
Descriptions,
|
|
1340
|
-
Progress,
|
|
1341
|
-
Typography,
|
|
1342
|
-
Divider,
|
|
1343
|
-
App,
|
|
1344
|
-
message,
|
|
1345
|
-
Radio
|
|
1346
|
-
} = antd;
|
|
1275
|
+
const { default: Modal, Drawer, DrawerContextHolder, ModalContextHolder, TabsLayout, ColumnsLayout, ScrollRegion, modalClassNames } = _ReactModal;
|
|
1276
|
+
const { Button, Space, Splitter, Input, Avatar, Tag, Descriptions, Progress, Typography, Divider, App, message, Radio } = antd;
|
|
1347
1277
|
const { useState, useMemo, useEffect } = React;
|
|
1348
1278
|
|
|
1349
1279
|
const { Text, Title, Paragraph } = Typography;
|
|
@@ -1500,26 +1430,15 @@ const SCORE_LABELS = {
|
|
|
1500
1430
|
const CandidateList = ({ items, activeKey, onSelect, search, onSearchChange }) => (
|
|
1501
1431
|
<>
|
|
1502
1432
|
<div className="modal-scroll-region-sticky candidate-list-toolbar">
|
|
1503
|
-
<Input
|
|
1504
|
-
allowClear
|
|
1505
|
-
placeholder="搜索姓名、岗位、城市…"
|
|
1506
|
-
value={search}
|
|
1507
|
-
onChange={e => onSearchChange(e.target.value)}
|
|
1508
|
-
/>
|
|
1433
|
+
<Input allowClear placeholder="搜索姓名、岗位、城市…" value={search} onChange={e => onSearchChange(e.target.value)} />
|
|
1509
1434
|
<Text type="secondary">本批 {items.length} 人 · 点击切换右侧详情</Text>
|
|
1510
1435
|
</div>
|
|
1511
1436
|
{items.map(item => {
|
|
1512
1437
|
const status = STATUS_MAP[item.status] || STATUS_MAP.pending;
|
|
1513
1438
|
return (
|
|
1514
|
-
<div
|
|
1515
|
-
key={item.key}
|
|
1516
|
-
className={`candidate-list-item${item.key === activeKey ? ' is-active' : ''}`}
|
|
1517
|
-
onClick={() => onSelect(item.key)}
|
|
1518
|
-
>
|
|
1439
|
+
<div key={item.key} className={`candidate-list-item${item.key === activeKey ? ' is-active' : ''}`} onClick={() => onSelect(item.key)}>
|
|
1519
1440
|
<div className="candidate-list-item-main">
|
|
1520
|
-
<Avatar style={{ backgroundColor: item.key === activeKey ? '#1677ff' : '#87d068' }}>
|
|
1521
|
-
{item.name.slice(-2)}
|
|
1522
|
-
</Avatar>
|
|
1441
|
+
<Avatar style={{ backgroundColor: item.key === activeKey ? '#1677ff' : '#87d068' }}>{item.name.slice(-2)}</Avatar>
|
|
1523
1442
|
<div className="candidate-list-item-body">
|
|
1524
1443
|
<div className="candidate-list-item-title">{item.name}</div>
|
|
1525
1444
|
<div className="candidate-list-item-meta">
|
|
@@ -1541,8 +1460,7 @@ const CandidateDetail = ({ candidate }) => {
|
|
|
1541
1460
|
return null;
|
|
1542
1461
|
}
|
|
1543
1462
|
const status = STATUS_MAP[candidate.status] || STATUS_MAP.pending;
|
|
1544
|
-
const avgScore =
|
|
1545
|
-
Object.values(candidate.scores).reduce((a, b) => a + b, 0) / Object.values(candidate.scores).length;
|
|
1463
|
+
const avgScore = Object.values(candidate.scores).reduce((a, b) => a + b, 0) / Object.values(candidate.scores).length;
|
|
1546
1464
|
|
|
1547
1465
|
return (
|
|
1548
1466
|
<div className="candidate-detail">
|
|
@@ -1560,9 +1478,7 @@ const CandidateDetail = ({ candidate }) => {
|
|
|
1560
1478
|
</div>
|
|
1561
1479
|
<div style={{ textAlign: 'right' }}>
|
|
1562
1480
|
<Text type="secondary">综合</Text>
|
|
1563
|
-
<div style={{ fontSize: 28, fontWeight: 600, color: '#1677ff', lineHeight: 1.2 }}>
|
|
1564
|
-
{avgScore.toFixed(1)}
|
|
1565
|
-
</div>
|
|
1481
|
+
<div style={{ fontSize: 28, fontWeight: 600, color: '#1677ff', lineHeight: 1.2 }}>{avgScore.toFixed(1)}</div>
|
|
1566
1482
|
</div>
|
|
1567
1483
|
</div>
|
|
1568
1484
|
|
|
@@ -1611,12 +1527,7 @@ const useCandidatePanel = () => {
|
|
|
1611
1527
|
if (!q) {
|
|
1612
1528
|
return ALL_CANDIDATES;
|
|
1613
1529
|
}
|
|
1614
|
-
return ALL_CANDIDATES.filter(
|
|
1615
|
-
c =>
|
|
1616
|
-
c.name.toLowerCase().includes(q) ||
|
|
1617
|
-
c.role.toLowerCase().includes(q) ||
|
|
1618
|
-
c.city.toLowerCase().includes(q)
|
|
1619
|
-
);
|
|
1530
|
+
return ALL_CANDIDATES.filter(c => c.name.toLowerCase().includes(q) || c.role.toLowerCase().includes(q) || c.city.toLowerCase().includes(q));
|
|
1620
1531
|
}, [search]);
|
|
1621
1532
|
|
|
1622
1533
|
const current = filtered.find(item => item.key === active) || filtered[0];
|
|
@@ -1630,13 +1541,7 @@ const ColumnsPane = () => {
|
|
|
1630
1541
|
return (
|
|
1631
1542
|
<ColumnsLayout widths={['34%', '1fr']}>
|
|
1632
1543
|
<ScrollRegion>
|
|
1633
|
-
<CandidateList
|
|
1634
|
-
items={filtered}
|
|
1635
|
-
activeKey={current?.key}
|
|
1636
|
-
onSelect={setActive}
|
|
1637
|
-
search={search}
|
|
1638
|
-
onSearchChange={setSearch}
|
|
1639
|
-
/>
|
|
1544
|
+
<CandidateList items={filtered} activeKey={current?.key} onSelect={setActive} search={search} onSearchChange={setSearch} />
|
|
1640
1545
|
</ScrollRegion>
|
|
1641
1546
|
<ScrollRegion inset>
|
|
1642
1547
|
<CandidateDetail candidate={current} />
|
|
@@ -1651,22 +1556,10 @@ const SplitterPane = () => {
|
|
|
1651
1556
|
return (
|
|
1652
1557
|
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', minHeight: 0 }}>
|
|
1653
1558
|
<p className="demo-panel-hint">可拖拽中间分隔条调整列表宽度,左右列仍各自 SimpleBar 滚动。</p>
|
|
1654
|
-
<Splitter
|
|
1655
|
-
className={modalClassNames.splitter}
|
|
1656
|
-
style={{ flex: 1, minHeight: 0 }}
|
|
1657
|
-
defaultSize="34%"
|
|
1658
|
-
min="240"
|
|
1659
|
-
max="52%"
|
|
1660
|
-
>
|
|
1559
|
+
<Splitter className={modalClassNames.splitter} style={{ flex: 1, minHeight: 0 }} defaultSize="34%" min="240" max="52%">
|
|
1661
1560
|
<Splitter.Panel>
|
|
1662
1561
|
<ScrollRegion>
|
|
1663
|
-
<CandidateList
|
|
1664
|
-
items={filtered}
|
|
1665
|
-
activeKey={current?.key}
|
|
1666
|
-
onSelect={setActive}
|
|
1667
|
-
search={search}
|
|
1668
|
-
onSearchChange={setSearch}
|
|
1669
|
-
/>
|
|
1562
|
+
<CandidateList items={filtered} activeKey={current?.key} onSelect={setActive} search={search} onSearchChange={setSearch} />
|
|
1670
1563
|
</ScrollRegion>
|
|
1671
1564
|
</Splitter.Panel>
|
|
1672
1565
|
<Splitter.Panel>
|
|
@@ -1819,6 +1712,7 @@ const ExtendLayoutExample = () => {
|
|
|
1819
1712
|
|
|
1820
1713
|
render(
|
|
1821
1714
|
<App>
|
|
1715
|
+
<ModalContextHolder />
|
|
1822
1716
|
<DrawerContextHolder />
|
|
1823
1717
|
<ExtendLayoutExample />
|
|
1824
1718
|
</App>
|
|
@@ -1831,7 +1725,7 @@ render(
|
|
|
1831
1725
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),antd(antd)
|
|
1832
1726
|
|
|
1833
1727
|
```jsx
|
|
1834
|
-
const { default: Modal, useModal, useDrawer, DrawerContextHolder } = _ReactModal;
|
|
1728
|
+
const { default: Modal, useModal, useDrawer, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
1835
1729
|
const { Button, Space, Typography, Tag, message, Checkbox, Radio, App } = antd;
|
|
1836
1730
|
const { useState, useEffect } = React;
|
|
1837
1731
|
const { Text, Paragraph } = Typography;
|
|
@@ -1870,11 +1764,7 @@ const NestProbe = ({ open, isDrawer }) => {
|
|
|
1870
1764
|
return <Text type="secondary">打开内层后显示挂载探针</Text>;
|
|
1871
1765
|
}
|
|
1872
1766
|
|
|
1873
|
-
return
|
|
1874
|
-
<Tag color={info.hoisted ? 'success' : 'error'}>
|
|
1875
|
-
内层 Modal {info.hoisted ? '已 hoist 到外层外侧' : '挂载异常'}
|
|
1876
|
-
</Tag>
|
|
1877
|
-
);
|
|
1767
|
+
return <Tag color={info.hoisted ? 'success' : 'error'}>内层 Modal {info.hoisted ? '已 hoist 到外层外侧' : '挂载异常'}</Tag>;
|
|
1878
1768
|
};
|
|
1879
1769
|
|
|
1880
1770
|
const ExportFieldPicker = ({ isDrawer }) => {
|
|
@@ -1884,8 +1774,7 @@ const ExportFieldPicker = ({ isDrawer }) => {
|
|
|
1884
1774
|
return (
|
|
1885
1775
|
<div>
|
|
1886
1776
|
<Paragraph>
|
|
1887
|
-
已选择本批 <Text strong>8</Text> 位候选人。内层始终为声明式 Modal;外层当前为{' '}
|
|
1888
|
-
<Text code>{isDrawer ? 'Drawer' : 'Modal'}</Text>。
|
|
1777
|
+
已选择本批 <Text strong>8</Text> 位候选人。内层始终为声明式 Modal;外层当前为 <Text code>{isDrawer ? 'Drawer' : 'Modal'}</Text>。
|
|
1889
1778
|
</Paragraph>
|
|
1890
1779
|
<Space>
|
|
1891
1780
|
<Button type="primary" onClick={() => setInnerOpen(true)}>
|
|
@@ -1907,12 +1796,7 @@ const ExportFieldPicker = ({ isDrawer }) => {
|
|
|
1907
1796
|
}}
|
|
1908
1797
|
confirmText="确认字段"
|
|
1909
1798
|
>
|
|
1910
|
-
<Checkbox.Group
|
|
1911
|
-
style={{ display: 'flex', flexDirection: 'column', gap: 10 }}
|
|
1912
|
-
options={EXPORT_FIELDS}
|
|
1913
|
-
value={checked}
|
|
1914
|
-
onChange={setChecked}
|
|
1915
|
-
/>
|
|
1799
|
+
<Checkbox.Group style={{ display: 'flex', flexDirection: 'column', gap: 10 }} options={EXPORT_FIELDS} value={checked} onChange={setChecked} />
|
|
1916
1800
|
</Modal>
|
|
1917
1801
|
</div>
|
|
1918
1802
|
);
|
|
@@ -1961,6 +1845,7 @@ const NestedModalExample = () => {
|
|
|
1961
1845
|
|
|
1962
1846
|
render(
|
|
1963
1847
|
<App>
|
|
1848
|
+
<ModalContextHolder />
|
|
1964
1849
|
<DrawerContextHolder />
|
|
1965
1850
|
<NestedModalExample />
|
|
1966
1851
|
</App>
|
|
@@ -1973,7 +1858,7 @@ render(
|
|
|
1973
1858
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),_FormInfo(@kne/form-info)[import * as _FormInfo from "@kne/form-info"],(@kne/form-info/dist/index.css),antd(antd)
|
|
1974
1859
|
|
|
1975
1860
|
```jsx
|
|
1976
|
-
const { createModalRender, createDrawerRender, DrawerContextHolder } = _ReactModal;
|
|
1861
|
+
const { createModalRender, createDrawerRender, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
1977
1862
|
const { default: FormInfo, FormModal, Input, TextArea } = _FormInfo;
|
|
1978
1863
|
const { Button, Space, Typography, App, message, Switch, Flex, Radio } = antd;
|
|
1979
1864
|
const { useState, useMemo, useEffect } = React;
|
|
@@ -2009,11 +1894,7 @@ const SECTION_DEFS = [
|
|
|
2009
1894
|
{
|
|
2010
1895
|
key: 'experience',
|
|
2011
1896
|
title: '经历与补充',
|
|
2012
|
-
fields: Array.from({ length: 16 }, (_, i) => [
|
|
2013
|
-
`expField${i + 1}`,
|
|
2014
|
-
`经历补充项 ${i + 1}`,
|
|
2015
|
-
i % 4 === 0 ? 'REQ' : ''
|
|
2016
|
-
])
|
|
1897
|
+
fields: Array.from({ length: 16 }, (_, i) => [`expField${i + 1}`, `经历补充项 ${i + 1}`, i % 4 === 0 ? 'REQ' : ''])
|
|
2017
1898
|
}
|
|
2018
1899
|
];
|
|
2019
1900
|
|
|
@@ -2033,8 +1914,7 @@ const buildInitialData = () => {
|
|
|
2033
1914
|
collabScore: '4',
|
|
2034
1915
|
cultureScore: '5',
|
|
2035
1916
|
overallScore: '4.5',
|
|
2036
|
-
summary:
|
|
2037
|
-
'沟通清晰,项目推进稳定。以下为加长评估说明,用于验证弹窗 body 在超长表单下的 SimpleBar 滚动:标题与底部按钮应固定,仅中间表单区域滚动。'.repeat(3)
|
|
1917
|
+
summary: '沟通清晰,项目推进稳定。以下为加长评估说明,用于验证弹窗 body 在超长表单下的 SimpleBar 滚动:标题与底部按钮应固定,仅中间表单区域滚动。'.repeat(3)
|
|
2038
1918
|
};
|
|
2039
1919
|
SECTION_DEFS[2].fields.forEach(([name], i) => {
|
|
2040
1920
|
data[name] = `补充说明内容 ${i + 1}:用于拉长表单高度。`;
|
|
@@ -2063,20 +1943,8 @@ const LongFormFields = () => (
|
|
|
2063
1943
|
gap={20}
|
|
2064
1944
|
list={[
|
|
2065
1945
|
<TextArea key="summary" name="summary" label="综合评语" rule="REQ" block />,
|
|
2066
|
-
<TextArea
|
|
2067
|
-
|
|
2068
|
-
name="risk"
|
|
2069
|
-
label="风险与待跟进"
|
|
2070
|
-
block
|
|
2071
|
-
placeholder="列出风险点、待确认事项等"
|
|
2072
|
-
/>,
|
|
2073
|
-
<TextArea
|
|
2074
|
-
key="plan"
|
|
2075
|
-
name="plan"
|
|
2076
|
-
label="入职 / 下轮计划"
|
|
2077
|
-
block
|
|
2078
|
-
placeholder="试用期目标、面试官建议等"
|
|
2079
|
-
/>
|
|
1946
|
+
<TextArea key="risk" name="risk" label="风险与待跟进" block placeholder="列出风险点、待确认事项等" />,
|
|
1947
|
+
<TextArea key="plan" name="plan" label="入职 / 下轮计划" block placeholder="试用期目标、面试官建议等" />
|
|
2080
1948
|
]}
|
|
2081
1949
|
/>
|
|
2082
1950
|
{Array.from({ length: 8 }, (_, block) => (
|
|
@@ -2108,20 +1976,9 @@ const FormInfoModalExample = () => {
|
|
|
2108
1976
|
}
|
|
2109
1977
|
}, [mode]);
|
|
2110
1978
|
|
|
2111
|
-
const renderModalBase = isDrawer
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
const renderModal = ({
|
|
2116
|
-
formProps,
|
|
2117
|
-
saveText,
|
|
2118
|
-
autoClose,
|
|
2119
|
-
onCancel,
|
|
2120
|
-
footer,
|
|
2121
|
-
modalRender,
|
|
2122
|
-
children,
|
|
2123
|
-
...props
|
|
2124
|
-
}) =>
|
|
1979
|
+
const renderModalBase = isDrawer ? createDrawerRender({ placement: 'right', footerButtons: [], bodyScroll: true, size: 'large' }) : createModalRender({ footerButtons: [], bodyScroll: true, size: 'large' });
|
|
1980
|
+
|
|
1981
|
+
const renderModal = ({ formProps, saveText, autoClose, onCancel, footer, modalRender, children, ...props }) =>
|
|
2125
1982
|
renderModalBase({
|
|
2126
1983
|
...props,
|
|
2127
1984
|
bodyScroll,
|
|
@@ -2155,9 +2012,7 @@ const FormInfoModalExample = () => {
|
|
|
2155
2012
|
<Switch checked={bodyScroll} onChange={setBodyScroll} checkedChildren="开" unCheckedChildren="关" />
|
|
2156
2013
|
</Space>
|
|
2157
2014
|
</Space>
|
|
2158
|
-
<Text type="secondary">
|
|
2159
|
-
createModalRender / createDrawerRender 注入默认 props;切换 Modal / Drawer 对比 form-info 宿主集成。
|
|
2160
|
-
</Text>
|
|
2015
|
+
<Text type="secondary">createModalRender / createDrawerRender 注入默认 props;切换 Modal / Drawer 对比 form-info 宿主集成。</Text>
|
|
2161
2016
|
|
|
2162
2017
|
<FormModal
|
|
2163
2018
|
title={isDrawer ? '候选人深度评估(侧滑)' : '候选人深度评估(超长表单)'}
|
|
@@ -2183,6 +2038,7 @@ const FormInfoModalExample = () => {
|
|
|
2183
2038
|
|
|
2184
2039
|
render(
|
|
2185
2040
|
<App>
|
|
2041
|
+
<ModalContextHolder />
|
|
2186
2042
|
<DrawerContextHolder />
|
|
2187
2043
|
<FormInfoModalExample />
|
|
2188
2044
|
</App>
|
|
@@ -2195,7 +2051,7 @@ render(
|
|
|
2195
2051
|
- _ReactModal(@kne/current-lib_react-modal)[import * as _ReactModal from "@kne/react-modal"],(@kne/current-lib_react-modal/dist/index.css),_FormInfo(@kne/form-info)[import * as _FormInfo from "@kne/form-info"],(@kne/form-info/dist/index.css),antd(antd)
|
|
2196
2052
|
|
|
2197
2053
|
```jsx
|
|
2198
|
-
const { createModalRender, createDrawerRender, modalClassNames, DrawerContextHolder } = _ReactModal;
|
|
2054
|
+
const { createModalRender, createDrawerRender, modalClassNames, DrawerContextHolder, ModalContextHolder } = _ReactModal;
|
|
2199
2055
|
const { default: FormInfo, FormStepsModal, List, Input, TextArea } = _FormInfo;
|
|
2200
2056
|
const { Button, Space, Typography, App, message, Flex, Radio } = antd;
|
|
2201
2057
|
const { useState, useEffect } = React;
|
|
@@ -2217,25 +2073,17 @@ const renderStepsModalBase = isDrawer =>
|
|
|
2217
2073
|
className: modalClassNames.stepsForm
|
|
2218
2074
|
});
|
|
2219
2075
|
|
|
2220
|
-
const renderStepsModal =
|
|
2221
|
-
|
|
2222
|
-
saveText,
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
})
|
|
2231
|
-
renderStepsModalBase(isDrawer)({
|
|
2232
|
-
...props,
|
|
2233
|
-
className,
|
|
2234
|
-
onClose: onCancel,
|
|
2235
|
-
footer: typeof footer === 'function' ? footer() : footer,
|
|
2236
|
-
modalRender,
|
|
2237
|
-
children
|
|
2238
|
-
});
|
|
2076
|
+
const renderStepsModal =
|
|
2077
|
+
isDrawer =>
|
|
2078
|
+
({ formProps, saveText, autoClose, onCancel, footer, modalRender, children, className, ...props }) =>
|
|
2079
|
+
renderStepsModalBase(isDrawer)({
|
|
2080
|
+
...props,
|
|
2081
|
+
className,
|
|
2082
|
+
onClose: onCancel,
|
|
2083
|
+
footer: typeof footer === 'function' ? footer() : footer,
|
|
2084
|
+
modalRender,
|
|
2085
|
+
children
|
|
2086
|
+
});
|
|
2239
2087
|
|
|
2240
2088
|
const STEP_DATA = {
|
|
2241
2089
|
name: '李四',
|
|
@@ -2340,21 +2188,9 @@ const FormInfoStepsModalExample = () => {
|
|
|
2340
2188
|
title="维度评分"
|
|
2341
2189
|
column={2}
|
|
2342
2190
|
gap={20}
|
|
2343
|
-
list={[
|
|
2344
|
-
<Input name="commScore" label="沟通表达" rule="REQ" />,
|
|
2345
|
-
<Input name="techScore" label="专业深度" rule="REQ" />,
|
|
2346
|
-
<Input name="projectScore" label="项目复杂度" rule="REQ" />
|
|
2347
|
-
]}
|
|
2348
|
-
/>
|
|
2349
|
-
<FormInfo
|
|
2350
|
-
bordered
|
|
2351
|
-
title="评语"
|
|
2352
|
-
column={1}
|
|
2353
|
-
gap={20}
|
|
2354
|
-
list={[
|
|
2355
|
-
<TextArea name="summary" label="综合评语" rule="REQ" block rows={4} />
|
|
2356
|
-
]}
|
|
2191
|
+
list={[<Input name="commScore" label="沟通表达" rule="REQ" />, <Input name="techScore" label="专业深度" rule="REQ" />, <Input name="projectScore" label="项目复杂度" rule="REQ" />]}
|
|
2357
2192
|
/>
|
|
2193
|
+
<FormInfo bordered title="评语" column={1} gap={20} list={[<TextArea name="summary" label="综合评语" rule="REQ" block rows={4} />]} />
|
|
2358
2194
|
</Flex>
|
|
2359
2195
|
)
|
|
2360
2196
|
},
|
|
@@ -2371,22 +2207,9 @@ const FormInfoStepsModalExample = () => {
|
|
|
2371
2207
|
maxLength={5}
|
|
2372
2208
|
addText="添加经历"
|
|
2373
2209
|
itemTitle={({ index, data }) => data?.companyName || `经历 ${index + 1}`}
|
|
2374
|
-
list={[
|
|
2375
|
-
<Input name="companyName" label="公司" rule="REQ" />,
|
|
2376
|
-
<Input name="role" label="职位" rule="REQ" />,
|
|
2377
|
-
<Input name="years" label="年限" placeholder="例如 2年" />
|
|
2378
|
-
]}
|
|
2379
|
-
/>
|
|
2380
|
-
<FormInfo
|
|
2381
|
-
bordered
|
|
2382
|
-
title="目标与风险"
|
|
2383
|
-
column={1}
|
|
2384
|
-
gap={20}
|
|
2385
|
-
list={[
|
|
2386
|
-
<TextArea name="objectives" label="培养目标" rule="REQ" block rows={4} />,
|
|
2387
|
-
<TextArea name="risks" label="风险与跟进" block rows={3} />
|
|
2388
|
-
]}
|
|
2210
|
+
list={[<Input name="companyName" label="公司" rule="REQ" />, <Input name="role" label="职位" rule="REQ" />, <Input name="years" label="年限" placeholder="例如 2年" />]}
|
|
2389
2211
|
/>
|
|
2212
|
+
<FormInfo bordered title="目标与风险" column={1} gap={20} list={[<TextArea name="objectives" label="培养目标" rule="REQ" block rows={4} />, <TextArea name="risks" label="风险与跟进" block rows={3} />]} />
|
|
2390
2213
|
</Flex>
|
|
2391
2214
|
)
|
|
2392
2215
|
}
|
|
@@ -2398,6 +2221,7 @@ const FormInfoStepsModalExample = () => {
|
|
|
2398
2221
|
|
|
2399
2222
|
render(
|
|
2400
2223
|
<App>
|
|
2224
|
+
<ModalContextHolder />
|
|
2401
2225
|
<DrawerContextHolder />
|
|
2402
2226
|
<FormInfoStepsModalExample />
|
|
2403
2227
|
</App>
|
|
@@ -2413,52 +2237,56 @@ render(
|
|
|
2413
2237
|
|
|
2414
2238
|
##### 属性
|
|
2415
2239
|
|
|
2416
|
-
| 属性
|
|
2417
|
-
|
|
2418
|
-
| open
|
|
2419
|
-
| onClose
|
|
2420
|
-
| title
|
|
2421
|
-
| children
|
|
2422
|
-
| onConfirm
|
|
2423
|
-
| onCancel
|
|
2424
|
-
| confirmText
|
|
2425
|
-
| cancelText
|
|
2426
|
-
| footer
|
|
2427
|
-
| footerButtons
|
|
2428
|
-
| size
|
|
2429
|
-
| noPadding
|
|
2430
|
-
| maskClosable
|
|
2431
|
-
| closable
|
|
2432
|
-
| bodyScroll
|
|
2433
|
-
| mobileFullscreen
|
|
2434
|
-
| getContainer
|
|
2435
|
-
| width / zIndex / className / afterClose / style / styles | -
|
|
2240
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
2241
|
+
| -------------------------------------------------------- | ------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
|
|
2242
|
+
| open | boolean | - | 是否显示 |
|
|
2243
|
+
| onClose | function | - | 关闭回调;受控时由此改 `open` |
|
|
2244
|
+
| title | ReactNode \| function | - | 标题;为 function 时入参含 `close` |
|
|
2245
|
+
| children | ReactNode \| function | - | 内容;为 function 时入参含 `close` |
|
|
2246
|
+
| onConfirm | function | - | 默认确认按钮;支持 Promise;返回 `false` 不关闭 |
|
|
2247
|
+
| onCancel | function | - | 默认取消按钮;语义同 `onConfirm` |
|
|
2248
|
+
| confirmText | ReactNode | - | 默认确认文案(默认 intl Confirm) |
|
|
2249
|
+
| cancelText | ReactNode | - | 默认取消文案(默认 intl Cancel) |
|
|
2250
|
+
| footer | ReactNode \| function \| null | - | 左侧 footer 插槽;与 `footerButtons` 均为「未设置」且 `footer === null` 时不渲染 footer |
|
|
2251
|
+
| footerButtons | array \| function | - | 右侧按钮区,见下表;未传时为取消+确认 |
|
|
2252
|
+
| size | `small` \| `default` \| `large` | `default` | 桌面宽度档位 |
|
|
2253
|
+
| noPadding | boolean | false | 去掉 body 内边距。未传且 `bodyScroll={false}` 时默认视为 true;显式 `noPadding={false}` 可保留内边距 |
|
|
2254
|
+
| maskClosable | boolean | false | 点击蒙层是否关闭 |
|
|
2255
|
+
| closable | boolean | true | 是否显示右上角关闭 |
|
|
2256
|
+
| bodyScroll | boolean | true | true 使用 SimpleBar;false 不挂 SimpleBar,内容自管滚动,且默认 noPadding(可用 `noPadding={false}` 覆盖) |
|
|
2257
|
+
| mobileFullscreen | boolean | true | 移动端是否全屏 |
|
|
2258
|
+
| getContainer | HTMLElement \| function | - | 挂载容器;嵌套时默认挂到外层 `.ant-modal-root` 外侧 |
|
|
2259
|
+
| width / zIndex / className / afterClose / style / styles | - | - | 透传或覆盖 antd Modal |
|
|
2436
2260
|
|
|
2437
2261
|
其余未列出参数按 antd Modal 习惯透传。
|
|
2438
2262
|
|
|
2439
2263
|
##### footerButtons 项
|
|
2440
2264
|
|
|
2441
|
-
| 属性
|
|
2442
|
-
|
|
2443
|
-
| children
|
|
2444
|
-
| type
|
|
2445
|
-
| onClick
|
|
2446
|
-
| autoClose
|
|
2447
|
-
| display
|
|
2448
|
-
| ButtonComponent | component
|
|
2449
|
-
| ...
|
|
2265
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
2266
|
+
| --------------- | ------------------- | ------ | ----------------------------------------------------------------------------------------- |
|
|
2267
|
+
| children | ReactNode | - | 按钮文案 |
|
|
2268
|
+
| type | string | - | antd Button type |
|
|
2269
|
+
| onClick | function | - | 可返回 Promise;末参为 `targetProps`(含 `close`);`autoClose` 且结果 `!== false` 时关闭 |
|
|
2270
|
+
| autoClose | boolean | true | 点击后是否自动关闭 |
|
|
2271
|
+
| display | boolean \| function | - | `false` 隐藏;function 返回值决定是否展示 |
|
|
2272
|
+
| ButtonComponent | component | - | 自定义按钮;默认走 ButtonGroup 内 LoadingButton |
|
|
2273
|
+
| ... | - | - | 其余透传 Button |
|
|
2450
2274
|
|
|
2451
2275
|
- `footerButtons={[]}`:不渲染按钮列(可与左侧 `footer` 并存)。**移动端**此模式且 `footer` 有内容时(如 FormModal 自带 Submit/Cancel),按钮区会自动居中,与默认 `footerButtons` 行为一致。
|
|
2452
2276
|
- `footer === null` 且未传 `footerButtons`:不渲染整个 footer 区
|
|
2453
2277
|
|
|
2454
2278
|
#### useModal
|
|
2455
2279
|
|
|
2280
|
+
命令式内容弹窗。须在 antd `App` 内挂载 **`<ModalContextHolder />`**(页面根层);弹窗内容树内另有 `ModalLayerProvider`,嵌套 `useModal` 会就近 patch,叠层交给 antd `ZIndexContext`。**不**再走 `App.modal.info` / ConfirmDialog。
|
|
2281
|
+
|
|
2282
|
+
打开时用 `document.activeElement` 解析示例手机框(`.example-driver-device-scroll`,与 `useDrawer` / FileModal 一致),使 `useFormModal` 在手机预览内挂进设备框,而不是落到 Global Holder 外层。
|
|
2283
|
+
|
|
2456
2284
|
命令式打开弹窗,参数同 Modal。需在 antd `App`(或 `App.useApp` 可用)上下文中使用。
|
|
2457
2285
|
|
|
2458
2286
|
##### 返回值
|
|
2459
2287
|
|
|
2460
|
-
| 属性
|
|
2461
|
-
|
|
2288
|
+
| 属性 | 类型 | 描述 |
|
|
2289
|
+
| ----- | -------- | --------------------------------------------------------- |
|
|
2462
2290
|
| modal | function | 调用后弹出 Modal;返回 `{ close }`;默认 `zIndex` 为 1100 |
|
|
2463
2291
|
|
|
2464
2292
|
#### useConfirmModal
|
|
@@ -2467,29 +2295,29 @@ render(
|
|
|
2467
2295
|
|
|
2468
2296
|
##### 参数
|
|
2469
2297
|
|
|
2470
|
-
| 属性
|
|
2471
|
-
|
|
2472
|
-
| type
|
|
2473
|
-
| title
|
|
2474
|
-
| message
|
|
2475
|
-
| danger
|
|
2476
|
-
| confirmType
|
|
2477
|
-
| icon
|
|
2478
|
-
| onConfirm
|
|
2479
|
-
| onCancel
|
|
2480
|
-
| confirmText
|
|
2481
|
-
| cancelText
|
|
2482
|
-
| onClose
|
|
2483
|
-
| maskClosable
|
|
2484
|
-
| getContainer
|
|
2485
|
-
| afterClose / zIndex / wrapClassName | -
|
|
2298
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
2299
|
+
| ----------------------------------- | -------------------------------------------------------- | --------- | ------------------------------------ |
|
|
2300
|
+
| type | `confirm` \| `info` \| `success` \| `warning` \| `error` | `confirm` | 调用 `modal[type]` |
|
|
2301
|
+
| title | ReactNode | - | 标题 |
|
|
2302
|
+
| message | ReactNode | - | 正文 |
|
|
2303
|
+
| danger | boolean | false | 为 true 时展示语义图标,确认钮危险色 |
|
|
2304
|
+
| confirmType | `info` \| `warning` \| `error` \| `success` | `info` | `type=confirm` 时图标语义 |
|
|
2305
|
+
| icon | ReactNode | - | 自定义图标,覆盖默认 |
|
|
2306
|
+
| onConfirm | function | - | 映射 antd `onOk` |
|
|
2307
|
+
| onCancel | function | - | 映射 antd `onCancel` |
|
|
2308
|
+
| confirmText | ReactNode | - | 映射 `okText` |
|
|
2309
|
+
| cancelText | ReactNode | - | 映射 `cancelText` |
|
|
2310
|
+
| onClose | function | - | 调用 `close()` 时触发 |
|
|
2311
|
+
| maskClosable | boolean | false | 默认不可点蒙层关闭 |
|
|
2312
|
+
| getContainer | HTMLElement \| function | - | 嵌套时挂到外层 modal 外侧 |
|
|
2313
|
+
| afterClose / zIndex / wrapClassName | - | - | 透传;默认 `zIndex` 1100 |
|
|
2486
2314
|
|
|
2487
2315
|
其余未列出参数按 antd Modal.confirm 习惯透传。
|
|
2488
2316
|
|
|
2489
2317
|
##### 返回值
|
|
2490
2318
|
|
|
2491
|
-
| 属性
|
|
2492
|
-
|
|
2319
|
+
| 属性 | 类型 | 描述 |
|
|
2320
|
+
| ------------ | -------- | ---------------------------------- |
|
|
2493
2321
|
| confirmModal | function | 调用后弹出确认框;返回 `{ close }` |
|
|
2494
2322
|
|
|
2495
2323
|
与 `useModal` 对比:专用于短文案确认 / 提示,桌面居中窄宽(约 400px),无 SimpleBar body。
|
|
@@ -2498,20 +2326,20 @@ render(
|
|
|
2498
2326
|
|
|
2499
2327
|
挂在 `.modal` / `.modal-outer` 上,可业务覆盖。
|
|
2500
2328
|
|
|
2501
|
-
| 变量
|
|
2502
|
-
|
|
2503
|
-
| `--kne-modal-viewport-height`
|
|
2504
|
-
| `--kne-modal-viewport-width`
|
|
2505
|
-
| `--kne-modal-title-height`
|
|
2506
|
-
| `--kne-modal-footer-height`
|
|
2507
|
-
| `--kne-modal-viewport-gutter`
|
|
2508
|
-
| `--kne-modal-body-padding-vertical`
|
|
2509
|
-
| `--kne-modal-body-padding-horizontal`
|
|
2510
|
-
| `--kne-modal-body-height`
|
|
2511
|
-
| `--kne-modal-content-height`
|
|
2512
|
-
| `--kne-modal-body-min-height` / `--kne-modal-body-max-height` | body 容器 min/max |
|
|
2513
|
-
| `--kne-modal-content-min-height`
|
|
2514
|
-
| `--kne-modal-content-width`
|
|
2329
|
+
| 变量 | 说明 |
|
|
2330
|
+
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
2331
|
+
| `--kne-modal-viewport-height` | 默认 `var(--kne-viewport-height, 100vh)` |
|
|
2332
|
+
| `--kne-modal-viewport-width` | 默认 `var(--kne-viewport-width, 100vw)` |
|
|
2333
|
+
| `--kne-modal-title-height` | 标题区高度贡献,默认 `48px`;无 title 为 `0` |
|
|
2334
|
+
| `--kne-modal-footer-height` | footer 高度贡献,默认 `58px`;无 footer 为 `0` |
|
|
2335
|
+
| `--kne-modal-viewport-gutter` | 桌面相对视口留白合计,默认 `80px`;移动全屏 `0` |
|
|
2336
|
+
| `--kne-modal-body-padding-vertical` | body 上下 padding 合计,默认 `48px`;`noPadding` 为 `0` |
|
|
2337
|
+
| `--kne-modal-body-padding-horizontal` | body 左右 padding 合计,默认 `48px`;`noPadding` 为 `0` |
|
|
2338
|
+
| `--kne-modal-body-height` | body **上限**高度公式(`100vh − title − footer − gutter`,**不**扣 body padding);`bodyScroll={false}` 时作为 body 实高 |
|
|
2339
|
+
| `--kne-modal-content-height` | 内容高度;默认 `body-height − padding-vertical`。`bodyScroll={false}` 时在 `.modal-body` 内覆盖为 `100%`(相对 body 实高),供内部滚动容器使用 |
|
|
2340
|
+
| `--kne-modal-body-min-height` / `--kne-modal-body-max-height` | body 容器 min/max。min 随 `size`:small 基准 300、default/large 基准 500,再扣 title/footer chrome;CSS 回退 small `252px` / 其它 `394px`。max 等于 `body-height`。桌面默认滚动:`height:auto`,不低于 min、不超过 max |
|
|
2341
|
+
| `--kne-modal-content-min-height` | content 侧 min(默认随 body-min − padding) |
|
|
2342
|
+
| `--kne-modal-content-width` | 内容宽度契约(扣 horizontal padding) |
|
|
2515
2343
|
|
|
2516
2344
|
#### 布局组合(Modal / Drawer 共用)
|
|
2517
2345
|
|
|
@@ -2536,10 +2364,10 @@ Tabs / 分栏弹层须 **`bodyScroll={false}`**,此时默认 **noPadding**(
|
|
|
2536
2364
|
|
|
2537
2365
|
##### modalClassNames
|
|
2538
2366
|
|
|
2539
|
-
| 常量
|
|
2540
|
-
|
|
2367
|
+
| 常量 | 值 | 用途 |
|
|
2368
|
+
| ----------- | ------------------------ | ---------------------------------- |
|
|
2541
2369
|
| `stepsForm` | `react-modal-steps-form` | 分步弹窗挂 `className`,去横向溢出 |
|
|
2542
|
-
| `splitter`
|
|
2370
|
+
| `splitter` | `react-modal-splitter` | antd Splitter 在弹层内的高度链 |
|
|
2543
2371
|
|
|
2544
2372
|
##### createModalRender
|
|
2545
2373
|
|
|
@@ -2551,11 +2379,11 @@ createModalRender(modalDefaults) => (hostProps) => Modal
|
|
|
2551
2379
|
|
|
2552
2380
|
推荐 `modalDefaults`:
|
|
2553
2381
|
|
|
2554
|
-
| 场景
|
|
2555
|
-
|
|
2556
|
-
| 子内容自带 Footer | `{ footerButtons: [] }`
|
|
2557
|
-
| 长内容
|
|
2558
|
-
| 分步弹窗
|
|
2382
|
+
| 场景 | modalDefaults |
|
|
2383
|
+
| ----------------- | ------------------------------------------------------------------------------------------------ |
|
|
2384
|
+
| 子内容自带 Footer | `{ footerButtons: [] }` |
|
|
2385
|
+
| 长内容 | `{ footerButtons: [], bodyScroll: true, size: 'large' }` |
|
|
2386
|
+
| 分步弹窗 | `{ footerButtons: [], bodyScroll: true, size: 'default', className: modalClassNames.stepsForm }` |
|
|
2559
2387
|
|
|
2560
2388
|
#### Drawer
|
|
2561
2389
|
|
|
@@ -2563,11 +2391,11 @@ createModalRender(modalDefaults) => (hostProps) => Modal
|
|
|
2563
2391
|
|
|
2564
2392
|
##### 属性(差异与补充)
|
|
2565
2393
|
|
|
2566
|
-
| 属性
|
|
2567
|
-
|
|
2568
|
-
| placement | `left` \| `right` \| `top` \| `bottom` | `right`
|
|
2569
|
-
| size
|
|
2570
|
-
| 移动端
|
|
2394
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
|
2395
|
+
| --------- | -------------------------------------- | --------- | ---------------------------------------------------------------- |
|
|
2396
|
+
| placement | `left` \| `right` \| `top` \| `bottom` | `right` | 滑出方向;`size` 映射 width(left/right)或 height(top/bottom) |
|
|
2397
|
+
| size | `small` \| `default` \| `large` | `default` | 600 / 1000 / min(vw−64, 1500) px |
|
|
2398
|
+
| 移动端 | - | 侧滑全宽 | left/right → 100vw;top/bottom → 100vh(非 Modal 式全屏居中) |
|
|
2571
2399
|
|
|
2572
2400
|
其余 `open` / `onClose` / `title` / `children` / `footer` / `footerButtons` / `bodyScroll` / `noPadding` / `closable` / `maskClosable` / `getContainer` 等与 Modal 相同。
|
|
2573
2401
|
|
|
@@ -2590,4 +2418,3 @@ createDrawerRender(drawerDefaults) => (hostProps) => Drawer
|
|
|
2590
2418
|
```
|
|
2591
2419
|
|
|
2592
2420
|
单参数合并渲染;宿主字段映射由 `renderModal` 回调内完成(同 `createModalRender`)。
|
|
2593
|
-
|