one-design-next 0.0.61 → 0.0.63

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,256 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import { useMemo, useState } from 'react';
3
+ import clsx from 'clsx';
4
+ import ChatItem from "../chat-item";
5
+ import Dropdown from "../dropdown";
6
+ import Icon from "../icon";
7
+ import "./style";
8
+
9
+ /** 按会话时间筛选:全部 / 今天 / 近 7 天 / 近 30 天。 */
10
+
11
+ /** 按会话类型筛选:全部 / AI / 人工客服。 */
12
+
13
+ var TIME_OPTIONS = [{
14
+ value: 'all',
15
+ label: '全部'
16
+ }, {
17
+ value: 'today',
18
+ label: '今天'
19
+ }, {
20
+ value: '7d',
21
+ label: '近 7 天'
22
+ }, {
23
+ value: '30d',
24
+ label: '近 30 天'
25
+ }];
26
+ var TYPE_OPTIONS = [{
27
+ value: 'all',
28
+ label: '全部'
29
+ }, {
30
+ value: 'ai',
31
+ label: 'AI 对话'
32
+ }, {
33
+ value: 'human',
34
+ label: '人工客服'
35
+ }];
36
+ function parseItemTime(time) {
37
+ if (time == null) return null;
38
+ var t = typeof time === 'number' ? time : time instanceof Date ? time.getTime() : Date.parse(time);
39
+ return Number.isFinite(t) ? t : null;
40
+ }
41
+ function startOfLocalDay(now) {
42
+ var d = new Date(now);
43
+ d.setHours(0, 0, 0, 0);
44
+ return d.getTime();
45
+ }
46
+
47
+ /** 按时间筛选项判断会话是否命中。无有效 `time` 时仅在「全部」下保留。 */
48
+ export function matchChatListFilterTime(time, filter) {
49
+ var now = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Date.now();
50
+ if (filter === 'all') return true;
51
+ var t = parseItemTime(time);
52
+ if (t == null) return false;
53
+ if (t > now) return false;
54
+ if (filter === 'today') return t >= startOfLocalDay(now);
55
+ if (filter === '7d') return t >= now - 7 * 86400000;
56
+ if (filter === '30d') return t >= now - 30 * 86400000;
57
+ return true;
58
+ }
59
+
60
+ /** 按类型筛选项判断会话是否命中。缺省 `type` 视为 `'ai'`。 */
61
+ export function matchChatListFilterType(type, filter) {
62
+ if (filter === 'all') return true;
63
+ return (type !== null && type !== void 0 ? type : 'ai') === filter;
64
+ }
65
+ function useControllable(controlled, defaultValue, onChange) {
66
+ var _useState = useState(defaultValue),
67
+ _useState2 = _slicedToArray(_useState, 2),
68
+ internal = _useState2[0],
69
+ setInternal = _useState2[1];
70
+ var value = controlled !== null && controlled !== void 0 ? controlled : internal;
71
+ var setValue = function setValue(next) {
72
+ onChange === null || onChange === void 0 || onChange(next);
73
+ if (controlled === undefined) setInternal(next);
74
+ };
75
+ return [value, setValue];
76
+ }
77
+ function defaultRenderItem(item, node) {
78
+ return node;
79
+ }
80
+ function filterOptionLabel(label, selected) {
81
+ return /*#__PURE__*/React.createElement("span", {
82
+ "data-odn-chat-list-filter-option": true
83
+ }, /*#__PURE__*/React.createElement("span", {
84
+ "data-odn-chat-list-filter-option-label": true
85
+ }, label), selected ? /*#__PURE__*/React.createElement(Icon, {
86
+ name: "check",
87
+ size: 14,
88
+ "data-odn-chat-list-filter-option-check": true
89
+ }) : null);
90
+ }
91
+ function buildFilterMenu(filterTime, filterType) {
92
+ return [{
93
+ type: 'label',
94
+ label: '时间'
95
+ }, {
96
+ type: 'group',
97
+ children: TIME_OPTIONS.map(function (opt) {
98
+ return {
99
+ value: "time:".concat(opt.value),
100
+ label: filterOptionLabel(opt.label, filterTime === opt.value)
101
+ };
102
+ })
103
+ }, {
104
+ type: 'separator'
105
+ }, {
106
+ type: 'label',
107
+ label: '类型'
108
+ }, {
109
+ type: 'group',
110
+ children: TYPE_OPTIONS.map(function (opt) {
111
+ return {
112
+ value: "type:".concat(opt.value),
113
+ label: filterOptionLabel(opt.label, filterType === opt.value)
114
+ };
115
+ })
116
+ }];
117
+ }
118
+ export function ChatList(_ref) {
119
+ var items = _ref.items,
120
+ _ref$title = _ref.title,
121
+ title = _ref$title === void 0 ? '对话' : _ref$title,
122
+ _ref$pinnedSectionTit = _ref.pinnedSectionTitle,
123
+ pinnedSectionTitle = _ref$pinnedSectionTit === void 0 ? '置顶' : _ref$pinnedSectionTit,
124
+ _ref$recentSectionTit = _ref.recentSectionTitle,
125
+ recentSectionTitle = _ref$recentSectionTit === void 0 ? '最近' : _ref$recentSectionTit,
126
+ filterTimeProp = _ref.filterTime,
127
+ _ref$defaultFilterTim = _ref.defaultFilterTime,
128
+ defaultFilterTime = _ref$defaultFilterTim === void 0 ? 'all' : _ref$defaultFilterTim,
129
+ onFilterTimeChange = _ref.onFilterTimeChange,
130
+ filterTypeProp = _ref.filterType,
131
+ _ref$defaultFilterTyp = _ref.defaultFilterType,
132
+ defaultFilterType = _ref$defaultFilterTyp === void 0 ? 'all' : _ref$defaultFilterTyp,
133
+ onFilterTypeChange = _ref.onFilterTypeChange,
134
+ filterOpenProp = _ref.filterOpen,
135
+ _ref$defaultFilterOpe = _ref.defaultFilterOpen,
136
+ defaultFilterOpen = _ref$defaultFilterOpe === void 0 ? false : _ref$defaultFilterOpe,
137
+ onFilterOpenChange = _ref.onFilterOpenChange,
138
+ empty = _ref.empty,
139
+ actionMenuZIndex = _ref.actionMenuZIndex,
140
+ filterMenuZIndex = _ref.filterMenuZIndex,
141
+ className = _ref.className,
142
+ onItemClick = _ref.onItemClick,
143
+ onRename = _ref.onRename,
144
+ onPin = _ref.onPin,
145
+ onDelete = _ref.onDelete,
146
+ _ref$renderItem = _ref.renderItem,
147
+ renderItem = _ref$renderItem === void 0 ? defaultRenderItem : _ref$renderItem;
148
+ var _useControllable = useControllable(filterTimeProp, defaultFilterTime, onFilterTimeChange),
149
+ _useControllable2 = _slicedToArray(_useControllable, 2),
150
+ filterTime = _useControllable2[0],
151
+ setFilterTime = _useControllable2[1];
152
+ var _useControllable3 = useControllable(filterTypeProp, defaultFilterType, onFilterTypeChange),
153
+ _useControllable4 = _slicedToArray(_useControllable3, 2),
154
+ filterType = _useControllable4[0],
155
+ setFilterType = _useControllable4[1];
156
+ var _useControllable5 = useControllable(filterOpenProp, defaultFilterOpen, onFilterOpenChange),
157
+ _useControllable6 = _slicedToArray(_useControllable5, 2),
158
+ filterOpen = _useControllable6[0],
159
+ setFilterOpen = _useControllable6[1];
160
+ var filteredItems = useMemo(function () {
161
+ return items.filter(function (item) {
162
+ return matchChatListFilterTime(item.time, filterTime) && matchChatListFilterType(item.type, filterType);
163
+ });
164
+ }, [items, filterTime, filterType]);
165
+ var pinnedItems = useMemo(function () {
166
+ return filteredItems.filter(function (item) {
167
+ return item.pinned;
168
+ });
169
+ }, [filteredItems]);
170
+ var restItems = useMemo(function () {
171
+ return filteredItems.filter(function (item) {
172
+ return !item.pinned;
173
+ });
174
+ }, [filteredItems]);
175
+ var filterMenu = useMemo(function () {
176
+ return buildFilterMenu(filterTime, filterType);
177
+ }, [filterTime, filterType]);
178
+ var renderChatItem = function renderChatItem(item) {
179
+ var node = /*#__PURE__*/React.createElement(ChatItem, {
180
+ key: item.id,
181
+ id: item.id,
182
+ title: item.title,
183
+ active: item.active,
184
+ type: item.type,
185
+ status: item.status,
186
+ pinned: item.pinned,
187
+ time: item.time,
188
+ actionMenuZIndex: actionMenuZIndex,
189
+ onClick: onItemClick,
190
+ onRename: onRename,
191
+ onPin: onPin,
192
+ onDelete: onDelete
193
+ });
194
+ return /*#__PURE__*/React.createElement("div", {
195
+ key: item.id
196
+ }, renderItem(item, node));
197
+ };
198
+ var hasContent = pinnedItems.length > 0 || restItems.length > 0;
199
+ return /*#__PURE__*/React.createElement("div", {
200
+ "data-odn-chat-list": true,
201
+ className: clsx(className)
202
+ }, /*#__PURE__*/React.createElement("div", {
203
+ "data-odn-chat-list-toolbar": true
204
+ }, /*#__PURE__*/React.createElement("div", {
205
+ "data-odn-chat-list-title": true
206
+ }, title), /*#__PURE__*/React.createElement("div", {
207
+ "data-odn-chat-list-toolbar-actions": true
208
+ }, /*#__PURE__*/React.createElement(Dropdown, {
209
+ trigger: "click",
210
+ placement: "bottomRight",
211
+ zIndex: filterMenuZIndex,
212
+ popupClassName: "odn-chat-list-filter-menu",
213
+ visible: filterOpen,
214
+ onVisibleChange: setFilterOpen,
215
+ menu: filterMenu,
216
+ onSelect: function onSelect(value) {
217
+ if (value.startsWith('time:')) {
218
+ setFilterTime(value.slice(5));
219
+ setFilterOpen(false);
220
+ return;
221
+ }
222
+ if (value.startsWith('type:')) {
223
+ setFilterType(value.slice(5));
224
+ setFilterOpen(false);
225
+ }
226
+ }
227
+ }, /*#__PURE__*/React.createElement("button", {
228
+ type: "button",
229
+ "data-odn-chat-list-filter-trigger": true,
230
+ "aria-label": "\u7B5B\u9009",
231
+ title: "\u7B5B\u9009",
232
+ "aria-expanded": filterOpen || undefined,
233
+ "aria-pressed": filterOpen || undefined
234
+ }, /*#__PURE__*/React.createElement(Icon, {
235
+ name: "list-filter",
236
+ size: 16
237
+ }))))), !hasContent ? /*#__PURE__*/React.createElement("div", {
238
+ "data-odn-chat-list-empty": true
239
+ }, empty !== null && empty !== void 0 ? empty : null) : /*#__PURE__*/React.createElement("div", {
240
+ "data-odn-chat-list-body": true
241
+ }, pinnedItems.length > 0 ? /*#__PURE__*/React.createElement("div", {
242
+ "data-odn-chat-list-pinned": true
243
+ }, pinnedSectionTitle != null ? /*#__PURE__*/React.createElement("div", {
244
+ "data-odn-chat-list-pinned-title": true
245
+ }, pinnedSectionTitle) : null, /*#__PURE__*/React.createElement("div", {
246
+ "data-odn-chat-list-pinned-body": true
247
+ }, pinnedItems.map(renderChatItem))) : null, restItems.length > 0 ? /*#__PURE__*/React.createElement("div", {
248
+ "data-odn-chat-list-rest": true
249
+ }, pinnedItems.length > 0 && recentSectionTitle != null ? /*#__PURE__*/React.createElement("div", {
250
+ "data-odn-chat-list-recent-title": true
251
+ }, recentSectionTitle) : null, /*#__PURE__*/React.createElement("div", {
252
+ "data-odn-chat-list-rest-body": true
253
+ }, restItems.map(renderChatItem))) : null));
254
+ }
255
+ ChatList.displayName = 'ChatList';
256
+ export default ChatList;
@@ -0,0 +1,135 @@
1
+ @charset "UTF-8";
2
+ [data-odn-chat-list] {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 8px;
6
+ min-width: 0;
7
+ min-height: 0;
8
+ }
9
+
10
+ [data-odn-chat-list-toolbar] {
11
+ display: flex;
12
+ align-items: center;
13
+ justify-content: space-between;
14
+ gap: 8px;
15
+ min-height: 32px;
16
+ min-width: 0;
17
+ padding: 0 4px;
18
+ background: transparent;
19
+ }
20
+
21
+ [data-odn-chat-list-title] {
22
+ flex: 1 1 auto;
23
+ min-width: 0;
24
+ padding: 0 4px;
25
+ color: var(--odn-color-black-9);
26
+ font-size: 14px;
27
+ font-weight: 400;
28
+ line-height: 22px;
29
+ overflow: hidden;
30
+ text-overflow: ellipsis;
31
+ white-space: nowrap;
32
+ }
33
+
34
+ [data-odn-chat-list-toolbar-actions] {
35
+ flex-shrink: 0;
36
+ display: flex;
37
+ align-items: center;
38
+ gap: 2px;
39
+ }
40
+
41
+ [data-odn-chat-list-filter-trigger] {
42
+ flex-shrink: 0;
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ width: 28px;
47
+ height: 28px;
48
+ margin: 0;
49
+ padding: 0;
50
+ border: none;
51
+ border-radius: 6px;
52
+ background: transparent;
53
+ color: var(--odn-color-black-9);
54
+ cursor: pointer;
55
+ }
56
+ [data-odn-chat-list-filter-trigger]:hover {
57
+ background: var(--odn-color-black-3);
58
+ color: var(--odn-color-black-12);
59
+ }
60
+ [data-odn-chat-list-filter-trigger]:focus-visible {
61
+ outline: none;
62
+ background: var(--odn-color-black-3);
63
+ color: var(--odn-color-black-12);
64
+ }
65
+ [data-odn-chat-list-filter-trigger][aria-pressed=true], [data-odn-chat-list-filter-trigger][aria-expanded=true] {
66
+ background: var(--odn-color-black-3);
67
+ color: var(--odn-color-black-12);
68
+ }
69
+
70
+ [data-odn-chat-list-filter-option] {
71
+ display: flex;
72
+ align-items: center;
73
+ width: 100%;
74
+ min-width: 0;
75
+ gap: 8px;
76
+ }
77
+
78
+ [data-odn-chat-list-filter-option-label] {
79
+ flex: 1 1 auto;
80
+ min-width: 0;
81
+ overflow: hidden;
82
+ text-overflow: ellipsis;
83
+ white-space: nowrap;
84
+ }
85
+
86
+ [data-odn-chat-list-filter-option-check] {
87
+ flex-shrink: 0;
88
+ color: var(--odn-color-black-8);
89
+ }
90
+
91
+ [data-odn-dropdown-content].odn-chat-list-filter-menu [data-odn-dropdown-item-label] {
92
+ overflow: visible;
93
+ }
94
+
95
+ [data-odn-chat-list-body] {
96
+ display: flex;
97
+ flex-direction: column;
98
+ gap: 8px;
99
+ min-width: 0;
100
+ }
101
+
102
+ [data-odn-chat-list-empty] {
103
+ padding: 16px 8px;
104
+ color: var(--odn-color-black-8);
105
+ font-size: 13px;
106
+ text-align: center;
107
+ }
108
+
109
+ [data-odn-chat-list-pinned],
110
+ [data-odn-chat-list-rest] {
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: 2px;
114
+ min-width: 0;
115
+ }
116
+
117
+ /* 置顶 / 最近分区头:视觉同组标题,无折叠 / 菜单等交互 */
118
+ [data-odn-chat-list-pinned-title],
119
+ [data-odn-chat-list-recent-title] {
120
+ padding: 4px 8px 2px;
121
+ color: var(--odn-color-black-9);
122
+ font-size: 12px;
123
+ font-weight: 400;
124
+ line-height: 18px;
125
+ user-select: none;
126
+ pointer-events: none;
127
+ }
128
+
129
+ [data-odn-chat-list-pinned-body],
130
+ [data-odn-chat-list-rest-body] {
131
+ display: flex;
132
+ flex-direction: column;
133
+ gap: 2px;
134
+ min-width: 0;
135
+ }
@@ -0,0 +1,2 @@
1
+ import '../../style';
2
+ import './index.scss';
@@ -0,0 +1,2 @@
1
+ import "../../style";
2
+ import "./index.css";
@@ -4,6 +4,7 @@ import './style';
4
4
  /** @deprecated 仅兼容旧 Host;上移 morph 已改为 FLIP,不再需要 layoutId / LayoutGroup。 */
