@nokecy/qc-ui-components 2.0.0-beta.0 → 2.0.0-beta.2
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/dist/cjs/ConfirmPro/index.d.ts +12 -9
- package/dist/cjs/ConfirmPro/index.js +11 -34
- package/dist/cjs/ag-grid-plus/ag-gridPlus.js +425 -157
- package/dist/cjs/ag-grid-plus/context/gridContext.d.ts +12 -1
- package/dist/cjs/ag-grid-plus/context/queryFormContext.d.ts +2 -0
- package/dist/cjs/ag-grid-plus/context/useSchemeDataFlow.js +8 -0
- package/dist/cjs/ag-grid-plus/density.d.ts +25 -0
- package/dist/cjs/ag-grid-plus/density.js +52 -0
- package/dist/cjs/ag-grid-plus/index.d.ts +1 -0
- package/dist/cjs/ag-grid-plus/index.js +7 -0
- package/dist/cjs/ag-grid-plus/index.less +43 -0
- package/dist/cjs/ag-grid-plus/interface.d.ts +58 -1
- package/dist/cjs/ag-grid-plus/interface.js +1 -1
- package/dist/cjs/ag-grid-plus/queryForm/index.d.ts +11 -0
- package/dist/cjs/ag-grid-plus/queryForm/index.js +62 -10
- package/dist/cjs/ag-grid-plus/queryForm/queryForm.d.ts +10 -0
- package/dist/cjs/ag-grid-plus/queryForm/queryForm.js +63 -26
- package/dist/cjs/ag-grid-plus/queryForm/queryValues.d.ts +9 -0
- package/dist/cjs/ag-grid-plus/queryForm/queryValues.js +61 -0
- package/dist/cjs/ag-grid-plus/rowColors.d.ts +12 -0
- package/dist/cjs/ag-grid-plus/rowColors.js +58 -0
- package/dist/cjs/ag-grid-plus/setting/ColumnConfigTable.d.ts +5 -0
- package/dist/cjs/ag-grid-plus/setting/ColumnConfigTable.js +14 -5
- package/dist/cjs/ag-grid-plus/setting/ColumnSetting.js +108 -76
- package/dist/cjs/ag-grid-plus/setting/QuerySchemeManager.js +10 -9
- package/dist/cjs/ag-grid-plus/setting/autoColumnMemory.d.ts +37 -0
- package/dist/cjs/ag-grid-plus/setting/autoColumnMemory.js +206 -0
- package/dist/cjs/ag-grid-plus/setting/columnGroupUtils.d.ts +2 -0
- package/dist/cjs/ag-grid-plus/setting/columnGroupUtils.js +19 -1
- package/dist/cjs/ag-grid-plus/setting/index.js +5 -14
- package/dist/cjs/ag-grid-plus/settingItem/index.d.ts +11 -1
- package/dist/cjs/ag-grid-plus/settingItem/index.js +34 -12
- package/dist/cjs/ag-grid-plus/shared/EmptyIllustration.d.ts +16 -0
- package/dist/cjs/ag-grid-plus/shared/EmptyIllustration.js +87 -0
- package/dist/cjs/ag-grid-plus/shared/NoRowsOverlay.js +9 -1
- package/dist/cjs/ag-grid-plus/shared/SkeletonOverlay.d.ts +11 -0
- package/dist/cjs/ag-grid-plus/shared/SkeletonOverlay.js +40 -0
- package/dist/cjs/ag-grid-plus/shared/storage/schemeStorageAdapter.d.ts +1 -1
- package/dist/cjs/ag-grid-plus/theme.d.ts +7 -1
- package/dist/cjs/ag-grid-plus/theme.js +31 -6
- package/dist/cjs/ag-grid-plus/toolBar/OverflowActions.d.ts +16 -0
- package/dist/cjs/ag-grid-plus/toolBar/OverflowActions.js +128 -0
- package/dist/cjs/ag-grid-plus/toolBar/index.d.ts +3 -1
- package/dist/cjs/ag-grid-plus/toolBar/index.js +43 -35
- package/dist/cjs/ag-grid-plus/toolBar/leftContent.d.ts +2 -2
- package/dist/cjs/ag-grid-plus/toolBar/leftContent.js +2 -2
- package/dist/cjs/ag-grid-plus/toolBar/overflow.d.ts +20 -0
- package/dist/cjs/ag-grid-plus/toolBar/overflow.js +48 -0
- package/dist/cjs/ag-grid-plus/toolBar/style.js +71 -15
- package/dist/cjs/ag-grid-plus/types.d.ts +6 -0
- package/dist/cjs/ag-grid-plus/utils/agGridCompat.js +12 -3
- package/dist/cjs/ag-grid-plus/utils/agGridLicenseNotice.d.ts +7 -0
- package/dist/cjs/ag-grid-plus/utils/agGridLicenseNotice.js +105 -0
- package/dist/cjs/ag-grid-plus/utils/columnProcessors.d.ts +3 -0
- package/dist/cjs/ag-grid-plus/utils/columnProcessors.js +13 -2
- package/dist/cjs/ag-grid-plus/utils/constants.d.ts +3 -2
- package/dist/cjs/ag-grid-plus/utils/constants.js +3 -2
- package/dist/cjs/ag-grid-plus/utils/crossPageSelection.d.ts +21 -0
- package/dist/cjs/ag-grid-plus/utils/crossPageSelection.js +58 -0
- package/dist/cjs/ag-grid-plus/utils/emptyState.d.ts +2 -0
- package/dist/cjs/ag-grid-plus/utils/emptyState.js +9 -5
- package/dist/cjs/ag-grid-plus/utils/listKeyboard.d.ts +24 -0
- package/dist/cjs/ag-grid-plus/utils/listKeyboard.js +83 -0
- package/dist/cjs/ag-grid-plus/utils/pagination.d.ts +26 -0
- package/dist/cjs/ag-grid-plus/utils/pagination.js +69 -0
- package/dist/cjs/ag-grid-plus/utils/queryDispatch.d.ts +7 -0
- package/dist/cjs/ag-grid-plus/utils/queryDispatch.js +17 -0
- package/dist/cjs/ag-grid-plus/utils/statusPill.d.ts +25 -0
- package/dist/cjs/ag-grid-plus/utils/statusPill.js +196 -0
- package/dist/cjs/ag-grid-plus/utils/valueEnumColor.d.ts +6 -1
- package/dist/cjs/ag-grid-plus/utils/valueEnumColor.js +13 -9
- package/dist/cjs/ag-grid-plus/utils/valueFormat.d.ts +19 -0
- package/dist/cjs/ag-grid-plus/utils/valueFormat.js +73 -0
- package/dist/cjs/ag-grid-plus/utils.js +3 -2
- package/dist/cjs/array-table/arrayAddBtn.d.ts +1 -0
- package/dist/cjs/array-table/arrayAddBtn.js +2 -2
- package/dist/cjs/array-table/autoHeight.d.ts +18 -0
- package/dist/cjs/array-table/autoHeight.js +30 -0
- package/dist/cjs/array-table/batchRemove.d.ts +2 -2
- package/dist/cjs/array-table/cellEditorMarker.d.ts +18 -0
- package/dist/cjs/array-table/cellEditorMarker.js +92 -0
- package/dist/cjs/array-table/errorLocator.d.ts +29 -0
- package/dist/cjs/array-table/errorLocator.js +101 -0
- package/dist/cjs/array-table/hooks.d.ts +52 -4
- package/dist/cjs/array-table/hooks.js +251 -18
- package/dist/cjs/array-table/index.d.ts +6 -0
- package/dist/cjs/array-table/index.js +167 -23
- package/dist/cjs/array-table/interface.d.ts +22 -0
- package/dist/cjs/array-table/preview.js +39 -5
- package/dist/cjs/array-table/rowFeedback.d.ts +2 -2
- package/dist/cjs/array-table/rowFeedback.js +8 -8
- package/dist/cjs/array-table/summary.d.ts +25 -0
- package/dist/cjs/array-table/summary.js +70 -0
- package/dist/cjs/array-table/theme.d.ts +35 -5
- package/dist/cjs/array-table/theme.js +49 -12
- package/dist/cjs/array-table/title.d.ts +3 -0
- package/dist/cjs/array-table/title.js +29 -0
- package/dist/cjs/array-table/utils.d.ts +2 -1
- package/dist/cjs/array-table/utils.js +94 -23
- package/dist/cjs/card/pro-card/Card/useLegacyItems.d.ts +1 -1
- package/dist/cjs/dateCellEditor/DateCellEditor.d.ts +5 -0
- package/dist/cjs/dateCellEditor/DateCellEditor.js +42 -17
- package/dist/cjs/deleteConfirm/index.d.ts +14 -0
- package/dist/cjs/deleteConfirm/index.js +73 -12
- package/dist/cjs/dialogSelect/index.d.ts +19 -0
- package/dist/cjs/dialogSelect/index.js +189 -15
- package/dist/cjs/dialogSelect/index.less +18 -0
- package/dist/cjs/documentPage/documentPage.d.ts +6 -3
- package/dist/cjs/documentPage/documentPage.js +23 -8
- package/dist/cjs/documentPage/index.d.ts +2 -0
- package/dist/cjs/documentPage/index.js +19 -0
- package/dist/cjs/documentPage/leaveGuard.d.ts +31 -0
- package/dist/cjs/documentPage/leaveGuard.js +91 -0
- package/dist/cjs/draggableModal/index.d.ts +24 -1
- package/dist/cjs/draggableModal/index.js +36 -6
- package/dist/cjs/fullScreenAlert/index.less +10 -10
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +22 -0
- package/dist/cjs/readPretty/arrayTable.js +5 -1
- package/dist/cjs/scanCollect/ScanFeedbackInput.d.ts +26 -0
- package/dist/cjs/scanCollect/ScanFeedbackInput.js +113 -0
- package/dist/cjs/scanCollect/index.d.ts +4 -0
- package/dist/cjs/scanCollect/index.js +14 -0
- package/dist/cjs/scanCollect/scanSound.d.ts +15 -0
- package/dist/cjs/scanCollect/scanSound.js +91 -0
- package/dist/esm/ConfirmPro/index.d.ts +12 -9
- package/dist/esm/ConfirmPro/index.js +11 -34
- package/dist/esm/ag-grid-plus/ag-gridPlus.js +426 -157
- package/dist/esm/ag-grid-plus/context/gridContext.d.ts +12 -1
- package/dist/esm/ag-grid-plus/context/queryFormContext.d.ts +2 -0
- package/dist/esm/ag-grid-plus/context/useSchemeDataFlow.js +8 -0
- package/dist/esm/ag-grid-plus/density.d.ts +25 -0
- package/dist/esm/ag-grid-plus/density.js +45 -0
- package/dist/esm/ag-grid-plus/index.d.ts +1 -0
- package/dist/esm/ag-grid-plus/index.js +3 -0
- package/dist/esm/ag-grid-plus/index.less +43 -0
- package/dist/esm/ag-grid-plus/interface.d.ts +58 -1
- package/dist/esm/ag-grid-plus/interface.js +2 -0
- package/dist/esm/ag-grid-plus/queryForm/index.d.ts +11 -0
- package/dist/esm/ag-grid-plus/queryForm/index.js +62 -10
- package/dist/esm/ag-grid-plus/queryForm/queryForm.d.ts +10 -0
- package/dist/esm/ag-grid-plus/queryForm/queryForm.js +64 -26
- package/dist/esm/ag-grid-plus/queryForm/queryValues.d.ts +9 -0
- package/dist/esm/ag-grid-plus/queryForm/queryValues.js +54 -0
- package/dist/esm/ag-grid-plus/rowColors.d.ts +12 -0
- package/dist/esm/ag-grid-plus/rowColors.js +50 -0
- package/dist/esm/ag-grid-plus/setting/ColumnConfigTable.d.ts +5 -0
- package/dist/esm/ag-grid-plus/setting/ColumnConfigTable.js +14 -5
- package/dist/esm/ag-grid-plus/setting/ColumnSetting.js +110 -78
- package/dist/esm/ag-grid-plus/setting/QuerySchemeManager.js +10 -9
- package/dist/esm/ag-grid-plus/setting/autoColumnMemory.d.ts +37 -0
- package/dist/esm/ag-grid-plus/setting/autoColumnMemory.js +198 -0
- package/dist/esm/ag-grid-plus/setting/columnGroupUtils.d.ts +2 -0
- package/dist/esm/ag-grid-plus/setting/columnGroupUtils.js +18 -1
- package/dist/esm/ag-grid-plus/setting/index.js +6 -15
- package/dist/esm/ag-grid-plus/settingItem/index.d.ts +11 -1
- package/dist/esm/ag-grid-plus/settingItem/index.js +35 -13
- package/dist/esm/ag-grid-plus/shared/EmptyIllustration.d.ts +16 -0
- package/dist/esm/ag-grid-plus/shared/EmptyIllustration.js +82 -0
- package/dist/esm/ag-grid-plus/shared/NoRowsOverlay.js +9 -1
- package/dist/esm/ag-grid-plus/shared/SkeletonOverlay.d.ts +11 -0
- package/dist/esm/ag-grid-plus/shared/SkeletonOverlay.js +34 -0
- package/dist/esm/ag-grid-plus/shared/storage/schemeStorageAdapter.d.ts +1 -1
- package/dist/esm/ag-grid-plus/theme.d.ts +7 -1
- package/dist/esm/ag-grid-plus/theme.js +31 -6
- package/dist/esm/ag-grid-plus/toolBar/OverflowActions.d.ts +16 -0
- package/dist/esm/ag-grid-plus/toolBar/OverflowActions.js +120 -0
- package/dist/esm/ag-grid-plus/toolBar/index.d.ts +3 -1
- package/dist/esm/ag-grid-plus/toolBar/index.js +43 -35
- package/dist/esm/ag-grid-plus/toolBar/leftContent.d.ts +2 -2
- package/dist/esm/ag-grid-plus/toolBar/leftContent.js +2 -2
- package/dist/esm/ag-grid-plus/toolBar/overflow.d.ts +20 -0
- package/dist/esm/ag-grid-plus/toolBar/overflow.js +41 -0
- package/dist/esm/ag-grid-plus/toolBar/style.js +71 -15
- package/dist/esm/ag-grid-plus/types.d.ts +6 -0
- package/dist/esm/ag-grid-plus/utils/agGridCompat.js +12 -3
- package/dist/esm/ag-grid-plus/utils/agGridLicenseNotice.d.ts +7 -0
- package/dist/esm/ag-grid-plus/utils/agGridLicenseNotice.js +97 -0
- package/dist/esm/ag-grid-plus/utils/columnProcessors.d.ts +3 -0
- package/dist/esm/ag-grid-plus/utils/columnProcessors.js +14 -3
- package/dist/esm/ag-grid-plus/utils/constants.d.ts +3 -2
- package/dist/esm/ag-grid-plus/utils/constants.js +3 -2
- package/dist/esm/ag-grid-plus/utils/crossPageSelection.d.ts +21 -0
- package/dist/esm/ag-grid-plus/utils/crossPageSelection.js +52 -0
- package/dist/esm/ag-grid-plus/utils/emptyState.d.ts +2 -0
- package/dist/esm/ag-grid-plus/utils/emptyState.js +9 -5
- package/dist/esm/ag-grid-plus/utils/listKeyboard.d.ts +24 -0
- package/dist/esm/ag-grid-plus/utils/listKeyboard.js +77 -0
- package/dist/esm/ag-grid-plus/utils/pagination.d.ts +26 -0
- package/dist/esm/ag-grid-plus/utils/pagination.js +60 -0
- package/dist/esm/ag-grid-plus/utils/queryDispatch.d.ts +7 -0
- package/dist/esm/ag-grid-plus/utils/queryDispatch.js +11 -0
- package/dist/esm/ag-grid-plus/utils/statusPill.d.ts +25 -0
- package/dist/esm/ag-grid-plus/utils/statusPill.js +192 -0
- package/dist/esm/ag-grid-plus/utils/valueEnumColor.d.ts +6 -1
- package/dist/esm/ag-grid-plus/utils/valueEnumColor.js +12 -8
- package/dist/esm/ag-grid-plus/utils/valueFormat.d.ts +19 -0
- package/dist/esm/ag-grid-plus/utils/valueFormat.js +63 -0
- package/dist/esm/ag-grid-plus/utils.js +3 -2
- package/dist/esm/array-table/arrayAddBtn.d.ts +1 -0
- package/dist/esm/array-table/arrayAddBtn.js +1 -1
- package/dist/esm/array-table/autoHeight.d.ts +18 -0
- package/dist/esm/array-table/autoHeight.js +25 -0
- package/dist/esm/array-table/batchRemove.d.ts +2 -2
- package/dist/esm/array-table/cellEditorMarker.d.ts +18 -0
- package/dist/esm/array-table/cellEditorMarker.js +84 -0
- package/dist/esm/array-table/errorLocator.d.ts +29 -0
- package/dist/esm/array-table/errorLocator.js +95 -0
- package/dist/esm/array-table/hooks.d.ts +52 -4
- package/dist/esm/array-table/hooks.js +251 -17
- package/dist/esm/array-table/index.d.ts +6 -0
- package/dist/esm/array-table/index.js +170 -25
- package/dist/esm/array-table/interface.d.ts +22 -0
- package/dist/esm/array-table/preview.js +43 -7
- package/dist/esm/array-table/rowFeedback.d.ts +2 -2
- package/dist/esm/array-table/rowFeedback.js +8 -8
- package/dist/esm/array-table/summary.d.ts +25 -0
- package/dist/esm/array-table/summary.js +66 -0
- package/dist/esm/array-table/theme.d.ts +35 -5
- package/dist/esm/array-table/theme.js +47 -12
- package/dist/esm/array-table/title.d.ts +3 -0
- package/dist/esm/array-table/title.js +24 -0
- package/dist/esm/array-table/utils.d.ts +2 -1
- package/dist/esm/array-table/utils.js +93 -22
- package/dist/esm/card/pro-card/Card/useLegacyItems.d.ts +1 -1
- package/dist/esm/dateCellEditor/DateCellEditor.d.ts +5 -0
- package/dist/esm/dateCellEditor/DateCellEditor.js +42 -17
- package/dist/esm/deleteConfirm/index.d.ts +14 -0
- package/dist/esm/deleteConfirm/index.js +72 -12
- package/dist/esm/dialogSelect/index.d.ts +19 -0
- package/dist/esm/dialogSelect/index.js +190 -16
- package/dist/esm/dialogSelect/index.less +18 -0
- package/dist/esm/documentPage/documentPage.d.ts +6 -3
- package/dist/esm/documentPage/documentPage.js +23 -8
- package/dist/esm/documentPage/index.d.ts +2 -0
- package/dist/esm/documentPage/index.js +1 -0
- package/dist/esm/documentPage/leaveGuard.d.ts +31 -0
- package/dist/esm/documentPage/leaveGuard.js +86 -0
- package/dist/esm/draggableModal/index.d.ts +24 -1
- package/dist/esm/draggableModal/index.js +35 -5
- package/dist/esm/fullScreenAlert/index.less +10 -10
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/readPretty/arrayTable.js +6 -2
- package/dist/esm/scanCollect/ScanFeedbackInput.d.ts +26 -0
- package/dist/esm/scanCollect/ScanFeedbackInput.js +107 -0
- package/dist/esm/scanCollect/index.d.ts +4 -0
- package/dist/esm/scanCollect/index.js +2 -0
- package/dist/esm/scanCollect/scanSound.d.ts +15 -0
- package/dist/esm/scanCollect/scanSound.js +84 -0
- package/package.json +2 -2
|
@@ -10,6 +10,7 @@ export { DisabledActionHint } from "./DisabledActionHint";
|
|
|
10
10
|
export { DocumentHeader, DocumentStatusBar } from "./DocumentHeader";
|
|
11
11
|
export { formatDocumentTime, latestDocumentAuditStep, normalizeDocumentAuditSteps } from "./documentAudit";
|
|
12
12
|
export { confirmDocumentAction, formatValidationFeedback, pickPrimaryAction, reloadAfterAction, submitButtonLabel, useDocumentActions, useDocumentEditState, validateBeforeConfirm, warnSavedButActionFailed } from "./documentPage";
|
|
13
|
+
export { LEAVE_GUARD_TEXT, confirmDiscardChanges, useLeaveGuard } from "./leaveGuard";
|
|
13
14
|
export { useHeaderItemToggleGrid } from "./useHeaderItemToggleGrid";
|
|
14
15
|
export { createHeaderItemGetRowId, getHeaderItemRowId } from "./headerItemRowId";
|
|
15
16
|
export { useSelectNumberInputOnFocus } from "./useSelectNumberInputOnFocus";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** 离开守卫的统一文案(DESIGN.md §6.8)。 */
|
|
2
|
+
export declare const LEAVE_GUARD_TEXT: {
|
|
3
|
+
readonly title: "有未保存的修改,离开后将丢失";
|
|
4
|
+
readonly keepEditing: "继续编辑";
|
|
5
|
+
readonly discard: "放弃修改";
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* 弹出「继续编辑 / 放弃修改」确认。放弃修改返回 true;继续编辑、Esc 返回 false。
|
|
9
|
+
* 默认焦点在「继续编辑」(§6.8),确认框宽 560(§9.0)。
|
|
10
|
+
*/
|
|
11
|
+
export declare const confirmDiscardChanges: () => Promise<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* 路由拦截适配器:qc-ui 不绑定路由库,由宿主把自己的路由拦截接进来。
|
|
14
|
+
* 宿主在导航发生时若 `shouldBlock()` 为真,就阻止并调用 `confirmLeave()`,得到 true 再放行。
|
|
15
|
+
* 返回取消拦截的函数。例(umi / react-router 的 history.block 一类):
|
|
16
|
+
* `(shouldBlock, confirmLeave) => history.block(tx => { if (!shouldBlock()) return; confirmLeave().then(ok => ok && (unblock(), tx.retry())); return false; })`
|
|
17
|
+
*/
|
|
18
|
+
export type RouteBlocker = (shouldBlock: () => boolean, confirmLeave: () => Promise<boolean>) => (() => void) | void;
|
|
19
|
+
export interface LeaveGuardOptions {
|
|
20
|
+
/** 浏览器刷新 / 关闭标签页时拦截,默认 true。 */
|
|
21
|
+
beforeUnload?: boolean;
|
|
22
|
+
/** 宿主的路由拦截适配器;不传则只守卫刷新 / 关闭与 `guardDiscard`。 */
|
|
23
|
+
blockRoute?: RouteBlocker;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 离开守卫统一入口:未保存时拦截 刷新 / 关闭标签页(beforeunload)与路由切换(经宿主适配器),
|
|
27
|
+
* 文案与按钮统一。切换页签(页面仍被缓存)不算离开,不在这里拦截(§6.8)。
|
|
28
|
+
*/
|
|
29
|
+
export declare const useLeaveGuard: (dirty: boolean, options?: LeaveGuardOptions) => {
|
|
30
|
+
guardDiscard: (proceed: () => void) => void;
|
|
31
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Modal } from 'antd';
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
/** 离开守卫的统一文案(DESIGN.md §6.8)。 */
|
|
5
|
+
export var LEAVE_GUARD_TEXT = {
|
|
6
|
+
title: '有未保存的修改,离开后将丢失',
|
|
7
|
+
keepEditing: '继续编辑',
|
|
8
|
+
discard: '放弃修改'
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 弹出「继续编辑 / 放弃修改」确认。放弃修改返回 true;继续编辑、Esc 返回 false。
|
|
13
|
+
* 默认焦点在「继续编辑」(§6.8),确认框宽 560(§9.0)。
|
|
14
|
+
*/
|
|
15
|
+
export var confirmDiscardChanges = function confirmDiscardChanges() {
|
|
16
|
+
return new Promise(function (resolve) {
|
|
17
|
+
Modal.confirm({
|
|
18
|
+
title: LEAVE_GUARD_TEXT.title,
|
|
19
|
+
okText: LEAVE_GUARD_TEXT.discard,
|
|
20
|
+
cancelText: LEAVE_GUARD_TEXT.keepEditing,
|
|
21
|
+
okButtonProps: {
|
|
22
|
+
danger: true
|
|
23
|
+
},
|
|
24
|
+
focusable: {
|
|
25
|
+
autoFocusButton: 'cancel'
|
|
26
|
+
},
|
|
27
|
+
width: 560,
|
|
28
|
+
onOk: function onOk() {
|
|
29
|
+
return resolve(true);
|
|
30
|
+
},
|
|
31
|
+
onCancel: function onCancel() {
|
|
32
|
+
return resolve(false);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 路由拦截适配器:qc-ui 不绑定路由库,由宿主把自己的路由拦截接进来。
|
|
40
|
+
* 宿主在导航发生时若 `shouldBlock()` 为真,就阻止并调用 `confirmLeave()`,得到 true 再放行。
|
|
41
|
+
* 返回取消拦截的函数。例(umi / react-router 的 history.block 一类):
|
|
42
|
+
* `(shouldBlock, confirmLeave) => history.block(tx => { if (!shouldBlock()) return; confirmLeave().then(ok => ok && (unblock(), tx.retry())); return false; })`
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 离开守卫统一入口:未保存时拦截 刷新 / 关闭标签页(beforeunload)与路由切换(经宿主适配器),
|
|
47
|
+
* 文案与按钮统一。切换页签(页面仍被缓存)不算离开,不在这里拦截(§6.8)。
|
|
48
|
+
*/
|
|
49
|
+
export var useLeaveGuard = function useLeaveGuard(dirty) {
|
|
50
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
51
|
+
var _options$beforeUnload = options.beforeUnload,
|
|
52
|
+
beforeUnload = _options$beforeUnload === void 0 ? true : _options$beforeUnload,
|
|
53
|
+
blockRoute = options.blockRoute;
|
|
54
|
+
var dirtyRef = useRef(dirty);
|
|
55
|
+
dirtyRef.current = dirty;
|
|
56
|
+
useEffect(function () {
|
|
57
|
+
if (!beforeUnload || !dirty) return;
|
|
58
|
+
var handler = function handler(event) {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
// 部分浏览器要求设置 returnValue 才弹出原生提示。
|
|
61
|
+
event.returnValue = '';
|
|
62
|
+
};
|
|
63
|
+
window.addEventListener('beforeunload', handler);
|
|
64
|
+
return function () {
|
|
65
|
+
return window.removeEventListener('beforeunload', handler);
|
|
66
|
+
};
|
|
67
|
+
}, [beforeUnload, dirty]);
|
|
68
|
+
useEffect(function () {
|
|
69
|
+
if (!blockRoute) return;
|
|
70
|
+
var release = blockRoute(function () {
|
|
71
|
+
return dirtyRef.current;
|
|
72
|
+
}, confirmDiscardChanges);
|
|
73
|
+
return typeof release === 'function' ? release : undefined;
|
|
74
|
+
}, [blockRoute]);
|
|
75
|
+
|
|
76
|
+
/** 返回、刷新等会丢弃录入的动作:有未保存修改先确认,放弃后才执行 `proceed`。 */
|
|
77
|
+
var guardDiscard = function guardDiscard(proceed) {
|
|
78
|
+
if (!dirtyRef.current) return proceed();
|
|
79
|
+
void confirmDiscardChanges().then(function (ok) {
|
|
80
|
+
return ok && proceed();
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
guardDiscard: guardDiscard
|
|
85
|
+
};
|
|
86
|
+
};
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
import type { ModalProps } from 'antd';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import './style.less';
|
|
4
|
-
|
|
4
|
+
/** 默认宽度取弹层三档(560 / 720 / 960)中的最小档,原先是 antd 默认的 520。@author nokecy */
|
|
5
|
+
export declare const DRAGGABLE_MODAL_DEFAULT_WIDTH = 560;
|
|
6
|
+
export interface DraggableModalProps extends ModalProps {
|
|
7
|
+
/**
|
|
8
|
+
* 弹窗内有未保存修改。传 boolean,或传函数在每次关闭时取最新值(如 `() => form.modified`)。
|
|
9
|
+
* 不传视为没有可丢失的录入,关闭不拦截,所以既有调用方行为不变。
|
|
10
|
+
*/
|
|
11
|
+
dirty?: boolean | (() => boolean);
|
|
12
|
+
/**
|
|
13
|
+
* 有未保存修改(`dirty` 为真)时,右上角叉、遮罩、Esc、取消按钮先弹「继续编辑 / 放弃修改」确认,
|
|
14
|
+
* 默认 true(DESIGN.md §6.6)。选「放弃修改」才调用 onCancel,选「继续编辑」保持打开。
|
|
15
|
+
*/
|
|
16
|
+
confirmOnDirtyClose?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* 是否显示八方向缩放手柄,默认 true(既有调用方一直可缩放,保持不变)。
|
|
19
|
+
* 关闭后只保留标题拖动,尺寸完全由 width / style 决定。缩放结果不持久化,重新打开恢复默认。
|
|
20
|
+
*/
|
|
21
|
+
resizable?: boolean;
|
|
22
|
+
/** 缩放的最小宽度,默认 400;表单类弹层应传 560(规范最小一档)。超出视口 95% 时以视口为准。 */
|
|
23
|
+
minWidth?: number;
|
|
24
|
+
/** 缩放的最小高度,默认 300:容纳标题、底栏与至少一行内容。 */
|
|
25
|
+
minHeight?: number;
|
|
26
|
+
}
|
|
27
|
+
declare const _default: ((props: DraggableModalProps) => React.JSX.Element) & {
|
|
5
28
|
Fill: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
6
29
|
};
|
|
7
30
|
export default _default;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var _excluded = ["wrapClassName", "width", "open", "style", "destroyOnClose", "destroyOnHidden", "mask", "maskClosable"];
|
|
1
|
+
var _excluded = ["wrapClassName", "width", "open", "style", "destroyOnClose", "destroyOnHidden", "mask", "maskClosable", "dirty", "confirmOnDirtyClose", "onCancel", "resizable", "minWidth", "minHeight"];
|
|
2
2
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
3
3
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
4
4
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
@@ -16,6 +16,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
16
16
|
import { Modal } from 'antd';
|
|
17
17
|
import React, { useRef, useState, useEffect } from 'react';
|
|
18
18
|
import Draggable from 'react-draggable';
|
|
19
|
+
import { confirmDiscardChanges } from "../documentPage/leaveGuard";
|
|
19
20
|
import "./style.less";
|
|
20
21
|
|
|
21
22
|
/** 弹窗中随边框缩放的内容区;初始高度由调用方提供,缩放后占用剩余空间。@author nokecy */
|
|
@@ -28,6 +29,8 @@ var Fill = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
28
29
|
}));
|
|
29
30
|
});
|
|
30
31
|
|
|
32
|
+
/** 默认宽度取弹层三档(560 / 720 / 960)中的最小档,原先是 antd 默认的 520。@author nokecy */
|
|
33
|
+
export var DRAGGABLE_MODAL_DEFAULT_WIDTH = 560;
|
|
31
34
|
/** 支持标题拖动、八方向缩放及自适应内容区的公共弹窗。@author nokecy */
|
|
32
35
|
var DraggableModal = function DraggableModal(props) {
|
|
33
36
|
var _geometry$width;
|
|
@@ -64,7 +67,8 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
64
67
|
var resizeFrame = useRef(undefined);
|
|
65
68
|
// antd 6 以 destroyOnHidden、mask.closable 取代 destroyOnClose、maskClosable;旧属性仍按原默认值生效。@author nokecy
|
|
66
69
|
var wrapClassName = props.wrapClassName,
|
|
67
|
-
width = props.width,
|
|
70
|
+
_props$width = props.width,
|
|
71
|
+
width = _props$width === void 0 ? DRAGGABLE_MODAL_DEFAULT_WIDTH : _props$width,
|
|
68
72
|
open = props.open,
|
|
69
73
|
style = props.style,
|
|
70
74
|
destroyOnClose = props.destroyOnClose,
|
|
@@ -72,7 +76,30 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
72
76
|
destroyOnHidden = _props$destroyOnHidde === void 0 ? destroyOnClose !== null && destroyOnClose !== void 0 ? destroyOnClose : true : _props$destroyOnHidde,
|
|
73
77
|
mask = props.mask,
|
|
74
78
|
maskClosable = props.maskClosable,
|
|
79
|
+
dirty = props.dirty,
|
|
80
|
+
_props$confirmOnDirty = props.confirmOnDirtyClose,
|
|
81
|
+
confirmOnDirtyClose = _props$confirmOnDirty === void 0 ? true : _props$confirmOnDirty,
|
|
82
|
+
onCancel = props.onCancel,
|
|
83
|
+
_props$resizable = props.resizable,
|
|
84
|
+
resizable = _props$resizable === void 0 ? true : _props$resizable,
|
|
85
|
+
_props$minWidth = props.minWidth,
|
|
86
|
+
minWidth = _props$minWidth === void 0 ? 400 : _props$minWidth,
|
|
87
|
+
_props$minHeight = props.minHeight,
|
|
88
|
+
minHeight = _props$minHeight === void 0 ? 300 : _props$minHeight,
|
|
75
89
|
restProps = _objectWithoutProperties(props, _excluded);
|
|
90
|
+
// 确认期间挡住重复触发(连按 Esc 不叠出多个确认框)。
|
|
91
|
+
var confirmingRef = useRef(false);
|
|
92
|
+
var handleCancel = function handleCancel(event) {
|
|
93
|
+
var isDirty = typeof dirty === 'function' ? dirty() : !!dirty;
|
|
94
|
+
if (!confirmOnDirtyClose || !isDirty) return onCancel === null || onCancel === void 0 ? void 0 : onCancel(event);
|
|
95
|
+
if (confirmingRef.current) return;
|
|
96
|
+
confirmingRef.current = true;
|
|
97
|
+
void confirmDiscardChanges().then(function (ok) {
|
|
98
|
+
if (ok) onCancel === null || onCancel === void 0 || onCancel(event);
|
|
99
|
+
}).finally(function () {
|
|
100
|
+
confirmingRef.current = false;
|
|
101
|
+
});
|
|
102
|
+
};
|
|
76
103
|
var mergedMask = typeof mask === 'boolean' ? {
|
|
77
104
|
enabled: mask,
|
|
78
105
|
closable: maskClosable !== null && maskClosable !== void 0 ? maskClosable : false
|
|
@@ -131,6 +158,7 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
131
158
|
var _resizeCleanup$curren2;
|
|
132
159
|
event.preventDefault();
|
|
133
160
|
event.stopPropagation();
|
|
161
|
+
if (!resizable) return;
|
|
134
162
|
var panel = draggleRef.current;
|
|
135
163
|
var modal = panel === null || panel === void 0 ? void 0 : panel.closest('.ant-modal');
|
|
136
164
|
if (!panel || !modal) return;
|
|
@@ -157,8 +185,9 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
157
185
|
var nextWidth = start.width + (direction.includes('e') ? dx : direction.includes('w') ? -dx : 0);
|
|
158
186
|
var nextHeight = start.height + (direction.includes('s') ? dy : direction.includes('n') ? -dy : 0);
|
|
159
187
|
var next = {
|
|
160
|
-
|
|
161
|
-
|
|
188
|
+
// 上限(视口 95%)优先于下限,小屏上不会出现比视口还大的最小尺寸。
|
|
189
|
+
width: Math.min(Math.max(minWidth, nextWidth), window.innerWidth * 0.95),
|
|
190
|
+
height: Math.min(Math.max(minHeight, nextHeight), window.innerHeight * 0.95),
|
|
162
191
|
left: start.left,
|
|
163
192
|
top: start.top
|
|
164
193
|
};
|
|
@@ -193,6 +222,7 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
193
222
|
destroyOnHidden: destroyOnHidden
|
|
194
223
|
}, restProps), {}, {
|
|
195
224
|
open: open,
|
|
225
|
+
onCancel: handleCancel,
|
|
196
226
|
width: (_geometry$width = geometry === null || geometry === void 0 ? void 0 : geometry.width) !== null && _geometry$width !== void 0 ? _geometry$width : width,
|
|
197
227
|
style: geometry ? _objectSpread(_objectSpread(_objectSpread({}, style), geometry), {}, {
|
|
198
228
|
position: 'fixed',
|
|
@@ -236,7 +266,7 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
236
266
|
height: geometry ? '100%' : undefined,
|
|
237
267
|
width: '100%'
|
|
238
268
|
},
|
|
239
|
-
children: [modal, ['e', 's', 'w', 'n', 'se', 'sw', 'ne', 'nw'].map(function (direction) {
|
|
269
|
+
children: [modal, resizable && ['e', 's', 'w', 'n', 'se', 'sw', 'ne', 'nw'].map(function (direction) {
|
|
240
270
|
return /*#__PURE__*/_jsx("div", {
|
|
241
271
|
className: "resize-handle resize-handle-".concat(direction),
|
|
242
272
|
onMouseDown: function onMouseDown(event) {
|
|
@@ -21,28 +21,28 @@
|
|
|
21
21
|
.successOverlay::before {
|
|
22
22
|
top: 0;
|
|
23
23
|
left: 0;
|
|
24
|
-
background: linear-gradient(to right, green, transparent);
|
|
24
|
+
background: linear-gradient(to right, var(--ant-color-success, green), transparent);
|
|
25
25
|
transform: rotate(0deg);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
.successOverlay::after {
|
|
29
29
|
top: 0%;
|
|
30
30
|
left: 100%;
|
|
31
|
-
background: linear-gradient(to left, green, transparent);
|
|
31
|
+
background: linear-gradient(to left, var(--ant-color-success, green), transparent);
|
|
32
32
|
transform: rotate(0deg) translate(calc(-1 * var(--alert-size)), 0px);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
.successOverlay > div::before {
|
|
36
36
|
top: 0;
|
|
37
37
|
left: 0;
|
|
38
|
-
background: linear-gradient(to top, green, transparent);
|
|
38
|
+
background: linear-gradient(to top, var(--ant-color-success, green), transparent);
|
|
39
39
|
transform: rotate(180deg);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
.successOverlay > div::after {
|
|
43
43
|
top: 100%;
|
|
44
44
|
left: 0;
|
|
45
|
-
background: linear-gradient(to top, green, transparent);
|
|
45
|
+
background: linear-gradient(to top, var(--ant-color-success, green), transparent);
|
|
46
46
|
transform: rotate(0deg) translate(0px, calc(-1 * var(--alert-size)));
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -78,28 +78,28 @@
|
|
|
78
78
|
.errorOverlay::before {
|
|
79
79
|
top: 0;
|
|
80
80
|
left: 0;
|
|
81
|
-
background: linear-gradient(to right, red, transparent);
|
|
81
|
+
background: linear-gradient(to right, var(--ant-color-error, red), transparent);
|
|
82
82
|
transform: rotate(0deg);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
.errorOverlay::after {
|
|
86
86
|
top: 0%;
|
|
87
87
|
left: 100%;
|
|
88
|
-
background: linear-gradient(to left, red, transparent);
|
|
88
|
+
background: linear-gradient(to left, var(--ant-color-error, red), transparent);
|
|
89
89
|
transform: rotate(0deg) translate(calc(-1 * var(--alert-size)), 0px);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
.errorOverlay > div::before {
|
|
93
93
|
top: 0;
|
|
94
94
|
left: 0;
|
|
95
|
-
background: linear-gradient(to top, red, transparent);
|
|
95
|
+
background: linear-gradient(to top, var(--ant-color-error, red), transparent);
|
|
96
96
|
transform: rotate(180deg);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
.errorOverlay > div::after {
|
|
100
100
|
top: 100%;
|
|
101
101
|
left: 0;
|
|
102
|
-
background: linear-gradient(to top, red, transparent);
|
|
102
|
+
background: linear-gradient(to top, var(--ant-color-error, red), transparent);
|
|
103
103
|
transform: rotate(0deg) translate(0px, calc(-1 * var(--alert-size)));
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -156,9 +156,9 @@
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
.alertBadge-success {
|
|
159
|
-
color: green;
|
|
159
|
+
color: var(--ant-color-success, green);
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
.alertBadge-error {
|
|
163
|
-
color: red;
|
|
163
|
+
color: var(--ant-color-error, red);
|
|
164
164
|
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -37,7 +37,10 @@ export * from "./scanCollect/index";
|
|
|
37
37
|
export * from "./documentPage/index";
|
|
38
38
|
export { semanticTextColors, toGridTextColor, gridValueEnum } from "./ag-grid-plus/utils/valueEnumColor";
|
|
39
39
|
export type { SemanticPreset } from "./ag-grid-plus/utils/valueEnumColor";
|
|
40
|
+
export { StatusPill, STATUS_PILL } from "./ag-grid-plus/utils/statusPill";
|
|
41
|
+
export type { StatusKey } from "./ag-grid-plus/utils/statusPill";
|
|
40
42
|
export { getQcColDefProp } from "./ag-grid-plus/utils/agGridCompat";
|
|
43
|
+
export { setAgGridLicenseKey } from "./ag-grid-plus/index";
|
|
41
44
|
export { contrastRatio, relativeLuminance, darkenUntilContrast, lightenUntilContrast, toRgb, toHsl, fromHsl } from "./shared/contrast";
|
|
42
45
|
export { BusinessDecimal, decimal, decimalText, nonNegativeDecimal, roundDecimal, sumDecimals, formatDecimal } from "./shared/businessDecimal";
|
|
43
46
|
export type { DecimalValue } from "./shared/businessDecimal";
|
package/dist/esm/index.js
CHANGED
|
@@ -34,7 +34,9 @@ export { GridPlusError, ErrorType, ErrorSeverity } from "./ag-grid-plus/errors/i
|
|
|
34
34
|
export * from "./scanCollect/index";
|
|
35
35
|
export * from "./documentPage/index";
|
|
36
36
|
export { semanticTextColors, toGridTextColor, gridValueEnum } from "./ag-grid-plus/utils/valueEnumColor";
|
|
37
|
+
export { StatusPill, STATUS_PILL } from "./ag-grid-plus/utils/statusPill";
|
|
37
38
|
export { getQcColDefProp } from "./ag-grid-plus/utils/agGridCompat";
|
|
39
|
+
export { setAgGridLicenseKey } from "./ag-grid-plus/index";
|
|
38
40
|
export { contrastRatio, relativeLuminance, darkenUntilContrast, lightenUntilContrast, toRgb, toHsl, fromHsl } from "./shared/contrast";
|
|
39
41
|
export { BusinessDecimal, decimal, decimalText, nonNegativeDecimal, roundDecimal, sumDecimals, formatDecimal } from "./shared/businessDecimal";
|
|
40
42
|
export * from "./formily/index";
|
|
@@ -12,7 +12,7 @@ import { AgGridReact } from 'ag-grid-react';
|
|
|
12
12
|
import { buildArrayTableColumns, useArrayTableSources } from "../array-table/utils";
|
|
13
13
|
import { groupColumnDefs } from "../array-table/columnGroup";
|
|
14
14
|
import { ARRAY_TABLE_INDEX_FIELD, hasOwnIndexColumn, makeIndexColumn } from "../array-table/indexColumn";
|
|
15
|
-
import {
|
|
15
|
+
import { useArrayTableMetrics, useArrayTableTheme } from "../array-table/theme";
|
|
16
16
|
import { hoistStatics } from "./hoistStatics";
|
|
17
17
|
import React, { useMemo, useRef } from 'react';
|
|
18
18
|
import { installDisplaySequenceOrder } from "../shared/gridSequence";
|
|
@@ -43,13 +43,17 @@ var ReadingArrayTable = observer(function (_ref) {
|
|
|
43
43
|
var showIndex = columns.length > 0 && !hasOwnIndexColumn(sources);
|
|
44
44
|
if (showIndex) columns.unshift(makeIndexColumn());
|
|
45
45
|
var theme = useArrayTableTheme();
|
|
46
|
+
var _useArrayTableMetrics = useArrayTableMetrics(),
|
|
47
|
+
rowHeight = _useArrayTableMetrics.rowHeight,
|
|
48
|
+
headerHeight = _useArrayTableMetrics.headerHeight;
|
|
46
49
|
return /*#__PURE__*/_jsx("div", {
|
|
47
50
|
style: {
|
|
48
51
|
height: height !== null && height !== void 0 ? height : 400
|
|
49
52
|
},
|
|
50
53
|
children: /*#__PURE__*/_jsx(AgGridReact, {
|
|
51
54
|
theme: theme,
|
|
52
|
-
rowHeight:
|
|
55
|
+
rowHeight: rowHeight,
|
|
56
|
+
headerHeight: headerHeight,
|
|
53
57
|
enableCellTextSelection: true,
|
|
54
58
|
ensureDomOrder: true,
|
|
55
59
|
defaultColDef: {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type ScanInputProps } from './ScanInput';
|
|
3
|
+
/** 一次扫码的结果。每次扫码传入新对象即重新触发一次边缘闪动;结果文字保留到下一次传入。 */
|
|
4
|
+
export interface ScanResult {
|
|
5
|
+
type: 'success' | 'error';
|
|
6
|
+
/** 徽标文字,不传按类型给「成功」/「失败」 */
|
|
7
|
+
message?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export interface ScanFeedbackInputProps extends ScanInputProps {
|
|
10
|
+
/** 最近一次扫码结果;换成新对象 = 新的一次扫码 */
|
|
11
|
+
result?: ScanResult;
|
|
12
|
+
/** 播放提示音(WebAudio 合成),默认 false 静音 */
|
|
13
|
+
sound?: boolean;
|
|
14
|
+
/** 边缘闪动时长(毫秒),默认 1200 */
|
|
15
|
+
flashDuration?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 扫码输入框 + 反馈整体组件(规范 §11.1):
|
|
19
|
+
* 输入框下方预留固定高度的图标+文字徽标(语义色,保留到下一次扫码),
|
|
20
|
+
* 屏幕边缘闪动约 1.2 秒后收起,可选提示音。
|
|
21
|
+
* 边缘闪动层相对最近的定位祖先铺满,宿主需要整屏效果时把它放进整页容器即可。
|
|
22
|
+
*
|
|
23
|
+
* @author nokecy
|
|
24
|
+
*/
|
|
25
|
+
declare const ScanFeedbackInput: React.FC<ScanFeedbackInputProps>;
|
|
26
|
+
export default ScanFeedbackInput;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
var _excluded = ["result", "sound", "flashDuration"];
|
|
3
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
7
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
8
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
9
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
10
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
11
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
12
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
13
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
14
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
15
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
16
|
+
import { CheckCircleFilled, CloseCircleFilled } from '@ant-design/icons';
|
|
17
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
18
|
+
import FullScreenAlert from "../fullScreenAlert/index";
|
|
19
|
+
import ScanInput from "./ScanInput";
|
|
20
|
+
import { playScanSound } from "./scanSound";
|
|
21
|
+
|
|
22
|
+
/** 一次扫码的结果。每次扫码传入新对象即重新触发一次边缘闪动;结果文字保留到下一次传入。 */
|
|
23
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
24
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
25
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
26
|
+
/** 反馈区预留高度:徽标出现、消失都不推动页面其余内容。 */
|
|
27
|
+
var BADGE_HEIGHT = 48;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 扫码输入框 + 反馈整体组件(规范 §11.1):
|
|
31
|
+
* 输入框下方预留固定高度的图标+文字徽标(语义色,保留到下一次扫码),
|
|
32
|
+
* 屏幕边缘闪动约 1.2 秒后收起,可选提示音。
|
|
33
|
+
* 边缘闪动层相对最近的定位祖先铺满,宿主需要整屏效果时把它放进整页容器即可。
|
|
34
|
+
*
|
|
35
|
+
* @author nokecy
|
|
36
|
+
*/
|
|
37
|
+
var ScanFeedbackInput = function ScanFeedbackInput(_ref) {
|
|
38
|
+
var _result$message;
|
|
39
|
+
var result = _ref.result,
|
|
40
|
+
_ref$sound = _ref.sound,
|
|
41
|
+
sound = _ref$sound === void 0 ? false : _ref$sound,
|
|
42
|
+
_ref$flashDuration = _ref.flashDuration,
|
|
43
|
+
flashDuration = _ref$flashDuration === void 0 ? 1200 : _ref$flashDuration,
|
|
44
|
+
inputProps = _objectWithoutProperties(_ref, _excluded);
|
|
45
|
+
// 每次拿到新的 result 递增,作为闪动层的 key 使其重新挂载、从头计时。
|
|
46
|
+
var _useState = useState({
|
|
47
|
+
id: 0,
|
|
48
|
+
active: false
|
|
49
|
+
}),
|
|
50
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
51
|
+
flash = _useState2[0],
|
|
52
|
+
setFlash = _useState2[1];
|
|
53
|
+
var first = useRef(true);
|
|
54
|
+
useEffect(function () {
|
|
55
|
+
// 首次渲染时的 result 视为历史结果(徽标显示),不闪、不响。
|
|
56
|
+
if (first.current) {
|
|
57
|
+
first.current = false;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!result) return;
|
|
61
|
+
setFlash(function (prev) {
|
|
62
|
+
return {
|
|
63
|
+
id: prev.id + 1,
|
|
64
|
+
active: true
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
if (sound) playScanSound(result.type);
|
|
68
|
+
}, [result]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
69
|
+
var onFlashChange = useCallback(function (active) {
|
|
70
|
+
return setFlash(function (prev) {
|
|
71
|
+
return _objectSpread(_objectSpread({}, prev), {}, {
|
|
72
|
+
active: active
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}, []);
|
|
76
|
+
var isError = (result === null || result === void 0 ? void 0 : result.type) === 'error';
|
|
77
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
78
|
+
className: "scanFeedbackInput",
|
|
79
|
+
children: [/*#__PURE__*/_jsx(ScanInput, _objectSpread({}, inputProps)), /*#__PURE__*/_jsx("div", {
|
|
80
|
+
className: "scanFeedbackBadge",
|
|
81
|
+
role: "status",
|
|
82
|
+
"aria-live": "polite",
|
|
83
|
+
style: {
|
|
84
|
+
minHeight: BADGE_HEIGHT,
|
|
85
|
+
display: 'flex',
|
|
86
|
+
alignItems: 'center',
|
|
87
|
+
justifyContent: 'center',
|
|
88
|
+
gap: 8,
|
|
89
|
+
fontSize: 20,
|
|
90
|
+
fontWeight: 700,
|
|
91
|
+
color: result ? isError ? 'var(--ant-color-error, red)' : 'var(--ant-color-success, green)' : undefined
|
|
92
|
+
},
|
|
93
|
+
children: result ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
94
|
+
children: [isError ? /*#__PURE__*/_jsx(CloseCircleFilled, {}) : /*#__PURE__*/_jsx(CheckCircleFilled, {}), /*#__PURE__*/_jsx("span", {
|
|
95
|
+
children: (_result$message = result.message) !== null && _result$message !== void 0 ? _result$message : isError ? '失败' : '成功'
|
|
96
|
+
})]
|
|
97
|
+
}) : null
|
|
98
|
+
}), result ? /*#__PURE__*/_jsx(FullScreenAlert, {
|
|
99
|
+
active: flash.active,
|
|
100
|
+
type: result.type,
|
|
101
|
+
duration: flashDuration,
|
|
102
|
+
showIcon: false,
|
|
103
|
+
onChange: onFlashChange
|
|
104
|
+
}, flash.id) : null]
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
export default ScanFeedbackInput;
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { default as ScanInput } from './ScanInput';
|
|
8
8
|
export type { ScanInputProps } from './ScanInput';
|
|
9
|
+
export { default as ScanFeedbackInput } from './ScanFeedbackInput';
|
|
10
|
+
export type { ScanFeedbackInputProps, ScanResult } from './ScanFeedbackInput';
|
|
11
|
+
export { playScanSound } from './scanSound';
|
|
12
|
+
export type { ScanSoundType } from './scanSound';
|
|
9
13
|
export { default as usePromiseQueue } from './usePromiseQueue';
|
|
10
14
|
export type { PromiseQueue, PromiseQueueOptions, QueueTask } from './usePromiseQueue';
|
|
11
15
|
export { createRequestGate } from './requestGate';
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* @author nokecy
|
|
6
6
|
*/
|
|
7
7
|
export { default as ScanInput } from "./ScanInput";
|
|
8
|
+
export { default as ScanFeedbackInput } from "./ScanFeedbackInput";
|
|
9
|
+
export { playScanSound } from "./scanSound";
|
|
8
10
|
export { default as usePromiseQueue } from "./usePromiseQueue";
|
|
9
11
|
export { createRequestGate } from "./requestGate";
|
|
10
12
|
export { blurOn, canTakeFocus, focusOn } from "./focus";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 扫码提示音:用 WebAudio 合成,不依赖音频资源文件。
|
|
3
|
+
* AudioContext 是模块级单例——浏览器限制同一页面可创建的上下文数量,且需要在用户手势后才能出声,
|
|
4
|
+
* 每次扫码都 new 一个既浪费也会被拒绝。
|
|
5
|
+
*
|
|
6
|
+
* @author nokecy
|
|
7
|
+
*/
|
|
8
|
+
export type ScanSoundType = 'success' | 'error';
|
|
9
|
+
/**
|
|
10
|
+
* 播放一次扫码提示音。静默失败:没有 WebAudio、上下文被浏览器挂起且无法恢复时直接忽略,不影响采集流程。
|
|
11
|
+
* @returns 是否已提交播放
|
|
12
|
+
*/
|
|
13
|
+
export declare function playScanSound(type: ScanSoundType): boolean;
|
|
14
|
+
/** 仅测试用:丢弃共享上下文。 */
|
|
15
|
+
export declare function resetScanSoundForTest(): void;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
4
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
5
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
6
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
7
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
8
|
+
/**
|
|
9
|
+
* 扫码提示音:用 WebAudio 合成,不依赖音频资源文件。
|
|
10
|
+
* AudioContext 是模块级单例——浏览器限制同一页面可创建的上下文数量,且需要在用户手势后才能出声,
|
|
11
|
+
* 每次扫码都 new 一个既浪费也会被拒绝。
|
|
12
|
+
*
|
|
13
|
+
* @author nokecy
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var sharedContext;
|
|
17
|
+
|
|
18
|
+
/** 取(或创建)共享的 AudioContext;环境不支持 WebAudio 时返回 undefined。 */
|
|
19
|
+
function getAudioContext() {
|
|
20
|
+
var _window$AudioContext;
|
|
21
|
+
if (sharedContext) return sharedContext;
|
|
22
|
+
var Ctor = typeof window === 'undefined' ? undefined : (_window$AudioContext = window.AudioContext) !== null && _window$AudioContext !== void 0 ? _window$AudioContext : window.webkitAudioContext;
|
|
23
|
+
if (!Ctor) return undefined;
|
|
24
|
+
try {
|
|
25
|
+
sharedContext = new Ctor();
|
|
26
|
+
} catch (_unused) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
return sharedContext;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** 每种结果的音符序列:[频率 Hz, 起点 s, 时长 s]。成功一声高短音;失败两声低音,听感上与成功明显不同。 */
|
|
33
|
+
var TONES = {
|
|
34
|
+
success: [[880, 0, 0.12]],
|
|
35
|
+
error: [[220, 0, 0.18], [220, 0.26, 0.18]]
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 播放一次扫码提示音。静默失败:没有 WebAudio、上下文被浏览器挂起且无法恢复时直接忽略,不影响采集流程。
|
|
40
|
+
* @returns 是否已提交播放
|
|
41
|
+
*/
|
|
42
|
+
export function playScanSound(type) {
|
|
43
|
+
var ctx = getAudioContext();
|
|
44
|
+
if (!ctx) return false;
|
|
45
|
+
try {
|
|
46
|
+
var _ctx$resume;
|
|
47
|
+
if (ctx.state === 'suspended') void ((_ctx$resume = ctx.resume) === null || _ctx$resume === void 0 ? void 0 : _ctx$resume.call(ctx));
|
|
48
|
+
var now = ctx.currentTime;
|
|
49
|
+
var _iterator = _createForOfIteratorHelper(TONES[type]),
|
|
50
|
+
_step;
|
|
51
|
+
try {
|
|
52
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
53
|
+
var _step$value = _slicedToArray(_step.value, 3),
|
|
54
|
+
frequency = _step$value[0],
|
|
55
|
+
offset = _step$value[1],
|
|
56
|
+
length = _step$value[2];
|
|
57
|
+
var osc = ctx.createOscillator();
|
|
58
|
+
var gain = ctx.createGain();
|
|
59
|
+
osc.type = type === 'error' ? 'square' : 'sine';
|
|
60
|
+
osc.frequency.value = frequency;
|
|
61
|
+
// 起止做短包络,避免爆音。
|
|
62
|
+
gain.gain.setValueAtTime(0.0001, now + offset);
|
|
63
|
+
gain.gain.exponentialRampToValueAtTime(0.2, now + offset + 0.01);
|
|
64
|
+
gain.gain.exponentialRampToValueAtTime(0.0001, now + offset + length);
|
|
65
|
+
osc.connect(gain);
|
|
66
|
+
gain.connect(ctx.destination);
|
|
67
|
+
osc.start(now + offset);
|
|
68
|
+
osc.stop(now + offset + length + 0.02);
|
|
69
|
+
}
|
|
70
|
+
} catch (err) {
|
|
71
|
+
_iterator.e(err);
|
|
72
|
+
} finally {
|
|
73
|
+
_iterator.f();
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
} catch (_unused2) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** 仅测试用:丢弃共享上下文。 */
|
|
82
|
+
export function resetScanSoundForTest() {
|
|
83
|
+
sharedContext = undefined;
|
|
84
|
+
}
|