@4399ywkf/design 2.0.0 → 2.1.0

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.
@@ -0,0 +1,25 @@
1
+ import React, { ReactNode } from 'react';
2
+ export interface MaxTokenSliderProps {
3
+ /** 初始 Token 数(非受控模式) */
4
+ defaultValue?: number;
5
+ /** 当前 Token 数(受控模式) */
6
+ value?: number;
7
+ /** 值变化回调 */
8
+ onChange?: (value: number) => void;
9
+ /** 是否禁用 */
10
+ disabled?: boolean;
11
+ /**
12
+ * 预设刻度档位(token 数组),决定 Slider 的可选刻度和范围。
13
+ * 第一项为最小值,最后一项为最大值。
14
+ * @default [0, 4096, 8192, 16384, 32768, 65536, 200000, 1048576, 2097152]
15
+ */
16
+ presets?: number[];
17
+ /** InputNumber 的步进值 @default 4096 */
18
+ inputStep?: number;
19
+ /** 最小值对应的展示文案(tooltip),设为 false 则不做特殊处理 @default "无限制" */
20
+ minLabel?: ReactNode | false;
21
+ /** 自定义 tooltip 格式化,覆盖默认逻辑 */
22
+ tooltipFormatter?: (token: number) => ReactNode;
23
+ }
24
+ declare const MaxTokenSlider: React.NamedExoticComponent<MaxTokenSliderProps>;
25
+ export default MaxTokenSlider;
@@ -0,0 +1,148 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
4
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
5
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
6
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
7
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
+ 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); }
9
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
10
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
11
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
12
+ import React, { memo, useMemo } from 'react';
13
+ import { InputNumber, Slider } from 'antd';
14
+ import { useControllableValue } from 'ahooks';
15
+ import { useMaxTokenSliderStyles } from "./style";
16
+ var KIBI = 1024;
17
+ var toExponent = function toExponent(num) {
18
+ return Math.log2(num);
19
+ };
20
+ var fromExponent = function fromExponent(exp) {
21
+ return Math.round(Math.pow(2, exp));
22
+ };
23
+ var toTokenValue = function toTokenValue(exp) {
24
+ return Math.round(Math.pow(2, exp) * KIBI);
25
+ };
26
+
27
+ /**
28
+ * token 数量 → 人类可读标签
29
+ * 如:4096 → "4K",200000 → "200k",1048576 → "1M"
30
+ */
31
+ var formatTokenLabel = function formatTokenLabel(token) {
32
+ if (token === 0) return '0';
33
+ if (token < 1000) return "".concat(token);
34
+ if (token < 100 * KIBI) return "".concat(Math.round(token / KIBI), "K");
35
+ if (token < KIBI * KIBI) return "".concat(Math.round(token / 1000), "k");
36
+ return "".concat(Math.round(token / (KIBI * KIBI)), "M");
37
+ };
38
+
39
+ /** 预设刻度集合:覆盖 0 ~ 2M 的常用档位 */
40
+ var DEFAULT_PRESETS = [0, 4096, 8192, 16384, 32768, 65536, 200000, 1048576, 2097152];
41
+ var DEFAULT_INPUT_STEP = 4 * KIBI;
42
+
43
+ /**
44
+ * 根据 presets 生成 Slider marks(对数刻度)和边界
45
+ * 返回 { marks, minExp, maxExp }
46
+ */
47
+ var buildMarksFromPresets = function buildMarksFromPresets(presets) {
48
+ var _sorted$, _sorted;
49
+ var sorted = _toConsumableArray(presets).sort(function (a, b) {
50
+ return a - b;
51
+ });
52
+ var minToken = (_sorted$ = sorted[0]) !== null && _sorted$ !== void 0 ? _sorted$ : 0;
53
+ var maxToken = (_sorted = sorted[sorted.length - 1]) !== null && _sorted !== void 0 ? _sorted : 2097152;
54
+ var safeMin = Math.max(minToken, 0);
55
+ var safeMax = Math.max(maxToken, KIBI);
56
+ var minExp = toExponent(safeMin <= 0 ? 2 : safeMin / KIBI);
57
+ var maxExp = toExponent(safeMax / KIBI);
58
+ var marks = {};
59
+ var _iterator = _createForOfIteratorHelper(sorted),
60
+ _step;
61
+ try {
62
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
63
+ var _token = _step.value;
64
+ var exp = _token <= 0 ? minExp : toExponent(_token / KIBI);
65
+ marks[exp] = formatTokenLabel(_token);
66
+ }
67
+ } catch (err) {
68
+ _iterator.e(err);
69
+ } finally {
70
+ _iterator.f();
71
+ }
72
+ return {
73
+ marks: marks,
74
+ minExp: minExp,
75
+ maxExp: maxExp
76
+ };
77
+ };
78
+ var MaxTokenSlider = /*#__PURE__*/memo(function (props) {
79
+ var disabled = props.disabled,
80
+ _props$presets = props.presets,
81
+ presets = _props$presets === void 0 ? DEFAULT_PRESETS : _props$presets,
82
+ _props$inputStep = props.inputStep,
83
+ inputStep = _props$inputStep === void 0 ? DEFAULT_INPUT_STEP : _props$inputStep,
84
+ _props$minLabel = props.minLabel,
85
+ minLabel = _props$minLabel === void 0 ? '无限制' : _props$minLabel,
86
+ tooltipFormatter = props.tooltipFormatter;
87
+ var _useMaxTokenSliderSty = useMaxTokenSliderStyles(),
88
+ styles = _useMaxTokenSliderSty.styles;
89
+ var _useControllableValue = useControllableValue(props, {
90
+ defaultValue: 0
91
+ }),
92
+ _useControllableValue2 = _slicedToArray(_useControllableValue, 2),
93
+ token = _useControllableValue2[0],
94
+ setToken = _useControllableValue2[1];
95
+ var _useMemo = useMemo(function () {
96
+ return buildMarksFromPresets(presets);
97
+ }, [presets]),
98
+ marks = _useMemo.marks,
99
+ minExp = _useMemo.minExp,
100
+ maxExp = _useMemo.maxExp;
101
+ var powValue = useMemo(function () {
102
+ if (!token || token <= 0) return minExp;
103
+ return toExponent(token / KIBI);
104
+ }, [token, minExp]);
105
+ var defaultTooltipFormatter = useMemo(function () {
106
+ return function (exp) {
107
+ if (typeof exp === 'undefined') return;
108
+ if (exp <= minExp && minLabel !== false) return minLabel;
109
+ var realToken = fromExponent(exp) * KIBI;
110
+ if (tooltipFormatter) return tooltipFormatter(realToken);
111
+ return formatTokenLabel(realToken);
112
+ };
113
+ }, [minExp, minLabel, tooltipFormatter]);
114
+ var handleSliderChange = function handleSliderChange(value) {
115
+ setToken(value <= minExp ? 0 : toTokenValue(value));
116
+ };
117
+ var handleInputChange = function handleInputChange(value) {
118
+ if (value === null || value === undefined) return;
119
+ setToken(Math.round(value));
120
+ };
121
+ return /*#__PURE__*/React.createElement("div", {
122
+ className: styles.root
123
+ }, /*#__PURE__*/React.createElement("div", {
124
+ className: styles.sliderWrapper
125
+ }, /*#__PURE__*/React.createElement(Slider, {
126
+ className: styles.slider,
127
+ disabled: disabled,
128
+ marks: marks,
129
+ max: maxExp,
130
+ min: minExp,
131
+ onChange: handleSliderChange,
132
+ step: null,
133
+ tooltip: {
134
+ formatter: defaultTooltipFormatter
135
+ },
136
+ value: powValue
137
+ })), /*#__PURE__*/React.createElement(InputNumber, {
138
+ className: styles.inputNumber,
139
+ changeOnWheel: true,
140
+ disabled: disabled,
141
+ min: 0,
142
+ max: presets[presets.length - 1],
143
+ onChange: handleInputChange,
144
+ step: inputStep,
145
+ value: token
146
+ }));
147
+ });
148
+ export default MaxTokenSlider;
@@ -0,0 +1,6 @@
1
+ export declare const useMaxTokenSliderStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
2
+ root: import("antd-style").SerializedStyles;
3
+ sliderWrapper: import("antd-style").SerializedStyles;
4
+ slider: import("antd-style").SerializedStyles;
5
+ inputNumber: import("antd-style").SerializedStyles;
6
+ }>;
@@ -0,0 +1,14 @@
1
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { createStyles } from 'antd-style';
4
+ export var useMaxTokenSliderStyles = createStyles(function (_ref) {
5
+ var css = _ref.css,
6
+ token = _ref.token,
7
+ prefixCls = _ref.prefixCls;
8
+ return {
9
+ root: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n align-items: center;\n gap: 12px;\n "]))),
10
+ sliderWrapper: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n flex: 1;\n min-width: 0;\n "]))),
11
+ slider: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n margin: 10px 0 18px;\n\n .", "-slider-mark-text {\n font-size: 12px;\n color: ", ";\n white-space: nowrap;\n }\n "])), prefixCls, token.colorTextSecondary),
12
+ inputNumber: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n width: 110px;\n flex-shrink: 0;\n\n .", "-input-number-input {\n text-align: center;\n }\n "])), prefixCls)
13
+ };
14
+ });
@@ -626,7 +626,7 @@ var WaterfallVirtual = function WaterfallVirtual(props) {
626
626
  className: "waterfall-virtual-container ".concat(className),
627
627
  onScroll: handleScroll,
628
628
  style: style
629
- }, /*#__PURE__*/React.createElement("div", {
629
+ }, components === null || components === void 0 ? void 0 : components.Header, /*#__PURE__*/React.createElement("div", {
630
630
  className: "waterfall-virtual-list",
631
631
  style: listStyle
632
632
  }, renderList.map(function (item) {
@@ -1,4 +1,4 @@
1
- import { CSSProperties } from 'react';
1
+ import { CSSProperties } from "react";
2
2
  export interface IVirtualWaterFallProps {
3
3
  gap: number;
4
4
  column: number;
@@ -28,6 +28,7 @@ export interface IVirtualWaterFallProps {
28
28
  atTopThreshold?: number;
29
29
  components?: {
30
30
  Footer?: React.ReactNode;
31
+ Header?: React.ReactNode;
31
32
  };
32
33
  }
33
34
  export interface IItemRenderProps {
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
+ export type * from './MaxTokenSlider';
2
3
  export type * from './RichText';
3
4
  export type * from './Table';
4
5
  export type * from './WaterfallVirtual';
5
6
  export declare const Button: React.LazyExoticComponent<React.NamedExoticComponent<import("./Button").ButtonProps>>;
7
+ export declare const MaxTokenSlider: React.LazyExoticComponent<React.NamedExoticComponent<import("./MaxTokenSlider").MaxTokenSliderProps>>;
6
8
  export declare const WaterfallVirtual: React.LazyExoticComponent<React.MemoExoticComponent<(props: import("./WaterfallVirtual/types").IVirtualWaterFallProps) => React.JSX.Element>>;
7
9
  export declare const Table: React.LazyExoticComponent<import("./Table").RefTable>;
8
10
  export declare const RichText: React.LazyExoticComponent<React.FC<import("./RichText").PromptInputProps>>;
package/dist/index.js CHANGED
@@ -6,6 +6,9 @@ import React from 'react';
6
6
  export var Button = /*#__PURE__*/React.lazy(function () {
7
7
  return import("./Button");
8
8
  });
9
+ export var MaxTokenSlider = /*#__PURE__*/React.lazy(function () {
10
+ return import("./MaxTokenSlider");
11
+ });
9
12
  export var WaterfallVirtual = /*#__PURE__*/React.lazy(function () {
10
13
  return import("./WaterfallVirtual");
11
14
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4399ywkf/design",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "4399ywkf Design React UI Library.",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",
@@ -25,12 +25,12 @@
25
25
  "lint:es": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\"",
26
26
  "prepare": "husky install && dumi setup",
27
27
  "prepublishOnly": "father doctor && npm run build",
28
- "postpublish": "git push && git push --tags",
29
28
  "pub": "npm run pub:check && npm run build && npm publish --ignore-scripts",
30
29
  "pub:check": "father doctor && node -e \"const p=require('./package.json');const d=require('child_process').execSync('npm view '+p.name+' version 2>/dev/null').toString().trim();if(d===p.version){console.error('\\x1b[31m✖ 版本 '+p.version+' 已存在,请先升级版本号\\x1b[0m');process.exit(1)}else{console.log('\\x1b[32m✔ 版本检查通过: '+p.version+'\\x1b[0m')}\"",
31
- "pub:patch": "npm version patch --no-git-tag-version && npm run pub",
32
- "pub:minor": "npm version minor --no-git-tag-version && npm run pub",
33
30
  "pub:major": "npm version major --no-git-tag-version && npm run pub",
31
+ "pub:minor": "npm version minor --no-git-tag-version && npm run pub",
32
+ "pub:patch": "npm version patch --no-git-tag-version && npm run pub",
33
+ "postpublish": "git push && git push --tags",
34
34
  "release": "npm run build && changeset publish",
35
35
  "start": "npm run dev",
36
36
  "test:build": "rm -rf dist docs-dist && pnpm build:ci && echo '✅ 构建测试通过'"