@nokecy/qc-ui 1.1.74 → 1.1.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/cjs/dialogSelect/index.d.ts +2 -2
  2. package/dist/cjs/dialogSelect/index.js +65 -10
  3. package/dist/cjs/entitySelect/index.d.ts +57 -0
  4. package/dist/cjs/entitySelect/index.js +172 -0
  5. package/dist/cjs/exportButton/exportAction.d.ts +74 -0
  6. package/dist/cjs/exportButton/exportAction.js +199 -0
  7. package/dist/cjs/exportButton/index.d.ts +39 -0
  8. package/dist/cjs/exportButton/index.js +295 -0
  9. package/dist/cjs/importModal/index.d.ts +9 -0
  10. package/dist/cjs/importModal/index.js +46 -8
  11. package/dist/cjs/index.d.ts +6 -0
  12. package/dist/cjs/index.js +74 -0
  13. package/dist/cjs/readPretty/arrayTable.d.ts +6 -0
  14. package/dist/cjs/readPretty/arrayTable.js +156 -0
  15. package/dist/cjs/readPretty/controls.d.ts +11 -0
  16. package/dist/cjs/readPretty/controls.js +68 -0
  17. package/dist/cjs/readPretty/decimal.d.ts +4 -0
  18. package/dist/cjs/readPretty/decimal.js +28 -0
  19. package/dist/cjs/readPretty/formily.d.ts +2 -0
  20. package/dist/cjs/readPretty/formily.js +71 -0
  21. package/dist/cjs/readPretty/hoistStatics.d.ts +1 -0
  22. package/dist/cjs/readPretty/hoistStatics.js +37 -0
  23. package/dist/cjs/readPretty/index.d.ts +11 -0
  24. package/dist/cjs/readPretty/index.js +70 -0
  25. package/dist/cjs/readPretty/selectValue.d.ts +7 -0
  26. package/dist/cjs/readPretty/selectValue.js +60 -0
  27. package/dist/cjs/readPretty/values.d.ts +4 -0
  28. package/dist/cjs/readPretty/values.js +49 -0
  29. package/dist/cjs/utils/download.d.ts +6 -0
  30. package/dist/cjs/utils/download.js +23 -0
  31. package/dist/esm/dialogSelect/index.d.ts +2 -2
  32. package/dist/esm/dialogSelect/index.js +59 -4
  33. package/dist/esm/entitySelect/index.d.ts +57 -0
  34. package/dist/esm/entitySelect/index.js +164 -0
  35. package/dist/esm/exportButton/exportAction.d.ts +74 -0
  36. package/dist/esm/exportButton/exportAction.js +193 -0
  37. package/dist/esm/exportButton/index.d.ts +39 -0
  38. package/dist/esm/exportButton/index.js +259 -0
  39. package/dist/esm/importModal/index.d.ts +9 -0
  40. package/dist/esm/importModal/index.js +46 -8
  41. package/dist/esm/index.d.ts +6 -0
  42. package/dist/esm/index.js +4 -0
  43. package/dist/esm/readPretty/arrayTable.d.ts +6 -0
  44. package/dist/esm/readPretty/arrayTable.js +147 -0
  45. package/dist/esm/readPretty/controls.d.ts +11 -0
  46. package/dist/esm/readPretty/controls.js +62 -0
  47. package/dist/esm/readPretty/decimal.d.ts +4 -0
  48. package/dist/esm/readPretty/decimal.js +22 -0
  49. package/dist/esm/readPretty/formily.d.ts +2 -0
  50. package/dist/esm/readPretty/formily.js +63 -0
  51. package/dist/esm/readPretty/hoistStatics.d.ts +1 -0
  52. package/dist/esm/readPretty/hoistStatics.js +31 -0
  53. package/dist/esm/readPretty/index.d.ts +11 -0
  54. package/dist/esm/readPretty/index.js +12 -0
  55. package/dist/esm/readPretty/selectValue.d.ts +7 -0
  56. package/dist/esm/readPretty/selectValue.js +53 -0
  57. package/dist/esm/readPretty/values.d.ts +4 -0
  58. package/dist/esm/readPretty/values.js +43 -0
  59. package/dist/esm/utils/download.d.ts +6 -0
  60. package/dist/esm/utils/download.js +17 -0
  61. package/dist/umd/qc-ui.min.js +1 -1
  62. package/package.json +1 -1
@@ -33,7 +33,10 @@ var ImportModal = function ImportModal(props) {
33
33
  _props$downloadBlob = props.downloadBlob,
34
34
  downloadBlob = _props$downloadBlob === void 0 ? defaultDownloadBlob : _props$downloadBlob,
35
35
  serverUrl = props.serverUrl,
36
- buttonProps = props.buttonProps;
36
+ buttonProps = props.buttonProps,
37
+ request = props.request,
38
+ method = props.method,
39
+ onRealSuccess = props.onRealSuccess;
37
40
  var _useBoolean = useBoolean(false),
38
41
  _useBoolean2 = _slicedToArray(_useBoolean, 2),
39
42
  visible = _useBoolean2[0],
@@ -63,12 +66,46 @@ var ImportModal = function ImportModal(props) {
63
66
  }
64
67
  }, "\u6A21\u7248")),
