one-design-next 0.0.99 → 0.0.100
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.
- package/dist/chat-group/index.d.ts +9 -5
- package/dist/chat-group/index.js +22 -21
- package/dist/chat-group/presence-list.d.ts +4 -2
- package/dist/chat-group/presence-list.js +13 -4
- package/dist/chat-list/index.d.ts +18 -10
- package/dist/chat-list/index.js +90 -41
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
2
|
import './style';
|
|
3
|
-
/**
|
|
3
|
+
/** 组内每页条数。首次展开与后续「展开更多」都按此分页。 */
|
|
4
4
|
export declare const CHAT_GROUP_PREVIEW_LIMIT = 5;
|
|
5
5
|
export interface ChatGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
6
6
|
/** 分组标题 */
|
|
@@ -34,14 +34,18 @@ export interface ChatGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'ti
|
|
|
34
34
|
/** 强制显示 extra(如菜单打开时) */
|
|
35
35
|
extraVisible?: boolean;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* 其间新增超过 N 条也不出现展开按钮。
|
|
37
|
+
* 组内每页条数。默认 5;`false` 关闭分页(搜索命中等)。
|
|
38
|
+
* 首次展开与每次「展开更多」都只增加一页,收起再打开回到第一页。
|
|
40
39
|
*/
|
|
41
40
|
previewLimit?: number | false;
|
|
41
|
+
/**
|
|
42
|
+
* 是否在截断时展示「展开更多」。默认 `true`。
|
|
43
|
+
* 未分组滚动分页时由 ChatList 关闭,改由外层滚动加载。
|
|
44
|
+
*/
|
|
45
|
+
overflowHint?: boolean;
|
|
42
46
|
children?: ReactNode;
|
|
43
47
|
}
|
|
44
|
-
export declare function ChatGroup({ title, collapsible, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, renaming: renamingProp, defaultRenaming, onRenamingChange, onRename, folderIcon, section, extra, extraVisible, previewLimit, children, className, ...rest }: ChatGroupProps): import("react").JSX.Element;
|
|
48
|
+
export declare function ChatGroup({ title, collapsible, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, renaming: renamingProp, defaultRenaming, onRenamingChange, onRename, folderIcon, section, extra, extraVisible, previewLimit, overflowHint, children, className, ...rest }: ChatGroupProps): import("react").JSX.Element;
|
|
45
49
|
export declare namespace ChatGroup {
|
|
46
50
|
var displayName: string;
|
|
47
51
|
}
|
package/dist/chat-group/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
3
3
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
|
-
var _excluded = ["title", "collapsible", "collapsed", "defaultCollapsed", "onCollapsedChange", "renaming", "defaultRenaming", "onRenamingChange", "onRename", "folderIcon", "section", "extra", "extraVisible", "previewLimit", "children", "className"];
|
|
4
|
+
var _excluded = ["title", "collapsible", "collapsed", "defaultCollapsed", "onCollapsedChange", "renaming", "defaultRenaming", "onRenamingChange", "onRename", "folderIcon", "section", "extra", "extraVisible", "previewLimit", "overflowHint", "children", "className"];
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { Children, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
7
7
|
import HoverFill from "../hover-fill";
|
|
@@ -9,7 +9,7 @@ import Icon from "../icon";
|
|
|
9
9
|
import { PRESENCE_TOTAL_MS, PresenceSlots } from "./presence-list";
|
|
10
10
|
import "./style";
|
|
11
11
|
|
|
12
|
-
/**
|
|
12
|
+
/** 组内每页条数。首次展开与后续「展开更多」都按此分页。 */
|
|
13
13
|
export var CHAT_GROUP_PREVIEW_LIMIT = 5;
|
|
14
14
|
function useControllableBool(controlled, defaultValue, onChange) {
|
|
15
15
|
var _useState = useState(defaultValue),
|
|
@@ -26,11 +26,9 @@ function useControllableBool(controlled, defaultValue, onChange) {
|
|
|
26
26
|
function ChatGroupHintRow(_ref) {
|
|
27
27
|
var kind = _ref.kind,
|
|
28
28
|
onExpand = _ref.onExpand,
|
|
29
|
-
_ref$remaining = _ref.remaining,
|
|
30
|
-
remaining = _ref$remaining === void 0 ? 0 : _ref$remaining,
|
|
31
29
|
_ref$expanded = _ref.expanded,
|
|
32
30
|
expanded = _ref$expanded === void 0 ? false : _ref$expanded;
|
|
33
|
-
var label = kind === 'empty' ? '暂无对话' :
|
|
31
|
+
var label = kind === 'empty' ? '暂无对话' : '展开更多';
|
|
34
32
|
if (kind === 'expand') {
|
|
35
33
|
return /*#__PURE__*/React.createElement(HoverFill, {
|
|
36
34
|
"data-odn-chat-group-hint": true,
|
|
@@ -73,6 +71,8 @@ export function ChatGroup(_ref2) {
|
|
|
73
71
|
extra = _ref2.extra,
|
|
74
72
|
extraVisible = _ref2.extraVisible,
|
|
75
73
|
previewLimit = _ref2.previewLimit,
|
|
74
|
+
_ref2$overflowHint = _ref2.overflowHint,
|
|
75
|
+
overflowHint = _ref2$overflowHint === void 0 ? true : _ref2$overflowHint,
|
|
76
76
|
children = _ref2.children,
|
|
77
77
|
className = _ref2.className,
|
|
78
78
|
rest = _objectWithoutProperties(_ref2, _excluded);
|
|
@@ -114,21 +114,22 @@ export function ChatGroup(_ref2) {
|
|
|
114
114
|
setDraft(titleText);
|
|
115
115
|
setRenaming(false);
|
|
116
116
|
};
|
|
117
|
-
var
|
|
118
|
-
var _useState5 = useState(
|
|
117
|
+
var pageSize = previewLimit === false ? Number.POSITIVE_INFINITY : Math.max(1, previewLimit !== null && previewLimit !== void 0 ? previewLimit : CHAT_GROUP_PREVIEW_LIMIT);
|
|
118
|
+
var _useState5 = useState(pageSize),
|
|
119
119
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
visibleCount = _useState6[0],
|
|
121
|
+
setVisibleCount = _useState6[1];
|
|
122
122
|
var _useState7 = useState(false),
|
|
123
123
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
124
124
|
hintLeaving = _useState8[0],
|
|
125
125
|
setHintLeaving = _useState8[1];
|
|
126
126
|
useLayoutEffect(function () {
|
|
127
127
|
if (collapsed) {
|
|
128
|
-
setOverflowOpen(false);
|
|
129
128
|
setHintLeaving(false);
|
|
129
|
+
return;
|
|
130
130
|
}
|
|
131
|
-
|
|
131
|
+
setVisibleCount(pageSize);
|
|
132
|
+
}, [collapsed, pageSize]);
|
|
132
133
|
useEffect(function () {
|
|
133
134
|
if (!hintLeaving) return;
|
|
134
135
|
var t = window.setTimeout(function () {
|
|
@@ -138,32 +139,32 @@ export function ChatGroup(_ref2) {
|
|
|
138
139
|
return window.clearTimeout(t);
|
|
139
140
|
};
|
|
140
141
|
}, [hintLeaving]);
|
|
142
|
+
var childList = Children.toArray(children).filter(Boolean);
|
|
143
|
+
var paginating = Number.isFinite(pageSize);
|
|
144
|
+
var remaining = paginating ? Math.max(0, childList.length - visibleCount) : 0;
|
|
145
|
+
var truncated = !collapsed && paginating && remaining > 0;
|
|
141
146
|
var expandOverflow = function expandOverflow() {
|
|
142
147
|
var _window$matchMedia, _window;
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
var next = visibleCount + pageSize;
|
|
149
|
+
setVisibleCount(next);
|
|
150
|
+
var willFinish = childList.length <= next;
|
|
151
|
+
if (!willFinish || typeof window !== 'undefined' && (_window$matchMedia = (_window = window).matchMedia) !== null && _window$matchMedia !== void 0 && _window$matchMedia.call(_window, '(prefers-reduced-motion: reduce)').matches) {
|
|
145
152
|
return;
|
|
146
153
|
}
|
|
147
154
|
setHintLeaving(true);
|
|
148
155
|
};
|
|
149
|
-
var childList = Children.toArray(children).filter(Boolean);
|
|
150
|
-
var resolvedLimit = previewLimit === false ? Number.POSITIVE_INFINITY : previewLimit !== null && previewLimit !== void 0 ? previewLimit : CHAT_GROUP_PREVIEW_LIMIT;
|
|
151
|
-
// 折叠过程中不要截成预览:否则 scrollHeight 先跳一截,滚动锚定会把列表拽走。
|
|
152
|
-
var truncated = !collapsed && !overflowOpen && Number.isFinite(resolvedLimit) && childList.length > resolvedLimit;
|
|
153
|
-
var remaining = Math.max(0, childList.length - resolvedLimit);
|
|
154
156
|
var expandHint = /*#__PURE__*/React.createElement(ChatGroupHintRow, {
|
|
155
157
|
kind: "expand",
|
|
156
|
-
remaining: remaining,
|
|
157
158
|
expanded: hintLeaving,
|
|
158
159
|
onExpand: expandOverflow
|
|
159
160
|
});
|
|
160
161
|
var body = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(PresenceSlots, {
|
|
161
162
|
enabled: !collapsed,
|
|
162
|
-
displayLimit:
|
|
163
|
+
displayLimit: collapsed || !paginating ? undefined : visibleCount,
|
|
163
164
|
empty: /*#__PURE__*/React.createElement(ChatGroupHintRow, {
|
|
164
165
|
kind: "empty"
|
|
165
166
|
})
|
|
166
|
-
}, children), truncated || hintLeaving ? hintLeaving ? /*#__PURE__*/React.createElement("div", {
|
|
167
|
+
}, children), overflowHint && (truncated || hintLeaving) ? hintLeaving ? /*#__PURE__*/React.createElement("div", {
|
|
167
168
|
"data-odn-chat-group-slot": true,
|
|
168
169
|
"data-odn-chat-group-leave": "swap",
|
|
169
170
|
"aria-hidden": true
|
|
@@ -14,16 +14,18 @@ type Leaving = {
|
|
|
14
14
|
index: number;
|
|
15
15
|
};
|
|
16
16
|
export declare function childSlotKey(child: ReactNode, index: number): string;
|
|
17
|
-
export declare function usePresence(childList: ReactNode[], enabled: boolean): {
|
|
17
|
+
export declare function usePresence(childList: ReactNode[], enabled: boolean, emptyKind?: PresenceKind): {
|
|
18
18
|
entering: Entering | null;
|
|
19
19
|
leaving: Leaving | null;
|
|
20
20
|
};
|
|
21
21
|
export declare function buildPresenceSlots(childList: ReactNode[], entering: Entering | null, leaving: Leaving | null, displayLimit?: number, revealingKeys?: string[] | null): import("react").JSX.Element[];
|
|
22
|
-
export declare function PresenceSlots({ children, enabled, displayLimit, empty, host, }: {
|
|
22
|
+
export declare function PresenceSlots({ children, enabled, displayLimit, empty, emptyKind, host, }: {
|
|
23
23
|
children?: ReactNode;
|
|
24
24
|
enabled?: boolean;
|
|
25
25
|
displayLimit?: number;
|
|
26
26
|
empty?: ReactNode;
|
|
27
|
+
/** 0 ↔ 1 条时的入场/离场。默认 `fade`;置顶组消失用 `shift` 收高度。 */
|
|
28
|
+
emptyKind?: PresenceKind;
|
|
27
29
|
host?: (content: ReactNode, occupied: boolean) => ReactNode;
|
|
28
30
|
}): import("react").JSX.Element;
|
|
29
31
|
export {};
|
|
@@ -15,6 +15,7 @@ function prefersReducedMotion() {
|
|
|
15
15
|
}
|
|
16
16
|
export function usePresence(childList, enabled) {
|
|
17
17
|
var _prevRef$current;
|
|
18
|
+
var emptyKind = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'fade';
|
|
18
19
|
var keys = childList.map(function (child, i) {
|
|
19
20
|
return childSlotKey(child, i);
|
|
20
21
|
});
|
|
@@ -49,7 +50,7 @@ export function usePresence(childList, enabled) {
|
|
|
49
50
|
setLeaving(null);
|
|
50
51
|
setEntering({
|
|
51
52
|
key: added[0],
|
|
52
|
-
kind: prev.keys.length === 0 ?
|
|
53
|
+
kind: prev.keys.length === 0 ? emptyKind : 'shift'
|
|
53
54
|
});
|
|
54
55
|
return;
|
|
55
56
|
}
|
|
@@ -61,12 +62,12 @@ export function usePresence(childList, enabled) {
|
|
|
61
62
|
key: key,
|
|
62
63
|
node: prev.nodes[index],
|
|
63
64
|
index: index,
|
|
64
|
-
kind: nextKeys.length === 0 ?
|
|
65
|
+
kind: nextKeys.length === 0 ? emptyKind : 'shift'
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
68
|
// childList 与 keysSig 同步;只跟签名,避免引用抖动。
|
|
68
69
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
69
|
-
}, [keysSig, enabled]);
|
|
70
|
+
}, [keysSig, enabled, emptyKind]);
|
|
70
71
|
useEffect(function () {
|
|
71
72
|
if (!entering) return;
|
|
72
73
|
var t = window.setTimeout(function () {
|
|
@@ -148,9 +149,11 @@ export function PresenceSlots(_ref) {
|
|
|
148
149
|
displayLimit = _ref.displayLimit,
|
|
149
150
|
_ref$empty = _ref.empty,
|
|
150
151
|
empty = _ref$empty === void 0 ? null : _ref$empty,
|
|
152
|
+
_ref$emptyKind = _ref.emptyKind,
|
|
153
|
+
emptyKind = _ref$emptyKind === void 0 ? 'fade' : _ref$emptyKind,
|
|
151
154
|
host = _ref.host;
|
|
152
155
|
var childList = Children.toArray(children).filter(Boolean);
|
|
153
|
-
var _usePresence = usePresence(childList, enabled),
|
|
156
|
+
var _usePresence = usePresence(childList, enabled, emptyKind),
|
|
154
157
|
entering = _usePresence.entering,
|
|
155
158
|
leaving = _usePresence.leaving;
|
|
156
159
|
var keysSig = childList.map(function (child, i) {
|
|
@@ -170,6 +173,12 @@ export function PresenceSlots(_ref) {
|
|
|
170
173
|
return;
|
|
171
174
|
}
|
|
172
175
|
if (!enabled || prefersReducedMotion()) return;
|
|
176
|
+
if (prevLimit !== undefined && Number.isFinite(prevLimit) && displayLimit !== undefined && Number.isFinite(displayLimit) && displayLimit > prevLimit && childList.length > prevLimit) {
|
|
177
|
+
setRevealingKeys(childList.slice(prevLimit, displayLimit).map(function (child, i) {
|
|
178
|
+
return childSlotKey(child, prevLimit + i);
|
|
179
|
+
}));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
173
182
|
if (prevLimit !== undefined && Number.isFinite(prevLimit) && displayLimit === undefined && childList.length > prevLimit) {
|
|
174
183
|
setRevealingKeys(childList.slice(prevLimit).map(function (child, i) {
|
|
175
184
|
return childSlotKey(child, prevLimit + i);
|
|
@@ -3,6 +3,8 @@ import { type ChatItemProps } from '../chat-item';
|
|
|
3
3
|
import './style';
|
|
4
4
|
/** 系统「未分组」默认 id;不在「分组」模块内渲染。 */
|
|
5
5
|
export declare const CHAT_LIST_UNGROUPED_ID = "ungrouped";
|
|
6
|
+
/** 系统「置顶」组 id。只能通过置顶操作进入,不出现在「移动到」。 */
|
|
7
|
+
export declare const CHAT_LIST_PINNED_ID = "pinned";
|
|
6
8
|
/** 按会话时间筛选(面板不含时间组;`filterTime` 仅受控 API)。 */
|
|
7
9
|
export type ChatListFilterTime = 'all' | 'today' | '7d' | '30d';
|
|
8
10
|
/** 按会话类型筛选:全部 / AI 任务 / 人工客服。 */
|
|
@@ -14,10 +16,6 @@ export interface ChatListGroup {
|
|
|
14
16
|
title: string;
|
|
15
17
|
/** 是否允许重命名。默认 `true`。系统「未分组」建议 `false`。 */
|
|
16
18
|
renamable?: boolean;
|
|
17
|
-
/**
|
|
18
|
-
* 置顶分组:仍在「分组」模块内,排到该模块最前;仍带文件夹 icon。
|
|
19
|
-
*/
|
|
20
|
-
pinned?: boolean;
|
|
21
19
|
}
|
|
22
20
|
export type ChatListItem = Pick<ChatItemProps, 'id' | 'title' | 'active' | 'type' | 'status' | 'pinned' | 'time' | 'groupId'>;
|
|
23
21
|
export interface ChatListProps {
|
|
@@ -25,14 +23,15 @@ export interface ChatListProps {
|
|
|
25
23
|
/** 列表标题。默认「对话」。 */
|
|
26
24
|
title?: ReactNode;
|
|
27
25
|
/**
|
|
28
|
-
*
|
|
26
|
+
* 自定义分组。传入后按「置顶组 → 分组模块 → 未分组」编排。
|
|
27
|
+
* 置顶与分组互斥:置顶会话只出现在「置顶」组,不出现在原组。
|
|
29
28
|
* 标题栏搜索默认关闭,需 `showSearch`。
|
|
30
29
|
* 不传则保持「置顶 / 最近」分区。
|
|
31
30
|
*/
|
|
32
31
|
groups?: ChatListGroup[];
|
|
33
32
|
/**
|
|
34
|
-
*
|
|
35
|
-
* 传入 `groups`
|
|
33
|
+
* 置顶分区标题。视觉同组头。传 `null` 在非分组模式隐藏标题。
|
|
34
|
+
* 传入 `groups` 时渲染为与「未分组」同款的「置顶」组头,默认「置顶」。
|
|
36
35
|
*/
|
|
37
36
|
pinnedSectionTitle?: ReactNode | null;
|
|
38
37
|
/**
|
|
@@ -101,8 +100,6 @@ export interface ChatListProps {
|
|
|
101
100
|
onAddGroup?: (group: ChatListGroup) => void;
|
|
102
101
|
/** 重命名分组 */
|
|
103
102
|
onRenameGroup?: (id: string, title: string) => void;
|
|
104
|
-
/** 置顶 / 取消置顶分组(组块在「分组」模块内排序) */
|
|
105
|
-
onPinGroup?: (id: string, pinned: boolean) => void;
|
|
106
103
|
/**
|
|
107
104
|
* 删除分组。确认后回调;业务侧应将组内会话移入未分组并移除该组。
|
|
108
105
|
*/
|
|
@@ -116,6 +113,17 @@ export interface ChatListProps {
|
|
|
116
113
|
collapsedGroupIds?: string[];
|
|
117
114
|
defaultCollapsedGroupIds?: string[];
|
|
118
115
|
onCollapsedGroupIdsChange?: (ids: string[]) => void;
|
|
116
|
+
/**
|
|
117
|
+
* 自定义组每页条数,传给 ChatGroup `previewLimit`。
|
|
118
|
+
* 首次展开与「展开更多」都按此分页。`false` 关闭。默认 5。
|
|
119
|
+
* 搜索命中仍不截断。
|
|
120
|
+
*/
|
|
121
|
+
groupPageSize?: number | false;
|
|
122
|
+
/**
|
|
123
|
+
* 未分组每页条数。展开后随列表滚动追加,不展示「展开更多」。
|
|
124
|
+
* `false` 关闭(一次铺开)。默认 `false`。搜索命中仍不截断。
|
|
125
|
+
*/
|
|
126
|
+
ungroupedPageSize?: number | false;
|
|
119
127
|
/**
|
|
120
128
|
* 将「最近」列表包进自定义滚动容器。
|
|
121
129
|
* 标题栏与置顶区始终留在外侧,不进入该容器。
|
|
@@ -129,7 +137,7 @@ export declare function matchChatListFilterTime(time: ChatListItem['time'], filt
|
|
|
129
137
|
export declare function matchChatListFilterType(type: ChatListItem['type'], filter: ChatListFilterType): boolean;
|
|
130
138
|
/** 按状态筛选项判断会话是否命中。无 `status` 时仅在「全部」下保留。 */
|
|
131
139
|
export declare function matchChatListFilterStatus(status: ChatListItem['status'], filter: ChatListFilterStatus): boolean;
|
|
132
|
-
export declare function ChatList({ items, title, groups, pinnedSectionTitle, recentSectionTitle, groupsSectionTitle, ungroupedTitle, ungroupedGroupId, filterTime: filterTimeProp, defaultFilterTime, filterType: filterTypeProp, defaultFilterType, onFilterTypeChange, filterStatus: filterStatusProp, defaultFilterStatus, onFilterStatusChange, search: searchProp, defaultSearch, onSearchChange, showSearch, filterOpen: filterOpenProp, defaultFilterOpen, onFilterOpenChange, showEmptyGroups, empty, actionMenuZIndex, filterMenuZIndex, className, onItemClick, onRename, onPin, onMoveToGroup, onDelete, onAddGroup, onRenameGroup,
|
|
140
|
+
export declare function ChatList({ items, title, groups, pinnedSectionTitle, recentSectionTitle, groupsSectionTitle, ungroupedTitle, ungroupedGroupId, filterTime: filterTimeProp, defaultFilterTime, filterType: filterTypeProp, defaultFilterType, onFilterTypeChange, filterStatus: filterStatusProp, defaultFilterStatus, onFilterStatusChange, search: searchProp, defaultSearch, onSearchChange, showSearch, filterOpen: filterOpenProp, defaultFilterOpen, onFilterOpenChange, showEmptyGroups, empty, actionMenuZIndex, filterMenuZIndex, className, onItemClick, onRename, onPin, onMoveToGroup, onDelete, onAddGroup, onRenameGroup, onDeleteGroup, onCreateConversation, renderItem, renderGroupHeader, collapsedGroupIds: collapsedProp, defaultCollapsedGroupIds, onCollapsedGroupIdsChange, groupPageSize, ungroupedPageSize, renderRestScroll, }: ChatListProps): import("react").JSX.Element;
|
|
133
141
|
export declare namespace ChatList {
|
|
134
142
|
var displayName: string;
|
|
135
143
|
}
|
package/dist/chat-list/index.js
CHANGED
|
@@ -15,8 +15,12 @@ import "./style";
|
|
|
15
15
|
|
|
16
16
|
/** 系统「未分组」默认 id;不在「分组」模块内渲染。 */
|
|
17
17
|
export var CHAT_LIST_UNGROUPED_ID = 'ungrouped';
|
|
18
|
+
|
|
19
|
+
/** 系统「置顶」组 id。只能通过置顶操作进入,不出现在「移动到」。 */
|
|
20
|
+
export var CHAT_LIST_PINNED_ID = 'pinned';
|
|
18
21
|
var CHAT_ITEM_ROW_FALLBACK = 40;
|
|
19
22
|
var UNGROUPED_EXPAND_SCROLL_MS = 320;
|
|
23
|
+
var UNGROUPED_SCROLL_LOAD_PX = 80;
|
|
20
24
|
function findScrollParent(el) {
|
|
21
25
|
var node = el;
|
|
22
26
|
while (node) {
|
|
@@ -80,6 +84,9 @@ var STATUS_OPTIONS = [{
|
|
|
80
84
|
value: 'error',
|
|
81
85
|
label: '任务报错'
|
|
82
86
|
}];
|
|
87
|
+
function isPinnedItem(item) {
|
|
88
|
+
return Boolean(item.pinned) || item.groupId === CHAT_LIST_PINNED_ID;
|
|
89
|
+
}
|
|
83
90
|
function parseItemTime(time) {
|
|
84
91
|
if (time === null || time === undefined) return null;
|
|
85
92
|
var t = typeof time === 'number' ? time : time instanceof Date ? time.getTime() : Date.parse(time);
|
|
@@ -239,7 +246,6 @@ export function ChatList(_ref3) {
|
|
|
239
246
|
onDelete = _ref3.onDelete,
|
|
240
247
|
onAddGroup = _ref3.onAddGroup,
|
|
241
248
|
onRenameGroup = _ref3.onRenameGroup,
|
|
242
|
-
onPinGroup = _ref3.onPinGroup,
|
|
243
249
|
onDeleteGroup = _ref3.onDeleteGroup,
|
|
244
250
|
onCreateConversation = _ref3.onCreateConversation,
|
|
245
251
|
_ref3$renderItem = _ref3.renderItem,
|
|
@@ -249,9 +255,12 @@ export function ChatList(_ref3) {
|
|
|
249
255
|
_ref3$defaultCollapse = _ref3.defaultCollapsedGroupIds,
|
|
250
256
|
defaultCollapsedGroupIds = _ref3$defaultCollapse === void 0 ? [] : _ref3$defaultCollapse,
|
|
251
257
|
onCollapsedGroupIdsChange = _ref3.onCollapsedGroupIdsChange,
|
|
258
|
+
groupPageSize = _ref3.groupPageSize,
|
|
259
|
+
_ref3$ungroupedPageSi = _ref3.ungroupedPageSize,
|
|
260
|
+
ungroupedPageSize = _ref3$ungroupedPageSi === void 0 ? false : _ref3$ungroupedPageSi,
|
|
252
261
|
renderRestScroll = _ref3.renderRestScroll;
|
|
253
262
|
var grouped = Array.isArray(groups);
|
|
254
|
-
var resolvedPinnedTitle = pinnedSectionTitle !== undefined ? pinnedSectionTitle :
|
|
263
|
+
var resolvedPinnedTitle = pinnedSectionTitle !== undefined ? pinnedSectionTitle : '置顶';
|
|
255
264
|
var filterTime = filterTimeProp !== null && filterTimeProp !== void 0 ? filterTimeProp : defaultFilterTime;
|
|
256
265
|
var _useControllable = useControllable(filterTypeProp, defaultFilterType, onFilterTypeChange),
|
|
257
266
|
_useControllable2 = _slicedToArray(_useControllable, 2),
|
|
@@ -335,7 +344,7 @@ export function ChatList(_ref3) {
|
|
|
335
344
|
revealUngroupedRef.current = false;
|
|
336
345
|
return;
|
|
337
346
|
}
|
|
338
|
-
var collapse = scroller.querySelector('[data-odn-chat-
|
|
347
|
+
var collapse = scroller.querySelector('[data-odn-chat-list-ungrouped] [data-odn-chat-group-collapse]');
|
|
339
348
|
var finished = false;
|
|
340
349
|
var timer = 0;
|
|
341
350
|
var onEnd;
|
|
@@ -376,37 +385,34 @@ export function ChatList(_ref3) {
|
|
|
376
385
|
});
|
|
377
386
|
}, [items, filterTime, filterType, filterStatus, highlightQuery]);
|
|
378
387
|
var pinnedItems = useMemo(function () {
|
|
379
|
-
return filteredItems.filter(
|
|
380
|
-
return item.pinned;
|
|
381
|
-
});
|
|
388
|
+
return filteredItems.filter(isPinnedItem);
|
|
382
389
|
}, [filteredItems]);
|
|
383
390
|
var restItems = useMemo(function () {
|
|
384
391
|
return filteredItems.filter(function (item) {
|
|
385
|
-
return !item
|
|
392
|
+
return !isPinnedItem(item);
|
|
386
393
|
});
|
|
387
394
|
}, [filteredItems]);
|
|
388
395
|
var _useMemo = useMemo(function () {
|
|
389
|
-
var _system$title;
|
|
396
|
+
var _system$title, _pinnedMeta$title;
|
|
390
397
|
var list = groups !== null && groups !== void 0 ? groups : [];
|
|
391
398
|
var system = list.find(function (g) {
|
|
392
399
|
return g.id === ungroupedGroupId;
|
|
393
400
|
});
|
|
394
|
-
var
|
|
395
|
-
return g.id
|
|
396
|
-
});
|
|
397
|
-
var pinned = custom.filter(function (g) {
|
|
398
|
-
return g.pinned;
|
|
401
|
+
var pinnedMeta = list.find(function (g) {
|
|
402
|
+
return g.id === CHAT_LIST_PINNED_ID;
|
|
399
403
|
});
|
|
400
|
-
var
|
|
401
|
-
return
|
|
404
|
+
var custom = list.filter(function (g) {
|
|
405
|
+
return g.id !== ungroupedGroupId && g.id !== CHAT_LIST_PINNED_ID;
|
|
402
406
|
});
|
|
403
407
|
return {
|
|
404
|
-
customGroups:
|
|
405
|
-
resolvedUngroupedTitle: (_system$title = system === null || system === void 0 ? void 0 : system.title) !== null && _system$title !== void 0 ? _system$title : ungroupedTitle
|
|
408
|
+
customGroups: custom,
|
|
409
|
+
resolvedUngroupedTitle: (_system$title = system === null || system === void 0 ? void 0 : system.title) !== null && _system$title !== void 0 ? _system$title : ungroupedTitle,
|
|
410
|
+
pinnedGroupTitle: resolvedPinnedTitle === null || resolvedPinnedTitle === undefined ? (_pinnedMeta$title = pinnedMeta === null || pinnedMeta === void 0 ? void 0 : pinnedMeta.title) !== null && _pinnedMeta$title !== void 0 ? _pinnedMeta$title : '置顶' : resolvedPinnedTitle
|
|
406
411
|
};
|
|
407
|
-
}, [groups, ungroupedGroupId, ungroupedTitle]),
|
|
412
|
+
}, [groups, ungroupedGroupId, ungroupedTitle, resolvedPinnedTitle]),
|
|
408
413
|
customGroups = _useMemo.customGroups,
|
|
409
|
-
resolvedUngroupedTitle = _useMemo.resolvedUngroupedTitle
|
|
414
|
+
resolvedUngroupedTitle = _useMemo.resolvedUngroupedTitle,
|
|
415
|
+
pinnedGroupTitle = _useMemo.pinnedGroupTitle;
|
|
410
416
|
var groupOptions = useMemo(function () {
|
|
411
417
|
return [].concat(_toConsumableArray(customGroups.map(function (g) {
|
|
412
418
|
return {
|
|
@@ -418,6 +424,10 @@ export function ChatList(_ref3) {
|
|
|
418
424
|
title: resolvedUngroupedTitle
|
|
419
425
|
}]);
|
|
420
426
|
}, [customGroups, ungroupedGroupId, resolvedUngroupedTitle]);
|
|
427
|
+
var emitMoveToGroup = useCallback(function (id, groupId) {
|
|
428
|
+
if (groupId === CHAT_LIST_PINNED_ID) return;
|
|
429
|
+
onMoveToGroup === null || onMoveToGroup === void 0 || onMoveToGroup(id, groupId);
|
|
430
|
+
}, [onMoveToGroup]);
|
|
421
431
|
var isSearching = Boolean(highlightQuery);
|
|
422
432
|
var customSections = useMemo(function () {
|
|
423
433
|
return customGroups.map(function (group) {
|
|
@@ -425,7 +435,7 @@ export function ChatList(_ref3) {
|
|
|
425
435
|
group: group,
|
|
426
436
|
items: filteredItems.filter(function (item) {
|
|
427
437
|
var _item$groupId;
|
|
428
|
-
return !item
|
|
438
|
+
return !isPinnedItem(item) && ((_item$groupId = item.groupId) !== null && _item$groupId !== void 0 ? _item$groupId : '') === group.id;
|
|
429
439
|
})
|
|
430
440
|
};
|
|
431
441
|
}).filter(function (section) {
|
|
@@ -435,10 +445,35 @@ export function ChatList(_ref3) {
|
|
|
435
445
|
var ungroupedItems = useMemo(function () {
|
|
436
446
|
return filteredItems.filter(function (item) {
|
|
437
447
|
var _item$groupId2;
|
|
438
|
-
return !item
|
|
448
|
+
return !isPinnedItem(item) && ((_item$groupId2 = item.groupId) !== null && _item$groupId2 !== void 0 ? _item$groupId2 : ungroupedGroupId) === ungroupedGroupId;
|
|
439
449
|
});
|
|
440
450
|
}, [filteredItems, ungroupedGroupId]);
|
|
441
451
|
var showUngrouped = grouped ? isSearching ? ungroupedItems.length > 0 : showEmptyGroups || ungroupedItems.length > 0 : false;
|
|
452
|
+
var showPinnedGroup = grouped && pinnedItems.length > 0;
|
|
453
|
+
var ungroupedCollapsed = collapsedIds.includes(ungroupedGroupId);
|
|
454
|
+
var ungroupedPage = grouped && !isSearching && ungroupedPageSize !== false ? Math.max(1, ungroupedPageSize) : Number.POSITIVE_INFINITY;
|
|
455
|
+
var _useState13 = useState(ungroupedPage),
|
|
456
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
457
|
+
ungroupedVisible = _useState14[0],
|
|
458
|
+
setUngroupedVisible = _useState14[1];
|
|
459
|
+
useLayoutEffect(function () {
|
|
460
|
+
setUngroupedVisible(Number.isFinite(ungroupedPage) ? ungroupedPage : Number.POSITIVE_INFINITY);
|
|
461
|
+
}, [ungroupedPage, ungroupedCollapsed]);
|
|
462
|
+
var loadMoreUngrouped = useCallback(function () {
|
|
463
|
+
if (!Number.isFinite(ungroupedPage) || ungroupedCollapsed) return;
|
|
464
|
+
var el = listBodyRef.current;
|
|
465
|
+
if (!el || el.clientHeight <= 0) return;
|
|
466
|
+
var remaining = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
467
|
+
var needMore = remaining < UNGROUPED_SCROLL_LOAD_PX || el.scrollHeight <= el.clientHeight + 1;
|
|
468
|
+
if (!needMore) return;
|
|
469
|
+
setUngroupedVisible(function (visible) {
|
|
470
|
+
if (visible >= ungroupedItems.length) return visible;
|
|
471
|
+
return Math.min(visible + ungroupedPage, ungroupedItems.length);
|
|
472
|
+
});
|
|
473
|
+
}, [ungroupedPage, ungroupedCollapsed, ungroupedItems.length]);
|
|
474
|
+
useLayoutEffect(function () {
|
|
475
|
+
loadMoreUngrouped();
|
|
476
|
+
}, [loadMoreUngrouped, ungroupedVisible]);
|
|
442
477
|
var filterMenu = useMemo(function () {
|
|
443
478
|
return buildFilterMenu(filterType, filterStatus);
|
|
444
479
|
}, [filterType, filterStatus]);
|
|
@@ -451,16 +486,16 @@ export function ChatList(_ref3) {
|
|
|
451
486
|
active: item.active,
|
|
452
487
|
type: item.type,
|
|
453
488
|
status: item.status,
|
|
454
|
-
pinned: item.pinned,
|
|
489
|
+
pinned: grouped ? isPinnedItem(item) : item.pinned,
|
|
455
490
|
time: item.time,
|
|
456
|
-
groupId: grouped ? (_item$groupId3 = item.groupId) !== null && _item$groupId3 !== void 0 ? _item$groupId3 : ungroupedGroupId : item.groupId,
|
|
491
|
+
groupId: grouped ? isPinnedItem(item) ? CHAT_LIST_PINNED_ID : (_item$groupId3 = item.groupId) !== null && _item$groupId3 !== void 0 ? _item$groupId3 : ungroupedGroupId : item.groupId,
|
|
457
492
|
groupOptions: grouped ? groupOptions : undefined,
|
|
458
493
|
highlightQuery: highlightQuery || undefined,
|
|
459
494
|
actionMenuZIndex: actionMenuZIndex,
|
|
460
495
|
onClick: onItemClick,
|
|
461
496
|
onRename: onRename,
|
|
462
497
|
onPin: onPin,
|
|
463
|
-
onMoveToGroup: grouped ?
|
|
498
|
+
onMoveToGroup: grouped ? emitMoveToGroup : undefined,
|
|
464
499
|
onDelete: onDelete
|
|
465
500
|
});
|
|
466
501
|
return renderItem(item, node);
|
|
@@ -493,10 +528,6 @@ export function ChatList(_ref3) {
|
|
|
493
528
|
value: 'rename',
|
|
494
529
|
label: '修改分组名称',
|
|
495
530
|
icon: 'pencil-line'
|
|
496
|
-
}] : []), _toConsumableArray(onPinGroup ? [{
|
|
497
|
-
value: 'pin',
|
|
498
|
-
label: group.pinned ? '取消置顶分组' : '置顶分组',
|
|
499
|
-
icon: 'arrow-up-to-line'
|
|
500
531
|
}] : []), _toConsumableArray(onDeleteGroup ? [{
|
|
501
532
|
value: 'delete',
|
|
502
533
|
label: '删除分组',
|
|
@@ -520,11 +551,6 @@ export function ChatList(_ref3) {
|
|
|
520
551
|
setGroupMenuOpenId(null);
|
|
521
552
|
return;
|
|
522
553
|
}
|
|
523
|
-
if (value === 'pin') {
|
|
524
|
-
onPinGroup === null || onPinGroup === void 0 || onPinGroup(group.id, !group.pinned);
|
|
525
|
-
setGroupMenuOpenId(null);
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
554
|
if (value === 'delete') {
|
|
529
555
|
setDeletingGroup(group);
|
|
530
556
|
setGroupMenuOpenId(null);
|
|
@@ -600,7 +626,10 @@ export function ChatList(_ref3) {
|
|
|
600
626
|
ref: listBodyRef,
|
|
601
627
|
"data-odn-chat-list-body": true,
|
|
602
628
|
"data-odn-hover-fill-share": grouped || undefined,
|
|
603
|
-
onScroll:
|
|
629
|
+
onScroll: function onScroll() {
|
|
630
|
+
updateEdgeFade();
|
|
631
|
+
loadMoreUngrouped();
|
|
632
|
+
}
|
|
604
633
|
}, children), /*#__PURE__*/React.createElement("div", {
|
|
605
634
|
"aria-hidden": true,
|
|
606
635
|
"data-odn-chat-list-fade": "top",
|
|
@@ -617,7 +646,11 @@ export function ChatList(_ref3) {
|
|
|
617
646
|
return;
|
|
618
647
|
}
|
|
619
648
|
updateEdgeFade();
|
|
620
|
-
|
|
649
|
+
loadMoreUngrouped();
|
|
650
|
+
var ro = new ResizeObserver(function () {
|
|
651
|
+
updateEdgeFade();
|
|
652
|
+
loadMoreUngrouped();
|
|
653
|
+
});
|
|
621
654
|
ro.observe(el);
|
|
622
655
|
if (el.firstElementChild) {
|
|
623
656
|
ro.observe(el.firstElementChild);
|
|
@@ -625,7 +658,7 @@ export function ChatList(_ref3) {
|
|
|
625
658
|
return function () {
|
|
626
659
|
return ro.disconnect();
|
|
627
660
|
};
|
|
628
|
-
}, [updateEdgeFade, grouped, hasGroupedContent, hasLeanContent]);
|
|
661
|
+
}, [updateEdgeFade, loadMoreUngrouped, grouped, hasGroupedContent, hasLeanContent]);
|
|
629
662
|
var pinnedSection = /*#__PURE__*/React.createElement(PresenceSlots, {
|
|
630
663
|
host: function host(content, occupied) {
|
|
631
664
|
return occupied ? /*#__PURE__*/React.createElement("div", {
|
|
@@ -719,7 +752,21 @@ export function ChatList(_ref3) {
|
|
|
719
752
|
"data-odn-chat-list-toolbar-actions": true
|
|
720
753
|
}, filterTrigger)), grouped ? !hasGroupedContent ? /*#__PURE__*/React.createElement("div", {
|
|
721
754
|
"data-odn-chat-list-empty": true
|
|
722
|
-
}, empty !== null && empty !== void 0 ? empty : null) : renderListScroll( /*#__PURE__*/React.createElement(React.Fragment, null,
|
|
755
|
+
}, empty !== null && empty !== void 0 ? empty : null) : renderListScroll( /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(PresenceSlots, {
|
|
756
|
+
emptyKind: "shift"
|
|
757
|
+
}, showPinnedGroup ? /*#__PURE__*/React.createElement(ChatGroup, {
|
|
758
|
+
key: CHAT_LIST_PINNED_ID,
|
|
759
|
+
"data-odn-chat-list-pinned": true,
|
|
760
|
+
title: pinnedGroupTitle,
|
|
761
|
+
section: true,
|
|
762
|
+
collapsed: collapsedIds.includes(CHAT_LIST_PINNED_ID),
|
|
763
|
+
onCollapsedChange: function onCollapsedChange(next) {
|
|
764
|
+
setCollapsedIds(next ? Array.from(new Set([].concat(_toConsumableArray(collapsedIds), [CHAT_LIST_PINNED_ID]))) : collapsedIds.filter(function (id) {
|
|
765
|
+
return id !== CHAT_LIST_PINNED_ID;
|
|
766
|
+
}));
|
|
767
|
+
},
|
|
768
|
+
previewLimit: false
|
|
769
|
+
}, pinnedItems.map(renderChatItem)) : null), showGroupsModule ? /*#__PURE__*/React.createElement("div", {
|
|
723
770
|
"data-odn-chat-list-groups": true
|
|
724
771
|
}, /*#__PURE__*/React.createElement("div", {
|
|
725
772
|
"data-odn-chat-list-section-header": true
|
|
@@ -759,15 +806,16 @@ export function ChatList(_ref3) {
|
|
|
759
806
|
} : undefined,
|
|
760
807
|
extraVisible: menuOpen,
|
|
761
808
|
extra: renderGroupActions(group, {
|
|
762
|
-
showMenu: Boolean(onRenameGroup ||
|
|
809
|
+
showMenu: Boolean(onRenameGroup || onDeleteGroup),
|
|
763
810
|
showAddConversation: Boolean(onCreateConversation)
|
|
764
811
|
}),
|
|
765
|
-
previewLimit: isSearching ? false :
|
|
812
|
+
previewLimit: isSearching ? false : groupPageSize
|
|
766
813
|
}, sectionItems.map(renderChatItem));
|
|
767
814
|
}))) : null, showUngrouped ? /*#__PURE__*/React.createElement(ChatGroup, {
|
|
815
|
+
"data-odn-chat-list-ungrouped": true,
|
|
768
816
|
title: resolvedUngroupedTitle,
|
|
769
817
|
section: true,
|
|
770
|
-
collapsed:
|
|
818
|
+
collapsed: ungroupedCollapsed,
|
|
771
819
|
onCollapsedChange: function onCollapsedChange(next) {
|
|
772
820
|
revealUngroupedRef.current = !next;
|
|
773
821
|
setCollapsedIds(next ? Array.from(new Set([].concat(_toConsumableArray(collapsedIds), [ungroupedGroupId]))) : collapsedIds.filter(function (id) {
|
|
@@ -781,7 +829,8 @@ export function ChatList(_ref3) {
|
|
|
781
829
|
}, {
|
|
782
830
|
showAddConversation: Boolean(onCreateConversation)
|
|
783
831
|
}),
|
|
784
|
-
previewLimit: false
|
|
832
|
+
previewLimit: isSearching || !Number.isFinite(ungroupedVisible) ? false : ungroupedVisible,
|
|
833
|
+
overflowHint: false
|
|
785
834
|
}, ungroupedItems.map(renderChatItem)) : null)) : !hasLeanContent ? /*#__PURE__*/React.createElement("div", {
|
|
786
835
|
"data-odn-chat-list-empty": true
|
|
787
836
|
}, empty !== null && empty !== void 0 ? empty : null) : renderRestScroll ? /*#__PURE__*/React.createElement(React.Fragment, null, pinnedSection, restSection ? renderRestScroll(restSection) : null) : renderListScroll( /*#__PURE__*/React.createElement(React.Fragment, null, pinnedSection, restSection)), /*#__PURE__*/React.createElement(Dialog, {
|
package/dist/index.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export { ARTIFACT_DEDICATED_FILE_ICON_TYPES, ARTIFACT_FILE_GLOW_COLORS, ARTIFACT
|
|
|
59
59
|
export { default as Attachments, type AttachmentsProps } from './attachments';
|
|
60
60
|
export { CHAT_GROUP_PREVIEW_LIMIT, default as ChatGroup, type ChatGroupProps, } from './chat-group';
|
|
61
61
|
export { default as ChatItem, formatRelativeTime, type ChatItemGroupOption, type ChatItemProps, } from './chat-item';
|
|
62
|
-
export { CHAT_LIST_UNGROUPED_ID, default as ChatList, matchChatListFilterStatus, matchChatListFilterTime, matchChatListFilterType, type ChatListFilterStatus, type ChatListFilterTime, type ChatListFilterType, type ChatListGroup, type ChatListItem, type ChatListProps, } from './chat-list';
|
|
62
|
+
export { CHAT_LIST_PINNED_ID, CHAT_LIST_UNGROUPED_ID, default as ChatList, matchChatListFilterStatus, matchChatListFilterTime, matchChatListFilterType, type ChatListFilterStatus, type ChatListFilterTime, type ChatListFilterType, type ChatListGroup, type ChatListItem, type ChatListProps, } from './chat-list';
|
|
63
63
|
export { CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE, ClarifyDockPanel, ClarifyDockTrigger, clarifyDockLayoutId, parseClarifyBoundDate, toISODate, useClarifyDockState, type ClarifyDockAnswerItem, type ClarifyDockHostMessage, type ClarifyDockMessageState, type ClarifyDockPanelProps, type ClarifyDockQuestion, type ClarifyDockResolvePayload, type ClarifyDockSpec, type ClarifyDockState, type ClarifyDockTriggerProps, type ClarifyInput, type ClarifyOption, } from './clarify-dock';
|
|
64
64
|
export { default as CodeBlock, type CodeBlockProps } from './code-block';
|
|
65
65
|
export { default as Composer, type ComposerProps, type ComposerRef, type ComposerSkillSlotProps, type ComposerTool, type ComposerToolConfig, } from './composer';
|
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ export { ARTIFACT_DEDICATED_FILE_ICON_TYPES, ARTIFACT_FILE_GLOW_COLORS, ARTIFACT
|
|
|
65
65
|
export { default as Attachments } from "./attachments";
|
|
66
66
|
export { CHAT_GROUP_PREVIEW_LIMIT, default as ChatGroup } from "./chat-group";
|
|
67
67
|
export { default as ChatItem, formatRelativeTime } from "./chat-item";
|
|
68
|
-
export { CHAT_LIST_UNGROUPED_ID, default as ChatList, matchChatListFilterStatus, matchChatListFilterTime, matchChatListFilterType } from "./chat-list";
|
|
68
|
+
export { CHAT_LIST_PINNED_ID, CHAT_LIST_UNGROUPED_ID, default as ChatList, matchChatListFilterStatus, matchChatListFilterTime, matchChatListFilterType } from "./chat-list";
|
|
69
69
|
export { CLARIFY_DOCK_MAX_OPTIONS, CLARIFY_DOCK_SKIPPED_LABEL, CLARIFY_DOCK_SKIPPED_VALUE, ClarifyDockPanel, ClarifyDockTrigger, clarifyDockLayoutId, parseClarifyBoundDate, toISODate, useClarifyDockState } from "./clarify-dock";
|
|
70
70
|
export { default as CodeBlock } from "./code-block";
|
|
71
71
|
export { default as Composer } from "./composer";
|