@opengeni/react 0.45.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -12
- package/dist/{chunk-U3CSCMWA.js → chunk-FK6VG4LL.js} +9 -13
- package/dist/chunk-FK6VG4LL.js.map +1 -0
- package/dist/{chunk-HFO4ERGQ.js → chunk-FWXGSNXT.js} +2 -2
- package/dist/{chunk-SRFUT2ZU.js → chunk-I4MPFDRP.js} +119 -63
- package/dist/chunk-I4MPFDRP.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-LWR4MXSS.js → chunk-LHLYWG5R.js} +10 -1
- package/dist/chunk-LHLYWG5R.js.map +1 -0
- package/dist/{chunk-L3EWO3UK.js → chunk-NJ7M2B6Z.js} +445 -84
- package/dist/chunk-NJ7M2B6Z.js.map +1 -0
- package/dist/{chunk-VCBFUSUZ.js → chunk-O4VXOBGF.js} +3 -3
- package/dist/{chunk-VCBFUSUZ.js.map → chunk-O4VXOBGF.js.map} +1 -1
- package/dist/{chunk-6EDV6YFE.js → chunk-OL6QVXGF.js} +121 -29
- package/dist/chunk-OL6QVXGF.js.map +1 -0
- package/dist/chunk-VZTQ73XT.js +86 -0
- package/dist/chunk-VZTQ73XT.js.map +1 -0
- package/dist/{chunk-EHSYZ4KP.js → chunk-WYA65Y3F.js} +16 -16
- package/dist/chunk-WYA65Y3F.js.map +1 -0
- package/dist/{chunk-FD72GJMK.js → chunk-XCNTXWBB.js} +274 -125
- package/dist/chunk-XCNTXWBB.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/components/chat-composer.d.ts +7 -2
- package/dist/components/composer-transcription-control.d.ts +2 -0
- package/dist/components/composer.d.ts +14 -0
- package/dist/components/machines/machine-detail.d.ts +3 -1
- package/dist/components/machines-dashboard.d.ts +3 -3
- package/dist/components/message-timeline.d.ts +12 -2
- package/dist/components/sandbox-files.d.ts +2 -2
- package/dist/components/sandbox-terminal.d.ts +29 -0
- package/dist/components/sandbox-workspace.d.ts +5 -1
- package/dist/components/workspace-dock.d.ts +3 -1
- package/dist/composer.d.ts +2 -2
- package/dist/composer.js +6 -6
- package/dist/hooks/internal.d.ts +6 -0
- package/dist/hooks/use-codex-accounts.d.ts +1 -1
- package/dist/hooks/use-environments.d.ts +10 -4
- package/dist/hooks/use-machines.d.ts +7 -0
- package/dist/hooks/use-sandbox-files.d.ts +19 -0
- package/dist/hooks/use-sandbox-git.d.ts +7 -0
- package/dist/hooks/use-transcription.d.ts +2 -2
- package/dist/hooks/use-voice-input.d.ts +13 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.js +904 -538
- package/dist/index.js.map +1 -1
- package/dist/lib/composer-responsive-context.d.ts +9 -0
- package/dist/lib/use-portal-token-style.d.ts +14 -3
- package/dist/machines.js +2 -2
- package/dist/{queue-surface-implementation-J4XJFKRW.js → queue-surface-implementation-U5JFG7HT.js} +19 -18
- package/dist/queue-surface-implementation-U5JFG7HT.js.map +1 -0
- package/dist/realtime/realtime-control.d.ts +9 -0
- package/dist/realtime.js +29 -32
- package/dist/realtime.js.map +1 -1
- package/dist/session-ui.js +5 -5
- package/dist/session.js +4 -4
- package/dist/timeline/activity-rail.d.ts +3 -2
- package/dist/timeline/index.d.ts +2 -2
- package/dist/timeline/parsers.d.ts +3 -3
- package/dist/timeline/registry.d.ts +3 -0
- package/dist/timeline/screenshot-lightbox.d.ts +1 -1
- package/dist/timeline/types.d.ts +4 -0
- package/dist/voice-recording-store.d.ts +8 -2
- package/package.json +20 -4
- package/src/client.ts +3 -0
- package/src/components/chat-composer.tsx +12 -2
- package/src/components/code-editor.tsx +1 -1
- package/src/components/command-palette.tsx +1 -1
- package/src/components/composer-transcription-control.tsx +41 -16
- package/src/components/composer.tsx +52 -26
- package/src/components/copy-button.tsx +2 -2
- package/src/components/desktop-viewer.tsx +2 -2
- package/src/components/file-browser.tsx +39 -17
- package/src/components/human-input-form.tsx +2 -2
- package/src/components/machine-card.tsx +1 -1
- package/src/components/machines/machine-detail.tsx +39 -15
- package/src/components/machines-dashboard.tsx +7 -6
- package/src/components/message-timeline.tsx +44 -11
- package/src/components/model-picker.tsx +2 -2
- package/src/components/model-policy-picker.tsx +16 -15
- package/src/components/queue-surface-implementation.tsx +20 -16
- package/src/components/queue-surface-state.tsx +2 -2
- package/src/components/sandbox-files.tsx +140 -60
- package/src/components/sandbox-terminal.tsx +24 -5
- package/src/components/sandbox-workspace.tsx +180 -142
- package/src/components/session-chrome.tsx +14 -14
- package/src/components/tooltip.tsx +13 -16
- package/src/components/user-message-body.tsx +1 -1
- package/src/components/workbench-changes.tsx +4 -4
- 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-codex-accounts.ts +4 -4
- 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-machines.ts +47 -1
- package/src/hooks/use-sandbox-files.ts +310 -59
- package/src/hooks/use-sandbox-git.ts +148 -41
- package/src/hooks/use-session-capabilities.ts +35 -24
- package/src/hooks/use-session-events.ts +18 -4
- package/src/hooks/use-transcription.ts +4 -14
- package/src/hooks/use-turn-queue.ts +17 -5
- package/src/hooks/use-voice-input.ts +481 -36
- package/src/hooks/use-windowed-sections.ts +9 -7
- package/src/index.ts +11 -6
- package/src/lib/composer-responsive-context.ts +15 -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 +18 -7
- package/src/timeline/activity-rail.tsx +15 -6
- package/src/timeline/index.ts +1 -1
- package/src/timeline/parsers.ts +33 -20
- package/src/timeline/projection.ts +23 -0
- package/src/timeline/registry.ts +7 -0
- package/src/timeline/screenshot-lightbox.tsx +15 -4
- package/src/timeline/shared.tsx +8 -8
- package/src/timeline/tool-renderers.tsx +166 -22
- package/src/timeline/turn-summary.tsx +6 -6
- package/src/timeline/types.ts +4 -0
- package/src/voice-recording-store.ts +15 -0
- package/styles/compiled.css +5065 -0
- package/styles/compiled.d.ts +2 -0
- package/styles/effective-tokens.css +27 -0
- package/styles/index.css +3 -0
- package/styles/responsive.css +196 -0
- package/styles/responsive.d.ts +2 -0
- package/styles/tokens.css +50 -17
- package/dist/chunk-6EDV6YFE.js.map +0 -1
- package/dist/chunk-EB67J347.js.map +0 -1
- package/dist/chunk-EHSYZ4KP.js.map +0 -1
- package/dist/chunk-FD72GJMK.js.map +0 -1
- package/dist/chunk-JB5725BI.js +0 -48
- package/dist/chunk-JB5725BI.js.map +0 -1
- package/dist/chunk-L3EWO3UK.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/queue-surface-implementation-J4XJFKRW.js.map +0 -1
- /package/dist/{chunk-HFO4ERGQ.js.map → chunk-FWXGSNXT.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
"styles"
|
|
15
15
|
],
|
|
16
16
|
"type": "module",
|
|
17
|
-
"sideEffects":
|
|
17
|
+
"sideEffects": [
|
|
18
|
+
"**/*.css"
|
|
19
|
+
],
|
|
18
20
|
"main": "./dist/index.js",
|
|
19
21
|
"module": "./dist/index.js",
|
|
20
22
|
"types": "./dist/index.d.ts",
|
|
@@ -49,10 +51,22 @@
|
|
|
49
51
|
},
|
|
50
52
|
"./styles.css": {
|
|
51
53
|
"types": "./styles/index.d.ts",
|
|
54
|
+
"style": "./styles/index.css",
|
|
52
55
|
"import": "./styles/index.css"
|
|
53
56
|
},
|
|
57
|
+
"./compiled.css": {
|
|
58
|
+
"types": "./styles/compiled.d.ts",
|
|
59
|
+
"style": "./styles/compiled.css",
|
|
60
|
+
"import": "./styles/compiled.css"
|
|
61
|
+
},
|
|
62
|
+
"./responsive.css": {
|
|
63
|
+
"types": "./styles/responsive.d.ts",
|
|
64
|
+
"style": "./styles/responsive.css",
|
|
65
|
+
"import": "./styles/responsive.css"
|
|
66
|
+
},
|
|
54
67
|
"./tokens.css": {
|
|
55
68
|
"types": "./styles/tokens.d.ts",
|
|
69
|
+
"style": "./styles/tokens.css",
|
|
56
70
|
"import": "./styles/tokens.css"
|
|
57
71
|
}
|
|
58
72
|
},
|
|
@@ -62,7 +76,9 @@
|
|
|
62
76
|
},
|
|
63
77
|
"scripts": {
|
|
64
78
|
"typecheck": "tsc --noEmit",
|
|
65
|
-
"build": "bun ../../scripts/build-typescript-package.ts",
|
|
79
|
+
"build": "bun run build:css && bun ../../scripts/build-typescript-package.ts",
|
|
80
|
+
"build:css": "bun scripts/build-compiled-css.ts",
|
|
81
|
+
"check:css": "bun scripts/build-compiled-css.ts --check",
|
|
66
82
|
"demo": "vite dev demo --port 3100",
|
|
67
83
|
"demo:build": "vite build demo",
|
|
68
84
|
"demo:build:deployed": "OPENGENI_REACT_DEMO_BASE=/react-demo/ OPENGENI_REACT_DEMO_OUT_DIR=../../../apps/web/dist/react-demo vite build demo",
|
|
@@ -75,7 +91,7 @@
|
|
|
75
91
|
"@dnd-kit/utilities": "3.2.2",
|
|
76
92
|
"@fontsource-variable/noto-sans-arabic": "5.2.10",
|
|
77
93
|
"@fontsource-variable/noto-sans-jp": "5.2.10",
|
|
78
|
-
"@opengeni/sdk": "^0.
|
|
94
|
+
"@opengeni/sdk": "^0.48.0",
|
|
79
95
|
"clsx": "^2.1.1",
|
|
80
96
|
"lucide-react": "^1.8.0",
|
|
81
97
|
"motion": "^12.0.0",
|
package/src/client.ts
CHANGED
|
@@ -50,6 +50,7 @@ export type SessionClientLike = Pick<
|
|
|
50
50
|
| "createFileDownloadUrl"
|
|
51
51
|
// VariableSets
|
|
52
52
|
| "listVariableSets"
|
|
53
|
+
| "getVariableSetVariable"
|
|
53
54
|
| "createVariableSet"
|
|
54
55
|
| "updateVariableSet"
|
|
55
56
|
| "deleteVariableSet"
|
|
@@ -99,6 +100,7 @@ export type SessionClientLike = Pick<
|
|
|
99
100
|
| "detachViewer"
|
|
100
101
|
// Channel-A structured services (terminal-as-events feed via fs/git/terminal)
|
|
101
102
|
| "fsList"
|
|
103
|
+
| "fsListBatch"
|
|
102
104
|
| "fsRead"
|
|
103
105
|
| "fsWrite"
|
|
104
106
|
| "fsDelete"
|
|
@@ -106,6 +108,7 @@ export type SessionClientLike = Pick<
|
|
|
106
108
|
| "fsMkdir"
|
|
107
109
|
| "gitStatus"
|
|
108
110
|
| "gitDiff"
|
|
111
|
+
| "gitReadBatch"
|
|
109
112
|
// Workbench v2 turn-end capture reads (the cold-paint source; M3 consumes these)
|
|
110
113
|
| "getWorkspaceCapture"
|
|
111
114
|
| "getWorkspaceCaptureFile"
|
|
@@ -29,6 +29,7 @@ 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,
|
|
@@ -39,6 +40,11 @@ export { OPEN_WORKSTREAM_CONTROL_EVENT };
|
|
|
39
40
|
|
|
40
41
|
export type ChatComposerProps = {
|
|
41
42
|
composer: ComposerState;
|
|
43
|
+
/**
|
|
44
|
+
* Measurement surface for responsive chrome. Defaults to the historical
|
|
45
|
+
* viewport breakpoints; opt into `container` for narrow embedded panels.
|
|
46
|
+
*/
|
|
47
|
+
responsiveBasis?: ResponsiveBasis | undefined;
|
|
42
48
|
/** Canonical workstream control, separate from lifecycle status. */
|
|
43
49
|
effectiveControl?: EffectiveSessionControl | null | undefined;
|
|
44
50
|
/** Waiting prompts already ahead of a normal Send. */
|
|
@@ -91,6 +97,7 @@ export type ChatComposerProps = {
|
|
|
91
97
|
*/
|
|
92
98
|
export function ChatComposer({
|
|
93
99
|
composer,
|
|
100
|
+
responsiveBasis,
|
|
94
101
|
effectiveControl,
|
|
95
102
|
queuedAheadCount,
|
|
96
103
|
canControlWorkspace,
|
|
@@ -140,7 +147,7 @@ export function ChatComposer({
|
|
|
140
147
|
const stackActions = hasControls && Boolean(actionsStart);
|
|
141
148
|
|
|
142
149
|
return (
|
|
143
|
-
<Root controller={controller} className={className}>
|
|
150
|
+
<Root controller={controller} responsiveBasis={responsiveBasis} className={className}>
|
|
144
151
|
<Frame>
|
|
145
152
|
<CommandPalette />
|
|
146
153
|
<Surface>
|
|
@@ -152,7 +159,10 @@ export function ChatComposer({
|
|
|
152
159
|
{controller.confirmState ? (
|
|
153
160
|
<Confirmation />
|
|
154
161
|
) : (
|
|
155
|
-
<Footer
|
|
162
|
+
<Footer
|
|
163
|
+
data-og-stack-actions={stackActions ? "" : undefined}
|
|
164
|
+
className={stackActions ? "max-sm:flex-nowrap sm:flex-wrap" : undefined}
|
|
165
|
+
>
|
|
156
166
|
<LayoutGroup id="og-composer-footer">
|
|
157
167
|
{hasControls ? (
|
|
158
168
|
<Controls
|
|
@@ -458,7 +458,7 @@ function PlainTextarea({
|
|
|
458
458
|
}
|
|
459
459
|
}}
|
|
460
460
|
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-
|
|
461
|
+
className="h-full w-full resize-none bg-transparent p-2 font-og-mono text-og-sm text-og-fg outline-hidden"
|
|
462
462
|
/>
|
|
463
463
|
);
|
|
464
464
|
}
|
|
@@ -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,7 @@ export function ComposerTranscriptionControl({
|
|
|
138
142
|
createOwnerId,
|
|
139
143
|
});
|
|
140
144
|
const { status } = transcription;
|
|
145
|
+
const retrying = status === "retrying";
|
|
141
146
|
|
|
142
147
|
const cancelTranscription = transcription.cancel;
|
|
143
148
|
useEffect(() => {
|
|
@@ -153,7 +158,7 @@ export function ComposerTranscriptionControl({
|
|
|
153
158
|
status === "transcribing";
|
|
154
159
|
const recoverable =
|
|
155
160
|
transcription.hasRecoverableRecording &&
|
|
156
|
-
(status === "recovered" || status === "transcript-ready" || status === "error");
|
|
161
|
+
(retrying || status === "recovered" || status === "transcript-ready" || status === "error");
|
|
157
162
|
const savedTranscript = status === "transcript-ready" && transcription.savedTranscript !== null;
|
|
158
163
|
const unavailableMessage = composer.disabled
|
|
159
164
|
? messages.unavailableDisabled
|
|
@@ -175,13 +180,15 @@ export function ComposerTranscriptionControl({
|
|
|
175
180
|
? messages.saving
|
|
176
181
|
: status === "transcribing"
|
|
177
182
|
? messages.transcribing
|
|
178
|
-
:
|
|
179
|
-
? messages.
|
|
180
|
-
: status === "
|
|
181
|
-
? messages.
|
|
182
|
-
: status === "
|
|
183
|
-
?
|
|
184
|
-
:
|
|
183
|
+
: retrying
|
|
184
|
+
? messages.retrying
|
|
185
|
+
: status === "recovered"
|
|
186
|
+
? messages.recovered
|
|
187
|
+
: status === "transcript-ready"
|
|
188
|
+
? messages.recoveredTranscript
|
|
189
|
+
: status === "error"
|
|
190
|
+
? (errorMessage ?? messages.errorUnknown)
|
|
191
|
+
: unavailableMessage;
|
|
185
192
|
|
|
186
193
|
function start(event: MouseEvent<HTMLButtonElement>) {
|
|
187
194
|
if (unavailableMessage) {
|
|
@@ -217,23 +224,39 @@ export function ComposerTranscriptionControl({
|
|
|
217
224
|
"bg-og-surface-2/70 pl-2 pr-1 pointer-coarse:h-11",
|
|
218
225
|
)}
|
|
219
226
|
>
|
|
220
|
-
<span className="max-w-44 truncate text-og-xs text-og-fg-muted max-sm:max-w-28">
|
|
227
|
+
<span className="og-transcription-recovered-label max-w-44 truncate text-og-xs text-og-fg-muted max-sm:max-w-28">
|
|
221
228
|
{savedTranscript
|
|
222
229
|
? (errorMessage ?? messages.recoveredTranscript)
|
|
223
|
-
:
|
|
224
|
-
?
|
|
225
|
-
:
|
|
230
|
+
: retrying
|
|
231
|
+
? messages.retrying
|
|
232
|
+
: status === "error"
|
|
233
|
+
? (errorMessage ?? messages.errorRetryable)
|
|
234
|
+
: messages.recovered}
|
|
226
235
|
</span>
|
|
227
|
-
<Tip
|
|
236
|
+
<Tip
|
|
237
|
+
tip={
|
|
238
|
+
savedTranscript
|
|
239
|
+
? messages.insertRecoveredTranscript
|
|
240
|
+
: retrying
|
|
241
|
+
? messages.pauseRetrying
|
|
242
|
+
: messages.retry
|
|
243
|
+
}
|
|
244
|
+
>
|
|
228
245
|
<button
|
|
229
246
|
type="button"
|
|
230
247
|
onClick={() =>
|
|
231
248
|
savedTranscript
|
|
232
249
|
? void transcription.insertSavedTranscript()
|
|
233
|
-
:
|
|
250
|
+
: retrying
|
|
251
|
+
? transcription.cancel()
|
|
252
|
+
: transcription.retry()
|
|
234
253
|
}
|
|
235
254
|
aria-label={
|
|
236
|
-
savedTranscript
|
|
255
|
+
savedTranscript
|
|
256
|
+
? messages.insertRecoveredTranscript
|
|
257
|
+
: retrying
|
|
258
|
+
? messages.pauseRetrying
|
|
259
|
+
: messages.retry
|
|
237
260
|
}
|
|
238
261
|
className={cn(
|
|
239
262
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
|
|
@@ -243,6 +266,8 @@ export function ComposerTranscriptionControl({
|
|
|
243
266
|
>
|
|
244
267
|
{savedTranscript ? (
|
|
245
268
|
<ClipboardPasteIcon className="size-3.5" />
|
|
269
|
+
) : retrying ? (
|
|
270
|
+
<SquareIcon className="size-3.5" />
|
|
246
271
|
) : (
|
|
247
272
|
<RefreshCwIcon className="size-3.5" />
|
|
248
273
|
)}
|
|
@@ -366,7 +391,7 @@ export function ComposerTranscriptionControl({
|
|
|
366
391
|
<Tip tip={errorMessage}>
|
|
367
392
|
<span
|
|
368
393
|
aria-hidden="true"
|
|
369
|
-
className="max-w-40 truncate text-og-xs text-og-status-failed max-sm:max-w-24"
|
|
394
|
+
className="og-transcription-error-label max-w-40 truncate text-og-xs text-og-status-failed max-sm:max-w-24"
|
|
370
395
|
>
|
|
371
396
|
{errorMessage}
|
|
372
397
|
</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",
|
|
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
|
)}
|
|
@@ -1095,7 +1117,7 @@ export const AttachButton = forwardRef<HTMLButtonElement, ComposerAttachButtonPr
|
|
|
1095
1117
|
className={cn(
|
|
1096
1118
|
"inline-flex size-8 items-center justify-center rounded-og-md",
|
|
1097
1119
|
"text-og-fg-muted transition-colors duration-150 hover:bg-og-surface-2 hover:text-og-fg",
|
|
1098
|
-
"disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-
|
|
1120
|
+
"disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-11",
|
|
1099
1121
|
className,
|
|
1100
1122
|
)}
|
|
1101
1123
|
>
|
|
@@ -1167,7 +1189,7 @@ export const PauseButton = forwardRef<HTMLButtonElement, ComposerPauseButtonProp
|
|
|
1167
1189
|
disabled={busy}
|
|
1168
1190
|
aria-label={ariaLabel ?? controller.messages.pauseAriaLabel}
|
|
1169
1191
|
className={cn(
|
|
1170
|
-
"inline-flex size-8 items-center justify-center rounded-og-md border border-og-border pointer-coarse:size-
|
|
1192
|
+
"inline-flex size-8 items-center justify-center rounded-og-md border border-og-border pointer-coarse:size-11",
|
|
1171
1193
|
"bg-og-surface-2 text-og-fg-muted transition-colors duration-150",
|
|
1172
1194
|
"hover:border-og-status-waiting/50 hover:text-og-status-waiting",
|
|
1173
1195
|
"disabled:opacity-50",
|
|
@@ -1216,7 +1238,7 @@ export const SendButton = forwardRef<HTMLButtonElement, ComposerSendButtonProps>
|
|
|
1216
1238
|
: controller.messages.sendMessageAriaLabel)
|
|
1217
1239
|
}
|
|
1218
1240
|
className={cn(
|
|
1219
|
-
"inline-flex size-8 items-center justify-center rounded-og-md pointer-coarse:size-
|
|
1241
|
+
"inline-flex size-8 items-center justify-center rounded-og-md pointer-coarse:size-11",
|
|
1220
1242
|
"bg-og-accent text-og-accent-fg shadow-og-sm",
|
|
1221
1243
|
"transition-[background-color,transform,opacity] duration-150 ease-og-spring",
|
|
1222
1244
|
"hover:bg-og-accent-strong active:scale-95",
|
|
@@ -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 =
|
|
@@ -93,10 +93,10 @@ export function CopyButton({
|
|
|
93
93
|
aria-label={tip}
|
|
94
94
|
onClick={onClick}
|
|
95
95
|
className={cn(
|
|
96
|
-
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm",
|
|
96
|
+
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm pointer-coarse:size-11",
|
|
97
97
|
"text-og-fg-subtle transition-[opacity,color,background-color] duration-150",
|
|
98
98
|
"hover:bg-og-surface-2/80 hover:text-og-fg",
|
|
99
|
-
"focus-visible:opacity-100 focus-visible:outline-
|
|
99
|
+
"focus-visible:opacity-100 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/40",
|
|
100
100
|
reveal === "group-hover" &&
|
|
101
101
|
"opacity-0 group-hover/copy:opacity-100 group-focus-within/copy:opacity-100 pointer-coarse:opacity-70",
|
|
102
102
|
copied && "opacity-100 text-og-accent",
|
|
@@ -507,7 +507,7 @@ function TakeControlCallToAction({
|
|
|
507
507
|
"border-og-border",
|
|
508
508
|
"bg-og-bg/85 backdrop-blur-md",
|
|
509
509
|
"shadow-og-lg",
|
|
510
|
-
"outline-
|
|
510
|
+
"outline-hidden transition-all duration-150 ease-out",
|
|
511
511
|
"focus-visible:ring-2 focus-visible:ring-og-accent focus-visible:ring-offset-2 focus-visible:ring-offset-og-bg",
|
|
512
512
|
disabled
|
|
513
513
|
? "cursor-not-allowed opacity-60"
|
|
@@ -568,7 +568,7 @@ function InControlBar({ shared, onRelease }: { shared: boolean; onRelease: () =>
|
|
|
568
568
|
className={cn(
|
|
569
569
|
"inline-flex items-center gap-1.5 rounded-og-sm border px-2.5 py-1 text-og-xs font-semibold shadow-og-md transition-colors",
|
|
570
570
|
"border-og-accent bg-og-bg/90 text-og-fg backdrop-blur-sm",
|
|
571
|
-
"outline-
|
|
571
|
+
"outline-hidden hover:bg-og-accent hover:text-og-accent-fg focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
572
572
|
)}
|
|
573
573
|
>
|
|
574
574
|
<MonitorIcon className="size-3.5" strokeWidth={2} aria-hidden />
|
|
@@ -24,7 +24,11 @@ import {
|
|
|
24
24
|
import { AlertDialog } from "radix-ui";
|
|
25
25
|
import { VList, type VListHandle } from "virtua";
|
|
26
26
|
import { cn } from "../lib/cn";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
type PortalTokenStyle,
|
|
29
|
+
usePortalTokenSource,
|
|
30
|
+
usePortalTokenStyle,
|
|
31
|
+
} from "../lib/use-portal-token-style";
|
|
28
32
|
import { useUnicodeFallbackFonts } from "../lib/use-unicode-fonts";
|
|
29
33
|
import type { FileTreeNode, UseSandboxFilesResult } from "../hooks/use-sandbox-files";
|
|
30
34
|
|
|
@@ -155,10 +159,11 @@ export function FileBrowser({
|
|
|
155
159
|
const [busy, setBusy] = useState(false);
|
|
156
160
|
const [coarsePointer, setCoarsePointer] = useState(false);
|
|
157
161
|
const treeId = useId();
|
|
158
|
-
const
|
|
162
|
+
const container = usePortalTokenSource<HTMLDivElement>();
|
|
163
|
+
const containerRef = container.currentRef;
|
|
159
164
|
const deleteReturnFocusRef = useRef<HTMLElement | null>(null);
|
|
160
165
|
const vlistRef = useRef<VListHandle>(null);
|
|
161
|
-
const portalTokenStyle = usePortalTokenStyle(
|
|
166
|
+
const portalTokenStyle = usePortalTokenStyle(container.source);
|
|
162
167
|
const getTreeElement = useCallback(
|
|
163
168
|
() => (typeof document === "undefined" ? null : document.getElementById(treeId)),
|
|
164
169
|
[treeId],
|
|
@@ -569,6 +574,7 @@ export function FileBrowser({
|
|
|
569
574
|
runDelete,
|
|
570
575
|
supportsMutation,
|
|
571
576
|
coarsePointer,
|
|
577
|
+
containerRef,
|
|
572
578
|
rowIndexByPath,
|
|
573
579
|
treeId,
|
|
574
580
|
],
|
|
@@ -594,7 +600,13 @@ export function FileBrowser({
|
|
|
594
600
|
// Retry lives next to the state it explains (the degraded/empty notice), so do
|
|
595
601
|
// not render a second toolbar retry for the same failure.
|
|
596
602
|
const showToolbar = supportsMutation || result.loading;
|
|
597
|
-
|
|
603
|
+
// Virtua caches the previous visible range when a lazy-expanded subtree is
|
|
604
|
+
// inserted in the middle of a short list. The spacer grows but later root
|
|
605
|
+
// siblings can remain unmounted until a scroll/resize (for example,
|
|
606
|
+
// `.bash_history` vanished after expanding `repositories/<repo>`). Small
|
|
607
|
+
// trees do not benefit from virtualization, so render them directly and keep
|
|
608
|
+
// Virtua only for genuinely large workspaces.
|
|
609
|
+
const usesVirtualTree = !showErrorEmpty && !showEmpty && renderItems.length > 500;
|
|
598
610
|
|
|
599
611
|
// Render a SINGLE node row (no recursion — children are separate flat items the
|
|
600
612
|
// virtualizer renders). Returns the row element; the caller assigns the key.
|
|
@@ -854,7 +866,7 @@ export function FileBrowser({
|
|
|
854
866
|
type="button"
|
|
855
867
|
onClick={() => void result.refresh()}
|
|
856
868
|
disabled={result.loading}
|
|
857
|
-
className="inline-flex min-h-7 shrink-0 items-center gap-1 rounded-og-sm border border-og-border bg-og-surface-1 px-2 font-medium text-og-fg transition-colors hover:border-og-border-strong focus-visible:outline-
|
|
869
|
+
className="inline-flex min-h-7 shrink-0 items-center gap-1 rounded-og-sm border border-og-border bg-og-surface-1 px-2 font-medium text-og-fg transition-colors hover:border-og-border-strong focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11"
|
|
858
870
|
>
|
|
859
871
|
<RefreshCwIcon
|
|
860
872
|
className={cn("size-3", result.loading && "animate-spin motion-reduce:animate-none")}
|
|
@@ -868,13 +880,7 @@ export function FileBrowser({
|
|
|
868
880
|
{/* The tree itself. The root is a drop target so a node can be moved to "". */}
|
|
869
881
|
{/* biome-ignore lint/a11y/noNoninteractiveTabindex: the tree owns keyboard nav */}
|
|
870
882
|
<div
|
|
871
|
-
ref={
|
|
872
|
-
id={usesVirtualTree ? undefined : treeId}
|
|
873
|
-
role={usesVirtualTree ? undefined : "tree"}
|
|
874
|
-
aria-label={usesVirtualTree ? undefined : "Workspace files"}
|
|
875
|
-
aria-activedescendant={usesVirtualTree ? undefined : activeDescendantId}
|
|
876
|
-
tabIndex={usesVirtualTree ? undefined : 0}
|
|
877
|
-
aria-multiselectable={usesVirtualTree ? undefined : false}
|
|
883
|
+
ref={container.ref}
|
|
878
884
|
onFocus={(event) => {
|
|
879
885
|
if ((event.target as HTMLElement).id === treeId && cursorIndex < 0) {
|
|
880
886
|
const first = flatRows[0];
|
|
@@ -901,7 +907,7 @@ export function FileBrowser({
|
|
|
901
907
|
: undefined
|
|
902
908
|
}
|
|
903
909
|
className={cn(
|
|
904
|
-
"flex min-h-0 min-w-0 flex-1 flex-col p-1
|
|
910
|
+
"flex min-h-0 min-w-0 flex-1 flex-col p-1",
|
|
905
911
|
dragOver === "" && "ring-1 ring-inset ring-og-accent",
|
|
906
912
|
)}
|
|
907
913
|
data-opengeni-file-tree
|
|
@@ -929,6 +935,22 @@ export function FileBrowser({
|
|
|
929
935
|
<div className="p-2 text-og-sm text-og-fg-subtle">
|
|
930
936
|
{emptyState ?? "This directory is empty"}
|
|
931
937
|
</div>
|
|
938
|
+
) : !usesVirtualTree ? (
|
|
939
|
+
<div
|
|
940
|
+
id={treeId}
|
|
941
|
+
role="tree"
|
|
942
|
+
aria-label="Workspace files"
|
|
943
|
+
aria-activedescendant={activeDescendantId}
|
|
944
|
+
aria-multiselectable={false}
|
|
945
|
+
tabIndex={0}
|
|
946
|
+
className="min-h-0 min-w-0 flex-1 overflow-auto outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent"
|
|
947
|
+
>
|
|
948
|
+
{renderItems.map((item) => (
|
|
949
|
+
<div key={itemKey(item)} className="min-w-0">
|
|
950
|
+
{renderItem(item)}
|
|
951
|
+
</div>
|
|
952
|
+
))}
|
|
953
|
+
</div>
|
|
932
954
|
) : (
|
|
933
955
|
// Virtualized: only the rows in/near the viewport mount, so a 3k-node
|
|
934
956
|
// tree stays responsive. The flat item list already carries the
|
|
@@ -941,7 +963,7 @@ export function FileBrowser({
|
|
|
941
963
|
aria-activedescendant={activeDescendantId}
|
|
942
964
|
aria-multiselectable={false}
|
|
943
965
|
tabIndex={0}
|
|
944
|
-
className="min-h-0 flex-1 outline-
|
|
966
|
+
className="min-h-0 flex-1 outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent"
|
|
945
967
|
itemSize={coarsePointer ? 44 : 28}
|
|
946
968
|
ssrCount={Math.min(32, renderItems.length)}
|
|
947
969
|
>
|
|
@@ -1041,9 +1063,9 @@ function DeleteDialog({
|
|
|
1041
1063
|
}}
|
|
1042
1064
|
>
|
|
1043
1065
|
<AlertDialog.Portal container={typeof document === "undefined" ? null : document.body}>
|
|
1044
|
-
<AlertDialog.Overlay className="fixed inset-0 z-[100] bg-black/45 backdrop-blur-[2px]" />
|
|
1066
|
+
<AlertDialog.Overlay className="og-root fixed inset-0 z-[100] bg-black/45 backdrop-blur-[2px]" />
|
|
1045
1067
|
<AlertDialog.Content
|
|
1046
|
-
className="og-root fixed left-1/2 top-1/2 z-[101] max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] max-w-sm -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-og-lg border border-og-border-strong bg-og-surface-1 p-4 text-og-fg shadow-2xl outline-
|
|
1068
|
+
className="og-root fixed left-1/2 top-1/2 z-[101] max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] max-w-sm -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-og-lg border border-og-border-strong bg-og-surface-1 p-4 text-og-fg shadow-2xl outline-hidden"
|
|
1047
1069
|
style={portalTokenStyle}
|
|
1048
1070
|
onOpenAutoFocus={(event) => {
|
|
1049
1071
|
event.preventDefault();
|
|
@@ -1208,7 +1230,7 @@ function InlineInput({
|
|
|
1208
1230
|
className={cn(
|
|
1209
1231
|
"min-w-0 flex-1 rounded-og-sm border bg-og-bg px-1 py-0 text-og-sm",
|
|
1210
1232
|
"border-og-accent text-og-fg",
|
|
1211
|
-
"outline-
|
|
1233
|
+
"outline-hidden",
|
|
1212
1234
|
)}
|
|
1213
1235
|
/>
|
|
1214
1236
|
</div>
|
|
@@ -559,7 +559,7 @@ function QuestionControls({
|
|
|
559
559
|
aria-describedby={describedBy}
|
|
560
560
|
autoFocus={autoFocus}
|
|
561
561
|
rows={2}
|
|
562
|
-
className="min-h-14 w-full resize-y rounded-og-md border border-og-border bg-og-surface-1 px-3 py-2 text-og-sm text-og-fg outline-
|
|
562
|
+
className="min-h-14 w-full resize-y rounded-og-md border border-og-border bg-og-surface-1 px-3 py-2 text-og-sm text-og-fg outline-hidden placeholder:text-og-fg-subtle focus:border-og-accent"
|
|
563
563
|
/>
|
|
564
564
|
) : (
|
|
565
565
|
<div
|
|
@@ -651,7 +651,7 @@ function QuestionControls({
|
|
|
651
651
|
other: event.target.value,
|
|
652
652
|
}))
|
|
653
653
|
}
|
|
654
|
-
className="mt-1.5 w-full rounded-og-sm border border-og-border bg-og-surface-1 px-2 py-1.5 text-og-sm text-og-fg outline-
|
|
654
|
+
className="mt-1.5 w-full rounded-og-sm border border-og-border bg-og-surface-1 px-2 py-1.5 text-og-sm text-og-fg outline-hidden focus:border-og-accent disabled:opacity-50"
|
|
655
655
|
/>
|
|
656
656
|
</span>
|
|
657
657
|
</label>
|