summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoradamelmore <[email protected]>2026-01-24 12:19:39 -0600
committeradamelmore <[email protected]>2026-01-24 12:41:50 -0600
commit42b802b688f92e7077c5a828df4c62296c326bbf (patch)
tree00f4b6f5d48680e7dc9123f9ec92a999b7196260
parentfa1a54ba3d44a584cfeea23de0364cbbaba449f1 (diff)
downloadopencode-42b802b688f92e7077c5a828df4c62296c326bbf.tar.gz
opencode-42b802b688f92e7077c5a828df4c62296c326bbf.zip
fix(app): line selection ux fixes
-rw-r--r--packages/ui/src/components/code.tsx29
-rw-r--r--packages/ui/src/components/diff.tsx37
-rw-r--r--packages/ui/src/components/line-comment.css2
-rw-r--r--packages/ui/src/components/session-review.tsx2
-rw-r--r--packages/ui/src/pierre/index.ts9
5 files changed, 57 insertions, 22 deletions
diff --git a/packages/ui/src/components/code.tsx b/packages/ui/src/components/code.tsx
index 16a915d9d..eb0ba7826 100644
--- a/packages/ui/src/components/code.tsx
+++ b/packages/ui/src/components/code.tsx
@@ -66,28 +66,16 @@ export function Code<T>(props: CodeProps<T>) {
"selectedLines",
"commentedLines",
"onRendered",
- "onLineSelectionEnd",
])
const [rendered, setRendered] = createSignal(0)
- const handleLineClick: FileOptions<T>["onLineClick"] = (info) => {
- props.onLineClick?.(info)
-
- if (props.enableLineSelection !== true) return
- if (info.numberColumn) return
- if (!local.selectedLines) return
-
- file().setSelectedLines(null)
- }
-
const file = createMemo(
() =>
new File<T>(
{
...createDefaultOptions<T>("unified"),
...others,
- onLineClick: props.enableLineSelection === true || props.onLineClick ? handleLineClick : undefined,
},
getWorkerPool("unified"),
),
@@ -332,12 +320,21 @@ export function Code<T>(props: CodeProps<T>) {
if (props.enableLineSelection !== true) return
if (dragStart === undefined) return
- if (dragMoved) {
- pendingSelectionEnd = true
- scheduleDragUpdate()
- scheduleSelectionUpdate()
+ if (!dragMoved) {
+ pendingSelectionEnd = false
+ const line = dragStart
+ setSelectedLines({ start: line, end: line })
+ props.onLineSelectionEnd?.(lastSelection)
+ dragStart = undefined
+ dragEnd = undefined
+ dragMoved = false
+ return
}
+ pendingSelectionEnd = true
+ scheduleDragUpdate()
+ scheduleSelectionUpdate()
+
dragStart = undefined
dragEnd = undefined
dragMoved = false
diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx
index 825a7e076..5aff93d1d 100644
--- a/packages/ui/src/components/diff.tsx
+++ b/packages/ui/src/components/diff.tsx
@@ -35,6 +35,13 @@ function findSide(node: Node | null): SelectionSide | undefined {
const element = findElement(node)
if (!element) return
+ const line = element.closest("[data-line], [data-alt-line]")
+ if (line instanceof HTMLElement) {
+ const type = line.dataset.lineType
+ if (type === "change-deletion") return "deletions"
+ if (type === "change-addition" || type === "change-additions") return "additions"
+ }
+
const code = element.closest("[data-code]")
if (!(code instanceof HTMLElement)) return
@@ -303,6 +310,12 @@ export function Diff<T>(props: DiffProps<T>) {
numberColumn = numberColumn || item.dataset.columnNumber != null
+ if (side === undefined) {
+ const type = item.dataset.lineType
+ if (type === "change-deletion") side = "deletions"
+ if (type === "change-addition" || type === "change-additions") side = "additions"
+ }
+
if (side === undefined && item.dataset.code != null) {
side = item.hasAttribute("data-deletions") ? "deletions" : "additions"
}
@@ -364,12 +377,28 @@ export function Diff<T>(props: DiffProps<T>) {
if (props.enableLineSelection !== true) return
if (dragStart === undefined) return
- if (dragMoved) {
- pendingSelectionEnd = true
- scheduleDragUpdate()
- scheduleSelectionUpdate()
+ if (!dragMoved) {
+ pendingSelectionEnd = false
+ const line = dragStart
+ const selected: SelectedLineRange = {
+ start: line,
+ end: line,
+ }
+ if (dragSide) selected.side = dragSide
+ setSelectedLines(selected)
+ props.onLineSelectionEnd?.(lastSelection)
+ dragStart = undefined
+ dragEnd = undefined
+ dragSide = undefined
+ dragEndSide = undefined
+ dragMoved = false
+ return
}
+ pendingSelectionEnd = true
+ scheduleDragUpdate()
+ scheduleSelectionUpdate()
+
dragStart = undefined
dragEnd = undefined
dragSide = undefined
diff --git a/packages/ui/src/components/line-comment.css b/packages/ui/src/components/line-comment.css
index 1cdf78189..d497f7fcd 100644
--- a/packages/ui/src/components/line-comment.css
+++ b/packages/ui/src/components/line-comment.css
@@ -13,7 +13,7 @@
justify-content: center;
background: var(--icon-interactive-base);
box-shadow: var(--shadow-xs);
- cursor: pointer;
+ cursor: default;
border: none;
}
diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx
index 2b6d93e2d..1174cf2f3 100644
--- a/packages/ui/src/components/session-review.tsx
+++ b/packages/ui/src/components/session-review.tsx
@@ -618,7 +618,7 @@ export const SessionReview = (props: SessionReviewProps) => {
/>
<div data-slot="session-review-comment-actions">
<div data-slot="session-review-comment-draft-label">
- Commenting on {getFilename(diff.file)}:{selectionLabel(range())}
+ Commenting on {selectionLabel(range())}
</div>
<Button size="small" variant="ghost" onClick={() => setCommenting(null)}>
Cancel
diff --git a/packages/ui/src/pierre/index.ts b/packages/ui/src/pierre/index.ts
index cef515613..976f67eca 100644
--- a/packages/ui/src/pierre/index.ts
+++ b/packages/ui/src/pierre/index.ts
@@ -87,6 +87,15 @@ const unsafeCSS = `
}
[data-column-number] {
background-color: var(--background-stronger);
+ cursor: default !important;
+ }
+
+ &[data-interactive-line-numbers] [data-column-number] {
+ cursor: default !important;
+ }
+
+ &[data-interactive-lines] [data-line] {
+ cursor: auto !important;
}
[data-code] {
overflow-x: auto !important;