@uipath/apollo-wind 2.55.0 → 2.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/index.cjs +106 -96
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/components/ui/index.js +1 -0
- package/dist/components/ui/model-picker/ModelPicker.cjs +495 -0
- package/dist/components/ui/model-picker/ModelPicker.d.ts +304 -0
- package/dist/components/ui/model-picker/ModelPicker.js +451 -0
- package/dist/components/ui/model-picker/ModelTagChip.cjs +101 -0
- package/dist/components/ui/model-picker/ModelTagChip.d.ts +29 -0
- package/dist/components/ui/model-picker/ModelTagChip.js +67 -0
- package/dist/components/ui/model-picker/badges.cjs +52 -0
- package/dist/components/ui/model-picker/badges.d.ts +41 -0
- package/dist/components/ui/model-picker/badges.js +18 -0
- package/dist/components/ui/model-picker/index.cjs +117 -0
- package/dist/components/ui/model-picker/index.d.ts +27 -0
- package/dist/components/ui/model-picker/index.js +14 -0
- package/dist/components/ui/model-picker/labels.cjs +107 -0
- package/dist/components/ui/model-picker/labels.d.ts +81 -0
- package/dist/components/ui/model-picker/labels.js +67 -0
- package/dist/components/ui/model-picker/primitives/FolderSwitcher.cjs +108 -0
- package/dist/components/ui/model-picker/primitives/FolderSwitcher.d.ts +38 -0
- package/dist/components/ui/model-picker/primitives/FolderSwitcher.js +74 -0
- package/dist/components/ui/model-picker/primitives/GroupHeader.cjs +84 -0
- package/dist/components/ui/model-picker/primitives/GroupHeader.d.ts +64 -0
- package/dist/components/ui/model-picker/primitives/GroupHeader.js +50 -0
- package/dist/components/ui/model-picker/primitives/ModelOptionRow.cjs +178 -0
- package/dist/components/ui/model-picker/primitives/ModelOptionRow.d.ts +95 -0
- package/dist/components/ui/model-picker/primitives/ModelOptionRow.js +135 -0
- package/dist/components/ui/model-picker/primitives/OptionList.cjs +295 -0
- package/dist/components/ui/model-picker/primitives/OptionList.d.ts +87 -0
- package/dist/components/ui/model-picker/primitives/OptionList.js +242 -0
- package/dist/components/ui/model-picker/primitives/PickerPopup.cjs +64 -0
- package/dist/components/ui/model-picker/primitives/PickerPopup.d.ts +39 -0
- package/dist/components/ui/model-picker/primitives/PickerPopup.js +30 -0
- package/dist/components/ui/model-picker/primitives/PickerSearchInput.cjs +77 -0
- package/dist/components/ui/model-picker/primitives/PickerSearchInput.d.ts +43 -0
- package/dist/components/ui/model-picker/primitives/PickerSearchInput.js +43 -0
- package/dist/components/ui/model-picker/primitives/PickerTrigger.cjs +112 -0
- package/dist/components/ui/model-picker/primitives/PickerTrigger.d.ts +73 -0
- package/dist/components/ui/model-picker/primitives/PickerTrigger.js +78 -0
- package/dist/components/ui/model-picker/types.cjs +18 -0
- package/dist/components/ui/model-picker/types.d.ts +154 -0
- package/dist/components/ui/model-picker/types.js +0 -0
- package/dist/components/ui/model-picker/useModelPickerState.cjs +250 -0
- package/dist/components/ui/model-picker/useModelPickerState.d.ts +135 -0
- package/dist/components/ui/model-picker/useModelPickerState.js +216 -0
- package/dist/components/ui/model-picker/utils.cjs +327 -0
- package/dist/components/ui/model-picker/utils.d.ts +121 -0
- package/dist/components/ui/model-picker/utils.js +272 -0
- package/dist/index.cjs +83 -10
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -1
- package/dist/styles.css +108 -0
- package/package.json +2 -1
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Plus } from "lucide-react";
|
|
4
|
+
import react from "react";
|
|
5
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "../alert-dialog.js";
|
|
6
|
+
import { FormField, FormFieldError, FormFieldLabel } from "../form-field.js";
|
|
7
|
+
import { Popover, PopoverTrigger } from "../popover.js";
|
|
8
|
+
import { Spinner } from "../spinner.js";
|
|
9
|
+
import { cn } from "../../../lib/index.js";
|
|
10
|
+
import { resolveLabels } from "./labels.js";
|
|
11
|
+
import { FolderSwitcher } from "./primitives/FolderSwitcher.js";
|
|
12
|
+
import { defaultRowActions } from "./primitives/ModelOptionRow.js";
|
|
13
|
+
import { GroupedOptionList, VirtualOptionList, optionDomId } from "./primitives/OptionList.js";
|
|
14
|
+
import { PickerPopup } from "./primitives/PickerPopup.js";
|
|
15
|
+
import { PickerSearchInput } from "./primitives/PickerSearchInput.js";
|
|
16
|
+
import { PickerTrigger } from "./primitives/PickerTrigger.js";
|
|
17
|
+
import { useModelPickerState } from "./useModelPickerState.js";
|
|
18
|
+
import { isByoModel, resolveHomeGeography } from "./utils.js";
|
|
19
|
+
const AUTO_VIRTUALIZE_THRESHOLD = 120;
|
|
20
|
+
const ModelPicker_ModelPicker = /*#__PURE__*/ react.forwardRef(function({ models, value, valueConnectionId, onChange, label, ariaLabel, required, placeholder, disabled, invalid, errorText, variant = 'searchable', groupBy = "subscription", allowGroupingChange = true, homeRegion, recommendedModelIds, previewModelIds, filter, badgesFor, customTagsFor, customTagVariants, canManageByo, onUseCustomModel, folders, folder: folderProp, onFolderChange, allFoldersLabel, loading, error, showGroupHeaders = true, popupContainer, onDeleteModel, onEditModel, labels: labelOverrides, slots, testId }, forwardedRef) {
|
|
21
|
+
const labels = react.useMemo(()=>resolveLabels(labelOverrides), [
|
|
22
|
+
labelOverrides
|
|
23
|
+
]);
|
|
24
|
+
const defaultLabel = labels.fieldLabel;
|
|
25
|
+
const resolvedLabel = label ?? defaultLabel;
|
|
26
|
+
const labelHidden = null === label;
|
|
27
|
+
const resolvedPlaceholder = placeholder ?? labels.placeholder;
|
|
28
|
+
const initiallyCollapsedGroups = react.useMemo(()=>[], []);
|
|
29
|
+
const [internalFolder, setInternalFolder] = react.useState(null);
|
|
30
|
+
const folderIsControlled = void 0 !== folderProp;
|
|
31
|
+
const folder = folderIsControlled ? folderProp : internalFolder;
|
|
32
|
+
const handleFolderChange = react.useCallback((next)=>{
|
|
33
|
+
if (!folderIsControlled) setInternalFolder(next);
|
|
34
|
+
onFolderChange?.(next);
|
|
35
|
+
}, [
|
|
36
|
+
folderIsControlled,
|
|
37
|
+
onFolderChange
|
|
38
|
+
]);
|
|
39
|
+
const catalog = models;
|
|
40
|
+
const effectiveLoading = loading ?? false;
|
|
41
|
+
const [pendingDelete, setPendingDelete] = react.useState(null);
|
|
42
|
+
const [deleteError, setDeleteError] = react.useState(null);
|
|
43
|
+
const pendingDeleteRef = react.useRef(null);
|
|
44
|
+
pendingDeleteRef.current = pendingDelete;
|
|
45
|
+
const deleteInFlight = react.useRef(false);
|
|
46
|
+
const handleDeleteModel = react.useMemo(()=>{
|
|
47
|
+
if (!onDeleteModel) return;
|
|
48
|
+
return (m)=>{
|
|
49
|
+
if (deleteInFlight.current) return;
|
|
50
|
+
setDeleteError(null);
|
|
51
|
+
setPendingDelete(m);
|
|
52
|
+
};
|
|
53
|
+
}, [
|
|
54
|
+
onDeleteModel
|
|
55
|
+
]);
|
|
56
|
+
const confirmPendingDelete = react.useCallback(async ()=>{
|
|
57
|
+
const model = pendingDelete;
|
|
58
|
+
setPendingDelete(null);
|
|
59
|
+
if (!model || !onDeleteModel || deleteInFlight.current) return;
|
|
60
|
+
deleteInFlight.current = true;
|
|
61
|
+
try {
|
|
62
|
+
await onDeleteModel(model);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
setDeleteError(err instanceof Error ? err : new Error(String(err)));
|
|
65
|
+
} finally{
|
|
66
|
+
deleteInFlight.current = false;
|
|
67
|
+
}
|
|
68
|
+
}, [
|
|
69
|
+
pendingDelete,
|
|
70
|
+
onDeleteModel
|
|
71
|
+
]);
|
|
72
|
+
const effectiveError = error ?? null;
|
|
73
|
+
const effectiveModels = react.useMemo(()=>catalog.filter((m)=>!m.isBlockedByPolicy), [
|
|
74
|
+
catalog
|
|
75
|
+
]);
|
|
76
|
+
const state = useModelPickerState({
|
|
77
|
+
models: effectiveModels,
|
|
78
|
+
value,
|
|
79
|
+
valueConnectionId,
|
|
80
|
+
onChange,
|
|
81
|
+
groupBy,
|
|
82
|
+
recommendedModelIds,
|
|
83
|
+
previewModelIds,
|
|
84
|
+
filter,
|
|
85
|
+
initiallyCollapsedGroups,
|
|
86
|
+
collapsibleGroups: showGroupHeaders,
|
|
87
|
+
labels
|
|
88
|
+
});
|
|
89
|
+
const { open, setOpen, query, setQuery, groupBy: activeGroupBy, setGroupBy, filtered, groupCounts, collapsedGroups, toggleGroup, selected, unknownValue, activeIndex, setActiveIndex, onSearchKeyDown, choose, id, triggerRef, searchRef, activeVisible } = state;
|
|
90
|
+
const listboxId = `${id}-listbox`;
|
|
91
|
+
const List = 'virtualized' === variant || filtered.length > AUTO_VIRTUALIZE_THRESHOLD ? VirtualOptionList : GroupedOptionList;
|
|
92
|
+
const handleTriggerRef = react.useCallback((node)=>{
|
|
93
|
+
triggerRef.current = node;
|
|
94
|
+
if ('function' == typeof forwardedRef) forwardedRef(node);
|
|
95
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
96
|
+
}, [
|
|
97
|
+
forwardedRef,
|
|
98
|
+
triggerRef
|
|
99
|
+
]);
|
|
100
|
+
const closePopup = react.useCallback(()=>{
|
|
101
|
+
setOpen(false);
|
|
102
|
+
setDeleteError(null);
|
|
103
|
+
}, [
|
|
104
|
+
setOpen
|
|
105
|
+
]);
|
|
106
|
+
const handleOpenChange = react.useCallback((next)=>{
|
|
107
|
+
if (next) return void setOpen(true);
|
|
108
|
+
if (pendingDeleteRef.current) return;
|
|
109
|
+
closePopup();
|
|
110
|
+
}, [
|
|
111
|
+
setOpen,
|
|
112
|
+
closePopup
|
|
113
|
+
]);
|
|
114
|
+
const slotCtx = react.useMemo(()=>({
|
|
115
|
+
selected,
|
|
116
|
+
close: closePopup
|
|
117
|
+
}), [
|
|
118
|
+
selected,
|
|
119
|
+
closePopup
|
|
120
|
+
]);
|
|
121
|
+
const effectiveCanManageByo = canManageByo ?? false;
|
|
122
|
+
const effectiveFolders = folders;
|
|
123
|
+
const listReady = !effectiveLoading && !effectiveError;
|
|
124
|
+
const handleSearchKeyDown = react.useCallback((e)=>{
|
|
125
|
+
if (!listReady) {
|
|
126
|
+
if ('Escape' === e.key) onSearchKeyDown(e);
|
|
127
|
+
else if ('Enter' === e.key || e.key.startsWith('Arrow')) e.preventDefault();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const active = filtered[activeIndex];
|
|
131
|
+
if (active && activeVisible && effectiveCanManageByo && isByoModel(active)) {
|
|
132
|
+
if ('Enter' === e.key && e.shiftKey && onEditModel) {
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
onEditModel(active);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const field = e.currentTarget;
|
|
138
|
+
const nothingToDelete = field.selectionStart === field.value.length && field.selectionEnd === field.selectionStart;
|
|
139
|
+
if ('Delete' === e.key && nothingToDelete && handleDeleteModel) {
|
|
140
|
+
e.preventDefault();
|
|
141
|
+
handleDeleteModel(active);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
onSearchKeyDown(e);
|
|
146
|
+
}, [
|
|
147
|
+
listReady,
|
|
148
|
+
filtered,
|
|
149
|
+
activeIndex,
|
|
150
|
+
activeVisible,
|
|
151
|
+
effectiveCanManageByo,
|
|
152
|
+
onEditModel,
|
|
153
|
+
handleDeleteModel,
|
|
154
|
+
onSearchKeyDown
|
|
155
|
+
]);
|
|
156
|
+
react.useEffect(()=>{
|
|
157
|
+
if ("u" < typeof process || 'production' === process.env.NODE_ENV || !effectiveFolders) return;
|
|
158
|
+
const seen = new Set();
|
|
159
|
+
for (const f of effectiveFolders){
|
|
160
|
+
if (seen.has(f.id)) return void console.warn(`[ModelPicker] Duplicate folder id "${f.id}" — folder selection will misbehave.`);
|
|
161
|
+
seen.add(f.id);
|
|
162
|
+
}
|
|
163
|
+
}, [
|
|
164
|
+
effectiveFolders
|
|
165
|
+
]);
|
|
166
|
+
const homeGeography = resolveHomeGeography(homeRegion);
|
|
167
|
+
const tagContext = react.useMemo(()=>({
|
|
168
|
+
labels,
|
|
169
|
+
homeRegion: homeGeography,
|
|
170
|
+
recommendedModelIds,
|
|
171
|
+
previewModelIds,
|
|
172
|
+
badgesFor,
|
|
173
|
+
customTagsFor
|
|
174
|
+
}), [
|
|
175
|
+
labels,
|
|
176
|
+
homeGeography,
|
|
177
|
+
recommendedModelIds,
|
|
178
|
+
previewModelIds,
|
|
179
|
+
badgesFor,
|
|
180
|
+
customTagsFor
|
|
181
|
+
]);
|
|
182
|
+
const renderRowActions = react.useMemo(()=>{
|
|
183
|
+
if (slots?.optionActions) return slots.optionActions;
|
|
184
|
+
if (!effectiveCanManageByo) return ()=>null;
|
|
185
|
+
if (!onEditModel && !handleDeleteModel) return ()=>null;
|
|
186
|
+
return (m)=>defaultRowActions(m, {
|
|
187
|
+
labels,
|
|
188
|
+
onEdit: onEditModel,
|
|
189
|
+
onDelete: handleDeleteModel
|
|
190
|
+
});
|
|
191
|
+
}, [
|
|
192
|
+
slots?.optionActions,
|
|
193
|
+
effectiveCanManageByo,
|
|
194
|
+
onEditModel,
|
|
195
|
+
handleDeleteModel,
|
|
196
|
+
labels
|
|
197
|
+
]);
|
|
198
|
+
const footerNode = react.useMemo(()=>{
|
|
199
|
+
if (slots && 'popupFooter' in slots) return slots.popupFooter ? slots.popupFooter(slotCtx) : null;
|
|
200
|
+
if (!effectiveCanManageByo) return null;
|
|
201
|
+
const activate = onUseCustomModel;
|
|
202
|
+
return /*#__PURE__*/ jsx(UseCustomModelFooter, {
|
|
203
|
+
disabled: !activate,
|
|
204
|
+
labels: labels,
|
|
205
|
+
onActivate: ()=>{
|
|
206
|
+
activate?.();
|
|
207
|
+
closePopup();
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}, [
|
|
211
|
+
slots,
|
|
212
|
+
effectiveCanManageByo,
|
|
213
|
+
onUseCustomModel,
|
|
214
|
+
slotCtx,
|
|
215
|
+
closePopup,
|
|
216
|
+
labels
|
|
217
|
+
]);
|
|
218
|
+
const pendingValue = effectiveLoading && !selected && value ? value : null;
|
|
219
|
+
const errorMessage = errorText ?? effectiveError?.message;
|
|
220
|
+
return /*#__PURE__*/ jsxs(FormField, {
|
|
221
|
+
className: "w-full",
|
|
222
|
+
"data-slot": "model-picker",
|
|
223
|
+
"data-testid": testId,
|
|
224
|
+
children: [
|
|
225
|
+
!labelHidden && /*#__PURE__*/ jsx(FormFieldLabel, {
|
|
226
|
+
htmlFor: `${id}-trigger`,
|
|
227
|
+
required: required,
|
|
228
|
+
children: resolvedLabel
|
|
229
|
+
}),
|
|
230
|
+
/*#__PURE__*/ jsxs(Popover, {
|
|
231
|
+
onOpenChange: handleOpenChange,
|
|
232
|
+
open: open,
|
|
233
|
+
children: [
|
|
234
|
+
/*#__PURE__*/ jsx(PopoverTrigger, {
|
|
235
|
+
asChild: true,
|
|
236
|
+
children: /*#__PURE__*/ jsx(PickerTrigger, {
|
|
237
|
+
controlsId: listboxId,
|
|
238
|
+
describedById: errorMessage ? `${id}-error` : void 0,
|
|
239
|
+
disabled: disabled,
|
|
240
|
+
extra: slots?.triggerExtra?.(selected),
|
|
241
|
+
"aria-label": labelHidden ? ariaLabel ?? defaultLabel : void 0,
|
|
242
|
+
id: `${id}-trigger`,
|
|
243
|
+
invalid: !!invalid || !!effectiveError || !!unknownValue,
|
|
244
|
+
open: open,
|
|
245
|
+
pendingValue: pendingValue,
|
|
246
|
+
placeholder: resolvedPlaceholder,
|
|
247
|
+
ref: handleTriggerRef,
|
|
248
|
+
required: required,
|
|
249
|
+
selected: selected,
|
|
250
|
+
tagContext: tagContext,
|
|
251
|
+
tagVariants: customTagVariants,
|
|
252
|
+
unknownValue: unknownValue
|
|
253
|
+
})
|
|
254
|
+
}),
|
|
255
|
+
/*#__PURE__*/ jsxs(PickerPopup, {
|
|
256
|
+
container: popupContainer,
|
|
257
|
+
footer: footerNode,
|
|
258
|
+
header: /*#__PURE__*/ jsxs(Fragment, {
|
|
259
|
+
children: [
|
|
260
|
+
slots?.popupHeader?.(),
|
|
261
|
+
/*#__PURE__*/ jsx(PickerSearchInput, {
|
|
262
|
+
activeDescendantId: listReady && activeVisible && filtered[activeIndex] ? optionDomId(listboxId, filtered[activeIndex].modelId) : void 0,
|
|
263
|
+
inputRef: searchRef,
|
|
264
|
+
leading: slots?.searchLeading?.() ?? (effectiveFolders && effectiveFolders.length > 0 ? /*#__PURE__*/ jsx(FolderSwitcher, {
|
|
265
|
+
allFoldersLabel: allFoldersLabel ?? labels.allFolders,
|
|
266
|
+
container: popupContainer,
|
|
267
|
+
folders: effectiveFolders,
|
|
268
|
+
onChange: handleFolderChange,
|
|
269
|
+
value: folder ?? null
|
|
270
|
+
}) : void 0),
|
|
271
|
+
listboxId: listboxId,
|
|
272
|
+
onChange: (next)=>{
|
|
273
|
+
setQuery(next);
|
|
274
|
+
setActiveIndex(0);
|
|
275
|
+
},
|
|
276
|
+
onKeyDown: handleSearchKeyDown,
|
|
277
|
+
placeholder: labels.searchPlaceholder,
|
|
278
|
+
trailing: allowGroupingChange ? /*#__PURE__*/ jsx(GroupBySegmented, {
|
|
279
|
+
labels: labels,
|
|
280
|
+
onChange: setGroupBy,
|
|
281
|
+
value: activeGroupBy
|
|
282
|
+
}) : void 0,
|
|
283
|
+
value: query
|
|
284
|
+
})
|
|
285
|
+
]
|
|
286
|
+
}),
|
|
287
|
+
onOpenAutoFocus: (e)=>{
|
|
288
|
+
e.preventDefault();
|
|
289
|
+
searchRef.current?.focus();
|
|
290
|
+
},
|
|
291
|
+
children: [
|
|
292
|
+
effectiveLoading && /*#__PURE__*/ jsx("div", {
|
|
293
|
+
"aria-label": labels.loading,
|
|
294
|
+
"aria-live": "polite",
|
|
295
|
+
className: "flex justify-center py-6 text-foreground-muted",
|
|
296
|
+
role: "status",
|
|
297
|
+
children: /*#__PURE__*/ jsx(Spinner, {
|
|
298
|
+
size: "sm"
|
|
299
|
+
})
|
|
300
|
+
}),
|
|
301
|
+
effectiveError && !effectiveLoading && /*#__PURE__*/ jsx("div", {
|
|
302
|
+
className: "px-4 py-4 text-center text-sm text-error",
|
|
303
|
+
role: "alert",
|
|
304
|
+
children: effectiveError.message
|
|
305
|
+
}),
|
|
306
|
+
deleteError && !effectiveError && /*#__PURE__*/ jsx("div", {
|
|
307
|
+
className: "border-b border-border px-4 py-2 text-sm text-error",
|
|
308
|
+
role: "alert",
|
|
309
|
+
children: deleteError.message
|
|
310
|
+
}),
|
|
311
|
+
!effectiveLoading && !effectiveError && 0 === filtered.length && /*#__PURE__*/ jsx("div", {
|
|
312
|
+
"aria-live": "polite",
|
|
313
|
+
className: "py-6 text-center text-sm text-foreground-muted",
|
|
314
|
+
role: "status",
|
|
315
|
+
children: query.trim() ? labels.emptyNoMatch(query.trim()) : labels.emptyNoModels
|
|
316
|
+
}),
|
|
317
|
+
/*#__PURE__*/ jsx("div", {
|
|
318
|
+
"aria-atomic": "true",
|
|
319
|
+
"aria-live": "polite",
|
|
320
|
+
className: "sr-only",
|
|
321
|
+
children: effectiveLoading || effectiveError || !(filtered.length > 0) ? '' : 1 === filtered.length ? labels.resultCount(filtered.length) : labels.resultCount(filtered.length)
|
|
322
|
+
}),
|
|
323
|
+
!effectiveLoading && !effectiveError && filtered.length > 0 && /*#__PURE__*/ jsxs(Fragment, {
|
|
324
|
+
children: [
|
|
325
|
+
/*#__PURE__*/ jsx(List, {
|
|
326
|
+
activeIndex: activeIndex,
|
|
327
|
+
"aria-label": labels.listboxLabel,
|
|
328
|
+
collapsedGroups: collapsedGroups,
|
|
329
|
+
groupCounts: groupCounts,
|
|
330
|
+
hideGroupHeaders: !showGroupHeaders || 'flat' === activeGroupBy,
|
|
331
|
+
id: listboxId,
|
|
332
|
+
onGroupToggle: toggleGroup,
|
|
333
|
+
onSelect: choose,
|
|
334
|
+
options: filtered,
|
|
335
|
+
renderRowActions: renderRowActions,
|
|
336
|
+
renderRowMeta: slots?.optionMeta,
|
|
337
|
+
selectedId: selected?.modelId ?? value ?? null,
|
|
338
|
+
setActiveIndex: setActiveIndex,
|
|
339
|
+
tagContext: tagContext,
|
|
340
|
+
tagVariants: customTagVariants
|
|
341
|
+
}),
|
|
342
|
+
slots?.listFooter?.(slotCtx)
|
|
343
|
+
]
|
|
344
|
+
})
|
|
345
|
+
]
|
|
346
|
+
})
|
|
347
|
+
]
|
|
348
|
+
}),
|
|
349
|
+
errorMessage && /*#__PURE__*/ jsx(FormFieldError, {
|
|
350
|
+
id: `${id}-error`,
|
|
351
|
+
role: "alert",
|
|
352
|
+
children: errorMessage
|
|
353
|
+
}),
|
|
354
|
+
/*#__PURE__*/ jsx(AlertDialog, {
|
|
355
|
+
onOpenChange: (next)=>!next && setPendingDelete(null),
|
|
356
|
+
open: null !== pendingDelete,
|
|
357
|
+
children: /*#__PURE__*/ jsxs(AlertDialogContent, {
|
|
358
|
+
container: popupContainer,
|
|
359
|
+
onCloseAutoFocus: (e)=>{
|
|
360
|
+
e.preventDefault();
|
|
361
|
+
searchRef.current?.focus();
|
|
362
|
+
},
|
|
363
|
+
children: [
|
|
364
|
+
/*#__PURE__*/ jsxs(AlertDialogHeader, {
|
|
365
|
+
children: [
|
|
366
|
+
/*#__PURE__*/ jsx(AlertDialogTitle, {
|
|
367
|
+
children: labels.deleteConfirmTitle
|
|
368
|
+
}),
|
|
369
|
+
/*#__PURE__*/ jsx(AlertDialogDescription, {
|
|
370
|
+
children: labels.deleteConfirmMessage(pendingDelete ? pendingDelete.displayName ?? pendingDelete.modelName : '')
|
|
371
|
+
})
|
|
372
|
+
]
|
|
373
|
+
}),
|
|
374
|
+
/*#__PURE__*/ jsxs(AlertDialogFooter, {
|
|
375
|
+
children: [
|
|
376
|
+
/*#__PURE__*/ jsx(AlertDialogCancel, {
|
|
377
|
+
autoFocus: true,
|
|
378
|
+
children: labels.deleteConfirmCancel
|
|
379
|
+
}),
|
|
380
|
+
/*#__PURE__*/ jsx(AlertDialogAction, {
|
|
381
|
+
className: "bg-error-background text-error hover:bg-error-background/80",
|
|
382
|
+
onClick: confirmPendingDelete,
|
|
383
|
+
children: labels.deleteConfirmConfirm
|
|
384
|
+
})
|
|
385
|
+
]
|
|
386
|
+
})
|
|
387
|
+
]
|
|
388
|
+
})
|
|
389
|
+
})
|
|
390
|
+
]
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
ModelPicker_ModelPicker.displayName = 'ModelPicker';
|
|
394
|
+
const GroupBySegmented = ({ value, onChange, labels })=>{
|
|
395
|
+
const groupByOptions = [
|
|
396
|
+
{
|
|
397
|
+
key: "subscription",
|
|
398
|
+
label: labels.groupByCategory
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
key: 'vendor',
|
|
402
|
+
label: labels.groupByProvider
|
|
403
|
+
}
|
|
404
|
+
];
|
|
405
|
+
return /*#__PURE__*/ jsx("div", {
|
|
406
|
+
"aria-label": labels.groupByAriaLabel,
|
|
407
|
+
className: "inline-flex gap-[3px] rounded-lg bg-surface-raised p-[3px]",
|
|
408
|
+
"data-slot": "model-picker-group-by",
|
|
409
|
+
role: "group",
|
|
410
|
+
children: groupByOptions.map((opt)=>{
|
|
411
|
+
const active = opt.key === value;
|
|
412
|
+
return /*#__PURE__*/ jsx("button", {
|
|
413
|
+
"aria-pressed": active,
|
|
414
|
+
className: cn('cursor-pointer rounded-md px-2.5 py-1.5 text-xs leading-tight font-semibold transition-colors', 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none', active ? 'bg-popover text-brand shadow-sm' : 'text-foreground-muted hover:bg-surface-hover'),
|
|
415
|
+
onClick: ()=>onChange(opt.key),
|
|
416
|
+
type: "button",
|
|
417
|
+
children: opt.label
|
|
418
|
+
}, opt.key);
|
|
419
|
+
})
|
|
420
|
+
});
|
|
421
|
+
};
|
|
422
|
+
const UseCustomModelFooter = ({ onActivate, disabled, labels })=>/*#__PURE__*/ jsxs("button", {
|
|
423
|
+
className: cn('flex w-full cursor-pointer items-center justify-start gap-3 px-4 py-3 text-left text-brand transition-colors', 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none focus-visible:ring-inset', 'disabled:cursor-default', disabled ? 'opacity-55' : 'hover:bg-surface-hover'),
|
|
424
|
+
"data-slot": "model-picker-use-custom-model",
|
|
425
|
+
disabled: disabled,
|
|
426
|
+
onClick: disabled ? void 0 : onActivate,
|
|
427
|
+
title: disabled ? labels.useCustomModelDisabledHint : void 0,
|
|
428
|
+
type: "button",
|
|
429
|
+
children: [
|
|
430
|
+
/*#__PURE__*/ jsx("span", {
|
|
431
|
+
className: "flex size-[30px] shrink-0 items-center justify-center rounded-lg bg-brand/10 text-brand",
|
|
432
|
+
children: /*#__PURE__*/ jsx(Plus, {
|
|
433
|
+
className: "size-[18px]"
|
|
434
|
+
})
|
|
435
|
+
}),
|
|
436
|
+
/*#__PURE__*/ jsxs("span", {
|
|
437
|
+
className: "flex min-w-0 flex-col",
|
|
438
|
+
children: [
|
|
439
|
+
/*#__PURE__*/ jsx("span", {
|
|
440
|
+
className: "text-sm leading-snug font-semibold",
|
|
441
|
+
children: labels.useCustomModelTitle
|
|
442
|
+
}),
|
|
443
|
+
/*#__PURE__*/ jsx("span", {
|
|
444
|
+
className: "text-xs leading-snug font-normal text-foreground-muted",
|
|
445
|
+
children: labels.useCustomModelSubtitle
|
|
446
|
+
})
|
|
447
|
+
]
|
|
448
|
+
})
|
|
449
|
+
]
|
|
450
|
+
});
|
|
451
|
+
export { ModelPicker_ModelPicker as ModelPicker };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __webpack_require__ = {};
|
|
4
|
+
(()=>{
|
|
5
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
6
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: definition[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.r = (exports1)=>{
|
|
17
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
18
|
+
value: 'Module'
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
21
|
+
value: true
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
})();
|
|
25
|
+
var __webpack_exports__ = {};
|
|
26
|
+
__webpack_require__.r(__webpack_exports__);
|
|
27
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
28
|
+
ModelTagChip: ()=>ModelTagChip
|
|
29
|
+
});
|
|
30
|
+
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
31
|
+
const external_lucide_react_namespaceObject = require("lucide-react");
|
|
32
|
+
const external_badge_cjs_namespaceObject = require("../badge.cjs");
|
|
33
|
+
const external_tooltip_cjs_namespaceObject = require("../tooltip.cjs");
|
|
34
|
+
const index_cjs_namespaceObject = require("../../../lib/index.cjs");
|
|
35
|
+
const VARIANT_MAP = {
|
|
36
|
+
recommended: 'success-mini',
|
|
37
|
+
preview: 'info-mini',
|
|
38
|
+
deprecating: 'warning-mini',
|
|
39
|
+
substituted: 'warning-mini',
|
|
40
|
+
'out-of-region': 'error-mini',
|
|
41
|
+
custom: 'mini',
|
|
42
|
+
thinking: 'info-mini',
|
|
43
|
+
'cost-basic': 'mini',
|
|
44
|
+
'cost-standard': 'mini',
|
|
45
|
+
'cost-premium': 'mini'
|
|
46
|
+
};
|
|
47
|
+
const BADGE_VARIANT = {
|
|
48
|
+
mini: 'secondary',
|
|
49
|
+
'info-mini': 'info',
|
|
50
|
+
'success-mini': 'success',
|
|
51
|
+
'warning-mini': 'warning',
|
|
52
|
+
'error-mini': 'error'
|
|
53
|
+
};
|
|
54
|
+
const ICON_MAP = {
|
|
55
|
+
recommended: external_lucide_react_namespaceObject.CircleCheck,
|
|
56
|
+
preview: external_lucide_react_namespaceObject.FlaskConical,
|
|
57
|
+
deprecating: external_lucide_react_namespaceObject.TriangleAlert,
|
|
58
|
+
substituted: external_lucide_react_namespaceObject.Route,
|
|
59
|
+
'out-of-region': external_lucide_react_namespaceObject.GlobeLock
|
|
60
|
+
};
|
|
61
|
+
const ModelTagChip = ({ tag, variants, icons, disableTooltip })=>{
|
|
62
|
+
const variantToken = tag.variant ?? variants?.[tag.kind] ?? VARIANT_MAP[tag.kind] ?? 'mini';
|
|
63
|
+
const Icon = icons && tag.kind in icons ? icons[tag.kind] : ICON_MAP[tag.kind];
|
|
64
|
+
const chip = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(external_badge_cjs_namespaceObject.Badge, {
|
|
65
|
+
className: (0, index_cjs_namespaceObject.cn)('h-4 gap-0.5 border-transparent px-1.5 py-0 text-[10px] leading-4 font-semibold pointer-events-none', 'mini' === variantToken && 'bg-foreground/10', variantToken),
|
|
66
|
+
"data-slot": "model-picker-tag",
|
|
67
|
+
"data-tag-kind": tag.kind,
|
|
68
|
+
variant: BADGE_VARIANT[variantToken] ?? 'secondary',
|
|
69
|
+
children: [
|
|
70
|
+
Icon ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(Icon, {
|
|
71
|
+
className: "size-3 shrink-0"
|
|
72
|
+
}) : null,
|
|
73
|
+
tag.label
|
|
74
|
+
]
|
|
75
|
+
});
|
|
76
|
+
if (tag.tooltip && !disableTooltip) return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_tooltip_cjs_namespaceObject.TooltipProvider, {
|
|
77
|
+
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(external_tooltip_cjs_namespaceObject.Tooltip, {
|
|
78
|
+
children: [
|
|
79
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_tooltip_cjs_namespaceObject.TooltipTrigger, {
|
|
80
|
+
asChild: true,
|
|
81
|
+
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
|
|
82
|
+
className: "inline-flex max-w-full",
|
|
83
|
+
children: chip
|
|
84
|
+
})
|
|
85
|
+
}),
|
|
86
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_tooltip_cjs_namespaceObject.TooltipContent, {
|
|
87
|
+
side: "top",
|
|
88
|
+
children: tag.tooltip
|
|
89
|
+
})
|
|
90
|
+
]
|
|
91
|
+
})
|
|
92
|
+
});
|
|
93
|
+
return chip;
|
|
94
|
+
};
|
|
95
|
+
exports.ModelTagChip = __webpack_exports__.ModelTagChip;
|
|
96
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
97
|
+
"ModelTagChip"
|
|
98
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
99
|
+
Object.defineProperty(exports, '__esModule', {
|
|
100
|
+
value: true
|
|
101
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { ModelTag } from './types';
|
|
3
|
+
export interface ModelTagChipProps {
|
|
4
|
+
tag: ModelTag;
|
|
5
|
+
/**
|
|
6
|
+
* Optional product-supplied lookup for tag kinds the design system
|
|
7
|
+
* doesn't know about. Wins over the built-in map for matching keys.
|
|
8
|
+
* Use when `customTagsFor` introduces a new kind (e.g.
|
|
9
|
+
* `{ multimodal: 'info-mini', onprem: 'warning-mini' }`).
|
|
10
|
+
*/
|
|
11
|
+
variants?: Record<string, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Optional product-supplied icon lookup for custom tag kinds. Keys
|
|
14
|
+
* are tag kinds; values are components rendered as the leading icon.
|
|
15
|
+
* Pass `null` for a kind to suppress the icon on a built-in kind.
|
|
16
|
+
* Tags without an entry render without an icon.
|
|
17
|
+
*/
|
|
18
|
+
icons?: Record<string, React.ComponentType<{
|
|
19
|
+
className?: string;
|
|
20
|
+
}> | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Render the chip without its tooltip. The tooltip trigger is a button, so
|
|
23
|
+
* a chip shown inside another button — the picker's trigger — would nest
|
|
24
|
+
* one button in another, which is invalid HTML and breaks hit-testing. The
|
|
25
|
+
* row chips carry the same tooltips, so nothing is lost.
|
|
26
|
+
*/
|
|
27
|
+
disableTooltip?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare const ModelTagChip: React.FC<ModelTagChipProps>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { CircleCheck, FlaskConical, GlobeLock, Route, TriangleAlert } from "lucide-react";
|
|
4
|
+
import { Badge } from "../badge.js";
|
|
5
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../tooltip.js";
|
|
6
|
+
import { cn } from "../../../lib/index.js";
|
|
7
|
+
const VARIANT_MAP = {
|
|
8
|
+
recommended: 'success-mini',
|
|
9
|
+
preview: 'info-mini',
|
|
10
|
+
deprecating: 'warning-mini',
|
|
11
|
+
substituted: 'warning-mini',
|
|
12
|
+
'out-of-region': 'error-mini',
|
|
13
|
+
custom: 'mini',
|
|
14
|
+
thinking: 'info-mini',
|
|
15
|
+
'cost-basic': 'mini',
|
|
16
|
+
'cost-standard': 'mini',
|
|
17
|
+
'cost-premium': 'mini'
|
|
18
|
+
};
|
|
19
|
+
const BADGE_VARIANT = {
|
|
20
|
+
mini: 'secondary',
|
|
21
|
+
'info-mini': 'info',
|
|
22
|
+
'success-mini': 'success',
|
|
23
|
+
'warning-mini': 'warning',
|
|
24
|
+
'error-mini': 'error'
|
|
25
|
+
};
|
|
26
|
+
const ICON_MAP = {
|
|
27
|
+
recommended: CircleCheck,
|
|
28
|
+
preview: FlaskConical,
|
|
29
|
+
deprecating: TriangleAlert,
|
|
30
|
+
substituted: Route,
|
|
31
|
+
'out-of-region': GlobeLock
|
|
32
|
+
};
|
|
33
|
+
const ModelTagChip = ({ tag, variants, icons, disableTooltip })=>{
|
|
34
|
+
const variantToken = tag.variant ?? variants?.[tag.kind] ?? VARIANT_MAP[tag.kind] ?? 'mini';
|
|
35
|
+
const Icon = icons && tag.kind in icons ? icons[tag.kind] : ICON_MAP[tag.kind];
|
|
36
|
+
const chip = /*#__PURE__*/ jsxs(Badge, {
|
|
37
|
+
className: cn('h-4 gap-0.5 border-transparent px-1.5 py-0 text-[10px] leading-4 font-semibold pointer-events-none', 'mini' === variantToken && 'bg-foreground/10', variantToken),
|
|
38
|
+
"data-slot": "model-picker-tag",
|
|
39
|
+
"data-tag-kind": tag.kind,
|
|
40
|
+
variant: BADGE_VARIANT[variantToken] ?? 'secondary',
|
|
41
|
+
children: [
|
|
42
|
+
Icon ? /*#__PURE__*/ jsx(Icon, {
|
|
43
|
+
className: "size-3 shrink-0"
|
|
44
|
+
}) : null,
|
|
45
|
+
tag.label
|
|
46
|
+
]
|
|
47
|
+
});
|
|
48
|
+
if (tag.tooltip && !disableTooltip) return /*#__PURE__*/ jsx(TooltipProvider, {
|
|
49
|
+
children: /*#__PURE__*/ jsxs(Tooltip, {
|
|
50
|
+
children: [
|
|
51
|
+
/*#__PURE__*/ jsx(TooltipTrigger, {
|
|
52
|
+
asChild: true,
|
|
53
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
54
|
+
className: "inline-flex max-w-full",
|
|
55
|
+
children: chip
|
|
56
|
+
})
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ jsx(TooltipContent, {
|
|
59
|
+
side: "top",
|
|
60
|
+
children: tag.tooltip
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
return chip;
|
|
66
|
+
};
|
|
67
|
+
export { ModelTagChip };
|