Repository navigation
feat(web-shell): refine file cards and configure drop destination #11298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b00d0d9
f2f3226
5af0f75
d3cfbff
8ce28f3
3dbc144
f9ff2cd
04028cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Web Shell attachment and file reference cards | ||
|
|
||
| Attachments currently render as single-line chips. Render pending and sent file | ||
| attachments as rounded cards with an inset file-type icon and a filename/type | ||
| stack, matching the supplied reference. Workspace upload progress retains its | ||
| status and cancel action. Completed uploads still insert ordinary file references. | ||
|
|
||
| File references remain compact icon-and-title chips in the composer and sent | ||
| messages, sharing the existing FileTypeIcon mapping used by artifacts. Preserve | ||
| custom renderers/icons, directory semantics, full-path serialization, preview, | ||
| removal, keyboard access, image thumbnails, and theme isolation. | ||
|
|
||
| Changes are confined to Web Shell presentation, shared attachment content, and | ||
| focused regression tests. No daemon, transport, or artifact behavior changes. | ||
|
|
||
| FileTypeIcon shares the existing artifact | ||
| component's format resolver and URL map; formats without specific artwork keep | ||
| the existing Lucide fallback. The outer SVG preserves existing sizing, CSS and | ||
| ARIA props while referencing the same asset as artifact cards. | ||
|
|
||
| The shared artwork intentionally keeps its format colors across file icon consumers, | ||
| including artifact file tabs, queued prompts and the environment panel. Lucide | ||
| stroke styling continues to apply to formats without dedicated artwork. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Default file drop action | ||
|
|
||
| Expose `fileDropAction?: 'upload' | 'attach'` on WebShell and its shared | ||
| customization context so main and split composers behave identically. Omission | ||
| preserves the choice dialog when both destinations are available. A configured | ||
| available destination runs immediately; if only one destination is available, | ||
| use it regardless of the preference. Neither available means no ingestion. | ||
|
|
||
| Workspace upload still requires the existing capability, selected workspace and | ||
| trust checks. Attachment availability remains governed by `attachmentsEnabled`. | ||
| `fileUploadEnabled=false` disables workspace upload without disabling attachments. | ||
| Keep the add menu's attachment availability consistent with drag-and-drop. | ||
| Cancel a pending choice if availability, default action, session or workspace | ||
| changes; do not apply an old drop to a newly selected destination. | ||
|
|
||
| Use existing upload and attachment ingestion callbacks. Preserve batch filtering, | ||
| drop cancellation, disabled behavior, image paste, and upload directory handling. | ||
| Validate the routing matrix with component tests and public prop/context tests; | ||
| use mocked browser drag events for direct-action and dialog flows. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2154,13 +2154,12 @@ | |
| position: relative; | ||
| display: inline-flex; | ||
| align-items: center; | ||
| gap: 6px; | ||
| max-width: 240px; | ||
| padding: 4px 8px; | ||
| box-sizing: border-box; | ||
| width: 272px; | ||
| max-width: 100%; | ||
| padding: 8px 32px 8px 8px; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keeping the existing scrollable attachment height budget in this PR. More card content requires scrolling, and the parent composer height still constrains short viewports even with a larger budget. The proposed combined-occupancy resize is deferred; no height change is claimed here. |
||
| border: 1px solid var(--chat-editor-border-color); | ||
| border-radius: 6px; | ||
| font-size: 12px; | ||
| line-height: 16px; | ||
| border-radius: 16px; | ||
| color: var(--chat-editor-text-primary); | ||
| } | ||
|
|
||
|
|
@@ -2176,8 +2175,9 @@ | |
| .fileChipPreview { | ||
| display: inline-flex; | ||
| min-width: 0; | ||
| width: 100%; | ||
| align-items: center; | ||
| gap: 6px; | ||
| gap: 12px; | ||
| padding: 0; | ||
| border: 0; | ||
| background: transparent; | ||
|
|
@@ -2190,39 +2190,17 @@ | |
| cursor: default; | ||
| } | ||
|
|
||
| .fileChipIcon { | ||
| flex: 0 0 auto; | ||
| color: var(--chat-editor-text-secondary, currentColor); | ||
| } | ||
|
|
||
| .fileChipName { | ||
| min-width: 0; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| } | ||
|
|
||
| .fileChipRemove { | ||
| position: absolute; | ||
| top: 50%; | ||
| right: 4px; | ||
| top: 8px; | ||
| right: 8px; | ||
| z-index: 1; | ||
| transform: translateY(-50%); | ||
| pointer-events: none; | ||
| } | ||
|
|
||
| .fileChip:hover .fileChipRemove:not(:disabled), | ||
| .fileChipRemove:focus-visible { | ||
| width: 20px; | ||
| height: 20px; | ||
| opacity: 1; | ||
| pointer-events: auto; | ||
| } | ||
|
|
||
| @media (hover: none) { | ||
| .fileChipRemove:not(:disabled) { | ||
| opacity: 1; | ||
| pointer-events: auto; | ||
| } | ||
| } | ||
|
|
||
| .searchPanel { | ||
| display: flex; | ||
| flex-direction: column; | ||
|
|
@@ -2341,24 +2319,18 @@ | |
| align-items: center; | ||
| gap: 10px; | ||
| min-width: 0; | ||
| padding: 7px 10px; | ||
| border: 1px solid color-mix(in srgb, var(--agent-blue-500) 24%, transparent); | ||
| box-sizing: border-box; | ||
| width: 100%; | ||
| max-width: 100%; | ||
| padding: 8px; | ||
| border: 1px solid var(--chat-editor-border-color); | ||
| border-radius: 10px; | ||
| background: color-mix( | ||
| in srgb, | ||
| var(--agent-blue-500) 8%, | ||
| var(--chat-editor-bg-primary) | ||
| ); | ||
| background: var(--chat-editor-bg-primary); | ||
| color: var(--chat-editor-text-primary); | ||
| font-size: 12px; | ||
| line-height: 1.4; | ||
| } | ||
|
|
||
| .uploadRow[data-status='done'] { | ||
| border-color: color-mix(in srgb, var(--success-color) 24%, transparent); | ||
| background: var(--success-bg); | ||
| } | ||
|
|
||
| .uploadRow[data-status='error'] { | ||
| border-color: var(--error-border); | ||
| background: var(--error-bg); | ||
|
|
@@ -2387,11 +2359,25 @@ | |
| font: inherit; | ||
| } | ||
|
|
||
| .uploadRowIcon { | ||
| flex: 0 0 auto; | ||
| } | ||
|
|
||
| .uploadRowName { | ||
| flex: 1 1 auto; | ||
| min-width: 0; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| text-align: left; | ||
| } | ||
|
|
||
| .uploadRowPreview:disabled { | ||
| cursor: default; | ||
| } | ||
|
|
||
| .uploadRow svg { | ||
| .uploadRowAction svg, | ||
| .uploadRowSpinner { | ||
| flex: 0 0 auto; | ||
| width: 14px; | ||
| height: 14px; | ||
|
|
@@ -2416,41 +2402,28 @@ | |
| } | ||
| } | ||
|
|
||
| .uploadRowName { | ||
| .uploadRowStatus { | ||
|
ytahdn marked this conversation as resolved.
Resolved
|
||
| display: inline-flex; | ||
| align-items: center; | ||
| gap: 4px; | ||
| min-width: 0; | ||
| flex: 0 1 auto; | ||
| max-width: 40%; | ||
| flex: 0 0 auto; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| font-family: var(--font-mono); | ||
| color: var(--chat-editor-text-dimmed); | ||
| } | ||
|
|
||
| .uploadRowStatus { | ||
| .uploadRowStatusText { | ||
| min-width: 0; | ||
| flex: 1 1 auto; | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| white-space: nowrap; | ||
| color: var(--chat-editor-text-dimmed); | ||
| text-align: right; | ||
| } | ||
|
|
||
| .uploadRow[data-status='error'] .uploadRowStatus { | ||
| color: var(--error-color); | ||
| } | ||
|
|
||
| .uploadRow[data-status='done'] .uploadRowStatus { | ||
| color: var(--success-color); | ||
| } | ||
|
|
||
| .uploadRow[data-status='done'] .uploadRowPreview > svg { | ||
| color: var(--success-color); | ||
| } | ||
|
|
||
| .uploadRow[data-status='error'] .uploadRowPreview > svg { | ||
| color: var(--error-color); | ||
| } | ||
|
|
||
| .uploadRowAction { | ||
| display: inline-flex; | ||
| align-items: center; | ||
|
|
@@ -2490,3 +2463,16 @@ | |
| font-size: 13px; | ||
| pointer-events: none; | ||
| } | ||
|
|
||
| .fileTag { | ||
| background: var(--chat-editor-bg-primary); | ||
| min-height: 28px; | ||
| border-radius: 8px; | ||
| font-family: var(--font-sans, system-ui, sans-serif); | ||
| } | ||
|
|
||
| .fileTagIcon { | ||
| flex: 0 0 auto; | ||
| margin-left: 8px; | ||
| color: var(--muted-foreground); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.