one-design-next 0.0.80 → 0.0.82

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.
@@ -23,7 +23,7 @@ export interface ClarifyDockSpec {
23
23
  answeredText?: string;
24
24
  /**
25
25
  * 单题选项上限(含「其他」),默认 {@link CLARIFY_DOCK_MAX_OPTIONS}。
26
- * 超过截断业务选项;有「其他」时优先保留末位。硬顶 26(AZ)。
26
+ * 超过截断业务选项;有「其他」时优先保留末位。硬顶 26(126)。
27
27
  */
28
28
  maxOptions?: number;
29
29
  }
@@ -215,16 +215,16 @@ var MULTI_UNSELECTED_ACTIVE_FILL = 'rgba(33, 34, 38, 0.08)';
215
215
  */
216
216
  export var CLARIFY_DOCK_MAX_OPTIONS = 5;
217
217
 
218
- /** 徽标字母硬顶 AZ,防止异常大值。 */
219
- var OPTION_LETTER_HARD_CAP = 26;
218
+ /** 徽标序号硬顶 126,防止异常大值。 */
219
+ var OPTION_INDEX_HARD_CAP = 26;
220
220
  function resolveMaxOptions(maxOptions) {
221
221
  var raw = maxOptions !== null && maxOptions !== void 0 ? maxOptions : CLARIFY_DOCK_MAX_OPTIONS;
222
222
  if (!Number.isFinite(raw)) return CLARIFY_DOCK_MAX_OPTIONS;
223
- return Math.max(1, Math.min(Math.floor(raw), OPTION_LETTER_HARD_CAP));
223
+ return Math.max(1, Math.min(Math.floor(raw), OPTION_INDEX_HARD_CAP));
224
224
  }
