@nokecy/qc-ui 1.1.73 → 1.1.75

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 (81) 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.js +8 -14
  5. package/dist/cjs/ag-grid-plus/utils/columnProcessors.d.ts +2 -1
  6. package/dist/cjs/ag-grid-plus/utils/columnProcessors.js +5 -2
  7. package/dist/cjs/ag-grid-plus/utils/valueEnumColor.d.ts +17 -0
  8. package/dist/cjs/ag-grid-plus/utils/valueEnumColor.js +99 -0
  9. package/dist/cjs/dialogSelect/index.d.ts +31 -2
  10. package/dist/cjs/dialogSelect/index.js +209 -105
  11. package/dist/cjs/dialogSelect/index.less +39 -0
  12. package/dist/cjs/draggableModal/index.js +12 -8
  13. package/dist/cjs/entitySelect/index.d.ts +57 -0
  14. package/dist/cjs/entitySelect/index.js +172 -0
  15. package/dist/cjs/index.d.ts +8 -0
  16. package/dist/cjs/index.js +143 -1
  17. package/dist/cjs/readPretty/arrayTable.d.ts +6 -0
  18. package/dist/cjs/readPretty/arrayTable.js +156 -0
  19. package/dist/cjs/readPretty/controls.d.ts +11 -0
  20. package/dist/cjs/readPretty/controls.js +68 -0
  21. package/dist/cjs/readPretty/decimal.d.ts +4 -0
  22. package/dist/cjs/readPretty/decimal.js +28 -0
  23. package/dist/cjs/readPretty/formily.d.ts +2 -0
  24. package/dist/cjs/readPretty/formily.js +71 -0
  25. package/dist/cjs/readPretty/hoistStatics.d.ts +1 -0
  26. package/dist/cjs/readPretty/hoistStatics.js +37 -0
  27. package/dist/cjs/readPretty/index.d.ts +11 -0
  28. package/dist/cjs/readPretty/index.js +70 -0
  29. package/dist/cjs/readPretty/selectValue.d.ts +7 -0
  30. package/dist/cjs/readPretty/selectValue.js +60 -0
  31. package/dist/cjs/readPretty/values.d.ts +4 -0
  32. package/dist/cjs/readPretty/values.js +49 -0
  33. package/dist/cjs/toolBar/index.d.ts +1 -0
  34. package/dist/cjs/toolBar/index.js +44 -10
  35. package/dist/cjs/toolBar/index.less +25 -7
  36. package/dist/cjs/utils/businessDecimal.d.ts +11 -0
  37. package/dist/cjs/utils/businessDecimal.js +53 -0
  38. package/dist/cjs/utils/contrast.d.ts +40 -0
  39. package/dist/cjs/utils/contrast.js +153 -0
  40. package/dist/esm/adapters/pagedApiAdapter.d.ts +2 -0
  41. package/dist/esm/ag-grid-plus/ag-gridPlus.js +5 -3
  42. package/dist/esm/ag-grid-plus/interface.d.ts +6 -0
  43. package/dist/esm/ag-grid-plus/utils/aggregation.js +1 -5
  44. package/dist/esm/ag-grid-plus/utils/columnProcessors.d.ts +2 -1
  45. package/dist/esm/ag-grid-plus/utils/columnProcessors.js +5 -2
  46. package/dist/esm/ag-grid-plus/utils/valueEnumColor.d.ts +17 -0
  47. package/dist/esm/ag-grid-plus/utils/valueEnumColor.js +95 -0
  48. package/dist/esm/dialogSelect/index.d.ts +31 -2
  49. package/dist/esm/dialogSelect/index.js +211 -106
  50. package/dist/esm/dialogSelect/index.less +39 -0
  51. package/dist/esm/draggableModal/index.js +12 -8
  52. package/dist/esm/entitySelect/index.d.ts +57 -0
  53. package/dist/esm/entitySelect/index.js +164 -0
  54. package/dist/esm/index.d.ts +8 -0
  55. package/dist/esm/index.js +5 -0
  56. package/dist/esm/readPretty/arrayTable.d.ts +6 -0
  57. package/dist/esm/readPretty/arrayTable.js +147 -0
  58. package/dist/esm/readPretty/controls.d.ts +11 -0
  59. package/dist/esm/readPretty/controls.js +62 -0
  60. package/dist/esm/readPretty/decimal.d.ts +4 -0
  61. package/dist/esm/readPretty/decimal.js +22 -0
  62. package/dist/esm/readPretty/formily.d.ts +2 -0
  63. package/dist/esm/readPretty/formily.js +63 -0
  64. package/dist/esm/readPretty/hoistStatics.d.ts +1 -0
  65. package/dist/esm/readPretty/hoistStatics.js +31 -0
  66. package/dist/esm/readPretty/index.d.ts +11 -0
  67. package/dist/esm/readPretty/index.js +12 -0
  68. package/dist/esm/readPretty/selectValue.d.ts +7 -0
  69. package/dist/esm/readPretty/selectValue.js +53 -0
  70. package/dist/esm/readPretty/values.d.ts +4 -0
  71. package/dist/esm/readPretty/values.js +43 -0
  72. package/dist/esm/toolBar/index.d.ts +1 -0
  73. package/dist/esm/toolBar/index.js +43 -10
  74. package/dist/esm/toolBar/index.less +25 -7
  75. package/dist/esm/utils/businessDecimal.d.ts +11 -0
  76. package/dist/esm/utils/businessDecimal.js +47 -0
  77. package/dist/esm/utils/contrast.d.ts +40 -0
  78. package/dist/esm/utils/contrast.js +141 -0
  79. package/dist/umd/qc-ui.min.css +1 -1
  80. package/dist/umd/qc-ui.min.js +1 -1
  81. package/package.json +1 -1
