@opencode-ai/ui 1.17.13 → 1.17.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/scroll-view.d.ts +5 -0
- package/dist/v2/components/icon.d.ts +24 -0
- package/dist/v2/components/project-avatar-v2.d.ts +2 -1
- package/dist/v2/components/text-input-v2.d.ts +9 -2
- package/package.json +1 -1
- package/src/components/collapsible.css +6 -0
- package/src/components/scroll-view.tsx +67 -7
- package/src/components/tabs.css +47 -1
- package/src/context/marked.tsx +55 -9
- package/src/i18n/en.ts +18 -0
- package/src/styles/theme.css +18 -0
- package/src/theme/v2/mapping.ts +26 -0
- package/src/v2/components/file-tree-v2.css +120 -0
- package/src/v2/components/icon.tsx +24 -0
- package/src/v2/components/project-avatar-v2.css +7 -0
- package/src/v2/components/project-avatar-v2.tsx +4 -1
- package/src/v2/components/text-input-v2.css +33 -0
- package/src/v2/components/text-input-v2.tsx +31 -5
- package/src/v2/components/toast-v2.tsx +39 -37
- package/src/v2/components/tooltip-v2.css +5 -0
- package/src/v2/styles/theme.css +40 -0
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { type ComponentProps } from "solid-js";
|
|
2
|
+
export type ScrollViewThumbVisibility = "hover" | "scroll";
|
|
2
3
|
export interface ScrollViewProps extends ComponentProps<"div"> {
|
|
3
4
|
viewportRef?: (el: HTMLDivElement) => void;
|
|
4
5
|
orientation?: "vertical" | "horizontal";
|
|
6
|
+
thumbVisibility?: ScrollViewThumbVisibility;
|
|
5
7
|
}
|
|
6
8
|
export declare const scrollKey: (event: Pick<KeyboardEvent, "key" | "altKey" | "ctrlKey" | "metaKey" | "shiftKey">) => "end" | "home" | "page-down" | "page-up" | "up" | "down" | undefined;
|
|
9
|
+
export declare function canScrollKey(element: HTMLElement, key: NonNullable<ReturnType<typeof scrollKey>>): boolean;
|
|
10
|
+
export declare function scrollKeyOwner(root: HTMLElement, target: EventTarget | null, key: NonNullable<ReturnType<typeof scrollKey>>): HTMLElement;
|
|
11
|
+
export declare function isScrollKeyTarget(target: EventTarget | null, key: NonNullable<ReturnType<typeof scrollKey>>): boolean;
|
|
7
12
|
export declare function scrollTopFromThumbPointer(input: {
|
|
8
13
|
pointer: number;
|
|
9
14
|
viewportTop: number;
|
|
@@ -56,6 +56,10 @@ declare const icons: {
|
|
|
56
56
|
viewBox: string;
|
|
57
57
|
body: string;
|
|
58
58
|
};
|
|
59
|
+
collapse: {
|
|
60
|
+
viewBox: string;
|
|
61
|
+
body: string;
|
|
62
|
+
};
|
|
59
63
|
check: {
|
|
60
64
|
viewBox: string;
|
|
61
65
|
body: string;
|
|
@@ -92,6 +96,26 @@ declare const icons: {
|
|
|
92
96
|
viewBox: string;
|
|
93
97
|
body: string;
|
|
94
98
|
};
|
|
99
|
+
expand: {
|
|
100
|
+
viewBox: string;
|
|
101
|
+
body: string;
|
|
102
|
+
};
|
|
103
|
+
filetree: {
|
|
104
|
+
viewBox: string;
|
|
105
|
+
body: string;
|
|
106
|
+
};
|
|
107
|
+
split: {
|
|
108
|
+
viewBox: string;
|
|
109
|
+
body: string;
|
|
110
|
+
};
|
|
111
|
+
unified: {
|
|
112
|
+
viewBox: string;
|
|
113
|
+
body: string;
|
|
114
|
+
};
|
|
115
|
+
review: {
|
|
116
|
+
viewBox: string;
|
|
117
|
+
body: string;
|
|
118
|
+
};
|
|
95
119
|
"outline-sliders": {
|
|
96
120
|
viewBox: string;
|
|
97
121
|
body: string;
|
|
@@ -2,10 +2,11 @@ import { type ComponentProps } from "solid-js";
|
|
|
2
2
|
import "./project-avatar-v2.css";
|
|
3
3
|
export declare const PROJECT_AVATAR_VARIANTS: readonly ["orange", "yellow", "cyan", "green", "red", "pink", "blue", "purple", "gray"];
|
|
4
4
|
export type ProjectAvatarVariant = (typeof PROJECT_AVATAR_VARIANTS)[number];
|
|
5
|
+
export type ProjectAvatarStyle = ProjectAvatarVariant | "outline";
|
|
5
6
|
export interface ProjectAvatarProps extends ComponentProps<"div"> {
|
|
6
7
|
fallback: string;
|
|
7
8
|
src?: string;
|
|
8
|
-
variant?:
|
|
9
|
+
variant?: ProjectAvatarStyle;
|
|
9
10
|
unread?: boolean;
|
|
10
11
|
}
|
|
11
12
|
export declare function ProjectAvatar(props: ProjectAvatarProps): import("solid-js").JSX.Element;
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { type ComponentProps } from "solid-js";
|
|
1
|
+
import { type ComponentProps, type JSX } from "solid-js";
|
|
2
2
|
import "./text-input-v2.css";
|
|
3
3
|
export interface TextInputV2Props extends Omit<ComponentProps<"input">, "type"> {
|
|
4
|
+
/** Icon or adornment shown before the field value. */
|
|
5
|
+
leadingIcon?: JSX.Element;
|
|
4
6
|
/** Show the trailing copy action. */
|
|
5
7
|
showCopyButton?: boolean;
|
|
8
|
+
/** Show the trailing clear action. */
|
|
9
|
+
showClearButton?: boolean;
|
|
6
10
|
/** Accessible label for the copy button. */
|
|
7
11
|
copyLabel?: string;
|
|
12
|
+
/** Accessible label for the clear button. */
|
|
13
|
+
clearLabel?: string;
|
|
8
14
|
onCopyClick?: (event: MouseEvent) => void;
|
|
15
|
+
onClearClick?: (event: MouseEvent) => void;
|
|
9
16
|
/** Apply tabular numerals to the field value. */
|
|
10
17
|
numeric?: boolean;
|
|
11
18
|
/** Error styling for the field and value text. */
|
|
@@ -14,4 +21,4 @@ export interface TextInputV2Props extends Omit<ComponentProps<"input">, "type">
|
|
|
14
21
|
appearance?: "base" | "large";
|
|
15
22
|
type?: ComponentProps<"input">["type"];
|
|
16
23
|
}
|
|
17
|
-
export declare function TextInputV2(props: TextInputV2Props):
|
|
24
|
+
export declare function TextInputV2(props: TextInputV2Props): JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { onMount, splitProps, type ComponentProps, Show, mergeProps } from "solid-js"
|
|
1
|
+
import { onCleanup, onMount, splitProps, type ComponentProps, Show, mergeProps } from "solid-js"
|
|
2
2
|
import { createResizeObserver } from "@solid-primitives/resize-observer"
|
|
3
3
|
import { createStore } from "solid-js/store"
|
|
4
4
|
import { useI18n } from "../context/i18n"
|
|
5
5
|
|
|
6
|
+
export type ScrollViewThumbVisibility = "hover" | "scroll"
|
|
7
|
+
|
|
6
8
|
export interface ScrollViewProps extends ComponentProps<"div"> {
|
|
7
9
|
viewportRef?: (el: HTMLDivElement) => void
|
|
8
10
|
orientation?: "vertical" | "horizontal" // currently only vertical is fully implemented for thumb
|
|
11
|
+
thumbVisibility?: ScrollViewThumbVisibility
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
export const scrollKey = (event: Pick<KeyboardEvent, "key" | "altKey" | "ctrlKey" | "metaKey" | "shiftKey">) => {
|
|
12
|
-
if (event.altKey || event.ctrlKey || event.metaKey
|
|
15
|
+
if (event.altKey || event.ctrlKey || event.metaKey) return
|
|
16
|
+
if (event.shiftKey && event.key !== " ") return
|
|
13
17
|
|
|
14
18
|
switch (event.key) {
|
|
15
19
|
case "PageDown":
|
|
@@ -24,9 +28,36 @@ export const scrollKey = (event: Pick<KeyboardEvent, "key" | "altKey" | "ctrlKey
|
|
|
24
28
|
return "up"
|
|
25
29
|
case "ArrowDown":
|
|
26
30
|
return "down"
|
|
31
|
+
case " ":
|
|
32
|
+
return event.shiftKey ? "page-up" : "page-down"
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
export function canScrollKey(element: HTMLElement, key: NonNullable<ReturnType<typeof scrollKey>>) {
|
|
37
|
+
const up = key === "up" || key === "page-up" || key === "home"
|
|
38
|
+
return up ? element.scrollTop > 0 : element.scrollTop + element.clientHeight < element.scrollHeight
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function scrollKeyOwner(
|
|
42
|
+
root: HTMLElement,
|
|
43
|
+
target: EventTarget | null,
|
|
44
|
+
key: NonNullable<ReturnType<typeof scrollKey>>,
|
|
45
|
+
) {
|
|
46
|
+
const element = target instanceof Element ? target : undefined
|
|
47
|
+
const owner = element?.closest<HTMLElement>("[data-scrollable]")
|
|
48
|
+
if (!owner || owner === root) return root
|
|
49
|
+
if (!root.contains(owner)) return owner
|
|
50
|
+
return canScrollKey(owner, key) ? owner : root
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function isScrollKeyTarget(target: EventTarget | null, key: NonNullable<ReturnType<typeof scrollKey>>) {
|
|
54
|
+
const element = target instanceof HTMLElement ? target : undefined
|
|
55
|
+
if (!element) return true
|
|
56
|
+
if (["INPUT", "TEXTAREA", "SELECT"].includes(element.tagName) || element.isContentEditable) return false
|
|
57
|
+
if ((key === "page-up" || key === "page-down") && element.closest('button, a[href], [role="button"]')) return false
|
|
58
|
+
return true
|
|
59
|
+
}
|
|
60
|
+
|
|
30
61
|
export function scrollTopFromThumbPointer(input: {
|
|
31
62
|
pointer: number
|
|
32
63
|
viewportTop: number
|
|
@@ -44,10 +75,10 @@ export function scrollTopFromThumbPointer(input: {
|
|
|
44
75
|
|
|
45
76
|
export function ScrollView(props: ScrollViewProps) {
|
|
46
77
|
const i18n = useI18n()
|
|
47
|
-
const merged = mergeProps({ orientation: "vertical" }, props)
|
|
78
|
+
const merged = mergeProps({ orientation: "vertical", thumbVisibility: "hover" }, props)
|
|
48
79
|
const [local, events, rest] = splitProps(
|
|
49
80
|
merged,
|
|
50
|
-
["class", "children", "viewportRef", "orientation", "style"],
|
|
81
|
+
["class", "children", "viewportRef", "orientation", "thumbVisibility", "style"],
|
|
51
82
|
[
|
|
52
83
|
"onScroll",
|
|
53
84
|
"onWheel",
|
|
@@ -68,16 +99,37 @@ export function ScrollView(props: ScrollViewProps) {
|
|
|
68
99
|
const [state, setState] = createStore({
|
|
69
100
|
isHovered: false,
|
|
70
101
|
isDragging: false,
|
|
102
|
+
isScrolling: false,
|
|
71
103
|
thumbHeight: 0,
|
|
72
104
|
thumbTop: 0,
|
|
73
105
|
showThumb: false,
|
|
74
106
|
})
|
|
75
107
|
const isHovered = () => state.isHovered
|
|
76
108
|
const isDragging = () => state.isDragging
|
|
109
|
+
const isScrolling = () => state.isScrolling
|
|
77
110
|
const thumbHeight = () => state.thumbHeight
|
|
78
111
|
const thumbTop = () => state.thumbTop
|
|
79
112
|
const showThumb = () => state.showThumb
|
|
80
113
|
|
|
114
|
+
let scrollIdleTimer: ReturnType<typeof setTimeout> | undefined
|
|
115
|
+
|
|
116
|
+
const markScrolling = () => {
|
|
117
|
+
if (local.thumbVisibility !== "scroll") return
|
|
118
|
+
setState("isScrolling", true)
|
|
119
|
+
if (scrollIdleTimer !== undefined) clearTimeout(scrollIdleTimer)
|
|
120
|
+
scrollIdleTimer = setTimeout(() => setState("isScrolling", false), 800)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const thumbVisible = () => {
|
|
124
|
+
if (isDragging()) return true
|
|
125
|
+
if (local.thumbVisibility === "scroll") return isScrolling()
|
|
126
|
+
return isHovered()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
onCleanup(() => {
|
|
130
|
+
if (scrollIdleTimer !== undefined) clearTimeout(scrollIdleTimer)
|
|
131
|
+
})
|
|
132
|
+
|
|
81
133
|
const updateThumb = () => {
|
|
82
134
|
if (!viewportRef) return
|
|
83
135
|
const { scrollTop, scrollHeight, clientHeight } = viewportRef
|
|
@@ -160,9 +212,10 @@ export function ScrollView(props: ScrollViewProps) {
|
|
|
160
212
|
if (document.activeElement && ["INPUT", "TEXTAREA", "SELECT"].includes(document.activeElement.tagName)) {
|
|
161
213
|
return
|
|
162
214
|
}
|
|
163
|
-
|
|
164
215
|
const next = scrollKey(e)
|
|
165
216
|
if (!next) return
|
|
217
|
+
if (!isScrollKeyTarget(e.target, next)) return
|
|
218
|
+
if (scrollKeyOwner(viewportRef, e.target, next) !== viewportRef) return
|
|
166
219
|
|
|
167
220
|
const scrollAmount = viewportRef.clientHeight * 0.8
|
|
168
221
|
const lineAmount = 40
|
|
@@ -208,11 +261,18 @@ export function ScrollView(props: ScrollViewProps) {
|
|
|
208
261
|
<div
|
|
209
262
|
ref={viewportRef}
|
|
210
263
|
class="scroll-view__viewport"
|
|
264
|
+
data-scrollable
|
|
211
265
|
onScroll={(e) => {
|
|
212
266
|
updateThumb()
|
|
267
|
+
markScrolling()
|
|
213
268
|
if (typeof events.onScroll === "function") events.onScroll(e as any)
|
|
214
269
|
}}
|
|
215
|
-
onWheel={
|
|
270
|
+
onWheel={(e) => {
|
|
271
|
+
markScrolling()
|
|
272
|
+
const handler = events.onWheel
|
|
273
|
+
if (typeof handler === "function") handler(e as any)
|
|
274
|
+
if (Array.isArray(handler)) handler[0](handler[1], e as any)
|
|
275
|
+
}}
|
|
216
276
|
onTouchStart={events.onTouchStart as any}
|
|
217
277
|
onTouchMove={events.onTouchMove as any}
|
|
218
278
|
onTouchEnd={events.onTouchEnd as any}
|
|
@@ -236,7 +296,7 @@ export function ScrollView(props: ScrollViewProps) {
|
|
|
236
296
|
ref={thumbRef}
|
|
237
297
|
onPointerDown={onThumbPointerDown}
|
|
238
298
|
class="scroll-view__thumb"
|
|
239
|
-
data-visible={
|
|
299
|
+
data-visible={thumbVisible()}
|
|
240
300
|
data-dragging={isDragging()}
|
|
241
301
|
style={{
|
|
242
302
|
height: `${thumbHeight()}px`,
|
package/src/components/tabs.css
CHANGED
|
@@ -135,7 +135,8 @@
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
#review-panel &[data-variant="normal"][data-orientation="horizontal"]
|
|
138
|
+
#review-panel &[data-variant="normal"][data-orientation="horizontal"],
|
|
139
|
+
#terminal-panel &[data-variant="normal"][data-orientation="horizontal"] {
|
|
139
140
|
background-color: var(--background-stronger);
|
|
140
141
|
|
|
141
142
|
[data-slot="tabs-list"] {
|
|
@@ -267,6 +268,51 @@
|
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
270
|
|
|
271
|
+
#terminal-panel &[data-variant="normal"][data-orientation="horizontal"] {
|
|
272
|
+
[data-slot="tabs-list"] {
|
|
273
|
+
height: 52px;
|
|
274
|
+
padding-right: 12px;
|
|
275
|
+
gap: 8px;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
[data-slot="tabs-trigger-wrapper"] {
|
|
279
|
+
height: 28px;
|
|
280
|
+
padding-inline: 8px;
|
|
281
|
+
border: 0;
|
|
282
|
+
background-color: transparent;
|
|
283
|
+
box-shadow: none;
|
|
284
|
+
|
|
285
|
+
&::after {
|
|
286
|
+
display: none;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
[data-slot="tabs-trigger"] {
|
|
290
|
+
padding: 0 !important;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
&:has([data-slot="tabs-trigger-close-button"]) {
|
|
294
|
+
padding-right: 8px;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
&:has([data-selected]) {
|
|
298
|
+
background-color: var(--v2-background-bg-layer-01);
|
|
299
|
+
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-muted);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
[data-slot="terminal-tab-title"] {
|
|
304
|
+
font-family: Inter, sans-serif;
|
|
305
|
+
font-style: normal;
|
|
306
|
+
font-weight: 440;
|
|
307
|
+
font-size: 13px;
|
|
308
|
+
line-height: 16px;
|
|
309
|
+
letter-spacing: -0.04px;
|
|
310
|
+
color: var(--v2-text-text-base);
|
|
311
|
+
font-variation-settings: "slnt" 0;
|
|
312
|
+
font-variant-numeric: tabular-nums;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
270
316
|
&[data-variant="alt"] {
|
|
271
317
|
[data-slot="tabs-list"] {
|
|
272
318
|
padding-left: 24px;
|
package/src/context/marked.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { marked } from "marked"
|
|
2
|
-
import markedKatex from "marked-katex-extension"
|
|
1
|
+
import { marked, type MarkedExtension, type Tokens } from "marked"
|
|
3
2
|
import markedShiki from "marked-shiki"
|
|
4
3
|
import katex from "katex"
|
|
5
4
|
import { bundledLanguages, type BundledLanguage } from "shiki"
|
|
@@ -395,8 +394,8 @@ function renderMathInText(text: string): string {
|
|
|
395
394
|
}
|
|
396
395
|
})
|
|
397
396
|
|
|
398
|
-
// Inline math:
|
|
399
|
-
const inlineMathRegex =
|
|
397
|
+
// Inline math: \(...\)
|
|
398
|
+
const inlineMathRegex = /\\\(((?:\\.|[^\\\n])*?)\\\)/g
|
|
400
399
|
result = result.replace(inlineMathRegex, (_, math) => {
|
|
401
400
|
try {
|
|
402
401
|
return katex.renderToString(math, {
|
|
@@ -404,13 +403,63 @@ function renderMathInText(text: string): string {
|
|
|
404
403
|
throwOnError: false,
|
|
405
404
|
})
|
|
406
405
|
} catch {
|
|
407
|
-
return
|
|
406
|
+
return `\\(${math}\\)`
|
|
408
407
|
}
|
|
409
408
|
})
|
|
410
409
|
|
|
411
410
|
return result
|
|
412
411
|
}
|
|
413
412
|
|
|
413
|
+
const inlineMathRegex = /^\\\(((?:\\.|[^\\\n])*?)\\\)/
|
|
414
|
+
const blockMathRegex = /^\$\$\n([\s\S]+?)\n\$\$(?:\n|$)/
|
|
415
|
+
|
|
416
|
+
const katexExtension: MarkedExtension = {
|
|
417
|
+
extensions: [
|
|
418
|
+
{
|
|
419
|
+
name: "inlineKatex",
|
|
420
|
+
level: "inline",
|
|
421
|
+
start(src) {
|
|
422
|
+
const index = src.indexOf("\\(")
|
|
423
|
+
if (index === -1) return
|
|
424
|
+
return index
|
|
425
|
+
},
|
|
426
|
+
tokenizer(src) {
|
|
427
|
+
const match = src.match(inlineMathRegex)
|
|
428
|
+
if (!match) return
|
|
429
|
+
return {
|
|
430
|
+
type: "inlineKatex",
|
|
431
|
+
raw: match[0],
|
|
432
|
+
text: match[1].trim(),
|
|
433
|
+
displayMode: false,
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
renderer: renderKatexToken,
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
name: "blockKatex",
|
|
440
|
+
level: "block",
|
|
441
|
+
tokenizer(src) {
|
|
442
|
+
const match = src.match(blockMathRegex)
|
|
443
|
+
if (!match) return
|
|
444
|
+
return {
|
|
445
|
+
type: "blockKatex",
|
|
446
|
+
raw: match[0],
|
|
447
|
+
text: match[1].trim(),
|
|
448
|
+
displayMode: true,
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
renderer: renderKatexToken,
|
|
452
|
+
},
|
|
453
|
+
],
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function renderKatexToken(token: Tokens.Generic) {
|
|
457
|
+
return katex.renderToString(typeof token.text === "string" ? token.text : "", {
|
|
458
|
+
displayMode: token.displayMode === true,
|
|
459
|
+
throwOnError: false,
|
|
460
|
+
})
|
|
461
|
+
}
|
|
462
|
+
|
|
414
463
|
function renderMathExpressions(html: string): string {
|
|
415
464
|
// Split on code/pre/kbd tags to avoid processing their contents
|
|
416
465
|
const codeBlockPattern = /(<(?:pre|code|kbd)[^>]*>[\s\S]*?<\/(?:pre|code|kbd)>)/gi
|
|
@@ -480,10 +529,7 @@ export const { use: useMarked, provider: MarkedProvider } = createSimpleContext(
|
|
|
480
529
|
},
|
|
481
530
|
},
|
|
482
531
|
},
|
|
483
|
-
|
|
484
|
-
throwOnError: false,
|
|
485
|
-
nonStandard: true,
|
|
486
|
-
}),
|
|
532
|
+
katexExtension,
|
|
487
533
|
markedShiki({
|
|
488
534
|
async highlight(code, lang) {
|
|
489
535
|
const highlighter = await getSharedHighlighter({
|
package/src/i18n/en.ts
CHANGED
|
@@ -15,6 +15,23 @@ export const dict: Record<string, string> = {
|
|
|
15
15
|
"ui.sessionReview.largeDiff.title": "Diff too large to render",
|
|
16
16
|
"ui.sessionReview.largeDiff.meta": "Limit: {{limit}} changed lines. Current: {{current}} changed lines.",
|
|
17
17
|
"ui.sessionReview.largeDiff.renderAnyway": "Render anyway",
|
|
18
|
+
"ui.sessionReviewV2.expandMode": "Expand or collapse diff",
|
|
19
|
+
"ui.sessionReviewV2.filterFiles": "Filter files",
|
|
20
|
+
"ui.sessionReviewV2.toggleSidebar": "Toggle file tree",
|
|
21
|
+
"ui.sessionReviewV2.showAllLines": "Show all lines",
|
|
22
|
+
"ui.sessionReviewV2.hideNonDiffLines": "Hide non-diff lines",
|
|
23
|
+
"ui.sessionReviewV2.unifiedDiff": "Unified diff",
|
|
24
|
+
"ui.sessionReviewV2.splitDiff": "Split diff",
|
|
25
|
+
"ui.sessionReviewV2.previousFile": "Previous file",
|
|
26
|
+
"ui.sessionReviewV2.nextFile": "Next file",
|
|
27
|
+
"ui.sessionReviewV2.diffView": "Diff view",
|
|
28
|
+
"ui.sessionReviewV2.empty.noGit.title": "No tracked changes",
|
|
29
|
+
"ui.sessionReviewV2.empty.noGit.description": "Track, review, and undo changes in this project",
|
|
30
|
+
"ui.sessionReviewV2.empty.noGit.action": "Create Git repository",
|
|
31
|
+
"ui.sessionReviewV2.empty.noGit.actionLoading": "Creating Git repository...",
|
|
32
|
+
"ui.sessionReviewV2.empty.changes.title": "No file changes yet",
|
|
33
|
+
"ui.sessionReviewV2.empty.changes.description": "Project changes will appear here",
|
|
34
|
+
|
|
18
35
|
"ui.sessionReview.openFile": "Open file",
|
|
19
36
|
"ui.sessionReview.selection.line": "line {{line}}",
|
|
20
37
|
"ui.sessionReview.selection.lines": "lines {{start}}-{{end}}",
|
|
@@ -35,6 +52,7 @@ export const dict: Record<string, string> = {
|
|
|
35
52
|
"ui.lineComment.editorLabel.suffix": "",
|
|
36
53
|
"ui.lineComment.placeholder": "Add comment",
|
|
37
54
|
"ui.lineComment.submit": "Comment",
|
|
55
|
+
"ui.lineComment.cancel": "Cancel",
|
|
38
56
|
|
|
39
57
|
"ui.sessionTurn.steps.show": "Show steps",
|
|
40
58
|
"ui.sessionTurn.steps.hide": "Hide steps",
|
package/src/styles/theme.css
CHANGED
|
@@ -281,6 +281,15 @@
|
|
|
281
281
|
--icon-agent-docs-base: #fcb239;
|
|
282
282
|
--icon-agent-ask-base: #2090f5;
|
|
283
283
|
--icon-agent-build-base: #034cff;
|
|
284
|
+
--v2-agent-plan-solid: var(--v2-pink-900);
|
|
285
|
+
--v2-agent-plan-border: rgba(200, 61, 139, 0.5);
|
|
286
|
+
--v2-agent-plan-background: rgba(253, 236, 243, 0.33);
|
|
287
|
+
--v2-agent-build-solid: var(--v2-blue-900);
|
|
288
|
+
--v2-agent-build-border: rgba(59, 92, 246, 0.5);
|
|
289
|
+
--v2-agent-build-background: rgba(236, 241, 254, 0.33);
|
|
290
|
+
--v2-agent-explore-solid: var(--v2-yellow-900);
|
|
291
|
+
--v2-agent-explore-border: rgba(142, 114, 49, 0.5);
|
|
292
|
+
--v2-agent-explore-background: rgba(254, 250, 236, 0.33);
|
|
284
293
|
--icon-on-success-base: rgba(18, 201, 5, 0.9);
|
|
285
294
|
--icon-on-success-hover: rgba(45, 186, 38, 0.9);
|
|
286
295
|
--icon-on-success-selected: rgba(7, 137, 1, 0.9);
|
|
@@ -541,6 +550,15 @@
|
|
|
541
550
|
--icon-agent-docs-base: #fbb73c;
|
|
542
551
|
--icon-agent-ask-base: #2090f5;
|
|
543
552
|
--icon-agent-build-base: #9dbefe;
|
|
553
|
+
--v2-agent-plan-solid: var(--v2-pink-400);
|
|
554
|
+
--v2-agent-plan-border: rgba(250, 188, 216, 0.5);
|
|
555
|
+
--v2-agent-plan-background: rgba(247, 213, 228, 0.1);
|
|
556
|
+
--v2-agent-build-solid: var(--v2-blue-400);
|
|
557
|
+
--v2-agent-build-border: rgba(215, 226, 252, 0.5);
|
|
558
|
+
--v2-agent-build-background: rgba(215, 226, 252, 0.1);
|
|
559
|
+
--v2-agent-explore-solid: var(--v2-yellow-400);
|
|
560
|
+
--v2-agent-explore-border: rgba(247, 229, 181, 0.5);
|
|
561
|
+
--v2-agent-explore-background: rgba(252, 239, 208, 0.1);
|
|
544
562
|
--icon-on-success-base: rgba(18, 201, 5, 0.9);
|
|
545
563
|
--icon-on-success-hover: rgba(53, 192, 45, 0.9);
|
|
546
564
|
--icon-on-success-selected: rgba(77, 225, 68, 0.9);
|
package/src/theme/v2/mapping.ts
CHANGED
|
@@ -3,6 +3,30 @@ import { V2_AVATAR_DARK, V2_AVATAR_LIGHT } from "./avatar"
|
|
|
3
3
|
|
|
4
4
|
const ref = (name: string): V2ColorValue => `var(--${name})`
|
|
5
5
|
|
|
6
|
+
const lightAgentTokens: Record<string, V2ColorValue> = {
|
|
7
|
+
"v2-agent-plan-solid": ref("v2-pink-900"),
|
|
8
|
+
"v2-agent-plan-border": "rgba(200, 61, 139, 0.5)",
|
|
9
|
+
"v2-agent-plan-background": "rgba(253, 236, 243, 0.33)",
|
|
10
|
+
"v2-agent-build-solid": ref("v2-blue-900"),
|
|
11
|
+
"v2-agent-build-border": "rgba(59, 92, 246, 0.5)",
|
|
12
|
+
"v2-agent-build-background": "rgba(236, 241, 254, 0.33)",
|
|
13
|
+
"v2-agent-explore-solid": ref("v2-yellow-900"),
|
|
14
|
+
"v2-agent-explore-border": "rgba(142, 114, 49, 0.5)",
|
|
15
|
+
"v2-agent-explore-background": "rgba(254, 250, 236, 0.33)",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const darkAgentTokens: Record<string, V2ColorValue> = {
|
|
19
|
+
"v2-agent-plan-solid": ref("v2-pink-400"),
|
|
20
|
+
"v2-agent-plan-border": "rgba(250, 188, 216, 0.5)",
|
|
21
|
+
"v2-agent-plan-background": "rgba(247, 213, 228, 0.1)",
|
|
22
|
+
"v2-agent-build-solid": ref("v2-blue-400"),
|
|
23
|
+
"v2-agent-build-border": "rgba(215, 226, 252, 0.5)",
|
|
24
|
+
"v2-agent-build-background": "rgba(215, 226, 252, 0.1)",
|
|
25
|
+
"v2-agent-explore-solid": ref("v2-yellow-400"),
|
|
26
|
+
"v2-agent-explore-border": "rgba(247, 229, 181, 0.5)",
|
|
27
|
+
"v2-agent-explore-background": "rgba(252, 239, 208, 0.1)",
|
|
28
|
+
}
|
|
29
|
+
|
|
6
30
|
const light: Record<string, V2ColorValue> = {
|
|
7
31
|
"v2-background-bg-base": ref("v2-grey-100"),
|
|
8
32
|
"v2-background-bg-deep": ref("v2-grey-200"),
|
|
@@ -46,6 +70,7 @@ const light: Record<string, V2ColorValue> = {
|
|
|
46
70
|
"v2-state-bg-info": ref("v2-blue-100"),
|
|
47
71
|
"v2-state-fg-info": ref("v2-blue-800"),
|
|
48
72
|
"v2-state-border-info": ref("v2-blue-300"),
|
|
73
|
+
...lightAgentTokens,
|
|
49
74
|
...V2_AVATAR_LIGHT,
|
|
50
75
|
"v2-elevation-raised":
|
|
51
76
|
"0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8), 0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0)",
|
|
@@ -110,6 +135,7 @@ const dark: Record<string, V2ColorValue> = {
|
|
|
110
135
|
"v2-state-bg-info": ref("v2-blue-1200"),
|
|
111
136
|
"v2-state-fg-info": ref("v2-blue-500"),
|
|
112
137
|
"v2-state-border-info": ref("v2-blue-900"),
|
|
138
|
+
...darkAgentTokens,
|
|
113
139
|
...V2_AVATAR_DARK,
|
|
114
140
|
"v2-elevation-raised":
|
|
115
141
|
"0px 2px 4px 0px var(--v2-alpha-dark-30), 0px 1px 2px 0px var(--v2-alpha-dark-30), 0px 0px 0px 0.5px var(--v2-alpha-light-16), 0px -0.5px 0px 0px var(--v2-alpha-light-6)",
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
[data-component="file-tree-v2"] {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 2px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"] {
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
width: 100%;
|
|
10
|
+
min-width: 0;
|
|
11
|
+
height: 28px;
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: flex-start;
|
|
15
|
+
gap: 6px;
|
|
16
|
+
padding-right: 8px;
|
|
17
|
+
border: none;
|
|
18
|
+
border-radius: 6px;
|
|
19
|
+
background-color: transparent;
|
|
20
|
+
color: var(--v2-text-text-muted);
|
|
21
|
+
text-align: left;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
transition:
|
|
24
|
+
background-color 120ms ease,
|
|
25
|
+
color 120ms ease;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"][data-ignored] {
|
|
29
|
+
color: var(--v2-text-text-faint);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"]:hover {
|
|
33
|
+
background-color: var(--v2-overlay-simple-overlay-hover);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"][data-selected] {
|
|
37
|
+
color: var(--v2-text-text-base);
|
|
38
|
+
background-color: var(--v2-overlay-simple-overlay-pressed);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"][data-selected]:hover {
|
|
42
|
+
background-color: var(--v2-overlay-simple-overlay-pressed);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
[data-component="file-tree-v2"] .filetree-icon--mono {
|
|
46
|
+
color: var(--v2-icon-icon-muted);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
[data-component="file-tree-v2"] .filetree-iconpair .filetree-icon--color {
|
|
50
|
+
opacity: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"][data-selected] .filetree-iconpair .filetree-icon--color {
|
|
54
|
+
opacity: 1;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"][data-selected] .filetree-iconpair .filetree-icon--mono {
|
|
58
|
+
opacity: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-chevron"] {
|
|
62
|
+
color: var(--v2-text-text-muted);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-chevron"] svg {
|
|
66
|
+
transition: transform 120ms ease;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-chevron"]:not([data-expanded]) svg {
|
|
70
|
+
transform: rotate(-90deg);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-row"][data-selected] [data-slot="file-tree-v2-chevron"] {
|
|
74
|
+
color: var(--v2-text-text-base);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
[data-component="file-tree-v2"] .filetree-iconpair {
|
|
78
|
+
position: relative;
|
|
79
|
+
display: inline-flex;
|
|
80
|
+
width: 16px;
|
|
81
|
+
height: 16px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
[data-component="file-tree-v2"] .filetree-iconpair [data-component="file-icon"] {
|
|
85
|
+
position: absolute;
|
|
86
|
+
inset: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-change"] {
|
|
90
|
+
box-sizing: border-box;
|
|
91
|
+
flex: none;
|
|
92
|
+
display: flex;
|
|
93
|
+
flex-direction: row;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
96
|
+
width: 16px;
|
|
97
|
+
height: 16px;
|
|
98
|
+
font-size: 11px;
|
|
99
|
+
font-weight: 530;
|
|
100
|
+
line-height: 1;
|
|
101
|
+
letter-spacing: -0.04px;
|
|
102
|
+
text-align: center;
|
|
103
|
+
text-transform: uppercase;
|
|
104
|
+
font-variant-numeric: tabular-nums lining-nums;
|
|
105
|
+
font-feature-settings:
|
|
106
|
+
"tnum" on,
|
|
107
|
+
"lnum" on;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-change"][data-change="modified"] {
|
|
111
|
+
opacity: 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-change"][data-change="added"] {
|
|
115
|
+
color: var(--v2-state-fg-success);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
[data-component="file-tree-v2"] [data-slot="file-tree-v2-change"][data-change="deleted"] {
|
|
119
|
+
color: var(--v2-state-fg-danger);
|
|
120
|
+
}
|
|
@@ -57,6 +57,10 @@ const icons = {
|
|
|
57
57
|
viewBox: "0 0 16 16",
|
|
58
58
|
body: `<path d="M5 6.5L8 9.5L11 6.5" stroke="currentColor"/>`,
|
|
59
59
|
},
|
|
60
|
+
collapse: {
|
|
61
|
+
viewBox: "0 0 16 16",
|
|
62
|
+
body: `<path d="M8 1V6M11 3L8 6L5 3" stroke="currentColor"/><path d="M8 15V10M11 13L8 10L5 13" stroke="currentColor"/><path d="M4 8H6" stroke="currentColor"/><path d="M7 8H9" stroke="currentColor"/><path d="M10 8H12" stroke="currentColor"/>`,
|
|
63
|
+
},
|
|
60
64
|
check: {
|
|
61
65
|
viewBox: "0 0 16 16",
|
|
62
66
|
body: `<path d="M3.53613 8.17857L6.39328 11.75L12.4647 4.25" stroke="currentColor"/>`,
|
|
@@ -93,6 +97,26 @@ const icons = {
|
|
|
93
97
|
viewBox: "0 0 16 16",
|
|
94
98
|
body: `<path d="M2.5 7.5H3.5V8.5H2.5V7.5Z" stroke="currentColor"/><path d="M7.5 7.5H8.5V8.5H7.5V7.5Z" stroke="currentColor"/><path d="M12.5 7.5H13.5V8.5H12.5V7.5Z" stroke="currentColor"/>`,
|
|
95
99
|
},
|
|
100
|
+
expand: {
|
|
101
|
+
viewBox: "0 0 16 16",
|
|
102
|
+
body: `<path d="M8.25 6.17773V1.17773M11.25 4.17773L8.25 1.17773L5.25 4.17773" stroke="currentColor"/><path d="M8.25 9.17773V14.1777M11.25 11.1777L8.25 14.1777L5.25 11.1777" stroke="currentColor"/><path d="M4.25 7.67773H12.25" stroke="currentColor"/>`,
|
|
103
|
+
},
|
|
104
|
+
filetree: {
|
|
105
|
+
viewBox: "0 0 16 16",
|
|
106
|
+
body: `<path d="M2.5 1.5V12.2484H6.75M2.5 4.74838H6.75" stroke="currentColor"/><rect x="8.5" y="3.2168" width="6" height="3" fill="none" stroke="currentColor"/><rect x="8.5" y="10.75" width="6" height="3" fill="none" stroke="currentColor"/>`,
|
|
107
|
+
},
|
|
108
|
+
split: {
|
|
109
|
+
viewBox: "0 0 16 16",
|
|
110
|
+
body: `<path d="M1 14H15L15 2H1V14Z" stroke="currentColor"/><rect x="3" y="4" width="4" height="8" fill="currentColor" fill-opacity="0.5"/><rect x="9" y="4" width="4" height="8" fill="currentColor" fill-opacity="0.5"/>`,
|
|
111
|
+
},
|
|
112
|
+
unified: {
|
|
113
|
+
viewBox: "0 0 16 16",
|
|
114
|
+
body: `<path d="M3.00001 4.00045L12.9998 4L13 6.99955L3 7L3.00001 4.00045Z" fill="currentColor" fill-opacity="0.5"/><path d="M3.0001 9H13L12.9999 12H3L3.0001 9Z" fill="currentColor" fill-opacity="0.5"/><path d="M1 14H15L15 2H1V14Z" stroke="currentColor"/>`,
|
|
115
|
+
},
|
|
116
|
+
review: {
|
|
117
|
+
viewBox: "0 0 20 20",
|
|
118
|
+
body: `<path d="M7 14.5H13M7 7.99512H10.0049M10.0049 7.99512H13M10.0049 7.99512V5M10.0049 7.99512V11M18 18V2L2 2L2 18H18Z" stroke="currentColor"/>`,
|
|
119
|
+
},
|
|
96
120
|
"outline-sliders": {
|
|
97
121
|
viewBox: "0 0 16 16",
|
|
98
122
|
body: `<path d="M11.7779 4.66675H14.4446M11.7779 4.66675C11.7779 5.77132 10.8825 6.66675 9.77789 6.66675C8.67332 6.66675 7.77789 5.77132 7.77789 4.66675M11.7779 4.66675C11.7779 3.56218 10.8825 2.66675 9.77789 2.66675C8.67332 2.66675 7.77789 3.56218 7.77789 4.66675M1.55566 4.66675H7.77789M4.22233 11.3334H1.55566M4.22233 11.3334C4.22233 12.438 5.11776 13.3334 6.22233 13.3334C7.3269 13.3334 8.22233 12.438 8.22233 11.3334M4.22233 11.3334C4.22233 10.2288 5.11776 9.33341 6.22233 9.33341C7.3269 9.33341 8.22233 10.2288 8.22233 11.3334M14.4446 11.3334H8.22233" stroke="currentColor"/>`,
|
|
@@ -81,6 +81,13 @@
|
|
|
81
81
|
--project-avatar-border: var(--v2-avatar-border-gray);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
[data-slot="project-avatar-surface"][data-variant="outline"] {
|
|
85
|
+
--project-avatar-bg: var(--v2-background-bg-base);
|
|
86
|
+
--project-avatar-border: var(--v2-border-border-strong);
|
|
87
|
+
color: var(--v2-text-text-muted);
|
|
88
|
+
text-shadow: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
84
91
|
[data-slot="project-avatar-surface"][data-has-image] {
|
|
85
92
|
background: var(--project-avatar-bg);
|
|
86
93
|
}
|
|
@@ -26,10 +26,13 @@ export const PROJECT_AVATAR_VARIANTS = [
|
|
|
26
26
|
|
|
27
27
|
export type ProjectAvatarVariant = (typeof PROJECT_AVATAR_VARIANTS)[number]
|
|
28
28
|
|
|
29
|
+
// "outline" is a neutral, muted style (e.g. recently closed projects) and is not part of the color rotation.
|
|
30
|
+
export type ProjectAvatarStyle = ProjectAvatarVariant | "outline"
|
|
31
|
+
|
|
29
32
|
export interface ProjectAvatarProps extends ComponentProps<"div"> {
|
|
30
33
|
fallback: string
|
|
31
34
|
src?: string
|
|
32
|
-
variant?:
|
|
35
|
+
variant?: ProjectAvatarStyle
|
|
33
36
|
unread?: boolean
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -53,11 +53,30 @@
|
|
|
53
53
|
align-items: center;
|
|
54
54
|
align-self: stretch;
|
|
55
55
|
padding: 0;
|
|
56
|
+
gap: 6px;
|
|
56
57
|
min-width: 0;
|
|
57
58
|
flex: 1 1 auto;
|
|
58
59
|
min-height: 0;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
[data-component="text-input-v2"] [data-slot="text-input-v2-leading-icon"] {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex: none;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
padding-left: 8px;
|
|
68
|
+
color: var(--v2-icon-icon-muted);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[data-component="text-input-v2"] [data-slot="text-input-v2-leading-icon"] :is(svg, [data-slot="icon-svg"]) {
|
|
72
|
+
display: block;
|
|
73
|
+
flex: none;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[data-component="text-input-v2"][data-leading-icon] [data-slot="text-input-v2-input"] {
|
|
77
|
+
padding-left: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
61
80
|
[data-component="text-input-v2"] [data-slot="text-input-v2-input"] {
|
|
62
81
|
display: block;
|
|
63
82
|
width: 100%;
|
|
@@ -81,6 +100,12 @@
|
|
|
81
100
|
color: var(--v2-text-text-faint);
|
|
82
101
|
}
|
|
83
102
|
|
|
103
|
+
[data-component="text-input-v2"] [data-slot="text-input-v2-input"][type="search"]::-webkit-search-cancel-button {
|
|
104
|
+
-webkit-appearance: none;
|
|
105
|
+
appearance: none;
|
|
106
|
+
display: none;
|
|
107
|
+
}
|
|
108
|
+
|
|
84
109
|
[data-component="text-input-v2"][data-numeric] [data-slot="text-input-v2-input"] {
|
|
85
110
|
font-variant-numeric: tabular-nums;
|
|
86
111
|
}
|
|
@@ -134,6 +159,14 @@
|
|
|
134
159
|
color: currentColor;
|
|
135
160
|
}
|
|
136
161
|
|
|
162
|
+
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"][data-variant="clear"] {
|
|
163
|
+
width: 28px;
|
|
164
|
+
height: 28px;
|
|
165
|
+
padding: 0;
|
|
166
|
+
border-radius: 6px;
|
|
167
|
+
margin-right: -8px;
|
|
168
|
+
}
|
|
169
|
+
|
|
137
170
|
[data-component="text-input-v2"][data-invalid]:not([data-disabled]) [data-slot="text-input-v2-input"] {
|
|
138
171
|
color: var(--v2-state-fg-danger);
|
|
139
172
|
caret-color: var(--v2-state-fg-danger);
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import { type ComponentProps, Show, splitProps } from "solid-js"
|
|
1
|
+
import { type ComponentProps, type JSX, Show, splitProps } from "solid-js"
|
|
2
2
|
import { Icon } from "./icon"
|
|
3
3
|
import "./text-input-v2.css"
|
|
4
4
|
|
|
5
5
|
export interface TextInputV2Props extends Omit<ComponentProps<"input">, "type"> {
|
|
6
|
+
/** Icon or adornment shown before the field value. */
|
|
7
|
+
leadingIcon?: JSX.Element
|
|
6
8
|
/** Show the trailing copy action. */
|
|
7
9
|
showCopyButton?: boolean
|
|
10
|
+
/** Show the trailing clear action. */
|
|
11
|
+
showClearButton?: boolean
|
|
8
12
|
/** Accessible label for the copy button. */
|
|
9
13
|
copyLabel?: string
|
|
14
|
+
/** Accessible label for the clear button. */
|
|
15
|
+
clearLabel?: string
|
|
10
16
|
onCopyClick?: (event: MouseEvent) => void
|
|
17
|
+
onClearClick?: (event: MouseEvent) => void
|
|
11
18
|
/** Apply tabular numerals to the field value. */
|
|
12
19
|
numeric?: boolean
|
|
13
20
|
/** Error styling for the field and value text. */
|
|
@@ -21,9 +28,13 @@ export function TextInputV2(props: TextInputV2Props) {
|
|
|
21
28
|
const [local, inputProps] = splitProps(props, [
|
|
22
29
|
"class",
|
|
23
30
|
"classList",
|
|
31
|
+
"leadingIcon",
|
|
24
32
|
"showCopyButton",
|
|
33
|
+
"showClearButton",
|
|
25
34
|
"copyLabel",
|
|
35
|
+
"clearLabel",
|
|
26
36
|
"onCopyClick",
|
|
37
|
+
"onClearClick",
|
|
27
38
|
"numeric",
|
|
28
39
|
"invalid",
|
|
29
40
|
"appearance",
|
|
@@ -37,12 +48,16 @@ export function TextInputV2(props: TextInputV2Props) {
|
|
|
37
48
|
data-invalid={local.invalid ? "" : undefined}
|
|
38
49
|
data-numeric={local.numeric ? "" : undefined}
|
|
39
50
|
data-appearance={local.appearance ?? "base"}
|
|
51
|
+
data-leading-icon={local.leadingIcon ? "" : undefined}
|
|
40
52
|
classList={{
|
|
41
53
|
...local.classList,
|
|
42
54
|
[local.class ?? ""]: !!local.class,
|
|
43
55
|
}}
|
|
44
56
|
>
|
|
45
57
|
<div data-slot="text-input-v2-value">
|
|
58
|
+
<Show when={local.leadingIcon}>
|
|
59
|
+
<span data-slot="text-input-v2-leading-icon">{local.leadingIcon}</span>
|
|
60
|
+
</Show>
|
|
46
61
|
<input
|
|
47
62
|
{...inputProps}
|
|
48
63
|
type={inputProps.type ?? "text"}
|
|
@@ -51,15 +66,26 @@ export function TextInputV2(props: TextInputV2Props) {
|
|
|
51
66
|
data-slot="text-input-v2-input"
|
|
52
67
|
/>
|
|
53
68
|
</div>
|
|
54
|
-
<Show when={local.showCopyButton}>
|
|
69
|
+
<Show when={local.showClearButton || local.showCopyButton}>
|
|
55
70
|
<button
|
|
56
71
|
type="button"
|
|
57
72
|
data-slot="text-input-v2-icon-button"
|
|
58
|
-
|
|
73
|
+
data-variant={local.showClearButton ? "clear" : "copy"}
|
|
74
|
+
aria-label={local.showClearButton ? (local.clearLabel ?? "Clear") : (local.copyLabel ?? "Copy")}
|
|
59
75
|
disabled={local.disabled}
|
|
60
|
-
|
|
76
|
+
onMouseDown={(event) => {
|
|
77
|
+
if (!local.showClearButton) return
|
|
78
|
+
event.preventDefault()
|
|
79
|
+
}}
|
|
80
|
+
onClick={(event) => {
|
|
81
|
+
if (local.showClearButton) {
|
|
82
|
+
local.onClearClick?.(event)
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
local.onCopyClick?.(event)
|
|
86
|
+
}}
|
|
61
87
|
>
|
|
62
|
-
<Icon name="copy" />
|
|
88
|
+
<Icon name={local.showClearButton ? "xmark-small" : "copy"} />
|
|
63
89
|
</button>
|
|
64
90
|
</Show>
|
|
65
91
|
</div>
|
|
@@ -97,44 +97,46 @@ export interface ToastV2Options {
|
|
|
97
97
|
|
|
98
98
|
export function showToastV2(options: ToastV2Options | string) {
|
|
99
99
|
const opts = typeof options === "string" ? { description: options } : options
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
<
|
|
104
|
-
<
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
<ToastV2.Content>
|
|
108
|
-
<Show when={opts.title}>
|
|
109
|
-
<ToastV2.Title>{opts.title}</ToastV2.Title>
|
|
110
|
-
</Show>
|
|
111
|
-
<Show when={opts.description}>
|
|
112
|
-
<ToastV2.Description>{opts.description}</ToastV2.Description>
|
|
100
|
+
return toaster.show((props) => {
|
|
101
|
+
const resolvedIcon = children(() => opts.icon)
|
|
102
|
+
return (
|
|
103
|
+
<ToastV2 toastId={props.toastId} duration={opts.duration} persistent={opts.persistent}>
|
|
104
|
+
<div data-slot="toast-v2-header">
|
|
105
|
+
<Show when={resolvedIcon()}>
|
|
106
|
+
<ToastV2.Icon>{resolvedIcon()}</ToastV2.Icon>
|
|
113
107
|
</Show>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
108
|
+
<ToastV2.Content>
|
|
109
|
+
<Show when={opts.title}>
|
|
110
|
+
<ToastV2.Title>{opts.title}</ToastV2.Title>
|
|
111
|
+
</Show>
|
|
112
|
+
<Show when={opts.description}>
|
|
113
|
+
<ToastV2.Description>{opts.description}</ToastV2.Description>
|
|
114
|
+
</Show>
|
|
115
|
+
</ToastV2.Content>
|
|
116
|
+
<ToastV2.CloseButton />
|
|
117
|
+
</div>
|
|
118
|
+
<Show when={opts.actions?.length}>
|
|
119
|
+
<ToastV2.Actions>
|
|
120
|
+
{opts.actions!.map((action) => (
|
|
121
|
+
<ButtonV2
|
|
122
|
+
variant={action.variant === "secondary" ? "ghost" : "neutral"}
|
|
123
|
+
size="small"
|
|
124
|
+
data-action-variant={action.variant ?? "primary"}
|
|
125
|
+
onClick={() => {
|
|
126
|
+
if (typeof action.onClick === "function") {
|
|
127
|
+
action.onClick()
|
|
128
|
+
}
|
|
129
|
+
toaster.dismiss(props.toastId)
|
|
130
|
+
}}
|
|
131
|
+
>
|
|
132
|
+
{action.label}
|
|
133
|
+
</ButtonV2>
|
|
134
|
+
))}
|
|
135
|
+
</ToastV2.Actions>
|
|
136
|
+
</Show>
|
|
137
|
+
</ToastV2>
|
|
138
|
+
)
|
|
139
|
+
})
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
export interface ToastV2PromiseOptions<T, U = unknown> {
|
package/src/v2/styles/theme.css
CHANGED
|
@@ -77,6 +77,16 @@
|
|
|
77
77
|
--v2-state-fg-info: var(--v2-blue-800);
|
|
78
78
|
--v2-state-border-info: var(--v2-blue-300);
|
|
79
79
|
|
|
80
|
+
--v2-agent-plan-solid: var(--v2-pink-900);
|
|
81
|
+
--v2-agent-plan-border: rgba(200, 61, 139, 0.5);
|
|
82
|
+
--v2-agent-plan-background: rgba(253, 236, 243, 0.33);
|
|
83
|
+
--v2-agent-build-solid: var(--v2-blue-900);
|
|
84
|
+
--v2-agent-build-border: rgba(59, 92, 246, 0.5);
|
|
85
|
+
--v2-agent-build-background: rgba(236, 241, 254, 0.33);
|
|
86
|
+
--v2-agent-explore-solid: var(--v2-yellow-900);
|
|
87
|
+
--v2-agent-explore-border: rgba(142, 114, 49, 0.5);
|
|
88
|
+
--v2-agent-explore-background: rgba(254, 250, 236, 0.33);
|
|
89
|
+
|
|
80
90
|
/* ── Project avatar (fixed; theme-independent) ── */
|
|
81
91
|
--v2-avatar-fg: #ffffffff;
|
|
82
92
|
--v2-avatar-bg-orange: #ee7330ff;
|
|
@@ -193,6 +203,16 @@
|
|
|
193
203
|
--v2-state-fg-info: var(--v2-blue-500);
|
|
194
204
|
--v2-state-border-info: var(--v2-blue-900);
|
|
195
205
|
|
|
206
|
+
--v2-agent-plan-solid: var(--v2-pink-400);
|
|
207
|
+
--v2-agent-plan-border: rgba(250, 188, 216, 0.5);
|
|
208
|
+
--v2-agent-plan-background: rgba(247, 213, 228, 0.1);
|
|
209
|
+
--v2-agent-build-solid: var(--v2-blue-400);
|
|
210
|
+
--v2-agent-build-border: rgba(215, 226, 252, 0.5);
|
|
211
|
+
--v2-agent-build-background: rgba(215, 226, 252, 0.1);
|
|
212
|
+
--v2-agent-explore-solid: var(--v2-yellow-400);
|
|
213
|
+
--v2-agent-explore-border: rgba(247, 229, 181, 0.5);
|
|
214
|
+
--v2-agent-explore-background: rgba(252, 239, 208, 0.1);
|
|
215
|
+
|
|
196
216
|
--v2-elevation-raised:
|
|
197
217
|
0px 2px 4px 0px var(--v2-alpha-dark-30),
|
|
198
218
|
0px 1px 2px 0px var(--v2-alpha-dark-30),
|
|
@@ -296,6 +316,16 @@
|
|
|
296
316
|
--v2-state-fg-info: var(--v2-blue-800);
|
|
297
317
|
--v2-state-border-info: var(--v2-blue-300);
|
|
298
318
|
|
|
319
|
+
--v2-agent-plan-solid: var(--v2-pink-900);
|
|
320
|
+
--v2-agent-plan-border: rgba(200, 61, 139, 0.5);
|
|
321
|
+
--v2-agent-plan-background: rgba(253, 236, 243, 0.33);
|
|
322
|
+
--v2-agent-build-solid: var(--v2-blue-900);
|
|
323
|
+
--v2-agent-build-border: rgba(59, 92, 246, 0.5);
|
|
324
|
+
--v2-agent-build-background: rgba(236, 241, 254, 0.33);
|
|
325
|
+
--v2-agent-explore-solid: var(--v2-yellow-900);
|
|
326
|
+
--v2-agent-explore-border: rgba(142, 114, 49, 0.5);
|
|
327
|
+
--v2-agent-explore-background: rgba(254, 250, 236, 0.33);
|
|
328
|
+
|
|
299
329
|
--v2-elevation-raised:
|
|
300
330
|
0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8),
|
|
301
331
|
0px 0px 0px 0.5px var(--v2-alpha-dark-12), 0px 0px 0px 0px var(--v2-alpha-dark-0);
|
|
@@ -406,6 +436,16 @@
|
|
|
406
436
|
--v2-state-fg-info: var(--v2-blue-500);
|
|
407
437
|
--v2-state-border-info: var(--v2-blue-900);
|
|
408
438
|
|
|
439
|
+
--v2-agent-plan-solid: var(--v2-pink-400);
|
|
440
|
+
--v2-agent-plan-border: rgba(250, 188, 216, 0.5);
|
|
441
|
+
--v2-agent-plan-background: rgba(247, 213, 228, 0.1);
|
|
442
|
+
--v2-agent-build-solid: var(--v2-blue-400);
|
|
443
|
+
--v2-agent-build-border: rgba(215, 226, 252, 0.5);
|
|
444
|
+
--v2-agent-build-background: rgba(215, 226, 252, 0.1);
|
|
445
|
+
--v2-agent-explore-solid: var(--v2-yellow-400);
|
|
446
|
+
--v2-agent-explore-border: rgba(247, 229, 181, 0.5);
|
|
447
|
+
--v2-agent-explore-background: rgba(252, 239, 208, 0.1);
|
|
448
|
+
|
|
409
449
|
--v2-avatar-fg: #ffffffff;
|
|
410
450
|
--v2-avatar-bg-orange: #723d22ff;
|
|
411
451
|
--v2-avatar-border-orange: #ff8648ff;
|