225
- function optionLetter(idx) {
226
- if (idx < 0 || idx >= OPTION_LETTER_HARD_CAP) return '';
227
- return String.fromCharCode(65 + idx);
225
+ function optionIndexLabel(idx) {
226
+ if (idx < 0 || idx >= OPTION_INDEX_HARD_CAP) return '';
227
+ return String(idx + 1);
228
228
  }
229
229
  export function ClarifyDockPanel(_ref2) {
230
230
  var msgId = _ref2.msgId,
@@ -248,24 +248,28 @@ export function ClarifyDockPanel(_ref2) {
248
248
  _useState10 = _slicedToArray(_useState9, 2),
249
249
  otherDraft = _useState10[0],
250
250
  setOtherDraft = _useState10[1];
251
- var _useState11 = useState(null),
251
+ var _useState11 = useState(''),
252
252
  _useState12 = _slicedToArray(_useState11, 2),
253
- dateDraft = _useState12[0],
254
- setDateDraft = _useState12[1];
253
+ textDraft = _useState12[0],
254
+ setTextDraft = _useState12[1];
255
255
  var _useState13 = useState(null),
256
256
  _useState14 = _slicedToArray(_useState13, 2),
257
- dateRangeDraft = _useState14[0],
258
- setDateRangeDraft = _useState14[1];
259
- /** AutoHeight 过渡结束后再递增,驱动选项延后 autofocus */
260
- var _useState15 = useState(0),
257
+ dateDraft = _useState14[0],
258
+ setDateDraft = _useState14[1];
259
+ var _useState15 = useState(null),
261
260
  _useState16 = _slicedToArray(_useState15, 2),
262
- inputFocusEpoch = _useState16[0],
263
- setInputFocusEpoch = _useState16[1];
261
+ dateRangeDraft = _useState16[0],
262
+ setDateRangeDraft = _useState16[1];
263
+ /** AutoHeight 过渡结束后再递增,驱动选项延后 autofocus */
264
+ var _useState17 = useState(0),
265
+ _useState18 = _slicedToArray(_useState17, 2),
266
+ inputFocusEpoch = _useState18[0],
267
+ setInputFocusEpoch = _useState18[1];
264
268
  var question = spec.questions[page];
265
269
  var answer = answers[page];
266
270
  var input = question.input;
267
271
 
268
- /* 切页:回显 other / date / date-range 草稿 */
272
+ /* 切页:回显 other / text / date / date-range 草稿 */
269
273
  useEffect(function () {
270
274
  if ((answer === null || answer === void 0 ? void 0 : answer.kind) === 'options' || (answer === null || answer === void 0 ? void 0 : answer.kind) === 'options-multi') {
271
275
  var _answer$otherText;
@@ -273,6 +277,11 @@ export function ClarifyDockPanel(_ref2) {
273
277
  } else {
274
278
  setOtherDraft('');
275
279
  }
280
+ if ((answer === null || answer === void 0 ? void 0 : answer.kind) === 'text') {
281
+ setTextDraft(answer.value);
282
+ } else {
283
+ setTextDraft('');
284
+ }
276
285
  if ((answer === null || answer === void 0 ? void 0 : answer.kind) === 'date') {
277
286
  setDateDraft(answer.value ? new Date("".concat(answer.value, "T00:00:00")) : null);
278
287
  } else {
@@ -309,6 +318,8 @@ export function ClarifyDockPanel(_ref2) {
309
318
  if (hasOther && otherDraft.trim().length === 0) return false;
310
319
  return hasRegular || hasOther;
311
320
  }
321
+ case 'text':
322
+ return answer.value.trim().length > 0;
312
323
  case 'date':
313
324
  return answer.value.trim().length > 0;
314
325
  case 'date-range':
@@ -360,6 +371,8 @@ export function ClarifyDockPanel(_ref2) {
360
371
  }
361
372
  return labels.join('、');
362
373
  }
374
+ case 'text':
375
+ return ans.value;
363
376
  case 'date':
364
377
  return ans.value;
365
378
  case 'date-range':
@@ -381,6 +394,12 @@ export function ClarifyDockPanel(_ref2) {
381
394
  otherText: otherDraft
382
395
  });
383
396
  }
397
+ if (a.kind === 'text') {
398
+ return {
399
+ kind: 'text',
400
+ value: textDraft
401
+ };
402
+ }
384
403
  if (a.kind === 'date' && dateDraft) {
385
404
  return {
386
405
  kind: 'date',
@@ -420,6 +439,9 @@ export function ClarifyDockPanel(_ref2) {
420
439
  data[q.key] = values;
421
440
  break;
422
441
  }
442
+ case 'text':
443
+ data[q.key] = a.value;
444
+ break;
423
445
  case 'date':
424
446
  data[q.key] = a.value;
425
447
  break;
@@ -483,6 +505,7 @@ export function ClarifyDockPanel(_ref2) {
483
505
  kind: 'skipped'
484
506
  };
485
507
  setOtherDraft('');
508
+ setTextDraft('');
486
509
  setDateDraft(null);
487
510
  setDateRangeDraft(null);
488
511
  /* 不按顺序跳过:任意一题跳过后若已全部有值(含已跳),直接提交 */
@@ -502,6 +525,7 @@ export function ClarifyDockPanel(_ref2) {
502
525
  if (!isSkipped) return;
503
526
  setAnswerForPage(undefined);
504
527
  setOtherDraft('');
528
+ setTextDraft('');
505
529
  setDateDraft(null);
506
530
  setDateRangeDraft(null);
507
531
  };
@@ -552,6 +576,7 @@ export function ClarifyDockPanel(_ref2) {
552
576
  answer: isSkipped ? undefined : answer,
553
577
  focusEpoch: inputFocusEpoch,
554
578
  otherDraft: otherDraft,
579
+ textDraft: textDraft,
555
580
  dateDraft: dateDraft,
556
581
  dateRangeDraft: dateRangeDraft,
557
582
  onOtherDraftChange: function onOtherDraftChange(v) {
@@ -570,6 +595,13 @@ export function ClarifyDockPanel(_ref2) {
570
595
  });
571
596
  }
572
597
  },
598
+ onTextChange: function onTextChange(v) {
599
+ setTextDraft(v);
600
+ setAnswerForPage(v.trim() ? {
601
+ kind: 'text',
602
+ value: v
603
+ } : undefined);
604
+ },
573
605
  onDateChange: function onDateChange(d) {
574
606
  setDateDraft(d);
575
607
  setAnswerForPage(d ? {
@@ -671,8 +703,8 @@ function withOtherOption(options, allowOther, maxOptions) {
671
703
 
672
704
  /**
673
705
  * 按 input.kind 适配录入组件:
674
- * options / options-multi → 选项列表;dateDatePicker;
675
- * date-range → DateRangePicker。自由文本走自然语言 + Composer,不在此渲染。
706
+ * options / options-multi → 选项列表;textInput 单行;
707
+ * date → DatePicker;date-range → DateRangePicker
676
708
  */
677
709
  function QuestionInput(_ref3) {
678
710
  var input = _ref3.input,
@@ -680,9 +712,11 @@ function QuestionInput(_ref3) {
680
712
  answer = _ref3.answer,
681
713
  focusEpoch = _ref3.focusEpoch,
682
714
  otherDraft = _ref3.otherDraft,
715
+ textDraft = _ref3.textDraft,
683
716
  dateDraft = _ref3.dateDraft,
684
717
  dateRangeDraft = _ref3.dateRangeDraft,
685
718
  onOtherDraftChange = _ref3.onOtherDraftChange,
719
+ onTextChange = _ref3.onTextChange,
686
720
  onDateChange = _ref3.onDateChange,
687
721
  onDateRangeChange = _ref3.onDateRangeChange,
688
722
  onPickSingle = _ref3.onPickSingle,
@@ -704,6 +738,17 @@ function QuestionInput(_ref3) {
704
738
  })
705
739
  );
706
740
  }
741
+ if (input.kind === 'text') {
742
+ return /*#__PURE__*/React.createElement("div", {
743
+ "data-odn-clarify-dock-input-row": true,
744
+ "data-kind": "text"
745
+ }, /*#__PURE__*/React.createElement(TextQuestionInput, {
746
+ value: textDraft,
747
+ placeholder: input.placeholder,
748
+ focusEpoch: focusEpoch,
749
+ onChange: onTextChange
750
+ }));
751
+ }
707
752
  if (input.kind === 'date') {
708
753
  return /*#__PURE__*/React.createElement("div", {
709
754
  "data-odn-clarify-dock-input-row": true
@@ -734,25 +779,57 @@ function QuestionInput(_ref3) {
734
779
  }
735
780
 
736
781
  /* ------------------------------------------------------------------ */
737
- /* OptionsList · A–E 徽标 + ↑↓ 框选(焦点隔离,不抢 Composer */
782
+ /* TextQuestionInput · 迷你单行输入(撑满宽度,13px */
738
783
  /* ------------------------------------------------------------------ */
739
784
 
740
- function OptionsList(_ref4) {
741
- var options = _ref4.options,
742
- multi = _ref4.multi,
743
- answer = _ref4.answer,
785
+ function TextQuestionInput(_ref4) {
786
+ var value = _ref4.value,
787
+ placeholder = _ref4.placeholder,
744
788
  focusEpoch = _ref4.focusEpoch,
745
- otherDraft = _ref4.otherDraft,
746
- otherPlaceholder = _ref4.otherPlaceholder,
747
- onOtherDraftChange = _ref4.onOtherDraftChange,
748
- onPickSingle = _ref4.onPickSingle,
749
- onToggleMulti = _ref4.onToggleMulti;
789
+ _onChange = _ref4.onChange;
790
+ var ref = useRef(null);
791
+ useEffect(function () {
792
+ if (focusEpoch <= 0) return;
793
+ var id = window.requestAnimationFrame(function () {
794
+ var _ref$current;
795
+ (_ref$current = ref.current) === null || _ref$current === void 0 || _ref$current.focus();
796
+ });
797
+ return function () {
798
+ return window.cancelAnimationFrame(id);
799
+ };
800
+ }, [focusEpoch]);
801
+ return /*#__PURE__*/React.createElement(Input, {
802
+ ref: ref,
803
+ value: value,
804
+ onChange: function onChange(_, next) {
805
+ return _onChange(next);
806
+ },
807
+ placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : '请输入…',
808
+ size: "small",
809
+ className: "w-full"
810
+ });
811
+ }
812
+
813
+ /* ------------------------------------------------------------------ */
814
+ /* OptionsList · 1–N 序号徽标 + ↑↓ 框选(焦点隔离,不抢 Composer) */
815
+ /* ------------------------------------------------------------------ */
816
+
817
+ function OptionsList(_ref5) {
818
+ var options = _ref5.options,
819
+ multi = _ref5.multi,
820
+ answer = _ref5.answer,
821
+ focusEpoch = _ref5.focusEpoch,
822
+ otherDraft = _ref5.otherDraft,
823
+ otherPlaceholder = _ref5.otherPlaceholder,
824
+ onOtherDraftChange = _ref5.onOtherDraftChange,
825
+ onPickSingle = _ref5.onPickSingle,
826
+ onToggleMulti = _ref5.onToggleMulti;
750
827
  var optionRefs = useRef([]);
751
828
  /** roving tabindex:当前键盘焦点项;与选中态解耦,避免重渲染丢焦 */
752
- var _useState17 = useState(0),
753
- _useState18 = _slicedToArray(_useState17, 2),
754
- focusedIdx = _useState18[0],
755
- setFocusedIdx = _useState18[1];
829
+ var _useState19 = useState(0),
830
+ _useState20 = _slicedToArray(_useState19, 2),
831
+ focusedIdx = _useState20[0],
832
+ setFocusedIdx = _useState20[1];
756
833
  /** 选中态导致「其他」编辑行等结构切换后,在 layout 再聚焦 */
757
834
  var pendingFocusIdxRef = useRef(null);
758
835
  var resolveSelectedIdx = function resolveSelectedIdx() {
@@ -832,7 +909,7 @@ function OptionsList(_ref4) {
832
909
  }, options.map(function (opt, idx) {
833
910
  var active = (answer === null || answer === void 0 ? void 0 : answer.kind) === 'options' ? answer.value === opt.value : (answer === null || answer === void 0 ? void 0 : answer.kind) === 'options-multi' ? answer.values.includes(opt.value) : false;
834
911
  var isOther = opt.value === OTHER_VALUE;
835
- var letter = optionLetter(idx);
912
+ var seq = optionIndexLabel(idx);
836
913
  if (isOther && active) {
837
914
  var editingRow = /*#__PURE__*/React.createElement("div", {
838
915
  "data-odn-clarify-dock-option": true,
@@ -854,10 +931,10 @@ function OptionsList(_ref4) {
854
931
  onToggleMulti(opt);
855
932
  }
856
933
  }
857
- }, letter) : /*#__PURE__*/React.createElement("span", {
934
+ }, seq) : /*#__PURE__*/React.createElement("span", {
858
935
  "data-odn-clarify-dock-option-letter": true,
859
936
  "aria-hidden": true
860
- }, letter), /*#__PURE__*/React.createElement(Input, {
937
+ }, seq), /*#__PURE__*/React.createElement(Input, {
861
938
  value: otherDraft,
862
939
  onChange: function onChange(_, value) {
863
940
  return onOtherDraftChange(value);
@@ -903,7 +980,7 @@ function OptionsList(_ref4) {
903
980
  var optionContent = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
904
981
  "data-odn-clarify-dock-option-letter": true,
905
982
  "aria-hidden": true
906
- }, letter), /*#__PURE__*/React.createElement("span", {
983
+ }, seq), /*#__PURE__*/React.createElement("span", {
907
984
  "data-odn-clarify-dock-option-label": true
908
985
  }, opt.label));
909
986
 
@@ -950,10 +1027,10 @@ function OptionsList(_ref4) {
950
1027
  * - recordAnswer 后 Panel 消失,Trigger 切 Approval 式锁态卡
951
1028
  */
952
1029
  export function useClarifyDockState(messages, sessionKey, resetVer) {
953
- var _useState19 = useState({}),
954
- _useState20 = _slicedToArray(_useState19, 2),
955
- answers = _useState20[0],
956
- setAnswers = _useState20[1];
1030
+ var _useState21 = useState({}),
1031
+ _useState22 = _slicedToArray(_useState21, 2),
1032
+ answers = _useState22[0],
1033
+ setAnswers = _useState22[1];
957
1034
 
958
1035
  /* 切换会话或点「重置」时清空已答标记,避免 Panel / Trigger 状态脱节 */
959
1036
  useEffect(function () {
@@ -142,16 +142,20 @@ div[data-odn-clarify-dock] [data-odn-clarify-dock-body] {
142
142
  [data-odn-clarify-dock-actions] [data-odn-pagination] {
143
143
  flex-shrink: 0;
144
144
  font-size: 12px;
145
+ font-family: inherit;
146
+ font-variant-numeric: normal;
145
147
  line-height: 1.5;
146
148
  color: var(--odn-color-black-9);
147
149
  }
148
150
 
149
151
  [data-odn-clarify-dock-actions] [data-odn-pagination-simple-page-value] {
152
+ font-family: inherit;
153
+ font-variant-numeric: normal;
150
154
  color: var(--odn-color-black-9);
151
155
  }
152
156
 
153
157
  /* ============================================================== */
154
- /* Options · AE 徽标 + 通栏灰底(不复用 Button 尺寸体系) */
158
+ /* Options · 1N 序号徽标 + 通栏灰底(不复用 Button 尺寸体系) */
155
159
  /* ============================================================== */
156
160
  [data-odn-clarify-dock] [data-odn-clarify-dock-options] {
157
161
  display: flex;
@@ -238,7 +242,8 @@ div[data-odn-clarify-dock] [data-odn-clarify-dock-body] {
238
242
  color: var(--odn-color-black-10);
239
243
  font-size: 11px;
240
244
  font-weight: 600;
241
- font-variant-numeric: tabular-nums;
245
+ font-family: inherit;
246
+ font-variant-numeric: normal;
242
247
  line-height: 1;
243
248
  }
244
249
 
@@ -288,7 +293,8 @@ div[data-odn-clarify-dock] [data-odn-clarify-dock-body] {
288
293
  line-height: 1;
289
294
  font-size: 11px;
290
295
  font-weight: 600;
291
- font-variant-numeric: tabular-nums;
296
+ font-family: inherit;
297
+ font-variant-numeric: normal;
292
298
  border: 1px solid var(--odn-color-brand-6);
293
299
  background: var(--odn-color-brand-6);
294
300
  color: var(--odn-color-bg-elevated);
@@ -542,6 +548,14 @@ div[data-odn-clarify-dock] [data-odn-clarify-dock-body] {
542
548
  flex: 0 0 auto;
543
549
  }
544
550
 
551
+ /* 纯文本题:迷你单行输入,默认撑满宽度,字号 13px,左右 padding 6px,圆角 4px */
552
+ [data-odn-clarify-dock-input-row][data-kind=text] {
553
+ width: 100%;
554
+ --odn-input-font-size-small: var(--odn-font-size-text-sm);
555
+ --odn-input-padding-inline-small: var(--odn-input-padding-block-medium);
556
+ --odn-input-border-radius-small: var(--odn-border-radius);
557
+ }
558
+
545
559
  div[data-odn-clarify-dock] [data-odn-date-picker-container]:not([data-odn-date-picker-container-range]) {
546
560
  display: inline-block;
547
561
  box-sizing: border-box;
@@ -17,6 +17,9 @@ export type ClarifyInput = {
17
17
  options: ClarifyOption[];
18
18
  allowOther?: boolean;
19
19
  otherPlaceholder?: string;
20
+ } | {
21
+ kind: 'text';
22
+ placeholder?: string;
20
23
  } | {
21
24
  kind: 'date';
22
25
  placeholder?: string;
@@ -12,7 +12,7 @@ export function toISODate(d) {
12
12
 
13
13
  /** 解析 Host 传入的日期边界;非法则忽略。 */
14
14
  export function parseClarifyBoundDate(value) {
15
- if (value == null) return undefined;
15
+ if (value === undefined || value === null) return undefined;
16
16
  if (value instanceof Date) {
17
17
  return Number.isNaN(value.getTime()) ? undefined : value;
18
18
  }
@@ -6,6 +6,8 @@ export type SelectFeedbackState = {
6
6
  export interface SelectFeedbackProps {
7
7
  feedback: SelectFeedbackState | null;
8
8
  onUndo?: () => void;
9
+ onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
10
+ onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
9
11
  }
10
12
  declare const SelectFeedback: React.FC<SelectFeedbackProps>;
11
13
  export default SelectFeedback;
@@ -1,17 +1,114 @@
1
- import React from 'react';
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
3
+ var ANIMATE_MS = 300;
4
+ var ANIMATE_DELAY_MS = 50;
5
+ var COLLAPSED_STYLE = {
6
+ height: '0px',
7
+ marginTop: '0',
8
+ marginBottom: '0',
9
+ paddingTop: '0',
10
+ paddingBottom: '0',
11
+ opacity: '0'
12
+ };
13
+ var EXPANDED_STYLE = {
14
+ height: '',
15
+ marginTop: '',
16
+ marginBottom: '',
17
+ paddingTop: '',
18
+ paddingBottom: '',
19
+ opacity: ''
20
+ };
21
+ function prefersReducedMotion() {
22
+ return typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
23
+ }
2
24
  var SelectFeedback = function SelectFeedback(_ref) {
3
25
  var feedback = _ref.feedback,
4
- onUndo = _ref.onUndo;
5
- if (!feedback) {
26
+ onUndo = _ref.onUndo,
27
+ onMouseEnter = _ref.onMouseEnter,
28
+ onMouseLeave = _ref.onMouseLeave;
29
+ var _useState = useState(feedback),
30
+ _useState2 = _slicedToArray(_useState, 2),
31
+ rendered = _useState2[0],
32
+ setRendered = _useState2[1];
33
+ var _useState3 = useState(Boolean(feedback)),
34
+ _useState4 = _slicedToArray(_useState3, 2),
35
+ open = _useState4[0],
36
+ setOpen = _useState4[1];
37
+ var rootRef = useRef(null);
38
+ var timersRef = useRef([]);
39
+ var clearTimers = function clearTimers() {
40
+ timersRef.current.forEach(function (id) {
41
+ return window.clearTimeout(id);
42
+ });
43
+ timersRef.current = [];
44
+ };
45
+ useEffect(function () {
46
+ if (feedback) {
47
+ setRendered(feedback);
48
+ setOpen(true);
49
+ return;
50
+ }
51
+ setOpen(false);
52
+ }, [feedback]);
53
+ useLayoutEffect(function () {
54
+ var el = rootRef.current;
55
+ if (!el) {
56
+ return;
57
+ }
58
+ clearTimers();
59
+ if (prefersReducedMotion()) {
60
+ if (open) {
61
+ Object.assign(el.style, EXPANDED_STYLE);
62
+ return;
63
+ }
64
+ setRendered(null);
65
+ return;
66
+ }
67
+ if (open) {
68
+ el.style.transition = 'none';
69
+ Object.assign(el.style, EXPANDED_STYLE);
70
+ el.style.height = '';
71
+ var height = el.offsetHeight;
72
+ Object.assign(el.style, COLLAPSED_STYLE);
73
+ void el.offsetHeight;
74
+ el.style.transition = '';
75
+ var expandId = window.setTimeout(function () {
76
+ Object.assign(el.style, EXPANDED_STYLE, {
77
+ height: "".concat(height, "px")
78
+ });
79
+ var settleId = window.setTimeout(function () {
80
+ el.style.height = '';
81
+ }, ANIMATE_MS + ANIMATE_DELAY_MS);
82
+ timersRef.current.push(settleId);
83
+ }, 0);
84
+ timersRef.current.push(expandId);
85
+ } else {
86
+ el.style.height = "".concat(el.offsetHeight, "px");
87
+ void el.offsetHeight;
88
+ var collapseId = window.setTimeout(function () {
89
+ Object.assign(el.style, COLLAPSED_STYLE);
90
+ var doneId = window.setTimeout(function () {
91
+ setRendered(null);
92
+ }, ANIMATE_MS);
93
+ timersRef.current.push(doneId);
94
+ }, 0);
95
+ timersRef.current.push(collapseId);
96
+ }
97
+ return clearTimers;
98
+ }, [open]);
99
+ if (!rendered) {
6
100
  return null;
7
101
  }
8
102
  return /*#__PURE__*/React.createElement("div", {
103
+ ref: rootRef,
9
104
  className: "odn-select-feedback",
10
105
  role: "status",
11
- "data-odn-select-feedback": true
106
+ "data-odn-select-feedback": true,
107
+ onMouseEnter: onMouseEnter,
108
+ onMouseLeave: onMouseLeave
12
109
  }, /*#__PURE__*/React.createElement("span", {
13
110
  className: "odn-select-feedback-message"
14
- }, feedback.message), feedback.undoable ? /*#__PURE__*/React.createElement("button", {
111
+ }, rendered.message), rendered.undoable ? /*#__PURE__*/React.createElement("button", {
15
112
  type: "button",
16
113
  className: "odn-select-feedback-undo",
17
114
  onClick: onUndo
@@ -72,7 +72,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
72
72
  * 传入 tokenSeparators 时默认 true;也可单独开启(需 allowClear)。
73
73
  */
74
74
  clearUndo?: boolean;
75
- /** 反馈条自动消失时长(ms */
75
+ /** 反馈条自动消失时长(ms)。下拉打开或悬停反馈条时不计时,离开后再开始 */
76
76
  feedbackDuration?: number;
77
77
  }
78
78
  export interface SelectButtonProps {
@@ -5,7 +5,7 @@ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
5
5
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
6
6
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
7
7
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
8
- var _excluded = ["className", "rootClassName", "style", "light", "mode", "suffixIcon", "popupClassName", "popupMatchSelectWidth", "visible", "onVisibleChange", "showInnerSearch", "popupRender", "searchValue", "onSearch", "maxCount", "defaultValue", "value", "onChange", "placeholder", "showSearch", "size", "autoClearSearchValue", "optionRender", "tagRender", "options", "allowClear", "onClear", "tokenSeparators", "tokenMismatch", "tokenFeedback", "validateTokens", "onTokenPaste", "clearUndo", "feedbackDuration", "disabled"];
8
+ var _excluded = ["className", "rootClassName", "style", "light", "mode", "suffixIcon", "popupClassName", "popupMatchSelectWidth", "visible", "open", "onVisibleChange", "showInnerSearch", "popupRender", "searchValue", "onSearch", "maxCount", "defaultValue", "value", "onChange", "placeholder", "showSearch", "size", "autoClearSearchValue", "optionRender", "tagRender", "options", "allowClear", "onClear", "tokenSeparators", "tokenMismatch", "tokenFeedback", "validateTokens", "onTokenPaste", "clearUndo", "feedbackDuration", "disabled"];
9
9
  import clsx from 'clsx';
10
10
  import RcSelect, { OptGroup, Option } from 'rc-select';
11
11
  import React, { useEffect, useRef, useState } from 'react';
@@ -17,6 +17,7 @@ import "./style";
17
17
  import { countValidValues, formatTokenPasteFeedback, readClipboardText, resolveTokenPaste, splitByTokenSeparators, toRawValueList } from "./tokenUtils";
18
18
  import useIcons from "./useIcons";
19
19
  var InternalSelect = function InternalSelect(props, ref) {
20
+ var _ref;
20
21
  var className = props.className,
21
22
  rootClassName = props.rootClassName,
22
23
  style = props.style,
@@ -29,6 +30,7 @@ var InternalSelect = function InternalSelect(props, ref) {
29
30
  popupClassName = props.popupClassName,
30
31
  popupMatchSelectWidth = props.popupMatchSelectWidth,
31
32
  visibleProp = props.visible,
33
+ openProp = props.open,
32
34
  onVisibleChange = props.onVisibleChange,
33
35
  _props$showInnerSearc = props.showInnerSearch,
34
36
  showInnerSearch = _props$showInnerSearc === void 0 ? false : _props$showInnerSearc,
@@ -102,10 +104,14 @@ var InternalSelect = function InternalSelect(props, ref) {
102
104
  _useState10 = _slicedToArray(_useState9, 2),
103
105
  feedback = _useState10[0],
104
106
  setFeedback = _useState10[1];
107
+ var _useState11 = useState(false),
108
+ _useState12 = _slicedToArray(_useState11, 2),
109
+ feedbackHovered = _useState12[0],
110
+ setFeedbackHovered = _useState12[1];
105
111
  var undoSnapshotRef = useRef(null);
106
- var feedbackTimerRef = useRef();
107
112
  var dropdownSearchInputRef = useRef(null);
108
113
  var pastingRef = useRef(false);
114
+ var mergedOpen = (_ref = visibleProp !== null && visibleProp !== void 0 ? visibleProp : openProp) !== null && _ref !== void 0 ? _ref : Boolean(visible);
109
115
  var handleVisibleChange = function handleVisibleChange(bool) {
110
116
  if (visibleProp === undefined) {
111
117
  setVisible(bool);
@@ -144,12 +150,24 @@ var InternalSelect = function InternalSelect(props, ref) {
144
150
  }
145
151
  }, [visible]);
146
152
  useEffect(function () {
153
+ if (!feedback) {
154
+ setFeedbackHovered(false);
155
+ }
156
+ }, [feedback]);
157
+
158
+ // 下拉盖住 / 悬停反馈条时不计时;可看见且离开后再开始 duration
159
+ useEffect(function () {
160
+ if (!feedback || mergedOpen || feedbackHovered) {
161
+ return;
162
+ }
163
+ var timer = window.setTimeout(function () {
164
+ setFeedback(null);
165
+ undoSnapshotRef.current = null;
166
+ }, feedbackDuration);
147
167
  return function () {
148
- if (feedbackTimerRef.current) {
149
- clearTimeout(feedbackTimerRef.current);
150
- }
168
+ window.clearTimeout(timer);
151
169
  };
152
- }, []);
170
+ }, [feedback, mergedOpen, feedbackHovered, feedbackDuration]);
153
171
  var showFeedback = function showFeedback(next) {
154
172
  if (!enableTokenFeedback && !(next !== null && next !== void 0 && next.undoable)) {
155
173
  setFeedback(null);
@@ -160,15 +178,6 @@ var InternalSelect = function InternalSelect(props, ref) {
160
178
  return;
161
179
  }
162
180
  setFeedback(next);
163
- if (feedbackTimerRef.current) {
164
- clearTimeout(feedbackTimerRef.current);
165
- }
166
- if (next) {
167
- feedbackTimerRef.current = setTimeout(function () {
168
- setFeedback(null);
169
- undoSnapshotRef.current = null;
170
- }, feedbackDuration);
171
- }
172
181
  };
173
182
  var commitValue = function commitValue(next, option) {
174
183
  if (valueProp === undefined) {
@@ -187,7 +196,7 @@ var InternalSelect = function InternalSelect(props, ref) {
187
196
  });
188
197
  };
189
198
  var handlePasteCapture = /*#__PURE__*/function () {
190
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(event) {
199
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(event) {
191
200
  var text, tokens, currentRaw, result;
192
201
  return _regeneratorRuntime().wrap(function _callee$(_context) {
193
202
  while (1) switch (_context.prev = _context.next) {
@@ -243,18 +252,23 @@ var InternalSelect = function InternalSelect(props, ref) {
243
252
  onSearch === null || onSearch === void 0 || onSearch('');
244
253
  }
245
254
 
255
+ // 分隔符拆词是提交,关掉下拉让反馈条可见
256
+ if (mergedOpen) {
257
+ handleVisibleChange(false);
258
+ }
259
+
246
260
  // 让受控/非受控 onChange 完成后再放开,避免同一次粘贴被 rc-select 再处理
247
261
  window.setTimeout(function () {
248
262
  pastingRef.current = false;
249
263
  }, 0);
250
- case 21:
264
+ case 22:
251
265
  case "end":
252
266
  return _context.stop();
253
267
  }
254
268
  }, _callee);
255
269
  }));
256
270
  return function handlePasteCapture(_x) {
257
- return _ref.apply(this, arguments);
271
+ return _ref2.apply(this, arguments);
258
272
  };
259
273
  }();
260
274
  var handleClear = function handleClear() {
@@ -346,7 +360,7 @@ var InternalSelect = function InternalSelect(props, ref) {
346
360
  removeIcon: removeIcon,
347
361
  clearIcon: clearIcon,
348
362
  maxCount: maxCount,
349
- open: visible,
363
+ open: mergedOpen,
350
364
  onDropdownVisibleChange: handleVisibleChange,
351
365
  searchValue: searchValue,
352
366
  onSearch: handleSearch,
@@ -420,32 +434,38 @@ var InternalSelect = function InternalSelect(props, ref) {
420
434
  "data-odn-select-shell": true
421
435
  }, selectNode, /*#__PURE__*/React.createElement(SelectFeedback, {
422
436
  feedback: enableTokenFeedback || feedback !== null && feedback !== void 0 && feedback.undoable && enableClearUndo ? feedback : null,
423
- onUndo: handleUndo
437
+ onUndo: handleUndo,
438
+ onMouseEnter: function onMouseEnter() {
439
+ return setFeedbackHovered(true);
440
+ },
441
+ onMouseLeave: function onMouseLeave() {
442
+ return setFeedbackHovered(false);
443
+ }
424
444
  }));
425
445
  };
426
446
 
427
447
  // Select.Button 组件接口
428
448
 
429
449
  // Select.Button 组件
430
- var SelectButton = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
431
- var _ref2$showArrow = _ref2.showArrow,
432
- showArrow = _ref2$showArrow === void 0 ? true : _ref2$showArrow,
433
- _ref2$size = _ref2.size,
434
- size = _ref2$size === void 0 ? 'middle' : _ref2$size,
435
- _ref2$disabled = _ref2.disabled,
436
- disabled = _ref2$disabled === void 0 ? false : _ref2$disabled,
437
- prefix = _ref2.prefix,
438
- _ref2$placeholder = _ref2.placeholder,
439
- placeholder = _ref2$placeholder === void 0 ? '请选择' : _ref2$placeholder,
440
- value = _ref2.value,
441
- _ref2$active = _ref2.active,
442
- active = _ref2$active === void 0 ? false : _ref2$active,
443
- _ref2$allowClear = _ref2.allowClear,
444
- allowClear = _ref2$allowClear === void 0 ? false : _ref2$allowClear,
445
- onClick = _ref2.onClick,
446
- onClear = _ref2.onClear,
447
- className = _ref2.className,
448
- style = _ref2.style;
450
+ var SelectButton = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
451
+ var _ref3$showArrow = _ref3.showArrow,
452
+ showArrow = _ref3$showArrow === void 0 ? true : _ref3$showArrow,
453
+ _ref3$size = _ref3.size,
454
+ size = _ref3$size === void 0 ? 'middle' : _ref3$size,
455
+ _ref3$disabled = _ref3.disabled,
456
+ disabled = _ref3$disabled === void 0 ? false : _ref3$disabled,
457
+ prefix = _ref3.prefix,
458
+ _ref3$placeholder = _ref3.placeholder,
459
+ placeholder = _ref3$placeholder === void 0 ? '请选择' : _ref3$placeholder,
460
+ value = _ref3.value,
461
+ _ref3$active = _ref3.active,
462
+ active = _ref3$active === void 0 ? false : _ref3$active,
463
+ _ref3$allowClear = _ref3.allowClear,
464
+ allowClear = _ref3$allowClear === void 0 ? false : _ref3$allowClear,
465
+ onClick = _ref3.onClick,
466
+ onClear = _ref3.onClear,
467
+ className = _ref3.className,
468
+ style = _ref3.style;
449
469
  var buttonClasses = clsx('odn-select-button odn-select odn-select-outlined odn-select-single odn-select-allow-clear odn-select-show-arrow', "odn-select-button-".concat(size), {
450
470
  'odn-select-button-disabled': disabled,
451
471
  'odn-select-open': active
@@ -1904,6 +1904,7 @@ html {
1904
1904
  display: flex;
1905
1905
  align-items: center;
1906
1906
  gap: 8px;
1907
+ overflow: hidden;
1907
1908
  margin-top: 8px;
1908
1909
  padding: 8px 12px;
1909
1910
  border-radius: var(--odn-select-border-radius-sm);
@@ -1911,8 +1912,14 @@ html {
1911
1912
  color: var(--odn-select-feedback-color);
1912
1913
  font-size: 13px;
1913
1914
  line-height: 20px;
1915
+ transition: all 300ms cubic-bezier(0.32, 0.72, 0, 1) 50ms, opacity 200ms cubic-bezier(0.32, 0.72, 0, 1);
1914
1916
  }
1915
1917
 
1918
+ @media (prefers-reduced-motion: reduce) {
1919
+ .odn-select-feedback {
1920
+ transition: none;
1921
+ }
1922
+ }
1916
1923
  .odn-select-feedback-message {
1917
1924
  flex: 1;
1918
1925
  min-width: 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one-design-next",
3
- "version": "0.0.80",
3
+ "version": "0.0.82",
4
4
  "description": "One Design Next from TAD@tencent.com",
5
5
  "license": "MIT",
6
6
  "type": "module",