@moldable-ai/ui 0.2.19 → 0.2.21
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/catalog-coverage.d.ts +15 -0
- package/dist/catalog/catalog-coverage.d.ts.map +1 -0
- package/dist/catalog/catalog-coverage.js +44 -0
- package/dist/catalog/catalog-manifest.d.ts +6 -0
- package/dist/catalog/catalog-manifest.d.ts.map +1 -0
- package/dist/catalog/catalog-manifest.js +117 -0
- package/dist/catalog/catalog-types.d.ts +64 -0
- package/dist/catalog/catalog-types.d.ts.map +1 -0
- package/dist/catalog/catalog-types.js +20 -0
- package/dist/catalog/component-catalog.d.ts +14 -0
- package/dist/catalog/component-catalog.d.ts.map +1 -0
- package/dist/catalog/component-catalog.js +49 -0
- package/dist/catalog/core-catalog-exclusions.d.ts +8 -0
- package/dist/catalog/core-catalog-exclusions.d.ts.map +1 -0
- package/dist/catalog/core-catalog-exclusions.js +151 -0
- package/dist/catalog/core-catalog.d.ts +2 -0
- package/dist/catalog/core-catalog.d.ts.map +1 -0
- package/dist/catalog/core-catalog.js +19 -0
- package/dist/catalog/core-collection-stories.d.ts +3 -0
- package/dist/catalog/core-collection-stories.d.ts.map +1 -0
- package/dist/catalog/core-collection-stories.js +42 -0
- package/dist/catalog/core-control-stories.d.ts +3 -0
- package/dist/catalog/core-control-stories.d.ts.map +1 -0
- package/dist/catalog/core-control-stories.js +94 -0
- package/dist/catalog/core-feedback-stories.d.ts +3 -0
- package/dist/catalog/core-feedback-stories.d.ts.map +1 -0
- package/dist/catalog/core-feedback-stories.js +50 -0
- package/dist/catalog/core-foundation-stories.d.ts +3 -0
- package/dist/catalog/core-foundation-stories.d.ts.map +1 -0
- package/dist/catalog/core-foundation-stories.js +53 -0
- package/dist/catalog/core-navigation-stories.d.ts +3 -0
- package/dist/catalog/core-navigation-stories.d.ts.map +1 -0
- package/dist/catalog/core-navigation-stories.js +25 -0
- package/dist/catalog/core-overlay-stories.d.ts +3 -0
- package/dist/catalog/core-overlay-stories.d.ts.map +1 -0
- package/dist/catalog/core-overlay-stories.js +20 -0
- package/dist/catalog/index.d.ts +7 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +6 -0
- package/dist/components/app-error-boundary.d.ts +1 -0
- package/dist/components/app-error-boundary.d.ts.map +1 -1
- package/dist/components/app-error-boundary.js +13 -0
- package/dist/components/chat/chat-image-lightbox.d.ts +9 -0
- package/dist/components/chat/chat-image-lightbox.d.ts.map +1 -0
- package/dist/components/chat/chat-image-lightbox.js +9 -0
- package/dist/components/chat/chat-message.d.ts +19 -1
- package/dist/components/chat/chat-message.d.ts.map +1 -1
- package/dist/components/chat/chat-message.js +66 -16
- package/dist/components/chat/chat-messages.d.ts +5 -2
- package/dist/components/chat/chat-messages.d.ts.map +1 -1
- package/dist/components/chat/chat-messages.js +61 -6
- package/dist/components/chat/chat-panel.d.ts +49 -6
- package/dist/components/chat/chat-panel.d.ts.map +1 -1
- package/dist/components/chat/chat-panel.js +196 -163
- package/dist/components/chat/conversation-history.d.ts +39 -5
- package/dist/components/chat/conversation-history.d.ts.map +1 -1
- package/dist/components/chat/conversation-history.js +192 -26
- package/dist/components/chat/index.d.ts +2 -2
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/tool-handlers.d.ts.map +1 -1
- package/dist/components/chat/tool-handlers.js +40 -2
- package/dist/components/chat/vertical-scroll-fade.d.ts +6 -0
- package/dist/components/chat/vertical-scroll-fade.d.ts.map +1 -0
- package/dist/components/chat/vertical-scroll-fade.js +12 -0
- package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts +9 -0
- package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts.map +1 -0
- package/dist/components/native-capabilities/bluetooth-panel-helpers.js +37 -0
- package/dist/components/native-capabilities/bluetooth-panel.d.ts +56 -0
- package/dist/components/native-capabilities/bluetooth-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/bluetooth-panel.js +470 -0
- package/dist/components/native-capabilities/camera-preview.d.ts +39 -0
- package/dist/components/native-capabilities/camera-preview.d.ts.map +1 -0
- package/dist/components/native-capabilities/camera-preview.js +228 -0
- package/dist/components/native-capabilities/capability-badge.d.ts +23 -0
- package/dist/components/native-capabilities/capability-badge.d.ts.map +1 -0
- package/dist/components/native-capabilities/capability-badge.js +39 -0
- package/dist/components/native-capabilities/capability-matrix.d.ts +14 -0
- package/dist/components/native-capabilities/capability-matrix.d.ts.map +1 -0
- package/dist/components/native-capabilities/capability-matrix.js +97 -0
- package/dist/components/native-capabilities/clipboard-button.d.ts +26 -0
- package/dist/components/native-capabilities/clipboard-button.d.ts.map +1 -0
- package/dist/components/native-capabilities/clipboard-button.js +99 -0
- package/dist/components/native-capabilities/device-io-controls.d.ts +4 -0
- package/dist/components/native-capabilities/device-io-controls.d.ts.map +1 -0
- package/dist/components/native-capabilities/device-io-controls.js +28 -0
- package/dist/components/native-capabilities/device-list.d.ts +20 -0
- package/dist/components/native-capabilities/device-list.d.ts.map +1 -0
- package/dist/components/native-capabilities/device-list.js +14 -0
- package/dist/components/native-capabilities/display-map.d.ts +23 -0
- package/dist/components/native-capabilities/display-map.d.ts.map +1 -0
- package/dist/components/native-capabilities/display-map.js +114 -0
- package/dist/components/native-capabilities/haptic-button.d.ts +26 -0
- package/dist/components/native-capabilities/haptic-button.d.ts.map +1 -0
- package/dist/components/native-capabilities/haptic-button.js +94 -0
- package/dist/components/native-capabilities/hid-panel.d.ts +40 -0
- package/dist/components/native-capabilities/hid-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/hid-panel.js +373 -0
- package/dist/components/native-capabilities/index.d.ts +27 -0
- package/dist/components/native-capabilities/index.d.ts.map +1 -0
- package/dist/components/native-capabilities/index.js +26 -0
- package/dist/components/native-capabilities/live-indicator.d.ts +15 -0
- package/dist/components/native-capabilities/live-indicator.d.ts.map +1 -0
- package/dist/components/native-capabilities/live-indicator.js +26 -0
- package/dist/components/native-capabilities/local-auth-button.d.ts +33 -0
- package/dist/components/native-capabilities/local-auth-button.d.ts.map +1 -0
- package/dist/components/native-capabilities/local-auth-button.js +115 -0
- package/dist/components/native-capabilities/location-panel.d.ts +29 -0
- package/dist/components/native-capabilities/location-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/location-panel.js +146 -0
- package/dist/components/native-capabilities/microphone-meter.d.ts +35 -0
- package/dist/components/native-capabilities/microphone-meter.d.ts.map +1 -0
- package/dist/components/native-capabilities/microphone-meter.js +244 -0
- package/dist/components/native-capabilities/midi-monitor.d.ts +54 -0
- package/dist/components/native-capabilities/midi-monitor.d.ts.map +1 -0
- package/dist/components/native-capabilities/midi-monitor.js +534 -0
- package/dist/components/native-capabilities/native-capability-panel.d.ts +11 -0
- package/dist/components/native-capabilities/native-capability-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/native-capability-panel.js +28 -0
- package/dist/components/native-capabilities/notification-panel.d.ts +24 -0
- package/dist/components/native-capabilities/notification-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/notification-panel.js +124 -0
- package/dist/components/native-capabilities/power-blocker-controller.d.ts +19 -0
- package/dist/components/native-capabilities/power-blocker-controller.d.ts.map +1 -0
- package/dist/components/native-capabilities/power-blocker-controller.js +83 -0
- package/dist/components/native-capabilities/power-panel.d.ts +67 -0
- package/dist/components/native-capabilities/power-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/power-panel.js +309 -0
- package/dist/components/native-capabilities/readout.d.ts +10 -0
- package/dist/components/native-capabilities/readout.d.ts.map +1 -0
- package/dist/components/native-capabilities/readout.js +11 -0
- package/dist/components/native-capabilities/screen-share-preview.d.ts +36 -0
- package/dist/components/native-capabilities/screen-share-preview.d.ts.map +1 -0
- package/dist/components/native-capabilities/screen-share-preview.js +191 -0
- package/dist/components/native-capabilities/secure-storage-panel.d.ts +36 -0
- package/dist/components/native-capabilities/secure-storage-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/secure-storage-panel.js +193 -0
- package/dist/components/native-capabilities/serial-console.d.ts +64 -0
- package/dist/components/native-capabilities/serial-console.d.ts.map +1 -0
- package/dist/components/native-capabilities/serial-console.js +399 -0
- package/dist/components/native-capabilities/shortcut-recorder.d.ts +35 -0
- package/dist/components/native-capabilities/shortcut-recorder.d.ts.map +1 -0
- package/dist/components/native-capabilities/shortcut-recorder.js +217 -0
- package/dist/components/native-capabilities/stream-log.d.ts +35 -0
- package/dist/components/native-capabilities/stream-log.d.ts.map +1 -0
- package/dist/components/native-capabilities/stream-log.js +65 -0
- package/dist/components/native-capabilities/system-audio-monitor.d.ts +34 -0
- package/dist/components/native-capabilities/system-audio-monitor.d.ts.map +1 -0
- package/dist/components/native-capabilities/system-audio-monitor.js +275 -0
- package/dist/components/native-capabilities/usb-panel.d.ts +54 -0
- package/dist/components/native-capabilities/usb-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/usb-panel.js +363 -0
- package/dist/components/native-capabilities/use-capability.d.ts +20 -0
- package/dist/components/native-capabilities/use-capability.d.ts.map +1 -0
- package/dist/components/native-capabilities/use-capability.js +61 -0
- package/dist/components/ui/alert-dialog.d.ts +7 -3
- package/dist/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/alert-dialog.js +9 -5
- package/dist/components/ui/alert.d.ts +19 -3
- package/dist/components/ui/alert.d.ts.map +1 -1
- package/dist/components/ui/alert.js +25 -8
- package/dist/components/ui/app-frame.d.ts +28 -0
- package/dist/components/ui/app-frame.d.ts.map +1 -0
- package/dist/components/ui/app-frame.js +95 -0
- package/dist/components/ui/button-group.d.ts +1 -1
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/collapsible.d.ts +9 -1
- package/dist/components/ui/collapsible.d.ts.map +1 -1
- package/dist/components/ui/collapsible.js +13 -2
- package/dist/components/ui/collection-navigation.d.ts +8 -0
- package/dist/components/ui/collection-navigation.d.ts.map +1 -0
- package/dist/components/ui/collection-navigation.js +19 -0
- package/dist/components/ui/color-well.d.ts +13 -0
- package/dist/components/ui/color-well.d.ts.map +1 -0
- package/dist/components/ui/color-well.js +30 -0
- package/dist/components/ui/command.d.ts +5 -1
- package/dist/components/ui/command.d.ts.map +1 -1
- package/dist/components/ui/command.js +13 -1
- package/dist/components/ui/confirm-dialog.d.ts +19 -0
- package/dist/components/ui/confirm-dialog.d.ts.map +1 -0
- package/dist/components/ui/confirm-dialog.js +45 -0
- package/dist/components/ui/date-field.d.ts +19 -0
- package/dist/components/ui/date-field.d.ts.map +1 -0
- package/dist/components/ui/date-field.js +54 -0
- package/dist/components/ui/date-picker.d.ts +24 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/date-picker.js +92 -0
- package/dist/components/ui/dialog.d.ts +4 -2
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog.js +8 -5
- package/dist/components/ui/edge-fade.d.ts +11 -0
- package/dist/components/ui/edge-fade.d.ts.map +1 -0
- package/dist/components/ui/edge-fade.js +41 -0
- package/dist/components/ui/empty.d.ts +7 -2
- package/dist/components/ui/empty.d.ts.map +1 -1
- package/dist/components/ui/empty.js +20 -7
- package/dist/components/ui/field.d.ts +1 -1
- package/dist/components/ui/grid.d.ts +24 -0
- package/dist/components/ui/grid.d.ts.map +1 -0
- package/dist/components/ui/grid.js +258 -0
- package/dist/components/ui/icon-button.d.ts +15 -0
- package/dist/components/ui/icon-button.d.ts.map +1 -0
- package/dist/components/ui/icon-button.js +15 -0
- package/dist/components/ui/index.d.ts +23 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +23 -0
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/components/ui/inspector.d.ts +15 -0
- package/dist/components/ui/inspector.d.ts.map +1 -0
- package/dist/components/ui/inspector.js +26 -0
- package/dist/components/ui/kbd.d.ts +1 -1
- package/dist/components/ui/list.d.ts +28 -0
- package/dist/components/ui/list.d.ts.map +1 -0
- package/dist/components/ui/list.js +235 -0
- package/dist/components/ui/material.d.ts +34 -0
- package/dist/components/ui/material.d.ts.map +1 -0
- package/dist/components/ui/material.js +34 -0
- package/dist/components/ui/message-scroller-controller.d.ts +162 -0
- package/dist/components/ui/message-scroller-controller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-controller.js +888 -0
- package/dist/components/ui/message-scroller-layout-stability.d.ts +33 -0
- package/dist/components/ui/message-scroller-layout-stability.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-layout-stability.js +153 -0
- package/dist/components/ui/message-scroller-policy.d.ts +74 -0
- package/dist/components/ui/message-scroller-policy.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-policy.js +129 -0
- package/dist/components/ui/message-scroller-primitive.d.ts +55 -0
- package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-primitive.js +226 -0
- package/dist/components/ui/message-scroller.d.ts +11 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller.js +25 -0
- package/dist/components/ui/navigation-button-group.d.ts +16 -0
- package/dist/components/ui/navigation-button-group.d.ts.map +1 -0
- package/dist/components/ui/navigation-button-group.js +9 -0
- package/dist/components/ui/notification-dot.d.ts +4 -0
- package/dist/components/ui/notification-dot.d.ts.map +1 -0
- package/dist/components/ui/notification-dot.js +7 -0
- package/dist/components/ui/number-input.d.ts +16 -0
- package/dist/components/ui/number-input.d.ts.map +1 -0
- package/dist/components/ui/number-input.js +56 -0
- package/dist/components/ui/panel.d.ts +18 -0
- package/dist/components/ui/panel.d.ts.map +1 -0
- package/dist/components/ui/panel.js +40 -0
- package/dist/components/ui/popover.d.ts +9 -2
- package/dist/components/ui/popover.d.ts.map +1 -1
- package/dist/components/ui/popover.js +14 -4
- package/dist/components/ui/scroll-area.d.ts +8 -2
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.js +6 -3
- package/dist/components/ui/search-field.d.ts +19 -0
- package/dist/components/ui/search-field.d.ts.map +1 -0
- package/dist/components/ui/search-field.js +64 -0
- package/dist/components/ui/segmented-control.d.ts +21 -0
- package/dist/components/ui/segmented-control.d.ts.map +1 -0
- package/dist/components/ui/segmented-control.js +62 -0
- package/dist/components/ui/sheet.d.ts +4 -2
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet.js +12 -9
- package/dist/components/ui/sidebar.js +1 -1
- package/dist/components/ui/sonner.d.ts +4 -3
- package/dist/components/ui/sonner.d.ts.map +1 -1
- package/dist/components/ui/sonner.js +7 -6
- package/dist/components/ui/split-view.d.ts +11 -0
- package/dist/components/ui/split-view.d.ts.map +1 -0
- package/dist/components/ui/split-view.js +13 -0
- package/dist/components/ui/status.d.ts +13 -0
- package/dist/components/ui/status.d.ts.map +1 -0
- package/dist/components/ui/status.js +36 -0
- package/dist/components/ui/table.d.ts +11 -2
- package/dist/components/ui/table.d.ts.map +1 -1
- package/dist/components/ui/table.js +33 -6
- package/dist/components/ui/text.d.ts +17 -0
- package/dist/components/ui/text.d.ts.map +1 -0
- package/dist/components/ui/text.js +55 -0
- package/dist/components/ui/toggle.d.ts +12 -4
- package/dist/components/ui/toggle.d.ts.map +1 -1
- package/dist/components/ui/toggle.js +13 -2
- package/dist/components/ui/toolbar.d.ts +27 -0
- package/dist/components/ui/toolbar.d.ts.map +1 -0
- package/dist/components/ui/toolbar.js +71 -0
- package/dist/components/ui/tooltip.d.ts +8 -3
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js +11 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/lib/frame-lifecycle.d.ts +29 -0
- package/dist/lib/frame-lifecycle.d.ts.map +1 -1
- package/dist/lib/frame-lifecycle.js +85 -0
- package/dist/lib/native-capabilities/access.d.ts +13 -0
- package/dist/lib/native-capabilities/access.d.ts.map +1 -0
- package/dist/lib/native-capabilities/access.js +53 -0
- package/dist/lib/native-capabilities/bluetooth-access.d.ts +14 -0
- package/dist/lib/native-capabilities/bluetooth-access.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-access.js +43 -0
- package/dist/lib/native-capabilities/bluetooth-connection.d.ts +19 -0
- package/dist/lib/native-capabilities/bluetooth-connection.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-connection.js +88 -0
- package/dist/lib/native-capabilities/bluetooth-gatt.d.ts +7 -0
- package/dist/lib/native-capabilities/bluetooth-gatt.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-gatt.js +77 -0
- package/dist/lib/native-capabilities/bluetooth-internal.d.ts +10 -0
- package/dist/lib/native-capabilities/bluetooth-internal.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-internal.js +105 -0
- package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts +33 -0
- package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-native-fallback.js +214 -0
- package/dist/lib/native-capabilities/bluetooth-types.d.ts +85 -0
- package/dist/lib/native-capabilities/bluetooth-types.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-types.js +2 -0
- package/dist/lib/native-capabilities/bluetooth.d.ts +7 -0
- package/dist/lib/native-capabilities/bluetooth.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth.js +4 -0
- package/dist/lib/native-capabilities/bridge.d.ts +23 -0
- package/dist/lib/native-capabilities/bridge.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bridge.js +266 -0
- package/dist/lib/native-capabilities/capabilities.d.ts +7 -0
- package/dist/lib/native-capabilities/capabilities.d.ts.map +1 -0
- package/dist/lib/native-capabilities/capabilities.js +95 -0
- package/dist/lib/native-capabilities/clipboard.d.ts +11 -0
- package/dist/lib/native-capabilities/clipboard.d.ts.map +1 -0
- package/dist/lib/native-capabilities/clipboard.js +58 -0
- package/dist/lib/native-capabilities/device-io-errors.d.ts +11 -0
- package/dist/lib/native-capabilities/device-io-errors.d.ts.map +1 -0
- package/dist/lib/native-capabilities/device-io-errors.js +82 -0
- package/dist/lib/native-capabilities/displays.d.ts +38 -0
- package/dist/lib/native-capabilities/displays.d.ts.map +1 -0
- package/dist/lib/native-capabilities/displays.js +12 -0
- package/dist/lib/native-capabilities/global-shortcuts.d.ts +86 -0
- package/dist/lib/native-capabilities/global-shortcuts.d.ts.map +1 -0
- package/dist/lib/native-capabilities/global-shortcuts.js +351 -0
- package/dist/lib/native-capabilities/haptics.d.ts +25 -0
- package/dist/lib/native-capabilities/haptics.d.ts.map +1 -0
- package/dist/lib/native-capabilities/haptics.js +18 -0
- package/dist/lib/native-capabilities/hid-native.d.ts +26 -0
- package/dist/lib/native-capabilities/hid-native.d.ts.map +1 -0
- package/dist/lib/native-capabilities/hid-native.js +229 -0
- package/dist/lib/native-capabilities/hid.d.ts +52 -0
- package/dist/lib/native-capabilities/hid.d.ts.map +1 -0
- package/dist/lib/native-capabilities/hid.js +163 -0
- package/dist/lib/native-capabilities/index.d.ts +40 -0
- package/dist/lib/native-capabilities/index.d.ts.map +1 -0
- package/dist/lib/native-capabilities/index.js +21 -0
- package/dist/lib/native-capabilities/local-authentication.d.ts +32 -0
- package/dist/lib/native-capabilities/local-authentication.d.ts.map +1 -0
- package/dist/lib/native-capabilities/local-authentication.js +46 -0
- package/dist/lib/native-capabilities/location.d.ts +49 -0
- package/dist/lib/native-capabilities/location.d.ts.map +1 -0
- package/dist/lib/native-capabilities/location.js +114 -0
- package/dist/lib/native-capabilities/media-permissions.d.ts +28 -0
- package/dist/lib/native-capabilities/media-permissions.d.ts.map +1 -0
- package/dist/lib/native-capabilities/media-permissions.js +37 -0
- package/dist/lib/native-capabilities/media.d.ts +17 -0
- package/dist/lib/native-capabilities/media.d.ts.map +1 -0
- package/dist/lib/native-capabilities/media.js +104 -0
- package/dist/lib/native-capabilities/midi-access.d.ts +13 -0
- package/dist/lib/native-capabilities/midi-access.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-access.js +68 -0
- package/dist/lib/native-capabilities/midi-internal.d.ts +12 -0
- package/dist/lib/native-capabilities/midi-internal.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-internal.js +88 -0
- package/dist/lib/native-capabilities/midi-native-fallback.d.ts +27 -0
- package/dist/lib/native-capabilities/midi-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-native-fallback.js +127 -0
- package/dist/lib/native-capabilities/midi-ports.d.ts +6 -0
- package/dist/lib/native-capabilities/midi-ports.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-ports.js +115 -0
- package/dist/lib/native-capabilities/midi-types.d.ts +25 -0
- package/dist/lib/native-capabilities/midi-types.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-types.js +1 -0
- package/dist/lib/native-capabilities/midi.d.ts +6 -0
- package/dist/lib/native-capabilities/midi.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi.js +3 -0
- package/dist/lib/native-capabilities/native-device-io.d.ts +28 -0
- package/dist/lib/native-capabilities/native-device-io.d.ts.map +1 -0
- package/dist/lib/native-capabilities/native-device-io.js +91 -0
- package/dist/lib/native-capabilities/native-device-lifecycle.d.ts +13 -0
- package/dist/lib/native-capabilities/native-device-lifecycle.d.ts.map +1 -0
- package/dist/lib/native-capabilities/native-device-lifecycle.js +40 -0
- package/dist/lib/native-capabilities/notifications.d.ts +38 -0
- package/dist/lib/native-capabilities/notifications.d.ts.map +1 -0
- package/dist/lib/native-capabilities/notifications.js +50 -0
- package/dist/lib/native-capabilities/power-session.d.ts +113 -0
- package/dist/lib/native-capabilities/power-session.d.ts.map +1 -0
- package/dist/lib/native-capabilities/power-session.js +264 -0
- package/dist/lib/native-capabilities/secure-storage.d.ts +36 -0
- package/dist/lib/native-capabilities/secure-storage.d.ts.map +1 -0
- package/dist/lib/native-capabilities/secure-storage.js +64 -0
- package/dist/lib/native-capabilities/serial-native.d.ts +23 -0
- package/dist/lib/native-capabilities/serial-native.d.ts.map +1 -0
- package/dist/lib/native-capabilities/serial-native.js +181 -0
- package/dist/lib/native-capabilities/serial.d.ts +76 -0
- package/dist/lib/native-capabilities/serial.d.ts.map +1 -0
- package/dist/lib/native-capabilities/serial.js +215 -0
- package/dist/lib/native-capabilities/system-audio.d.ts +127 -0
- package/dist/lib/native-capabilities/system-audio.d.ts.map +1 -0
- package/dist/lib/native-capabilities/system-audio.js +330 -0
- package/dist/lib/native-capabilities/types.d.ts +62 -0
- package/dist/lib/native-capabilities/types.d.ts.map +1 -0
- package/dist/lib/native-capabilities/types.js +27 -0
- package/dist/lib/native-capabilities/usb-native.d.ts +39 -0
- package/dist/lib/native-capabilities/usb-native.d.ts.map +1 -0
- package/dist/lib/native-capabilities/usb-native.js +217 -0
- package/dist/lib/native-capabilities/usb.d.ts +85 -0
- package/dist/lib/native-capabilities/usb.d.ts.map +1 -0
- package/dist/lib/native-capabilities/usb.js +225 -0
- package/dist/lib/theme.d.ts.map +1 -1
- package/dist/lib/theme.js +2 -1
- package/docs/README.md +39 -0
- package/docs/accessibility.md +32 -0
- package/docs/adaptive-materials.md +79 -0
- package/docs/app-anatomy.md +74 -0
- package/docs/component-catalog.md +82 -0
- package/docs/component-guide-template.md +37 -0
- package/docs/design-tokens.md +185 -0
- package/docs/foundations.md +58 -0
- package/docs/native-integration.md +33 -0
- package/docs/standalone-app-windows.md +136 -0
- package/package.json +8 -3
- package/src/components/ui/alert-dialog.md +31 -0
- package/src/components/ui/alert.md +77 -0
- package/src/components/ui/app-frame.md +38 -0
- package/src/components/ui/badge.md +57 -0
- package/src/components/ui/button.md +76 -0
- package/src/components/ui/collapsible.md +52 -0
- package/src/components/ui/color-well.md +11 -0
- package/src/components/ui/combobox.md +42 -0
- package/src/components/ui/command.md +54 -0
- package/src/components/ui/date-field.md +32 -0
- package/src/components/ui/date-picker.md +55 -0
- package/src/components/ui/dialog.md +40 -0
- package/src/components/ui/edge-fade.md +7 -0
- package/src/components/ui/empty.md +87 -0
- package/src/components/ui/field.md +77 -0
- package/src/components/ui/grid.md +109 -0
- package/src/components/ui/icon-button.md +36 -0
- package/src/components/ui/inspector.md +11 -0
- package/src/components/ui/item.md +87 -0
- package/src/components/ui/list.md +140 -0
- package/src/components/ui/material.md +51 -0
- package/src/components/ui/navigation-button-group.md +46 -0
- package/src/components/ui/notification-dot.md +7 -0
- package/src/components/ui/number-input.md +19 -0
- package/src/components/ui/panel.md +11 -0
- package/src/components/ui/popover.md +31 -0
- package/src/components/ui/resizable.md +66 -0
- package/src/components/ui/scroll-area.md +72 -0
- package/src/components/ui/search-field.md +33 -0
- package/src/components/ui/segmented-control.md +36 -0
- package/src/components/ui/sheet.md +30 -0
- package/src/components/ui/sidebar.md +113 -0
- package/src/components/ui/sonner.md +37 -0
- package/src/components/ui/split-view.md +15 -0
- package/src/components/ui/status.md +12 -0
- package/src/components/ui/table.md +37 -0
- package/src/components/ui/tabs.md +66 -0
- package/src/components/ui/text.md +17 -0
- package/src/components/ui/toggle-button.md +48 -0
- package/src/components/ui/toggle-group.md +80 -0
- package/src/components/ui/toggle.md +73 -0
- package/src/components/ui/toolbar.md +26 -0
- package/src/components/ui/tooltip.md +31 -0
- package/src/styles/index.css +704 -3
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
3
|
-
import { AlertCircle,
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AlertCircle, ChevronDown, ClipboardList, Code2, CornerDownRight, GripVertical, Image as ImageIcon, ListPlus, Loader2, Maximize2, Minimize2, Pencil, RotateCcw, Trash2, } from 'lucide-react';
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
5
5
|
import { cn } from '../../lib/utils';
|
|
6
6
|
import { Button } from '../ui/button';
|
|
7
|
-
import {
|
|
7
|
+
import { Dialog, DialogContent, DialogTitle } from '../ui/dialog';
|
|
8
|
+
import { MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, useMessageScroller, useMessageScrollerVisibility, } from '../ui/message-scroller';
|
|
9
|
+
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
|
|
8
10
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '../ui/tooltip';
|
|
9
11
|
import { ChatInput, } from './chat-input';
|
|
10
|
-
import { CompactingMessage, ThinkingMessage, } from './chat-message';
|
|
12
|
+
import { CompactingMessage, ThinkingMessage, getChatMessageRenderKey, } from './chat-message';
|
|
11
13
|
import { MessageRow, computeIsThinking, } from './chat-messages';
|
|
12
|
-
import { ConversationHistory, } from './conversation-history';
|
|
14
|
+
import { ConversationHistory, ConversationSidebar, } from './conversation-history';
|
|
13
15
|
import { ModelEffortSelector, } from './model-effort-selector';
|
|
14
16
|
import { ToolApprovalProvider, } from './tool-approval-context';
|
|
15
17
|
import { ToolProgressProvider } from './tool-progress-context';
|
|
@@ -17,7 +19,6 @@ import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, us
|
|
|
17
19
|
import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable';
|
|
18
20
|
import { CSS } from '@dnd-kit/utilities';
|
|
19
21
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
20
|
-
import { Virtualizer } from 'virtua';
|
|
21
22
|
const CODEX_OAUTH_ERROR_PATTERNS = [
|
|
22
23
|
'codex oauth',
|
|
23
24
|
'codex-oauth',
|
|
@@ -34,18 +35,26 @@ const MISSING_API_KEY_ERROR_PATTERNS = [
|
|
|
34
35
|
'credential required in vault',
|
|
35
36
|
'credential not configured in vault',
|
|
36
37
|
];
|
|
38
|
+
function isToastInteractionTarget(target) {
|
|
39
|
+
return (target instanceof Element &&
|
|
40
|
+
target.closest('[data-sonner-toaster], [data-sonner-toast]') !== null);
|
|
41
|
+
}
|
|
37
42
|
const AUTH_PROMPT_COPY = {
|
|
38
43
|
'missing-api-key': {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
action: 'Add API key',
|
|
44
|
+
label: 'Sign in with your ChatGPT account to chat with AI',
|
|
45
|
+
action: 'Connect ChatGPT',
|
|
42
46
|
},
|
|
43
47
|
'codex-oauth-expired': {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
action: 'Reconnect OpenAI Codex',
|
|
48
|
+
label: 'Sign in again to refresh your ChatGPT connection',
|
|
49
|
+
action: 'Reconnect ChatGPT',
|
|
47
50
|
},
|
|
48
51
|
};
|
|
52
|
+
export function getChatAuthPromptCopy(issue) {
|
|
53
|
+
return AUTH_PROMPT_COPY[issue];
|
|
54
|
+
}
|
|
55
|
+
function ChatAuthPrompt({ copy, isConnecting, onConnect, onAdvancedSetup, }) {
|
|
56
|
+
return (_jsxs("div", { className: "flex flex-col items-center gap-2 py-3 text-center", "data-chat-auth-prompt": true, children: [_jsx("p", { className: "text-muted-foreground max-w-sm text-sm", children: copy.label }), onConnect && (_jsx(Button, { onClick: onConnect, size: "sm", className: "cursor-pointer", disabled: isConnecting, children: isConnecting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 size-4 animate-spin" }), "Waiting for ChatGPT..."] })) : (copy.action) })), onAdvancedSetup && (_jsx(Button, { variant: "ghost", size: "sm", className: "text-muted-foreground hover:text-foreground h-auto cursor-pointer px-2 py-1 text-xs font-normal", onClick: onAdvancedSetup, disabled: isConnecting, children: "Advanced setup" }))] }));
|
|
57
|
+
}
|
|
49
58
|
function messageIncludesAny(message, patterns) {
|
|
50
59
|
const normalized = message.toLowerCase();
|
|
51
60
|
return patterns.some((pattern) => normalized.includes(pattern));
|
|
@@ -64,6 +73,81 @@ export function resolveChatAuthIssue({ missingApiKey, authIssue, error, }) {
|
|
|
64
73
|
}
|
|
65
74
|
return null;
|
|
66
75
|
}
|
|
76
|
+
export function hasPersistedChatError(messages) {
|
|
77
|
+
const lastMessage = messages.at(-1);
|
|
78
|
+
return Boolean(lastMessage?.parts?.some((part) => part.type === 'error'));
|
|
79
|
+
}
|
|
80
|
+
function MessageScrollerCommandSync({ signal }) {
|
|
81
|
+
const { scrollToEnd } = useMessageScroller();
|
|
82
|
+
const previousSignalRef = useRef(signal);
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (previousSignalRef.current === signal)
|
|
85
|
+
return;
|
|
86
|
+
previousSignalRef.current = signal;
|
|
87
|
+
scrollToEnd({ behavior: 'auto' });
|
|
88
|
+
}, [scrollToEnd, signal]);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
function getNavigationLabel(message) {
|
|
92
|
+
const text = message.content ??
|
|
93
|
+
message.parts
|
|
94
|
+
?.flatMap((part) => (part.type === 'text' ? [part.text] : []))
|
|
95
|
+
.join(' ');
|
|
96
|
+
const normalized = text?.replace(/\s+/g, ' ').trim() || 'User message';
|
|
97
|
+
return normalized.length > 56 ? `${normalized.slice(0, 53)}...` : normalized;
|
|
98
|
+
}
|
|
99
|
+
function MessageNavigationTrail({ items }) {
|
|
100
|
+
const { scrollToMessage } = useMessageScroller();
|
|
101
|
+
const { currentAnchorId } = useMessageScrollerVisibility();
|
|
102
|
+
const anchors = useMemo(() => items.flatMap((item) => item.kind === 'message' && item.message.role === 'user'
|
|
103
|
+
? [{ id: item.key, label: getNavigationLabel(item.message) }]
|
|
104
|
+
: []), [items]);
|
|
105
|
+
if (anchors.length < 2)
|
|
106
|
+
return null;
|
|
107
|
+
return (_jsx("div", { "data-fullscreen-message-navigation": true, className: "absolute bottom-8 left-3 top-8 z-20 flex w-9 items-center", children: _jsx(TooltipProvider, { delayDuration: 250, children: _jsx("nav", { "aria-label": "Conversation turns", className: "flex max-h-full w-full flex-col items-start overflow-y-auto py-2 [scrollbar-width:none]", children: _jsx("div", { "data-message-navigation-list": true, className: "my-auto flex w-full shrink-0 flex-col items-start", children: anchors.map((anchor) => {
|
|
108
|
+
const isCurrent = anchor.id === currentAnchorId;
|
|
109
|
+
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-current": isCurrent ? 'location' : undefined, "aria-label": `Jump to: ${anchor.label}`, onClick: () => scrollToMessage(anchor.id, {
|
|
110
|
+
align: 'start',
|
|
111
|
+
behavior: 'smooth',
|
|
112
|
+
scrollMargin: 64,
|
|
113
|
+
}), "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 h-0.5 w-[26px] origin-left rounded-full opacity-40', isCurrent && 'bg-foreground opacity-60') }) }) }) }), _jsx(TooltipContent, { side: "right", className: "max-w-72", children: anchor.label })] }, anchor.id));
|
|
114
|
+
}) }) }) }) }));
|
|
115
|
+
}
|
|
116
|
+
function ChatMessageViewport({ items, renderItem, toolProgress, onApprovalResponse, currentConversationId, scrollToBottomSignal, isBusy, hasOlderMessages = false, isLoadingOlderMessages = false, onLoadOlderMessages, showNavigationTrail = false, scrollAreaClassName, contentClassName, scrollButtonClassName, }) {
|
|
117
|
+
const viewportRef = useRef(null);
|
|
118
|
+
const loadingOlderRef = useRef(false);
|
|
119
|
+
const handleViewportScroll = useCallback((event) => {
|
|
120
|
+
const viewport = event.currentTarget;
|
|
121
|
+
if (viewport.scrollTop > 64 ||
|
|
122
|
+
!hasOlderMessages ||
|
|
123
|
+
isLoadingOlderMessages ||
|
|
124
|
+
loadingOlderRef.current ||
|
|
125
|
+
!onLoadOlderMessages) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
loadingOlderRef.current = true;
|
|
129
|
+
// A prepended page is position-preserved by the message scroller
|
|
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
|
+
void onLoadOlderMessages()
|
|
134
|
+
.then((outcome) => {
|
|
135
|
+
if (outcome !== 'reset')
|
|
136
|
+
return;
|
|
137
|
+
window.requestAnimationFrame(() => {
|
|
138
|
+
if (viewportRef.current !== viewport)
|
|
139
|
+
return;
|
|
140
|
+
viewport.scrollTop = viewport.scrollHeight;
|
|
141
|
+
});
|
|
142
|
+
})
|
|
143
|
+
.finally(() => {
|
|
144
|
+
window.requestAnimationFrame(() => {
|
|
145
|
+
loadingOlderRef.current = false;
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
}, [hasOlderMessages, isLoadingOlderMessages, onLoadOlderMessages]);
|
|
149
|
+
return (_jsx(MessageScrollerProvider, { autoScroll: true, defaultScrollPosition: "end", scrollPreviousItemPeek: 64, children: _jsxs(MessageScroller, { className: "relative min-h-0 min-w-0 flex-1", children: [_jsx(MessageScrollerCommandSync, { signal: scrollToBottomSignal }), _jsx(MessageScrollerViewport, { ref: viewportRef, 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 })] }) }, currentConversationId ?? 'new-conversation'));
|
|
150
|
+
}
|
|
67
151
|
function clampPercent(value) {
|
|
68
152
|
if (!Number.isFinite(value))
|
|
69
153
|
return 0;
|
|
@@ -77,7 +161,16 @@ function formatTokenCount(tokens) {
|
|
|
77
161
|
const millions = tokens / 1_000_000;
|
|
78
162
|
return `${Number.isInteger(millions) ? millions.toFixed(0) : millions.toFixed(2)}M`;
|
|
79
163
|
}
|
|
80
|
-
function
|
|
164
|
+
function formatUsageReset(resetAt) {
|
|
165
|
+
if (!resetAt)
|
|
166
|
+
return null;
|
|
167
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
168
|
+
weekday: 'short',
|
|
169
|
+
hour: 'numeric',
|
|
170
|
+
minute: '2-digit',
|
|
171
|
+
}).format(new Date(resetAt * 1_000));
|
|
172
|
+
}
|
|
173
|
+
function ContextWindowIndicator({ usage, planUsage, }) {
|
|
81
174
|
if (!usage || usage.maxTokens <= 0)
|
|
82
175
|
return null;
|
|
83
176
|
const usedPercent = clampPercent(Math.round((usage.usedTokens / usage.maxTokens) * 100));
|
|
@@ -86,9 +179,15 @@ function ContextWindowIndicator({ usage }) {
|
|
|
86
179
|
: usedPercent >= 75
|
|
87
180
|
? 'var(--warning)'
|
|
88
181
|
: 'var(--muted-foreground)';
|
|
89
|
-
return (_jsxs(
|
|
182
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring flex size-8 cursor-pointer items-center justify-center rounded-full bg-transparent p-0 focus-visible:outline-none focus-visible:ring-2", "aria-label": `Context window ${usedPercent}% full`, children: _jsx("span", { className: "relative size-4 rounded-full", style: {
|
|
90
183
|
background: `conic-gradient(${ringColor} ${usedPercent}%, color-mix(in oklch, var(--muted-foreground) 22%, transparent) 0)`,
|
|
91
|
-
}, children: _jsx("span", { className: "bg-background absolute inset-[3px] rounded-full" }) }) }) }), _jsxs(
|
|
184
|
+
}, children: _jsx("span", { className: "bg-background absolute inset-[3px] rounded-full" }) }) }) }), _jsxs(PopoverContent, { align: "end", side: "top", sideOffset: 8, className: "w-80 p-3 shadow-lg", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 text-sm", 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 mt-2 h-1.5 overflow-hidden rounded-full", children: _jsx("div", { className: "bg-primary h-full rounded-full", style: { width: `${usedPercent}%` } }) }), usage.compactsAutomatically && (_jsx("div", { className: "text-muted-foreground mt-2 text-[11px] 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-xs", children: ["Plan usage limits", planUsage.planLabel ? ` · ${planUsage.planLabel}` : ''] }), planUsage.accountLabel && (_jsx("div", { className: "mt-0.5 truncate text-xs font-medium", children: planUsage.accountLabel }))] }), planUsage.windows.map((window) => {
|
|
185
|
+
const reset = formatUsageReset(window.resetAt);
|
|
186
|
+
const percent = clampPercent(window.usedPercent);
|
|
187
|
+
return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 text-xs", children: [_jsx("span", { children: window.label }), _jsxs("span", { className: "text-muted-foreground", children: [reset ? `Resets ${reset} · ` : '', percent, "%"] })] }), _jsx("div", { className: "bg-muted h-1.5 overflow-hidden rounded-full", children: _jsx("div", { className: percent >= 90
|
|
188
|
+
? 'bg-destructive h-full rounded-full'
|
|
189
|
+
: 'bg-primary h-full rounded-full', style: { width: `${percent}%` } }) })] }, window.label));
|
|
190
|
+
})] }))] })] }));
|
|
92
191
|
}
|
|
93
192
|
function ContextCompactedDivider() {
|
|
94
193
|
return (_jsx("div", { "data-testid": "context-compacted-divider", className: "text-muted-foreground/80 w-full px-4 py-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "bg-border h-px min-w-8 flex-1" }), _jsxs("div", { className: "flex select-none items-center gap-2 whitespace-nowrap text-[13px] font-medium leading-5", children: [_jsx(ClipboardList, { className: "size-4" }), _jsx("span", { children: "Context automatically compacted" })] }), _jsx("div", { className: "bg-border h-px min-w-8 flex-1" })] }) }));
|
|
@@ -118,19 +217,10 @@ function QueuedMessageRow({ message, isResponding, onRetryQueuedMessage, onSteer
|
|
|
118
217
|
/**
|
|
119
218
|
* Floating chat panel with model selector
|
|
120
219
|
*/
|
|
121
|
-
export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChange, onSubmit, onStop, onNewChat, modelProviders, modelEffortPresets, selectedModel, selectedReasoningEffort, onModelEffortChange, conversations, currentConversationId, scrollToBottomSignal = 0, onSelectConversation,
|
|
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, }) {
|
|
122
221
|
const inputRef = useRef(null);
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
const virtualizerRef = useRef(null);
|
|
126
|
-
const prevMessageCountRef = useRef(messages.length);
|
|
127
|
-
const prevConversationIdRef = useRef(currentConversationId ?? null);
|
|
128
|
-
const prevScrollToBottomSignalRef = useRef(scrollToBottomSignal);
|
|
129
|
-
const pendingConversationScrollIdRef = useRef(null);
|
|
130
|
-
const hasPendingScrollToBottomSignalRef = useRef(false);
|
|
131
|
-
const scrollRafRef = useRef(null);
|
|
132
|
-
const [viewportVersion, setViewportVersion] = useState(0);
|
|
133
|
-
const [isAtBottom, setIsAtBottom] = useState(true);
|
|
222
|
+
const fullScreenTriggerRef = useRef(null);
|
|
223
|
+
const [isConnectingChatGPT, setIsConnectingChatGPT] = useState(false);
|
|
134
224
|
const queuedMessageIds = useMemo(() => queuedMessages.map((message) => message.id), [queuedMessages]);
|
|
135
225
|
const queueSensors = useSensors(useSensor(PointerSensor, {
|
|
136
226
|
activationConstraint: {
|
|
@@ -141,59 +231,31 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
141
231
|
}));
|
|
142
232
|
const isResponding = status === 'streaming' || status === 'submitted';
|
|
143
233
|
const controlsDisabled = isTurnInFlight ?? isResponding;
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
useEffect(() => {
|
|
147
|
-
const scrollArea = scrollAreaRef.current;
|
|
148
|
-
if (!scrollArea)
|
|
149
|
-
return;
|
|
150
|
-
const viewport = scrollArea.querySelector('[data-radix-scroll-area-viewport]');
|
|
151
|
-
if (!viewport)
|
|
152
|
-
return;
|
|
153
|
-
viewport.style.overflowAnchor = 'none';
|
|
154
|
-
if (viewportRef.current !== viewport) {
|
|
155
|
-
viewportRef.current = viewport;
|
|
156
|
-
setViewportVersion((version) => version + 1);
|
|
157
|
-
}
|
|
158
|
-
}, [isExpanded]);
|
|
159
|
-
// Track scroll position to detect if user is at bottom
|
|
160
|
-
useEffect(() => {
|
|
161
|
-
const viewport = viewportRef.current;
|
|
162
|
-
if (!viewport)
|
|
163
|
-
return;
|
|
164
|
-
const handleScroll = () => {
|
|
165
|
-
const { scrollTop, scrollHeight, clientHeight } = viewport;
|
|
166
|
-
// Consider "at bottom" if within 50px of the bottom
|
|
167
|
-
const atBottom = scrollHeight - scrollTop - clientHeight < 50;
|
|
168
|
-
setIsAtBottom(atBottom);
|
|
169
|
-
};
|
|
170
|
-
handleScroll();
|
|
171
|
-
viewport.addEventListener('scroll', handleScroll);
|
|
172
|
-
return () => viewport.removeEventListener('scroll', handleScroll);
|
|
173
|
-
}, [viewportVersion]);
|
|
234
|
+
const isChatOpen = isExpanded || isFullScreen;
|
|
235
|
+
const composerControls = (_jsxs(_Fragment, { children: [_jsx(ContextWindowIndicator, { usage: contextUsage, planUsage: planUsage }), modelProviders.length > 0 && modelEffortPresets.length > 0 ? (_jsx(ModelEffortSelector, { providers: modelProviders, presets: modelEffortPresets, selectedModel: selectedModel, selectedReasoningEffort: selectedReasoningEffort, onSelectionChange: onModelEffortChange, disabled: controlsDisabled })) : null] }));
|
|
174
236
|
// Focus input when expanded
|
|
175
237
|
useEffect(() => {
|
|
176
|
-
if (
|
|
238
|
+
if (isChatOpen) {
|
|
177
239
|
const timer = setTimeout(() => {
|
|
178
240
|
inputRef.current?.focus();
|
|
179
241
|
}, 200);
|
|
180
242
|
return () => clearTimeout(timer);
|
|
181
243
|
}
|
|
182
|
-
}, [
|
|
244
|
+
}, [isChatOpen]);
|
|
183
245
|
const resolvedAuthIssue = resolveChatAuthIssue({
|
|
184
246
|
missingApiKey,
|
|
185
247
|
authIssue,
|
|
186
248
|
error,
|
|
187
249
|
});
|
|
188
250
|
const authPromptCopy = resolvedAuthIssue
|
|
189
|
-
?
|
|
251
|
+
? getChatAuthPromptCopy(resolvedAuthIssue)
|
|
190
252
|
: null;
|
|
191
253
|
const showAuthPrompt = Boolean(resolvedAuthIssue);
|
|
192
254
|
const submitDisabled = showAuthPrompt;
|
|
193
255
|
const handleSubmit = useCallback((e, mode) => {
|
|
194
256
|
e?.preventDefault();
|
|
195
257
|
if (submitDisabled) {
|
|
196
|
-
if (!
|
|
258
|
+
if (!isChatOpen) {
|
|
197
259
|
onExpandedChange(true);
|
|
198
260
|
}
|
|
199
261
|
return;
|
|
@@ -201,17 +263,15 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
201
263
|
if (!input.trim() && imageAttachments.length === 0)
|
|
202
264
|
return;
|
|
203
265
|
const submitMode = mode ?? (isResponding ? 'queue' : 'send');
|
|
204
|
-
if (!
|
|
266
|
+
if (!isChatOpen) {
|
|
205
267
|
onExpandedChange(true);
|
|
206
268
|
}
|
|
207
|
-
// Reset to bottom when user sends a message
|
|
208
|
-
setIsAtBottom(true);
|
|
209
269
|
onSubmit(e, submitMode);
|
|
210
270
|
}, [
|
|
211
271
|
imageAttachments.length,
|
|
212
272
|
input,
|
|
213
273
|
isResponding,
|
|
214
|
-
|
|
274
|
+
isChatOpen,
|
|
215
275
|
onExpandedChange,
|
|
216
276
|
onSubmit,
|
|
217
277
|
submitDisabled,
|
|
@@ -224,50 +284,79 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
224
284
|
}, [onReorderQueuedMessages]);
|
|
225
285
|
const handleEditQueuedMessage = useCallback((id) => {
|
|
226
286
|
onEditQueuedMessage?.(id);
|
|
227
|
-
if (!
|
|
287
|
+
if (!isChatOpen) {
|
|
228
288
|
onExpandedChange(true);
|
|
229
289
|
}
|
|
230
290
|
window.setTimeout(() => inputRef.current?.focus(), 0);
|
|
231
|
-
}, [
|
|
291
|
+
}, [isChatOpen, onEditQueuedMessage, onExpandedChange]);
|
|
232
292
|
const handleNewChat = useCallback(() => {
|
|
233
293
|
onNewChat?.();
|
|
234
294
|
inputRef.current?.focus();
|
|
235
295
|
}, [onNewChat]);
|
|
296
|
+
const handleConnectChatGPT = useCallback(async () => {
|
|
297
|
+
if (!onConnectChatGPT || isConnectingChatGPT)
|
|
298
|
+
return;
|
|
299
|
+
setIsConnectingChatGPT(true);
|
|
300
|
+
try {
|
|
301
|
+
await onConnectChatGPT();
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
console.error('Failed to connect ChatGPT:', error);
|
|
305
|
+
}
|
|
306
|
+
finally {
|
|
307
|
+
setIsConnectingChatGPT(false);
|
|
308
|
+
}
|
|
309
|
+
}, [isConnectingChatGPT, onConnectChatGPT]);
|
|
310
|
+
const editingAppControl = showEditingAppToggle && onEditingAppChange ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: (event) => {
|
|
311
|
+
event.preventDefault();
|
|
312
|
+
onEditingAppChange(!isEditingApp);
|
|
313
|
+
}, className: cn('cursor-pointer', isEditingApp
|
|
314
|
+
? 'text-primary bg-primary/10 hover:bg-primary/20'
|
|
315
|
+
: 'text-muted-foreground hover:text-foreground'), children: _jsx(Code2, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "top", children: _jsx("p", { children: isEditingApp
|
|
316
|
+
? 'Editing this app (click to disable)'
|
|
317
|
+
: 'Not editing app (click to enable)' }) })] }) })) : null;
|
|
236
318
|
const composerStartControls = (_jsxs(_Fragment, { children: [conversations &&
|
|
237
319
|
(conversations.length > 0 || onNewChat) &&
|
|
238
|
-
onSelectConversation && (_jsx(ConversationHistory, { conversations: conversations, currentConversationId: currentConversationId, onSelect: onSelectConversation,
|
|
239
|
-
event.preventDefault();
|
|
240
|
-
onEditingAppChange(!isEditingApp);
|
|
241
|
-
}, className: cn('cursor-pointer', isEditingApp
|
|
242
|
-
? 'text-primary bg-primary/10 hover:bg-primary/20'
|
|
243
|
-
: 'text-muted-foreground hover:text-foreground'), children: _jsx(Code2, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "top", children: _jsx("p", { children: isEditingApp
|
|
244
|
-
? 'Editing this app (click to disable)'
|
|
245
|
-
: 'Not editing app (click to enable)' }) })] }) }))] }));
|
|
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] }));
|
|
246
321
|
// Keyboard shortcut: Cmd+Shift+O for new chat
|
|
247
322
|
useEffect(() => {
|
|
248
323
|
const handleKeyDown = (e) => {
|
|
249
324
|
if (e.key === 'o' && e.metaKey && e.shiftKey) {
|
|
250
325
|
e.preventDefault();
|
|
251
326
|
// Only create new chat if conversation controls are currently available.
|
|
252
|
-
if (
|
|
327
|
+
if (isChatOpen) {
|
|
253
328
|
handleNewChat();
|
|
254
329
|
}
|
|
255
330
|
}
|
|
256
331
|
};
|
|
257
332
|
document.addEventListener('keydown', handleKeyDown);
|
|
258
333
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
259
|
-
}, [
|
|
334
|
+
}, [isChatOpen, handleNewChat]);
|
|
260
335
|
// Handle minimize button - now goes to minimized state
|
|
261
336
|
const handleMinimize = useCallback(() => {
|
|
337
|
+
if (isFullScreen) {
|
|
338
|
+
onFullScreenChange?.(false);
|
|
339
|
+
}
|
|
262
340
|
if (isExpanded) {
|
|
263
341
|
onExpandedChange(false);
|
|
264
342
|
}
|
|
265
343
|
onMinimizedChange?.(true);
|
|
266
|
-
}, [
|
|
344
|
+
}, [
|
|
345
|
+
isExpanded,
|
|
346
|
+
isFullScreen,
|
|
347
|
+
onExpandedChange,
|
|
348
|
+
onFullScreenChange,
|
|
349
|
+
onMinimizedChange,
|
|
350
|
+
]);
|
|
267
351
|
const isStreaming = status === 'streaming' || status === 'submitted';
|
|
268
352
|
const isThinking = useMemo(() => computeIsThinking(messages, status), [messages, status]);
|
|
269
|
-
const showErrorMessage = Boolean(error) &&
|
|
270
|
-
|
|
353
|
+
const showErrorMessage = Boolean(error) &&
|
|
354
|
+
status === 'error' &&
|
|
355
|
+
!showAuthPrompt &&
|
|
356
|
+
!hasPersistedChatError(messages);
|
|
357
|
+
const lastMessageKey = messages.length > 0
|
|
358
|
+
? getChatMessageRenderKey(messages[messages.length - 1], messages.length - 1)
|
|
359
|
+
: null;
|
|
271
360
|
const listItems = useMemo(() => {
|
|
272
361
|
const items = [];
|
|
273
362
|
if (messages.length === 0 && welcomeMessage) {
|
|
@@ -283,7 +372,11 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
283
372
|
kind: 'context-compacted-divider',
|
|
284
373
|
});
|
|
285
374
|
}
|
|
286
|
-
items.push({
|
|
375
|
+
items.push({
|
|
376
|
+
key: getChatMessageRenderKey(message, index),
|
|
377
|
+
kind: 'message',
|
|
378
|
+
message,
|
|
379
|
+
});
|
|
287
380
|
}
|
|
288
381
|
if (isThinking && !isCompacting) {
|
|
289
382
|
items.push({ key: 'thinking', kind: 'thinking' });
|
|
@@ -291,9 +384,6 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
291
384
|
if (isCompacting) {
|
|
292
385
|
items.push({ key: 'compacting', kind: 'compacting' });
|
|
293
386
|
}
|
|
294
|
-
if (showAuthPrompt) {
|
|
295
|
-
items.push({ key: 'auth-prompt', kind: 'auth-prompt' });
|
|
296
|
-
}
|
|
297
387
|
if (showErrorMessage) {
|
|
298
388
|
items.push({ key: 'error', kind: 'error' });
|
|
299
389
|
}
|
|
@@ -304,7 +394,6 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
304
394
|
compactedHistoryStartIndex,
|
|
305
395
|
messages,
|
|
306
396
|
showErrorMessage,
|
|
307
|
-
showAuthPrompt,
|
|
308
397
|
welcomeMessage,
|
|
309
398
|
]);
|
|
310
399
|
const renderVirtualItem = useCallback((item) => {
|
|
@@ -315,99 +404,43 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
315
404
|
return (_jsx("div", { className: "px-2 pb-3", children: _jsx(ContextCompactedDivider, {}) }));
|
|
316
405
|
case 'message': {
|
|
317
406
|
const checkpoint = checkpoints?.get(item.message.id);
|
|
318
|
-
return (_jsx("div", { className: "px-2 pb-3", children: _jsx(MessageRow, { message: item.message, isLast: item.
|
|
407
|
+
return (_jsx("div", { className: "px-2 pb-3", children: _jsx(MessageRow, { message: item.message, isLast: item.key === lastMessageKey, isStreaming: isStreaming, checkpoint: checkpoint, restoringMessageId: restoringMessageId, onRestoreCheckpoint: onRestoreCheckpoint, onResolveMessageContent: onResolveMessageContent, onRetryError: item.key === lastMessageKey ? onRetryError : undefined }) }));
|
|
319
408
|
}
|
|
320
409
|
case 'thinking':
|
|
321
410
|
return (_jsx("div", { className: "px-2 pb-3", children: _jsx(ThinkingMessage, {}) }));
|
|
322
411
|
case 'compacting':
|
|
323
412
|
return (_jsx("div", { className: "px-2 pb-3", children: _jsx(CompactingMessage, {}) }));
|
|
324
|
-
case 'auth-prompt':
|
|
325
|
-
if (resolvedAuthIssue === 'codex-oauth-expired') {
|
|
326
|
-
return (_jsx("div", { className: "px-2 pb-4", children: _jsxs("div", { className: "bg-muted/30 mx-2 flex flex-col gap-3 rounded-lg p-4", children: [_jsx("div", { className: "flex items-start justify-between gap-3", children: _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium", children: authPromptCopy?.title ?? 'Refresh OpenAI Codex auth' }), _jsx("p", { className: "text-muted-foreground text-xs", children: authPromptCopy?.description ??
|
|
327
|
-
'Open Settings > API Keys and reconnect OpenAI Codex.' })] }) }), onAddApiKey && (_jsxs(Button, { variant: "outline", className: "w-full cursor-pointer", onClick: onAddApiKey, children: [_jsx(ExternalLink, { className: "mr-2 size-4" }), authPromptCopy?.action ?? 'Reconnect OpenAI Codex'] }))] }) }));
|
|
328
|
-
}
|
|
329
|
-
return (_jsx("div", { className: "px-2 pb-4", children: _jsxs("div", { className: "border-primary/30 bg-primary/5 mx-2 flex flex-col items-center gap-3 rounded-lg border p-4 text-center", children: [_jsx("div", { className: "bg-primary/10 flex size-10 items-center justify-center rounded-full", children: _jsx(AlertCircle, { className: "text-primary size-5" }) }), _jsxs("div", { className: "max-w-sm", children: [_jsx("p", { className: "text-foreground font-medium", children: authPromptCopy?.title ?? 'Authentication required' }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: authPromptCopy?.description ??
|
|
330
|
-
'Open settings to configure chat authentication.' })] }), onAddApiKey && (_jsx(Button, { onClick: onAddApiKey, size: "sm", className: "cursor-pointer", children: authPromptCopy?.action ?? 'Open settings' }))] }) }));
|
|
331
413
|
case 'error':
|
|
332
|
-
return (_jsx("div", { className: "px-2 pb-4", children: error && (_jsxs("div", { className: "border-destructive/30 bg-destructive/10 text-destructive mx-2 flex items-start gap-2 rounded-lg border p-3 text-sm", children: [_jsx(AlertCircle, { className: "mt-0.5 size-4 shrink-0" }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "font-medium", children: "Request failed" }), _jsx("p", { className: "text-destructive/80 mt-0.5 break-words", children: error.message || 'An unknown error occurred' })] })] })) }));
|
|
414
|
+
return (_jsx("div", { className: "px-2 pb-4", children: error && (_jsxs("div", { className: "border-destructive/30 bg-destructive/10 text-destructive mx-2 flex items-start gap-2 rounded-lg border p-3 text-sm", children: [_jsx(AlertCircle, { className: "mt-0.5 size-4 shrink-0" }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "font-medium", children: "Request failed" }), _jsx("p", { className: "text-destructive/80 mt-0.5 break-words", children: error.message || 'An unknown error occurred' }), onRetryError && (_jsxs("button", { type: "button", onClick: onRetryError, className: "border-destructive/30 hover:bg-destructive/10 mt-2 inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border px-2.5 text-xs font-medium transition-colors", children: [_jsx(RotateCcw, { className: "size-3.5" }), "Retry"] }))] })] })) }));
|
|
333
415
|
}
|
|
334
416
|
}, [
|
|
335
417
|
checkpoints,
|
|
336
418
|
error,
|
|
337
|
-
authPromptCopy,
|
|
338
|
-
resolvedAuthIssue,
|
|
339
419
|
isStreaming,
|
|
340
|
-
|
|
420
|
+
lastMessageKey,
|
|
341
421
|
messages.length,
|
|
342
|
-
onAddApiKey,
|
|
343
422
|
onRestoreCheckpoint,
|
|
423
|
+
onResolveMessageContent,
|
|
424
|
+
onRetryError,
|
|
344
425
|
restoringMessageId,
|
|
345
426
|
welcomeMessage,
|
|
346
427
|
]);
|
|
347
|
-
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
}
|
|
363
|
-
// New conversations loaded from history should start at the latest message.
|
|
364
|
-
useEffect(() => {
|
|
365
|
-
const previousConversationId = prevConversationIdRef.current;
|
|
366
|
-
const nextConversationId = currentConversationId ?? null;
|
|
367
|
-
prevConversationIdRef.current = nextConversationId;
|
|
368
|
-
if (previousConversationId !== nextConversationId) {
|
|
369
|
-
pendingConversationScrollIdRef.current = nextConversationId;
|
|
370
|
-
setIsAtBottom(true);
|
|
371
|
-
}
|
|
372
|
-
if (!nextConversationId ||
|
|
373
|
-
pendingConversationScrollIdRef.current !== nextConversationId ||
|
|
374
|
-
!isExpanded ||
|
|
375
|
-
listItems.length === 0) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
scrollToBottom(false);
|
|
379
|
-
pendingConversationScrollIdRef.current = null;
|
|
380
|
-
}, [currentConversationId, isExpanded, listItems.length, scrollToBottom]);
|
|
381
|
-
useEffect(() => {
|
|
382
|
-
if (prevScrollToBottomSignalRef.current !== scrollToBottomSignal) {
|
|
383
|
-
prevScrollToBottomSignalRef.current = scrollToBottomSignal;
|
|
384
|
-
hasPendingScrollToBottomSignalRef.current = true;
|
|
385
|
-
setIsAtBottom(true);
|
|
386
|
-
}
|
|
387
|
-
if (!hasPendingScrollToBottomSignalRef.current ||
|
|
388
|
-
!isExpanded ||
|
|
389
|
-
listItems.length === 0) {
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
scrollToBottom(false);
|
|
393
|
-
hasPendingScrollToBottomSignalRef.current = false;
|
|
394
|
-
}, [isExpanded, listItems.length, scrollToBottom, scrollToBottomSignal]);
|
|
395
|
-
// Scroll to bottom on new messages if the user is already at bottom
|
|
396
|
-
useEffect(() => {
|
|
397
|
-
const previousMessageCount = prevMessageCountRef.current;
|
|
398
|
-
const hasNewMessage = messages.length > previousMessageCount;
|
|
399
|
-
prevMessageCountRef.current = messages.length;
|
|
400
|
-
if (!isExpanded || !isAtBottom) {
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
scrollToBottom(hasNewMessage);
|
|
404
|
-
return () => {
|
|
405
|
-
if (scrollRafRef.current !== null) {
|
|
406
|
-
cancelAnimationFrame(scrollRafRef.current);
|
|
407
|
-
scrollRafRef.current = null;
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
}, [isAtBottom, isExpanded, messages.length, scrollToBottom]);
|
|
428
|
+
if (isFullScreen && !isMinimized) {
|
|
429
|
+
const selectedConversation = conversations?.find((conversation) => conversation.id === currentConversationId);
|
|
430
|
+
return (_jsx(Dialog, { open: true, onOpenChange: () => undefined, children: _jsxs(DialogContent, { "data-moldable-chat-fullscreen": true, "data-chat-drop-target": true, showCloseButton: false, "aria-describedby": undefined, onInteractOutside: (event) => {
|
|
431
|
+
if (isToastInteractionTarget(event.target)) {
|
|
432
|
+
event.preventDefault();
|
|
433
|
+
}
|
|
434
|
+
}, onEscapeKeyDown: (event) => {
|
|
435
|
+
event.preventDefault();
|
|
436
|
+
onFullScreenChange?.(false);
|
|
437
|
+
}, onCloseAutoFocus: (event) => {
|
|
438
|
+
event.preventDefault();
|
|
439
|
+
window.requestAnimationFrame(() => {
|
|
440
|
+
fullScreenTriggerRef.current?.focus();
|
|
441
|
+
});
|
|
442
|
+
}, className: "bottom-1 left-1 right-1 top-1 z-50 flex h-auto w-auto max-w-none translate-x-0 translate-y-0 gap-0 overflow-hidden rounded-lg border-0 p-0 sm:max-w-none", 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-sm font-medium", children: "Drop images to attach" }), _jsx("p", { className: "text-muted-foreground text-xs", children: "They stay on disk and are read when sent" })] })] })), _jsxs("aside", { className: "border-border bg-muted/50 relative z-10 flex w-[280px] shrink-0 flex-col overflow-hidden rounded-r-lg border-r px-3 pb-4 pt-11", children: [_jsxs("button", { type: "button", onClick: () => onFullScreenChange?.(false), className: "text-muted-foreground hover:text-foreground mb-4 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-2 text-sm 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: "truncate text-sm 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-full 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 mb-2 rounded-xl border p-3", children: [_jsxs("div", { className: "text-muted-foreground mb-2 flex items-center gap-2 text-xs 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
|
+
}
|
|
411
444
|
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: {
|
|
412
445
|
width: isExpanded ? 'min(90vw, 640px)' : '400px',
|
|
413
446
|
y: isMinimized ? 'calc(100% + 24px)' : 0,
|
|
@@ -437,7 +470,7 @@ export function ChatPanel({ messages, status, isTurnInFlight, input, onInputChan
|
|
|
437
470
|
} })), _jsxs("div", { className: "relative z-10 overflow-hidden rounded-[inherit]", children: [_jsxs(motion.div, { initial: false, animate: {
|
|
438
471
|
height: isExpanded ? 'min(60vh, 480px)' : '0px',
|
|
439
472
|
opacity: isExpanded ? 1 : 0,
|
|
440
|
-
}, transition: { type: 'tween', duration: 0.2, ease: 'easeOut' }, className: "flex flex-col overflow-hidden", style: { pointerEvents: isExpanded ? 'auto' : 'none' }, children: [
|
|
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-2 top-2 z-20 grid grid-cols-1 gap-0.5", "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-sm", onClick: () => onFullScreenChange(true), "aria-label": "Enter full screen", className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(Maximize2, { className: "size-4" }) }) }), _jsx(TooltipContent, { side: "bottom", children: "Full screen" })] }) })), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", onClick: handleMinimize, className: "text-muted-foreground hover:text-foreground cursor-pointer", children: _jsx(ChevronDown, { className: "size-4" }) }) }), _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-full 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: () => {
|
|
441
474
|
if (!isExpanded) {
|
|
442
475
|
onExpandedChange(true);
|
|
443
476
|
}
|