@opengeni/react 0.46.1 → 0.52.1
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/README.md +158 -14
- package/dist/artifacts-document.d.ts +3 -0
- package/dist/artifacts-document.js +17 -0
- package/dist/artifacts-document.js.map +1 -0
- package/dist/artifacts-presentation.d.ts +3 -0
- package/dist/artifacts-presentation.js +17 -0
- package/dist/artifacts-presentation.js.map +1 -0
- package/dist/artifacts-spreadsheet.d.ts +3 -0
- package/dist/artifacts-spreadsheet.js +17 -0
- package/dist/artifacts-spreadsheet.js.map +1 -0
- package/dist/artifacts.d.ts +2 -0
- package/dist/artifacts.js +170 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/chunk-6BBWWOOU.js +82 -0
- package/dist/chunk-6BBWWOOU.js.map +1 -0
- package/dist/{chunk-HFO4ERGQ.js → chunk-724BW4TW.js} +586 -35
- package/dist/chunk-724BW4TW.js.map +1 -0
- package/dist/chunk-7I2KB3OK.js +3895 -0
- package/dist/chunk-7I2KB3OK.js.map +1 -0
- package/dist/chunk-7WCLAEFV.js +2828 -0
- package/dist/chunk-7WCLAEFV.js.map +1 -0
- package/dist/{chunk-U3CSCMWA.js → chunk-FK6VG4LL.js} +9 -13
- package/dist/chunk-FK6VG4LL.js.map +1 -0
- package/dist/{chunk-SRFUT2ZU.js → chunk-FWS3KC3Z.js} +120 -64
- package/dist/chunk-FWS3KC3Z.js.map +1 -0
- package/dist/{chunk-EKZH6IDG.js → chunk-HDBG7XGO.js} +62 -1
- package/dist/chunk-HDBG7XGO.js.map +1 -0
- package/dist/chunk-HUIKIDM5.js +2148 -0
- package/dist/chunk-HUIKIDM5.js.map +1 -0
- package/dist/{chunk-LGVMUIRV.js → chunk-JAGDUCZQ.js} +1053 -390
- package/dist/chunk-JAGDUCZQ.js.map +1 -0
- package/dist/{chunk-LWR4MXSS.js → chunk-JR3QFY6B.js} +420 -35
- package/dist/chunk-JR3QFY6B.js.map +1 -0
- package/dist/chunk-JVYQRRC4.js +53 -0
- package/dist/chunk-JVYQRRC4.js.map +1 -0
- package/dist/chunk-KCGXPP5V.js +157 -0
- package/dist/chunk-KCGXPP5V.js.map +1 -0
- package/dist/{chunk-EB67J347.js → chunk-KZ73RL76.js} +111 -31
- package/dist/chunk-KZ73RL76.js.map +1 -0
- package/dist/chunk-PEI6RANI.js +3234 -0
- package/dist/chunk-PEI6RANI.js.map +1 -0
- package/dist/{chunk-3PB7MIT6.js → chunk-ROIRTM37.js} +220 -72
- package/dist/chunk-ROIRTM37.js.map +1 -0
- package/dist/chunk-VZTQ73XT.js +86 -0
- package/dist/chunk-VZTQ73XT.js.map +1 -0
- package/dist/{chunk-VCBFUSUZ.js → chunk-WSK7G5LE.js} +72 -4
- package/dist/chunk-WSK7G5LE.js.map +1 -0
- package/dist/{chunk-FGZUCXZF.js → chunk-WYA65Y3F.js} +16 -16
- package/dist/chunk-WYA65Y3F.js.map +1 -0
- package/dist/{chunk-6EDV6YFE.js → chunk-X4S56Y2H.js} +147 -35
- package/dist/chunk-X4S56Y2H.js.map +1 -0
- package/dist/client.d.ts +7 -1
- package/dist/clipboard.d.ts +1 -0
- package/dist/clipboard.js +7 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/commands/index.d.ts +3 -3
- package/dist/commands/registry.d.ts +1 -1
- package/dist/commands/types.d.ts +1 -1
- package/dist/components/approval-surface.d.ts +2 -2
- package/dist/components/artifacts/artifact-surface.d.ts +18 -0
- package/dist/components/artifacts/document-editor.d.ts +172 -0
- package/dist/components/artifacts/editable-artifact-ui.d.ts +13 -0
- package/dist/components/artifacts/editable-artifact-workbench.d.ts +49 -0
- package/dist/components/artifacts/editable-document.d.ts +24 -0
- package/dist/components/artifacts/editable-presentation.d.ts +24 -0
- package/dist/components/artifacts/editable-spreadsheet.d.ts +32 -0
- package/dist/components/artifacts/index.d.ts +8 -0
- package/dist/components/artifacts/presentation-editor.d.ts +297 -0
- package/dist/components/artifacts/spreadsheet-canvas.d.ts +120 -0
- package/dist/components/artifacts/spreadsheet-grid.d.ts +113 -0
- package/dist/components/browser-viewer.d.ts +29 -0
- package/dist/components/chat-composer.d.ts +13 -8
- package/dist/components/code-editor.d.ts +25 -3
- package/dist/components/command-palette.d.ts +2 -2
- package/dist/components/composer-transcription-control.d.ts +4 -2
- package/dist/components/composer.d.ts +29 -15
- package/dist/components/computer-viewer.d.ts +23 -0
- package/dist/components/copy-button.d.ts +2 -2
- package/dist/components/desktop-viewer.d.ts +25 -21
- package/dist/components/diff-view.d.ts +1 -1
- package/dist/components/enrollment-consent.d.ts +1 -1
- package/dist/components/enrollment-device-flow.d.ts +1 -1
- package/dist/components/file-browser.d.ts +2 -2
- package/dist/components/fleet-tile.d.ts +1 -1
- package/dist/components/generated-video-player.d.ts +10 -0
- package/dist/components/human-input-form.d.ts +1 -1
- package/dist/components/human-input-surface.d.ts +2 -2
- package/dist/components/interactive-workbench-viewers.d.ts +2 -0
- package/dist/components/machine-card.d.ts +2 -2
- package/dist/components/machine-dock-bar.d.ts +3 -3
- package/dist/components/machine-health-pill.d.ts +2 -2
- package/dist/components/machine-input-display.d.ts +1 -1
- package/dist/components/machine-metrics.d.ts +2 -2
- package/dist/components/machine-status-pill.d.ts +4 -4
- package/dist/components/machines/health.d.ts +1 -1
- package/dist/components/machines/machine-detail.d.ts +5 -3
- package/dist/components/machines/metric-history-chart.d.ts +1 -1
- package/dist/components/machines/metric-sparkline.d.ts +2 -2
- package/dist/components/machines/series.d.ts +2 -2
- package/dist/components/machines-dashboard.d.ts +5 -5
- package/dist/components/markdown.d.ts +1 -1
- package/dist/components/message-timeline.d.ts +22 -5
- package/dist/components/model-picker.d.ts +2 -2
- package/dist/components/model-policy-picker.d.ts +7 -7
- package/dist/components/pierre-diff.d.ts +1 -1
- package/dist/components/pierre-file.d.ts +1 -1
- package/dist/components/queue-draft-policy.d.ts +1 -1
- package/dist/components/queue-surface-implementation.d.ts +3 -3
- package/dist/components/queue-surface-state.d.ts +4 -4
- package/dist/components/queue-surface.d.ts +5 -5
- package/dist/components/sandbox-files.d.ts +5 -5
- package/dist/components/sandbox-terminal.d.ts +50 -4
- package/dist/components/sandbox-workspace.d.ts +30 -10
- package/dist/components/session-chrome.d.ts +4 -4
- package/dist/components/session-status.d.ts +2 -2
- package/dist/components/timeline-annotation-selection.d.ts +9 -0
- package/dist/components/timeline-annotations-dialog.d.ts +16 -0
- package/dist/components/timeline-annotations.d.ts +13 -0
- package/dist/components/tooltip.d.ts +4 -4
- package/dist/components/user-message-body.d.ts +2 -2
- package/dist/components/workbench-changes.d.ts +2 -2
- package/dist/components/workspace-dock.d.ts +3 -1
- package/dist/composer.d.ts +11 -11
- package/dist/composer.js +7 -7
- package/dist/hooks/internal.d.ts +7 -1
- package/dist/hooks/use-attached-browsers.d.ts +21 -0
- package/dist/hooks/use-available-models.d.ts +2 -2
- package/dist/hooks/use-billing-usage.d.ts +1 -1
- package/dist/hooks/use-browser-frame-stream.d.ts +28 -0
- package/dist/hooks/use-browser-identities.d.ts +26 -0
- package/dist/hooks/use-browser-session.d.ts +28 -0
- package/dist/hooks/use-browser-sessions.d.ts +32 -0
- package/dist/hooks/use-codex-accounts.d.ts +3 -3
- package/dist/hooks/use-composer.d.ts +36 -9
- package/dist/hooks/use-computer-frame-stream.d.ts +24 -0
- package/dist/hooks/use-computer-session.d.ts +28 -0
- package/dist/hooks/use-computer-sessions.d.ts +28 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-environments.d.ts +11 -5
- package/dist/hooks/use-file-attachments.d.ts +1 -1
- package/dist/hooks/use-goal.d.ts +2 -2
- package/dist/hooks/use-human-input.d.ts +2 -2
- package/dist/hooks/use-last-started-turn-policy.d.ts +2 -2
- package/dist/hooks/use-machine-chip.d.ts +2 -2
- package/dist/hooks/use-machines.d.ts +10 -3
- package/dist/hooks/use-packs.d.ts +7 -2
- package/dist/hooks/use-rigs.d.ts +1 -1
- package/dist/hooks/use-sandbox-files.d.ts +25 -4
- package/dist/hooks/use-sandbox-git.d.ts +13 -5
- package/dist/hooks/use-sandbox-terminal.d.ts +1 -1
- package/dist/hooks/use-scheduled-tasks.d.ts +1 -1
- package/dist/hooks/use-session-capabilities.d.ts +5 -4
- package/dist/hooks/use-session-control.d.ts +1 -1
- package/dist/hooks/use-session-events.d.ts +2 -2
- package/dist/hooks/use-session-lineage.d.ts +1 -1
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session.d.ts +2 -2
- package/dist/hooks/use-slash-commands.d.ts +1 -1
- package/dist/hooks/use-terminal-stream.d.ts +8 -2
- package/dist/hooks/use-transcription.d.ts +2 -2
- package/dist/hooks/use-turn-queue.d.ts +2 -2
- package/dist/hooks/use-video-artifact-playback.d.ts +9 -0
- package/dist/hooks/use-voice-input.d.ts +6 -4
- package/dist/hooks/use-workspace-capture.d.ts +1 -1
- package/dist/hooks/use-workspace-edit.d.ts +1 -1
- package/dist/hooks/use-workspace-sessions.d.ts +1 -1
- package/dist/hooks/use-workspaces.d.ts +1 -1
- package/dist/index.d.ts +158 -154
- package/dist/index.js +1718 -908
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +23 -0
- package/dist/interaction.js +36 -0
- package/dist/interaction.js.map +1 -0
- package/dist/interactive-workbench-viewers-KHNOHWQE.js +13 -0
- package/dist/interactive-workbench-viewers-KHNOHWQE.js.map +1 -0
- package/dist/lib/composer-responsive-context.d.ts +9 -0
- package/dist/lib/relay-wire.d.ts +4 -0
- package/dist/lib/sandbox-liveness.d.ts +9 -0
- package/dist/lib/terminal-capability.d.ts +5 -0
- package/dist/lib/use-portal-token-style.d.ts +14 -3
- package/dist/lib/xterm-theme.d.ts +1 -1
- package/dist/machines.d.ts +30 -30
- package/dist/machines.js +3 -3
- package/dist/provider.d.ts +4 -4
- package/dist/{queue-surface-implementation-J4XJFKRW.js → queue-surface-implementation-2KVJTYXH.js} +117 -64
- package/dist/queue-surface-implementation-2KVJTYXH.js.map +1 -0
- package/dist/realtime/dropdown-menu.d.ts +8 -8
- package/dist/realtime/realtime-control.d.ts +15 -6
- package/dist/realtime.d.ts +4 -4
- package/dist/realtime.js +30 -33
- package/dist/realtime.js.map +1 -1
- package/dist/session-context.d.ts +19 -1
- package/dist/session-ui.d.ts +14 -14
- package/dist/session-ui.js +6 -5
- package/dist/session.d.ts +28 -28
- package/dist/session.js +5 -5
- package/dist/timeline/activity-rail.d.ts +6 -3
- package/dist/timeline/disclosure-context.d.ts +1 -1
- package/dist/timeline/fleet-decision-projection.d.ts +1 -1
- package/dist/timeline/fleet-decision-row.d.ts +3 -3
- package/dist/timeline/index.d.ts +19 -19
- package/dist/timeline/parsers.d.ts +6 -3
- package/dist/timeline/projection.d.ts +3 -3
- package/dist/timeline/registry.d.ts +10 -1
- package/dist/timeline/screenshot-lightbox.d.ts +2 -2
- package/dist/timeline/shared.d.ts +21 -10
- package/dist/timeline/tool-diff.d.ts +2 -2
- package/dist/timeline/tool-renderers.d.ts +1 -1
- package/dist/timeline/turn-summary.d.ts +3 -3
- package/dist/timeline/types.d.ts +42 -2
- package/dist/timeline-annotation-selection-3L7LHGG2.js +187 -0
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +1 -0
- package/dist/timeline-annotations-dialog-U7EVLR75.js +196 -0
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +1 -0
- package/dist/voice-recording-store.d.ts +8 -2
- package/package.json +52 -7
- package/src/artifacts-document.ts +31 -0
- package/src/artifacts-presentation.ts +36 -0
- package/src/artifacts-spreadsheet.ts +21 -0
- package/src/artifacts.ts +86 -0
- package/src/client.ts +90 -1
- package/src/clipboard.ts +2 -0
- package/src/components/artifacts/artifact-surface.tsx +93 -0
- package/src/components/artifacts/document-editor.tsx +2255 -0
- package/src/components/artifacts/editable-artifact-ui.tsx +89 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +203 -0
- package/src/components/artifacts/editable-document.tsx +657 -0
- package/src/components/artifacts/editable-presentation.tsx +1020 -0
- package/src/components/artifacts/editable-spreadsheet.tsx +733 -0
- package/src/components/artifacts/index.ts +99 -0
- package/src/components/artifacts/presentation-editor.tsx +3148 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +799 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +2129 -0
- package/src/components/browser-viewer.tsx +1592 -0
- package/src/components/chat-composer.tsx +25 -2
- package/src/components/code-editor.tsx +90 -31
- package/src/components/command-palette.tsx +1 -1
- package/src/components/composer-transcription-control.tsx +51 -22
- package/src/components/composer.tsx +49 -23
- package/src/components/computer-viewer.tsx +1139 -0
- package/src/components/copy-button.tsx +1 -1
- package/src/components/desktop-viewer.tsx +103 -75
- package/src/components/file-browser.tsx +39 -17
- package/src/components/generated-video-player.tsx +89 -0
- package/src/components/human-input-form.tsx +2 -2
- package/src/components/interactive-workbench-viewers.ts +2 -0
- package/src/components/machine-card.tsx +1 -1
- package/src/components/machine-input-display.ts +3 -0
- package/src/components/machines/machine-detail.tsx +39 -15
- package/src/components/machines-dashboard.tsx +7 -6
- package/src/components/message-timeline.tsx +327 -37
- package/src/components/model-picker.tsx +2 -2
- package/src/components/model-policy-picker.tsx +16 -15
- package/src/components/queue-surface-implementation.tsx +135 -75
- package/src/components/queue-surface-state.tsx +2 -2
- package/src/components/sandbox-files.tsx +142 -62
- package/src/components/sandbox-terminal.tsx +119 -35
- package/src/components/sandbox-workspace.tsx +394 -228
- package/src/components/session-chrome.tsx +67 -27
- package/src/components/timeline-annotation-selection.tsx +221 -0
- package/src/components/timeline-annotations-dialog.tsx +213 -0
- package/src/components/timeline-annotations.tsx +84 -0
- package/src/components/tooltip.tsx +13 -16
- package/src/components/user-message-body.tsx +1 -1
- package/src/components/workbench-changes.tsx +192 -35
- package/src/components/workspace-dock.tsx +13 -5
- package/src/composer.ts +3 -0
- package/src/hooks/internal.ts +132 -38
- package/src/hooks/use-attached-browsers.ts +152 -0
- package/src/hooks/use-browser-frame-stream.ts +316 -0
- package/src/hooks/use-browser-identities.ts +225 -0
- package/src/hooks/use-browser-session.ts +476 -0
- package/src/hooks/use-browser-sessions.ts +281 -0
- package/src/hooks/use-codex-accounts.ts +4 -4
- package/src/hooks/use-composer.ts +769 -24
- package/src/hooks/use-computer-frame-stream.ts +311 -0
- package/src/hooks/use-computer-session.ts +442 -0
- package/src/hooks/use-computer-sessions.ts +245 -0
- package/src/hooks/use-environments.ts +24 -5
- package/src/hooks/use-file-attachments.ts +70 -32
- package/src/hooks/use-goal.ts +17 -5
- package/src/hooks/use-machine-chip.ts +5 -3
- package/src/hooks/use-machines.ts +79 -3
- package/src/hooks/use-packs.ts +51 -0
- package/src/hooks/use-sandbox-files.ts +382 -88
- package/src/hooks/use-sandbox-git.ts +208 -46
- package/src/hooks/use-sandbox-terminal.ts +3 -2
- package/src/hooks/use-session-capabilities.ts +94 -70
- package/src/hooks/use-session-events.ts +18 -4
- package/src/hooks/use-terminal-stream.ts +102 -23
- package/src/hooks/use-transcription.ts +4 -14
- package/src/hooks/use-turn-queue.ts +17 -5
- package/src/hooks/use-video-artifact-playback.ts +28 -0
- package/src/hooks/use-voice-input.ts +163 -19
- package/src/hooks/use-windowed-sections.ts +9 -7
- package/src/hooks/use-workspace-edit.ts +2 -1
- package/src/index.ts +21 -6
- package/src/interaction.ts +71 -0
- package/src/lib/composer-responsive-context.ts +15 -0
- package/src/lib/relay-wire.ts +4 -0
- package/src/lib/sandbox-liveness.ts +11 -0
- package/src/lib/terminal-capability.ts +10 -0
- package/src/lib/use-portal-token-style.ts +60 -15
- package/src/provider.tsx +52 -7
- package/src/realtime/dropdown-menu.tsx +15 -19
- package/src/realtime/realtime-control.tsx +16 -5
- package/src/session-context.ts +90 -0
- package/src/timeline/activity-rail.tsx +31 -6
- package/src/timeline/index.ts +4 -1
- package/src/timeline/parsers.ts +46 -20
- package/src/timeline/projection.ts +233 -13
- package/src/timeline/registry.ts +19 -0
- package/src/timeline/screenshot-lightbox.tsx +30 -9
- package/src/timeline/shared.tsx +59 -11
- package/src/timeline/tool-renderers.tsx +421 -24
- package/src/timeline/turn-summary.tsx +2 -2
- package/src/timeline/types.ts +58 -2
- package/src/voice-recording-store.ts +15 -0
- package/styles/compiled.css +5298 -0
- package/styles/compiled.d.ts +2 -0
- package/styles/effective-tokens.css +27 -0
- package/styles/index.css +18 -0
- package/styles/responsive.css +208 -0
- package/styles/responsive.d.ts +2 -0
- package/styles/tokens.css +50 -17
- package/dist/chunk-3PB7MIT6.js.map +0 -1
- package/dist/chunk-6EDV6YFE.js.map +0 -1
- package/dist/chunk-EB67J347.js.map +0 -1
- package/dist/chunk-EKZH6IDG.js.map +0 -1
- package/dist/chunk-FGZUCXZF.js.map +0 -1
- package/dist/chunk-HFO4ERGQ.js.map +0 -1
- package/dist/chunk-JB5725BI.js +0 -48
- package/dist/chunk-JB5725BI.js.map +0 -1
- package/dist/chunk-LGVMUIRV.js.map +0 -1
- package/dist/chunk-LWR4MXSS.js.map +0 -1
- package/dist/chunk-SRFUT2ZU.js.map +0 -1
- package/dist/chunk-U3CSCMWA.js.map +0 -1
- package/dist/chunk-VCBFUSUZ.js.map +0 -1
- package/dist/fleet-decision-projection-SLNZMS42.js +0 -241
- package/dist/fleet-decision-projection-SLNZMS42.js.map +0 -1
- package/dist/queue-surface-implementation-J4XJFKRW.js.map +0 -1
|
@@ -29,16 +29,23 @@ import {
|
|
|
29
29
|
useChatComposerController,
|
|
30
30
|
type ChatComposerMessages,
|
|
31
31
|
type ComposerControlLinks,
|
|
32
|
+
type ResponsiveBasis,
|
|
32
33
|
} from "./composer";
|
|
33
34
|
import {
|
|
34
35
|
ComposerTranscriptionControl,
|
|
35
36
|
type ComposerTranscriptionControlProps,
|
|
36
37
|
} from "./composer-transcription-control";
|
|
38
|
+
import { TimelineAnnotationsChip } from "./timeline-annotations";
|
|
37
39
|
|
|
38
40
|
export { OPEN_WORKSTREAM_CONTROL_EVENT };
|
|
39
41
|
|
|
40
42
|
export type ChatComposerProps = {
|
|
41
43
|
composer: ComposerState;
|
|
44
|
+
/**
|
|
45
|
+
* Measurement surface for responsive chrome. Defaults to the historical
|
|
46
|
+
* viewport breakpoints; opt into `container` for narrow embedded panels.
|
|
47
|
+
*/
|
|
48
|
+
responsiveBasis?: ResponsiveBasis | undefined;
|
|
42
49
|
/** Canonical workstream control, separate from lifecycle status. */
|
|
43
50
|
effectiveControl?: EffectiveSessionControl | null | undefined;
|
|
44
51
|
/** Waiting prompts already ahead of a normal Send. */
|
|
@@ -91,6 +98,7 @@ export type ChatComposerProps = {
|
|
|
91
98
|
*/
|
|
92
99
|
export function ChatComposer({
|
|
93
100
|
composer,
|
|
101
|
+
responsiveBasis,
|
|
94
102
|
effectiveControl,
|
|
95
103
|
queuedAheadCount,
|
|
96
104
|
canControlWorkspace,
|
|
@@ -140,7 +148,7 @@ export function ChatComposer({
|
|
|
140
148
|
const stackActions = hasControls && Boolean(actionsStart);
|
|
141
149
|
|
|
142
150
|
return (
|
|
143
|
-
<Root controller={controller} className={className}>
|
|
151
|
+
<Root controller={controller} responsiveBasis={responsiveBasis} className={className}>
|
|
144
152
|
<Frame>
|
|
145
153
|
<CommandPalette />
|
|
146
154
|
<Surface>
|
|
@@ -148,11 +156,26 @@ export function ChatComposer({
|
|
|
148
156
|
<RestoredResources />
|
|
149
157
|
<Attachments />
|
|
150
158
|
{header}
|
|
159
|
+
{composer.annotations && composer.annotations.length > 0 ? (
|
|
160
|
+
<div className="px-3 pt-2 sm:px-4">
|
|
161
|
+
<TimelineAnnotationsChip
|
|
162
|
+
annotations={composer.annotations}
|
|
163
|
+
editable
|
|
164
|
+
focusAnnotationId={composer.annotationReviewTargetId}
|
|
165
|
+
onFocusConsumed={composer.clearAnnotationReviewTarget}
|
|
166
|
+
onUpdate={composer.updateAnnotation}
|
|
167
|
+
onRemove={composer.removeAnnotation}
|
|
168
|
+
/>
|
|
169
|
+
</div>
|
|
170
|
+
) : null}
|
|
151
171
|
<Input placeholder={placeholder} autoFocus={autoFocus} />
|
|
152
172
|
{controller.confirmState ? (
|
|
153
173
|
<Confirmation />
|
|
154
174
|
) : (
|
|
155
|
-
<Footer
|
|
175
|
+
<Footer
|
|
176
|
+
data-og-stack-actions={stackActions ? "" : undefined}
|
|
177
|
+
className={stackActions ? "max-sm:flex-nowrap sm:flex-wrap" : undefined}
|
|
178
|
+
>
|
|
156
179
|
<LayoutGroup id="og-composer-footer">
|
|
157
180
|
{hasControls ? (
|
|
158
181
|
<Controls
|
|
@@ -95,8 +95,13 @@ export type CodeEditorProps = {
|
|
|
95
95
|
path: string;
|
|
96
96
|
/** The decoded text contents to seed the editor with. */
|
|
97
97
|
initialContents: string;
|
|
98
|
-
/**
|
|
99
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Persist the current buffer against the exact contents it was edited from.
|
|
100
|
+
* The second argument is the immutable compare-and-swap baseline; hosts must
|
|
101
|
+
* not replace it with a newer remote snapshot or concurrent writes can be
|
|
102
|
+
* silently overwritten.
|
|
103
|
+
*/
|
|
104
|
+
onSave: (contents: string, expectedContents: string) => Promise<unknown>;
|
|
100
105
|
/** Explicitly overwrite after a visible expected-content conflict. */
|
|
101
106
|
onOverwrite?: ((contents: string) => Promise<unknown>) | undefined;
|
|
102
107
|
/** Re-read the selected file after a visible save conflict. */
|
|
@@ -115,6 +120,41 @@ export type CodeEditorProps = {
|
|
|
115
120
|
className?: string | undefined;
|
|
116
121
|
};
|
|
117
122
|
|
|
123
|
+
export type EditorBufferState = {
|
|
124
|
+
path: string;
|
|
125
|
+
value: string;
|
|
126
|
+
baseline: string;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Reconcile a remote file snapshot without destroying unsaved local work.
|
|
131
|
+
*
|
|
132
|
+
* A different path is a new document and always resets. For the same path, a
|
|
133
|
+
* clean editor follows the remote snapshot while a dirty editor retains both
|
|
134
|
+
* its local value and the original CAS baseline. The eventual save will then
|
|
135
|
+
* either succeed against that baseline or surface a typed conflict.
|
|
136
|
+
*/
|
|
137
|
+
export function reconcileEditorBuffer(
|
|
138
|
+
current: EditorBufferState,
|
|
139
|
+
incoming: { path: string; contents: string },
|
|
140
|
+
): EditorBufferState {
|
|
141
|
+
if (current.path === incoming.path && current.value !== current.baseline) {
|
|
142
|
+
return current;
|
|
143
|
+
}
|
|
144
|
+
if (
|
|
145
|
+
current.path === incoming.path &&
|
|
146
|
+
current.value === incoming.contents &&
|
|
147
|
+
current.baseline === incoming.contents
|
|
148
|
+
) {
|
|
149
|
+
return current;
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
path: incoming.path,
|
|
153
|
+
value: incoming.contents,
|
|
154
|
+
baseline: incoming.contents,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
118
158
|
/**
|
|
119
159
|
* The EDITABLE single-file pane: CodeMirror 6 with a per-language grammar chosen
|
|
120
160
|
* from the filename, og-* themed, with dirty tracking and a save path wired to
|
|
@@ -143,42 +183,45 @@ export function CodeEditor({
|
|
|
143
183
|
const [failed, setFailed] = useState(false);
|
|
144
184
|
const [bundle, setBundle] = useState<EditorBundle | null>(null);
|
|
145
185
|
|
|
146
|
-
// The live buffer
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
186
|
+
// The live buffer and its compare-and-swap baseline are one state value so a
|
|
187
|
+
// remote refresh cannot update one without the other.
|
|
188
|
+
const [buffer, setBuffer] = useState<EditorBufferState>(() => ({
|
|
189
|
+
path,
|
|
190
|
+
value: initialContents,
|
|
191
|
+
baseline: initialContents,
|
|
192
|
+
}));
|
|
193
|
+
const { value, baseline } = buffer;
|
|
151
194
|
const [saving, setSaving] = useState(false);
|
|
152
195
|
const [saveError, setSaveError] = useState<Error | null>(null);
|
|
153
196
|
const [savedTick, setSavedTick] = useState(false);
|
|
197
|
+
const saveInFlightRef = useRef(false);
|
|
154
198
|
|
|
155
199
|
const dirty = value !== baseline;
|
|
156
200
|
const saveConflict =
|
|
157
201
|
saveError !== null && (saveError as Error & { code?: unknown }).code === "file_write_conflict";
|
|
158
202
|
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
//
|
|
162
|
-
// Fire the wake-on-edit intent at most once per opened file — reset on re-seed.
|
|
203
|
+
// Follow path changes and clean same-file refreshes. Dirty same-file buffers
|
|
204
|
+
// intentionally ignore remote snapshots: the original baseline must survive
|
|
205
|
+
// until guarded save, explicit reload, or navigation.
|
|
163
206
|
const editIntentFiredRef = useRef(false);
|
|
164
|
-
const lastSeed = useRef<{ path: string; contents: string }>({ path, contents: initialContents });
|
|
165
207
|
useEffect(() => {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
208
|
+
setBuffer((current) => reconcileEditorBuffer(current, { path, contents: initialContents }));
|
|
209
|
+
}, [path, initialContents]);
|
|
210
|
+
|
|
211
|
+
// A new document is a new edit-intent/error lifecycle. The normal
|
|
212
|
+
// SandboxFiles host also keys the component by path; this keeps standalone
|
|
213
|
+
// consumers correct without relying on that implementation detail.
|
|
214
|
+
useEffect(() => {
|
|
170
215
|
editIntentFiredRef.current = false;
|
|
171
|
-
setValue(initialContents);
|
|
172
|
-
setBaseline(initialContents);
|
|
173
216
|
setSaveError(null);
|
|
174
217
|
setSavedTick(false);
|
|
175
|
-
}, [path
|
|
218
|
+
}, [path]);
|
|
176
219
|
|
|
177
220
|
// Record a buffer change: the FIRST divergence from the baseline is the edit
|
|
178
221
|
// intent that warms the box (idempotent — latched per opened file).
|
|
179
222
|
const noteEdit = useCallback(
|
|
180
223
|
(next: string) => {
|
|
181
|
-
|
|
224
|
+
setBuffer((current) => ({ ...current, value: next }));
|
|
182
225
|
setSavedTick(false);
|
|
183
226
|
if (!editIntentFiredRef.current && next !== baseline) {
|
|
184
227
|
editIntentFiredRef.current = true;
|
|
@@ -246,40 +289,46 @@ export function CodeEditor({
|
|
|
246
289
|
const saveRef = useRef<() => void>(() => {});
|
|
247
290
|
|
|
248
291
|
const save = useCallback(async () => {
|
|
249
|
-
if (readOnly) return;
|
|
292
|
+
if (readOnly || saveInFlightRef.current) return;
|
|
250
293
|
// Snapshot the buffer at call time so an in-flight edit can't race the write.
|
|
251
294
|
const snapshot = value;
|
|
252
295
|
if (snapshot === baseline) return; // nothing to persist
|
|
296
|
+
saveInFlightRef.current = true;
|
|
253
297
|
setSaving(true);
|
|
254
298
|
setSaveError(null);
|
|
255
299
|
setSavedTick(false);
|
|
256
300
|
try {
|
|
257
|
-
await onSave(snapshot);
|
|
258
|
-
|
|
259
|
-
|
|
301
|
+
await onSave(snapshot, baseline);
|
|
302
|
+
setBuffer((current) =>
|
|
303
|
+
current.path === path ? { ...current, baseline: snapshot } : current,
|
|
304
|
+
);
|
|
260
305
|
setSavedTick(true);
|
|
261
306
|
} catch (cause) {
|
|
262
307
|
setSaveError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
263
308
|
} finally {
|
|
309
|
+
saveInFlightRef.current = false;
|
|
264
310
|
setSaving(false);
|
|
265
311
|
}
|
|
266
312
|
}, [readOnly, value, baseline, onSave, path]);
|
|
267
313
|
|
|
268
314
|
const overwrite = useCallback(async () => {
|
|
269
|
-
if (readOnly || !onOverwrite) return;
|
|
315
|
+
if (readOnly || !onOverwrite || saveInFlightRef.current) return;
|
|
270
316
|
const snapshot = value;
|
|
271
317
|
if (snapshot === baseline) return;
|
|
318
|
+
saveInFlightRef.current = true;
|
|
272
319
|
setSaving(true);
|
|
273
320
|
setSaveError(null);
|
|
274
321
|
setSavedTick(false);
|
|
275
322
|
try {
|
|
276
323
|
await onOverwrite(snapshot);
|
|
277
|
-
|
|
278
|
-
|
|
324
|
+
setBuffer((current) =>
|
|
325
|
+
current.path === path ? { ...current, baseline: snapshot } : current,
|
|
326
|
+
);
|
|
279
327
|
setSavedTick(true);
|
|
280
328
|
} catch (cause) {
|
|
281
329
|
setSaveError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
282
330
|
} finally {
|
|
331
|
+
saveInFlightRef.current = false;
|
|
283
332
|
setSaving(false);
|
|
284
333
|
}
|
|
285
334
|
}, [readOnly, onOverwrite, value, baseline, path]);
|
|
@@ -306,10 +355,19 @@ export function CodeEditor({
|
|
|
306
355
|
|
|
307
356
|
const Editor = bundle?.Editor;
|
|
308
357
|
|
|
358
|
+
const reload = useCallback(() => {
|
|
359
|
+
setBuffer({ path, value: initialContents, baseline: initialContents });
|
|
360
|
+
editIntentFiredRef.current = false;
|
|
361
|
+
setSaveError(null);
|
|
362
|
+
setSavedTick(false);
|
|
363
|
+
onReload?.();
|
|
364
|
+
}, [initialContents, onReload, path]);
|
|
365
|
+
|
|
309
366
|
return (
|
|
310
367
|
<div
|
|
311
368
|
className={cn("flex h-full min-h-0 flex-col", className)}
|
|
312
369
|
data-opengeni-code-editor
|
|
370
|
+
data-opengeni-editor-dirty={dirty ? "true" : "false"}
|
|
313
371
|
style={editorVars}
|
|
314
372
|
>
|
|
315
373
|
{/* Save bar: dirty indicator + status + the explicit Save button. */}
|
|
@@ -334,7 +392,9 @@ export function CodeEditor({
|
|
|
334
392
|
{saveError.message}
|
|
335
393
|
</span>
|
|
336
394
|
)}
|
|
337
|
-
{!saveError && savedTick &&
|
|
395
|
+
{!saveError && savedTick && !dirty && (
|
|
396
|
+
<span className="text-og-xs text-og-status-idle">Saved</span>
|
|
397
|
+
)}
|
|
338
398
|
{readOnly ? (
|
|
339
399
|
<span className="text-og-xs uppercase tracking-wide text-og-fg-subtle">Read-only</span>
|
|
340
400
|
) : !saveConflict ? (
|
|
@@ -375,8 +435,7 @@ export function CodeEditor({
|
|
|
375
435
|
<button
|
|
376
436
|
type="button"
|
|
377
437
|
onClick={() => {
|
|
378
|
-
|
|
379
|
-
onReload();
|
|
438
|
+
reload();
|
|
380
439
|
}}
|
|
381
440
|
className="min-h-8 rounded-og-sm border border-og-border bg-og-surface-1 px-2 text-og-xs font-medium text-og-fg hover:bg-og-surface-2 pointer-coarse:min-h-11"
|
|
382
441
|
>
|
|
@@ -458,7 +517,7 @@ function PlainTextarea({
|
|
|
458
517
|
}
|
|
459
518
|
}}
|
|
460
519
|
aria-label="Plain text file editor"
|
|
461
|
-
className="h-full w-full resize-none bg-transparent p-2 font-og-mono text-og-sm text-og-fg outline-
|
|
520
|
+
className="h-full w-full resize-none bg-transparent p-2 font-og-mono text-og-sm text-og-fg outline-hidden"
|
|
462
521
|
/>
|
|
463
522
|
);
|
|
464
523
|
}
|
|
@@ -101,7 +101,7 @@ export function CommandPalette({
|
|
|
101
101
|
{dangerLabel}
|
|
102
102
|
</span>
|
|
103
103
|
) : null}
|
|
104
|
-
<span className="truncate text-[12px] text-og-fg-subtle max-sm:hidden">
|
|
104
|
+
<span className="og-command-description truncate text-[12px] text-og-fg-subtle max-sm:hidden">
|
|
105
105
|
{command.description}
|
|
106
106
|
</span>
|
|
107
107
|
</span>
|
|
@@ -35,10 +35,12 @@ export type ComposerTranscriptionMessages = {
|
|
|
35
35
|
stop: string;
|
|
36
36
|
cancel: string;
|
|
37
37
|
retry: string;
|
|
38
|
+
pauseRetrying: string;
|
|
38
39
|
requestingPermission: string;
|
|
39
40
|
recording: string;
|
|
40
41
|
saving: string;
|
|
41
42
|
transcribing: string;
|
|
43
|
+
retrying: string;
|
|
42
44
|
recovered: string;
|
|
43
45
|
recoveredTranscript: string;
|
|
44
46
|
insertRecoveredTranscript: string;
|
|
@@ -61,10 +63,12 @@ const defaultMessages: ComposerTranscriptionMessages = {
|
|
|
61
63
|
stop: "Stop and transcribe",
|
|
62
64
|
cancel: "Cancel recording",
|
|
63
65
|
retry: "Retry voice input",
|
|
66
|
+
pauseRetrying: "Pause automatic retry",
|
|
64
67
|
requestingPermission: "Requesting microphone…",
|
|
65
68
|
recording: "Recording. Press Escape to cancel.",
|
|
66
69
|
saving: "Saving audio locally…",
|
|
67
70
|
transcribing: "Transcribing…",
|
|
71
|
+
retrying: "Recording saved. Retrying automatically…",
|
|
68
72
|
recovered: "Recording recovered and saved locally.",
|
|
69
73
|
recoveredTranscript: "Transcript saved locally. Check your draft before inserting.",
|
|
70
74
|
insertRecoveredTranscript: "Insert saved transcript",
|
|
@@ -138,6 +142,8 @@ export function ComposerTranscriptionControl({
|
|
|
138
142
|
createOwnerId,
|
|
139
143
|
});
|
|
140
144
|
const { status } = transcription;
|
|
145
|
+
const retrying = status === "retrying";
|
|
146
|
+
const capturing = status === "requesting-permission" || status === "recording";
|
|
141
147
|
|
|
142
148
|
const cancelTranscription = transcription.cancel;
|
|
143
149
|
useEffect(() => {
|
|
@@ -146,14 +152,10 @@ export function ComposerTranscriptionControl({
|
|
|
146
152
|
cancelTranscription();
|
|
147
153
|
}
|
|
148
154
|
}, [cancelTranscription, status, suppressed]);
|
|
149
|
-
const active =
|
|
150
|
-
status === "requesting-permission" ||
|
|
151
|
-
status === "recording" ||
|
|
152
|
-
status === "saving" ||
|
|
153
|
-
status === "transcribing";
|
|
155
|
+
const active = capturing || status === "saving" || status === "transcribing";
|
|
154
156
|
const recoverable =
|
|
155
157
|
transcription.hasRecoverableRecording &&
|
|
156
|
-
(status === "recovered" || status === "transcript-ready" || status === "error");
|
|
158
|
+
(retrying || status === "recovered" || status === "transcript-ready" || status === "error");
|
|
157
159
|
const savedTranscript = status === "transcript-ready" && transcription.savedTranscript !== null;
|
|
158
160
|
const unavailableMessage = composer.disabled
|
|
159
161
|
? messages.unavailableDisabled
|
|
@@ -175,13 +177,15 @@ export function ComposerTranscriptionControl({
|
|
|
175
177
|
? messages.saving
|
|
176
178
|
: status === "transcribing"
|
|
177
179
|
? messages.transcribing
|
|
178
|
-
:
|
|
179
|
-
? messages.
|
|
180
|
-
: status === "
|
|
181
|
-
? messages.
|
|
182
|
-
: status === "
|
|
183
|
-
?
|
|
184
|
-
:
|
|
180
|
+
: retrying
|
|
181
|
+
? messages.retrying
|
|
182
|
+
: status === "recovered"
|
|
183
|
+
? messages.recovered
|
|
184
|
+
: status === "transcript-ready"
|
|
185
|
+
? messages.recoveredTranscript
|
|
186
|
+
: status === "error"
|
|
187
|
+
? (errorMessage ?? messages.errorUnknown)
|
|
188
|
+
: unavailableMessage;
|
|
185
189
|
|
|
186
190
|
function start(event: MouseEvent<HTMLButtonElement>) {
|
|
187
191
|
if (unavailableMessage) {
|
|
@@ -200,8 +204,15 @@ export function ComposerTranscriptionControl({
|
|
|
200
204
|
animate={{ opacity: 1, width: "auto" }}
|
|
201
205
|
exit={{ opacity: 0, width: 0 }}
|
|
202
206
|
transition={{ duration: 0.36, ease: [0.22, 1, 0.36, 1] }}
|
|
203
|
-
className={cn(
|
|
207
|
+
className={cn(
|
|
208
|
+
"inline-flex min-w-0 overflow-hidden",
|
|
209
|
+
// Mobile capture mode reserves the footer for this control. Keep the
|
|
210
|
+
// shell itself from shrinking and clipping its trailing actions.
|
|
211
|
+
capturing && "shrink-0",
|
|
212
|
+
className,
|
|
213
|
+
)}
|
|
204
214
|
data-transcription-status={status}
|
|
215
|
+
data-transcription-capturing={capturing ? "" : undefined}
|
|
205
216
|
>
|
|
206
217
|
<span className="inline-flex min-w-0 items-center gap-1.5">
|
|
207
218
|
<AnimatePresence mode="popLayout" initial={false}>
|
|
@@ -217,23 +228,39 @@ export function ComposerTranscriptionControl({
|
|
|
217
228
|
"bg-og-surface-2/70 pl-2 pr-1 pointer-coarse:h-11",
|
|
218
229
|
)}
|
|
219
230
|
>
|
|
220
|
-
<span className="max-w-44 truncate text-og-xs text-og-fg-muted max-sm:max-w-28">
|
|
231
|
+
<span className="og-transcription-recovered-label max-w-44 truncate text-og-xs text-og-fg-muted max-sm:max-w-28">
|
|
221
232
|
{savedTranscript
|
|
222
233
|
? (errorMessage ?? messages.recoveredTranscript)
|
|
223
|
-
:
|
|
224
|
-
?
|
|
225
|
-
:
|
|
234
|
+
: retrying
|
|
235
|
+
? messages.retrying
|
|
236
|
+
: status === "error"
|
|
237
|
+
? (errorMessage ?? messages.errorRetryable)
|
|
238
|
+
: messages.recovered}
|
|
226
239
|
</span>
|
|
227
|
-
<Tip
|
|
240
|
+
<Tip
|
|
241
|
+
tip={
|
|
242
|
+
savedTranscript
|
|
243
|
+
? messages.insertRecoveredTranscript
|
|
244
|
+
: retrying
|
|
245
|
+
? messages.pauseRetrying
|
|
246
|
+
: messages.retry
|
|
247
|
+
}
|
|
248
|
+
>
|
|
228
249
|
<button
|
|
229
250
|
type="button"
|
|
230
251
|
onClick={() =>
|
|
231
252
|
savedTranscript
|
|
232
253
|
? void transcription.insertSavedTranscript()
|
|
233
|
-
:
|
|
254
|
+
: retrying
|
|
255
|
+
? transcription.cancel()
|
|
256
|
+
: transcription.retry()
|
|
234
257
|
}
|
|
235
258
|
aria-label={
|
|
236
|
-
savedTranscript
|
|
259
|
+
savedTranscript
|
|
260
|
+
? messages.insertRecoveredTranscript
|
|
261
|
+
: retrying
|
|
262
|
+
? messages.pauseRetrying
|
|
263
|
+
: messages.retry
|
|
237
264
|
}
|
|
238
265
|
className={cn(
|
|
239
266
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
|
|
@@ -243,6 +270,8 @@ export function ComposerTranscriptionControl({
|
|
|
243
270
|
>
|
|
244
271
|
{savedTranscript ? (
|
|
245
272
|
<ClipboardPasteIcon className="size-3.5" />
|
|
273
|
+
) : retrying ? (
|
|
274
|
+
<SquareIcon className="size-3.5" />
|
|
246
275
|
) : (
|
|
247
276
|
<RefreshCwIcon className="size-3.5" />
|
|
248
277
|
)}
|
|
@@ -366,7 +395,7 @@ export function ComposerTranscriptionControl({
|
|
|
366
395
|
<Tip tip={errorMessage}>
|
|
367
396
|
<span
|
|
368
397
|
aria-hidden="true"
|
|
369
|
-
className="max-w-40 truncate text-og-xs text-og-status-failed max-sm:max-w-24"
|
|
398
|
+
className="og-transcription-error-label max-w-40 truncate text-og-xs text-og-status-failed max-sm:max-w-24"
|
|
370
399
|
>
|
|
371
400
|
{errorMessage}
|
|
372
401
|
</span>
|
|
@@ -45,6 +45,10 @@ import {
|
|
|
45
45
|
type SlashCommandContext,
|
|
46
46
|
} from "../hooks/use-slash-commands";
|
|
47
47
|
import { cn } from "../lib/cn";
|
|
48
|
+
import {
|
|
49
|
+
ComposerResponsiveContext,
|
|
50
|
+
type ResponsiveBasis,
|
|
51
|
+
} from "../lib/composer-responsive-context";
|
|
48
52
|
import { composerSubmissionErrorMessage, formatBytes, formatRelativeTime } from "../lib/format";
|
|
49
53
|
import type { PickerModelRow } from "../model-policy";
|
|
50
54
|
import { OPEN_WORKSTREAM_CONTROL_EVENT } from "../workstream-control-event";
|
|
@@ -53,6 +57,7 @@ import { ModelPicker as ModelPickerView } from "./model-picker";
|
|
|
53
57
|
import { TooltipProvider } from "./tooltip";
|
|
54
58
|
|
|
55
59
|
export { OPEN_WORKSTREAM_CONTROL_EVENT };
|
|
60
|
+
export type { ResponsiveBasis } from "../lib/composer-responsive-context";
|
|
56
61
|
|
|
57
62
|
function ComposerTip({
|
|
58
63
|
tip,
|
|
@@ -743,29 +748,43 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
743
748
|
export type ComposerRootProps = Omit<ComponentPropsWithoutRef<"div">, "children"> & {
|
|
744
749
|
controller: ChatComposerController;
|
|
745
750
|
children: ReactNode;
|
|
751
|
+
/**
|
|
752
|
+
* Measurement surface for responsive composer chrome. `viewport` preserves
|
|
753
|
+
* the existing breakpoint behavior; `container` responds to this root's
|
|
754
|
+
* inline size and also bounds composer-owned portalled menus to it.
|
|
755
|
+
*/
|
|
756
|
+
responsiveBasis?: ResponsiveBasis | undefined;
|
|
746
757
|
};
|
|
747
758
|
|
|
748
759
|
export const Root = forwardRef<HTMLDivElement, ComposerRootProps>(function ComposerRoot(
|
|
749
|
-
{ controller, children, className, style, ...props },
|
|
760
|
+
{ controller, children, className, style, responsiveBasis = "viewport", ...props },
|
|
750
761
|
forwardedRef,
|
|
751
762
|
) {
|
|
763
|
+
const responsiveRootRef = useRef<HTMLDivElement | null>(null);
|
|
764
|
+
const responsiveContext = useMemo(
|
|
765
|
+
() => ({ responsiveBasis, rootRef: responsiveRootRef }),
|
|
766
|
+
[responsiveBasis],
|
|
767
|
+
);
|
|
752
768
|
// Provider stays on Root so optional Radix tip surfaces (voice input) work.
|
|
753
769
|
// Ordinary composer actions use native `title` via ComposerTip to avoid
|
|
754
770
|
// pulling Popper into every tip hotspot.
|
|
755
771
|
return (
|
|
756
772
|
<ComposerContext.Provider value={controller}>
|
|
757
|
-
<
|
|
758
|
-
<
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
773
|
+
<ComposerResponsiveContext.Provider value={responsiveContext}>
|
|
774
|
+
<TooltipProvider delayDuration={300}>
|
|
775
|
+
<div
|
|
776
|
+
{...props}
|
|
777
|
+
ref={mergeRefs(controller.rootRef, responsiveRootRef, forwardedRef)}
|
|
778
|
+
data-og-composer-id={controller.id}
|
|
779
|
+
data-og-responsive-basis={responsiveBasis}
|
|
780
|
+
className={cn("og-root og-composer", className)}
|
|
781
|
+
style={{ paddingBottom: "env(safe-area-inset-bottom)", ...style }}
|
|
782
|
+
>
|
|
783
|
+
{children}
|
|
784
|
+
<ComposerAnnouncements />
|
|
785
|
+
</div>
|
|
786
|
+
</TooltipProvider>
|
|
787
|
+
</ComposerResponsiveContext.Provider>
|
|
769
788
|
</ComposerContext.Provider>
|
|
770
789
|
);
|
|
771
790
|
});
|
|
@@ -957,8 +976,8 @@ export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(functio
|
|
|
957
976
|
paletteOpen ? `${controller.listboxId}-option-${controller.palette.highlight}` : undefined
|
|
958
977
|
}
|
|
959
978
|
className={cn(
|
|
960
|
-
"block w-full resize-none bg-transparent px-3.5 pt-3 pb-1 text-og-composer md:px-4 md:text-og-composer-wide pointer-coarse:min-h-11",
|
|
961
|
-
"text-og-fg placeholder:text-og-fg-subtle focus:outline-
|
|
979
|
+
"og-composer-input block w-full resize-none bg-transparent px-3.5 pt-3 pb-1 text-og-composer md:px-4 md:text-og-composer-wide pointer-coarse:min-h-11",
|
|
980
|
+
"text-og-fg placeholder:text-og-fg-subtle focus:outline-hidden focus-visible:outline-hidden",
|
|
962
981
|
"disabled:cursor-not-allowed disabled:opacity-60",
|
|
963
982
|
className,
|
|
964
983
|
)}
|
|
@@ -992,7 +1011,7 @@ export const Footer = forwardRef<HTMLDivElement, ComposerFooterProps>(function C
|
|
|
992
1011
|
{...props}
|
|
993
1012
|
ref={ref}
|
|
994
1013
|
className={cn(
|
|
995
|
-
"flex items-end gap-1.5 px-2 pb-2 pt-0.5 sm:px-2.5 sm:pb-2.5",
|
|
1014
|
+
"og-composer-footer flex items-end gap-1.5 px-2 pb-2 pt-0.5 sm:px-2.5 sm:pb-2.5",
|
|
996
1015
|
// Mobile: one control row — never wrap into a second toolbar line.
|
|
997
1016
|
"max-sm:flex-nowrap max-sm:items-center max-sm:gap-1",
|
|
998
1017
|
className,
|
|
@@ -1010,7 +1029,7 @@ export const Controls = forwardRef<HTMLSpanElement, ComposerControlsProps>(
|
|
|
1010
1029
|
{...props}
|
|
1011
1030
|
ref={ref}
|
|
1012
1031
|
className={cn(
|
|
1013
|
-
"flex min-w-0 flex-1 flex-wrap items-center gap-1.5",
|
|
1032
|
+
"og-composer-controls flex min-w-0 flex-1 flex-wrap items-center gap-1.5",
|
|
1014
1033
|
"max-sm:flex-nowrap max-sm:gap-1",
|
|
1015
1034
|
className,
|
|
1016
1035
|
)}
|
|
@@ -1030,7 +1049,10 @@ export const Hint = forwardRef<HTMLSpanElement, ComposerHintProps>(function Comp
|
|
|
1030
1049
|
<span
|
|
1031
1050
|
{...props}
|
|
1032
1051
|
ref={ref}
|
|
1033
|
-
className={cn(
|
|
1052
|
+
className={cn(
|
|
1053
|
+
"og-composer-hint min-w-0 flex-1 px-1.5 text-og-xs text-og-fg-subtle max-sm:hidden",
|
|
1054
|
+
className,
|
|
1055
|
+
)}
|
|
1034
1056
|
>
|
|
1035
1057
|
{children ?? controller.messages.keyboardHint}
|
|
1036
1058
|
</span>
|
|
@@ -1048,7 +1070,7 @@ export const Actions = forwardRef<HTMLSpanElement, ComposerActionsProps>(functio
|
|
|
1048
1070
|
{...props}
|
|
1049
1071
|
ref={ref}
|
|
1050
1072
|
className={cn(
|
|
1051
|
-
"ml-auto flex shrink-0 items-center gap-1.5",
|
|
1073
|
+
"og-composer-actions ml-auto flex shrink-0 items-center gap-1.5",
|
|
1052
1074
|
"max-sm:flex-nowrap max-sm:gap-1",
|
|
1053
1075
|
className,
|
|
1054
1076
|
)}
|
|
@@ -1386,8 +1408,12 @@ function WorkstreamPausedStrip({
|
|
|
1386
1408
|
) : (
|
|
1387
1409
|
<PlayIcon className="size-3.5 fill-current" />
|
|
1388
1410
|
)}
|
|
1389
|
-
<span className="hidden min-[400px]:inline">
|
|
1390
|
-
|
|
1411
|
+
<span className="og-composer-resume-label-long hidden min-[400px]:inline">
|
|
1412
|
+
{messages.resumeThisWorkstream}
|
|
1413
|
+
</span>
|
|
1414
|
+
<span className="og-composer-resume-label-short min-[400px]:hidden">
|
|
1415
|
+
{messages.resumeShort}
|
|
1416
|
+
</span>
|
|
1391
1417
|
</button>
|
|
1392
1418
|
<button
|
|
1393
1419
|
type="button"
|
|
@@ -1412,7 +1438,7 @@ function WorkstreamPausedStrip({
|
|
|
1412
1438
|
{blockerHref(entry, controlLinks) ? (
|
|
1413
1439
|
<a
|
|
1414
1440
|
href={blockerHref(entry, controlLinks)}
|
|
1415
|
-
className="font-medium text-og-fg underline decoration-og-border-strong underline-offset-2 hover:text-og-accent focus-visible:outline-
|
|
1441
|
+
className="font-medium text-og-fg underline decoration-og-border-strong underline-offset-2 hover:text-og-accent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-ring/40"
|
|
1416
1442
|
>
|
|
1417
1443
|
{entry.displayName}
|
|
1418
1444
|
</a>
|
|
@@ -1582,7 +1608,7 @@ function AttachmentChips({
|
|
|
1582
1608
|
onRetry?: ((id: string) => void) | undefined;
|
|
1583
1609
|
}) {
|
|
1584
1610
|
return (
|
|
1585
|
-
<div className="flex flex-wrap gap-2
|
|
1611
|
+
<div className="flex flex-wrap gap-2 px-3 py-2">
|
|
1586
1612
|
{attachments.map((attachment) => {
|
|
1587
1613
|
const failed = attachment.status === "failed";
|
|
1588
1614
|
const statusText =
|