@nokecy/qc-ui 1.1.72 → 1.1.74

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 (47) hide show
  1. package/dist/cjs/adapters/pagedApiAdapter.d.ts +2 -0
  2. package/dist/cjs/ag-grid-plus/ag-gridPlus.js +5 -3
  3. package/dist/cjs/ag-grid-plus/interface.d.ts +6 -0
  4. package/dist/cjs/ag-grid-plus/utils/aggregation.d.ts +6 -5
  5. package/dist/cjs/ag-grid-plus/utils/aggregation.js +60 -50
  6. package/dist/cjs/ag-grid-plus/utils/columnProcessors.d.ts +2 -1
  7. package/dist/cjs/ag-grid-plus/utils/columnProcessors.js +5 -2
  8. package/dist/cjs/ag-grid-plus/utils/valueEnumColor.d.ts +17 -0
  9. package/dist/cjs/ag-grid-plus/utils/valueEnumColor.js +99 -0
  10. package/dist/cjs/dialogSelect/index.d.ts +29 -0
  11. package/dist/cjs/dialogSelect/index.js +152 -103
  12. package/dist/cjs/dialogSelect/index.less +39 -0
  13. package/dist/cjs/draggableModal/index.js +12 -8
  14. package/dist/cjs/index.d.ts +5 -0
  15. package/dist/cjs/index.js +123 -1
  16. package/dist/cjs/toolBar/index.d.ts +1 -0
  17. package/dist/cjs/toolBar/index.js +44 -10
  18. package/dist/cjs/toolBar/index.less +25 -7
  19. package/dist/cjs/utils/businessDecimal.d.ts +11 -0
  20. package/dist/cjs/utils/businessDecimal.js +53 -0
  21. package/dist/cjs/utils/contrast.d.ts +40 -0
  22. package/dist/cjs/utils/contrast.js +153 -0
  23. package/dist/esm/adapters/pagedApiAdapter.d.ts +2 -0
  24. package/dist/esm/ag-grid-plus/ag-gridPlus.js +5 -3
  25. package/dist/esm/ag-grid-plus/interface.d.ts +6 -0
  26. package/dist/esm/ag-grid-plus/utils/aggregation.d.ts +6 -5
  27. package/dist/esm/ag-grid-plus/utils/aggregation.js +60 -47
  28. package/dist/esm/ag-grid-plus/utils/columnProcessors.d.ts +2 -1
  29. package/dist/esm/ag-grid-plus/utils/columnProcessors.js +5 -2
  30. package/dist/esm/ag-grid-plus/utils/valueEnumColor.d.ts +17 -0
  31. package/dist/esm/ag-grid-plus/utils/valueEnumColor.js +95 -0
  32. package/dist/esm/dialogSelect/index.d.ts +29 -0
  33. package/dist/esm/dialogSelect/index.js +155 -105
  34. package/dist/esm/dialogSelect/index.less +39 -0
  35. package/dist/esm/draggableModal/index.js +12 -8
  36. package/dist/esm/index.d.ts +5 -0
  37. package/dist/esm/index.js +3 -0
  38. package/dist/esm/toolBar/index.d.ts +1 -0
  39. package/dist/esm/toolBar/index.js +43 -10
  40. package/dist/esm/toolBar/index.less +25 -7
  41. package/dist/esm/utils/businessDecimal.d.ts +11 -0
  42. package/dist/esm/utils/businessDecimal.js +47 -0
  43. package/dist/esm/utils/contrast.d.ts +40 -0
  44. package/dist/esm/utils/contrast.js +141 -0
  45. package/dist/umd/qc-ui.min.css +1 -1
  46. package/dist/umd/qc-ui.min.js +1 -1
  47. package/package.json +2 -1
@@ -1,35 +1,69 @@
1
1
  "use strict";
2
2
 
3
+ 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
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.default = void 0;
7
- var _react = _interopRequireDefault(require("react"));
8
+ var _react = _interopRequireWildcard(require("react"));
8
9
  var _antd = require("antd");
9
10
  require("./index.less");
