wip(app): line selection
This commit is contained in:
@@ -167,18 +167,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
|
|||||||
return files.pathFromTab(tab)
|
return files.pathFromTab(tab)
|
||||||
})
|
})
|
||||||
|
|
||||||
const selectionPreview = (path: string, selection?: FileSelection, preview?: string) => {
|
|
||||||
if (preview) return preview
|
|
||||||
if (!selection) return undefined
|
|
||||||
const content = files.get(path)?.content?.content
|
|
||||||
if (!content) return undefined
|
|
||||||
const start = Math.max(1, Math.min(selection.startLine, selection.endLine))
|
|
||||||
const end = Math.max(selection.startLine, selection.endLine)
|
|
||||||
const lines = content.split("\n").slice(start - 1, end)
|
|
||||||
if (lines.length === 0) return undefined
|
|
||||||
return lines.slice(0, 2).join("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
const activeFileSelection = createMemo(() => {
|
const activeFileSelection = createMemo(() => {
|
||||||
const path = activeFile()
|
const path = activeFile()
|
||||||
if (!path) return
|
if (!path) return
|
||||||
@@ -186,11 +174,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
|
|||||||
if (!range) return
|
if (!range) return
|
||||||
return selectionFromLines(range)
|
return selectionFromLines(range)
|
||||||
})
|
})
|
||||||
const activeSelectionPreview = createMemo(() => {
|
|
||||||
const path = activeFile()
|
|
||||||
if (!path) return
|
|
||||||
return selectionPreview(path, activeFileSelection())
|
|
||||||
})
|
|
||||||
const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined))
|
const info = createMemo(() => (params.id ? sync.session.get(params.id) : undefined))
|
||||||
const status = createMemo(
|
const status = createMemo(
|
||||||
() =>
|
() =>
|
||||||
@@ -1534,13 +1517,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
|
|||||||
aria-label={language.t("prompt.context.removeActiveFile")}
|
aria-label={language.t("prompt.context.removeActiveFile")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Show when={activeSelectionPreview()}>
|
|
||||||
{(preview) => (
|
|
||||||
<pre class="text-10-regular text-text-weak font-mono whitespace-pre-wrap leading-4">
|
|
||||||
{preview()}
|
|
||||||
</pre>
|
|
||||||
)}
|
|
||||||
</Show>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Show>
|
</Show>
|
||||||
|
|||||||
@@ -2074,13 +2074,14 @@ export default function Page() {
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="flex items-center gap-2 px-2 py-1 rounded-md bg-surface-raised-stronger-non-alpha border border-border-base text-12-regular text-text-strong hover:bg-surface-raised-base-hover"
|
class="group relative flex items-center gap-2 h-6 px-2.5 rounded-md bg-surface-raised-stronger-non-alpha border border-border-weak-base text-12-medium text-text-strong shadow-xs-border whitespace-nowrap hover:bg-surface-raised-stronger-hover hover:border-border-hover focus:outline-none focus-visible:shadow-xs-border-focus"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const p = path()
|
const p = path()
|
||||||
if (!p) return
|
if (!p) return
|
||||||
addSelectionToContext(p, sel())
|
addSelectionToContext(p, sel())
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<span class="pointer-events-none absolute -left-1 top-1/2 size-2.5 -translate-y-1/2 rotate-45 bg-surface-raised-stronger-non-alpha border-l border-b border-border-weak-base group-hover:bg-surface-raised-stronger-hover group-hover:border-border-hover" />
|
||||||
<Icon name="plus-small" size="small" />
|
<Icon name="plus-small" size="small" />
|
||||||
<span>
|
<span>
|
||||||
{language.t("session.context.addToContext", {
|
{language.t("session.context.addToContext", {
|
||||||
|
|||||||
@@ -60,8 +60,8 @@
|
|||||||
ol {
|
ol {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
padding-left: 0;
|
padding-left: 1.5rem;
|
||||||
list-style-position: inside;
|
list-style-position: outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
@@ -76,6 +76,16 @@
|
|||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li > p:first-child {
|
||||||
|
display: inline;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li > p + p {
|
||||||
|
display: block;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
li::marker {
|
li::marker {
|
||||||
color: var(--text-weak);
|
color: var(--text-weak);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export interface PopoverProps<T extends ValidComponent = "div">
|
|||||||
description?: JSXElement
|
description?: JSXElement
|
||||||
class?: ComponentProps<"div">["class"]
|
class?: ComponentProps<"div">["class"]
|
||||||
classList?: ComponentProps<"div">["classList"]
|
classList?: ComponentProps<"div">["classList"]
|
||||||
|
portal?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Popover<T extends ValidComponent = "div">(props: PopoverProps<T>) {
|
export function Popover<T extends ValidComponent = "div">(props: PopoverProps<T>) {
|
||||||
@@ -26,40 +27,45 @@ export function Popover<T extends ValidComponent = "div">(props: PopoverProps<T>
|
|||||||
"class",
|
"class",
|
||||||
"classList",
|
"classList",
|
||||||
"children",
|
"children",
|
||||||
|
"portal",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const content = () => (
|
||||||
|
<Kobalte.Content
|
||||||
|
data-component="popover-content"
|
||||||
|
classList={{
|
||||||
|
...(local.classList ?? {}),
|
||||||
|
[local.class ?? ""]: !!local.class,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* <Kobalte.Arrow data-slot="popover-arrow" /> */}
|
||||||
|
<Show when={local.title}>
|
||||||
|
<div data-slot="popover-header">
|
||||||
|
<Kobalte.Title data-slot="popover-title">{local.title}</Kobalte.Title>
|
||||||
|
<Kobalte.CloseButton
|
||||||
|
data-slot="popover-close-button"
|
||||||
|
as={IconButton}
|
||||||
|
icon="close"
|
||||||
|
variant="ghost"
|
||||||
|
aria-label={i18n.t("ui.common.close")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
<Show when={local.description}>
|
||||||
|
<Kobalte.Description data-slot="popover-description">{local.description}</Kobalte.Description>
|
||||||
|
</Show>
|
||||||
|
<div data-slot="popover-body">{local.children}</div>
|
||||||
|
</Kobalte.Content>
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Kobalte gutter={4} {...rest}>
|
<Kobalte gutter={4} {...rest}>
|
||||||
<Kobalte.Trigger as={local.triggerAs ?? "div"} data-slot="popover-trigger" {...(local.triggerProps as any)}>
|
<Kobalte.Trigger as={local.triggerAs ?? "div"} data-slot="popover-trigger" {...(local.triggerProps as any)}>
|
||||||
{local.trigger}
|
{local.trigger}
|
||||||
</Kobalte.Trigger>
|
</Kobalte.Trigger>
|
||||||
<Kobalte.Portal>
|
<Show when={local.portal ?? true} fallback={content()}>
|
||||||
<Kobalte.Content
|
<Kobalte.Portal>{content()}</Kobalte.Portal>
|
||||||
data-component="popover-content"
|
</Show>
|
||||||
classList={{
|
|
||||||
...(local.classList ?? {}),
|
|
||||||
[local.class ?? ""]: !!local.class,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{/* <Kobalte.Arrow data-slot="popover-arrow" /> */}
|
|
||||||
<Show when={local.title}>
|
|
||||||
<div data-slot="popover-header">
|
|
||||||
<Kobalte.Title data-slot="popover-title">{local.title}</Kobalte.Title>
|
|
||||||
<Kobalte.CloseButton
|
|
||||||
data-slot="popover-close-button"
|
|
||||||
as={IconButton}
|
|
||||||
icon="close"
|
|
||||||
variant="ghost"
|
|
||||||
aria-label={i18n.t("ui.common.close")}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
<Show when={local.description}>
|
|
||||||
<Kobalte.Description data-slot="popover-description">{local.description}</Kobalte.Description>
|
|
||||||
</Show>
|
|
||||||
<div data-slot="popover-body">{local.children}</div>
|
|
||||||
</Kobalte.Content>
|
|
||||||
</Kobalte.Portal>
|
|
||||||
</Kobalte>
|
</Kobalte>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,6 +198,7 @@
|
|||||||
|
|
||||||
[data-slot="session-review-diff-wrapper"] {
|
[data-slot="session-review-diff-wrapper"] {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-slot="session-review-comment-anchor"] {
|
[data-slot="session-review-comment-anchor"] {
|
||||||
@@ -213,15 +214,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: var(--surface-base);
|
background: var(--surface-warning-base);
|
||||||
border: 1px solid color-mix(in oklch, var(--icon-info-active) 60%, transparent);
|
border: 1px solid var(--border-warning-base);
|
||||||
color: var(--icon-info-active);
|
color: var(--icon-warning-active);
|
||||||
box-shadow: var(--shadow-xs-border);
|
box-shadow: var(--shadow-xs);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--surface-raised-base-hover);
|
background: var(--surface-warning-weak);
|
||||||
border-color: var(--icon-info-active);
|
border-color: var(--border-warning-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
@@ -240,6 +241,12 @@
|
|||||||
max-width: 320px;
|
max-width: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-slot="session-review-comment-popover"] {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
[data-slot="session-review-comment-hover-label"],
|
[data-slot="session-review-comment-hover-label"],
|
||||||
[data-slot="session-review-comment-popover-label"] {
|
[data-slot="session-review-comment-popover-label"] {
|
||||||
font-family: var(--font-family-sans);
|
font-family: var(--font-family-sans);
|
||||||
|
|||||||
@@ -581,6 +581,7 @@ export const SessionReview = (props: SessionReviewProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Popover
|
<Popover
|
||||||
|
portal={false}
|
||||||
open={isCommentOpen(comment)}
|
open={isCommentOpen(comment)}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
if (open) {
|
if (open) {
|
||||||
@@ -632,6 +633,7 @@ export const SessionReview = (props: SessionReviewProps) => {
|
|||||||
<Show when={draftTop() !== undefined}>
|
<Show when={draftTop() !== undefined}>
|
||||||
<div data-slot="session-review-comment-anchor" style={{ top: `${draftTop() ?? 0}px` }}>
|
<div data-slot="session-review-comment-anchor" style={{ top: `${draftTop() ?? 0}px` }}>
|
||||||
<Popover
|
<Popover
|
||||||
|
portal={false}
|
||||||
open={true}
|
open={true}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
if (open) return
|
if (open) return
|
||||||
|
|||||||
@@ -32,11 +32,12 @@ const unsafeCSS = `
|
|||||||
--diffs-bg-addition-number: var(--diffs-bg-addition-number-override, light-dark( color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-addition-base)), color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-addition-base))));
|
--diffs-bg-addition-number: var(--diffs-bg-addition-number-override, light-dark( color-mix(in lab, var(--diffs-bg) 91%, var(--diffs-addition-base)), color-mix(in lab, var(--diffs-bg) 85%, var(--diffs-addition-base))));
|
||||||
--diffs-bg-addition-hover: var(--diffs-bg-addition-hover-override, light-dark( color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-addition-base)), color-mix(in lab, var(--diffs-bg) 70%, var(--diffs-addition-base))));
|
--diffs-bg-addition-hover: var(--diffs-bg-addition-hover-override, light-dark( color-mix(in lab, var(--diffs-bg) 80%, var(--diffs-addition-base)), color-mix(in lab, var(--diffs-bg) 70%, var(--diffs-addition-base))));
|
||||||
--diffs-bg-addition-emphasis: var(--diffs-bg-addition-emphasis-override, light-dark(rgb(from var(--diffs-addition-base) r g b / 0.07), rgb(from var(--diffs-addition-base) r g b / 0.1)));
|
--diffs-bg-addition-emphasis: var(--diffs-bg-addition-emphasis-override, light-dark(rgb(from var(--diffs-addition-base) r g b / 0.07), rgb(from var(--diffs-addition-base) r g b / 0.1)));
|
||||||
--diffs-selection-base: var(--text-interactive-base);
|
--diffs-selection-base: var(--surface-warning-strong);
|
||||||
--diffs-selection-number-fg: light-dark( color-mix(in lab, var(--diffs-selection-base) 65%, var(--diffs-mixer)), color-mix(in lab, var(--diffs-selection-base) 75%, var(--diffs-mixer)));
|
--diffs-selection-border: var(--border-warning-base);
|
||||||
--diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--diffs-selection-base) r g b / 0.18));
|
--diffs-selection-number-fg: var(--text-on-warning-strong);
|
||||||
--diffs-bg-selection-number: var(--diffs-bg-selection-number-override, rgb(from var(--diffs-selection-base) r g b / 0.22));
|
--diffs-bg-selection: var(--diffs-bg-selection-override, color-mix(in oklch, var(--surface-warning-base) 65%, transparent));
|
||||||
--diffs-bg-selection-text: rgb(from var(--diffs-selection-base) r g b / 0.12);
|
--diffs-bg-selection-number: var(--diffs-bg-selection-number-override, color-mix(in oklch, var(--surface-warning-base) 85%, transparent));
|
||||||
|
--diffs-bg-selection-text: color-mix(in oklch, var(--surface-warning-strong) 20%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-diffs] ::selection {
|
[data-diffs] ::selection {
|
||||||
@@ -52,6 +53,16 @@ const unsafeCSS = `
|
|||||||
color: var(--diffs-selection-number-fg);
|
color: var(--diffs-selection-number-fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-diffs] [data-selected-line] {
|
||||||
|
background-color: var(--diffs-bg-selection);
|
||||||
|
box-shadow: inset 2px 0 0 var(--diffs-selection-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-diffs] [data-selected-line] [data-column-number] {
|
||||||
|
background-color: var(--diffs-bg-selection-number);
|
||||||
|
color: var(--diffs-selection-number-fg);
|
||||||
|
}
|
||||||
|
|
||||||
[data-diffs-header],
|
[data-diffs-header],
|
||||||
[data-diffs] {
|
[data-diffs] {
|
||||||
[data-separator-wrapper] {
|
[data-separator-wrapper] {
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ a {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
-webkit-text-decoration: inherit;
|
-webkit-text-decoration: inherit;
|
||||||
text-decoration: inherit;
|
text-decoration: inherit;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
*[data-tauri-drag-region] {
|
||||||
|
app-region: drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user