Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .claude/rules/ui-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,34 @@ and keep the callbacks in the dependency array identity-stable (`useCallback`
with functional `setState`) so the listener is not torn down and rebuilt on
every render. See `src/components/schedule/schedule-grid.tsx`.

## Textarea that must fill, not grow: `min-h-0` + `field-sizing-fixed`

The shared `Textarea` (`src/components/ui/textarea.tsx`) carries
`field-sizing-content`, so it sizes itself to its content. That is the right
default for a form field, but it is wrong for a textarea meant to fill the
remaining height of a fixed-height layout — `h-full` alone does not stop it.

Two things break at once. The flex item wrapping the textarea defaults to
`min-height: auto`, so it cannot shrink below its content; and with no
definite height on the wrapper, `height: 100%` on the textarea cannot
resolve and falls back to content sizing. The row then grows past the
container, and whatever sits below it is clipped by the container's
`overflow-hidden` — silently, since nothing scrolls.

When the textarea should fill and scroll instead:

```tsx
<div className="relative min-h-0 flex-1">
<Textarea className="h-full min-h-0 field-sizing-fixed resize-none overflow-auto" />
</div>
```

`min-h-0` is needed on **both** the wrapper and the textarea. This bit the
quick-capture window, where a long description hid the "Save to inbox" button
entirely (T-0102); the maximized editor in `task-dialog.tsx` uses the same
idiom. Textareas that genuinely should grow (`notes-dialog`,
`settings-dialog`, `schedule/*`) keep the default.

## Selection state: keep the id, look up the object

When a view owns a document and a side panel edits one element of it, store
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/quick_capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ pub fn create_window(app: &AppHandle) -> tauri::Result<()> {
)
.title("workhub — quick capture")
.inner_size(width, height)
// Below this the form's footer (Save to inbox) stops fitting.
.min_inner_size(360.0, 260.0)
.always_on_top(true)
.skip_taskbar(true)
.decorations(false)
Expand Down
8 changes: 6 additions & 2 deletions src/quick-capture/capture-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,17 @@ export function CaptureApp() {
placeholder="Task title"
className="h-8"
/>
<div className="relative flex-1">
{/* min-h-0 on both the wrapper and the textarea, plus
field-sizing-fixed: without them the shared Textarea's
grow-with-content sizing expands this row past the window and the
footer (Save to inbox) is clipped by the container's overflow. */}
<div className="relative min-h-0 flex-1">
<Textarea
ref={descriptionRef}
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Description (a copied Slack / PR / monday link is pasted here)"
className="h-full resize-none pr-8 font-mono text-xs"
className="h-full min-h-0 field-sizing-fixed resize-none overflow-auto pr-8 font-mono text-xs"
/>
{description && (
<Button
Expand Down
Loading