Merge branch 'dev' of https://github.com/sst/opencode into dev

This commit is contained in:
David Hill
2025-11-10 13:44:12 +00:00
288 changed files with 10426 additions and 13146 deletions

View File

@@ -18,4 +18,4 @@
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
}

View File

@@ -1,9 +1,11 @@
import { Accordion as Kobalte } from "@kobalte/core/accordion"
import { splitProps } from "solid-js"
import { createSignal, splitProps } from "solid-js"
import type { ComponentProps, ParentProps } from "solid-js"
export interface AccordionProps extends ComponentProps<typeof Kobalte> {}
export interface AccordionItemProps extends ComponentProps<typeof Kobalte.Item> {}
export interface AccordionItemProps extends ComponentProps<typeof Kobalte.Item> {
defaultOpen?: boolean
}
export interface AccordionHeaderProps extends ComponentProps<typeof Kobalte.Header> {}
export interface AccordionTriggerProps extends ComponentProps<typeof Kobalte.Trigger> {}
export interface AccordionContentProps extends ComponentProps<typeof Kobalte.Content> {}
@@ -23,11 +25,14 @@ function AccordionRoot(props: AccordionProps) {
}
function AccordionItem(props: AccordionItemProps) {
const [split, rest] = splitProps(props, ["class", "classList"])
const [split, rest] = splitProps(props, ["class", "classList", "defaultOpen"])
const [open, setOpen] = createSignal(split.defaultOpen ?? false)
return (
<Kobalte.Item
{...rest}
data-slot="accordion-item"
onOpenChange={setOpen}
open={open()}
classList={{
...(split.classList ?? {}),
[split.class ?? ""]: !!split.class,

View File

@@ -7,6 +7,7 @@
border-radius: 6px;
text-decoration: none;
user-select: none;
cursor: default;
outline: none;
&[data-variant="primary"] {
@@ -66,27 +67,26 @@
color: var(--text-strong);
&:hover:not(:disabled) {
background-color: var(--surface-hover);
background-color: var(--button-ghost-hover);
}
&:active:not(:disabled) {
border-color: var(--border-active);
background-color: var(--surface-active);
background-color: var(--button-ghost-hover-2);
}
&:focus:not(:disabled) {
border-color: var(--border-focus);
background-color: var(--surface-focus);
background-color: var(--button-ghost-hover);
}
}
&[data-size="normal"] {
height: 24px;
padding: 0 6px;
&[data-icon] {
padding: 0 6px 0 4px;
padding: 0 8px 0 6px;
}
font-size: var(--font-size-small);
line-height: var(--line-height-large);
gap: calc(var(--spacing) * 0.5);
gap: 6px;
}
&[data-size="large"] {
@@ -99,11 +99,12 @@
gap: 8px;
/* text-12-medium */
font-family: var(--font-family-sans);
font-size: var(--font-size-base);
font-size: var(--font-size-small);
font-style: normal;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large); /* 171.429% */
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);
}

View File

@@ -11,20 +11,21 @@ export type CodeProps<T = {}> = FileOptions<T> & {
export function Code<T>(props: CodeProps<T>) {
let container!: HTMLDivElement
const [local, others] = splitProps(props, ["file", "class", "classList", "annotations"])
const file = () => local.file
createEffect(() => {
const instance = new File<T>({
theme: { dark: "oc-1-dark", light: "oc-1-light" }, // or any Shiki theme
theme: "OpenCode",
overflow: "wrap", // or 'scroll'
themeType: "system", // 'system', 'light', or 'dark'
disableFileHeader: true,
disableLineNumbers: false, // optional
// lang: 'typescript', // optional - auto-detected from filename if not provided
...others,
})
container.innerHTML = ""
instance.render({
file: file(),
file: local.file,
lineAnnotations: local.annotations,
containerWrapper: container,
})

View File

@@ -1,18 +1,21 @@
import type { FileDiff } from "@opencode-ai/sdk"
import { createMemo, For, Match, Show, Switch } from "solid-js"
export function DiffChanges(props: { diff: FileDiff | FileDiff[]; variant?: "default" | "bars" }) {
export function DiffChanges(props: {
class?: string
changes: { additions: number; deletions: number } | { additions: number; deletions: number }[]
variant?: "default" | "bars"
}) {
const variant = () => props.variant ?? "default"
const additions = createMemo(() =>
Array.isArray(props.diff)
? props.diff.reduce((acc, diff) => acc + (diff.additions ?? 0), 0)
: props.diff.additions,
Array.isArray(props.changes)
? props.changes.reduce((acc, diff) => acc + (diff.additions ?? 0), 0)
: props.changes.additions,
)
const deletions = createMemo(() =>
Array.isArray(props.diff)
? props.diff.reduce((acc, diff) => acc + (diff.deletions ?? 0), 0)
: props.diff.deletions,
Array.isArray(props.changes)
? props.changes.reduce((acc, diff) => acc + (diff.deletions ?? 0), 0)
: props.changes.deletions,
)
const total = createMemo(() => (additions() ?? 0) + (deletions() ?? 0))
@@ -90,7 +93,7 @@ export function DiffChanges(props: { diff: FileDiff | FileDiff[]; variant?: "def
return (
<Show when={variant() === "default" ? total() > 0 : true}>
<div data-component="diff-changes" data-variant={variant()}>
<div data-component="diff-changes" data-variant={variant()} classList={{ [props.class ?? ""]: true }}>
<Switch>
<Match when={variant() === "bars"}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 12" fill="none">

File diff suppressed because it is too large Load Diff

View File

@@ -2,20 +2,11 @@
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 100%;
border-radius: 6px;
text-decoration: none;
user-select: none;
aspect-ratio: 1;
&:disabled {
background-color: var(--icon-strong-disabled);
color: var(--icon-invert-base);
cursor: not-allowed;
}
&:focus {
outline: none;
}
flex-shrink: 0;
&[data-variant="primary"] {
background-color: var(--icon-strong-base);
@@ -51,45 +42,62 @@
}
&[data-variant="secondary"] {
border: transparent;
background-color: var(--button-secondary-base);
color: var(--text-strong);
box-shadow: var(--shadow-xs-border);
&:hover:not(:disabled) {
background-color: var(--surface-hover);
background-color: var(--button-secondary-hover);
}
&:active:not(:disabled) {
background-color: var(--surface-active);
background-color: var(--button-secondary-base);
}
&:focus:not(:disabled) {
background-color: var(--surface-focus);
background-color: var(--button-secondary-base);
}
&:focus-visible:not(:active) {
background-color: var(--button-secondary-base);
box-shadow: var(--shadow-xs-border-focus);
}
&:focus-visible:active {
box-shadow: none;
}
[data-slot="icon"] {
color: var(--icon-strong-base);
}
}
&[data-variant="ghost"] {
background-color: transparent;
/* color: var(--icon-base); */
[data-slot="icon"] {
color: var(--icon-weak-base);
&:hover:not(:disabled) {
color: var(--icon-weak-hover);
}
&:active:not(:disabled) {
color: var(--icon-string-active);
}
color: var(--icon-base);
}
/* color: var(--text-strong); */
/**/
/* &:hover:not(:disabled) { */
/* background-color: var(--surface-hover); */
/* } */
/* &:active:not(:disabled) { */
/* background-color: var(--surface-active); */
/* } */
/* &:focus:not(:disabled) { */
/* background-color: var(--surface-focus); */
/* } */
&:hover:not(:disabled) {
background-color: var(--surface-base-hover);
[data-slot="icon"] {
color: var(--icon-hover);
}
}
&:active:not(:disabled) {
[data-slot="icon"] {
color: var(--icon-active);
}
}
&:selected:not(:disabled) {
background-color: var(--surface-base-active);
[data-slot="icon"] {
color: var(--icon-selected);
}
}
&:focus:not(:disabled) {
background-color: var(--surface-focus);
}
}
&[data-size="normal"] {
@@ -103,9 +111,14 @@
&[data-size="large"] {
height: 32px;
padding: 0 8px 0 6px;
/* padding: 0 8px 0 6px; */
gap: 8px;
[data-slot="icon"] {
height: 16px;
width: 16px;
}
/* text-12-medium */
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
@@ -114,4 +127,14 @@
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);
}
&:disabled {
background-color: var(--icon-strong-disabled);
color: var(--icon-invert-base);
cursor: not-allowed;
}
&:focus {
outline: none;
}
}

View File

@@ -2,7 +2,7 @@ import { Button as Kobalte } from "@kobalte/core/button"
import { type ComponentProps, splitProps } from "solid-js"
import { Icon, IconProps } from "./icon"
export interface IconButtonProps {
export interface IconButtonProps extends ComponentProps<typeof Kobalte> {
icon: IconProps["name"]
size?: "normal" | "large"
iconSize?: IconProps["size"]

View File

@@ -150,6 +150,13 @@ const newIcons = {
"code-lines": `<path d="M2.08325 3.75H11.2499M14.5833 3.75H17.9166M2.08325 10L7.08325 10M10.4166 10L17.9166 10M2.08325 16.25L8.74992 16.25M12.0833 16.25L17.9166 16.25" stroke="currentColor" stroke-linecap="square" stroke-linejoin="round"/>`,
"square-arrow-top-right": `<path d="M7.91675 2.9165H2.91675V17.0832H17.0834V12.0832M12.0834 2.9165H17.0834V7.9165M9.58342 10.4165L16.6667 3.33317" stroke="currentColor" stroke-linecap="square"/>`,
"circle-ban-sign": `<path d="M15.3675 4.63087L4.55742 15.441M17.9163 9.9987C17.9163 14.371 14.3719 17.9154 9.99967 17.9154C7.81355 17.9154 5.83438 17.0293 4.40175 15.5966C2.96911 14.164 2.08301 12.1848 2.08301 9.9987C2.08301 5.62644 5.62742 2.08203 9.99967 2.08203C12.1858 2.08203 14.165 2.96813 15.5976 4.40077C17.0302 5.8334 17.9163 7.81257 17.9163 9.9987Z" stroke="currentColor" stroke-linecap="round"/>`,
stop: `<rect x="5" y="5" width="10" height="10" fill="currentColor"/>`,
enter: `<path d="M5.83333 15.8334L2.5 12.5L5.83333 9.16671M3.33333 12.5H17.9167V4.58337H10" stroke="currentColor" stroke-linecap="square"/>`,
"layout-left": `<path d="M2.91675 2.91699L2.91675 2.41699L2.41675 2.41699L2.41675 2.91699L2.91675 2.91699ZM17.0834 2.91699L17.5834 2.91699L17.5834 2.41699L17.0834 2.41699L17.0834 2.91699ZM17.0834 17.0837L17.0834 17.5837L17.5834 17.5837L17.5834 17.0837L17.0834 17.0837ZM2.91675 17.0837L2.41675 17.0837L2.41675 17.5837L2.91675 17.5837L2.91675 17.0837ZM7.41674 17.0837L7.41674 17.5837L8.41674 17.5837L8.41674 17.0837L7.91674 17.0837L7.41674 17.0837ZM8.41674 2.91699L8.41674 2.41699L7.41674 2.41699L7.41674 2.91699L7.91674 2.91699L8.41674 2.91699ZM2.91675 2.91699L2.91675 3.41699L17.0834 3.41699L17.0834 2.91699L17.0834 2.41699L2.91675 2.41699L2.91675 2.91699ZM17.0834 2.91699L16.5834 2.91699L16.5834 17.0837L17.0834 17.0837L17.5834 17.0837L17.5834 2.91699L17.0834 2.91699ZM17.0834 17.0837L17.0834 16.5837L2.91675 16.5837L2.91675 17.0837L2.91675 17.5837L17.0834 17.5837L17.0834 17.0837ZM2.91675 17.0837L3.41675 17.0837L3.41675 2.91699L2.91675 2.91699L2.41675 2.91699L2.41675 17.0837L2.91675 17.0837ZM7.91674 17.0837L8.41674 17.0837L8.41674 2.91699L7.91674 2.91699L7.41674 2.91699L7.41674 17.0837L7.91674 17.0837Z" fill="currentColor"/>`,
"layout-right": `<path d="M17.0832 2.91699L17.5832 2.91699L17.5832 2.41699L17.0832 2.41699L17.0832 2.91699ZM2.91651 2.91699L2.91651 2.41699L2.41651 2.41699L2.41651 2.91699L2.91651 2.91699ZM2.9165 17.0837L2.4165 17.0837L2.4165 17.5837L2.9165 17.5837L2.9165 17.0837ZM17.0832 17.0837L17.0832 17.5837L17.5832 17.5837L17.5832 17.0837L17.0832 17.0837ZM11.5832 17.0837L11.5832 17.5837L12.5832 17.5837L12.5832 17.0837L12.0832 17.0837L11.5832 17.0837ZM12.5832 2.91699L12.5832 2.41699L11.5832 2.41699L11.5832 2.91699L12.0832 2.91699L12.5832 2.91699ZM17.0832 2.91699L17.0832 2.41699L2.91651 2.41699L2.91651 2.91699L2.91651 3.41699L17.0832 3.41699L17.0832 2.91699ZM2.91651 2.91699L2.41651 2.91699L2.4165 17.0837L2.9165 17.0837L3.4165 17.0837L3.41651 2.91699L2.91651 2.91699ZM2.9165 17.0837L2.9165 17.5837L17.0832 17.5837L17.0832 17.0837L17.0832 16.5837L2.9165 16.5837L2.9165 17.0837ZM17.0832 17.0837L17.5832 17.0837L17.5832 2.91699L17.0832 2.91699L16.5832 2.91699L16.5832 17.0837L17.0832 17.0837ZM12.0832 17.0837L12.5832 17.0837L12.5832 2.91699L12.0832 2.91699L11.5832 2.91699L11.5832 17.0837L12.0832 17.0837Z" fill="currentColor"/>`,
"speech-bubble": `<path d="M18.3334 10.0003C18.3334 5.57324 15.0927 2.91699 10.0001 2.91699C4.90749 2.91699 1.66675 5.57324 1.66675 10.0003C1.66675 11.1497 2.45578 13.1016 2.5771 13.3949C2.5878 13.4207 2.59839 13.4444 2.60802 13.4706C2.69194 13.6996 3.04282 14.9364 1.66675 16.7684C3.5186 17.6538 5.48526 16.1982 5.48526 16.1982C6.84592 16.9202 8.46491 17.0837 10.0001 17.0837C15.0927 17.0837 18.3334 14.4274 18.3334 10.0003Z" stroke="currentColor" stroke-linecap="square"/>`,
"align-right": `<path d="M12.292 6.04167L16.2503 9.99998L12.292 13.9583M2.91699 9.99998H15.6253M17.0837 3.75V16.25" stroke="currentColor" stroke-linecap="square"/>`,
expand: `<path d="M4.58301 10.4163V15.4163H9.58301M10.4163 4.58301H15.4163V9.58301" stroke="currentColor" stroke-linecap="square"/>`,
}
export interface IconProps extends ComponentProps<"svg"> {

View File

@@ -24,5 +24,4 @@ export * from "./tooltip"
export * from "./typewriter"
export * from "../context/helper"
export * from "../context/shiki"
export * from "../context/marked"

View File

@@ -2,22 +2,32 @@ import { TextField as Kobalte } from "@kobalte/core/text-field"
import { Show, splitProps } from "solid-js"
import type { ComponentProps } from "solid-js"
export interface InputProps extends ComponentProps<typeof Kobalte> {
export interface InputProps
extends ComponentProps<typeof Kobalte.Input>,
Partial<Pick<ComponentProps<typeof Kobalte>, "value" | "onChange" | "onKeyDown">> {
label?: string
hideLabel?: boolean
description?: string
}
export function Input(props: InputProps) {
const [local, others] = splitProps(props, ["class", "label", "hideLabel", "description", "placeholder"])
const [local, others] = splitProps(props, [
"class",
"label",
"hideLabel",
"description",
"value",
"onChange",
"onKeyDown",
])
return (
<Kobalte {...others} data-component="input">
<Kobalte data-component="input" value={local.value} onChange={local.onChange} onKeyDown={local.onKeyDown}>
<Show when={local.label}>
<Kobalte.Label data-slot="label" classList={{ "sr-only": local.hideLabel }}>
{local.label}
</Kobalte.Label>
</Show>
<Kobalte.Input data-slot="input" class={local.class} placeholder={local.placeholder} />
<Kobalte.Input {...others} data-slot="input" class={local.class} />
<Show when={local.description}>
<Kobalte.Description data-slot="description">{local.description}</Kobalte.Description>
</Show>

View File

@@ -53,16 +53,11 @@ export function Message(props: MessageProps) {
return (
<Switch>
<Match when={props.message.role === "user" && props.message}>
{(userMessage) => (
<UserMessageDisplay message={userMessage() as UserMessage} parts={props.parts} />
)}
{(userMessage) => <UserMessageDisplay message={userMessage() as UserMessage} parts={props.parts} />}
</Match>
<Match when={props.message.role === "assistant" && props.message}>
{(assistantMessage) => (
<AssistantMessageDisplay
message={assistantMessage() as AssistantMessage}
parts={props.parts}
/>
<AssistantMessageDisplay message={assistantMessage() as AssistantMessage} parts={props.parts} />
)}
</Match>
</Switch>
@@ -93,12 +88,7 @@ export function Part(props: MessagePartProps) {
const component = createMemo(() => PART_MAPPING[props.part.type])
return (
<Show when={component()}>
<Dynamic
component={component()}
part={props.part}
message={props.message}
hideDetails={props.hideDetails}
/>
<Dynamic component={component()} part={props.part} message={props.message} hideDetails={props.hideDetails} />
</Show>
)
}
@@ -226,10 +216,7 @@ ToolRegistry.register({
name: "list",
render(props) {
return (
<BasicTool
icon="bullet-list"
trigger={{ title: "List", subtitle: getDirectory(props.input.path || "/") }}
>
<BasicTool icon="bullet-list" trigger={{ title: "List", subtitle: getDirectory(props.input.path || "/") }}>
<Show when={false && props.output}>
<div data-component="tool-output">{props.output}</div>
</Show>
@@ -364,7 +351,7 @@ ToolRegistry.register({
</div>
<div data-slot="actions">
<Show when={props.metadata.filediff}>
<DiffChanges diff={props.metadata.filediff} />
<DiffChanges changes={props.metadata.filediff} />
</Show>
</div>
</div>

View File

@@ -7,13 +7,7 @@ export interface ProgressCircleProps extends Pick<ComponentProps<"svg">, "class"
}
export function ProgressCircle(props: ProgressCircleProps) {
const [split, rest] = splitProps(props, [
"percentage",
"size",
"strokeWidth",
"class",
"classList",
])
const [split, rest] = splitProps(props, ["percentage", "size", "strokeWidth", "class", "classList"])
const size = () => split.size || 16
const strokeWidth = () => split.strokeWidth || 3
@@ -42,13 +36,7 @@ export function ProgressCircle(props: ProgressCircleProps) {
[split.class ?? ""]: !!split.class,
}}
>
<circle
cx={center}
cy={center}
r={radius()}
data-slot="background"
stroke-width={strokeWidth()}
/>
<circle cx={center} cy={center} r={radius()} data-slot="background" stroke-width={strokeWidth()} />
<circle
cx={center}
cy={center}

View File

@@ -1,14 +1,14 @@
[data-component="select"] {
[data-slot="trigger"] {
[data-slot="select-trigger"] {
padding: 0 4px 0 8px;
box-shadow: none;
[data-slot="value"] {
[data-slot="select-trigger-value"] {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
[data-slot="icon"] {
[data-slot="select-trigger-icon"] {
width: 16px;
height: 16px;
flex-shrink: 0;
@@ -38,7 +38,7 @@
animation: select-open 0.15s ease-out;
}
[data-slot="list"] {
[data-slot="select-content-list"] {
overflow-y: auto;
max-height: 12rem;
white-space: nowrap;
@@ -55,7 +55,7 @@
/* [data-slot="section"] { */
/* } */
[data-slot="item"] {
[data-slot="select-item"] {
position: relative;
display: flex;
align-items: center;
@@ -85,7 +85,7 @@
background-color: var(--surface-raised-base);
pointer-events: none;
}
[data-slot="item-indicator"] {
[data-slot="select-item-indicator"] {
margin-left: auto;
width: 16px;
height: 16px;

View File

@@ -41,17 +41,17 @@ export function Select<T>(props: SelectProps<T> & ButtonProps) {
)}
itemComponent={(itemProps) => (
<Kobalte.Item
data-slot="item"
data-slot="select-item"
classList={{
...(props.classList ?? {}),
[props.class ?? ""]: !!props.class,
}}
{...itemProps}
>
<Kobalte.ItemLabel data-slot="item-label">
<Kobalte.ItemLabel data-slot="select-item-label">
{props.label ? props.label(itemProps.item.rawValue) : (itemProps.item.rawValue as string)}
</Kobalte.ItemLabel>
<Kobalte.ItemIndicator data-slot="item-indicator">
<Kobalte.ItemIndicator data-slot="select-item-indicator">
<Icon name="check-small" size="small" />
</Kobalte.ItemIndicator>
</Kobalte.Item>
@@ -61,7 +61,7 @@ export function Select<T>(props: SelectProps<T> & ButtonProps) {
}}
>
<Kobalte.Trigger
data-slot="trigger"
data-slot="select-trigger"
as={Button}
size={props.size}
variant={props.variant}
@@ -70,7 +70,7 @@ export function Select<T>(props: SelectProps<T> & ButtonProps) {
[props.class ?? ""]: !!props.class,
}}
>
<Kobalte.Value<T> data-slot="value">
<Kobalte.Value<T> data-slot="select-trigger-value">
{(state) => {
const selected = state.selectedOption() ?? props.current
if (!selected) return props.placeholder || ""
@@ -78,7 +78,7 @@ export function Select<T>(props: SelectProps<T> & ButtonProps) {
return selected as string
}}
</Kobalte.Value>
<Kobalte.Icon data-slot="icon">
<Kobalte.Icon data-slot="select-trigger-icon">
<Icon name="chevron-down" size="small" />
</Kobalte.Icon>
</Kobalte.Trigger>
@@ -90,7 +90,7 @@ export function Select<T>(props: SelectProps<T> & ButtonProps) {
}}
data-component="select-content"
>
<Kobalte.Listbox data-slot="list" />
<Kobalte.Listbox data-slot="select-content-list" />
</Kobalte.Content>
</Kobalte.Portal>
</Kobalte>

View File

@@ -7,7 +7,7 @@
overflow: clip;
[data-slot="list"] {
height: 40px;
height: 48px;
width: 100%;
position: relative;
display: flex;
@@ -39,7 +39,7 @@
[data-slot="trigger"] {
position: relative;
height: 100%;
padding: 8px 24px;
padding: 14px 24px;
display: flex;
align-items: center;
color: var(--text-base);

View File

@@ -6,54 +6,55 @@
[data-component="tooltip"] {
z-index: 1000;
max-width: 320px;
border-radius: 12px;
border-radius: 6px;
background-color: var(--surface-float-base);
color: var(--white);
padding: 2px 12px 2px 12px;
color: rgba(253, 252, 252, 0.94);
padding: 2px 8px;
border: 0.5px solid rgba(253, 252, 252, 0.2);
box-shadow: var(--shadow-md);
pointer-events: none !important;
transition: all 150ms ease-out;
transform: translate3d(0, 0, 0);
transform-origin: var(--kb-tooltip-content-transform-origin);
/* transition: all 150ms ease-out; */
/* transform: translate3d(0, 0, 0); */
/* transform-origin: var(--kb-tooltip-content-transform-origin); */
/* text-14-regular */
/* text-12-medium */
font-family: var(--font-family-sans);
font-size: var(--font-size-base);
font-size: var(--font-size-small);
font-style: normal;
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large); /* 171.429% */
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);
&[data-expanded] {
opacity: 1;
transform: translate3d(0, 0, 0);
/* transform: translate3d(0, 0, 0); */
}
&[data-closed] {
opacity: 0;
}
&[data-placement="top"] {
&[data-closed] {
transform: translate3d(0, 4px, 0);
}
}
&[data-placement="bottom"] {
&[data-closed] {
transform: translate3d(0, -4px, 0);
}
}
&[data-placement="left"] {
&[data-closed] {
transform: translate3d(4px, 0, 0);
}
}
&[data-placement="right"] {
&[data-closed] {
transform: translate3d(-4px, 0, 0);
}
}
/* &[data-placement="top"] { */
/* &[data-closed] { */
/* transform: translate3d(0, 4px, 0); */
/* } */
/* } */
/**/
/* &[data-placement="bottom"] { */
/* &[data-closed] { */
/* transform: translate3d(0, -4px, 0); */
/* } */
/* } */
/**/
/* &[data-placement="left"] { */
/* &[data-closed] { */
/* transform: translate3d(4px, 0, 0); */
/* } */
/* } */
/**/
/* &[data-placement="right"] { */
/* &[data-closed] { */
/* transform: translate3d(-4px, 0, 0); */
/* } */
/* } */
}

View File

@@ -1,9 +1,9 @@
import { Tooltip as KobalteTooltip } from "@kobalte/core/tooltip"
import { children, createEffect, createSignal, splitProps } from "solid-js"
import { children, createEffect, createSignal, splitProps, type JSX } from "solid-js"
import type { ComponentProps } from "solid-js"
export interface TooltipProps extends ComponentProps<typeof KobalteTooltip> {
value: string | (() => string)
value: JSX.Element
class?: string
}
@@ -29,13 +29,13 @@ export function Tooltip(props: TooltipProps) {
})
return (
<KobalteTooltip forceMount {...others} open={open()} onOpenChange={setOpen}>
<KobalteTooltip forceMount gutter={4} {...others} open={open()} onOpenChange={setOpen}>
<KobalteTooltip.Trigger as={"div"} data-component="tooltip-trigger" class={local.class}>
{c()}
</KobalteTooltip.Trigger>
<KobalteTooltip.Portal>
<KobalteTooltip.Content data-component="tooltip" data-placement={props.placement}>
{typeof others.value === "function" ? others.value() : others.value}
{others.value}
{/* <KobalteTooltip.Arrow data-slot="arrow" /> */}
</KobalteTooltip.Content>
</KobalteTooltip.Portal>

View File

@@ -2,11 +2,7 @@ import { createEffect, Show, type ValidComponent } from "solid-js"
import { createStore } from "solid-js/store"
import { Dynamic } from "solid-js/web"
export const Typewriter = <T extends ValidComponent = "p">(props: {
text?: string
class?: string
as?: T
}) => {
export const Typewriter = <T extends ValidComponent = "p">(props: { text?: string; class?: string; as?: T }) => {
const [store, setStore] = createStore({
typing: false,
displayed: "",

View File

@@ -1,14 +1,14 @@
import { marked } from "marked"
import markedShiki from "marked-shiki"
import { bundledLanguages, type BundledLanguage } from "shiki"
import { createSimpleContext } from "./helper"
import { useShiki } from "./shiki"
import { getSharedHighlighter } from "@pierre/precision-diffs"
const highlighter = await getSharedHighlighter({ themes: ["OpenCode"], langs: [] })
export const { use: useMarked, provider: MarkedProvider } = createSimpleContext({
name: "Marked",
init: () => {
const highlighter = useShiki()
return marked.use(
markedShiki({
async highlight(code, lang) {
@@ -20,7 +20,7 @@ export const { use: useMarked, provider: MarkedProvider } = createSimpleContext(
}
return highlighter.codeToHtml(code, {
lang: lang || "text",
theme: "opencode",
theme: "OpenCode",
tabindex: false,
})
},

View File

@@ -1,577 +0,0 @@
import { createSimpleContext } from "./helper"
import { createHighlighter, type ThemeInput } from "shiki"
const theme: ThemeInput = {
colors: {
"actionBar.toggledBackground": "var(--surface-raised-base)",
"activityBarBadge.background": "var(--surface-brand-base)",
"checkbox.border": "var(--border-base)",
"editor.background": "transparent",
"editor.foreground": "var(--text-base)",
"editor.inactiveSelectionBackground": "var(--surface-raised-base)",
"editor.selectionHighlightBackground": "var(--border-active)",
"editorIndentGuide.activeBackground1": "var(--border-weak-base)",
"editorIndentGuide.background1": "var(--border-weak-base)",
"input.placeholderForeground": "var(--text-weak)",
"list.activeSelectionIconForeground": "var(--text-base)",
"list.dropBackground": "var(--surface-raised-base)",
"menu.background": "var(--surface-base)",
"menu.border": "var(--border-base)",
"menu.foreground": "var(--text-base)",
"menu.selectionBackground": "var(--surface-interactive-base)",
"menu.separatorBackground": "var(--border-base)",
"ports.iconRunningProcessForeground": "var(--icon-success-base)",
"sideBarSectionHeader.background": "transparent",
"sideBarSectionHeader.border": "var(--border-weak-base)",
"sideBarTitle.foreground": "var(--text-weak)",
"statusBarItem.remoteBackground": "var(--surface-success-base)",
"statusBarItem.remoteForeground": "var(--text-base)",
"tab.lastPinnedBorder": "var(--border-weak-base)",
"tab.selectedBackground": "var(--surface-raised-base)",
"tab.selectedForeground": "var(--text-weak)",
"terminal.inactiveSelectionBackground": "var(--surface-raised-base)",
"widget.border": "var(--border-base)",
},
displayName: "opencode",
name: "opencode",
semanticHighlighting: true,
semanticTokenColors: {
customLiteral: "var(--syntax-function)",
newOperator: "var(--syntax-operator)",
numberLiteral: "var(--syntax-number)",
stringLiteral: "var(--syntax-string)",
},
tokenColors: [
{
scope: [
"meta.embedded",
"source.groovy.embedded",
"string meta.image.inline.markdown",
"variable.legacy.builtin.python",
],
settings: {
foreground: "var(--text-base)",
},
},
{
scope: "emphasis",
settings: {
fontStyle: "italic",
},
},
{
scope: "strong",
settings: {
fontStyle: "bold",
},
},
{
scope: "header",
settings: {
foreground: "var(--markdown-heading)",
},
},
{
scope: "comment",
settings: {
foreground: "var(--syntax-comment)",
},
},
{
scope: "constant.language",
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: [
"constant.numeric",
"variable.other.enummember",
"keyword.operator.plus.exponent",
"keyword.operator.minus.exponent",
],
settings: {
foreground: "var(--syntax-number)",
},
},
{
scope: "constant.regexp",
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: "entity.name.tag",
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: ["entity.name.tag.css", "entity.name.tag.less"],
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: "entity.other.attribute-name",
settings: {
foreground: "var(--syntax-variable)",
},
},
{
scope: [
"entity.other.attribute-name.class.css",
"source.css entity.other.attribute-name.class",
"entity.other.attribute-name.id.css",
"entity.other.attribute-name.parent-selector.css",
"entity.other.attribute-name.parent.less",
"source.css entity.other.attribute-name.pseudo-class",
"entity.other.attribute-name.pseudo-element.css",
"source.css.less entity.other.attribute-name.id",
"entity.other.attribute-name.scss",
],
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: "invalid",
settings: {
foreground: "var(--syntax-critical)",
},
},
{
scope: "markup.underline",
settings: {
fontStyle: "underline",
},
},
{
scope: "markup.bold",
settings: {
fontStyle: "bold",
foreground: "var(--markdown-strong)",
},
},
{
scope: "markup.heading",
settings: {
fontStyle: "bold",
foreground: "var(--theme-markdown-heading)",
},
},
{
scope: "markup.italic",
settings: {
fontStyle: "italic",
},
},
{
scope: "markup.strikethrough",
settings: {
fontStyle: "strikethrough",
},
},
{
scope: "markup.inserted",
settings: {
foreground: "var(--text-diff-add-base)",
},
},
{
scope: "markup.deleted",
settings: {
foreground: "var(--text-diff-delete-base)",
},
},
{
scope: "markup.changed",
settings: {
foreground: "var(--text-base)",
},
},
{
scope: "punctuation.definition.quote.begin.markdown",
settings: {
foreground: "var(--markdown-block-quote)",
},
},
{
scope: "punctuation.definition.list.begin.markdown",
settings: {
foreground: "var(--markdown-list-enumeration)",
},
},
{
scope: "markup.inline.raw",
settings: {
foreground: "var(--markdown-code)",
},
},
{
scope: "punctuation.definition.tag",
settings: {
foreground: "var(--syntax-punctuation)",
},
},
{
scope: ["meta.preprocessor", "entity.name.function.preprocessor"],
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: "meta.preprocessor.string",
settings: {
foreground: "var(--syntax-string)",
},
},
{
scope: "meta.preprocessor.numeric",
settings: {
foreground: "var(--syntax-number)",
},
},
{
scope: "meta.structure.dictionary.key.python",
settings: {
foreground: "var(--syntax-variable)",
},
},
{
scope: "meta.diff.header",
settings: {
foreground: "var(--text-weak)",
},
},
{
scope: "storage",
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: "storage.type",
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: ["storage.modifier", "keyword.operator.noexcept"],
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: ["string", "meta.embedded.assembly"],
settings: {
foreground: "var(--syntax-string)",
},
},
{
scope: "string.tag",
settings: {
foreground: "var(--syntax-string)",
},
},
{
scope: "string.value",
settings: {
foreground: "var(--syntax-string)",
},
},
{
scope: "string.regexp",
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: [
"punctuation.definition.template-expression.begin",
"punctuation.definition.template-expression.end",
"punctuation.section.embedded",
],
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: ["meta.template.expression"],
settings: {
foreground: "var(--text-base)",
},
},
{
scope: [
"support.type.vendored.property-name",
"support.type.property-name",
"source.css variable",
"source.coffee.embedded",
],
settings: {
foreground: "var(--syntax-variable)",
},
},
{
scope: "keyword",
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: "keyword.control",
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: "keyword.operator",
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: [
"keyword.operator.new",
"keyword.operator.expression",
"keyword.operator.cast",
"keyword.operator.sizeof",
"keyword.operator.alignof",
"keyword.operator.typeid",
"keyword.operator.alignas",
"keyword.operator.instanceof",
"keyword.operator.logical.python",
"keyword.operator.wordlike",
],
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: "keyword.other.unit",
settings: {
foreground: "var(--syntax-number)",
},
},
{
scope: ["punctuation.section.embedded.begin.php", "punctuation.section.embedded.end.php"],
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: "support.function.git-rebase",
settings: {
foreground: "var(--syntax-variable)",
},
},
{
scope: "constant.sha.git-rebase",
settings: {
foreground: "var(--syntax-number)",
},
},
{
scope: [
"storage.modifier.import.java",
"variable.language.wildcard.java",
"storage.modifier.package.java",
],
settings: {
foreground: "var(--text-base)",
},
},
{
scope: "variable.language",
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: [
"entity.name.function",
"support.function",
"support.constant.handlebars",
"source.powershell variable.other.member",
"entity.name.operator.custom-literal",
],
settings: {
foreground: "var(--syntax-function)",
},
},
{
scope: [
"support.class",
"support.type",
"entity.name.type",
"entity.name.namespace",
"entity.other.attribute",
"entity.name.scope-resolution",
"entity.name.class",
"storage.type.numeric.go",
"storage.type.byte.go",
"storage.type.boolean.go",
"storage.type.string.go",
"storage.type.uintptr.go",
"storage.type.error.go",
"storage.type.rune.go",
"storage.type.cs",
"storage.type.generic.cs",
"storage.type.modifier.cs",
"storage.type.variable.cs",
"storage.type.annotation.java",
"storage.type.generic.java",
"storage.type.java",
"storage.type.object.array.java",
"storage.type.primitive.array.java",
"storage.type.primitive.java",
"storage.type.token.java",
"storage.type.groovy",
"storage.type.annotation.groovy",
"storage.type.parameters.groovy",
"storage.type.generic.groovy",
"storage.type.object.array.groovy",
"storage.type.primitive.array.groovy",
"storage.type.primitive.groovy",
],
settings: {
foreground: "var(--syntax-type)",
},
},
{
scope: [
"meta.type.cast.expr",
"meta.type.new.expr",
"support.constant.math",
"support.constant.dom",
"support.constant.json",
"entity.other.inherited-class",
"punctuation.separator.namespace.ruby",
],
settings: {
foreground: "var(--syntax-type)",
},
},
{
scope: [
"keyword.control",
"source.cpp keyword.operator.new",
"keyword.operator.delete",
"keyword.other.using",
"keyword.other.directive.using",
"keyword.other.operator",
"entity.name.operator",
],
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: [
"variable",
"meta.definition.variable.name",
"support.variable",
"entity.name.variable",
"constant.other.placeholder",
],
settings: {
foreground: "var(--syntax-variable)",
},
},
{
scope: ["variable.other.constant", "variable.other.enummember"],
settings: {
foreground: "var(--syntax-variable)",
},
},
{
scope: ["meta.object-literal.key"],
settings: {
foreground: "var(--syntax-variable)",
},
},
{
scope: [
"support.constant.property-value",
"support.constant.font-name",
"support.constant.media-type",
"support.constant.media",
"constant.other.color.rgb-value",
"constant.other.rgb-value",
"support.constant.color",
],
settings: {
foreground: "var(--syntax-string)",
},
},
{
scope: [
"punctuation.definition.group.regexp",
"punctuation.definition.group.assertion.regexp",
"punctuation.definition.character-class.regexp",
"punctuation.character.set.begin.regexp",
"punctuation.character.set.end.regexp",
"keyword.operator.negation.regexp",
"support.other.parenthesis.regexp",
],
settings: {
foreground: "var(--syntax-string)",
},
},
{
scope: [
"constant.character.character-class.regexp",
"constant.other.character-class.set.regexp",
"constant.other.character-class.regexp",
"constant.character.set.regexp",
],
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"],
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: "keyword.operator.quantifier.regexp",
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: ["constant.character", "constant.other.option"],
settings: {
foreground: "var(--syntax-keyword)",
},
},
{
scope: "constant.character.escape",
settings: {
foreground: "var(--syntax-operator)",
},
},
{
scope: "entity.name.label",
settings: {
foreground: "var(--text-weak)",
},
},
],
type: "dark",
}
const highlighter = await createHighlighter({
themes: [theme],
langs: [],
})
export const { use: useShiki, provider: ShikiProvider } = createSimpleContext({
name: "Shiki",
init: () => {
return highlighter
},
})

View File

@@ -126,7 +126,7 @@ const Demo: Component = () => {
<Tooltip value="This is a right tooltip" placement="right">
<Button variant="secondary">Right Tooltip</Button>
</Tooltip>
<Tooltip value={() => `Dynamic tooltip: ${new Date().toLocaleTimeString()}`} placement="top">
<Tooltip value={`Dynamic tooltip: ${new Date().toLocaleTimeString()}`} placement="top">
<Button variant="primary">Dynamic Tooltip</Button>
</Tooltip>
</section>
@@ -191,7 +191,14 @@ const Demo: Component = () => {
<Dialog open={dialogOpen()} onOpenChange={setDialogOpen}>
<Dialog.Title>Example Dialog</Dialog.Title>
<Dialog.Description>This is an example dialog with a title and description.</Dialog.Description>
<div style={{ "margin-top": "16px", display: "flex", gap: "8px", "justify-content": "flex-end" }}>
<div
style={{
"margin-top": "16px",
display: "flex",
gap: "8px",
"justify-content": "flex-end",
}}
>
<Button variant="ghost" onClick={() => setDialogOpen(false)}>
Cancel
</Button>

View File

@@ -11,10 +11,7 @@ export interface FilteredListProps<T> {
current?: T
groupBy?: (x: T) => string
sortBy?: (a: T, b: T) => number
sortGroupsBy?: (
a: { category: string; items: T[] },
b: { category: string; items: T[] },
) => number
sortGroupsBy?: (a: { category: string; items: T[] }, b: { category: string; items: T[] }) => number
onSelect?: (value: T | undefined) => void
}
@@ -25,8 +22,7 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
() => store.filter,
async (filter) => {
const needle = filter?.toLowerCase()
const all =
(typeof props.items === "function" ? await props.items(needle) : props.items) || []
const all = (typeof props.items === "function" ? await props.items(needle) : props.items) || []
const result = pipe(
all,
(x) => {

View File

@@ -196,15 +196,20 @@
--color-icon-diff-delete-base: var(--icon-diff-delete-base);
--color-icon-diff-delete-hover: var(--icon-diff-delete-hover);
--color-syntax-comment: var(--syntax-comment);
--color-syntax-regexp: var(--syntax-regexp);
--color-syntax-string: var(--syntax-string);
--color-syntax-keyword: var(--syntax-keyword);
--color-syntax-function: var(--syntax-function);
--color-syntax-number: var(--syntax-number);
--color-syntax-operator: var(--syntax-operator);
--color-syntax-variable: var(--syntax-variable);
--color-syntax-property: var(--syntax-property);
--color-syntax-parameter: var(--syntax-parameter);
--color-syntax-type: var(--syntax-type);
--color-syntax-constant: var(--syntax-constant);
--color-syntax-punctuation: var(--syntax-punctuation);
--color-syntax-namespace: var(--syntax-namespace);
--color-syntax-enum: var(--syntax-enum);
--color-syntax-success: var(--syntax-success);
--color-syntax-warning: var(--syntax-warning);
--color-syntax-critical: var(--syntax-critical);
@@ -232,4 +237,4 @@
--color-border-weaker-focus: var(--border-weaker-focus);
--color-button-ghost-hover: var(--button-ghost-hover);
--color-button-ghost-hover2: var(--button-ghost-hover2);
}
}

View File

@@ -50,29 +50,21 @@
--radius-4xl: 2rem;
--shadow-xs:
0 1px 2px -1px rgba(19, 16, 16, 0.04), 0 1px 2px 0 rgba(19, 16, 16, 0.06),
0 1px 3px 0 rgba(19, 16, 16, 0.08);
0 1px 2px -1px rgba(19, 16, 16, 0.04), 0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);
--shadow-md:
0 6px 8px -4px rgba(19, 16, 16, 0.12), 0 4px 3px -2px rgba(19, 16, 16, 0.12),
0 1px 2px -1px rgba(19, 16, 16, 0.12);
0 6px 8px -4px rgba(19, 16, 16, 0.12), 0 4px 3px -2px rgba(19, 16, 16, 0.12), 0 1px 2px -1px rgba(19, 16, 16, 0.12);
--shadow-xs-border:
0 0 0 1px var(--border-weak-base, rgba(11, 6, 0, 0.20)),
0 1px 2px -1px rgba(19, 16, 16, 0.04),
0 1px 2px 0 rgba(19, 16, 16, 0.06),
0 1px 3px 0 rgba(19, 16, 16, 0.08);
0 0 0 1px var(--border-base, rgba(11, 6, 0, 0.2)), 0 1px 2px -1px rgba(19, 16, 16, 0.04),
0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);
--shadow-xs-border-select:
0 0 0 3px var(--border-weak-selected, rgba(1, 103, 255, 0.29)),
0 0 0 1px var(--border-selected, rgba(0, 74, 255, 0.99)), 0 1px 2px -1px rgba(19, 16, 16, 0.25),
0 1px 2px 0 rgba(19, 16, 16, 0.08), 0 1px 3px 0 rgba(19, 16, 16, 0.12);
--shadow-xs-border-focus:
0 0 0 1px var(--border-base, rgba(11, 6, 0, 0.20)),
0 1px 2px -1px rgba(19, 16, 16, 0.25),
0 1px 2px 0 rgba(19, 16, 16, 0.08),
0 1px 3px 0 rgba(19, 16, 16, 0.12),
0 0 0 2px var(--background-weak, #F1F0F0),
0 0 0 1px var(--border-base, rgba(11, 6, 0, 0.2)), 0 1px 2px -1px rgba(19, 16, 16, 0.25),
0 1px 2px 0 rgba(19, 16, 16, 0.08), 0 1px 3px 0 rgba(19, 16, 16, 0.12), 0 0 0 2px var(--background-weak, #f1f0f0),
0 0 0 3px var(--border-selected, rgba(0, 74, 255, 0.99));
--text-mix-blend-mode: multiply;
}
@@ -273,20 +265,25 @@
--icon-diff-add-active: var(--mint-light-12);
--icon-diff-delete-base: var(--ember-light-10);
--icon-diff-delete-hover: var(--ember-light-11);
--syntax-comment: #8a8a8a;
--syntax-string: #d68c27;
--syntax-keyword: #3b7dd8;
--syntax-function: #d1383d;
--syntax-number: #3d9a57;
--syntax-operator: #d68c27;
--syntax-variable: #b0851f;
--syntax-type: #318795;
--syntax-constant: #953170;
--syntax-punctuation: #1a1a1a;
--syntax-success: var(--apple-dark-10);
--syntax-comment: var(--text-weaker);
--syntax-regexp: var(--text-base);
--syntax-string: var(--mint-light-11);
--syntax-keyword: var(--text-weak);
--syntax-primitive: var(--ember-light-11);
--syntax-operator: var(--text-weak);
--syntax-variable: var(--text-strong);
--syntax-property: var(--lilac-light-11);
--syntax-type: var(--cobalt-light-11);
--syntax-constant: var(--lilac-light-11);
--syntax-punctuation: var(--text-weak);
--syntax-object: var(--blue-light-11);
--syntax-success: var(--apple-light-10);
--syntax-warning: var(--amber-light-10);
--syntax-critical: var(--ember-dark-9);
--syntax-info: var(--lilac-dark-11);
--syntax-critical: var(--ember-light-9);
--syntax-info: var(--lilac-light-11);
--syntax-diff-add: var(--mint-light-11);
--syntax-diff-delete: var(--ember-light-11);
--syntax-unknown: red;
--markdown-heading: #d68c27;
--markdown-text: #1a1a1a;
--markdown-link: #3b7dd8;
@@ -413,7 +410,7 @@
--text-on-brand-weaker: var(--smoke-dark-alpha-8);
--text-on-brand-strong: var(--smoke-dark-alpha-12);
--button-secondary-base: var(--smoke-dark-4);
--button-secondary-hover: #2A2727;
--button-secondary-hover: #2a2727;
--border-base: var(--smoke-dark-alpha-7);
--border-hover: var(--smoke-dark-alpha-8);
--border-active: var(--smoke-dark-alpha-9);
@@ -508,20 +505,24 @@
--icon-diff-add-active: var(--mint-dark-11);
--icon-diff-delete-base: var(--ember-dark-9);
--icon-diff-delete-hover: var(--ember-dark-10);
--syntax-comment: #808080;
--syntax-string: #9d7cd8;
--syntax-keyword: #fab283;
--syntax-function: #e06c75;
--syntax-number: #7fd88f;
--syntax-operator: #f5a742;
--syntax-variable: #e5c07b;
--syntax-type: #56b6c2;
--syntax-constant: #c2569a;
--syntax-punctuation: #eeeeee;
--syntax-comment: var(--text-weaker);
--syntax-regexp: var(--text-base);
--syntax-string: var(--mint-dark-11);
--syntax-keyword: var(--text-weak);
--syntax-primitive: var(--ember-dark-11);
--syntax-operator: var(--text-weak);
--syntax-variable: var(--text-strong);
--syntax-property: var(--lilac-dark-11);
--syntax-type: var(--cobalt-dark-11);
--syntax-constant: var(--lilac-dark-11);
--syntax-punctuation: var(--text-weak);
--syntax-object: var(--blue-dark-11);
--syntax-success: var(--apple-dark-10);
--syntax-warning: var(--amber-dark-10);
--syntax-critical: var(--ember-dark-10);
--syntax-info: var(--lilac-dark-10);
--syntax-critical: var(--ember-dark-9);
--syntax-info: var(--lilac-dark-11);
--syntax-diff-add: var(--mint-dark-11);
--syntax-diff-delete: var(--ember-dark-11);
--markdown-heading: #9d7cd8;
--markdown-text: #eeeeee;
--markdown-link: #fab283;