65
68
  type: "info"
66
- }), /*#__PURE__*/React.createElement(Upload.Dragger, {
69
+ }), /*#__PURE__*/React.createElement(Upload.Dragger, _extends({
67
70
  style: {
68
71
  marginTop: 10
69
72
  },
70
73
  multiple: false,
71
- action: getUploadUrl(),
74
+ action: getUploadUrl()
75
+ }, request ? {
76
+ customRequest: function customRequest(_ref) {
77
+ var action = _ref.action,
78
+ file = _ref.file,
79
+ headers = _ref.headers,
80
+ onError = _ref.onError,
81
+ onProgress = _ref.onProgress,
82
+ onSuccess = _ref.onSuccess;
83
+ var formData = new FormData();
84
+ formData.append('file', file);
85
+ request(action, {
86
+ method: method || 'POST',
87
+ data: formData,
88
+ headers: headers,
89
+ // 导入失败要展示行级原因,交给下面的弹窗统一报,不再走全局吐司。
90
+ skipErrorHandler: true,
91
+ onUploadProgress: function onUploadProgress(_ref2) {
92
+ var total = _ref2.total,
93
+ loaded = _ref2.loaded;
94
+ onProgress === null || onProgress === void 0 || onProgress({
95
+ percent: Number((loaded / total * 100).toFixed(2))
96
+ }, file);
97
+ }
98
+ }).then(function (response) {
99
+ onSuccess === null || onSuccess === void 0 || onSuccess(response, file);
100
+ onRealSuccess === null || onRealSuccess === void 0 || onRealSuccess(response);
101
+ })
102
+ // 第二个参数成为 info.file.response,onChange 靠它拿到后端的失败原因,而不是 axios 的英文文案。
103
+ .catch(function (err) {
104
+ var _err$response;
105
+ return onError === null || onError === void 0 ? void 0 : onError(err, err === null || err === void 0 || (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.data);
106
+ });
107
+ }
108
+ } : {}, {
72
109
  onChange: function onChange(info) {
73
110
  if (info.file.status === 'done') {
74
111
  message.success('导入成功');
@@ -77,15 +114,16 @@ var ImportModal = function ImportModal(props) {
77
114
  }
78
115
  if (info.file.status === 'error') {
79
116
  var _info$file;
80
- Modal.info({
81
- title: '导入失败,原因如下:',
117
+ // 没有后端给的原因时也要有提示,不能让失败无声无息。
118
+ Modal.error({
119
+ title: '导入失败',
82
120
  closable: true,
83
- width: 1000,
84
- content: info === null || info === void 0 || (_info$file = info.file) === null || _info$file === void 0 || (_info$file = _info$file.response) === null || _info$file === void 0 || (_info$file = _info$file.error) === null || _info$file === void 0 ? void 0 : _info$file.message
121
+ width: 800,
122
+ content: (info === null || info === void 0 || (_info$file = info.file) === null || _info$file === void 0 || (_info$file = _info$file.response) === null || _info$file === void 0 || (_info$file = _info$file.error) === null || _info$file === void 0 ? void 0 : _info$file.message) || '文件未能导入。请核对模板格式与必填列后重试;若持续失败请联系技术支持。'
85
123
  });
86
124
  }
87
125
  }
88
- }, /*#__PURE__*/React.createElement("p", {
126
+ }), /*#__PURE__*/React.createElement("p", {
89
127
  className: "ant-upload-drag-icon"
90
128
  }, /*#__PURE__*/React.createElement(InboxOutlined, null)), /*#__PURE__*/React.createElement("p", {
91
129
  className: "ant-upload-text"
@@ -31,6 +31,12 @@ export type * from "./RuleBuilder";
31
31
  export type { ColumnConfig } from "./array-table/columnHelper";
32
32
  export type { CentralizedColumnScheme, QueryScheme, SchemeStorageAdapter, SchemeSyncDataDto, CurrentSchemeDto, SchemeStorageConfig, LocalStorageAdapterConfig, BackendApiAdapterConfig, UseSchemeManagerConfig, GridPlusContextValue, GlobalConfigPermissions, } from "./ag-grid-plus";
33
33
  export * from './adapters';
34
+ export * from "./readPretty";
35
+ export { createEntitySelect } from "./entitySelect";
36
+ export { default as ExportButton, buildExportUrl, DEFAULT_EXPORT_TEMPLATE_API, resolveExportAction, resolveExportError, resolveFileName } from "./exportButton";
37
+ export type { ExportButtonProps, ExportTemplateApi, ExportTemplateOption } from "./exportButton";
38
+ export { saveAs } from "./utils/download";
39
+ export type { EntitySelectConfig, EntitySelectProps, EntitySelectQuery } from "./entitySelect";
34
40
  export { semanticTextColors, toGridTextColor, gridValueEnum } from "./ag-grid-plus/utils/valueEnumColor";
35
41
  export type { SemanticPreset } from "./ag-grid-plus/utils/valueEnumColor";
36
42
  export { contrastRatio, relativeLuminance, darkenUntilContrast, lightenUntilContrast, toRgb, toHsl, fromHsl } from "./utils/contrast";
package/dist/esm/index.js CHANGED
@@ -42,6 +42,10 @@ useSchemeManager, useGridSchemes, LocalStorageSchemeAdapter, BackendApiSchemeAda
42
42
 
43
43
  // 分页适配器:值 + 类型一并导出,支持非 ABP 后端注入
44
44
  export * from "./adapters";
45
+ export * from "./readPretty";
46
+ export { createEntitySelect } from "./entitySelect";
47
+ export { default as ExportButton, buildExportUrl, DEFAULT_EXPORT_TEMPLATE_API, resolveExportAction, resolveExportError, resolveFileName } from "./exportButton";
48
+ export { saveAs } from "./utils/download";
45
49
  export { semanticTextColors, toGridTextColor, gridValueEnum } from "./ag-grid-plus/utils/valueEnumColor";
46
50
  export { contrastRatio, relativeLuminance, darkenUntilContrast, lightenUntilContrast, toRgb, toHsl, fromHsl } from "./utils/contrast";
47
51
  export { BusinessDecimal, decimal, decimalText, nonNegativeDecimal, roundDecimal, sumDecimals, formatDecimal } from "./utils/businessDecimal";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 阅读态也创建列的 void 字段,让 Formily 求值标题、显隐与 reactions;
3
+ * qc-ui 的阅读视图只读取列状态,未像编辑视图一样挂载这些字段。
4
+ * @author nokecy
5
+ */
6
+ export declare const withReadingArrayTable: (Control: any) => any;
@@ -0,0 +1,147 @@
1
+ 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; } } }; }
2
+ 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); }
3
+ 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; }
4
+ import { observer, RecursionField, useField, useFieldSchema } from '@formily/react';
5
+ import { AgGridReact } from 'ag-grid-react';
6
+ import { buildArrayTableColumns, useArrayTableSources } from "../array-table/utils";
7
+ import { groupColumnDefs } from "../array-table/columnGroup";
8
+ import { ARRAY_TABLE_INDEX_FIELD, hasOwnIndexColumn, makeIndexColumn } from "../array-table/indexColumn";
9
+ import { ARRAY_TABLE_ROW_HEIGHT, useArrayTableTheme } from "../array-table/theme";
10
+ import { hoistStatics } from "./hoistStatics";
11
+ import React, { useMemo, useRef } from 'react';
12
+ /** 阅读态直接使用 ArrayTable 的列定义,避免 AgGridPlus 的原值渲染器覆盖格式化结果。@author nokecy */
13
+ var ReadingArrayTable = observer(function (_ref) {
14
+ var _buildArrayTableColum;
15
+ var height = _ref.height;
16
+ var field = useField();
17
+ var sources = useArrayTableSources();
18
+ var rows = Array.isArray(field.value) ? field.value.slice() : [];
19
+ var generatedRowIds = useRef(new WeakMap());
20
+ var generatedRowIdSequence = useRef(0);
21
+ var columns = (_buildArrayTableColum = buildArrayTableColumns(rows, field, sources)) !== null && _buildArrayTableColum !== void 0 ? _buildArrayTableColum : [];
22
+ var showIndex = columns.length > 0 && !hasOwnIndexColumn(sources);
23
+ if (showIndex) columns.unshift(makeIndexColumn());
24
+ var theme = useArrayTableTheme();
25
+ return /*#__PURE__*/React.createElement("div", {
26
+ style: {
27
+ height: height !== null && height !== void 0 ? height : 400
28
+ }
29
+ }, /*#__PURE__*/React.createElement(AgGridReact, {
30
+ theme: theme,
31
+ rowHeight: ARRAY_TABLE_ROW_HEIGHT,
32
+ enableCellTextSelection: true,
33
+ ensureDomOrder: true,
34
+ defaultColDef: {
35
+ resizable: true,
36
+ sortable: true,
37
+ filter: true
38
+ },
39
+ rowSelection: {
40
+ mode: 'singleRow',
41
+ enableClickSelection: true
42
+ },
43
+ selectionColumnDef: {
44
+ pinned: 'left',
45
+ lockPosition: true,
46
+ width: 50,
47
+ suppressHeaderMenuButton: true
48
+ },
49
+ columnDefs: groupColumnDefs(columns),
50
+ rowData: rows,
51
+ getRowId: function getRowId(_ref2) {
52
+ var _data$_id;
53
+ var data = _ref2.data;
54
+ var id = (_data$_id = data === null || data === void 0 ? void 0 : data._id) !== null && _data$_id !== void 0 ? _data$_id : data === null || data === void 0 ? void 0 : data.id;
55
+ if (id != null) return "data:".concat(String(id));
56
+
57
+ // 阅读态明细常用旧表行号等字段,不一定有 id/_id。给无 ID 的对象分配稳定行键,
58
+ // 否则多行都会返回 "undefined",AG Grid 在数据更新后会合并掉重复行。@author nokecy
59
+ var row = data;
60
+ var rowId = generatedRowIds.current.get(row);
61
+ if (!rowId) {
62
+ rowId = "generated:".concat(++generatedRowIdSequence.current);
63
+ generatedRowIds.current.set(row, rowId);
64
+ }
65
+ return rowId;
66
+ },
67
+ onRowDataUpdated: function onRowDataUpdated(_ref3) {
68
+ var api = _ref3.api;
69
+ if (showIndex) api.refreshCells({
70
+ columns: [ARRAY_TABLE_INDEX_FIELD],
71
+ force: true
72
+ });
73
+ }
74
+ }));
75
+ });
76
+
77
+ /** 按 ArrayTable 的列提取规则收集列节点,不挂载明细数据字段。@author nokecy */
78
+ var columnsOf = function columnsOf(schema) {
79
+ var columns = [];
80
+ var visit = function visit(node) {
81
+ if (typeof node['x-component'] === 'string' && node['x-component'].includes('Column')) {
82
+ var _node$xComponentPro, _node$xComponentPro2;
83
+ var name = (_node$xComponentPro = (_node$xComponentPro2 = node['x-component-props']) === null || _node$xComponentPro2 === void 0 ? void 0 : _node$xComponentPro2.dataIndex) !== null && _node$xComponentPro !== void 0 ? _node$xComponentPro : node.name;
84
+ if (name !== undefined) columns.push({
85
+ name: name,
86
+ schema: node
87
+ });
88
+ } else {
89
+ Object.values(node.properties || {}).forEach(visit);
90
+ }
91
+ };
92
+ var items = Array.isArray(schema.items) ? schema.items : schema.items ? [schema.items] : [];
93
+ items.forEach(visit);
94
+ return columns;
95
+ };
96
+
97
+ /**
98
+ * 阅读态也创建列的 void 字段,让 Formily 求值标题、显隐与 reactions;
99
+ * qc-ui 的阅读视图只读取列状态,未像编辑视图一样挂载这些字段。
100
+ * @author nokecy
101
+ */
102
+ export var withReadingArrayTable = function withReadingArrayTable(Control) {
103
+ var ReactiveTable = observer(function (_ref4) {
104
+ var columns = _ref4.columns,
105
+ tableProps = _ref4.tableProps;
106
+ var field = useField();
107
+ // 阅读视图本身未订阅列状态,在此建立依赖,条件变化后重新提取表头。@author nokecy
108
+ var _iterator = _createForOfIteratorHelper(columns),
109
+ _step;
110
+ try {
111
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
112
+ var _column$componentProp, _column$componentProp2, _column$componentProp3;
113
+ var name = _step.value.name;
114
+ var column = field.query(field.address.concat(name)).take();
115
+ void (column === null || column === void 0 ? void 0 : column.display);
116
+ void (column === null || column === void 0 || (_column$componentProp = column.componentProps) === null || _column$componentProp === void 0 ? void 0 : _column$componentProp.title);
117
+ void (column === null || column === void 0 || (_column$componentProp2 = column.componentProps) === null || _column$componentProp2 === void 0 ? void 0 : _column$componentProp2.headerName);
118
+ void (column === null || column === void 0 || (_column$componentProp3 = column.componentProps) === null || _column$componentProp3 === void 0 ? void 0 : _column$componentProp3.headerGroup);
119
+ }
120
+ } catch (err) {
121
+ _iterator.e(err);
122
+ } finally {
123
+ _iterator.f();
124
+ }
125
+ return /*#__PURE__*/React.createElement(ReadingArrayTable, tableProps);
126
+ });
127
+ var Table = observer(function (props) {
128
+ var field = useField();
129
+ var schema = useFieldSchema();
130
+ var columns = useMemo(function () {
131
+ return columnsOf(schema);
132
+ }, [schema]);
133
+ if (field.pattern !== 'readPretty') return /*#__PURE__*/React.createElement(Control, props);
134
+ return /*#__PURE__*/React.createElement(React.Fragment, null, columns.map(function (column) {
135
+ return /*#__PURE__*/React.createElement(RecursionField, {
136
+ key: column.name,
137
+ name: column.name,
138
+ schema: column.schema,
139
+ onlyRenderSelf: true
140
+ });
141
+ }), /*#__PURE__*/React.createElement(ReactiveTable, {
142
+ columns: columns,
143
+ tableProps: props
144
+ }));
145
+ });
146
+ return hoistStatics(Table, Control);
147
+ };
@@ -0,0 +1,11 @@
1
+ import { Input as AntInput, InputNumber as AntInputNumber, Select as AntSelect, Switch as AntSwitch, Checkbox as AntCheckbox, Radio as AntRadio, DatePicker as AntDatePicker, TimePicker as AntTimePicker, TreeSelect as AntTreeSelect, Cascader as AntCascader } from 'antd';
2
+ export declare const Input: typeof AntInput;
3
+ export declare const InputNumber: typeof AntInputNumber;
4
+ export declare const Select: typeof AntSelect;
5
+ export declare const Switch: typeof AntSwitch;
6
+ export declare const Checkbox: typeof AntCheckbox;
7
+ export declare const Radio: typeof AntRadio;
8
+ export declare const DatePicker: typeof AntDatePicker;
9
+ export declare const TimePicker: typeof AntTimePicker;
10
+ export declare const TreeSelect: typeof AntTreeSelect;
11
+ export declare const Cascader: typeof AntCascader;
@@ -0,0 +1,62 @@
1
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+ import { PreviewText } from '@formily/antd-v5';
3
+ import { ConfigProvider, Input as AntInput, InputNumber as AntInputNumber, Select as AntSelect, Switch as AntSwitch, Checkbox as AntCheckbox, Radio as AntRadio, DatePicker as AntDatePicker, TimePicker as AntTimePicker, TreeSelect as AntTreeSelect, Cascader as AntCascader } from 'antd';
4
+ import React from 'react';
5
+ import { hoistStatics } from "./hoistStatics";
6
+ import { flattenOptions, selectedLabels } from "./values";
7
+
8
+ /** 普通表单控件在不可编辑时使用阅读展示,继承整张表单的禁用状态。@author nokecy */
9
+ var readingControl = function readingControl(Control, Preview) {
10
+ var map = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (props) {
11
+ return props;
12
+ };
13
+ var Component = /*#__PURE__*/React.forwardRef(function (props, ref) {
14
+ var _props$disabled;
15
+ var _ConfigProvider$useCo = ConfigProvider.useConfig(),
16
+ componentDisabled = _ConfigProvider$useCo.componentDisabled;
17
+ var reading = props.readOnly || ((_props$disabled = props.disabled) !== null && _props$disabled !== void 0 ? _props$disabled : componentDisabled);
18
+ return reading ? /*#__PURE__*/React.createElement(PreviewText.Placeholder, {
19
+ value: "\u2014"
20
+ }, /*#__PURE__*/React.createElement(Preview, map(props))) : /*#__PURE__*/React.createElement(Control, _extends({}, props, {
21
+ ref: ref
22
+ }));
23
+ });
24
+ return hoistStatics(Component, Control);
25
+ };
26
+
27
+ /** 选择项来自 options 或原生 Option/Radio 子节点,阅读态显示名称。@author nokecy */
28
+ var choiceOptions = function choiceOptions(props) {
29
+ return props.options || React.Children.toArray(props.children).flatMap(function (child) {
30
+ var _child$props;
31
+ return ((_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.value) !== undefined ? [{
32
+ value: child.props.value,
33
+ label: child.props.children
34
+ }] : choiceOptions(child.props || {});
35
+ });
36
+ };
37
+ var ChoicePreview = function ChoicePreview(props) {
38
+ return /*#__PURE__*/React.createElement("span", null, selectedLabels(props.value, flattenOptions(choiceOptions(props), props.fieldNames), props.labelInValue));
39
+ };
40
+ var BooleanPreview = function BooleanPreview(props) {
41
+ return /*#__PURE__*/React.createElement("span", null, props.children, props.children ? ':' : '', props.checked == null ? '—' : props.checked ? '是' : '否');
42
+ };
43
+ var PasswordPreview = function PasswordPreview(props) {
44
+ return /*#__PURE__*/React.createElement("span", null, props.value ? '••••••' : '—');
45
+ };
46
+ export var Input = readingControl(AntInput, PreviewText.Input);
47
+ Input.TextArea = readingControl(AntInput.TextArea, PreviewText.Input);
48
+ Input.Password = readingControl(AntInput.Password, PasswordPreview);
49
+ Input.Search = readingControl(AntInput.Search, PreviewText.Input);
50
+ export var InputNumber = readingControl(AntInputNumber, PreviewText.NumberPicker);
51
+ export var Select = readingControl(AntSelect, ChoicePreview);
52
+ export var Switch = readingControl(AntSwitch, BooleanPreview);
53
+ export var Checkbox = readingControl(AntCheckbox, BooleanPreview);
54
+ Checkbox.Group = readingControl(AntCheckbox.Group, ChoicePreview);
55
+ export var Radio = readingControl(AntRadio, BooleanPreview);
56
+ Radio.Group = readingControl(AntRadio.Group, ChoicePreview);
57
+ export var DatePicker = readingControl(AntDatePicker, PreviewText.DatePicker);
58
+ DatePicker.RangePicker = readingControl(AntDatePicker.RangePicker, PreviewText.DateRangePicker);
59
+ export var TimePicker = readingControl(AntTimePicker, PreviewText.TimePicker);
60
+ TimePicker.RangePicker = readingControl(AntTimePicker.RangePicker, PreviewText.TimeRangePicker);
61
+ export var TreeSelect = readingControl(AntTreeSelect, PreviewText.TreeSelect);
62
+ export var Cascader = readingControl(AntCascader, PreviewText.Cascader);
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ /** 精确业务数值录入和阅读展示,零值与原始十进制字符串始终保留。@author nokecy */
3
+ export declare const DecimalInput: React.ForwardRefExoticComponent<Omit<any, "ref"> & React.RefAttributes<any>>;
4
+ export declare const DecimalPicker: React.ForwardRefExoticComponent<Omit<Partial<Omit<any, "ref"> & React.RefAttributes<any>>, "ref"> & React.RefAttributes<unknown>>;
@@ -0,0 +1,22 @@
1
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+ import { connect, mapReadPretty } from '@formily/react';
3
+ import React from 'react';
4
+ import { InputNumber } from "./controls";
5
+ import { decimalText } from "../utils/businessDecimal";
6
+
7
+ /** 精确业务数值录入和阅读展示,零值与原始十进制字符串始终保留。@author nokecy */
8
+ export var DecimalInput = /*#__PURE__*/React.forwardRef(function (props, ref) {
9
+ return /*#__PURE__*/React.createElement(InputNumber, _extends({}, props, {
10
+ stringMode: true,
11
+ ref: ref
12
+ }));
13
+ });
14
+ var DecimalPreview = function DecimalPreview(_ref) {
15
+ var value = _ref.value,
16
+ formatter = _ref.formatter;
17
+ return /*#__PURE__*/React.createElement("span", null, value == null || value === '' ? '—' : formatter ? formatter(value, {
18
+ userTyping: false,
19
+ input: String(value)
20
+ }) : decimalText(value));
21
+ };
22
+ export var DecimalPicker = connect(DecimalInput, mapReadPretty(DecimalPreview));
@@ -0,0 +1,2 @@
1
+ /** 动态表单统一入口:禁用/只读的数据控件使用阅读展示,保持字段值和校验模型。@author nokecy */
2
+ export declare function withReadingFields(components: Record<string, any>): Record<string, any>;
@@ -0,0 +1,63 @@
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
+ 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; } } }; }
3
+ 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); }
4
+ 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; }
5
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
6
+ 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; }
7
+ 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; }
8
+ 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; }
9
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
10
+ 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); }
11
+ import { observer, useField } from '@formily/react';
12
+ import React from 'react';
13
+ import { hoistStatics } from "./hoistStatics";
14
+ import * as Reading from "./controls";
15
+ import { withReadingArrayTable } from "./arrayTable";
16
+
17
+ /** 动态表单统一入口:禁用/只读的数据控件使用阅读展示,保持字段值和校验模型。@author nokecy */
18
+ export function withReadingFields(components) {
19
+ var result = _objectSpread({}, components);
20
+ var previews = _objectSpread(_objectSpread({}, Reading), {}, {
21
+ NumberPicker: Reading.InputNumber,
22
+ Password: Reading.Input.Password
23
+ });
24
+ var wrap = function wrap(Control, Preview) {
25
+ var Component = observer(function (props) {
26
+ var field = useField();
27
+ if (props.disabled || props.readOnly || field !== null && field !== void 0 && field.disabled || field !== null && field !== void 0 && field.readOnly) {
28
+ var _field$value, _field$value2, _field$dataSource;
29
+ return /*#__PURE__*/React.createElement(Preview, _extends({}, props, {
30
+ value: (_field$value = field === null || field === void 0 ? void 0 : field.value) !== null && _field$value !== void 0 ? _field$value : props.value,
31
+ checked: (_field$value2 = field === null || field === void 0 ? void 0 : field.value) !== null && _field$value2 !== void 0 ? _field$value2 : props.checked,
32
+ options: field !== null && field !== void 0 && (_field$dataSource = field.dataSource) !== null && _field$dataSource !== void 0 && _field$dataSource.length ? field.dataSource : props.options,
33
+ disabled: true
34
+ }));
35
+ }
36
+ return /*#__PURE__*/React.createElement(Control, props);
37
+ });
38
+ var Wrapped = hoistStatics(Component, Control);
39
+ // 嵌套控件同样按字段状态展示,例如Input.TextArea、DatePicker.RangePicker。
40
+ for (var _i = 0, _arr = ['TextArea', 'Password', 'Search', 'Group', 'RangePicker']; _i < _arr.length; _i++) {
41
+ var key = _arr[_i];
42
+ if (Control[key] && Preview[key]) Wrapped[key] = wrap(Control[key], Preview[key]);
43
+ }
44
+ return Wrapped;
45
+ };
46
+ var _iterator = _createForOfIteratorHelper(Object.keys(previews).filter(function (name) {
47
+ return components[name];
48
+ })),
49
+ _step;
50
+ try {
51
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
52
+ var name = _step.value;
53
+ result[name] = wrap(components[name], previews[name]);
54
+ }
55
+ // ArrayTable 阅读态保留动态列的标题和显隐状态。@author nokecy
56
+ } catch (err) {
57
+ _iterator.e(err);
58
+ } finally {
59
+ _iterator.f();
60
+ }
61
+ if (components.ArrayTable) result.ArrayTable = withReadingArrayTable(components.ArrayTable);
62
+ return result;
63
+ }
@@ -0,0 +1 @@
1
+ export declare function hoistStatics<T, S>(target: T, source: S): T & S;
@@ -0,0 +1,31 @@
1
+ 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; } } }; }
2
+ 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); }
3
+ 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; }
4
+ /**
5
+ * 把被包装组件的静态成员(如 Input.TextArea、Select.Option)带到包装后的组件上,
6
+ * 等价于 hoist-non-react-statics,但不新增依赖。React 自有的静态属性不拷贝。
7
+ * @author nokecy
8
+ */
9
+ var REACT_STATICS = new Set(['$$typeof', 'render', 'defaultProps', 'displayName', 'propTypes', 'contextType', 'contextTypes', 'childContextTypes', 'getDefaultProps', 'getDerivedStateFromProps', 'getDerivedStateFromError', 'mixins', 'type', 'compare', 'length', 'name', 'prototype', 'caller', 'callee', 'arguments', 'arity']);
10
+ export function hoistStatics(target, source) {
11
+ var _iterator = _createForOfIteratorHelper(Reflect.ownKeys(source)),
12
+ _step;
13
+ try {
14
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
15
+ var key = _step.value;
16
+ if (REACT_STATICS.has(key)) continue;
17
+ var descriptor = Object.getOwnPropertyDescriptor(source, key);
18
+ if (!descriptor) continue;
19
+ try {
20
+ Object.defineProperty(target, key, descriptor);
21
+ } catch (_unused) {
22
+ // 个别只读属性无法重定义,跳过即可。
23
+ }
24
+ }
25
+ } catch (err) {
26
+ _iterator.e(err);
27
+ } finally {
28
+ _iterator.f();
29
+ }
30
+ return target;
31
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 阅读态控件:不可编辑时展示名称/文本而不是禁用的输入框,继承整张表单的禁用状态。
3
+ * 动态表单入口 `withReadingFields` 按字段的 disabled/readOnly 状态切换阅读展示,并保留 ArrayTable 动态列。
4
+ * @author nokecy
5
+ */
6
+ export * as ReadPrettyControls from './controls';
7
+ export { withReadingFields } from './formily';
8
+ export { withReadingArrayTable } from './arrayTable';
9
+ export { DecimalInput, DecimalPicker } from './decimal';
10
+ export { flattenOptions, selectedLabels } from './values';
11
+ export { normalizeSelectValue, selectCode, selectLabel } from './selectValue';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 阅读态控件:不可编辑时展示名称/文本而不是禁用的输入框,继承整张表单的禁用状态。
3
+ * 动态表单入口 `withReadingFields` 按字段的 disabled/readOnly 状态切换阅读展示,并保留 ArrayTable 动态列。
4
+ * @author nokecy
5
+ */
6
+ import * as _ReadPrettyControls from "./controls";
7
+ export { _ReadPrettyControls as ReadPrettyControls };
8
+ export { withReadingFields } from "./formily";
9
+ export { withReadingArrayTable } from "./arrayTable";
10
+ export { DecimalInput, DecimalPicker } from "./decimal";
11
+ export { flattenOptions, selectedLabels } from "./values";
12
+ export { normalizeSelectValue, selectCode, selectLabel } from "./selectValue";
@@ -0,0 +1,7 @@
1
+ import { type ReactNode } from 'react';
2
+ /** 提取选择项的标量编码,兼容嵌套 labelInValue;保留编码 0 和显式空字符串选项。@author nokecy */
3
+ export declare function selectCode(value: unknown, depth?: number): string | number | undefined;
4
+ /** 标签只输出可渲染内容;选择项对象取名称后再回落编码,避免 React 对象子节点异常。@author nokecy */
5
+ export declare function selectLabel(value: unknown, depth?: number): ReactNode;
6
+ /** 单选、多选与阅读态共用同一值形状;名称缺省时保留组件按选项查名称的行为。@author nokecy */
7
+ export declare function normalizeSelectValue(value: unknown, labelInValue?: boolean): any;
@@ -0,0 +1,53 @@
1
+ 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; }
2
+ 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; }
3
+ 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; }
4
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
5
+ 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); }
6
+ 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); }
7
+ import { isValidElement } from 'react';
8
+
9
+ /** 提取选择项的标量编码,兼容嵌套 labelInValue;保留编码 0 和显式空字符串选项。@author nokecy */
10
+ export function selectCode(value) {
11
+ var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
12
+ if (typeof value === 'string') return value;
13
+ if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;
14
+ if (!value || _typeof(value) !== 'object' || depth >= 8 || /*#__PURE__*/isValidElement(value)) return undefined;
15
+ return selectCode(value.value, depth + 1);
16
+ }
17
+
18
+ /** 标签只输出可渲染内容;选择项对象取名称后再回落编码,避免 React 对象子节点异常。@author nokecy */
19
+ export function selectLabel(value) {
20
+ var _selectLabel;
21
+ var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
22
+ if (value == null || typeof value === 'boolean' || depth >= 8) return undefined;
23
+ if (typeof value === 'string' || typeof value === 'number' || /*#__PURE__*/isValidElement(value)) return value;
24
+ if (Array.isArray(value)) return value.map(function (item) {
25
+ return selectLabel(item, depth + 1);
26
+ });
27
+ if (_typeof(value) !== 'object') return undefined;
28
+ var item = value;
29
+ return (_selectLabel = selectLabel(item.label, depth + 1)) !== null && _selectLabel !== void 0 ? _selectLabel : selectLabel(item.value, depth + 1);
30
+ }
31
+
32
+ /** 单选、多选与阅读态共用同一值形状;名称缺省时保留组件按选项查名称的行为。@author nokecy */
33
+ export function normalizeSelectValue(value, labelInValue) {
34
+ var _selectLabel2;
35
+ if (Array.isArray(value)) return value.map(function (item) {
36
+ return normalizeSelectValue(item, labelInValue);
37
+ }).filter(function (item) {
38
+ return item !== undefined;
39
+ });
40
+ var code = selectCode(value);
41
+ if (code === undefined) return undefined;
42
+ if (!labelInValue) return code;
43
+ if (!value || _typeof(value) !== 'object') return {
44
+ value: code
45
+ };
46
+ var item = value;
47
+ var label = (_selectLabel2 = selectLabel(item.label)) !== null && _selectLabel2 !== void 0 ? _selectLabel2 : _typeof(item.value) === 'object' ? selectLabel(item.value) : undefined;
48
+ return _objectSpread({
49
+ value: code
50
+ }, label !== undefined ? {
51
+ label: label
52
+ } : {});
53
+ }
@@ -0,0 +1,4 @@
1
+ /** 阅读态选择项展开,保留分组内选项及自定义字段名。@author nokecy */
2
+ export declare function flattenOptions(options?: any[], fieldNames?: any): any[];
3
+ /** 保留0和空选项标签;有 labelInValue 时优先使用已加载的名称。@author nokecy */
4
+ export declare function selectedLabels(value: any, options: any[], labelInValue?: boolean): any;
@@ -0,0 +1,43 @@
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
+ import { normalizeSelectValue, selectLabel } from "./selectValue";
3
+
4
+ /** 阅读态选择项展开,保留分组内选项及自定义字段名。@author nokecy */
5
+ export function flattenOptions() {
6
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7
+ var fieldNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
8
+ var _ref = fieldNames || {},
9
+ _ref$label = _ref.label,
10
+ label = _ref$label === void 0 ? 'label' : _ref$label,
11
+ _ref$value = _ref.value,
12
+ value = _ref$value === void 0 ? 'value' : _ref$value,
13
+ _ref$options = _ref.options,
14
+ children = _ref$options === void 0 ? 'options' : _ref$options;
15
+ return options.flatMap(function (option) {
16
+ return _typeof(option) === 'object' && option !== null ? option[children] ? flattenOptions(option[children], fieldNames) : [{
17
+ value: option[value],
18
+ label: option[label]
19
+ }] : [{
20
+ value: option,
21
+ label: option
22
+ }];
23
+ });
24
+ }
25
+
26
+ /** 保留0和空选项标签;有 labelInValue 时优先使用已加载的名称。@author nokecy */
27
+ export function selectedLabels(value, options, labelInValue) {
28
+ if (value == null || value === '' || Array.isArray(value) && !value.length) return '—';
29
+ var normalized = labelInValue ? normalizeSelectValue(value, true) : value;
30
+ var values = Array.isArray(normalized) ? normalized : normalized == null ? [] : [normalized];
31
+ if (!values.length) return '—';
32
+ var labels = values.map(function (item) {
33
+ var _ref2, _selectLabel, _options$find, _item$label;
34
+ var raw = labelInValue ? item.value : item;
35
+ return (_ref2 = (_selectLabel = selectLabel((_options$find = options.find(function (option) {
36
+ return option.value === raw;
37
+ })) === null || _options$find === void 0 ? void 0 : _options$find.label)) !== null && _selectLabel !== void 0 ? _selectLabel : selectLabel(labelInValue ? (_item$label = item.label) !== null && _item$label !== void 0 ? _item$label : raw : raw)) !== null && _ref2 !== void 0 ? _ref2 : '—';
38
+ });
39
+ // 选项标签可以是React节点,交由调用组件按顺序渲染。
40
+ return labels.flatMap(function (label, index) {
41
+ return index ? ['、', label] : [label];
42
+ });
43
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 把 Blob 存成本地文件。
3
+ *
4
+ * @author nokecy
5
+ */
6
+ export declare const saveAs: (blob: Blob, filename: string) => void;