5
5
  export declare function clarifyDockLayoutId(msgId: string): string;
6
6
  export type { ClarifyInput, ClarifyOption } from './types';
7
+ export { parseClarifyBoundDate, toISODate } from './types';
7
8
  export interface ClarifyDockQuestion {
8
9
  key: string;
9
10
  /** 题面文案。 */
@@ -20,6 +21,11 @@ export interface ClarifyDockSpec {
20
21
  questions: ClarifyDockQuestion[];
21
22
  /** 用户提交后写入的摘要文本;存在则进入完成锁态。 */
22
23
  answeredText?: string;
24
+ /**
25
+ * 单题选项上限(含「其他」),默认 {@link CLARIFY_DOCK_MAX_OPTIONS}。
26
+ * 超过截断业务选项;有「其他」时优先保留末位。硬顶 26(A–Z)。
27
+ */
28
+ maxOptions?: number;
23
29
  }
24
30
  /** 整卷提交:自然语言摘要 + 结构化 data + 锁态小票行。 */
25
31
  export interface ClarifyDockAnswerItem {
@@ -62,8 +68,8 @@ export declare namespace ClarifyDockTrigger {
62
68
  var displayName: string;
63
69
  }
64
70
  /**
65
- * 单题选项上限(含「其他」),与 A–E 徽标一一对应。
66
- * 超过时截断业务选项,优先保留末位「其他」。
71
+ * 单题选项上限默认值(含「其他」)。
72
+ * 业务可通过 {@link ClarifyDockSpec.maxOptions} 覆盖(如 6 / 7)。
67
73
  */
68
74
  export declare const CLARIFY_DOCK_MAX_OPTIONS = 5;
69
75
  export interface ClarifyDockPanelProps {
@@ -14,7 +14,7 @@ import Input from "../input";
14
14
  import Pagination from "../pagination";
15
15
  import { AutoHeight } from "./auto-height";
16
16
  import { discardClarifyDockMorph, stashClarifyDockMorph, takeClarifyDockMorph } from "./morph-handoff";
17
- import { toISODate } from "./types";
17
+ import { parseClarifyBoundDate, toISODate } from "./types";
18
18
  import "./style";
19
19
 
20
20
  /** @deprecated 仅兼容旧 Host;上移 morph 已改为 FLIP,不再需要 layoutId / LayoutGroup。 */
@@ -41,6 +41,8 @@ var MORPH_EASING = 'cubic-bezier(0.22, 1, 0.36, 1)';
41
41
  * 提交锁态:Panel 提交前 stash 视口矩形,Trigger 挂载时 FLIP 上移(不碰 layoutId,避免弄坏翻页/展开)。
42
42
  */
43
43
 
44
+ export { parseClarifyBoundDate, toISODate } from "./types";
45
+
44
46
  /** 整卷提交:自然语言摘要 + 结构化 data + 锁态小票行。 */
45
47
 
46
48
  /** 锁态 / 回看提示:跳过题统一文案(不展示 AI 默认选项)。 */
@@ -207,11 +209,22 @@ var MULTI_UNSELECTED_HOVER_FILL = 'rgba(33, 34, 38, 0.05)';
207
209
  var MULTI_UNSELECTED_ACTIVE_FILL = 'rgba(33, 34, 38, 0.08)';
208
210
 
209
211
  /**
210
- * 单题选项上限(含「其他」),与 A–E 徽标一一对应。
211
- * 超过时截断业务选项,优先保留末位「其他」。
212
+ * 单题选项上限默认值(含「其他」)。
213
+ * 业务可通过 {@link ClarifyDockSpec.maxOptions} 覆盖(如 6 / 7)。
212
214
  */
213
215
  export var CLARIFY_DOCK_MAX_OPTIONS = 5;
214
- var LETTER_BADGES = ['A', 'B', 'C', 'D', 'E'];
216
+
217
+ /** 徽标字母硬顶 A–Z,防止异常大值。 */
218
+ var OPTION_LETTER_HARD_CAP = 26;
219
+ function resolveMaxOptions(maxOptions) {
220
+ var raw = maxOptions !== null && maxOptions !== void 0 ? maxOptions : CLARIFY_DOCK_MAX_OPTIONS;
221
+ if (!Number.isFinite(raw)) return CLARIFY_DOCK_MAX_OPTIONS;
222
+ return Math.max(1, Math.min(Math.floor(raw), OPTION_LETTER_HARD_CAP));
223
+ }
224
+ function optionLetter(idx) {
225
+ if (idx < 0 || idx >= OPTION_LETTER_HARD_CAP) return '';
226
+ return String.fromCharCode(65 + idx);
227
+ }
215
228
  export function ClarifyDockPanel(_ref2) {
216
229
  var msgId = _ref2.msgId,
217
230
  spec = _ref2.spec,
@@ -524,6 +537,7 @@ export function ClarifyDockPanel(_ref2) {
524
537
  "aria-hidden": isSkipped
525
538
  }, /*#__PURE__*/React.createElement(QuestionInput, {
526
539
  input: input,
540
+ maxOptions: resolveMaxOptions(spec.maxOptions),
527
541
  answer: isSkipped ? undefined : answer,
528
542
  otherDraft: otherDraft,
529
543
  dateDraft: dateDraft,
@@ -626,21 +640,21 @@ export function ClarifyDockPanel(_ref2) {
626
640
  /* ================================================================== */
627
641
 
628
642
  /**
629
- * 组装选项列表并强制 ≤ CLARIFY_DOCK_MAX_OPTIONS。
643
+ * 组装选项列表并强制 ≤ maxOptions。
630
644
  * allowOther 时末位固定为「其他」,业务选项占前 N-1 席。
631
645
  */
632
- function withOtherOption(options, allowOther) {
646
+ function withOtherOption(options, allowOther, maxOptions) {
633
647
  if (allowOther) {
634
648
  var withoutDup = options.filter(function (o) {
635
649
  return o.value !== OTHER_VALUE;
636
650
  });
637
- var capped = withoutDup.slice(0, CLARIFY_DOCK_MAX_OPTIONS - 1);
651
+ var capped = withoutDup.slice(0, Math.max(0, maxOptions - 1));
638
652
  return [].concat(_toConsumableArray(capped), [{
639
653
  value: OTHER_VALUE,
640
654
  label: '其他'
641
655
  }]);
642
656
  }
643
- return options.slice(0, CLARIFY_DOCK_MAX_OPTIONS);
657
+ return options.slice(0, maxOptions);
644
658
  }
645
659
 
646
660
  /**
@@ -650,6 +664,7 @@ function withOtherOption(options, allowOther) {
650
664
  */
651
665
  function QuestionInput(_ref3) {
652
666
  var input = _ref3.input,
667
+ maxOptions = _ref3.maxOptions,
653
668
  answer = _ref3.answer,
654
669
  otherDraft = _ref3.otherDraft,
655
670
  dateDraft = _ref3.dateDraft,
@@ -661,7 +676,7 @@ function QuestionInput(_ref3) {
661
676
  onToggleMulti = _ref3.onToggleMulti;
662
677
  if (input.kind === 'options' || input.kind === 'options-multi') {
663
678
  return /*#__PURE__*/React.createElement(OptionsList, {
664
- options: withOtherOption(input.options, input.allowOther),
679
+ options: withOtherOption(input.options, input.allowOther, maxOptions),
665
680
  multi: input.kind === 'options-multi',
666
681
  answer: answer,
667
682
  otherDraft: otherDraft,
@@ -676,6 +691,8 @@ function QuestionInput(_ref3) {
676
691
  "data-odn-clarify-dock-input-row": true
677
692
  }, /*#__PURE__*/React.createElement(DatePicker, {
678
693
  value: dateDraft,
694
+ minDate: parseClarifyBoundDate(input.minDate),
695
+ maxDate: parseClarifyBoundDate(input.maxDate),
679
696
  onChange: function onChange(d) {
680
697
  return onDateChange(d);
681
698
  }
@@ -686,6 +703,8 @@ function QuestionInput(_ref3) {
686
703
  "data-odn-clarify-dock-input-row": true
687
704
  }, /*#__PURE__*/React.createElement(DateRangePicker, {
688
705
  value: dateRangeDraft,
706
+ minDate: parseClarifyBoundDate(input.minDate),
707
+ maxDate: parseClarifyBoundDate(input.maxDate),
689
708
  onChange: function onChange(range) {
690
709
  return onDateRangeChange(range);
691
710
  }
@@ -767,10 +786,9 @@ function OptionsList(_ref4) {
767
786
  role: multi ? 'group' : 'radiogroup',
768
787
  "aria-label": "\u6F84\u6E05\u9009\u9879"
769
788
  }, options.map(function (opt, idx) {
770
- var _LETTER_BADGES$idx;
771
789
  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;
772
790
  var isOther = opt.value === OTHER_VALUE;
773
- var letter = (_LETTER_BADGES$idx = LETTER_BADGES[idx]) !== null && _LETTER_BADGES$idx !== void 0 ? _LETTER_BADGES$idx : '';
791
+ var letter = optionLetter(idx);
774
792
  if (isOther && active) {
775
793
  var editingRow = /*#__PURE__*/React.createElement("div", {
776
794
  "data-odn-clarify-dock-option": true,
@@ -20,9 +20,19 @@ export type ClarifyInput = {
20
20
  } | {
21
21
  kind: 'date';
22
22
  placeholder?: string;
23
+ /** 可选最早日;`Date` 或 `YYYY-MM-DD`。 */
24
+ minDate?: Date | string;
25
+ /** 可选最晚日;`Date` 或 `YYYY-MM-DD`。 */
26
+ maxDate?: Date | string;
23
27
  } | {
24
28
  kind: 'date-range';
25
29
  placeholder?: string;
30
+ /** 可选最早日;`Date` 或 `YYYY-MM-DD`。 */
31
+ minDate?: Date | string;
32
+ /** 可选最晚日;`Date` 或 `YYYY-MM-DD`。 */
33
+ maxDate?: Date | string;
26
34
  };
27
35
  /** Date → 'YYYY-MM-DD' */
28
36
  export declare function toISODate(d: Date): string;
37
+ /** 解析 Host 传入的日期边界;非法则忽略。 */
38
+ export declare function parseClarifyBoundDate(value?: Date | string): Date | undefined;
@@ -8,4 +8,16 @@ export function toISODate(d) {
8
8
  var m = String(d.getMonth() + 1).padStart(2, '0');
9
9
  var day = String(d.getDate()).padStart(2, '0');
10
10
  return "".concat(y, "-").concat(m, "-").concat(day);
11
+ }
12
+
13
+ /** 解析 Host 传入的日期边界;非法则忽略。 */
14
+ export function parseClarifyBoundDate(value) {
15
+ if (value == null) return undefined;
16
+ if (value instanceof Date) {
17
+ return Number.isNaN(value.getTime()) ? undefined : value;
18
+ }
19
+ var s = value.trim();
20
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) return undefined;
21
+ var d = new Date("".concat(s, "T00:00:00"));
22
+ return Number.isNaN(d.getTime()) ? undefined : d;
11
23
  }
package/dist/index.d.ts CHANGED
@@ -57,7 +57,7 @@ export { default as ActionBar, type ActionBarProps } from './action-bar';
57
57
  export { default as AgentStep, type AgentStepProps, type AgentStepGroupProps } from './agent-step';
58
58
  export { default as AgentThink, type AgentThinkProps } from './agent-think';
59
59
  export { default as Approval, type ApprovalProps, type ApprovalSpec, type ApprovalDecision, type ApprovalResolvePayload, type ApprovalSummaryItem, } from './approval';
60
- export { ClarifyDockPanel, ClarifyDockTrigger, useClarifyDockState, clarifyDockLayoutId, CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE, type ClarifyDockPanelProps, type ClarifyDockTriggerProps, type ClarifyDockSpec, type ClarifyDockQuestion, type ClarifyDockAnswerItem, type ClarifyDockResolvePayload, type ClarifyDockMessageState, type ClarifyDockState, type ClarifyDockHostMessage, type ClarifyInput, type ClarifyOption, } from './clarify-dock';
60
+ export { ClarifyDockPanel, ClarifyDockTrigger, useClarifyDockState, clarifyDockLayoutId, CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE, parseClarifyBoundDate, toISODate, type ClarifyDockPanelProps, type ClarifyDockTriggerProps, type ClarifyDockSpec, type ClarifyDockQuestion, type ClarifyDockAnswerItem, type ClarifyDockResolvePayload, type ClarifyDockMessageState, type ClarifyDockState, type ClarifyDockHostMessage, type ClarifyInput, type ClarifyOption, } from './clarify-dock';
61
61
  export { default as Artifact, type ArtifactProps } from './artifact';
62
62
  export { default as Attachments, type AttachmentsProps } from './attachments';
63
63
  export { default as CodeBlock, type CodeBlockProps } from './code-block';
@@ -65,7 +65,8 @@ export { default as Composer, type ComposerProps, type ComposerRef, type Compose
65
65
  export { default as Invocation, InvocationParamPopover, type InvocationProps, type InvocationParamPopoverProps, } from './invocation';
66
66
  export { type ComposerParamPanelContext } from './composer/param-panel';
67
67
  export { default as Mention, type MentionProps } from './mention';
68
- export { default as ChatItem, type ChatItemProps } from './chat-item';
68
+ export { default as ChatItem, formatRelativeTime, type ChatItemProps, } from './chat-item';
69
+ export { default as ChatList, matchChatListFilterTime, matchChatListFilterType, type ChatListProps, type ChatListItem, type ChatListFilterTime, type ChatListFilterType, } from './chat-list';
69
70
  export { default as SkillSlot, type SkillSlotHandle, type SkillSlotProps } from './skill-slot';
70
71
  export { default as ErrorBlock, type ErrorBlockProps } from './error-block';
71
72
  export { default as Fab, type FabProps } from './fab';
package/dist/index.js CHANGED
@@ -63,14 +63,15 @@ export { default as ActionBar } from "./action-bar";
63
63
  export { default as AgentStep } from "./agent-step";
64
64
  export { default as AgentThink } from "./agent-think";
65
65
  export { default as Approval } from "./approval";
66
- export { ClarifyDockPanel, ClarifyDockTrigger, useClarifyDockState, clarifyDockLayoutId, CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE } from "./clarify-dock";
66
+ export { ClarifyDockPanel, ClarifyDockTrigger, useClarifyDockState, clarifyDockLayoutId, CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE, parseClarifyBoundDate, toISODate } from "./clarify-dock";
67
67
  export { default as Artifact } from "./artifact";
68
68
  export { default as Attachments } from "./attachments";
69
69
  export { default as CodeBlock } from "./code-block";
70
70
  export { default as Composer } from "./composer";
71
71
  export { default as Invocation, InvocationParamPopover } from "./invocation";
72
72
  export { default as Mention } from "./mention";
73
- export { default as ChatItem } from "./chat-item";
73
+ export { default as ChatItem, formatRelativeTime } from "./chat-item";
74
+ export { default as ChatList, matchChatListFilterTime, matchChatListFilterType } from "./chat-list";
74
75
  export { default as SkillSlot } from "./skill-slot";
75
76
  export { default as ErrorBlock } from "./error-block";
76
77
  export { default as Fab } from "./fab";
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import type { ParsedCsv } from './parseCsv';
3
+ interface CsvPreviewTableProps {
4
+ data: ParsedCsv;
5
+ }
6
+ /** 预览用只读表格;列数按首行对齐,短行补空、长行多出的列仍展示。 */
7
+ export declare function CsvPreviewTable({ data }: CsvPreviewTableProps): import("react").JSX.Element;
8
+ export {};