10
- var _excluded = ["children", "className", "extra", "style", "renderContent", "getTargetContainer"];
11
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ var _excluded = ["children", "className", "extra", "identity", "banner", "style", "renderContent", "getTargetContainer"];
12
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
13
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
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; }
13
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
+ /** 详情、表单共用工具栏:按实际操作元素统一留出间距,宽度不足时换行。@author nokecy */
14
17
  var ToolBar = function ToolBar(props) {
15
18
  var children = props.children,
16
19
  className = props.className,
17
20
  extra = props.extra,
21
+ identity = props.identity,
22
+ banner = props.banner,
18
23
  style = props.style,
19
24
  renderContent = props.renderContent,
20
25
  getTargetContainer = props.getTargetContainer,
21
26
  restProps = _objectWithoutProperties(props, _excluded);
27
+ var _theme$useToken = _antd.theme.useToken(),
28
+ token = _theme$useToken.token; // 单据操作栏跟随宿主主题。@author nokecy
29
+ var barRef = (0, _react.useRef)(null);
30
+ // @author nokecy:KeepAlive 内容区独立滚动,吸顶应相对其视口,避免定位到应用顶栏下面。
31
+ var defaultTarget = (0, _react.useCallback)(function () {
32
+ var _barRef$current$paren, _barRef$current;
33
+ var parent = (_barRef$current$paren = (_barRef$current = barRef.current) === null || _barRef$current === void 0 ? void 0 : _barRef$current.parentElement) !== null && _barRef$current$paren !== void 0 ? _barRef$current$paren : null;
34
+ while (parent) {
35
+ if (/auto|scroll/.test(getComputedStyle(parent).overflowY)) return parent;
36
+ parent = parent.parentElement;
37
+ }
38
+ return window;
39
+ }, []);
22
40
  return /*#__PURE__*/_react.default.createElement(_antd.Affix, {
23
41
  offsetTop: 2,
24
42
  style: style,
25
43
  offsetBottom: 2,
26
- target: getTargetContainer
44
+ target: getTargetContainer || defaultTarget
27
45
  }, /*#__PURE__*/_react.default.createElement("div", {
28
- className: "antd-tool-bar"
29
- }, /*#__PURE__*/_react.default.createElement("div", {
30
- className: "antd-tool-bar-left".trim()
31
- }, /*#__PURE__*/_react.default.createElement(_antd.Space, null, extra)), /*#__PURE__*/_react.default.createElement("div", {
32
- className: "antd-tool-bar-right".trim()
33
- }, /*#__PURE__*/_react.default.createElement(_antd.Space, null, children))));
46
+ ref: barRef,
47
+ className: "antd-tool-bar",
48
+ style: {
49
+ backgroundColor: token.colorBgContainer,
50
+ color: token.colorText,
51
+ borderBlockStartColor: token.colorBorderSecondary,
52
+ gap: token.marginXS,
53
+ paddingBlock: token.paddingXXS
54
+ }
55
+ }, banner && /*#__PURE__*/_react.default.createElement("div", {
56
+ className: "antd-tool-bar-banner"
57
+ }, banner), /*#__PURE__*/_react.default.createElement("div", {
58
+ className: "antd-tool-bar-left",
59
+ style: {
60
+ gap: token.marginXS
61
+ }
62
+ }, extra, identity), /*#__PURE__*/_react.default.createElement("div", {
63
+ className: "antd-tool-bar-right",
64
+ style: {
65
+ gap: token.marginXS
66
+ }
67
+ }, children)));
34
68
  };
35
69
  var _default = exports.default = ToolBar;
@@ -1,25 +1,43 @@
1
1
  .antd-tool-bar {
2
2
  display: flex;
3
+ flex-wrap: wrap;
3
4
  align-items: center;
4
5
  box-sizing: border-box;
5
6
  width: 100%;
6
- color: rgba(0, 0, 0, 0.88);
7
7
  line-height: 40px;
8
- background-color: rgba(255, 255, 255);
9
- -webkit-backdrop-filter: blur(8px);
8
+ backdrop-filter: blur(8px);
10
9
  backdrop-filter: blur(8px);
11
10
  transition: all 0.2s ease 0s;
12
11
  inset-inline-end: 0;
13
12
  padding-inline: 16px;
14
13
  padding-block: 0;
15
- border-block-start: 1px solid rgba(5, 5, 5, 0.06);
14
+ // 颜色由组件读取主题 token;子区域继承正文色。
15
+ border-block-start: 1px solid;
16
+ }
17
+
18
+ .antd-tool-bar-banner {
19
+ flex: 1 0 100%;
20
+ min-width: 0;
21
+ line-height: normal;
16
22
  }
17
23
 
18
24
  .antd-tool-bar-left {
19
- flex: 1;
20
- color: rgba(0, 0, 0, 0.88);
25
+ flex: 1 0 auto;
26
+ color: inherit;
27
+ }
28
+
29
+ .antd-tool-bar-right {
30
+ margin-inline-start: auto;
31
+ justify-content: flex-end;
32
+ color: inherit;
21
33
  }
22
34
 
35
+ /* 直接排列组件输出的按钮,React Fragment 内的按钮也获得相同间距。@author nokecy */
36
+ .antd-tool-bar-left,
23
37
  .antd-tool-bar-right {
24
- color: rgba(0, 0, 0, 0.88);
38
+ display: flex;
39
+ flex-wrap: wrap;
40
+ align-items: center;
41
+ min-width: 0;
42
+ max-width: 100%;
25
43
  }