@@ -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
+ }
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
2
  import './index.less';
3
+ /** 详情、表单共用工具栏:按实际操作元素统一留出间距,宽度不足时换行。@author nokecy */
3
4
  declare const ToolBar: (props: any) => React.JSX.Element;
4
5
  export default ToolBar;
@@ -1,28 +1,61 @@
1
- var _excluded = ["children", "className", "extra", "style", "renderContent", "getTargetContainer"];
1
+ var _excluded = ["children", "className", "extra", "identity", "banner", "style", "renderContent", "getTargetContainer"];
2
2
  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; }
3
3
  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; }
4
- import React from 'react';
5
- import { Affix, Space } from 'antd';
4
+ import React, { useCallback, useRef } from 'react';
5
+ import { Affix, theme } from 'antd';
6
6
  import "./index.less";
7
+
8
+ /** 详情、表单共用工具栏:按实际操作元素统一留出间距,宽度不足时换行。@author nokecy */
7
9
  var ToolBar = function ToolBar(props) {
8
10
  var children = props.children,
9
11
  className = props.className,
10
12
  extra = props.extra,
13
+ identity = props.identity,
14
+ banner = props.banner,
11
15
  style = props.style,
12
16
  renderContent = props.renderContent,
13
17
  getTargetContainer = props.getTargetContainer,
14
18
  restProps = _objectWithoutProperties(props, _excluded);
19
+ var _theme$useToken = theme.useToken(),
20
+ token = _theme$useToken.token; // 单据操作栏跟随宿主主题。@author nokecy
21
+ var barRef = useRef(null);
22
+ // @author nokecy:KeepAlive 内容区独立滚动,吸顶应相对其视口,避免定位到应用顶栏下面。
23
+ var defaultTarget = useCallback(function () {
24
+ var _barRef$current$paren, _barRef$current;
25
+ 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;
26
+ while (parent) {
27
+ if (/auto|scroll/.test(getComputedStyle(parent).overflowY)) return parent;
28
+ parent = parent.parentElement;
29
+ }
30
+ return window;
31
+ }, []);
15
32
  return /*#__PURE__*/React.createElement(Affix, {
16
33
  offsetTop: 2,
17
34
  style: style,
18
35
  offsetBottom: 2,
19
- target: getTargetContainer
36
+ target: getTargetContainer || defaultTarget
20
37
  }, /*#__PURE__*/React.createElement("div", {
21
- className: "antd-tool-bar"
22
- }, /*#__PURE__*/React.createElement("div", {
23
- className: "antd-tool-bar-left".trim()
24
- }, /*#__PURE__*/React.createElement(Space, null, extra)), /*#__PURE__*/React.createElement("div", {
25
- className: "antd-tool-bar-right".trim()
26
- }, /*#__PURE__*/React.createElement(Space, null, children))));
38
+ ref: barRef,
39
+ className: "antd-tool-bar",
40
+ style: {
41
+ backgroundColor: token.colorBgContainer,
42
+ color: token.colorText,
43
+ borderBlockStartColor: token.colorBorderSecondary,
44
+ gap: token.marginXS,
45
+ paddingBlock: token.paddingXXS
46
+ }
47
+ }, banner && /*#__PURE__*/React.createElement("div", {
48
+ className: "antd-tool-bar-banner"
49
+ }, banner), /*#__PURE__*/React.createElement("div", {
50
+ className: "antd-tool-bar-left",
51
+ style: {
52
+ gap: token.marginXS
53
+ }
54
+ }, extra, identity), /*#__PURE__*/React.createElement("div", {
55
+ className: "antd-tool-bar-right",
56
+ style: {
57
+ gap: token.marginXS
58
+ }
59
+ }, children)));
27
60
  };
