@moldable-ai/ui 0.2.29 → 0.2.32
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/catalog/component-catalog.d.ts +9 -2
- package/dist/catalog/component-catalog.d.ts.map +1 -1
- package/dist/catalog/component-catalog.js +11 -7
- package/dist/catalog/core-control-stories.d.ts.map +1 -1
- package/dist/catalog/core-control-stories.js +1 -1
- package/dist/catalog/core-foundation-stories.d.ts.map +1 -1
- package/dist/catalog/core-foundation-stories.js +5 -5
- package/dist/components/app-error-boundary.d.ts +1 -1
- package/dist/components/chat/chat-image-lightbox.d.ts +8 -0
- package/dist/components/chat/chat-image-lightbox.d.ts.map +1 -1
- package/dist/components/chat/chat-image-lightbox.js +24 -2
- package/dist/components/chat/chat-input.d.ts +3 -2
- package/dist/components/chat/chat-input.d.ts.map +1 -1
- package/dist/components/chat/chat-input.js +3 -3
- package/dist/components/chat/chat-message.d.ts.map +1 -1
- package/dist/components/chat/chat-message.js +3 -1
- package/dist/components/chat/chat-panel.d.ts +3 -1
- package/dist/components/chat/chat-panel.d.ts.map +1 -1
- package/dist/components/chat/chat-panel.js +53 -39
- package/dist/components/chat/conversation-history.d.ts +4 -2
- package/dist/components/chat/conversation-history.d.ts.map +1 -1
- package/dist/components/chat/conversation-history.js +20 -15
- package/dist/components/ui/alert.d.ts +1 -1
- package/dist/components/ui/app-frame.d.ts +20 -1
- package/dist/components/ui/app-frame.d.ts.map +1 -1
- package/dist/components/ui/app-frame.js +37 -7
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/button.d.ts +5 -3
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/button.js +39 -11
- package/dist/components/ui/card.d.ts +12 -2
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/card.js +3 -2
- package/dist/components/ui/checkbox.d.ts +4 -1
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/checkbox.js +4 -4
- package/dist/components/ui/context-menu.d.ts.map +1 -1
- package/dist/components/ui/context-menu.js +7 -6
- package/dist/components/ui/date-field.d.ts +1 -1
- package/dist/components/ui/dropdown-menu.d.ts +1 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js +9 -8
- package/dist/components/ui/icon-button.d.ts +1 -1
- package/dist/components/ui/icon-button.d.ts.map +1 -1
- package/dist/components/ui/icon-button.js +1 -0
- package/dist/components/ui/input.d.ts +6 -2
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/input.js +2 -2
- package/dist/components/ui/material.d.ts +8 -3
- package/dist/components/ui/material.d.ts.map +1 -1
- package/dist/components/ui/material.js +2 -2
- package/dist/components/ui/menu-items.d.ts +2 -1
- package/dist/components/ui/menu-items.d.ts.map +1 -1
- package/dist/components/ui/menu-items.js +3 -2
- package/dist/components/ui/message-scroller-controller.d.ts +15 -17
- package/dist/components/ui/message-scroller-controller.d.ts.map +1 -1
- package/dist/components/ui/message-scroller-controller.js +106 -91
- package/dist/components/ui/message-scroller-primitive.d.ts +2 -0
- package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -1
- package/dist/components/ui/message-scroller-primitive.js +2 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -1
- package/dist/components/ui/message-scroller.js +2 -2
- package/dist/components/ui/number-input.d.ts +1 -1
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/search-field.d.ts +4 -2
- package/dist/components/ui/search-field.d.ts.map +1 -1
- package/dist/components/ui/search-field.js +16 -6
- package/dist/components/ui/segmented-control.d.ts +3 -1
- package/dist/components/ui/segmented-control.d.ts.map +1 -1
- package/dist/components/ui/segmented-control.js +23 -17
- package/dist/components/ui/select.js +2 -2
- package/dist/components/ui/sidebar.d.ts +10 -4
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/sidebar.js +74 -17
- package/dist/components/ui/status.d.ts +1 -1
- package/dist/components/ui/status.js +1 -1
- package/dist/components/ui/switch.d.ts +3 -1
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/components/ui/switch.js +3 -2
- package/dist/components/ui/toolbar-controls.d.ts +13 -3
- package/dist/components/ui/toolbar-controls.d.ts.map +1 -1
- package/dist/components/ui/toolbar-controls.js +35 -10
- package/dist/components/ui/toolbar.d.ts +5 -4
- package/dist/components/ui/toolbar.d.ts.map +1 -1
- package/dist/components/ui/toolbar.js +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/frame-lifecycle.d.ts +1 -0
- package/dist/lib/frame-lifecycle.d.ts.map +1 -1
- package/dist/lib/frame-lifecycle.js +7 -0
- package/dist/lib/theme.d.ts +39 -5
- package/dist/lib/theme.d.ts.map +1 -1
- package/dist/lib/theme.js +105 -17
- package/dist/tokens/contracts.d.ts +79 -0
- package/dist/tokens/contracts.d.ts.map +1 -0
- package/dist/tokens/contracts.js +57 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +1 -0
- package/docs/README.md +2 -0
- package/docs/adaptive-materials.md +14 -9
- package/docs/design-tokens.md +10 -6
- package/docs/foundations.md +3 -3
- package/docs/macos-design-audit.md +144 -0
- package/docs/native-integration.md +4 -4
- package/docs/platform-architecture.md +189 -0
- package/docs/standalone-app-windows.md +37 -0
- package/docs/visual-regression.md +6 -8
- package/package.json +13 -1
- package/src/components/ui/accordion.md +46 -0
- package/src/components/ui/alert.md +12 -4
- package/src/components/ui/app-frame.md +8 -5
- package/src/components/ui/aspect-ratio.md +37 -0
- package/src/components/ui/avatar.md +48 -0
- package/src/components/ui/breadcrumb.md +52 -0
- package/src/components/ui/button-group.md +43 -0
- package/src/components/ui/button.md +21 -4
- package/src/components/ui/calendar.md +42 -0
- package/src/components/ui/card.md +43 -0
- package/src/components/ui/carousel.md +47 -0
- package/src/components/ui/chart.md +52 -0
- package/src/components/ui/checkbox.md +36 -0
- package/src/components/ui/collapsible.md +2 -3
- package/src/components/ui/color-well.md +14 -4
- package/src/components/ui/combobox.md +3 -3
- package/src/components/ui/confirm-dialog.md +5 -4
- package/src/components/ui/context-menu.md +3 -2
- package/src/components/ui/date-field.md +6 -1
- package/src/components/ui/date-picker.md +6 -3
- package/src/components/ui/dialog.md +14 -12
- package/src/components/ui/drawer.md +58 -0
- package/src/components/ui/dropdown-menu.md +16 -14
- package/src/components/ui/error-boundary-view.md +1 -1
- package/src/components/ui/field.md +2 -1
- package/src/components/ui/form.md +71 -0
- package/src/components/ui/grid.md +4 -3
- package/src/components/ui/icon-button.md +4 -1
- package/src/components/ui/input-group.md +49 -0
- package/src/components/ui/input-otp.md +56 -0
- package/src/components/ui/input.md +40 -0
- package/src/components/ui/inspector.md +47 -7
- package/src/components/ui/item.md +5 -3
- package/src/components/ui/kbd.md +30 -0
- package/src/components/ui/label.md +29 -0
- package/src/components/ui/list.md +2 -2
- package/src/components/ui/material.md +25 -12
- package/src/components/ui/menu-items.md +62 -0
- package/src/components/ui/menubar.md +58 -0
- package/src/components/ui/message-scroller-primitive.md +70 -0
- package/src/components/ui/message-scroller.md +89 -0
- package/src/components/ui/navigation-button-group.md +4 -3
- package/src/components/ui/navigation-menu.md +52 -0
- package/src/components/ui/number-input.md +8 -0
- package/src/components/ui/pagination.md +51 -0
- package/src/components/ui/panel.md +6 -0
- package/src/components/ui/popover.md +10 -7
- package/src/components/ui/progress.md +31 -0
- package/src/components/ui/radio-group.md +36 -0
- package/src/components/ui/resizable.md +2 -1
- package/src/components/ui/scroll-area.md +3 -1
- package/src/components/ui/search-field.md +6 -1
- package/src/components/ui/segmented-control.md +6 -1
- package/src/components/ui/separator.md +35 -0
- package/src/components/ui/sidebar.md +29 -6
- package/src/components/ui/skeleton.md +36 -0
- package/src/components/ui/slider.md +58 -0
- package/src/components/ui/spinner.md +41 -0
- package/src/components/ui/split-view.md +8 -4
- package/src/components/ui/switch.md +44 -0
- package/src/components/ui/table.md +7 -7
- package/src/components/ui/tabs.md +3 -1
- package/src/components/ui/textarea.md +41 -0
- package/src/components/ui/toggle-group.md +2 -2
- package/src/components/ui/toggle.md +9 -9
- package/src/components/ui/toolbar-controls.md +24 -12
- package/src/components/ui/toolbar.md +6 -6
- package/src/styles/index.css +298 -117
- package/src/tokens/contracts.ts +131 -0
- package/src/tokens/index.css +6 -0
- package/src/tokens/index.ts +23 -0
- package/src/tokens/macos-26/README.md +37 -0
- package/src/tokens/macos-26/aliases.css +53 -0
- package/src/tokens/macos-26/compatibility.css +7 -0
- package/src/tokens/macos-26/index.css +3 -0
- package/src/tokens/macos-26/source/provenance.generated.json +28 -0
- package/src/tokens/macos-26/source/sidebar.generated.css +29 -0
- package/src/tokens/macos-26/source.css +7 -0
- package/src/tokens/macos-26/web-adaptations.json +25 -0
- package/src/tokens/macos-26/web-adaptations.md +15 -0
- package/src/tokens/macos-27/accessibility.css +11 -0
- package/src/tokens/macos-27/aliases.css +304 -0
- package/src/tokens/macos-27/compatibility.css +212 -0
- package/src/tokens/macos-27/index.css +15 -0
- package/src/tokens/macos-27/recipes.css +23 -0
- package/src/tokens/macos-27/source/chrome.generated.css +338 -0
- package/src/tokens/macos-27/source/colors.generated.css +140 -0
- package/src/tokens/macos-27/source/context.generated.css +18 -0
- package/src/tokens/macos-27/source/controls.generated.css +764 -0
- package/src/tokens/macos-27/source/effects.generated.css +68 -0
- package/src/tokens/macos-27/source/kit.generated.css +50 -0
- package/src/tokens/macos-27/source/overlays-status.generated.css +931 -0
- package/src/tokens/macos-27/source/paint-styles.generated.css +81 -0
- package/src/tokens/macos-27/source/provenance.generated.json +62 -0
- package/src/tokens/macos-27/source/sizes.generated.css +385 -0
- package/src/tokens/macos-27/source/source.generated.json +554 -0
- package/src/tokens/macos-27/source/text-styles.generated.css +116 -0
- package/src/tokens/macos-27/source.css +17 -0
- package/src/tokens/macos-27/web-adaptations.css +98 -0
- package/src/tokens/macos-27/web-adaptations.json +163 -0
- package/src/tokens/macos-27/web-adaptations.md +117 -0
- package/src/tokens/moldable/brand.css +165 -0
- package/src/tokens/moldable/index.css +1 -0
- package/src/tokens/platform-contract.test.ts +294 -0
|
@@ -10,6 +10,7 @@ import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover.js';
|
|
|
10
10
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '../ui/tooltip.js';
|
|
11
11
|
import { ChatInput, } from './chat-input.js';
|
|
12
12
|
import { CompactingMessage, ThinkingMessage, getChatMessageRenderKey, } from './chat-message.js';
|
|
13
|
+
import { ChatImageLightboxProvider } from './chat-image-lightbox.js';
|
|
13
14
|
import { MessageRow, computeIsThinking, } from './chat-messages.js';
|
|
14
15
|
import { ConversationHistory, ConversationSidebar, } from './conversation-history.js';
|
|
15
16
|
import { ModelEffortSelector, } from './model-effort-selector.js';
|
|
@@ -113,8 +114,11 @@ function MessageNavigationTrail({ items }) {
|
|
|
113
114
|
}), "data-message-navigation-row": true, className: "flex h-2.5 w-9 shrink-0 cursor-pointer items-center outline-none", children: _jsx("span", { className: "flex h-0.5 w-[30px] items-center", children: _jsx("span", { "data-message-navigation-marker": true, className: cn('bg-muted-foreground rounded-pill h-0.5 w-[26px] origin-left opacity-40', isCurrent && 'bg-foreground opacity-60') }) }) }) }), _jsx(TooltipContent, { side: "right", className: "max-w-72", children: anchor.label })] }, anchor.id));
|
|
114
115
|
}) }) }) }) }));
|
|
115
116
|
}
|
|
116
|
-
function ChatMessageViewport({
|
|
117
|
-
|
|
117
|
+
function ChatMessageViewport({ currentConversationId, ...props }) {
|
|
118
|
+
return (_jsx(MessageScrollerProvider, { autoScroll: true, defaultScrollPosition: "end", scrollPreviousItemPeek: 64, children: _jsx(ChatImageLightboxProvider, { children: _jsx(ChatMessageViewportBody, { ...props }) }) }, currentConversationId ?? 'new-conversation'));
|
|
119
|
+
}
|
|
120
|
+
function ChatMessageViewportBody({ items, renderItem, toolProgress, onApprovalResponse, scrollToBottomSignal, isBusy, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, showNavigationTrail = false, scrollAreaClassName, contentClassName, scrollButtonClassName, }) {
|
|
121
|
+
const { beginHistoryLoad, finishHistoryLoad } = useMessageScroller();
|
|
118
122
|
const loadingOlderRef = useRef(false);
|
|
119
123
|
const handleViewportScroll = useCallback((event) => {
|
|
120
124
|
const viewport = event.currentTarget;
|
|
@@ -126,27 +130,27 @@ function ChatMessageViewport({ items, renderItem, toolProgress, onApprovalRespon
|
|
|
126
130
|
return;
|
|
127
131
|
}
|
|
128
132
|
loadingOlderRef.current = true;
|
|
129
|
-
|
|
130
|
-
// itself, synchronously in the same mutation pass — compensating here
|
|
131
|
-
// after a paint produced a visible two-step jump. Only a reset (the
|
|
132
|
-
// cursor raced a history rewrite) still needs an explicit landing.
|
|
133
|
+
beginHistoryLoad();
|
|
133
134
|
void onLoadOlderMessages()
|
|
134
135
|
.then((outcome) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return;
|
|
140
|
-
viewport.scrollTop = viewport.scrollHeight;
|
|
141
|
-
});
|
|
136
|
+
finishHistoryLoad(outcome !== 'unchanged');
|
|
137
|
+
})
|
|
138
|
+
.catch(() => {
|
|
139
|
+
finishHistoryLoad(false);
|
|
142
140
|
})
|
|
143
141
|
.finally(() => {
|
|
144
142
|
window.requestAnimationFrame(() => {
|
|
145
143
|
loadingOlderRef.current = false;
|
|
146
144
|
});
|
|
147
145
|
});
|
|
148
|
-
}, [
|
|
149
|
-
|
|
146
|
+
}, [
|
|
147
|
+
beginHistoryLoad,
|
|
148
|
+
finishHistoryLoad,
|
|
149
|
+
hasOlderMessages,
|
|
150
|
+
isLoadingOlderMessages,
|
|
151
|
+
onLoadOlderMessages,
|
|
152
|
+
]);
|
|
153
|
+
return (_jsxs(MessageScroller, { className: "relative min-h-0 min-w-0 flex-1", children: [_jsx(MessageScrollerCommandSync, { signal: scrollToBottomSignal }), _jsx(MessageScrollerViewport, { className: scrollAreaClassName, "data-message-scroll-fade": true, "data-has-older-messages": hasOlderMessages ? 'true' : 'false', onScroll: handleViewportScroll, children: _jsx(MessageScrollerContent, { "aria-busy": isBusy || isLoadingOlderMessages, className: contentClassName, children: _jsx(ToolProgressProvider, { value: toolProgress, children: _jsx(ToolApprovalProvider, { onApprovalResponse: onApprovalResponse ?? null, children: items.map((item) => (_jsx(MessageScrollerItem, { messageId: item.key, scrollAnchor: item.kind === 'message' && item.message.role === 'user', children: renderItem(item) }, item.key))) }) }) }) }), items.length > 0 && (_jsx(MessageScrollerButton, { className: scrollButtonClassName })), showNavigationTrail && _jsx(MessageNavigationTrail, { items: items })] }));
|
|
150
154
|
}
|
|
151
155
|
function clampPercent(value) {
|
|
152
156
|
if (!Number.isFinite(value))
|
|
@@ -181,7 +185,7 @@ function ContextWindowIndicator({ usage, planUsage, }) {
|
|
|
181
185
|
: 'var(--muted-foreground)';
|
|
182
186
|
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring rounded-pill flex size-8 cursor-pointer items-center justify-center bg-transparent p-0 focus-visible:outline-none focus-visible:ring-1", "aria-label": `Context window ${usedPercent}% full`, children: _jsx("span", { className: "rounded-pill relative size-4", style: {
|
|
183
187
|
background: `conic-gradient(${ringColor} ${usedPercent}%, color-mix(in oklch, var(--muted-foreground) 22%, transparent) 0)`,
|
|
184
|
-
}, children: _jsx("span", { className: "bg-background rounded-pill absolute inset-[3px]" }) }) }) }), _jsxs(PopoverContent, { align: "end", side: "top", sideOffset: 8, className: "w-80 p-3 shadow-lg", children: [_jsxs("div", { className: "text-ui-body flex items-center justify-between gap-3", children: [_jsx("span", { className: "text-muted-foreground", children: "Context window" }), _jsxs("span", { children: [formatTokenCount(usage.usedTokens), " /", ' ', formatTokenCount(usage.maxTokens), " (", usedPercent, "%)"] })] }), _jsx("div", { className: "bg-muted rounded-pill mt-2 h-1.5 overflow-hidden", children: _jsx("div", { className: "bg-primary rounded-pill h-full", style: { width: `${usedPercent}%` } }) }), usage.compactsAutomatically && (_jsx("div", { className: "text-muted-foreground text-11 mt-2 leading-4", children: "Moldable automatically compacts its context" })), planUsage && planUsage.windows.length > 0 && (_jsxs("div", { className: "border-border mt-3 flex flex-col gap-3 border-t pt-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption", children: ["Plan usage limits", planUsage.planLabel ? ` · ${planUsage.planLabel}` : ''] }), planUsage.accountLabel && (_jsx("div", { className: "text-ui-caption mt-0.5 truncate font-medium", children: planUsage.accountLabel }))] }), planUsage.windows.map((window) => {
|
|
188
|
+
}, children: _jsx("span", { className: "bg-background rounded-pill absolute inset-[3px]" }) }) }) }), _jsxs(PopoverContent, { align: "end", side: "top", sideOffset: 8, className: "w-80 p-3 shadow-lg", children: [_jsxs("div", { className: "text-ui-body flex items-center justify-between gap-3", children: [_jsx("span", { className: "text-muted-foreground", children: "Context window" }), _jsxs("span", { className: "text-ui-caption", children: [formatTokenCount(usage.usedTokens), " /", ' ', formatTokenCount(usage.maxTokens), " (", usedPercent, "%)"] })] }), _jsx("div", { className: "bg-muted rounded-pill mt-2 h-1.5 overflow-hidden", children: _jsx("div", { className: "bg-primary rounded-pill h-full", style: { width: `${usedPercent}%` } }) }), usage.compactsAutomatically && (_jsx("div", { className: "text-muted-foreground text-11 mt-2 leading-4", children: "Moldable automatically compacts its context" })), planUsage && planUsage.windows.length > 0 && (_jsxs("div", { className: "border-border mt-3 flex flex-col gap-3 border-t pt-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption", children: ["Plan usage limits", planUsage.planLabel ? ` · ${planUsage.planLabel}` : ''] }), planUsage.accountLabel && (_jsx("div", { className: "text-ui-caption mt-0.5 truncate font-medium", children: planUsage.accountLabel }))] }), planUsage.windows.map((window) => {
|
|
185
189
|
const reset = formatUsageReset(window.resetAt);
|
|
186
190
|
const percent = clampPercent(window.usedPercent);
|
|
187
191
|
return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-ui-caption flex items-center justify-between gap-3", children: [_jsx("span", { children: window.label }), _jsxs("span", { className: "text-muted-foreground", children: [reset ? `Resets ${reset} · ` : '', percent, "%"] })] }), _jsx("div", { className: "bg-muted rounded-pill h-1.5 overflow-hidden", children: _jsx("div", { className: percent >= 90
|
|
@@ -217,7 +221,7 @@ function QueuedMessageRow({ message, isResponding, onRetryQueuedMessage, onSteer
|
|
|
217
221
|
/**
|
|
218
222
|
* Floating chat panel with model selector
|
|
219
223
|
*/
|
|
220
|
-
export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, modelProviders, modelEffortPresets, selectedModel, selectedReasoningEffort, onModelEffortChange, conversations, currentConversationId, currentAppId, hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, onResolveMessageContent, scrollToBottomSignal = 0, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, onSelectConversation, onArchiveConversation, onArchiveConversationGroup, placeholder = 'Ask anything...', welcomeMessage, isExpanded, onExpandedChange, isFullScreen = false, onFullScreenChange, isMinimized = false, onMinimizedChange, className, error, onRetryError, missingApiKey, authIssue, onConnectChatGPT, onAdvancedSetup, toolProgress = {}, onApprovalResponse, isEditingApp = true, onEditingAppChange, showEditingAppToggle = false, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments = [], onRemoveImageAttachment, isImageDropActive = false, queuedMessages = [], onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, onReorderQueuedMessages, onEditQueuedMessage, slashCommands, onSlashCommandSelect, isCompacting = false, compactedHistoryStartIndex, contextUsage, planUsage, }) {
|
|
224
|
+
export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, modelProviders, modelEffortPresets, selectedModel, selectedReasoningEffort, onModelEffortChange, conversations, currentConversationId, currentAppId, groupConversationHistory = false, hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, onResolveMessageContent, scrollToBottomSignal = 0, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, onSelectConversation, onArchiveConversation, onArchiveConversationGroup, placeholder = 'Ask anything...', welcomeMessage, isExpanded, onExpandedChange, isFullScreen = false, onFullScreenChange, isMinimized = false, onMinimizedChange, className, error, onRetryError, missingApiKey, authIssue, onConnectChatGPT, onAdvancedSetup, toolProgress = {}, onApprovalResponse, isEditingApp = true, onEditingAppChange, showEditingAppToggle = false, checkpoints, restoringMessageId, onRestoreCheckpoint, imageAttachments = [], onRemoveImageAttachment, isImageDropActive = false, queuedMessages = [], onRemoveQueuedMessage, onRetryQueuedMessage, onSteerQueuedMessage, onReorderQueuedMessages, onEditQueuedMessage, slashCommands, onSlashCommandSelect, isCompacting = false, compactedHistoryStartIndex, contextUsage, planUsage, }) {
|
|
221
225
|
const inputRef = useRef(null);
|
|
222
226
|
const fullScreenTriggerRef = useRef(null);
|
|
223
227
|
const [isConnectingChatGPT, setIsConnectingChatGPT] = useState(false);
|
|
@@ -317,7 +321,7 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
317
321
|
: 'Not editing app (click to enable)' }) })] }) })) : null;
|
|
318
322
|
const composerStartControls = (_jsxs(_Fragment, { children: [conversations &&
|
|
319
323
|
(conversations.length > 0 || onNewChat) &&
|
|
320
|
-
onSelectConversation && (_jsx(ConversationHistory, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: onSelectConversation, onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, disabled: false, dropdownAlign: "start", dropdownSide: "top", tooltipSide: "top", hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations })), editingAppControl] }));
|
|
324
|
+
onSelectConversation && (_jsx(ConversationHistory, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, groupByScope: groupConversationHistory, onSelect: onSelectConversation, onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, disabled: false, dropdownAlign: "start", dropdownSide: "top", tooltipSide: "top", hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations })), editingAppControl] }));
|
|
321
325
|
// Keyboard shortcut: Cmd+Shift+O for new chat
|
|
322
326
|
useEffect(() => {
|
|
323
327
|
const handleKeyDown = (e) => {
|
|
@@ -439,40 +443,50 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
439
443
|
window.requestAnimationFrame(() => {
|
|
440
444
|
fullScreenTriggerRef.current?.focus();
|
|
441
445
|
});
|
|
442
|
-
}, size: "full", className: "rounded-container flex gap-0 overflow-hidden border-0 p-0", children: [_jsx("div", { "data-tauri-drag-region": true, className: "absolute inset-x-0 top-0 z-20 h-9", "aria-hidden": "true" }), isImageDropActive && (_jsxs("div", { className: "bg-background/90 border-primary/50 text-foreground absolute inset-0 z-50 flex flex-col items-center justify-center gap-2 rounded-[inherit] border-2 border-dashed backdrop-blur-sm", children: [_jsx(ImageIcon, { className: "text-primary size-7" }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-ui-body font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-ui-caption", children: "They stay on disk and are read when sent" })] })] })), _jsxs("aside", { className: "border-border bg-muted/50 rounded-r-container relative z-10 flex w-[280px] shrink-0 flex-col overflow-hidden border-r px-3 pb-4 pt-11", children: [_jsxs("button", { type: "button", onClick: () => onFullScreenChange?.(false), className: "text-muted-foreground hover:text-foreground rounded-container text-ui-body mb-4 flex h-8 cursor-pointer items-center gap-2 px-2 transition-colors", children: [_jsx(Minimize2, { className: "size-4" }), "Back to app"] }), _jsx(ConversationSidebar, { conversations: conversations ?? [], currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: onSelectConversation ?? (() => undefined), onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, hideScrollbar: true, disabled: false, hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations, className: "min-h-0 flex-1" })] }), _jsxs("section", { className: "relative flex min-w-0 flex-1 flex-col", children: [_jsxs("header", { className: "border-border flex h-14 shrink-0 items-center justify-between border-b px-5", children: [_jsx(DialogTitle, { className: "text-ui-body truncate font-medium", children: selectedConversation?.title ?? 'New conversation' }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", onClick: () => onFullScreenChange?.(false), "aria-label": "Exit full screen", className: "text-muted-foreground hover:text-foreground relative z-30 cursor-pointer", children: _jsx(Minimize2, { className: "size-4" }) }) }), _jsx(TooltipContent, { children: "Exit full screen" })] }) })] }), _jsx(ChatMessageViewport, { items: listItems, renderItem: renderVirtualItem, toolProgress: toolProgress, onApprovalResponse: onApprovalResponse, currentConversationId: currentConversationId, scrollToBottomSignal: scrollToBottomSignal, isBusy: isResponding, hasOlderMessages: hasOlderMessages, isLoadingOlderMessages: isLoadingOlderMessages, onLoadOlderMessages: onLoadOlderMessages, showNavigationTrail: true, contentClassName: "mx-auto w-full min-w-0 max-w-3xl overflow-hidden px-6 py-6", scrollButtonClassName: "absolute bottom-3 left-1/2 z-20 size-8 -translate-x-1/2 cursor-pointer rounded-pill shadow-lg" }), authPromptCopy && (_jsx("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: _jsx(ChatAuthPrompt, { copy: authPromptCopy, isConnecting: isConnectingChatGPT, onConnect: onConnectChatGPT ? handleConnectChatGPT : undefined, onAdvancedSetup: onAdvancedSetup }) })), _jsxs("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border bg-muted/30 rounded-container mb-2 border p-3", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx("div", { className: "bg-background overflow-hidden rounded-[24px] shadow-[0_8px_40px_-12px_rgba(0,0,0,0.2)]", children: _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: editingAppControl, footerControls: composerControls, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect }) })] })] })] }) }));
|
|
446
|
+
}, size: "full", className: "rounded-container flex gap-0 overflow-hidden border-0 p-0", children: [_jsx("div", { "data-tauri-drag-region": true, className: "absolute inset-x-0 top-0 z-20 h-9", "aria-hidden": "true" }), isImageDropActive && (_jsxs("div", { className: "bg-background/90 border-primary/50 text-foreground absolute inset-0 z-50 flex flex-col items-center justify-center gap-2 rounded-[inherit] border-2 border-dashed backdrop-blur-sm", children: [_jsx(ImageIcon, { className: "text-primary size-7" }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-ui-body font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-ui-caption", children: "They stay on disk and are read when sent" })] })] })), _jsxs("aside", { className: "border-border bg-muted/50 rounded-r-container relative z-10 flex w-[280px] shrink-0 flex-col overflow-hidden border-r px-3 pb-4 pt-11", children: [_jsxs("button", { type: "button", onClick: () => onFullScreenChange?.(false), className: "text-muted-foreground hover:text-foreground rounded-container text-ui-body mb-4 flex h-8 cursor-pointer items-center gap-2 px-2 transition-colors", children: [_jsx(Minimize2, { className: "size-4" }), "Back to app"] }), _jsx(ConversationSidebar, { conversations: conversations ?? [], currentConversationId: currentConversationId, currentAppId: currentAppId, groupByScope: groupConversationHistory, onSelect: onSelectConversation ?? (() => undefined), onArchive: onArchiveConversation, onArchiveGroup: onArchiveConversationGroup, onNewChat: handleNewChat, newChatDisabled: false, hideScrollbar: true, disabled: false, hasMoreConversations: hasMoreConversations, isLoadingMoreConversations: isLoadingMoreConversations, onLoadMoreConversations: onLoadMoreConversations, className: "min-h-0 flex-1" })] }), _jsxs("section", { className: "relative flex min-w-0 flex-1 flex-col", children: [_jsxs("header", { className: "border-border flex h-14 shrink-0 items-center justify-between border-b px-5", children: [_jsx(DialogTitle, { className: "text-ui-body truncate font-medium", children: selectedConversation?.title ?? 'New conversation' }), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", onClick: () => onFullScreenChange?.(false), "aria-label": "Exit full screen", className: "text-muted-foreground hover:text-foreground relative z-30 cursor-pointer", children: _jsx(Minimize2, { className: "size-4" }) }) }), _jsx(TooltipContent, { children: "Exit full screen" })] }) })] }), _jsx(ChatMessageViewport, { items: listItems, renderItem: renderVirtualItem, toolProgress: toolProgress, onApprovalResponse: onApprovalResponse, currentConversationId: currentConversationId, scrollToBottomSignal: scrollToBottomSignal, isBusy: isResponding, hasOlderMessages: hasOlderMessages, isLoadingOlderMessages: isLoadingOlderMessages, onLoadOlderMessages: onLoadOlderMessages, showNavigationTrail: true, contentClassName: "mx-auto w-full min-w-0 max-w-3xl overflow-hidden px-6 py-6", scrollButtonClassName: "absolute bottom-3 left-1/2 z-20 size-8 -translate-x-1/2 cursor-pointer rounded-pill shadow-lg" }), authPromptCopy && (_jsx("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: _jsx(ChatAuthPrompt, { copy: authPromptCopy, isConnecting: isConnectingChatGPT, onConnect: onConnectChatGPT ? handleConnectChatGPT : undefined, onAdvancedSetup: onAdvancedSetup }) })), _jsxs("div", { className: "mx-auto w-full max-w-3xl shrink-0 px-6 pb-2", children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border bg-muted/30 rounded-container mb-2 border p-3", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx("div", { className: "bg-background overflow-hidden rounded-[24px] shadow-[0_8px_40px_-12px_rgba(0,0,0,0.2)]", children: _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: editingAppControl, footerControls: composerControls, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect }) })] })] })] }) }));
|
|
443
447
|
}
|
|
444
448
|
return (_jsxs(_Fragment, { children: [_jsx(AnimatePresence, { children: isExpanded && !isMinimized && (_jsx(motion.div, { "data-moldable-chat-backdrop": true, initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, className: "fixed inset-0 z-40 bg-black/20", onClick: () => onExpandedChange(false) })) }), _jsx(motion.div, { "data-moldable-chat-panel": true, initial: false, animate: {
|
|
445
449
|
width: isExpanded ? 'min(90vw, 640px)' : '400px',
|
|
446
450
|
y: isMinimized ? 'calc(100% + 24px)' : 0,
|
|
447
451
|
opacity: isMinimized ? 0 : 1,
|
|
448
|
-
}, transition: { type: 'tween', duration: 0.25, ease: 'easeOut' }, className: cn('pointer-events-none fixed bottom-6 left-[calc(50%+var(--sidebar-width,0px)/2)] z-50 flex -translate-x-1/2 justify-center', isMinimized && 'pointer-events-none', className), children: _jsxs("div", { "data-chat-drop-target": true, className: cn('bg-background/80 pointer-events-auto relative w-full
|
|
449
|
-
? 'bg-background'
|
|
450
|
-
: 'bg-background/80 supports-[backdrop-filter]:backdrop-blur-xl',
|
|
451
|
-
|
|
452
|
-
|
|
452
|
+
}, transition: { type: 'tween', duration: 0.25, ease: 'easeOut' }, className: cn('pointer-events-none fixed bottom-6 left-[calc(50%+var(--sidebar-width,0px)/2)] z-50 flex -translate-x-1/2 justify-center', isMinimized && 'pointer-events-none', className), children: _jsxs("div", { "data-chat-drop-target": true, className: cn('bg-background/80 pointer-events-auto relative isolate w-full transition-[background-color,border-radius,box-shadow] duration-200 ease-out', isExpanded
|
|
453
|
+
? 'bg-background rounded-[28px] shadow-[0_8px_40px_-12px_rgba(0,0,0,0.15)]'
|
|
454
|
+
: 'bg-background/80 rounded-[36px] supports-[backdrop-filter]:backdrop-blur-xl', isExpanded ? 'overflow-hidden' : 'overflow-visible'), children: [_jsx(motion.div, { initial: false, animate: { opacity: isExpanded ? 0 : 1 }, transition: {
|
|
455
|
+
duration: isExpanded ? 0.08 : 0.12,
|
|
456
|
+
delay: isExpanded ? 0 : 0.18,
|
|
457
|
+
ease: 'easeOut',
|
|
458
|
+
}, className: "pointer-events-none absolute inset-0 z-0 rounded-[inherit]", style: {
|
|
459
|
+
background: 'linear-gradient(135deg, color-mix(in oklch, var(--foreground) 9%, transparent) 0%, color-mix(in oklch, var(--foreground) 2%, transparent) 42%, transparent 58%)',
|
|
460
|
+
} }), isImageDropActive && (_jsxs("div", { className: "bg-background/90 border-primary/50 text-foreground absolute inset-0 z-[70] flex flex-col items-center justify-center gap-2 rounded-[inherit] border-2 border-dashed backdrop-blur-sm", children: [_jsx(ImageIcon, { className: "text-primary size-7" }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-ui-body font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-ui-caption", children: "They stay on disk and are read when sent" })] })] })), _jsx("div", { className: "pointer-events-none absolute inset-0 z-[49] rounded-[inherit]", style: {
|
|
461
|
+
padding: '1px',
|
|
462
|
+
background: 'linear-gradient(135deg, color-mix(in oklch, var(--foreground) 20%, transparent), color-mix(in oklch, var(--border) 65%, transparent) 48%, color-mix(in oklch, var(--foreground) 12%, transparent))',
|
|
463
|
+
mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
|
|
464
|
+
WebkitMask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
|
|
465
|
+
maskComposite: 'exclude',
|
|
466
|
+
WebkitMaskComposite: 'xor',
|
|
467
|
+
} }), _jsx(motion.div, { "data-moldable-chat-edge-treatment": true, initial: false, animate: { opacity: isExpanded ? 0 : 1 }, transition: {
|
|
468
|
+
duration: isExpanded ? 0.08 : 0.12,
|
|
469
|
+
delay: isExpanded ? 0 : 0.18,
|
|
470
|
+
ease: 'easeOut',
|
|
471
|
+
}, className: "pointer-events-none absolute inset-0 z-50 rounded-[inherit]", style: {
|
|
453
472
|
padding: '1px',
|
|
454
|
-
background: '
|
|
473
|
+
background: 'conic-gradient(from 205deg at 50% 50%, color-mix(in oklch, var(--foreground) 16%, transparent) 0deg, color-mix(in oklch, var(--border) 72%, transparent) 72deg, color-mix(in oklch, var(--primary) 18%, transparent) 148deg, color-mix(in oklch, var(--foreground) 30%, transparent) 226deg, color-mix(in oklch, var(--border) 68%, transparent) 304deg, color-mix(in oklch, var(--foreground) 16%, transparent) 360deg)',
|
|
455
474
|
mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
|
|
456
475
|
WebkitMask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',
|
|
457
476
|
maskComposite: 'exclude',
|
|
458
477
|
WebkitMaskComposite: 'xor',
|
|
459
|
-
} }),
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
},
|
|
466
|
-
duration: 4,
|
|
467
|
-
repeat: Infinity,
|
|
468
|
-
repeatDelay: 5,
|
|
469
|
-
ease: [0.4, 0, 0.2, 1],
|
|
470
|
-
} })), _jsxs("div", { className: "relative z-10 overflow-hidden rounded-[inherit]", children: [_jsxs(motion.div, { initial: false, animate: {
|
|
478
|
+
} }), _jsx(motion.div, { "data-moldable-chat-edge-depth": true, initial: false, animate: { opacity: isExpanded ? 0 : 1 }, transition: {
|
|
479
|
+
duration: isExpanded ? 0.08 : 0.12,
|
|
480
|
+
delay: isExpanded ? 0 : 0.18,
|
|
481
|
+
ease: 'easeOut',
|
|
482
|
+
}, className: "pointer-events-none absolute inset-0 z-40 rounded-[inherit]", style: {
|
|
483
|
+
boxShadow: 'inset 0 1px 0 color-mix(in oklch, var(--foreground) 9%, transparent), inset 0 -1px 0 color-mix(in oklch, var(--background) 72%, transparent), 0 16px 38px -26px color-mix(in oklch, var(--foreground) 52%, transparent), 0 0 24px -17px color-mix(in oklch, var(--primary) 42%, transparent)',
|
|
484
|
+
} }), _jsxs("div", { className: "relative z-10 overflow-hidden rounded-[inherit]", children: [_jsxs(motion.div, { initial: false, animate: {
|
|
471
485
|
height: isExpanded ? 'min(60vh, 480px)' : '0px',
|
|
472
486
|
opacity: isExpanded ? 1 : 0,
|
|
473
|
-
}, transition: { type: 'tween', duration: 0.2, ease: 'easeOut' }, className: "flex flex-col overflow-hidden", style: { pointerEvents: isExpanded ? 'auto' : 'none' }, children: [isExpanded && !isMinimized && (_jsxs("div", { className: "absolute right-
|
|
487
|
+
}, transition: { type: 'tween', duration: 0.2, ease: 'easeOut' }, className: "flex flex-col overflow-hidden", style: { pointerEvents: isExpanded ? 'auto' : 'none' }, children: [isExpanded && !isMinimized && (_jsxs("div", { className: "absolute right-4 top-3 z-20 grid grid-cols-1 gap-1", "data-moldable-chat-panel-controls": true, role: "toolbar", "aria-label": "Chat view controls", "aria-orientation": "vertical", children: [onFullScreenChange && (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { ref: fullScreenTriggerRef, "data-moldable-chat-enter-fullscreen": true, variant: "ghost", size: "icon-xl", onClick: () => onFullScreenChange(true), "aria-label": "Enter full screen", className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(Maximize2, { className: "size-5" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Full screen" })] }) })), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-xl", onClick: handleMinimize, className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(ChevronDown, { className: "size-5" }) }) }), _jsx(TooltipContent, { side: "bottom", children: _jsx("p", { children: "Minimize" }) })] }) })] })), _jsx(ChatMessageViewport, { items: listItems, renderItem: renderVirtualItem, toolProgress: toolProgress, onApprovalResponse: onApprovalResponse, currentConversationId: currentConversationId, scrollToBottomSignal: scrollToBottomSignal, isBusy: isResponding, hasOlderMessages: hasOlderMessages, isLoadingOlderMessages: isLoadingOlderMessages, onLoadOlderMessages: onLoadOlderMessages, scrollAreaClassName: "px-2", contentClassName: "w-full min-w-0 max-w-full overflow-hidden py-4 pr-12", scrollButtonClassName: "absolute bottom-3 left-auto right-4 z-20 size-8 translate-x-0 cursor-pointer rounded-pill shadow-lg" }), authPromptCopy && (_jsx("div", { className: "shrink-0 px-4 pb-2", children: _jsx(ChatAuthPrompt, { copy: authPromptCopy, isConnecting: isConnectingChatGPT, onConnect: onConnectChatGPT ? handleConnectChatGPT : undefined, onAdvancedSetup: onAdvancedSetup }) }))] }), _jsxs("div", { className: "relative z-10", onClick: () => {
|
|
474
488
|
if (!isExpanded) {
|
|
475
489
|
onExpandedChange(true);
|
|
476
490
|
}
|
|
477
|
-
}, children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border/70 bg-background/95 border-t px-4 py-2", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, compact: !isExpanded, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: isExpanded ? composerStartControls : null, footerControls: isExpanded ? composerControls : null, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect })] })] })] }) })] }));
|
|
491
|
+
}, children: [queuedMessages.length > 0 && (_jsxs("div", { className: "border-border/70 bg-background/95 border-t px-4 py-2", children: [_jsxs("div", { className: "text-muted-foreground text-ui-caption mb-2 flex items-center gap-2 font-medium", children: [_jsx(ListPlus, { className: "size-3.5" }), _jsx("span", { children: "Queued follow-ups" })] }), _jsx(DndContext, { sensors: queueSensors, collisionDetection: closestCenter, onDragEnd: handleQueuedDragEnd, children: _jsx(SortableContext, { items: queuedMessageIds, strategy: verticalListSortingStrategy, children: _jsx("div", { className: "space-y-1.5", children: queuedMessages.map((message) => (_jsx(QueuedMessageRow, { message: message, isResponding: isResponding, onRetryQueuedMessage: onRetryQueuedMessage, onSteerQueuedMessage: onSteerQueuedMessage, onRemoveQueuedMessage: onRemoveQueuedMessage, onEditQueuedMessage: handleEditQueuedMessage }, message.id))) }) }) })] })), _jsx(ChatInput, { input: input, onInputChange: onInputChange, onSubmit: handleSubmit, isResponding: isResponding, placeholder: placeholder, inputRef: inputRef, onStop: onStop, compact: !isExpanded, surfaceBorderRadius: isExpanded ? 24 : undefined, imageAttachments: imageAttachments, onRemoveImageAttachment: onRemoveImageAttachment, footerStartControls: isExpanded ? composerStartControls : null, footerControls: isExpanded ? composerControls : null, submitDisabled: submitDisabled, slashCommands: slashCommands, onSlashCommandSelect: onSlashCommandSelect })] })] })] }) })] }));
|
|
478
492
|
}
|
|
@@ -26,6 +26,8 @@ interface ConversationListProps {
|
|
|
26
26
|
conversations: ConversationMeta[];
|
|
27
27
|
currentConversationId?: string | null;
|
|
28
28
|
currentAppId?: string | null;
|
|
29
|
+
/** Opts into app/scope disclosure groups for unified conversation surfaces. */
|
|
30
|
+
groupByScope?: boolean;
|
|
29
31
|
onSelect: (id: string) => void;
|
|
30
32
|
onArchive?: (id: string) => void;
|
|
31
33
|
onArchiveGroup?: (group: ConversationGroup) => void;
|
|
@@ -51,7 +53,7 @@ interface ConversationSidebarProps extends ConversationListProps {
|
|
|
51
53
|
onLoadMoreConversations?: () => void | Promise<unknown>;
|
|
52
54
|
}
|
|
53
55
|
export declare function groupConversations(conversations: ConversationMeta[], currentAppId?: string | null): ConversationGroup[];
|
|
54
|
-
export declare function ConversationSidebar({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, hideScrollbar, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, disabled, className, }: ConversationSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
55
|
-
export declare function ConversationHistory({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, disabled, className, dropdownAlign, dropdownSide, tooltipSide, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, }: ConversationHistoryProps): import("react/jsx-runtime").JSX.Element | null;
|
|
56
|
+
export declare function ConversationSidebar({ conversations, currentConversationId, currentAppId, groupByScope, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, hideScrollbar, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, disabled, className, }: ConversationSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
57
|
+
export declare function ConversationHistory({ conversations, currentConversationId, currentAppId, groupByScope, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, disabled, className, dropdownAlign, dropdownSide, tooltipSide, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, }: ConversationHistoryProps): import("react/jsx-runtime").JSX.Element | null;
|
|
56
58
|
export {};
|
|
57
59
|
//# sourceMappingURL=conversation-history.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-history.d.ts","sourceRoot":"","sources":["../../../src/components/chat/conversation-history.tsx"],"names":[],"mappings":"AAiCA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,aAAa,EAAE,gBAAgB,EAAE,CAAA;CAClC;AAOD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAIR;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GACnB,IAAI,IAAI,MAAM,CAIhB;AAED,UAAU,qBAAqB;IAC7B,aAAa,EAAE,gBAAgB,EAAE,CAAA;IACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAC1C,YAAY,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClD,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,gBAAgB,EAAE,EACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAC3B,iBAAiB,EAAE,CA8CrB;
|
|
1
|
+
{"version":3,"file":"conversation-history.d.ts","sourceRoot":"","sources":["../../../src/components/chat/conversation-history.tsx"],"names":[],"mappings":"AAiCA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,aAAa,EAAE,gBAAgB,EAAE,CAAA;CAClC;AAOD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAIR;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GACnB,IAAI,IAAI,MAAM,CAIhB;AAED,UAAU,qBAAqB;IAC7B,aAAa,EAAE,gBAAgB,EAAE,CAAA;IACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAC1C,YAAY,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClD,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,gBAAgB,EAAE,EACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAC3B,iBAAiB,EAAE,CA8CrB;AAqPD,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,YAAoB,EACpB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAuB,EACvB,aAAqB,EACrB,oBAA4B,EAC5B,0BAAkC,EAClC,uBAAuB,EACvB,QAAgB,EAChB,SAAS,GACV,EAAE,wBAAwB,2CAwH1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,YAAoB,EACpB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAuB,EACvB,QAAgB,EAChB,SAAS,EACT,aAAuB,EACvB,YAAuB,EACvB,WAAsB,EACtB,oBAA4B,EAC5B,0BAAkC,EAClC,uBAAuB,GACxB,EAAE,wBAAwB,kDAmG1B"}
|
|
@@ -69,18 +69,28 @@ function AppScopeIcon({ icon, isChats, }) {
|
|
|
69
69
|
if (isChats)
|
|
70
70
|
return _jsx(MessageCircle, { className: "size-4" });
|
|
71
71
|
if (isConversationIconImageSource(icon)) {
|
|
72
|
-
return
|
|
72
|
+
return _jsx("img", { src: icon, alt: "", className: "size-4 rounded object-cover" });
|
|
73
73
|
}
|
|
74
74
|
if (icon)
|
|
75
|
-
return _jsx("span", { className: "text-
|
|
75
|
+
return _jsx("span", { className: "text-sm leading-none", children: icon });
|
|
76
76
|
return _jsx(Folder, { className: "size-4" });
|
|
77
77
|
}
|
|
78
|
-
function
|
|
78
|
+
function ConversationRows({ conversations, currentConversationId, onSelect, onArchive, disabled, }) {
|
|
79
|
+
return conversations.map((conversation) => (_jsxs("li", { "data-conversation-id": conversation.id, className: cn('group/conversation relative flex min-w-0 items-center rounded-lg', conversation.id === currentConversationId && 'bg-accent'), children: [_jsx("button", { type: "button", disabled: disabled, onClick: () => onSelect(conversation.id), "aria-current": conversation.id === currentConversationId ? 'page' : undefined, className: "min-w-0 flex-1 cursor-pointer truncate rounded-lg py-1.5 pl-3 pr-8 text-left text-sm disabled:cursor-default", children: conversation.title }), conversation.isActive && (_jsx(LoaderCircle, { className: "text-muted-foreground absolute right-2 size-3.5 animate-spin", "aria-label": "Conversation is working" })), onArchive && !conversation.isActive && (_jsx("button", { type: "button", onClick: (event) => {
|
|
80
|
+
event.stopPropagation();
|
|
81
|
+
onArchive(conversation.id);
|
|
82
|
+
}, disabled: disabled, className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute right-1 flex size-7 cursor-pointer items-center justify-center rounded-md opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 disabled:cursor-default group-focus-within/conversation:opacity-100 group-hover/conversation:opacity-100", "aria-label": `Archive ${conversation.title}`, children: _jsx(Archive, { className: "size-3.5" }) }))] }, conversation.id)));
|
|
83
|
+
}
|
|
84
|
+
function ConversationList({ conversations, currentConversationId, currentAppId, groupByScope = false, onSelect, onArchive, onArchiveGroup, disabled = false, className, }) {
|
|
79
85
|
const groups = useMemo(() => groupConversations(conversations, currentAppId), [conversations, currentAppId]);
|
|
80
86
|
const [collapsedGroups, setCollapsedGroups] = useState(() => new Set());
|
|
81
87
|
const [expandedGroups, setExpandedGroups] = useState(() => new Set());
|
|
82
88
|
const [groupPendingArchive, setGroupPendingArchive] = useState(null);
|
|
83
89
|
const listIdPrefix = useId();
|
|
90
|
+
const flatConversations = useMemo(() => [...conversations].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)), [conversations]);
|
|
91
|
+
if (!groupByScope) {
|
|
92
|
+
return (_jsx("nav", { "aria-label": "Conversations", className: className, children: _jsx("ul", { className: "space-y-0.5", children: _jsx(ConversationRows, { conversations: flatConversations, currentConversationId: currentConversationId, onSelect: onSelect, onArchive: onArchive, disabled: disabled }) }) }));
|
|
93
|
+
}
|
|
84
94
|
return (_jsxs("nav", { "aria-label": "Conversations", className: cn('space-y-1', className), children: [groups.map((group) => {
|
|
85
95
|
const isCollapsed = collapsedGroups.has(group.id);
|
|
86
96
|
const isShowingAll = expandedGroups.has(group.id);
|
|
@@ -96,19 +106,14 @@ function ConversationList({ conversations, currentConversationId, currentAppId,
|
|
|
96
106
|
else
|
|
97
107
|
next.add(group.id);
|
|
98
108
|
return next;
|
|
99
|
-
}), className: "text-foreground hover:bg-accent/60
|
|
100
|
-
? 'page'
|
|
101
|
-
: undefined, className: "rounded-container text-ui-body min-w-0 flex-1 cursor-pointer truncate py-1.5 pl-3 pr-8 text-left disabled:cursor-default", children: conversation.title }), conversation.isActive && (_jsx(LoaderCircle, { className: "text-muted-foreground absolute right-2 size-3.5 animate-spin", "aria-label": "Conversation is working" })), onArchive && !conversation.isActive && (_jsx("button", { type: "button", onClick: (event) => {
|
|
102
|
-
event.stopPropagation();
|
|
103
|
-
onArchive(conversation.id);
|
|
104
|
-
}, disabled: disabled, className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring rounded-control absolute right-1 flex size-7 cursor-pointer items-center justify-center opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 disabled:cursor-default group-focus-within/conversation:opacity-100 group-hover/conversation:opacity-100", "aria-label": `Archive ${conversation.title}`, children: _jsx(Archive, { className: "size-3.5" }) }))] }, conversation.id))), hasMoreConversations && (_jsx("li", { children: _jsx("button", { type: "button", onClick: () => setExpandedGroups((current) => {
|
|
109
|
+
}), className: "text-foreground hover:bg-accent/60 flex h-9 min-w-0 flex-1 cursor-pointer items-center gap-2 rounded-lg px-2 pr-9 text-left text-sm font-medium transition-colors", children: [_jsx(ChevronDown, { className: cn('text-muted-foreground size-3.5 shrink-0 transition-transform', isCollapsed && '-rotate-90') }), _jsx("span", { className: "text-muted-foreground flex size-4 shrink-0 items-center justify-center", children: _jsx(AppScopeIcon, { icon: group.icon, isChats: group.id === CHATS_GROUP_ID }) }), _jsx("span", { className: "truncate", children: group.label })] }), onArchiveGroup && (_jsx("button", { type: "button", onClick: () => setGroupPendingArchive(group), className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute right-1 flex size-7 cursor-pointer items-center justify-center rounded-md opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 group-focus-within/conversation-scope:opacity-100 group-hover/conversation-scope:opacity-100", "aria-label": `Archive all chats in ${group.label}`, children: _jsx(Archive, { className: "size-3.5" }) }))] }), !isCollapsed && (_jsxs("ul", { id: listId, className: "ml-5 space-y-0.5 py-0.5", children: [_jsx(ConversationRows, { conversations: visibleConversations, currentConversationId: currentConversationId, onSelect: onSelect, onArchive: onArchive, disabled: disabled }), hasMoreConversations && (_jsx("li", { children: _jsx("button", { type: "button", onClick: () => setExpandedGroups((current) => {
|
|
105
110
|
const next = new Set(current);
|
|
106
111
|
if (next.has(group.id))
|
|
107
112
|
next.delete(group.id);
|
|
108
113
|
else
|
|
109
114
|
next.add(group.id);
|
|
110
115
|
return next;
|
|
111
|
-
}), className: "text-muted-foreground hover:bg-accent/60 hover:text-foreground
|
|
116
|
+
}), className: "text-muted-foreground hover:bg-accent/60 hover:text-foreground flex h-7 w-full cursor-pointer items-center rounded-lg px-3 text-left text-xs transition-colors", "aria-label": `${isShowingAll ? 'Show fewer' : 'Show all'} ${group.label} conversations`, children: isShowingAll ? 'Show less' : 'Show all' }) }))] }))] }, group.id));
|
|
112
117
|
}), _jsx(AlertDialog, { open: groupPendingArchive !== null, onOpenChange: (open) => {
|
|
113
118
|
if (!open)
|
|
114
119
|
setGroupPendingArchive(null);
|
|
@@ -119,7 +124,7 @@ function ConversationList({ conversations, currentConversationId, currentAppId,
|
|
|
119
124
|
setGroupPendingArchive(null);
|
|
120
125
|
}, children: "Archive all" })] })] }) })] }));
|
|
121
126
|
}
|
|
122
|
-
export function ConversationSidebar({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled = false, hideScrollbar = false, hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, disabled = false, className, }) {
|
|
127
|
+
export function ConversationSidebar({ conversations, currentConversationId, currentAppId, groupByScope = false, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled = false, hideScrollbar = false, hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, disabled = false, className, }) {
|
|
123
128
|
const scrollContainerRef = useRef(null);
|
|
124
129
|
const [scrollFadeEdges, setScrollFadeEdges] = useState({
|
|
125
130
|
top: false,
|
|
@@ -172,16 +177,16 @@ export function ConversationSidebar({ conversations, currentConversationId, curr
|
|
|
172
177
|
'[scrollbar-width:none] [&::-webkit-scrollbar]:hidden'), "data-conversation-scroll-fade": true, "data-scroll-fade-top": scrollFadeEdges.top || undefined, "data-scroll-fade-bottom": scrollFadeEdges.bottom || undefined, onScroll: (event) => handleScroll(event.currentTarget), style: {
|
|
173
178
|
maskImage: scrollMask,
|
|
174
179
|
WebkitMaskImage: scrollMask,
|
|
175
|
-
}, children: [_jsx(ConversationList, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: onSelect, onArchive: onArchive, onArchiveGroup: hasMoreConversations ? undefined : onArchiveGroup, disabled: disabled }), hasMoreConversations && (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isLoadingMoreConversations, onClick: () => void onLoadMoreConversations?.(), className: "text-muted-foreground mt-1 w-full cursor-pointer", children: [isLoadingMoreConversations && (_jsx(LoaderCircle, { className: "size-3.5 animate-spin" })), "Load older conversations"] }))] })] }));
|
|
180
|
+
}, children: [_jsx(ConversationList, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, groupByScope: groupByScope, onSelect: onSelect, onArchive: onArchive, onArchiveGroup: hasMoreConversations ? undefined : onArchiveGroup, disabled: disabled }), hasMoreConversations && (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isLoadingMoreConversations, onClick: () => void onLoadMoreConversations?.(), className: "text-muted-foreground mt-1 w-full cursor-pointer", children: [isLoadingMoreConversations && (_jsx(LoaderCircle, { className: "size-3.5 animate-spin" })), "Load older conversations"] }))] })] }));
|
|
176
181
|
}
|
|
177
|
-
export function ConversationHistory({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled = false, disabled = false, className, dropdownAlign = 'start', dropdownSide = 'bottom', tooltipSide = 'bottom', hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, }) {
|
|
182
|
+
export function ConversationHistory({ conversations, currentConversationId, currentAppId, groupByScope = false, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled = false, disabled = false, className, dropdownAlign = 'start', dropdownSide = 'bottom', tooltipSide = 'bottom', hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, }) {
|
|
178
183
|
const [isOpen, setIsOpen] = useState(false);
|
|
179
184
|
if (conversations.length === 0 && !onNewChat)
|
|
180
185
|
return null;
|
|
181
186
|
return (_jsx(TooltipProvider, { children: _jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", disabled: disabled, className: cn('text-muted-foreground hover:text-foreground cursor-pointer', className), "aria-label": "Conversations", children: _jsx(MessageCircle, { className: "size-4" }) }) }) }), _jsx(TooltipContent, { side: tooltipSide, children: "Conversations" })] }), _jsxs(PopoverContent, { align: dropdownAlign, side: dropdownSide, className: "w-72 p-2", children: [onNewChat && (_jsxs(Button, { type: "button", variant: "ghost", onClick: () => {
|
|
182
187
|
onNewChat();
|
|
183
188
|
setIsOpen(false);
|
|
184
|
-
}, disabled: newChatDisabled, title: "New conversation (Cmd+Shift+O)", className: "mb-1 flex w-full cursor-pointer items-center justify-start gap-2", children: [_jsx(Plus, { className: "size-4" }), _jsx("span", { children: "New conversation" }), _jsx("span", { className: "text-muted-foreground
|
|
189
|
+
}, disabled: newChatDisabled, title: "New conversation (Cmd+Shift+O)", className: "mb-1 flex w-full cursor-pointer items-center justify-start gap-2 rounded-lg text-sm [&_[data-slot=button-content]]:w-full", children: [_jsx(Plus, { className: "size-4" }), _jsx("span", { children: "New conversation" }), _jsx("span", { className: "text-muted-foreground ml-auto text-xs", children: "\u2318\u21E7O" })] })), _jsxs("div", { className: "max-h-80 overflow-y-auto", onScroll: (event) => {
|
|
185
190
|
const element = event.currentTarget;
|
|
186
191
|
if (hasMoreConversations &&
|
|
187
192
|
!isLoadingMoreConversations &&
|
|
@@ -191,7 +196,7 @@ export function ConversationHistory({ conversations, currentConversationId, curr
|
|
|
191
196
|
120) {
|
|
192
197
|
void onLoadMoreConversations?.();
|
|
193
198
|
}
|
|
194
|
-
}, children: [_jsx(ConversationList, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: (id) => {
|
|
199
|
+
}, children: [_jsx(ConversationList, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, groupByScope: groupByScope, onSelect: (id) => {
|
|
195
200
|
onSelect(id);
|
|
196
201
|
setIsOpen(false);
|
|
197
202
|
}, onArchive: onArchive, onArchiveGroup: hasMoreConversations ? undefined : onArchiveGroup, disabled: disabled }), hasMoreConversations && (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isLoadingMoreConversations, onClick: () => void onLoadMoreConversations?.(), className: "text-muted-foreground mt-1 w-full cursor-pointer", children: [isLoadingMoreConversations && (_jsx(LoaderCircle, { className: "size-3.5 animate-spin" })), "Load older conversations"] }))] })] })] }) }));
|
|
@@ -3,7 +3,7 @@ import { type IconButtonProps } from './icon-button.js';
|
|
|
3
3
|
import { type VariantProps } from 'class-variance-authority';
|
|
4
4
|
declare const alertVariants: (props?: ({
|
|
5
5
|
tone?: "neutral" | "info" | "success" | "warning" | "danger" | null | undefined;
|
|
6
|
-
density?: "
|
|
6
|
+
density?: "default" | "compact" | null | undefined;
|
|
7
7
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
8
|
type AlertTone = NonNullable<VariantProps<typeof alertVariants>['tone']>;
|
|
9
9
|
type AlertDensity = NonNullable<VariantProps<typeof alertVariants>['density']>;
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { MaterialVariant } from './material.js';
|
|
3
3
|
export type AppFrameMode = 'auto' | 'embedded' | 'window';
|
|
4
|
+
export interface AppFrameNativeMaterial {
|
|
5
|
+
/**
|
|
6
|
+
* Reveal the host-rendered frosted window background while keeping the
|
|
7
|
+
* portable canvas fill as the fallback.
|
|
8
|
+
*/
|
|
9
|
+
background?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Allow a compatible leading `Sidebar` to request host-rendered native
|
|
12
|
+
* material when the app manifest and host both advertise support.
|
|
13
|
+
*/
|
|
14
|
+
sidebar?: boolean;
|
|
15
|
+
}
|
|
4
16
|
declare function resolveAppFrameMode(mode: AppFrameMode): Exclude<AppFrameMode, 'auto'>;
|
|
5
17
|
export interface AppFrameProps extends React.ComponentProps<'div'> {
|
|
6
18
|
/**
|
|
@@ -8,14 +20,21 @@ export interface AppFrameProps extends React.ComponentProps<'div'> {
|
|
|
8
20
|
* in catalogs, previews, and tests where the runtime environment is ambiguous.
|
|
9
21
|
*/
|
|
10
22
|
mode?: AppFrameMode;
|
|
23
|
+
/**
|
|
24
|
+
* Explicitly opts this app frame into renderer-owned native material
|
|
25
|
+
* regions. The matching region must also be enabled in `moldable.json`.
|
|
26
|
+
*/
|
|
27
|
+
nativeMaterial?: AppFrameNativeMaterial;
|
|
11
28
|
}
|
|
12
29
|
interface AppFrameRuntimeContextValue {
|
|
13
30
|
mode: Exclude<AppFrameMode, 'auto'>;
|
|
31
|
+
backgroundMaterialActive: boolean;
|
|
14
32
|
sidebarMaterialAvailable: boolean;
|
|
33
|
+
sidebarMaterialEnabled: boolean;
|
|
15
34
|
sidebarMaterialRegionId: string | null;
|
|
16
35
|
}
|
|
17
36
|
export declare function useAppFrameRuntime(): AppFrameRuntimeContextValue | null;
|
|
18
|
-
declare function AppFrame({ mode, className, style, ...props }: AppFrameProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
declare function AppFrame({ mode, nativeMaterial, className, style, ...props }: AppFrameProps): import("react/jsx-runtime").JSX.Element;
|
|
19
38
|
export interface AppFrameTitlebarProps extends React.ComponentPropsWithoutRef<'header'> {
|
|
20
39
|
material?: MaterialVariant | 'none';
|
|
21
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-frame.d.ts","sourceRoot":"","sources":["../../../src/components/ui/app-frame.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAMjD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEzD,iBAAS,mBAAmB,CAC1B,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAM/B;AAED,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IAChE;;;OAGG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"app-frame.d.ts","sourceRoot":"","sources":["../../../src/components/ui/app-frame.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAMjD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEzD,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,iBAAS,mBAAmB,CAC1B,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAM/B;AAED,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IAChE;;;OAGG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB;;;OAGG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAA;CACxC;AAED,UAAU,2BAA2B;IACnC,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;IACnC,wBAAwB,EAAE,OAAO,CAAA;IACjC,wBAAwB,EAAE,OAAO,CAAA;IACjC,sBAAsB,EAAE,OAAO,CAAA;IAC/B,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAA;CACvC;AAKD,wBAAgB,kBAAkB,IAAI,2BAA2B,GAAG,IAAI,CAEvE;AA8BD,iBAAS,QAAQ,CAAC,EAChB,IAAa,EACb,cAAc,EACd,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,aAAa,2CAuGf;AAED,MAAM,WAAW,qBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC;IAChD,QAAQ,CAAC,EAAE,eAAe,GAAG,MAAM,CAAA;CACpC;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAoB,EACpB,aAAa,EACb,WAAW,EACX,KAAK,EACL,GAAG,KAAK,EACT,EAAE,qBAAqB,2CA+BvB;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,2CAWvC;AAED,MAAM,WAAW,oBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,MAAM,CAAC;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,iBAAS,eAAe,CAAC,EACvB,UAAiB,EACjB,QAAe,EACf,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,oBAAoB,2CAoBtB;AAED,MAAM,WAAW,sBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC;IAChD,QAAQ,CAAC,EAAE,eAAe,GAAG,MAAM,CAAA;CACpC;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,QAAoB,EACpB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,sBAAsB,2CAmBxB;AAED,OAAO,EACL,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,GACpB,CAAA"}
|
|
@@ -30,13 +30,20 @@ function sidebarMaterialAvailable() {
|
|
|
30
30
|
document.documentElement.dataset.moldableNativeMaterialSidebar ===
|
|
31
31
|
'available');
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function backgroundMaterialAvailable() {
|
|
34
|
+
return (typeof document !== 'undefined' &&
|
|
35
|
+
document.documentElement.dataset.moldableNativeMaterialBackground ===
|
|
36
|
+
'available');
|
|
37
|
+
}
|
|
38
|
+
function AppFrame({ mode = 'auto', nativeMaterial, className, style, ...props }) {
|
|
34
39
|
const [resolvedMode, setResolvedMode] = React.useState(() => resolveAppFrameMode(mode));
|
|
35
40
|
const [sidebarMaterialRegionId, setSidebarMaterialRegionId] = React.useState(activeSidebarMaterialRegionId);
|
|
36
41
|
const [nativeSidebarMaterialAvailable, setNativeSidebarMaterialAvailable] = React.useState(sidebarMaterialAvailable);
|
|
42
|
+
const [nativeBackgroundMaterialAvailable, setNativeBackgroundMaterialAvailable,] = React.useState(backgroundMaterialAvailable);
|
|
37
43
|
React.useEffect(() => {
|
|
38
44
|
const updateHostState = () => {
|
|
39
45
|
setResolvedMode(resolveAppFrameMode(mode));
|
|
46
|
+
setNativeBackgroundMaterialAvailable(backgroundMaterialAvailable());
|
|
40
47
|
setNativeSidebarMaterialAvailable(sidebarMaterialAvailable());
|
|
41
48
|
setSidebarMaterialRegionId(activeSidebarMaterialRegionId());
|
|
42
49
|
};
|
|
@@ -50,19 +57,42 @@ function AppFrame({ mode = 'auto', className, style, ...props }) {
|
|
|
50
57
|
};
|
|
51
58
|
}, [mode]);
|
|
52
59
|
const sidebarMaterialActive = resolvedMode === 'window' && sidebarMaterialRegionId !== null;
|
|
60
|
+
const backgroundMaterialActive = resolvedMode === 'window' &&
|
|
61
|
+
nativeMaterial?.background === true &&
|
|
62
|
+
nativeBackgroundMaterialAvailable;
|
|
63
|
+
React.useEffect(() => {
|
|
64
|
+
if (!backgroundMaterialActive)
|
|
65
|
+
return;
|
|
66
|
+
const previousBackgroundColor = document.body.style.backgroundColor;
|
|
67
|
+
document.body.style.backgroundColor = 'transparent';
|
|
68
|
+
return () => {
|
|
69
|
+
if (previousBackgroundColor) {
|
|
70
|
+
document.body.style.backgroundColor = previousBackgroundColor;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
document.body.style.removeProperty('background-color');
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}, [backgroundMaterialActive]);
|
|
53
77
|
return (_jsx(AppFrameRuntimeContext.Provider, { value: {
|
|
54
78
|
mode: resolvedMode,
|
|
79
|
+
backgroundMaterialActive,
|
|
55
80
|
sidebarMaterialAvailable: nativeSidebarMaterialAvailable,
|
|
81
|
+
sidebarMaterialEnabled: nativeMaterial?.sidebar === true,
|
|
56
82
|
sidebarMaterialRegionId,
|
|
57
|
-
}, children: _jsx("div", { "data-slot": "app-frame", "data-mode": resolvedMode, "data-native-material-sidebar": sidebarMaterialActive ? 'active' : undefined, className: cn('text-foreground flex h-dvh min-h-0 min-w-0 flex-col overflow-hidden
|
|
83
|
+
}, children: _jsx("div", { "data-slot": "app-frame", "data-mode": resolvedMode, "data-native-material-background": backgroundMaterialActive ? 'active' : undefined, "data-native-material-sidebar": sidebarMaterialActive ? 'active' : undefined, "data-native-material-sidebar-enabled": nativeMaterial?.sidebar === true ? 'true' : undefined, className: cn('text-foreground flex h-dvh min-h-0 min-w-0 flex-col overflow-hidden', backgroundMaterialActive
|
|
84
|
+
? 'bg-transparent'
|
|
85
|
+
: 'bg-[var(--surface-canvas,var(--background))]', className), style: {
|
|
58
86
|
paddingInlineStart: 'var(--window-safe-area-inline-start, 0px)',
|
|
59
87
|
paddingInlineEnd: 'var(--window-safe-area-inline-end, 0px)',
|
|
60
88
|
...style,
|
|
61
|
-
...(
|
|
62
|
-
? {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
89
|
+
...(backgroundMaterialActive
|
|
90
|
+
? { background: 'transparent' }
|
|
91
|
+
: sidebarMaterialActive
|
|
92
|
+
? {
|
|
93
|
+
background: 'linear-gradient(to right, transparent 0 var(--moldable-material-region-sidebar-width), var(--surface-canvas, var(--background)) var(--moldable-material-region-sidebar-width) 100%)',
|
|
94
|
+
}
|
|
95
|
+
: {}),
|
|
66
96
|
}, ...props }) }));
|
|
67
97
|
}
|
|
68
98
|
function AppFrameTitlebar({ className, material = 'regular', onDoubleClick, onMouseDown, style, ...props }) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
3
|
declare const badgeVariants: (props?: ({
|
|
4
|
-
variant?: "
|
|
4
|
+
variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
declare function Badge({ className, variant, asChild, ...props }: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & {
|
|
7
7
|
asChild?: boolean;
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { Slot } from '@radix-ui/react-slot';
|
|
4
4
|
import { cn } from '../../lib/utils.js';
|
|
5
5
|
import { cva } from 'class-variance-authority';
|
|
6
|
-
const badgeVariants = cva('
|
|
6
|
+
const badgeVariants = cva('inline-flex h-[var(--density-badge-height)] w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-pill border border-transparent px-[var(--density-badge-padding-inline)] py-0 text-[length:var(--type-badge-size)] leading-[var(--type-badge-line-height)] font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring aria-invalid:border-destructive [&>svg]:pointer-events-none [&>svg]:size-3', {
|
|
7
7
|
variants: {
|
|
8
8
|
variant: {
|
|
9
9
|
default: 'bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import type { ControlSize } from '../../tokens/contracts.js';
|
|
2
3
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
4
|
declare const buttonVariants: (props?: ({
|
|
4
|
-
variant?: "link" | "toolbar" | "default" | "
|
|
5
|
-
size?: "
|
|
5
|
+
variant?: "link" | "toolbar" | "outline" | "default" | "prominent" | "bordered" | "borderless" | "tinted" | "destructive" | "destructive-tinted" | "secondary" | "ghost" | null | undefined;
|
|
6
|
+
size?: "small" | "sm" | "default" | "lg" | "xs" | "xl" | "mini" | "medium" | "large" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | "icon-xl" | null | undefined;
|
|
6
7
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
8
|
type ButtonProps = React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
|
|
8
9
|
asChild?: boolean;
|
|
10
|
+
controlSize?: ControlSize;
|
|
9
11
|
loading?: boolean;
|
|
10
12
|
};
|
|
11
|
-
declare function Button({ 'aria-busy': ariaBusy, children, className, disabled, loading, onClick, onKeyDown, variant, size, asChild, ...props }: ButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
declare function Button({ 'aria-busy': ariaBusy, children, className, controlSize, disabled, loading, onClick, onKeyDown, variant, size, asChild, ...props }: ButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
12
14
|
export { Button, buttonVariants };
|
|
13
15
|
//# sourceMappingURL=button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEzD,OAAO,EAAE,KAAK,YAAY,EAAO,MAAM,0BAA0B,CAAA;AAEjE,QAAA,MAAM,cAAc;;;8EAwDnB,CAAA;AAED,KAAK,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAC/C,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AA4CH,iBAAS,MAAM,CAAC,EACd,WAAW,EAAE,QAAQ,EACrB,QAAQ,EACR,SAAS,EACT,WAAW,EACX,QAAQ,EACR,OAAe,EACf,OAAO,EACP,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,OAAe,EACf,GAAG,KAAK,EACT,EAAE,WAAW,2CA0Eb;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA"}
|