@@ -0,0 +1,11 @@
1
+ import Decimal from 'decimal.js';
2
+ /** 业务值保留十进制文本,运算使用十进制库;整型标识和时间不经过此入口。@author nokecy */
3
+ export declare const BusinessDecimal: typeof Decimal;
4
+ export type DecimalValue = string | number | Decimal | null | undefined;
5
+ export declare const decimal: (value: DecimalValue) => Decimal;
6
+ export declare const decimalText: (value: DecimalValue) => string;
7
+ export declare const nonNegativeDecimal: (value: DecimalValue) => string;
8
+ export declare const roundDecimal: (value: DecimalValue, places: number) => string;
9
+ export declare const sumDecimals: (values: DecimalValue[]) => string;
10
+ /** 指定取位规则显示,千分位直接处理文本,不转换为 JavaScript number。@author nokecy */
11
+ export declare const formatDecimal: (value: DecimalValue, places?: number, minimumPlaces?: number) => string;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.sumDecimals = exports.roundDecimal = exports.nonNegativeDecimal = exports.formatDecimal = exports.decimalText = exports.decimal = exports.BusinessDecimal = void 0;
7
+ var _decimal = _interopRequireDefault(require("decimal.js"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
10
+ 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."); }
11
+ 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); }
12
+ 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; }
13
+ 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; } }
14
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
15
+ /** 业务值保留十进制文本,运算使用十进制库;整型标识和时间不经过此入口。@author nokecy */
16
+ var BusinessDecimal = exports.BusinessDecimal = _decimal.default.clone({
17
+ precision: 64,
18
+ rounding: _decimal.default.ROUND_HALF_UP,
19
+ toExpNeg: -64,
20
+ toExpPos: 64
21
+ });
22
+ var decimal = exports.decimal = function decimal(value) {
23
+ return new BusinessDecimal(value == null || value === '' ? '0' : value);
24
+ };
25
+ var decimalText = exports.decimalText = function decimalText(value) {
26
+ return decimal(value).toFixed();
27
+ };
28
+ var nonNegativeDecimal = exports.nonNegativeDecimal = function nonNegativeDecimal(value) {
29
+ return BusinessDecimal.max(0, decimal(value)).toFixed();
30
+ };
31
+ var roundDecimal = exports.roundDecimal = function roundDecimal(value, places) {
32
+ return decimal(value).toDecimalPlaces(places).toFixed();
33
+ };
34
+ var sumDecimals = exports.sumDecimals = function sumDecimals(values) {
35
+ return values.reduce(function (sum, value) {
36
+ return sum.plus(decimal(value));
37
+ }, decimal('0')).toFixed();
38
+ };
39
+
40
+ /** 指定取位规则显示,千分位直接处理文本,不转换为 JavaScript number。@author nokecy */
41
+ var formatDecimal = exports.formatDecimal = function formatDecimal(value) {
42
+ var places = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 6;
43
+ var minimumPlaces = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
44
+ if (value == null || value === '') return '';
45
+ var _decimal$toFixed$spli = decimal(value).toFixed(places).split('.'),
46
+ _decimal$toFixed$spli2 = _slicedToArray(_decimal$toFixed$spli, 2),
47
+ integer = _decimal$toFixed$spli2[0],
48
+ _decimal$toFixed$spli3 = _decimal$toFixed$spli2[1],
49
+ fraction = _decimal$toFixed$spli3 === void 0 ? '' : _decimal$toFixed$spli3;
50
+ while (fraction.length > minimumPlaces && fraction.endsWith('0')) fraction = fraction.slice(0, -1);
51
+ integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
52
+ return fraction ? "".concat(integer, ".").concat(fraction) : integer;
53
+ };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * 对比度计算与「够读的主色」派生。
3
+ *
4
+ * 背景:品牌绿 #00b96b 落在白底上只有 2.58:1,而正文文字要 4.5:1、非文本要 3:1(WCAG 2.1)。
5
+ * antd 从它派生的最深一档 colorPrimaryActive 也只有 3.90:1——够非文本,够不到文字。
6
+ * 所以菜单选中态、行内操作按钮这些「用主色写字」的地方,靠 antd 自带档位解决不了。
7
+ *
8
+ * 这里按色相不变、只压明度的方式派生出刚好达标的一档:绿还是那个绿,但读得清。
9
+ * 写成纯函数而不是写死一个色值,是因为四个客户各有各的主色,写死就只对信诚成立。
10
+ *
11
+ * 验收方法沿用登录页复核那套:实测计算,不看源码想当然。
12
+ *
13
+ * @author nokecy
14
+ */
15
+ /** hex -> [r, g, b],每项 0~255。 */
16
+ export declare function toRgb(hex: string): [number, number, number];
17
+ /** WCAG 相对亮度。 */
18
+ export declare function relativeLuminance(hex: string): number;
19
+ /** WCAG 对比度,1 ~ 21。 */
20
+ export declare function contrastRatio(a: string, b: string): number;
21
+ /** hex -> [h(0~360), s(0~1), l(0~1)]。 */
22
+ export declare function toHsl(hex: string): [number, number, number];
23
+ /** [h, s, l] -> hex。 */
24
+ export declare function fromHsl(h: number, s: number, l: number): string;
25
+ /**
26
+ * 压暗到刚好满足对比度要求的一档,色相与饱和度保持不变。
27
+ *
28
+ * @param hex 起始色(通常是品牌主色)
29
+ * @param against 要压在什么底色上,默认白底
30
+ * @param min 目标对比度,正文 4.5、非文本 3
31
+ */
32
+ export declare function darkenUntilContrast(hex: string, { against, min }?: {
33
+ against?: string | undefined;
34
+ min?: number | undefined;
35
+ }): string;
36
+ /** 深色表面上的文字保持色相,提亮至正文对比度。@author nokecy */
37
+ export declare function lightenUntilContrast(hex: string, { against, min }?: {
38
+ against?: string | undefined;
39
+ min?: number | undefined;
40
+ }): string;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.contrastRatio = contrastRatio;
7
+ exports.darkenUntilContrast = darkenUntilContrast;
8
+ exports.fromHsl = fromHsl;
9
+ exports.lightenUntilContrast = lightenUntilContrast;
10
+ exports.relativeLuminance = relativeLuminance;
11
+ exports.toHsl = toHsl;
12
+ exports.toRgb = toRgb;
13
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
14
+ 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."); }
15
+ 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); }
16
+ 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; }
17
+ 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; } }
18
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
19
+ /**
20
+ * 对比度计算与「够读的主色」派生。
21
+ *
22
+ * 背景:品牌绿 #00b96b 落在白底上只有 2.58:1,而正文文字要 4.5:1、非文本要 3:1(WCAG 2.1)。
23
+ * antd 从它派生的最深一档 colorPrimaryActive 也只有 3.90:1——够非文本,够不到文字。
24
+ * 所以菜单选中态、行内操作按钮这些「用主色写字」的地方,靠 antd 自带档位解决不了。
25
+ *
26
+ * 这里按色相不变、只压明度的方式派生出刚好达标的一档:绿还是那个绿,但读得清。
27
+ * 写成纯函数而不是写死一个色值,是因为四个客户各有各的主色,写死就只对信诚成立。
28
+ *
29
+ * 验收方法沿用登录页复核那套:实测计算,不看源码想当然。
30
+ *
31
+ * @author nokecy
32
+ */
33
+
34
+ var WHITE = '#ffffff';
35
+ var expand = function expand(hex) {
36
+ var raw = hex.replace('#', '');
37
+ return raw.length === 3 ? raw.split('').map(function (c) {
38
+ return c + c;
39
+ }).join('') : raw;
40
+ };
41
+
42
+ /** hex -> [r, g, b],每项 0~255。 */
43
+ function toRgb(hex) {
44
+ var value = parseInt(expand(hex), 16);
45
+ return [value >> 16 & 255, value >> 8 & 255, value & 255];
46
+ }
47
+ var channelLuminance = function channelLuminance(channel) {
48
+ var v = channel / 255;
49
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
50
+ };
51
+
52
+ /** WCAG 相对亮度。 */
53
+ function relativeLuminance(hex) {
54
+ var _toRgb = toRgb(hex),
55
+ _toRgb2 = _slicedToArray(_toRgb, 3),
56
+ r = _toRgb2[0],
57
+ g = _toRgb2[1],
58
+ b = _toRgb2[2];
59
+ return 0.2126 * channelLuminance(r) + 0.7152 * channelLuminance(g) + 0.0722 * channelLuminance(b);
60
+ }
61
+
62
+ /** WCAG 对比度,1 ~ 21。 */
63
+ function contrastRatio(a, b) {
64
+ var _sort = [relativeLuminance(a), relativeLuminance(b)].sort(function (x, y) {
65
+ return y - x;
66
+ }),
67
+ _sort2 = _slicedToArray(_sort, 2),
68
+ lighter = _sort2[0],
69
+ darker = _sort2[1];
70
+ return (lighter + 0.05) / (darker + 0.05);
71
+ }
72
+
73
+ /** hex -> [h(0~360), s(0~1), l(0~1)]。 */
74
+ function toHsl(hex) {
75
+ var _ref = toRgb(hex).map(function (v) {
76
+ return v / 255;
77
+ }),
78
+ _ref2 = _slicedToArray(_ref, 3),
79
+ r = _ref2[0],
80
+ g = _ref2[1],
81
+ b = _ref2[2];
82
+ var max = Math.max(r, g, b);
83
+ var min = Math.min(r, g, b);
84
+ var l = (max + min) / 2;
85
+ var d = max - min;
86
+ if (d === 0) return [0, 0, l];
87
+ var s = d / (1 - Math.abs(2 * l - 1));
88
+ var h;
89
+ if (max === r) h = 60 * ((g - b) / d % 6);else if (max === g) h = 60 * ((b - r) / d + 2);else h = 60 * ((r - g) / d + 4);
90
+ return [(h + 360) % 360, s, l];
91
+ }
92
+
93
+ /** [h, s, l] -> hex。 */
94
+ function fromHsl(h, s, l) {
95
+ var c = (1 - Math.abs(2 * l - 1)) * s;
96
+ var x = c * (1 - Math.abs(h / 60 % 2 - 1));
97
+ var m = l - c / 2;
98
+ var table = [[c, x, 0], [x, c, 0], [0, c, x], [0, x, c], [x, 0, c], [c, 0, x]];
99
+ var _table$Math$min = _slicedToArray(table[Math.min(5, Math.floor((h % 360 + 360) % 360 / 60))], 3),
100
+ r = _table$Math$min[0],
101
+ g = _table$Math$min[1],
102
+ b = _table$Math$min[2];
103
+ var toHex = function toHex(v) {
104
+ return Math.round((v + m) * 255).toString(16).padStart(2, '0');
105
+ };
106
+ return "#".concat(toHex(r)).concat(toHex(g)).concat(toHex(b));
107
+ }
108
+
109
+ /**
110
+ * 压暗到刚好满足对比度要求的一档,色相与饱和度保持不变。
111
+ *
112
+ * @param hex 起始色(通常是品牌主色)
113
+ * @param against 要压在什么底色上,默认白底
114
+ * @param min 目标对比度,正文 4.5、非文本 3
115
+ */
116
+ function darkenUntilContrast(hex) {
117
+ var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
118
+ _ref3$against = _ref3.against,
119
+ against = _ref3$against === void 0 ? WHITE : _ref3$against,
120
+ _ref3$min = _ref3.min,
121
+ min = _ref3$min === void 0 ? 4.5 : _ref3$min;
122
+ var _toHsl = toHsl(hex),
123
+ _toHsl2 = _slicedToArray(_toHsl, 3),
124
+ h = _toHsl2[0],
125
+ s = _toHsl2[1],
126
+ l = _toHsl2[2];
127
+ if (contrastRatio(hex, against) >= min) return hex;
128
+ for (var step = 1; step <= 100; step++) {
129
+ var candidate = fromHsl(h, s, Math.max(0, l - step / 100));
130
+ if (contrastRatio(candidate, against) >= min) return candidate;
131
+ }
132
+ return '#000000';
133
+ }
134
+
135
+ /** 深色表面上的文字保持色相,提亮至正文对比度。@author nokecy */
136
+ function lightenUntilContrast(hex) {
137
+ var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
138
+ _ref4$against = _ref4.against,
139
+ against = _ref4$against === void 0 ? '#141414' : _ref4$against,
140
+ _ref4$min = _ref4.min,
141
+ min = _ref4$min === void 0 ? 4.5 : _ref4$min;
142
+ var _toHsl3 = toHsl(hex),
143
+ _toHsl4 = _slicedToArray(_toHsl3, 3),
144
+ h = _toHsl4[0],
145
+ s = _toHsl4[1],
146
+ l = _toHsl4[2];
147
+ if (contrastRatio(hex, against) >= min) return hex;
148
+ for (var step = 1; step <= 100; step++) {
149
+ var candidate = fromHsl(h, s, Math.min(1, l + step / 100));
150
+ if (contrastRatio(candidate, against) >= min) return candidate;
151
+ }
152
+ return '#ffffff';
153
+ }
@@ -13,6 +13,8 @@ export interface GenericPagedQuery {
13
13
  filter?: string;
14
14
  /** 排序表达式,如 "name asc"。 */
15
15
  sorter?: string;
16
+ /** 表格请求的原始筛选对象(请求函数的第三个参数);需要把它放进后端请求体的适配器才读取。 */
17
+ record?: any;
16
18
  }
