@arbidocs/blocks 0.4.29 → 0.4.31
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/agents/index.cjs +212 -212
- package/dist/agents/index.js +3 -3
- package/dist/chat/index.cjs +63 -63
- package/dist/chat/index.js +2 -2
- package/dist/{chunk-7FF473XB.js → chunk-3NZR6PAG.js} +3 -3
- package/dist/{chunk-7FF473XB.js.map → chunk-3NZR6PAG.js.map} +1 -1
- package/dist/{chunk-CRIKTUEU.cjs → chunk-46IU3UPF.cjs} +3 -3
- package/dist/{chunk-CRIKTUEU.cjs.map → chunk-46IU3UPF.cjs.map} +1 -1
- package/dist/{chunk-ZJ6RIPFS.js → chunk-C75S6USL.js} +70 -11
- package/dist/chunk-C75S6USL.js.map +1 -0
- package/dist/{chunk-L6YRTT5M.cjs → chunk-CQWRVIJC.cjs} +6 -6
- package/dist/{chunk-L6YRTT5M.cjs.map → chunk-CQWRVIJC.cjs.map} +1 -1
- package/dist/{chunk-U2E3WT3J.js → chunk-D5T53XCL.js} +3 -3
- package/dist/{chunk-U2E3WT3J.js.map → chunk-D5T53XCL.js.map} +1 -1
- package/dist/{chunk-ZXGBUHES.cjs → chunk-FRRDPYBR.cjs} +3 -3
- package/dist/{chunk-ZXGBUHES.cjs.map → chunk-FRRDPYBR.cjs.map} +1 -1
- package/dist/{chunk-LXC5PTTI.cjs → chunk-GVQOBJKR.cjs} +71 -9
- package/dist/chunk-GVQOBJKR.cjs.map +1 -0
- package/dist/{chunk-G4YOH5DU.cjs → chunk-LPXAWW62.cjs} +4 -4
- package/dist/chunk-LPXAWW62.cjs.map +1 -0
- package/dist/{chunk-HER7MTRR.js → chunk-PH7YTYYH.js} +4 -4
- package/dist/chunk-PH7YTYYH.js.map +1 -0
- package/dist/{chunk-I7FJS7WG.js → chunk-Y2LWA4ZO.js} +6 -6
- package/dist/{chunk-I7FJS7WG.js.map → chunk-Y2LWA4ZO.js.map} +1 -1
- package/dist/facts/index.cjs +1 -1
- package/dist/facts/index.js +1 -1
- package/dist/files/index.cjs +1 -1
- package/dist/files/index.js +1 -1
- package/dist/index.cjs +622 -610
- package/dist/index.js +12 -12
- package/dist/retrieval/index.cjs +36 -36
- package/dist/retrieval/index.js +1 -1
- package/dist/settings/index.cjs +9 -9
- package/dist/settings/index.cjs.map +1 -1
- package/dist/settings/index.js +7 -7
- package/dist/settings/index.js.map +1 -1
- package/dist/shell/ActionCluster.d.ts +2 -1
- package/dist/shell/StatusRow.d.ts +8 -0
- package/dist/shell/index.cjs +54 -42
- package/dist/shell/index.d.ts +2 -1
- package/dist/shell/index.js +1 -1
- package/dist/shell/status-row-styles.d.ts +8 -0
- package/dist/site/index.cjs +5 -5
- package/dist/site/index.js +1 -1
- package/dist/studio/index.cjs +1 -1
- package/dist/studio/index.js +1 -1
- package/package.json +3 -3
- package/src/tokens.css +23 -23
- package/dist/chunk-G4YOH5DU.cjs.map +0 -1
- package/dist/chunk-HER7MTRR.js.map +0 -1
- package/dist/chunk-LXC5PTTI.cjs.map +0 -1
- package/dist/chunk-ZJ6RIPFS.js.map +0 -1
|
@@ -12,6 +12,7 @@ export interface ActionClusterProps {
|
|
|
12
12
|
/** Status pill (remote control); `bar` only. Other layouts show status in their own rows. */
|
|
13
13
|
status?: ReactNode;
|
|
14
14
|
/** Notification bell (the kit's NotificationBell, or a `Sidebar.BadgeRow`). */
|
|
15
|
+
mail?: ReactNode;
|
|
15
16
|
bell?: ReactNode;
|
|
16
17
|
/** Contacts / messages entry with its own badge (a `Sidebar.BadgeRow`). */
|
|
17
18
|
contacts?: ReactNode;
|
|
@@ -30,4 +31,4 @@ export interface ActionClusterProps {
|
|
|
30
31
|
* order, so nothing moves when the rail expands; the account menu holds everything else (help,
|
|
31
32
|
* settings, tips, processing).
|
|
32
33
|
*/
|
|
33
|
-
export declare function ActionCluster({ layout, status, bell, contacts, account, label, 'data-testid': testId, }: ActionClusterProps): import("react").JSX.Element;
|
|
34
|
+
export declare function ActionCluster({ layout, status, mail, bell, contacts, account, label, 'data-testid': testId, }: ActionClusterProps): import("react").JSX.Element;
|
|
@@ -18,3 +18,11 @@ export interface StatusRowProps {
|
|
|
18
18
|
* something failed), so a quiet app shows nothing. Announced politely to screen readers.
|
|
19
19
|
*/
|
|
20
20
|
export declare function StatusRow({ tone, label, onClick, compact, icon, 'data-testid': testId, }: StatusRowProps): import("react").JSX.Element;
|
|
21
|
+
/** Short live state at a navigation row's right edge, replacing inventory counts. */
|
|
22
|
+
export declare function StatusBadge({ tone, label, onClick, onDismiss, 'data-testid': testId, }: {
|
|
23
|
+
tone: StatusRowTone;
|
|
24
|
+
label: string;
|
|
25
|
+
onClick?: () => void;
|
|
26
|
+
onDismiss?: () => void;
|
|
27
|
+
'data-testid'?: string;
|
|
28
|
+
}): import("react").JSX.Element;
|
package/dist/shell/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkGVQOBJKR_cjs = require('../chunk-GVQOBJKR.cjs');
|
|
5
5
|
require('../chunk-OB5F4577.cjs');
|
|
6
6
|
var chunk5B4PXAKI_cjs = require('../chunk-5B4PXAKI.cjs');
|
|
7
7
|
var chunkXKSFJYOD_cjs = require('../chunk-XKSFJYOD.cjs');
|
|
@@ -15,167 +15,179 @@ require('../chunk-MHVNT4J3.cjs');
|
|
|
15
15
|
|
|
16
16
|
Object.defineProperty(exports, "ActionCluster", {
|
|
17
17
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunkGVQOBJKR_cjs.ActionCluster; }
|
|
19
19
|
});
|
|
20
20
|
Object.defineProperty(exports, "AskField", {
|
|
21
21
|
enumerable: true,
|
|
22
|
-
get: function () { return
|
|
22
|
+
get: function () { return chunkGVQOBJKR_cjs.AskField; }
|
|
23
23
|
});
|
|
24
24
|
Object.defineProperty(exports, "AskRow", {
|
|
25
25
|
enumerable: true,
|
|
26
|
-
get: function () { return
|
|
26
|
+
get: function () { return chunkGVQOBJKR_cjs.AskRow; }
|
|
27
27
|
});
|
|
28
28
|
Object.defineProperty(exports, "AskTrigger", {
|
|
29
29
|
enumerable: true,
|
|
30
|
-
get: function () { return
|
|
30
|
+
get: function () { return chunkGVQOBJKR_cjs.AskTrigger; }
|
|
31
31
|
});
|
|
32
32
|
Object.defineProperty(exports, "DEFAULT_ASK_FIELD_LABELS", {
|
|
33
33
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
34
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_ASK_FIELD_LABELS; }
|
|
35
35
|
});
|
|
36
36
|
Object.defineProperty(exports, "DEFAULT_INSTALL_PROMPT_LABELS", {
|
|
37
37
|
enumerable: true,
|
|
38
|
-
get: function () { return
|
|
38
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_INSTALL_PROMPT_LABELS; }
|
|
39
39
|
});
|
|
40
40
|
Object.defineProperty(exports, "DEFAULT_MOBILE_BARS_LABELS", {
|
|
41
41
|
enumerable: true,
|
|
42
|
-
get: function () { return
|
|
42
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_MOBILE_BARS_LABELS; }
|
|
43
43
|
});
|
|
44
44
|
Object.defineProperty(exports, "DEFAULT_OFFLINE_PILL_LABELS", {
|
|
45
45
|
enumerable: true,
|
|
46
|
-
get: function () { return
|
|
46
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_OFFLINE_PILL_LABELS; }
|
|
47
47
|
});
|
|
48
48
|
Object.defineProperty(exports, "DEFAULT_REMOTE_CONTROL_PILL_LABELS", {
|
|
49
49
|
enumerable: true,
|
|
50
|
-
get: function () { return
|
|
50
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_REMOTE_CONTROL_PILL_LABELS; }
|
|
51
51
|
});
|
|
52
52
|
Object.defineProperty(exports, "DEFAULT_SIDEBAR_LABELS", {
|
|
53
53
|
enumerable: true,
|
|
54
|
-
get: function () { return
|
|
54
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_SIDEBAR_LABELS; }
|
|
55
55
|
});
|
|
56
56
|
Object.defineProperty(exports, "DEFAULT_TIP_CARD_LABELS", {
|
|
57
57
|
enumerable: true,
|
|
58
|
-
get: function () { return
|
|
58
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_TIP_CARD_LABELS; }
|
|
59
59
|
});
|
|
60
60
|
Object.defineProperty(exports, "DEFAULT_WORKSPACE_KIND_LABELS", {
|
|
61
61
|
enumerable: true,
|
|
62
|
-
get: function () { return
|
|
62
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_WORKSPACE_KIND_LABELS; }
|
|
63
63
|
});
|
|
64
64
|
Object.defineProperty(exports, "DEFAULT_WORKSPACE_SWITCHER_LABELS", {
|
|
65
65
|
enumerable: true,
|
|
66
|
-
get: function () { return
|
|
66
|
+
get: function () { return chunkGVQOBJKR_cjs.DEFAULT_WORKSPACE_SWITCHER_LABELS; }
|
|
67
67
|
});
|
|
68
68
|
Object.defineProperty(exports, "INSTALL_PROMPT_DISMISSED_KEY", {
|
|
69
69
|
enumerable: true,
|
|
70
|
-
get: function () { return
|
|
70
|
+
get: function () { return chunkGVQOBJKR_cjs.INSTALL_PROMPT_DISMISSED_KEY; }
|
|
71
71
|
});
|
|
72
72
|
Object.defineProperty(exports, "InfoBar", {
|
|
73
73
|
enumerable: true,
|
|
74
|
-
get: function () { return
|
|
74
|
+
get: function () { return chunkGVQOBJKR_cjs.InfoBar; }
|
|
75
75
|
});
|
|
76
76
|
Object.defineProperty(exports, "InstallPrompt", {
|
|
77
77
|
enumerable: true,
|
|
78
|
-
get: function () { return
|
|
78
|
+
get: function () { return chunkGVQOBJKR_cjs.InstallPrompt; }
|
|
79
79
|
});
|
|
80
80
|
Object.defineProperty(exports, "MobileAppBar", {
|
|
81
81
|
enumerable: true,
|
|
82
|
-
get: function () { return
|
|
82
|
+
get: function () { return chunkGVQOBJKR_cjs.MobileAppBar; }
|
|
83
83
|
});
|
|
84
84
|
Object.defineProperty(exports, "MobileTabBar", {
|
|
85
85
|
enumerable: true,
|
|
86
|
-
get: function () { return
|
|
86
|
+
get: function () { return chunkGVQOBJKR_cjs.MobileTabBar; }
|
|
87
87
|
});
|
|
88
88
|
Object.defineProperty(exports, "NotificationBell", {
|
|
89
89
|
enumerable: true,
|
|
90
|
-
get: function () { return
|
|
90
|
+
get: function () { return chunkGVQOBJKR_cjs.NotificationBell; }
|
|
91
91
|
});
|
|
92
92
|
Object.defineProperty(exports, "OfflinePill", {
|
|
93
93
|
enumerable: true,
|
|
94
|
-
get: function () { return
|
|
94
|
+
get: function () { return chunkGVQOBJKR_cjs.OfflinePill; }
|
|
95
95
|
});
|
|
96
96
|
Object.defineProperty(exports, "RemoteControlPill", {
|
|
97
97
|
enumerable: true,
|
|
98
|
-
get: function () { return
|
|
98
|
+
get: function () { return chunkGVQOBJKR_cjs.RemoteControlPill; }
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(exports, "STATUS_ROW_BASE_CLASS", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get: function () { return chunkGVQOBJKR_cjs.STATUS_ROW_BASE_CLASS; }
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(exports, "STATUS_ROW_TONES", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
get: function () { return chunkGVQOBJKR_cjs.STATUS_ROW_TONES; }
|
|
99
107
|
});
|
|
100
108
|
Object.defineProperty(exports, "Sidebar", {
|
|
101
109
|
enumerable: true,
|
|
102
|
-
get: function () { return
|
|
110
|
+
get: function () { return chunkGVQOBJKR_cjs.Sidebar; }
|
|
103
111
|
});
|
|
104
112
|
Object.defineProperty(exports, "SidebarBadgeRow", {
|
|
105
113
|
enumerable: true,
|
|
106
|
-
get: function () { return
|
|
114
|
+
get: function () { return chunkGVQOBJKR_cjs.SidebarBadgeRow; }
|
|
107
115
|
});
|
|
108
116
|
Object.defineProperty(exports, "SidebarRowAction", {
|
|
109
117
|
enumerable: true,
|
|
110
|
-
get: function () { return
|
|
118
|
+
get: function () { return chunkGVQOBJKR_cjs.SidebarRowAction; }
|
|
111
119
|
});
|
|
112
120
|
Object.defineProperty(exports, "SidebarRowHoverContext", {
|
|
113
121
|
enumerable: true,
|
|
114
|
-
get: function () { return
|
|
122
|
+
get: function () { return chunkGVQOBJKR_cjs.SidebarRowHoverContext; }
|
|
115
123
|
});
|
|
116
124
|
Object.defineProperty(exports, "SplitLayout", {
|
|
117
125
|
enumerable: true,
|
|
118
|
-
get: function () { return
|
|
126
|
+
get: function () { return chunkGVQOBJKR_cjs.SplitLayout; }
|
|
127
|
+
});
|
|
128
|
+
Object.defineProperty(exports, "StatusBadge", {
|
|
129
|
+
enumerable: true,
|
|
130
|
+
get: function () { return chunkGVQOBJKR_cjs.StatusBadge; }
|
|
119
131
|
});
|
|
120
132
|
Object.defineProperty(exports, "StatusRow", {
|
|
121
133
|
enumerable: true,
|
|
122
|
-
get: function () { return
|
|
134
|
+
get: function () { return chunkGVQOBJKR_cjs.StatusRow; }
|
|
123
135
|
});
|
|
124
136
|
Object.defineProperty(exports, "TipCard", {
|
|
125
137
|
enumerable: true,
|
|
126
|
-
get: function () { return
|
|
138
|
+
get: function () { return chunkGVQOBJKR_cjs.TipCard; }
|
|
127
139
|
});
|
|
128
140
|
Object.defineProperty(exports, "UserMenu", {
|
|
129
141
|
enumerable: true,
|
|
130
|
-
get: function () { return
|
|
142
|
+
get: function () { return chunkGVQOBJKR_cjs.UserMenu; }
|
|
131
143
|
});
|
|
132
144
|
Object.defineProperty(exports, "WorkspaceIdentity", {
|
|
133
145
|
enumerable: true,
|
|
134
|
-
get: function () { return
|
|
146
|
+
get: function () { return chunkGVQOBJKR_cjs.WorkspaceIdentity; }
|
|
135
147
|
});
|
|
136
148
|
Object.defineProperty(exports, "WorkspaceSwitcher", {
|
|
137
149
|
enumerable: true,
|
|
138
|
-
get: function () { return
|
|
150
|
+
get: function () { return chunkGVQOBJKR_cjs.WorkspaceSwitcher; }
|
|
139
151
|
});
|
|
140
152
|
Object.defineProperty(exports, "getInstallInstructions", {
|
|
141
153
|
enumerable: true,
|
|
142
|
-
get: function () { return
|
|
154
|
+
get: function () { return chunkGVQOBJKR_cjs.getInstallInstructions; }
|
|
143
155
|
});
|
|
144
156
|
Object.defineProperty(exports, "initInstallPrompt", {
|
|
145
157
|
enumerable: true,
|
|
146
|
-
get: function () { return
|
|
158
|
+
get: function () { return chunkGVQOBJKR_cjs.initInstallPrompt; }
|
|
147
159
|
});
|
|
148
160
|
Object.defineProperty(exports, "isIosDevice", {
|
|
149
161
|
enumerable: true,
|
|
150
|
-
get: function () { return
|
|
162
|
+
get: function () { return chunkGVQOBJKR_cjs.isIosDevice; }
|
|
151
163
|
});
|
|
152
164
|
Object.defineProperty(exports, "promptAppInstall", {
|
|
153
165
|
enumerable: true,
|
|
154
|
-
get: function () { return
|
|
166
|
+
get: function () { return chunkGVQOBJKR_cjs.promptAppInstall; }
|
|
155
167
|
});
|
|
156
168
|
Object.defineProperty(exports, "resolveSidebarLayout", {
|
|
157
169
|
enumerable: true,
|
|
158
|
-
get: function () { return
|
|
170
|
+
get: function () { return chunkGVQOBJKR_cjs.resolveSidebarLayout; }
|
|
159
171
|
});
|
|
160
172
|
Object.defineProperty(exports, "useInstallPrompt", {
|
|
161
173
|
enumerable: true,
|
|
162
|
-
get: function () { return
|
|
174
|
+
get: function () { return chunkGVQOBJKR_cjs.useInstallPrompt; }
|
|
163
175
|
});
|
|
164
176
|
Object.defineProperty(exports, "useSidebarContext", {
|
|
165
177
|
enumerable: true,
|
|
166
|
-
get: function () { return
|
|
178
|
+
get: function () { return chunkGVQOBJKR_cjs.useSidebarContext; }
|
|
167
179
|
});
|
|
168
180
|
Object.defineProperty(exports, "useSidebarSettle", {
|
|
169
181
|
enumerable: true,
|
|
170
|
-
get: function () { return
|
|
182
|
+
get: function () { return chunkGVQOBJKR_cjs.useSidebarSettle; }
|
|
171
183
|
});
|
|
172
184
|
Object.defineProperty(exports, "workspaceKindColor", {
|
|
173
185
|
enumerable: true,
|
|
174
|
-
get: function () { return
|
|
186
|
+
get: function () { return chunkGVQOBJKR_cjs.workspaceKindColor; }
|
|
175
187
|
});
|
|
176
188
|
Object.defineProperty(exports, "workspaceKindMeta", {
|
|
177
189
|
enumerable: true,
|
|
178
|
-
get: function () { return
|
|
190
|
+
get: function () { return chunkGVQOBJKR_cjs.workspaceKindMeta; }
|
|
179
191
|
});
|
|
180
192
|
Object.defineProperty(exports, "DEFAULT_TAB_HEADER_LABELS", {
|
|
181
193
|
enumerable: true,
|
package/dist/shell/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { getInstallInstructions, isIosDevice, type InstallGuide, type InstallIns
|
|
|
11
11
|
export { useShellBottomInset, SHELL_BOTTOM_INSET_VAR } from '../lib/bottom-inset';
|
|
12
12
|
export { ActionCluster, type ActionClusterProps } from './ActionCluster';
|
|
13
13
|
export { ToolButton, type ToolButtonProps } from './ToolButton';
|
|
14
|
-
export { StatusRow, type StatusRowProps, type StatusRowTone } from './StatusRow';
|
|
14
|
+
export { StatusRow, StatusBadge, type StatusRowProps, type StatusRowTone } from './StatusRow';
|
|
15
15
|
export { OfflinePill, DEFAULT_OFFLINE_PILL_LABELS, type OfflinePillLabels, type OfflinePillProps, type OfflinePillTone, } from './OfflinePill';
|
|
16
16
|
export { RemoteControlPill, DEFAULT_REMOTE_CONTROL_PILL_LABELS, type RemoteControlPillLabels, type RemoteControlPillProps, } from './RemoteControlPill';
|
|
17
17
|
export { TipCard, DEFAULT_TIP_CARD_LABELS, type TipCardLabels, type TipCardProps } from './TipCard';
|
|
@@ -25,3 +25,4 @@ export { UserMenu, type UserMenuProps, type UserMenuItem, type UserMenuStatus, }
|
|
|
25
25
|
export { NotificationBell, type NotificationBellProps } from '@arbidocs/react/shell';
|
|
26
26
|
export { SplitLayout, type SplitLayoutProps } from './SplitLayout';
|
|
27
27
|
export { Toaster, DEFAULT_DOCK_WIDTH, type ShellToasterProps } from './Toaster';
|
|
28
|
+
export { STATUS_ROW_BASE_CLASS, STATUS_ROW_TONES } from './status-row-styles';
|
package/dist/shell/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { ActionCluster, AskField, AskRow, AskTrigger, DEFAULT_ASK_FIELD_LABELS, DEFAULT_INSTALL_PROMPT_LABELS, DEFAULT_MOBILE_BARS_LABELS, DEFAULT_OFFLINE_PILL_LABELS, DEFAULT_REMOTE_CONTROL_PILL_LABELS, DEFAULT_SIDEBAR_LABELS, DEFAULT_TIP_CARD_LABELS, DEFAULT_WORKSPACE_KIND_LABELS, DEFAULT_WORKSPACE_SWITCHER_LABELS, INSTALL_PROMPT_DISMISSED_KEY, InfoBar, InstallPrompt, MobileAppBar, MobileTabBar, NotificationBell, OfflinePill, RemoteControlPill, Sidebar, SidebarBadgeRow, SidebarRowAction, SidebarRowHoverContext, SplitLayout, StatusRow, TipCard, UserMenu, WorkspaceIdentity, WorkspaceSwitcher, getInstallInstructions, initInstallPrompt, isIosDevice, promptAppInstall, resolveSidebarLayout, useInstallPrompt, useSidebarContext, useSidebarSettle, workspaceKindColor, workspaceKindMeta } from '../chunk-
|
|
2
|
+
export { ActionCluster, AskField, AskRow, AskTrigger, DEFAULT_ASK_FIELD_LABELS, DEFAULT_INSTALL_PROMPT_LABELS, DEFAULT_MOBILE_BARS_LABELS, DEFAULT_OFFLINE_PILL_LABELS, DEFAULT_REMOTE_CONTROL_PILL_LABELS, DEFAULT_SIDEBAR_LABELS, DEFAULT_TIP_CARD_LABELS, DEFAULT_WORKSPACE_KIND_LABELS, DEFAULT_WORKSPACE_SWITCHER_LABELS, INSTALL_PROMPT_DISMISSED_KEY, InfoBar, InstallPrompt, MobileAppBar, MobileTabBar, NotificationBell, OfflinePill, RemoteControlPill, STATUS_ROW_BASE_CLASS, STATUS_ROW_TONES, Sidebar, SidebarBadgeRow, SidebarRowAction, SidebarRowHoverContext, SplitLayout, StatusBadge, StatusRow, TipCard, UserMenu, WorkspaceIdentity, WorkspaceSwitcher, getInstallInstructions, initInstallPrompt, isIosDevice, promptAppInstall, resolveSidebarLayout, useInstallPrompt, useSidebarContext, useSidebarSettle, workspaceKindColor, workspaceKindMeta } from '../chunk-C75S6USL.js';
|
|
3
3
|
import '../chunk-S7PSMMRG.js';
|
|
4
4
|
export { DEFAULT_TAB_HEADER_LABELS, TabHeader } from '../chunk-UBNVIIBT.js';
|
|
5
5
|
export { DEFAULT_DOCK_WIDTH, Toaster } from '../chunk-BV7FEMSI.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Loader2 } from 'lucide-react';
|
|
2
|
+
import type { StatusRowTone } from './StatusRow';
|
|
3
|
+
export declare const STATUS_ROW_BASE_CLASS = "flex items-center gap-2 rounded-md text-sm font-medium transition-colors hover:brightness-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11";
|
|
4
|
+
export declare const STATUS_ROW_TONES: Record<StatusRowTone, {
|
|
5
|
+
className: string;
|
|
6
|
+
Icon: typeof Loader2;
|
|
7
|
+
spin?: boolean;
|
|
8
|
+
}>;
|
package/dist/site/index.cjs
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
var chunk56BUD74K_cjs = require('../chunk-56BUD74K.cjs');
|
|
5
5
|
var chunk5ZBP7TCD_cjs = require('../chunk-5ZBP7TCD.cjs');
|
|
6
6
|
var chunkELR74ME6_cjs = require('../chunk-ELR74ME6.cjs');
|
|
7
|
-
var chunkPCB2BPN3_cjs = require('../chunk-PCB2BPN3.cjs');
|
|
8
7
|
var chunkVPPX5XUF_cjs = require('../chunk-VPPX5XUF.cjs');
|
|
8
|
+
var chunkPCB2BPN3_cjs = require('../chunk-PCB2BPN3.cjs');
|
|
9
9
|
var chunkVFUWWH52_cjs = require('../chunk-VFUWWH52.cjs');
|
|
10
10
|
var chunkKDG6FER6_cjs = require('../chunk-KDG6FER6.cjs');
|
|
11
11
|
|
|
@@ -255,10 +255,6 @@ Object.defineProperty(exports, "Timeline", {
|
|
|
255
255
|
enumerable: true,
|
|
256
256
|
get: function () { return chunkELR74ME6_cjs.Timeline; }
|
|
257
257
|
});
|
|
258
|
-
Object.defineProperty(exports, "Callout", {
|
|
259
|
-
enumerable: true,
|
|
260
|
-
get: function () { return chunkPCB2BPN3_cjs.Callout; }
|
|
261
|
-
});
|
|
262
258
|
Object.defineProperty(exports, "TimelineCalendar", {
|
|
263
259
|
enumerable: true,
|
|
264
260
|
get: function () { return chunkVPPX5XUF_cjs.TimelineCalendar; }
|
|
@@ -287,6 +283,10 @@ Object.defineProperty(exports, "utcDay", {
|
|
|
287
283
|
enumerable: true,
|
|
288
284
|
get: function () { return chunkVPPX5XUF_cjs.utcDay; }
|
|
289
285
|
});
|
|
286
|
+
Object.defineProperty(exports, "Callout", {
|
|
287
|
+
enumerable: true,
|
|
288
|
+
get: function () { return chunkPCB2BPN3_cjs.Callout; }
|
|
289
|
+
});
|
|
290
290
|
Object.defineProperty(exports, "Dot", {
|
|
291
291
|
enumerable: true,
|
|
292
292
|
get: function () { return chunkVFUWWH52_cjs.Dot; }
|
package/dist/site/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
export { ArticleList, Chart, CheckList, CollectionDetail, CtaBand, DefinitionList, EditorialHeading, EditorialHero, EditorialProse, EditorialSection, Eyebrow, PanelGrid, ProofStrip, PullQuote, Reveal, TagList } from '../chunk-IAKUTBPX.js';
|
|
3
3
|
export { Accordion, AvatarBlock, Banner, BlockImage, BlockLink, CTABanner, Columns, ContactForm, Container, FAQ, FONT_PAIRINGS, FeatureGrid, Footer, Gallery, Hero, ListBlock, LogoCloud, MediaText, Navbar, PricingTable, ProfileCard, RichTextBlock, SectionHeading, Spacer, Steps, THEME_STYLE_ID, Tabs, TeamGrid, Testimonial, TestimonialGrid, ThemeEditor, VideoEmbed, applyFontVars, applyStoredTheme, applyThemeVars, clearFontVars, clearThemeVars, createThemeStore, fontPackages, getFontPairing, matchFontPairing, tid, toEmbedUrl, toHslTriplet } from '../chunk-KXMDOTGW.js';
|
|
4
4
|
export { Timeline } from '../chunk-OVEQERPO.js';
|
|
5
|
-
export { Callout } from '../chunk-UJE32SST.js';
|
|
6
5
|
export { TimelineCalendar, TimelineGantt, dayKey, formatSpan, monthLabel, parseIso, utcDay } from '../chunk-4EZVCGRL.js';
|
|
6
|
+
export { Callout } from '../chunk-UJE32SST.js';
|
|
7
7
|
export { Dot, ToneBadge } from '../chunk-DPLRHEJZ.js';
|
|
8
8
|
export { daysUntil, fmtDate, fmtDateTime, formatCurrency, fromNow, hrs, initials, pct } from '../chunk-OXF2IFXG.js';
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
package/dist/studio/index.cjs
CHANGED
|
@@ -5,8 +5,8 @@ var chunkEYPPB5CY_cjs = require('../chunk-EYPPB5CY.cjs');
|
|
|
5
5
|
var chunkUTYQPVIW_cjs = require('../chunk-UTYQPVIW.cjs');
|
|
6
6
|
var chunk5ZBP7TCD_cjs = require('../chunk-5ZBP7TCD.cjs');
|
|
7
7
|
var chunkELR74ME6_cjs = require('../chunk-ELR74ME6.cjs');
|
|
8
|
-
var chunkPCB2BPN3_cjs = require('../chunk-PCB2BPN3.cjs');
|
|
9
8
|
require('../chunk-VPPX5XUF.cjs');
|
|
9
|
+
var chunkPCB2BPN3_cjs = require('../chunk-PCB2BPN3.cjs');
|
|
10
10
|
var chunkZW6FPIFC_cjs = require('../chunk-ZW6FPIFC.cjs');
|
|
11
11
|
require('../chunk-OB5F4577.cjs');
|
|
12
12
|
require('../chunk-ZHLMDJCO.cjs');
|
package/dist/studio/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import { PageHeader, MetricCard, DataTableBlock, StatGroup } from '../chunk-YMHG
|
|
|
4
4
|
import { assetRefId, applyStoredTheme, AssetResolverProvider, ThemeEditor, applyThemeVars, tid, SectionHeading, PricingTable, Tabs as Tabs$1, Accordion, Gallery, VideoEmbed, ContactForm, Banner, MediaText, TeamGrid, Steps, TestimonialGrid, Columns, Spacer, Container, Hero, FeatureGrid, Testimonial, CTABanner, LogoCloud, FAQ, RichTextBlock, BlockImage, AvatarBlock, Navbar, Footer, ListBlock, isAssetRef, asAssetRef } from '../chunk-KXMDOTGW.js';
|
|
5
5
|
export { ASSET_REF_PREFIX, AssetResolverProvider, asAssetRef, assetRefId, isAssetRef, useAssetRenderer, useAssetResolverActive } from '../chunk-KXMDOTGW.js';
|
|
6
6
|
import { Timeline } from '../chunk-OVEQERPO.js';
|
|
7
|
-
import { Callout } from '../chunk-UJE32SST.js';
|
|
8
7
|
import '../chunk-4EZVCGRL.js';
|
|
8
|
+
import { Callout } from '../chunk-UJE32SST.js';
|
|
9
9
|
import { EmptyState } from '../chunk-P6GHJSLR.js';
|
|
10
10
|
import '../chunk-S7PSMMRG.js';
|
|
11
11
|
import '../chunk-WSJVHSGN.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arbidocs/blocks",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.31",
|
|
4
4
|
"description": "Composable, domain-neutral UI blocks for ARBI apps, organised by capability (retrieval, facts, agents, workspaces, citations, collaboration) plus shell, theme and site primitives, on top of @arbidocs/react.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
"example:test:e2e": "playwright test -c examples/custom-ui/playwright.config.ts"
|
|
214
214
|
},
|
|
215
215
|
"dependencies": {
|
|
216
|
-
"@arbidocs/client": "0.4.
|
|
216
|
+
"@arbidocs/client": "0.4.31",
|
|
217
217
|
"@dnd-kit/core": "^6.3.1",
|
|
218
218
|
"@dnd-kit/sortable": "^10.0.0",
|
|
219
219
|
"@dnd-kit/utilities": "^3.2.2",
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
"@hocuspocus/provider": "4.6.0"
|
|
231
231
|
},
|
|
232
232
|
"peerDependencies": {
|
|
233
|
-
"@arbidocs/react": "0.4.
|
|
233
|
+
"@arbidocs/react": "0.4.31",
|
|
234
234
|
"@mdxeditor/editor": "^4.0.4",
|
|
235
235
|
"@measured/puck": ">=0.20",
|
|
236
236
|
"@playwright/test": ">=1.40",
|
package/src/tokens.css
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
--card-foreground: 233 45% 11.4%;
|
|
36
36
|
--popover: 0 0% 100%;
|
|
37
37
|
--popover-foreground: 233 45% 11.4%;
|
|
38
|
-
--primary:
|
|
38
|
+
--primary: 229.846154 50.42735% 25.294118%;
|
|
39
39
|
--primary-foreground: 210 20% 98%;
|
|
40
40
|
--secondary: 195 100% 47%;
|
|
41
41
|
--secondary-foreground: 233 45% 11.4%;
|
|
@@ -56,12 +56,12 @@
|
|
|
56
56
|
--hero: 228 50% 25%;
|
|
57
57
|
--ai-ink: 198 100% 32%;
|
|
58
58
|
--ai-soft: 198 82% 93.5%;
|
|
59
|
-
--blue-bg:
|
|
60
|
-
--blue-text:
|
|
61
|
-
--blue-border:
|
|
62
|
-
--green-bg:
|
|
63
|
-
--green-text:
|
|
64
|
-
--green-border:
|
|
59
|
+
--blue-bg: var(--accent);
|
|
60
|
+
--blue-text: var(--primary);
|
|
61
|
+
--blue-border: var(--border);
|
|
62
|
+
--green-bg: var(--accent);
|
|
63
|
+
--green-text: var(--primary);
|
|
64
|
+
--green-border: var(--border);
|
|
65
65
|
--yellow-bg: 48 100% 96%;
|
|
66
66
|
--yellow-text: 26 90% 37%;
|
|
67
67
|
--yellow-border: 48 96% 89%;
|
|
@@ -72,17 +72,17 @@
|
|
|
72
72
|
--purple-text: 304 99% 29%;
|
|
73
73
|
--purple-border: 287 100% 95%;
|
|
74
74
|
--red-solid: 0 84% 60%;
|
|
75
|
-
--green-solid:
|
|
75
|
+
--green-solid: var(--primary);
|
|
76
76
|
--yellow-solid: 40 95% 50%;
|
|
77
|
-
--blue-solid:
|
|
77
|
+
--blue-solid: var(--primary);
|
|
78
78
|
--purple-solid: 271 81% 56%;
|
|
79
79
|
--red-text-strong: 0 74% 32%;
|
|
80
|
-
--green-text-strong:
|
|
80
|
+
--green-text-strong: var(--primary);
|
|
81
81
|
--yellow-text-strong: 26 90% 28%;
|
|
82
|
-
--blue-text-strong:
|
|
82
|
+
--blue-text-strong: var(--primary);
|
|
83
83
|
--purple-text-strong: 304 99% 22%;
|
|
84
|
-
--status-online:
|
|
85
|
-
--status-connecting:
|
|
84
|
+
--status-online: hsl(var(--primary));
|
|
85
|
+
--status-connecting: hsl(var(--primary));
|
|
86
86
|
--status-away: oklch(79.5% 0.184 86.047);
|
|
87
87
|
--status-busy: oklch(63.7% 0.237 25.331);
|
|
88
88
|
--status-offline: oklch(70.7% 0.022 261.325);
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
--popover-foreground: 220 18% 93%;
|
|
108
108
|
--primary: 228 70% 70%;
|
|
109
109
|
--primary-foreground: 230 30% 8%;
|
|
110
|
-
--secondary:
|
|
111
|
-
--secondary-foreground:
|
|
110
|
+
--secondary: 195 100% 47%;
|
|
111
|
+
--secondary-foreground: 233 45% 11.4%;
|
|
112
112
|
--muted: 230 15% 14%;
|
|
113
113
|
--muted-foreground: 225 12% 68%;
|
|
114
114
|
--accent: 229 32% 21%;
|
|
@@ -123,14 +123,14 @@
|
|
|
123
123
|
--hero: 228 48% 17%;
|
|
124
124
|
--ai-ink: 195 90% 62%;
|
|
125
125
|
--ai-soft: 205 35% 17%;
|
|
126
|
-
--blue-bg:
|
|
127
|
-
--blue-text:
|
|
128
|
-
--blue-border:
|
|
129
|
-
--blue-text-strong:
|
|
130
|
-
--green-bg:
|
|
131
|
-
--green-text:
|
|
132
|
-
--green-border:
|
|
133
|
-
--green-text-strong:
|
|
126
|
+
--blue-bg: var(--accent);
|
|
127
|
+
--blue-text: var(--primary);
|
|
128
|
+
--blue-border: var(--border);
|
|
129
|
+
--blue-text-strong: var(--primary);
|
|
130
|
+
--green-bg: var(--accent);
|
|
131
|
+
--green-text: var(--primary);
|
|
132
|
+
--green-border: var(--border);
|
|
133
|
+
--green-text-strong: var(--primary);
|
|
134
134
|
--yellow-bg: 45 45% 12%;
|
|
135
135
|
--yellow-text: 45 90% 62%;
|
|
136
136
|
--yellow-border: 40 35% 24%;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/retrieval/highlight.ts","../src/retrieval/SearchPagination.tsx","../src/retrieval/SearchGroupHeader.tsx","../src/retrieval/SearchEmptyState.tsx","../src/retrieval/SearchPage.tsx","../src/retrieval/HighlightText.tsx"],"names":["memo","SearchPagination","jsxs","cn","testIdOr","jsx","Button","ChevronLeft","ChevronRight","SearchGroupHeader","Fragment","FileUp","Plus","Search","Blend","Quote","useMemo","useRef","useCallback","useLayoutEffect","X","Loader2","prefixedTestId","AlertCircle","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Input","DialogFooter","TagIcon"],"mappings":"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","file":"chunk-G4YOH5DU.cjs","sourcesContent":["/**\n * Flatten inline markdown links to their visible label: `[label](url)` -> `label`\n * (and image `` -> `alt`).\n *\n * Search snippets must not navigate away when clicked, and highlighting wraps matches in\n * `<mark>`: doing that over raw markdown would inject `<mark>` inside link URLs that contain a\n * query word, corrupting both the href and the text. Removing the URLs first makes it safe.\n */\nexport function stripMarkdownLinks(text: string): string {\n return text.replace(/!?\\[([^\\]]+)\\]\\([^)]*\\)/g, '$1')\n}\n\n/**\n * Prepare a snippet for markdown rendering: links flattened, and every (case-insensitive)\n * occurrence of a query term wrapped in `<mark>`. The renderer must allow `mark` through its\n * sanitizer.\n */\nexport function highlightTerms(content: string, terms: string[]): string {\n const plain = stripMarkdownLinks(content)\n if (terms.length === 0) return plain\n const escaped = terms.map((t) => t.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n return plain.replace(new RegExp(`(${escaped.join('|')})`, 'gi'), '<mark>$1</mark>')\n}\n\n/**\n * Page numbers for a pagination control: first + last + a window around the current page.\n * getPageNumbers(1, 3) -> [1, 2, 3]\n * getPageNumbers(7, 50) -> [1, 'ellipsis', 6, 7, 8, 'ellipsis', 50]\n */\nexport function getPageNumbers(current: number, total: number): (number | 'ellipsis')[] {\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1)\n\n const pages: (number | 'ellipsis')[] = [1]\n const windowStart = Math.max(2, current - 1)\n const windowEnd = Math.min(total - 1, current + 1)\n\n if (windowStart > 2) pages.push('ellipsis')\n for (let p = windowStart; p <= windowEnd; p++) pages.push(p)\n if (windowEnd < total - 1) pages.push('ellipsis')\n\n pages.push(total)\n return pages\n}\n","import { memo } from 'react'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\nimport { getPageNumbers } from './highlight'\n\nexport interface SearchPaginationLabels {\n navigation: string\n previous: string\n next: string\n page: (page: number) => string\n}\n\nexport const DEFAULT_SEARCH_PAGINATION_LABELS: SearchPaginationLabels = {\n navigation: 'Search results pagination',\n previous: 'Previous page',\n next: 'Next page',\n page: (page) => `Page ${page}`,\n}\n\nexport interface SearchPaginationTestIds {\n root: string\n /** Builds the id of a page button from its number. */\n page: (page: number) => string\n}\n\nexport interface SearchPaginationProps {\n currentPage: number\n totalPages: number\n onPageChange: (page: number) => void\n labels?: Partial<SearchPaginationLabels>\n testIds?: Partial<SearchPaginationTestIds>\n className?: string\n}\n\nexport const SearchPagination = memo(function SearchPagination({\n currentPage,\n totalPages,\n onPageChange,\n labels,\n testIds,\n className,\n}: SearchPaginationProps) {\n const l = { ...DEFAULT_SEARCH_PAGINATION_LABELS, ...labels }\n if (totalPages <= 1) return null\n const pages = getPageNumbers(currentPage, totalPages)\n return (\n <nav\n className={cn('mt-6 mb-2 flex items-center justify-center gap-1', className)}\n aria-label={l.navigation}\n data-testid={testIdOr(testIds?.root, { testId: 'smart-search-pagination' })}\n data-slot=\"search-pagination\"\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 px-2 pointer-coarse:h-11 pointer-coarse:min-w-11\"\n onClick={() => onPageChange(currentPage - 1)}\n disabled={currentPage <= 1}\n aria-label={l.previous}\n >\n <ChevronLeft className=\"size-4\" />\n </Button>\n {pages.map((p, i) =>\n p === 'ellipsis' ? (\n <span\n key={`ellipsis-${i}`}\n className=\"select-none px-2 text-sm text-muted-foreground\"\n aria-hidden\n >\n …\n </span>\n ) : (\n <Button\n key={p}\n variant={p === currentPage ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-8 min-w-8 px-2 pointer-coarse:h-11 pointer-coarse:min-w-11\"\n onClick={() => onPageChange(p)}\n aria-current={p === currentPage ? 'page' : undefined}\n aria-label={l.page(p)}\n data-testid={testIdOr(testIds?.page?.(p), { testId: `smart-search-page-${p}` })}\n >\n {p}\n </Button>\n )\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 px-2 pointer-coarse:h-11 pointer-coarse:min-w-11\"\n onClick={() => onPageChange(currentPage + 1)}\n disabled={currentPage >= totalPages}\n aria-label={l.next}\n >\n <ChevronRight className=\"size-4\" />\n </Button>\n </nav>\n )\n})\n","import { memo, type ReactNode } from 'react'\nimport { ChevronRight } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\nexport interface SearchGroupHeaderLabels {\n hit: string\n hits: string\n}\n\nexport const DEFAULT_SEARCH_GROUP_HEADER_LABELS: SearchGroupHeaderLabels = {\n hit: 'hit',\n hits: 'hits',\n}\n\nexport interface SearchGroupHeaderProps {\n /** Group key, handed back to `onToggle`. */\n groupId: string\n hitCount: number\n isExpanded: boolean\n onToggle: (groupId: string) => void\n /** The source pill; clicks on it do not toggle the group. */\n source: ReactNode\n labels?: Partial<SearchGroupHeaderLabels>\n /** Defaults to `search-result-group-toggle-${groupId}`. */\n testId?: string\n className?: string\n}\n\n/** Collapsible group row: chevron + source + hit count. The whole row toggles. */\nexport const SearchGroupHeader = memo(function SearchGroupHeader({\n groupId,\n hitCount,\n isExpanded,\n onToggle,\n source,\n labels,\n testId,\n className,\n}: SearchGroupHeaderProps) {\n const l = { ...DEFAULT_SEARCH_GROUP_HEADER_LABELS, ...labels }\n const toggle = () => onToggle(groupId)\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={toggle}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n toggle()\n }\n }}\n aria-expanded={isExpanded}\n className={cn(\n 'flex cursor-pointer items-center gap-2 px-3 py-1.5 pointer-coarse:min-h-11 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n isExpanded && 'border-b border-border',\n className\n )}\n data-testid={testIdOr(testId, { testId: `search-result-group-toggle-${groupId}` })}\n data-slot=\"search-group-header\"\n >\n <ChevronRight\n className={cn(\n 'size-4 shrink-0 text-muted-foreground transition-transform',\n isExpanded && 'rotate-90'\n )}\n />\n <span className=\"min-w-0\" onClick={(e) => e.stopPropagation()}>\n {source}\n </span>\n <span className=\"shrink-0 text-sm text-muted-foreground\">\n {hitCount} {hitCount === 1 ? l.hit : l.hits}\n </span>\n </div>\n )\n})\n","import type { ReactNode } from 'react'\nimport { Blend, FileUp, Plus, Quote, Search, type LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\nexport interface SearchEmptyNouns {\n singular: string\n plural: string\n /** The unit a hit returns (passage / fact). */\n hit: string\n hits: string\n emptyTitle: string\n emptyHint: ReactNode\n EmptyIcon: LucideIcon\n}\n\nexport const DOCUMENT_SEARCH_NOUNS: SearchEmptyNouns = {\n singular: 'document',\n plural: 'documents',\n hit: 'passage',\n hits: 'passages',\n emptyTitle: 'No documents to search yet',\n emptyHint: (\n <>\n Add files under <span className=\"font-medium text-foreground/80\">“Files”</span>, then come\n back to search their full text by keyword or meaning.\n </>\n ),\n EmptyIcon: FileUp,\n}\n\n/** Nouns for searching a custom collection (e.g. facts). `singular`/`plural` are lower case. */\nexport function searchNouns(\n singular: string,\n plural: string,\n addHint: ReactNode,\n EmptyIcon: LucideIcon = Plus\n): SearchEmptyNouns {\n return {\n singular,\n plural,\n hit: singular,\n hits: plural,\n emptyTitle: `No ${plural} to search yet`,\n emptyHint: addHint,\n EmptyIcon,\n }\n}\n\nexport interface SearchEmptyStateLabels {\n /** Title when there are items. */\n title: (nouns: SearchEmptyNouns) => string\n /** Intro sentence; receives the count and the nouns. */\n intro: (count: number, nouns: SearchEmptyNouns) => ReactNode\n hybridTitle: string\n hybridBody: (nouns: SearchEmptyNouns) => string\n phraseTitle: string\n phraseBefore: string\n phraseExample: string\n phraseAfter: (nouns: SearchEmptyNouns) => string\n}\n\nexport const DEFAULT_SEARCH_EMPTY_STATE_LABELS: SearchEmptyStateLabels = {\n title: (n) => `Search across your ${n.plural}`,\n intro: (count, n) => (\n <>\n Find any {n.hit} across{' '}\n <span className=\"font-medium text-foreground/80\">\n {count.toLocaleString()} {count === 1 ? n.singular : n.plural}\n </span>{' '}\n — by keyword, by meaning, or both.\n </>\n ),\n hybridTitle: 'Words and meaning, together',\n hybridBody: (n) =>\n `Every search matches exact words and meaning, so ${n.hits} worded differently are still found.`,\n phraseTitle: 'Quote an exact phrase',\n phraseBefore: 'Wrap a phrase in double quotes, like ',\n phraseExample: '\"force majeure\"',\n phraseAfter: (n) => `, to return only ${n.hits} containing it.`,\n}\n\nexport interface SearchEmptyStateProps {\n /** Number of searchable items in the workspace. */\n count: number\n /** Defaults to documents. */\n nouns?: SearchEmptyNouns\n labels?: Partial<SearchEmptyStateLabels>\n testId?: string\n className?: string\n}\n\n/** Shown before the first search: explains hybrid matching and quoted phrases. */\nexport function SearchEmptyState({\n count,\n nouns = DOCUMENT_SEARCH_NOUNS,\n labels,\n testId,\n className,\n}: SearchEmptyStateProps) {\n const l = { ...DEFAULT_SEARCH_EMPTY_STATE_LABELS, ...labels }\n const hasItems = count > 0\n const Icon = hasItems ? Search : nouns.EmptyIcon\n\n return (\n <div\n className={cn('flex justify-center px-10 pb-10 pt-6', className)}\n data-testid={testIdOr(testId, { testId: 'smart-search-empty-state' })}\n data-slot=\"search-empty-state\"\n >\n <div className=\"w-full max-w-xl text-center\">\n <div\n className={cn(\n 'mx-auto mb-4 flex size-12 items-center justify-center rounded-lg',\n hasItems ? 'bg-ai-soft text-ai-ink' : 'bg-muted text-muted-foreground'\n )}\n >\n <Icon className=\"size-6\" />\n </div>\n\n {hasItems ? (\n <>\n <h2 className=\"mt-2 text-xl font-semibold text-foreground\">{l.title(nouns)}</h2>\n <p className=\"mt-2 text-sm text-muted-foreground\">{l.intro(count, nouns)}</p>\n\n <div className=\"mt-7 grid gap-3 text-left @xl:grid-cols-2\">\n <div className=\"rounded-lg bg-muted p-3\">\n <div className=\"flex items-center gap-1.5 text-sm font-medium text-foreground\">\n <Blend className=\"size-4 text-ai-ink\" />\n {l.hybridTitle}\n </div>\n <p className=\"mt-1 text-sm leading-snug text-muted-foreground\">\n {l.hybridBody(nouns)}\n </p>\n </div>\n <div className=\"rounded-lg bg-muted p-3\">\n <div className=\"flex items-center gap-1.5 text-sm font-medium text-foreground\">\n <Quote className=\"size-4 text-ai-ink\" />\n {l.phraseTitle}\n </div>\n <p className=\"mt-1 text-sm leading-snug text-muted-foreground\">\n {l.phraseBefore}\n <code className=\"rounded bg-background px-1 py-0.5 font-mono text-sm text-foreground/90\">\n {l.phraseExample}\n </code>\n {l.phraseAfter(nouns)}\n </p>\n </div>\n </div>\n </>\n ) : (\n <>\n <h2 className=\"text-xl font-semibold text-foreground\">{nouns.emptyTitle}</h2>\n <p className=\"mx-auto mt-1.5 max-w-sm text-sm text-muted-foreground\">\n {nouns.emptyHint}\n </p>\n </>\n )}\n </div>\n </div>\n )\n}\n","import { useCallback, useLayoutEffect, useMemo, useRef, type ReactNode, type Ref } from 'react'\nimport { AlertCircle, Loader2, Search, TagIcon, X } from 'lucide-react'\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n cn,\n} from '@arbidocs/react/ui'\nimport { prefixedTestId, testIdOr } from '../chat/test-id'\n\n/* -------------------------------------------------------------------------- */\n/* Page frame */\n/* -------------------------------------------------------------------------- */\n\n/** Column that fills the Smart Search page (padded when standalone, flush when embedded). */\nexport function SearchPageFrame({\n isEmbedded,\n testId = 'smart-search',\n children,\n}: {\n isEmbedded?: boolean\n testId?: string\n children: ReactNode\n}) {\n return (\n <div\n data-slot=\"search-page\"\n data-testid={testId}\n className={cn('flex h-full flex-col', !isEmbedded && 'px-4')}\n >\n {children}\n </div>\n )\n}\n\n/** Sticky header slot; `-mx-4` cancels the frame's padding so the tab sits at the page inset. */\nexport function SearchPageHeader({ children }: { children: ReactNode }) {\n return (\n <div data-slot=\"search-page-header\" className=\"sticky top-0 z-10 -mx-4 bg-background\">\n {children}\n </div>\n )\n}\n\n/** Everything under the header. */\nexport function SearchPageBody({ children }: { children: ReactNode }) {\n return (\n <div data-slot=\"search-page-body\" className=\"flex min-h-0 flex-1 flex-col\">\n {children}\n </div>\n )\n}\n\n/** Thin row above the search bar (the embedded view puts the grouping toggle here). */\nexport function SearchToolbarRow({ children }: { children: ReactNode }) {\n return (\n <div\n data-slot=\"search-toolbar-row\"\n className=\"group flex h-8 items-center gap-2 border-b border-border/60 bg-background pl-5 pr-3\"\n >\n <div className=\"ml-auto flex shrink-0 items-center\">{children}</div>\n </div>\n )\n}\n\n/** Scrolling results area with its inner padding. */\nexport function SearchResultsMain({ children }: { children: ReactNode }) {\n return (\n <main data-slot=\"search-results-main\" className=\"flex-1 overflow-auto\">\n {children}\n </main>\n )\n}\n\n/** Padded wrapper of the hits. */\nexport function SearchResultsInner({ children }: { children: ReactNode }) {\n return <div className=\"w-full px-6 pb-6 pt-1\">{children}</div>\n}\n\n/** Vertical list of result rows or group cards. */\nexport function SearchResultList({ testId, children }: { testId?: string; children: ReactNode }) {\n return (\n <div className=\"space-y-3\" data-testid={testId}>\n {children}\n </div>\n )\n}\n\n/** One document's collapsible group: header (the toggle) plus the expanded hits. */\nexport function SearchGroupCard({\n testId,\n header,\n isExpanded,\n children,\n}: {\n testId?: string\n header: ReactNode\n isExpanded: boolean\n children: ReactNode\n}) {\n return (\n <div\n data-slot=\"search-group-card\"\n className=\"rounded border border-border transition-colors\"\n data-testid={testId}\n >\n {header}\n {isExpanded && <div className=\"space-y-3 p-3\">{children}</div>}\n </div>\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* Search bar */\n/* -------------------------------------------------------------------------- */\n\nexport interface SearchBarLabels {\n search: string\n clear: string\n submit: string\n}\n\nexport const DEFAULT_SEARCH_BAR_LABELS: SearchBarLabels = {\n search: 'Search:',\n clear: 'Clear search',\n submit: 'Search',\n}\n\nexport interface SearchBarProps {\n query: string\n onQueryChange: (query: string) => void\n /** Enter (without Shift) or the submit button. */\n onSubmit: () => void\n onClear: () => void\n canSubmit: boolean\n isSearching: boolean\n placeholder?: string\n /** Tooltip of the submit button (e.g. why it is disabled). */\n submitTitle?: string\n /** Message under the box (e.g. \"too many documents selected\"). */\n notice?: ReactNode\n noticeTestId?: string\n inputId?: string\n testIds?: { input?: string; clear?: string; submit?: string }\n /** Lets the host refocus the box and reset its height after a clear. */\n inputRef?: Ref<HTMLTextAreaElement>\n isEmbedded?: boolean\n labels?: Partial<SearchBarLabels>\n}\n\n/** The bordered, auto-growing query box with an inline clear and submit. */\nexport function SearchBar({\n query,\n onQueryChange,\n onSubmit,\n onClear,\n canSubmit,\n isSearching,\n placeholder,\n submitTitle,\n notice,\n noticeTestId,\n inputId = 'smart-search-input',\n testIds,\n inputRef,\n isEmbedded,\n labels,\n}: SearchBarProps) {\n const l = useMemo(() => ({ ...DEFAULT_SEARCH_BAR_LABELS, ...labels }), [labels])\n // The field grows with its content, and an empty field with its (possibly wrapping) placeholder:\n // a fixed single row cut the second line of a long placeholder on phones.\n const fieldRef = useRef<HTMLTextAreaElement | null>(null)\n const setRefs = useCallback(\n (el: HTMLTextAreaElement | null) => {\n fieldRef.current = el\n if (typeof inputRef === 'function') inputRef(el)\n else if (inputRef) (inputRef as { current: HTMLTextAreaElement | null }).current = el\n },\n [inputRef]\n )\n useLayoutEffect(() => {\n const el = fieldRef.current\n if (!el) return\n const resize = () => {\n el.style.height = 'auto'\n el.style.height = `${el.scrollHeight}px`\n }\n resize()\n if (typeof ResizeObserver === 'undefined') return\n let lastWidth = el.clientWidth\n const observer = new ResizeObserver(() => {\n if (el.clientWidth === lastWidth) return\n lastWidth = el.clientWidth\n resize()\n })\n observer.observe(el)\n return () => observer.disconnect()\n }, [query, placeholder])\n return (\n <div data-slot=\"search-bar\" className={cn('pl-6 pr-4', isEmbedded ? 'pb-4 pt-6' : 'py-4')}>\n <form\n onSubmit={(e) => {\n e.preventDefault()\n onSubmit()\n }}\n className=\"mx-auto flex w-full max-w-2xl items-center gap-3\"\n >\n <label htmlFor={inputId} className=\"sr-only\">\n {l.search}\n </label>\n <div className=\"flex min-w-0 flex-1 items-start gap-2 rounded-lg border border-border bg-background px-3.5 py-2.5 transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring\">\n <textarea\n id={inputId}\n ref={setRefs}\n rows={1}\n value={query}\n onChange={(e) => {\n onQueryChange(e.target.value)\n e.target.style.height = 'auto'\n e.target.style.height = `${e.target.scrollHeight}px`\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n onSubmit()\n }\n }}\n placeholder={placeholder}\n className=\"flex-1 resize-none overflow-hidden border-0 bg-transparent p-0 pointer-coarse:min-h-11 pointer-coarse:py-2.5 text-base leading-relaxed text-foreground outline-none placeholder:text-muted-foreground\"\n data-testid={testIdOr(testIds?.input, { testId: 'smart-search-input' })}\n />\n <div className=\"flex shrink-0 items-center gap-1\">\n {query && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 text-muted-foreground hover:text-foreground pointer-coarse:size-11\"\n onClick={onClear}\n aria-label={l.clear}\n title={l.clear}\n data-testid={testIdOr(testIds?.clear, { testId: 'smart-search-clear-button' })}\n >\n <X className=\"size-4\" />\n </Button>\n )}\n <Button\n type=\"submit\"\n size=\"sm\"\n disabled={!canSubmit}\n className=\"h-8 gap-1.5 px-3 text-sm pointer-coarse:h-11\"\n data-testid={testIdOr(testIds?.submit, { testId: 'smart-search-submit-button' })}\n title={submitTitle ?? l.submit}\n aria-label={l.submit}\n >\n {isSearching ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Search className=\"size-4\" />\n )}\n {l.submit}\n </Button>\n </div>\n {notice && (\n <p\n className=\"mt-2 text-sm text-destructive\"\n data-testid={testIdOr(noticeTestId, { testId: 'smart-search-selection-too-large' })}\n >\n {notice}\n </p>\n )}\n </div>\n </form>\n </div>\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* Controls: grouping toggle, relevance threshold, totals */\n/* -------------------------------------------------------------------------- */\n\nexport interface SearchPillOption {\n value: string\n /** Visible content (icon + text). */\n content: ReactNode\n /** Tooltip. */\n title: string\n}\n\nexport interface SearchPillToggleProps {\n options: SearchPillOption[]\n value: string\n onChange: (value: string) => void\n ariaLabel: string\n /** Prefix of the option buttons' test ids (`<prefix>-<value>-button`); default `smart-search-view`. */\n testIdPrefix?: string\n}\n\n/** Pill-shaped segmented toggle of `aria-pressed` buttons. */\nexport function SearchPillToggle({\n options,\n value,\n onChange,\n ariaLabel,\n testIdPrefix,\n}: SearchPillToggleProps) {\n return (\n <div\n className=\"inline-flex items-center rounded-full bg-muted p-0.5\"\n role=\"group\"\n aria-label={ariaLabel}\n data-slot=\"search-pill-toggle\"\n >\n {options.map((o) => {\n const active = o.value === value\n return (\n <button\n key={o.value}\n type=\"button\"\n onClick={() => onChange(o.value)}\n aria-pressed={active}\n title={o.title}\n data-testid={prefixedTestId(\n testIdPrefix,\n o.value,\n { testId: `smart-search-view-${o.value}-button` },\n '-button'\n )}\n className={cn(\n 'flex min-h-8 items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11',\n active\n ? 'bg-background text-foreground'\n : 'text-muted-foreground hover:text-foreground'\n )}\n >\n {o.content}\n </button>\n )\n })}\n </div>\n )\n}\n\nexport interface RelevanceStep {\n /** Minimum score kept at this step. */\n value: number\n label: string\n}\n\nexport const DEFAULT_RELEVANCE_STEPS: RelevanceStep[] = [\n { value: 0, label: 'Low' },\n { value: 0.7, label: 'High' },\n]\n\n// Accents match the relevance colours used for chunk borders and score pills elsewhere.\nconst STEP_DOT_CLASS = ['bg-muted-foreground/40', 'bg-green-500']\nconst STEP_LABEL_CLASS = ['text-foreground', 'text-green-700']\n\nexport interface RelevanceThresholdProps {\n value: number\n onChange: (value: number) => void\n steps?: RelevanceStep[]\n title?: string\n ariaLabel?: string\n}\n\n/** Compact segmented control (Low / High) with a colour-coded dot on the active step. */\nexport function RelevanceThreshold({\n value,\n onChange,\n steps = DEFAULT_RELEVANCE_STEPS,\n title = 'Relevance Threshold',\n ariaLabel = 'Search relevance threshold',\n}: RelevanceThresholdProps) {\n const active = steps.reduce((best, s, i) => (value >= s.value ? i : best), 0)\n return (\n <div className=\"flex items-center gap-1.5\" data-slot=\"relevance-threshold\">\n <span className=\"whitespace-nowrap text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {title}\n </span>\n <div\n className=\"inline-flex items-center rounded-full bg-muted p-0.5\"\n role=\"group\"\n aria-label={ariaLabel}\n >\n {steps.map((step, i) => {\n const isActive = i === active\n return (\n <button\n key={step.label}\n type=\"button\"\n onClick={() => onChange(step.value)}\n aria-pressed={isActive}\n data-testid={`smart-search-threshold-${step.label.toLowerCase()}`}\n className={cn(\n 'flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11 pointer-coarse:px-3',\n isActive\n ? cn('bg-background', STEP_LABEL_CLASS[i] ?? STEP_LABEL_CLASS[0])\n : 'text-muted-foreground hover:text-foreground'\n )}\n >\n <span\n className={cn(\n 'size-1.5 rounded-full transition-colors',\n isActive ? (STEP_DOT_CLASS[i] ?? STEP_DOT_CLASS[0]) : 'bg-muted-foreground/30'\n )}\n />\n {step.label}\n </button>\n )\n })}\n </div>\n </div>\n )\n}\n\n/** Result controls pinned between the search bar and the scrolling results. */\nexport function SearchControlsBar({\n start,\n end,\n children,\n}: {\n /** Left side: the totals headline. */\n start: ReactNode\n /** Right side: threshold and toggle. */\n end: ReactNode\n children?: ReactNode\n}) {\n return (\n <div\n data-slot=\"search-controls-bar\"\n className=\"flex flex-wrap items-center justify-between gap-x-4 gap-y-2 pb-3 pl-6 pr-4\"\n >\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-2\">{start}</div>\n <div className=\"flex items-center gap-3\">{end}</div>\n {children}\n </div>\n )\n}\n\nexport interface SearchTotalsHeadlineLabels {\n hit: string\n hits: string\n document: string\n documents: string\n passages: string\n}\n\nexport const DEFAULT_SEARCH_TOTALS_LABELS: SearchTotalsHeadlineLabels = {\n hit: 'hit',\n hits: 'hits',\n document: 'document',\n documents: 'documents',\n passages: 'passages',\n}\n\nexport interface SearchTotalsHeadlineProps {\n /** Hits passing the relevance threshold. */\n shownHits: number\n totalHits: number\n /** Documents among the shown hits. */\n shownDocuments: number\n totalDocuments: number\n /** Paging range, shown when there is more than one page. */\n range?: { start: number; end: number; total: number; unit: 'passages' | 'documents' } | null\n /** Inline action after the sentence (e.g. Apply label). */\n action?: ReactNode\n testId?: string\n labels?: Partial<SearchTotalsHeadlineLabels>\n}\n\nconst fmt = (n: number) => n.toLocaleString()\n\n/** \"N hits (M total) across K documents\", with an optional inline action and page range. */\nexport function SearchTotalsHeadline({\n shownHits,\n totalHits,\n shownDocuments,\n totalDocuments,\n range,\n action,\n testId = 'smart-search-totals',\n labels,\n}: SearchTotalsHeadlineProps) {\n const l = useMemo(() => ({ ...DEFAULT_SEARCH_TOTALS_LABELS, ...labels }), [labels])\n const hitWord = (n: number) => (n === 1 ? l.hit : l.hits)\n const docWord = (n: number) => (n === 1 ? l.document : l.documents)\n return (\n <p\n className=\"flex flex-wrap items-baseline gap-x-2 font-sans text-base font-semibold tabular-nums text-foreground\"\n data-testid={testId}\n >\n <span>\n {shownHits < totalHits ? (\n <>\n {fmt(shownHits)} {hitWord(shownHits)}{' '}\n <span className=\"font-normal text-muted-foreground\">({fmt(totalHits)} total)</span>{' '}\n across {fmt(shownDocuments)} {docWord(shownDocuments)}\n </>\n ) : (\n <>\n {fmt(totalHits)} {hitWord(totalHits)} across {fmt(totalDocuments)}{' '}\n {docWord(totalDocuments)}\n </>\n )}\n </span>\n {action && (\n <span className=\"inline-flex items-center gap-2 text-sm font-normal text-muted-foreground\">\n –{action}\n </span>\n )}\n {range && range.total > 0 && (\n <span className=\"text-sm font-normal text-muted-foreground\">\n · showing {fmt(range.start)}–{fmt(range.end)} of {fmt(range.total)}{' '}\n {range.unit === 'passages' ? l.passages : l.documents}\n </span>\n )}\n </p>\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* States */\n/* -------------------------------------------------------------------------- */\n\n/** Inline error of a failed search. */\nexport function SearchErrorBanner({ message }: { message: string }) {\n return (\n <div\n role=\"alert\"\n className=\"flex items-center gap-2 rounded-md bg-destructive/10 p-4 text-destructive\"\n >\n <AlertCircle className=\"size-5 flex-shrink-0\" />\n <p>{message}</p>\n </div>\n )\n}\n\nexport interface SearchNoResultsProps {\n /** Hits that exist but fall below the threshold; 0 when the search found nothing. */\n hiddenHits: number\n onLowerThreshold: () => void\n labels?: Partial<SearchNoResultsLabels>\n testId?: string\n}\n\nexport interface SearchNoResultsLabels {\n none: string\n hidden: (count: number) => string\n lower: string\n}\n\nexport const DEFAULT_SEARCH_NO_RESULTS_LABELS: SearchNoResultsLabels = {\n none: 'No results found for your search query.',\n hidden: (n) =>\n `All ${fmt(n)} ${n === 1 ? 'hit is' : 'hits are'} below the current relevance threshold.`,\n lower: 'Lower threshold to Low',\n}\n\n/** Nothing to list: either no hits, or all hits are under the relevance threshold. */\nexport function SearchNoResults({\n hiddenHits,\n onLowerThreshold,\n labels,\n testId = 'smart-search-no-results',\n}: SearchNoResultsProps) {\n const l = useMemo(() => ({ ...DEFAULT_SEARCH_NO_RESULTS_LABELS, ...labels }), [labels])\n return (\n <div className=\"py-12 text-center\" data-testid={testId}>\n <Search className=\"mx-auto mb-4 size-12 text-muted-foreground\" />\n {hiddenHits > 0 ? (\n <>\n <p className=\"text-muted-foreground\">{l.hidden(hiddenHits)}</p>\n <Button variant=\"link\" size=\"sm\" className=\"mt-2\" onClick={onLowerThreshold}>\n {l.lower}\n </Button>\n </>\n ) : (\n <p className=\"text-muted-foreground\">{l.none}</p>\n )}\n </div>\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* Apply label dialog */\n/* -------------------------------------------------------------------------- */\n\nexport interface ApplyLabelDialogLabels {\n title: string\n description: (documents: number, passages: number) => string\n placeholder: string\n cancel: string\n apply: string\n}\n\nexport const DEFAULT_APPLY_LABEL_DIALOG_LABELS: ApplyLabelDialogLabels = {\n title: 'Apply label',\n description: (documents, passages) =>\n `Labels ${documents} ${documents === 1 ? 'document' : 'documents'} with ${passages} passage ${passages === 1 ? 'reference' : 'references'}.`,\n placeholder: 'Label name',\n cancel: 'Cancel',\n apply: 'Apply label',\n}\n\nexport interface ApplyLabelDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n name: string\n onNameChange: (name: string) => void\n onApply: (name: string) => void\n isApplying: boolean\n documentCount: number\n passageCount: number\n labels?: Partial<ApplyLabelDialogLabels>\n}\n\n/** Name a label and apply it to every document in the results. */\nexport function ApplyLabelDialog({\n open,\n onOpenChange,\n name,\n onNameChange,\n onApply,\n isApplying,\n documentCount,\n passageCount,\n labels,\n}: ApplyLabelDialogProps) {\n const l = useMemo(() => ({ ...DEFAULT_APPLY_LABEL_DIALOG_LABELS, ...labels }), [labels])\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{l.title}</DialogTitle>\n <DialogDescription>{l.description(documentCount, passageCount)}</DialogDescription>\n </DialogHeader>\n <div className=\"py-2\">\n <Input\n value={name}\n onChange={(e) => onNameChange(e.target.value)}\n placeholder={l.placeholder}\n aria-label={l.placeholder}\n autoFocus\n onKeyDown={(e) => {\n if (e.key === 'Enter' && name.trim()) onApply(name)\n }}\n />\n </div>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n {l.cancel}\n </Button>\n <Button onClick={() => onApply(name)} disabled={isApplying || !name.trim()}>\n {isApplying && <Loader2 className=\"mr-2 size-4 animate-spin\" />}\n {l.apply}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\n/** Small outlined \"Apply label\" button used inside the totals sentence. */\nexport function ApplyLabelButton({\n onClick,\n label = 'Apply label',\n testId = 'smart-search-apply-label-button',\n}: {\n onClick: () => void\n label?: string\n testId?: string\n}) {\n return (\n <Button\n onClick={onClick}\n size=\"sm\"\n variant=\"outline\"\n className=\"h-6 px-2 text-sm font-normal pointer-coarse:h-11\"\n data-testid={testId}\n >\n <TagIcon className=\"mr-1 size-3\" />\n {label}\n </Button>\n )\n}\n","import { Fragment, type ReactNode } from 'react'\nimport { cn } from '@arbidocs/react/ui'\nimport { stripMarkdownLinks } from './highlight'\n\nexport interface HighlightProps {\n /** Text to render; markdown links are flattened to their label first. */\n text: string\n /** Terms to mark (case-insensitive, matched literally). Blank terms are ignored. */\n terms: string[]\n /** Class for each `<mark>`. */\n markClassName?: string\n className?: string\n}\n\n/** Split `text` into plain and matching runs. Exported for hosts that render their own marks. */\nexport function splitByTerms(text: string, terms: string[]): { text: string; match: boolean }[] {\n const escaped = terms\n .map((t) => t.trim())\n .filter(Boolean)\n .map((t) => t.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n if (escaped.length === 0) return [{ text, match: false }]\n const re = new RegExp(`(${escaped.join('|')})`, 'gi')\n // split() with one capture group alternates plain, match, plain, ...\n return text\n .split(re)\n .map((part, i) => ({ text: part, match: i % 2 === 1 }))\n .filter((run) => run.text !== '')\n}\n\n/**\n * Plain-text snippet with the query terms wrapped in `<mark>`. Built from React nodes (no\n * `dangerouslySetInnerHTML`, no markdown pipeline), so it is safe for untrusted text: a use for\n * `SearchHit.renderSnippet` when the host does not render markdown.\n */\nexport function Highlight({ text, terms, markClassName, className }: HighlightProps): ReactNode {\n const runs = splitByTerms(stripMarkdownLinks(text), terms)\n return (\n <span className={className} data-slot=\"highlight\">\n {runs.map((run, i) =>\n run.match ? (\n <mark key={i} className={cn('rounded-sm bg-yellow-bg text-inherit', markClassName)}>\n {run.text}\n </mark>\n ) : (\n <Fragment key={i}>{run.text}</Fragment>\n )\n )}\n </span>\n )\n}\n"]}
|