feat(desktop): expand prompt composer inline#174
feat(desktop): expand prompt composer inline#174JUk1-GH wants to merge 1 commit intoOpenCoworkAI:mainfrom
Conversation
Signed-off-by: juki <chinahujunkai@gmail.com>
|
原来的输入框太小了,没有自适应变化和展开功能,现在我加了点击外扩角标后,左右面板的可拖拽分割线平滑右移,左侧输入区获得更多宽度,同时输入框从底部向上扩展;点击收起再平滑回到原布局。 |
There was a problem hiding this comment.
Findings
-
[Major] Escape handling leaks to global shortcuts while composer is expanded — pressing
Escapein expanded composer also bubbles to app-levelescapebindings (close dialog/view mode changes), causing unintended UI state changes beyond collapse. Evidence:apps/desktop/src/renderer/src/components/chat/PromptInput.tsx:180,apps/desktop/src/renderer/src/App.tsx:164
Suggested fix:const handleDocKeyDown = (e: globalThis.KeyboardEvent) => { if (e.key !== 'Escape') return; e.preventDefault(); e.stopPropagation(); setIsExpanded(false); };
-
[Minor] Forced synchronous layout on every textarea change risks typing jank —
resizeTextareaperformsoffsetHeightreflow and is called fromonChange, which can degrade input responsiveness as prompt length grows. Evidence:apps/desktop/src/renderer/src/components/chat/PromptInput.tsx:79,apps/desktop/src/renderer/src/components/chat/PromptInput.tsx:229
Suggested fix:function resizeTextarea(el: HTMLTextAreaElement, isExpanded: boolean): boolean { const rowHeight = getTextareaLineHeight(el); el.style.height = 'auto'; const trueScrollHeight = el.scrollHeight; const nextHeight = isExpanded ? Math.min(Math.max(trueScrollHeight, window.innerHeight * 0.4), window.innerHeight * 0.6) : Math.min(trueScrollHeight, rowHeight * MAX_TEXTAREA_ROWS); el.style.height = `${nextHeight}px`; return trueScrollHeight > rowHeight * 2.5; }
Summary
- Review mode: initial
- Two issues found in the latest diff: one behavioral regression in Escape handling and one input-path performance risk.
- Required context docs
docs/VISION.mdanddocs/PRINCIPLES.mdwere not found in this checkout (Not found in repo/docs). - Test coverage for the new expand/collapse keyboard interaction and textarea resizing path is missing in this diff.
Testing
- Not run (automation)
open-codesign Bot
| }, []); | ||
| if (!isExpanded) return; | ||
| const handleDocKeyDown = (e: globalThis.KeyboardEvent) => { | ||
| if (e.key === 'Escape') { |
There was a problem hiding this comment.
Escape here collapses the prompt but still bubbles to window-level escape bindings in App, which can also close dialogs/switch modes. Please consume the event (preventDefault + stopPropagation) when expanded composer handles Escape.
|
|
||
| el.style.height = cachedHeight; | ||
| // Force a layout recalc so the browser commits the origin height before transitioning | ||
| void el.offsetHeight; |
There was a problem hiding this comment.
void el.offsetHeight forces sync layout, and this function is called from onChange on each keystroke. This can cause typing jank for long prompts; prefer a non-forced measurement/update path.
|
感谢您的贡献和反馈 请您看看bot的回复 再修一修bug 谢谢! |
There was a problem hiding this comment.
Review mode: initial
Findings
-
[Minor] Expand button is focusable via Tab key when visually hidden (opacity-0 + pointer-events-none). Keyboard users may navigate to an invisible control, causing confusion.
Suggested fix:<div className={...} inert={!showExpandIcon && !isExpanded ? true : undefined} >
Or set
tabIndex={-1}on the button when hidden. -
[Minor] The
useEffectresize callback atPromptInput.tsx:167checkstextarea.value === promptbefore proceeding, but this condition is always true in a controlled component wherepromptis the source of truth. The check adds no value and could confuse readers.
Suggested fix:useEffect(() => { const textarea = taRef.current; if (textarea) { const isOver = resizeTextarea(textarea, isExpanded); setShowExpandIcon(isOver); if (isExpanded) { textarea.focus(); } } }, [prompt, isExpanded]);
-
[Minor] No new tests added for the expand/collapse interactions. The PR description mentions
pnpm testas validation but does not include unit or integration tests for the new state (isPromptExpanded), resize logic, or Escape key behavior. Consider adding Vitest tests forresizeTextareaand a Playwright interaction test for the expand button. -
[Minor] The component uses several hardcoded sizing values (
h-[14px],w-[14px],p-1.5,text-[14px],leading-[1.55],pl-[14px],pr-[36px],pt-[12px],pb-[44px]) instead of tokens frompackages/ui. The existing codebase already has many such values, so this is consistent with current practice, but note that the project hard constraint "Every UI value viapackages/uitokens" is not fully satisfied. Ideally, these values should be defined as CSS custom properties or design tokens.
Questions
- None
Summary
Review mode: initial. The PR adds a clean inline expand/collapse mechanism for the prompt composer with smooth transitions, i18n labels, and correct store wiring. The changes are scoped and follow existing patterns. No blockers or majors found. The main concerns are the focusable-but-invisible expand button (accessibility), the unnecessary condition in the resize effect, missing test coverage, and partial non-compliance with the UI token constraint (pre-existing pattern). Address the accessibility issue before merging.
Testing
- Not run (automation).
- Suggested: Vitest unit test for
resizeTextareaedge cases (zero height, overflow threshold). Playwright test to verify expand/collapse click interaction and Escape key collapse.
Open-CoDesign Bot
Summary
Validation
pnpm lint -- apps/desktop/src/renderer/src/App.tsx apps/desktop/src/renderer/src/components/chat/PromptInput.tsx apps/desktop/src/renderer/src/store.ts packages/i18n/src/locales/en.json packages/i18n/src/locales/zh-CN.json packages/i18n/src/locales/pt-BR.jsonpnpm --filter @open-codesign/desktop typecheckpnpm --filter @open-codesign/i18n testpnpm --filter @open-codesign/desktop testturbo run test