17
19
  /** 分页 API 适配器。 */
18
20
  export interface PagedApiAdapter {
@@ -1,4 +1,4 @@
1
- var _excluded = ["style", "loading", "params", "request", "dataSource", "treeKeyName", "treeParentName", "rowData", "gridRef", "headerTitle", "toolBarRender", "search", "hideTool", "onGridReady", "gridKey", "children", "defaultSearchExpand", "overlayNoRowsTemplateText", "queryDefaultRows", "onSelectedRowsChange", "emptyState", "accessible", "enableClickSelection", "rowSelection", "useNativeTreeFilter", "entityType"];
1
+ var _excluded = ["style", "loading", "params", "request", "dataSource", "treeKeyName", "treeParentName", "rowData", "gridRef", "headerTitle", "toolBarRender", "search", "hideTool", "onGridReady", "gridKey", "children", "defaultSearchExpand", "overlayNoRowsTemplateText", "queryDefaultRows", "onSelectedRowsChange", "emptyState", "accessible", "enableClickSelection", "rowSelection", "useNativeTreeFilter", "entityType", "valueEnumContrast"];
2
2
  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); }
3
3
  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); }
4
4
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
@@ -109,6 +109,8 @@ function AgGridPlus(props) {
109
109
  _props$useNativeTreeF = props.useNativeTreeFilter,
110
110
  useNativeTreeFilter = _props$useNativeTreeF === void 0 ? false : _props$useNativeTreeF,
111
111
  entityType = props.entityType,
112
+ _props$valueEnumContr = props.valueEnumContrast,
113
+ valueEnumContrast = _props$valueEnumContr === void 0 ? false : _props$valueEnumContr,
112
114
  rest = _objectWithoutProperties(props, _excluded);
113
115
  var _useGridPlusColumnSta = useGridPlusColumnState(),
114
116
  onSaveColumnState = _useGridPlusColumnSta.onSaveColumnState,
@@ -462,7 +464,7 @@ function AgGridPlus(props) {
462
464
  if (col.valueEnum && Array.isArray(col.valueEnum)) {
463
465
  // 枚举列渲染只走一处实现,见 columnProcessors.processEnumColumn
464
466
  // (命中上色、未命中交给 col.enumFallbackRenderer,都没配则回原始码)
465
- return processEnumColumn(col, dataType);
467
+ return processEnumColumn(col, dataType, valueEnumContrast ? token.colorBgContainer : undefined);
466
468
  }
467
469
  if (col.type || typeof col.cellRenderer == "string") {
468
470
  return mergeInferredColumnType(col, dataType);
@@ -568,7 +570,7 @@ function AgGridPlus(props) {
568
570
  });
569
571
  }
570
572
  return cols;
571
- }, [React.Children.count(children), props.columnDefs, extensibleColumns, gridKey, entityType, hostEntityExtensions, typeInferenceRow]);
573
+ }, [React.Children.count(children), props.columnDefs, extensibleColumns, gridKey, entityType, hostEntityExtensions, typeInferenceRow, valueEnumContrast ? token.colorBgContainer : undefined]);
572
574
 
