-
Notifications
You must be signed in to change notification settings - Fork 3.1k
feat(vscode): add Display setting for prompt navigator rail position #13338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "kilo-code": minor | ||
| --- | ||
|
|
||
| Add a Display setting to choose whether the prompt navigator rail sits on the left or right edge of the chat. The rail, its hover card, and its open animation mirror to the selected side, and the choice applies everywhere the transcript is shown, including the sidebar, Kilo editor tabs, the sub-agent viewer, and Agent Manager. Left remains the default. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
|
|
||
| /** | ||
| * PromptRail component | ||
| * Thin vertical summary rail on the left edge of the transcript. Hovering or | ||
| * Thin vertical summary rail on the edge of the transcript. Hovering or | ||
| * focusing opens a bounded navigator for every loaded prompt; clicking jumps | ||
| * the virtualized transcript without mounting the intervening rows. | ||
| */ | ||
|
|
@@ -15,8 +15,10 @@ import { Portal } from "solid-js/web" | |
| import { VList, type VListHandle } from "virtua/solid" | ||
| import { useLanguage } from "../../context/language" | ||
| import { RAIL_INSET, ROW_HEIGHT, TICK_MIN, TICK_STEP, type PromptRailEntry, type PromptRailItem } from "./prompt-rail" | ||
| import type { PromptRailPosition } from "../../types/messages" | ||
|
|
||
| interface PromptRailProps { | ||
| position: Accessor<PromptRailPosition> | ||
| entries: Accessor<PromptRailEntry[]> | ||
| items: Accessor<PromptRailItem[]> | ||
| /** Row key of the item whose turn is currently at the top of the transcript. */ | ||
|
|
@@ -47,7 +49,7 @@ export function PromptRail(props: PromptRailProps) { | |
| const [open, setOpen] = createSignal(false) | ||
| const [hover, setHover] = createSignal<string>() | ||
| const [focused, setFocused] = createSignal<number>() | ||
| const [anchor, setAnchor] = createSignal<{ top: number; left: number; height: number }>() | ||
| const [anchor, setAnchor] = createSignal<{ top: number; left?: number; right?: number; height: number }>() | ||
| let rail: HTMLElement | undefined | ||
| let card: HTMLDivElement | undefined | ||
| let list: VListHandle | undefined | ||
|
|
@@ -86,6 +88,12 @@ export function PromptRail(props: PromptRailProps) { | |
| // and the card never rides up over the task header or down over the composer. | ||
| // Before the card is mounted its height is estimated from the row count; the | ||
| // measured value takes over on the next frame, inside the fade-in. | ||
| // | ||
| // The side is anchored physically so the card always opens inward, away from | ||
| // the panel edge: only one of left/right is ever set, because a fixed element | ||
| // given both and no width stretches to span the gap between them. This math | ||
| // is physical in both directions, which is why .prompt-rail places itself | ||
| // with physical left/right instead of logical insets. | ||
| const place = () => { | ||
| if (!rail) return | ||
| const rect = rail.getBoundingClientRect() | ||
|
|
@@ -96,9 +104,11 @@ export function PromptRail(props: PromptRailProps) { | |
| const min = Math.max(EDGE, rect.top + 4) | ||
| const max = Math.min(window.innerHeight - EDGE, rect.bottom - 4) - height | ||
| const center = rect.top + rect.height / 2 - height / 2 | ||
| const isRight = props.position() === "right" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WARNING: Right-edge placement mixes logical CSS with physical card math, which breaks RTL
Suggestion: use physical Reply with |
||
| setAnchor({ | ||
| top: max < min ? min : Math.min(Math.max(center, min), max), | ||
| left: rect.right + GAP, | ||
| left: isRight ? undefined : rect.right + GAP, | ||
| right: isRight ? window.innerWidth - rect.left + GAP : undefined, | ||
| height: limit, | ||
| }) | ||
| } | ||
|
|
@@ -252,6 +262,16 @@ export function PromptRail(props: PromptRailProps) { | |
| props.onLatest() | ||
| } | ||
|
|
||
| const cardStyle = (position: { top: number; left?: number; right?: number; height: number }) => { | ||
| const style: Record<string, string> = { | ||
| top: `${position.top}px`, | ||
| "--prompt-rail-card-height": `${position.height}px`, | ||
| } | ||
| if (position.left !== undefined) style.left = `${position.left}px` | ||
| if (position.right !== undefined) style.right = `${position.right}px` | ||
| return style | ||
| } | ||
|
|
||
| const row = (item: PromptRailItem, index: Accessor<number>) => ( | ||
| <button | ||
| type="button" | ||
|
|
@@ -279,6 +299,7 @@ export function PromptRail(props: PromptRailProps) { | |
| <nav | ||
| ref={rail} | ||
| class="prompt-rail" | ||
| data-position={props.position()} | ||
| aria-label={language.t("session.prompts.navLabel")} | ||
| style={{ "--prompt-rail-step": `${step()}px` }} | ||
| onMouseLeave={closeCard} | ||
|
|
@@ -328,14 +349,11 @@ export function PromptRail(props: PromptRailProps) { | |
| <div | ||
| ref={card} | ||
| class="prompt-rail-card" | ||
| data-position={props.position()} | ||
| data-virtualized={virtualized() || undefined} | ||
| role="dialog" | ||
| aria-label={language.t("session.prompts.navLabel")} | ||
| style={{ | ||
| top: `${position().top}px`, | ||
| left: `${position().left}px`, | ||
| "--prompt-rail-card-height": `${position().height}px`, | ||
| }} | ||
| style={cardStyle(position())} | ||
| onMouseEnter={cancelClose} | ||
| onMouseLeave={closeCard} | ||
| onWheel={(event) => { | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SUGGESTION: Mirror
prompt_rail_positionin the cloud config JSON SchemaThis file notes that new
kilocode_changekeys onConfig.Infomust also be added inapps/web/src/app/config.json/extras.tsin the cloud repo. Until that lands,$schema: https://app.kilo.ai/config.jsonwill treat the key as unknown. CI does not check this.Reply with
@kilocode-bot fix itto have Kilo Code address this issue.