28
61
  export 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,47 @@
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 Decimal from 'decimal.js';
8
+
9
+ /** 业务值保留十进制文本,运算使用十进制库;整型标识和时间不经过此入口。@author nokecy */
10
+ export var BusinessDecimal = Decimal.clone({
11
+ precision: 64,
12
+ rounding: Decimal.ROUND_HALF_UP,
13
+ toExpNeg: -64,
14
+ toExpPos: 64
15
+ });
16
+ export var decimal = function decimal(value) {
17
+ return new BusinessDecimal(value == null || value === '' ? '0' : value);
18
+ };
19
+ export var decimalText = function decimalText(value) {
20
+ return decimal(value).toFixed();
21
+ };
22
+ export var nonNegativeDecimal = function nonNegativeDecimal(value) {
23
+ return BusinessDecimal.max(0, decimal(value)).toFixed();
24
+ };
25
+ export var roundDecimal = function roundDecimal(value, places) {
26
+ return decimal(value).toDecimalPlaces(places).toFixed();
27
+ };
28
+ export var sumDecimals = function sumDecimals(values) {
29
+ return values.reduce(function (sum, value) {
30
+ return sum.plus(decimal(value));
31
+ }, decimal('0')).toFixed();
32
+ };
33
+
34
+ /** 指定取位规则显示,千分位直接处理文本,不转换为 JavaScript number。@author nokecy */
35
+ export var formatDecimal = function formatDecimal(value) {
36
+ var places = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 6;
37
+ var minimumPlaces = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
38
+ if (value == null || value === '') return '';
39
+ var _decimal$toFixed$spli = decimal(value).toFixed(places).split('.'),
40
+ _decimal$toFixed$spli2 = _slicedToArray(_decimal$toFixed$spli, 2),
41
+ integer = _decimal$toFixed$spli2[0],
42
+ _decimal$toFixed$spli3 = _decimal$toFixed$spli2[1],
43
+ fraction = _decimal$toFixed$spli3 === void 0 ? '' : _decimal$toFixed$spli3;
44
+ while (fraction.length > minimumPlaces && fraction.endsWith('0')) fraction = fraction.slice(0, -1);
45
+ integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
46
+ return fraction ? "".concat(integer, ".").concat(fraction) : integer;
47
+ };
@@ -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,141 @@
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
+ /**
8
+ * 对比度计算与「够读的主色」派生。
9
+ *
10
+ * 背景:品牌绿 #00b96b 落在白底上只有 2.58:1,而正文文字要 4.5:1、非文本要 3:1(WCAG 2.1)。
11
+ * antd 从它派生的最深一档 colorPrimaryActive 也只有 3.90:1——够非文本,够不到文字。
12
+ * 所以菜单选中态、行内操作按钮这些「用主色写字」的地方,靠 antd 自带档位解决不了。
13
+ *
14
+ * 这里按色相不变、只压明度的方式派生出刚好达标的一档:绿还是那个绿,但读得清。
15
+ * 写成纯函数而不是写死一个色值,是因为四个客户各有各的主色,写死就只对信诚成立。
16
+ *
17
+ * 验收方法沿用登录页复核那套:实测计算,不看源码想当然。
18
+ *
19
+ * @author nokecy
20
+ */
21
+
22
+ var WHITE = '#ffffff';
23
+ var expand = function expand(hex) {
24
+ var raw = hex.replace('#', '');
25
+ return raw.length === 3 ? raw.split('').map(function (c) {
26
+ return c + c;
27
+ }).join('') : raw;
28
+ };
29
+
30
+ /** hex -> [r, g, b],每项 0~255。 */
31
+ export function toRgb(hex) {
32
+ var value = parseInt(expand(hex), 16);
33
+ return [value >> 16 & 255, value >> 8 & 255, value & 255];
34
+ }
35
+ var channelLuminance = function channelLuminance(channel) {
36
+ var v = channel / 255;
37
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
38
+ };
39
+
40
+ /** WCAG 相对亮度。 */
41
+ export function relativeLuminance(hex) {
42
+ var _toRgb = toRgb(hex),
43
+ _toRgb2 = _slicedToArray(_toRgb, 3),
44
+ r = _toRgb2[0],
45
+ g = _toRgb2[1],
46
+ b = _toRgb2[2];
47
+ return 0.2126 * channelLuminance(r) + 0.7152 * channelLuminance(g) + 0.0722 * channelLuminance(b);
48
+ }
49
+
50
+ /** WCAG 对比度,1 ~ 21。 */
51
+ export function contrastRatio(a, b) {
52
+ var _sort = [relativeLuminance(a), relativeLuminance(b)].sort(function (x, y) {
53
+ return y - x;
54
+ }),
55
+ _sort2 = _slicedToArray(_sort, 2),
56
+ lighter = _sort2[0],
57
+ darker = _sort2[1];
58
+ return (lighter + 0.05) / (darker + 0.05);
59
+ }
60
+
61
+ /** hex -> [h(0~360), s(0~1), l(0~1)]。 */
62
+ export function toHsl(hex) {
63
+ var _ref = toRgb(hex).map(function (v) {
64
+ return v / 255;
65
+ }),
66
+ _ref2 = _slicedToArray(_ref, 3),
67
+ r = _ref2[0],
68
+ g = _ref2[1],
69
+ b = _ref2[2];
70
+ var max = Math.max(r, g, b);
71
+ var min = Math.min(r, g, b);
72
+ var l = (max + min) / 2;
73
+ var d = max - min;
74
+ if (d === 0) return [0, 0, l];
75
+ var s = d / (1 - Math.abs(2 * l - 1));
76
+ var h;
77
+ 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);
78
+ return [(h + 360) % 360, s, l];
79
+ }
80
+
81
+ /** [h, s, l] -> hex。 */
82
+ export function fromHsl(h, s, l) {
83
+ var c = (1 - Math.abs(2 * l - 1)) * s;
84
+ var x = c * (1 - Math.abs(h / 60 % 2 - 1));
85
+ var m = l - c / 2;
86
+ var table = [[c, x, 0], [x, c, 0], [0, c, x], [0, x, c], [x, 0, c], [c, 0, x]];
87
+ var _table$Math$min = _slicedToArray(table[Math.min(5, Math.floor((h % 360 + 360) % 360 / 60))], 3),
88
+ r = _table$Math$min[0],
89
+ g = _table$Math$min[1],
90
+ b = _table$Math$min[2];
91
+ var toHex = function toHex(v) {
92
+ return Math.round((v + m) * 255).toString(16).padStart(2, '0');
93
+ };
94
+ return "#".concat(toHex(r)).concat(toHex(g)).concat(toHex(b));
95
+ }
96
+
97
+ /**
98
+ * 压暗到刚好满足对比度要求的一档,色相与饱和度保持不变。
99
+ *
100
+ * @param hex 起始色(通常是品牌主色)
101
+ * @param against 要压在什么底色上,默认白底
102
+ * @param min 目标对比度,正文 4.5、非文本 3
103
+ */
104
+ export function darkenUntilContrast(hex) {
105
+ var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
106
+ _ref3$against = _ref3.against,
107
+ against = _ref3$against === void 0 ? WHITE : _ref3$against,
108
+ _ref3$min = _ref3.min,
109
+ min = _ref3$min === void 0 ? 4.5 : _ref3$min;
110
+ var _toHsl = toHsl(hex),
111
+ _toHsl2 = _slicedToArray(_toHsl, 3),
112
+ h = _toHsl2[0],
113
+ s = _toHsl2[1],
114
+ l = _toHsl2[2];
115
+ if (contrastRatio(hex, against) >= min) return hex;
116
+ for (var step = 1; step <= 100; step++) {
117
+ var candidate = fromHsl(h, s, Math.max(0, l - step / 100));
118
+ if (contrastRatio(candidate, against) >= min) return candidate;
119
+ }
120
+ return '#000000';
121
+ }
122
+
123
+ /** 深色表面上的文字保持色相,提亮至正文对比度。@author nokecy */
124
+ export function lightenUntilContrast(hex) {
125
+ var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
126
+ _ref4$against = _ref4.against,
127
+ against = _ref4$against === void 0 ? '#141414' : _ref4$against,
128
+ _ref4$min = _ref4.min,
129
+ min = _ref4$min === void 0 ? 4.5 : _ref4$min;
130
+ var _toHsl3 = toHsl(hex),
131
+ _toHsl4 = _slicedToArray(_toHsl3, 3),
132
+ h = _toHsl4[0],
133
+ s = _toHsl4[1],
134
+ l = _toHsl4[2];
135
+ if (contrastRatio(hex, against) >= min) return hex;
136
+ for (var step = 1; step <= 100; step++) {
137
+ var candidate = fromHsl(h, s, Math.min(1, l + step / 100));
138
+ if (contrastRatio(candidate, against) >= min) return candidate;
139
+ }
140
+ return '#ffffff';
141
+ }