573
575
  // 稳定化 gridParams 和 sortColumn 的引用(深比较,内容不变即复用旧引用)
574
576
  var stableGridParams = useDeepCompareStable(gridParams);
@@ -7,6 +7,12 @@ interface GridRef {
7
7
  onRefresh: () => void;
8
8
  }
9
9
  interface GridProps extends AgGridReactProps {
10
+ /**
11
+ * 为 true 时,`valueEnum[].color` 按当前主题底色自动收成够读(WCAG 正文 4.5:1)的 CSS 色:
12
+ * 语义档名(success/warning…)与预设名(cyan/pink…)换成真实色值,过浅的 hex 压暗(深色主题则提亮),
13
+ * 缺省色写成 `inherit`。默认 false:color 按 CSS 原样输出,保持既有行为。@author nokecy
14
+ */
15
+ valueEnumContrast?: boolean;
10
16
  hideTool?: boolean;
11
17
  style?: CSSProperties;
12
18
  params?: any;
@@ -5,7 +5,7 @@
5
5
  export interface CalculationColumnConfig {
6
6
  field: string;
7
7
  calculateType: 'sum' | 'avg' | 'standardDeviation';
8
- transactionAmount: number;
8
+ transactionAmount?: number;
9
9
  formatWithCommas?: boolean;
10
10
  cellRenderer?: any;
11
11
  }
@@ -18,9 +18,10 @@ export interface CalculationColumnDefinition {
18
18
  }
19
19
  /** 分组表头只是展示结构;原生固定合计行要读取所有叶子数值列。@author nokecy */
20
20
  export declare const getCalculationColumns: (columns: CalculationColumnDefinition[]) => CalculationColumnConfig[];
21
+ /** 精确数值字符串参与汇总;空值、非法文本及非有限数字跳过。@author nokecy */
21
22
  export declare const isValidNumber: (value: any) => boolean;
22
- export declare const sumField: (field: string, data: any[]) => number;
23
- export declare const avgField: (field: string, data: any[]) => number;
24
- export declare const stdDevField: (field: string, data: any[]) => number;
25
- export declare const formatWithCommas: (value: number) => string;
23
+ export declare const sumField: (field: string, data: any[]) => number | string;
24
+ export declare const avgField: (field: string, data: any[]) => number | string;
25
+ export declare const stdDevField: (field: string, data: any[]) => number | string;
26
+ export declare const formatWithCommas: (value: number | string, places?: number) => string;
26
27
  export declare const computeAggregationRow: (calcColFields: CalculationColumnConfig[], data: any[]) => any[];
@@ -1,4 +1,11 @@
1
- import _, { uniqueId } from 'lodash';
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 _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 _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; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { uniqueId } from 'lodash';
8
+ import { BusinessDecimal as Exact } from "../../utils/businessDecimal";
2
9
 
3
10
  /**
4
11
  * AG-Grid 底部汇总聚合纯函数(从 ag-gridPlus.tsx 抽出,行为原样)。
@@ -8,63 +15,68 @@ import _, { uniqueId } from 'lodash';
8
15
  /** 分组表头只是展示结构;原生固定合计行要读取所有叶子数值列。@author nokecy */
9
16
  export var getCalculationColumns = function getCalculationColumns(columns) {
10
17
  return columns.flatMap(function (column) {
11
- var _column$transactionAm;
12
18
  if (column.children) return getCalculationColumns(column.children);
13
19
  if (!column.field || !column.calculateType) return [];
14
20
  return [{
15
21
  field: column.field,
16
22
  calculateType: column.calculateType,
17
- transactionAmount: (_column$transactionAm = column.transactionAmount) !== null && _column$transactionAm !== void 0 ? _column$transactionAm : 2,
23
+ transactionAmount: column.transactionAmount,
18
24
  formatWithCommas: column.formatWithCommas
19
25
  }];
20
26
  });
21
27
  };
28
+
29
+ /** 精确数值字符串参与汇总;空值、非法文本及非有限数字跳过。@author nokecy */
22
30
  export var isValidNumber = function isValidNumber(value) {
23
- return typeof value === 'number' && !isNaN(value);
31
+ return typeof value === 'number' && Number.isFinite(value) || typeof value === 'string' && /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(value);
24
32
  };
25
- export var sumField = function sumField(field, data) {
26
- return _.sumBy(data, function (cur) {
27
- if (cur && isValidNumber(cur[field])) {
28
- return cur[field];
29
- }
30
- return 0;
33
+ var valuesOf = function valuesOf(field, data) {
34
+ return data.filter(function (row) {
35
+ return row && isValidNumber(row[field]);
36
+ }).map(function (row) {
37
+ return row[field];
31
38
  });
32
39
  };
40
+ var resultOf = function resultOf(value, values) {
41
+ return values.some(function (value) {
42
+ return typeof value === 'string';
43
+ }) ? value.toFixed() : value.toNumber();
44
+ };
45
+ export var sumField = function sumField(field, data) {
46
+ var values = valuesOf(field, data);
47
+ return resultOf(values.reduce(function (sum, value) {
48
+ return sum.plus(value);
49
+ }, new Exact(0)), values);
50
+ };
33
51
  export var avgField = function avgField(field, data) {
34
- // 分子分母口径统一为「有效数字」,避免除零得 NaN
35
- var validValues = data.filter(function (cur) {
36
- return cur && isValidNumber(cur[field]);
37
- });
38
- if (validValues.length === 0) return 0;
39
- var sum = _.sumBy(validValues, function (cur) {
40
- return cur[field];
41
- });
42
- return sum / validValues.length;
52
+ var values = valuesOf(field, data);
53
+ return values.length ? resultOf(new Exact(sumField(field, data)).div(values.length), values) : 0;
43
54
  };
44
-
45
- // 注:现存口径小瑕疵——mean 的分母用有效值数,sumField 对全部行求和(无效计 0);
46
- // variance 遍历全部行且判定用 !== undefined/null(非 isValidNumber)。首刀只保持原行为,不修正。
47
55
  export var stdDevField = function stdDevField(field, data) {
48
- var validValues = data.filter(function (cur) {
49
- return isValidNumber(cur[field]);
50
- });
51
- var count = validValues.length;
52
- if (count === 0) return 0;
53
- var mean = sumField(field, data) / count;
54
- var variance = _.sumBy(data, function (cur) {
55
- if (cur && cur[field] !== undefined && cur[field] !== null) {
56
- var diff = cur[field] - mean;
57
- return diff * diff;
58
- }
59
- return 0;
60
- }) / count;
61
- return Math.sqrt(variance);
56
+ var values = valuesOf(field, data);
57
+ if (!values.length) return 0;
58
+ var mean = new Exact(sumField(field, data)).div(values.length);
59
+ var variance = values.reduce(function (sum, value) {
60
+ return sum.plus(new Exact(value).minus(mean).pow(2));
61
+ }, new Exact(0)).div(values.length);
62
+ return resultOf(variance.sqrt(), values);
62
63
  };
63
64
  export var formatWithCommas = function formatWithCommas(value) {
64
- return (value / 1).toLocaleString(undefined, {
65
- minimumFractionDigits: 2,
66
- maximumFractionDigits: 2
67
- });
65
+ var places = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
66
+ var _Exact$toFixed$split = new Exact(value).toFixed(places).split('.'),
67
+ _Exact$toFixed$split2 = _slicedToArray(_Exact$toFixed$split, 2),
68
+ whole = _Exact$toFixed$split2[0],
69
+ fraction = _Exact$toFixed$split2[1];
70
+ return whole.replace(/\B(?=(\d{3})+(?!\d))/g, ',') + (fraction === undefined ? '' : '.' + fraction);
71
+ };
72
+ var roundedResult = function roundedResult(value, places) {
73
+ return typeof value === 'string' ? new Exact(value).toDecimalPlaces(places).toFixed() : new Exact(value).toDecimalPlaces(places).toNumber();
74
+ };
75
+
76
+ /** 精确接口默认保留十位小数;数值型兼容原有两位规则。@author nokecy */
77
+ var precisionOf = function precisionOf(column, value) {
78
+ var _column$transactionAm;
79
+ return (_column$transactionAm = column.transactionAmount) !== null && _column$transactionAm !== void 0 ? _column$transactionAm : typeof value === 'string' ? 10 : 2;
68
80
  };
69
81
 
70
82
  // sum 求和 / avg 平均值 / standardDeviation 标准差
@@ -78,21 +90,22 @@ export var computeAggregationRow = function computeAggregationRow(calcColFields,
78
90
  switch (i.calculateType) {
79
91
  case 'sum':
80
92
  {
81
- var sumPrecision = typeof i.transactionAmount === 'number' ? i.transactionAmount : 2;
82
- var sumValue = Number(sumField(i.field, data).toFixed(sumPrecision));
83
- calculateData[i.field] = i.formatWithCommas ? formatWithCommas(sumValue) : sumValue;
93
+ var total = sumField(i.field, data);
94
+ var sumPrecision = precisionOf(i, total);
95
+ var sumValue = roundedResult(total, sumPrecision);
96
+ calculateData[i.field] = i.formatWithCommas ? formatWithCommas(sumValue, sumPrecision) : sumValue;
84
97
  break;
85
98
  }
86
99
  case 'avg':
87
100
  {
88
- var avgPrecision = typeof i.transactionAmount === 'number' ? i.transactionAmount : 2;
89
- calculateData[i.field] = Number(avgField(i.field, data).toFixed(avgPrecision));
101
+ var average = avgField(i.field, data);
102
+ calculateData[i.field] = roundedResult(average, precisionOf(i, average));
90
103
  break;
91
104
  }
92
105
  case 'standardDeviation':
93
106
  {
94
- var stdPrecision = typeof i.transactionAmount === 'number' ? i.transactionAmount : 2;
95
- calculateData[i.field] = Number(stdDevField(i.field, data).toFixed(stdPrecision));
107
+ var deviation = stdDevField(i.field, data);
108
+ calculateData[i.field] = roundedResult(deviation, precisionOf(i, deviation));
96
109
  break;
97
110
  }
98
111
  default:
@@ -83,10 +83,11 @@ export declare function mergeInferredColumnType<T extends object>(column: T, dat
83
83
  *
84
84
  * @param col 原始列定义
85
85
  * @param dataType 数据类型(决定是否右对齐,见 {@link toColumnType})
86
+ * @param background 单元格底色(hex)。传入则把枚举颜色压/提到够读的对比度;不传则 color 原样输出
86
87
  * @returns 处理后的列定义
87
88
  * @author nokecy
88
89
  */
89
- export declare function processEnumColumn(col: any, dataType?: DataTypeInference): ColDef;
90
+ export declare function processEnumColumn(col: any, dataType?: DataTypeInference, background?: string): ColDef;
90
91
  /**
91
92
  * 处理省略列定义
92
93
  *