mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-24 14:43:37 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82fc68aae8 | |||
| 26f3dbe612 |
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@@ -188,7 +188,7 @@ export function Prompt(props: PromptProps) {
|
|||||||
const renderer = useRenderer()
|
const renderer = useRenderer()
|
||||||
const exit = useExit()
|
const exit = useExit()
|
||||||
const dimensions = useTerminalDimensions()
|
const dimensions = useTerminalDimensions()
|
||||||
const { themeV2, syntax, mode } = useTheme()
|
const { themeV2, syntax } = useTheme()
|
||||||
const animationsEnabled = createMemo(() => config.animations ?? true)
|
const animationsEnabled = createMemo(() => config.animations ?? true)
|
||||||
const list = createMemo(() => props.placeholders?.normal ?? [])
|
const list = createMemo(() => props.placeholders?.normal ?? [])
|
||||||
const shell = createMemo(() => props.placeholders?.shell ?? [])
|
const shell = createMemo(() => props.placeholders?.shell ?? [])
|
||||||
@@ -1379,11 +1379,7 @@ export function Prompt(props: PromptProps) {
|
|||||||
})
|
})
|
||||||
const maxHeight = createMemo(() => Math.max(6, Math.floor(dimensions().height / 3)))
|
const maxHeight = createMemo(() => Math.max(6, Math.floor(dimensions().height / 3)))
|
||||||
|
|
||||||
const promptBg = createMemo(() =>
|
const promptBg = createMemo(() => themeV2.raise(themeV2.background.surface.offset()))
|
||||||
mode() === "light"
|
|
||||||
? themeV2.increase(themeV2.background.surface.offset(), 1)
|
|
||||||
: themeV2.decrease(themeV2.background.surface.offset(), 1),
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -297,18 +297,19 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
|||||||
themePerformance.set("Resolve final theme", duration(performance.now() - resolveStarted))
|
themePerformance.set("Resolve final theme", duration(performance.now() - resolveStarted))
|
||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
const themeV2 = createComponentTheme(valuesV2)
|
const mode = () => store.mode
|
||||||
|
const themeV2 = createComponentTheme(valuesV2, mode)
|
||||||
const contextsV2 = {
|
const contextsV2 = {
|
||||||
elevated: createComponentTheme(() => {
|
elevated: createComponentTheme(() => {
|
||||||
const theme = valuesV2().contexts["@context:elevated"]
|
const theme = valuesV2().contexts["@context:elevated"]
|
||||||
if (!theme) throw new Error("Theme context is not defined: elevated")
|
if (!theme) throw new Error("Theme context is not defined: elevated")
|
||||||
return theme
|
return theme
|
||||||
}),
|
}, mode),
|
||||||
overlay: createComponentTheme(() => {
|
overlay: createComponentTheme(() => {
|
||||||
const theme = valuesV2().contexts["@context:overlay"]
|
const theme = valuesV2().contexts["@context:overlay"]
|
||||||
if (!theme) throw new Error("Theme context is not defined: overlay")
|
if (!theme) throw new Error("Theme context is not defined: overlay")
|
||||||
return theme
|
return theme
|
||||||
}),
|
}, mode),
|
||||||
}
|
}
|
||||||
|
|
||||||
createEffect(() => renderer.setBackgroundColor(values().background))
|
createEffect(() => renderer.setBackgroundColor(values().background))
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ import { useLocation } from "../../context/location"
|
|||||||
import { createSessionRows, messageBoundaryIDs, resolvePart, type PartRef, type SessionRow } from "./rows"
|
import { createSessionRows, messageBoundaryIDs, resolvePart, type PartRef, type SessionRow } from "./rows"
|
||||||
import { switchLabel } from "../../util/model"
|
import { switchLabel } from "../../util/model"
|
||||||
import { findMessageBoundary, messageNavigationSlack } from "./message-navigation"
|
import { findMessageBoundary, messageNavigationSlack } from "./message-navigation"
|
||||||
import type { ComponentTheme } from "../../theme/v2/component"
|
|
||||||
import { stringWidth } from "../../util/string-width"
|
import { stringWidth } from "../../util/string-width"
|
||||||
|
|
||||||
addDefaultParsers(parsers.parsers)
|
addDefaultParsers(parsers.parsers)
|
||||||
@@ -100,11 +99,6 @@ function use() {
|
|||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
function offsetBackground(themeV2: ComponentTheme, mode: "light" | "dark") {
|
|
||||||
if (mode === "light") return themeV2.increase(themeV2.background.surface.offset(), 1)
|
|
||||||
return themeV2.decrease(themeV2.background.surface.offset(), 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Session() {
|
export function Session() {
|
||||||
const setEpilogue = useEpilogue()
|
const setEpilogue = useEpilogue()
|
||||||
const clipboard = useClipboard()
|
const clipboard = useClipboard()
|
||||||
@@ -119,7 +113,7 @@ export function Session() {
|
|||||||
const paths = useTuiPaths()
|
const paths = useTuiPaths()
|
||||||
const configState = useConfig()
|
const configState = useConfig()
|
||||||
const config = configState.data
|
const config = configState.data
|
||||||
const { themeV2, mode } = useTheme()
|
const { themeV2 } = useTheme()
|
||||||
const promptRef = usePromptRef()
|
const promptRef = usePromptRef()
|
||||||
const session = createMemo(() => data.session.get(route.sessionID))
|
const session = createMemo(() => data.session.get(route.sessionID))
|
||||||
const messages = () => data.session.message.list(route.sessionID)
|
const messages = () => data.session.message.list(route.sessionID)
|
||||||
@@ -898,7 +892,7 @@ export function Session() {
|
|||||||
paddingLeft: 1,
|
paddingLeft: 1,
|
||||||
visible: showScrollbar(),
|
visible: showScrollbar(),
|
||||||
trackOptions: {
|
trackOptions: {
|
||||||
backgroundColor: offsetBackground(themeV2, mode()),
|
backgroundColor: themeV2.raise(themeV2.background.surface.offset()),
|
||||||
foregroundColor: themeV2.border(),
|
foregroundColor: themeV2.border(),
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@@ -1140,7 +1134,7 @@ function SessionReasoningGroupView(props: {
|
|||||||
message: (messageID: string) => SessionMessageInfo | undefined
|
message: (messageID: string) => SessionMessageInfo | undefined
|
||||||
}) {
|
}) {
|
||||||
const ctx = use()
|
const ctx = use()
|
||||||
const { themeV2, syntax, mode } = useTheme()
|
const { themeV2, syntax } = useTheme()
|
||||||
const renderer = useRenderer()
|
const renderer = useRenderer()
|
||||||
const [expanded, setExpanded] = createSignal(false)
|
const [expanded, setExpanded] = createSignal(false)
|
||||||
const [hover, setHover] = createSignal(false)
|
const [hover, setHover] = createSignal(false)
|
||||||
@@ -1229,7 +1223,7 @@ function SessionReasoningGroupView(props: {
|
|||||||
<box
|
<box
|
||||||
border={["left"]}
|
border={["left"]}
|
||||||
customBorderChars={SplitBorder.customBorderChars}
|
customBorderChars={SplitBorder.customBorderChars}
|
||||||
borderColor={offsetBackground(themeV2, mode())}
|
borderColor={themeV2.raise(themeV2.background.surface.offset())}
|
||||||
paddingLeft={1}
|
paddingLeft={1}
|
||||||
>
|
>
|
||||||
<code
|
<code
|
||||||
@@ -1513,7 +1507,7 @@ function RevertMessage(props: {
|
|||||||
}>
|
}>
|
||||||
}) {
|
}) {
|
||||||
const ctx = use()
|
const ctx = use()
|
||||||
const { themeV2, mode } = useTheme().contextual("elevated")
|
const { themeV2 } = useTheme().contextual("elevated")
|
||||||
const route = useRouteData("session")
|
const route = useRouteData("session")
|
||||||
const client = useClient()
|
const client = useClient()
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
@@ -1544,7 +1538,7 @@ function RevertMessage(props: {
|
|||||||
paddingTop={1}
|
paddingTop={1}
|
||||||
paddingBottom={1}
|
paddingBottom={1}
|
||||||
paddingLeft={2}
|
paddingLeft={2}
|
||||||
backgroundColor={hover() ? offsetBackground(themeV2, mode()) : themeV2.background()}
|
backgroundColor={hover() ? themeV2.raise(themeV2.background()) : themeV2.background()}
|
||||||
>
|
>
|
||||||
<text fg={themeV2.text.subdued()}>
|
<text fg={themeV2.text.subdued()}>
|
||||||
{props.count} message{props.count === 1 ? "" : "s"} reverted
|
{props.count} message{props.count === 1 ? "" : "s"} reverted
|
||||||
@@ -1613,7 +1607,7 @@ function UserMessage(props: { message: SessionMessageUser }) {
|
|||||||
const data = useData()
|
const data = useData()
|
||||||
const local = useLocal()
|
const local = useLocal()
|
||||||
const files = createMemo(() => props.message.files ?? [])
|
const files = createMemo(() => props.message.files ?? [])
|
||||||
const { themeV2, mode } = useTheme().contextual("elevated")
|
const { themeV2 } = useTheme().contextual("elevated")
|
||||||
const [hover, setHover] = createSignal(false)
|
const [hover, setHover] = createSignal(false)
|
||||||
const color = createMemo(() => local.agent.color(data.session.get(ctx.sessionID)?.agent ?? "build"))
|
const color = createMemo(() => local.agent.color(data.session.get(ctx.sessionID)?.agent ?? "build"))
|
||||||
const queued = createMemo(
|
const queued = createMemo(
|
||||||
@@ -1650,7 +1644,7 @@ function UserMessage(props: { message: SessionMessageUser }) {
|
|||||||
paddingTop={1}
|
paddingTop={1}
|
||||||
paddingBottom={1}
|
paddingBottom={1}
|
||||||
paddingLeft={2}
|
paddingLeft={2}
|
||||||
backgroundColor={hover() ? offsetBackground(themeV2, mode()) : themeV2.background()}
|
backgroundColor={hover() ? themeV2.raise(themeV2.background()) : themeV2.background()}
|
||||||
flexShrink={0}
|
flexShrink={0}
|
||||||
>
|
>
|
||||||
<text fg={themeV2.text()}>{props.message.text}</text>
|
<text fg={themeV2.text()}>{props.message.text}</text>
|
||||||
@@ -1670,7 +1664,7 @@ function UserMessage(props: { message: SessionMessageUser }) {
|
|||||||
>
|
>
|
||||||
{` ${label} `}
|
{` ${label} `}
|
||||||
</span>
|
</span>
|
||||||
<span style={{ bg: offsetBackground(themeV2, mode()), fg: themeV2.text.subdued() }}>
|
<span style={{ bg: themeV2.raise(themeV2.background()), fg: themeV2.text.subdued() }}>
|
||||||
{" "}
|
{" "}
|
||||||
{file.name ?? (file.source.type === "uri" ? file.source.uri : "attachment")}{" "}
|
{file.name ?? (file.source.type === "uri" ? file.source.uri : "attachment")}{" "}
|
||||||
</span>
|
</span>
|
||||||
@@ -1858,7 +1852,7 @@ function ReasoningPart(props: {
|
|||||||
part: SessionMessageAssistantReasoning
|
part: SessionMessageAssistantReasoning
|
||||||
message: SessionMessageAssistant
|
message: SessionMessageAssistant
|
||||||
}) {
|
}) {
|
||||||
const { themeV2, syntax, mode } = useTheme()
|
const { themeV2, syntax } = useTheme()
|
||||||
const ctx = use()
|
const ctx = use()
|
||||||
// Collapsed by default in hide mode: a single line throughout, so the
|
// Collapsed by default in hide mode: a single line throughout, so the
|
||||||
// layout never shifts. Click to open the full markdown block, click to close.
|
// layout never shifts. Click to open the full markdown block, click to close.
|
||||||
@@ -1886,7 +1880,7 @@ function ReasoningPart(props: {
|
|||||||
<box
|
<box
|
||||||
border={!inMinimal() || expanded() ? ["left"] : undefined}
|
border={!inMinimal() || expanded() ? ["left"] : undefined}
|
||||||
customBorderChars={SplitBorder.customBorderChars}
|
customBorderChars={SplitBorder.customBorderChars}
|
||||||
borderColor={offsetBackground(themeV2, mode())}
|
borderColor={themeV2.raise(themeV2.background())}
|
||||||
paddingLeft={!inMinimal() || expanded() ? 1 : 0}
|
paddingLeft={!inMinimal() || expanded() ? 1 : 0}
|
||||||
>
|
>
|
||||||
<box onMouseUp={toggle}>
|
<box onMouseUp={toggle}>
|
||||||
@@ -1904,7 +1898,7 @@ function ReasoningPart(props: {
|
|||||||
<box
|
<box
|
||||||
border={["left"]}
|
border={["left"]}
|
||||||
customBorderChars={SplitBorder.customBorderChars}
|
customBorderChars={SplitBorder.customBorderChars}
|
||||||
borderColor={offsetBackground(themeV2, mode())}
|
borderColor={themeV2.raise(themeV2.background())}
|
||||||
paddingLeft={inMinimal() ? 3 : 1}
|
paddingLeft={inMinimal() ? 3 : 1}
|
||||||
>
|
>
|
||||||
<code
|
<code
|
||||||
@@ -2081,7 +2075,7 @@ type ToolProps = {
|
|||||||
part: SessionMessageAssistantTool
|
part: SessionMessageAssistantTool
|
||||||
}
|
}
|
||||||
function GenericTool(props: ToolProps) {
|
function GenericTool(props: ToolProps) {
|
||||||
const { themeV2, syntax, mode } = useTheme()
|
const { themeV2, syntax } = useTheme()
|
||||||
const output = createMemo(() => props.output?.trim() ?? "")
|
const output = createMemo(() => props.output?.trim() ?? "")
|
||||||
const args = createMemo(() => JSON.stringify(props.input, null, 2))
|
const args = createMemo(() => JSON.stringify(props.input, null, 2))
|
||||||
const [expanded, setExpanded] = createSignal(false)
|
const [expanded, setExpanded] = createSignal(false)
|
||||||
@@ -2099,7 +2093,7 @@ function GenericTool(props: ToolProps) {
|
|||||||
<Show when={Object.keys(props.input).length > 0}>
|
<Show when={Object.keys(props.input).length > 0}>
|
||||||
<box gap={1}>
|
<box gap={1}>
|
||||||
<text>
|
<text>
|
||||||
<span style={{ bg: offsetBackground(themeV2, mode()), fg: themeV2.text.subdued() }}> Input </span>
|
<span style={{ bg: themeV2.raise(themeV2.background()), fg: themeV2.text.subdued() }}> Input </span>
|
||||||
</text>
|
</text>
|
||||||
<box paddingLeft={1}>
|
<box paddingLeft={1}>
|
||||||
<code
|
<code
|
||||||
@@ -2117,7 +2111,7 @@ function GenericTool(props: ToolProps) {
|
|||||||
{(value) => (
|
{(value) => (
|
||||||
<box gap={1}>
|
<box gap={1}>
|
||||||
<text>
|
<text>
|
||||||
<span style={{ bg: offsetBackground(themeV2, mode()), fg: themeV2.text.subdued() }}> Output </span>
|
<span style={{ bg: themeV2.raise(themeV2.background()), fg: themeV2.text.subdued() }}> Output </span>
|
||||||
</text>
|
</text>
|
||||||
<box paddingLeft={1}>
|
<box paddingLeft={1}>
|
||||||
<text fg={themeV2.text()} wrapMode="word">
|
<text fg={themeV2.text()} wrapMode="word">
|
||||||
@@ -2305,9 +2299,9 @@ function InlineToolLabel(props: { color?: RGBA; denied?: boolean; status: JSX.El
|
|||||||
}
|
}
|
||||||
|
|
||||||
function StatusBadge(props: { children: string }) {
|
function StatusBadge(props: { children: string }) {
|
||||||
const { themeV2, mode } = useTheme()
|
const { themeV2 } = useTheme()
|
||||||
return (
|
return (
|
||||||
<text flexShrink={0} bg={offsetBackground(themeV2, mode())} fg={themeV2.text.subdued()}>
|
<text flexShrink={0} bg={themeV2.raise(themeV2.background())} fg={themeV2.text.subdued()}>
|
||||||
{" "}
|
{" "}
|
||||||
{props.children}{" "}
|
{props.children}{" "}
|
||||||
</text>
|
</text>
|
||||||
@@ -2322,7 +2316,7 @@ function BlockTool(props: {
|
|||||||
part?: SessionMessageAssistantTool
|
part?: SessionMessageAssistantTool
|
||||||
spinner?: boolean
|
spinner?: boolean
|
||||||
}) {
|
}) {
|
||||||
const { themeV2, mode } = useTheme().contextual("elevated")
|
const { themeV2 } = useTheme().contextual("elevated")
|
||||||
const ctx = use()
|
const ctx = use()
|
||||||
const data = useData()
|
const data = useData()
|
||||||
const renderer = useRenderer()
|
const renderer = useRenderer()
|
||||||
@@ -2341,7 +2335,7 @@ function BlockTool(props: {
|
|||||||
paddingLeft={2}
|
paddingLeft={2}
|
||||||
gap={1}
|
gap={1}
|
||||||
backgroundColor={
|
backgroundColor={
|
||||||
hover() ? offsetBackground(themeV2, mode()) : themeV2.background()
|
hover() ? themeV2.raise(themeV2.background()) : themeV2.background()
|
||||||
}
|
}
|
||||||
customBorderChars={SplitBorder.customBorderChars}
|
customBorderChars={SplitBorder.customBorderChars}
|
||||||
borderColor={themeV2.background()}
|
borderColor={themeV2.background()}
|
||||||
|
|||||||
@@ -516,7 +516,7 @@ function RejectPrompt(props: { onConfirm: (message: string) => void; onCancel: (
|
|||||||
paddingLeft={2}
|
paddingLeft={2}
|
||||||
paddingRight={3}
|
paddingRight={3}
|
||||||
paddingBottom={1}
|
paddingBottom={1}
|
||||||
backgroundColor={themeV2.background.action("focused")}
|
backgroundColor={themeV2.raise(themeV2.background())}
|
||||||
justifyContent={narrow() ? "flex-start" : "space-between"}
|
justifyContent={narrow() ? "flex-start" : "space-between"}
|
||||||
alignItems={narrow() ? "flex-start" : "center"}
|
alignItems={narrow() ? "flex-start" : "center"}
|
||||||
gap={1}
|
gap={1}
|
||||||
@@ -693,7 +693,7 @@ function Prompt<const T extends Record<string, string>>(props: {
|
|||||||
paddingLeft={2}
|
paddingLeft={2}
|
||||||
paddingRight={3}
|
paddingRight={3}
|
||||||
paddingBottom={1}
|
paddingBottom={1}
|
||||||
backgroundColor={themeV2.background.action("focused")}
|
backgroundColor={themeV2.raise(themeV2.background())}
|
||||||
justifyContent={narrow() ? "flex-start" : "space-between"}
|
justifyContent={narrow() ? "flex-start" : "space-between"}
|
||||||
alignItems={narrow() ? "flex-start" : "center"}
|
alignItems={narrow() ? "flex-start" : "center"}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { RGBA } from "@opentui/core"
|
|||||||
import type { Accessor } from "solid-js"
|
import type { Accessor } from "solid-js"
|
||||||
import type {
|
import type {
|
||||||
ActionVariant,
|
ActionVariant,
|
||||||
|
Mode,
|
||||||
ResolvedActionState,
|
ResolvedActionState,
|
||||||
ResolvedThemeView,
|
ResolvedThemeView,
|
||||||
} from "./index"
|
} from "./index"
|
||||||
@@ -9,7 +10,7 @@ import { ActionState, HueStep } from "./schema"
|
|||||||
|
|
||||||
type StateFlags = Partial<Record<ActionState, boolean>>
|
type StateFlags = Partial<Record<ActionState, boolean>>
|
||||||
|
|
||||||
export function createComponentTheme(current: Accessor<ResolvedThemeView>) {
|
export function createComponentTheme(current: Accessor<ResolvedThemeView>, mode: Accessor<Mode>) {
|
||||||
const textAction = actions((variant, state) => current().text.action[variant][state])
|
const textAction = actions((variant, state) => current().text.action[variant][state])
|
||||||
const backgroundAction = actions((variant, state) => current().background.action[variant][state])
|
const backgroundAction = actions((variant, state) => current().background.action[variant][state])
|
||||||
const textFormfield = formfield((state) => current().text.formfield[state])
|
const textFormfield = formfield((state) => current().text.formfield[state])
|
||||||
@@ -78,6 +79,7 @@ export function createComponentTheme(current: Accessor<ResolvedThemeView>) {
|
|||||||
hue,
|
hue,
|
||||||
increase: (color: RGBA, amount = 1) => current().increase(color, amount),
|
increase: (color: RGBA, amount = 1) => current().increase(color, amount),
|
||||||
decrease: (color: RGBA, amount = 1) => current().decrease(color, amount),
|
decrease: (color: RGBA, amount = 1) => current().decrease(color, amount),
|
||||||
|
raise: (color: RGBA) => (mode() === "light" ? current().increase(color) : current().decrease(color)),
|
||||||
text,
|
text,
|
||||||
background,
|
background,
|
||||||
border: () => current().border.default,
|
border: () => current().border.default,
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
import { createComponent, createContext, useContext, type Accessor, type ParentProps } from "solid-js"
|
import { createComponent, createContext, useContext, type Accessor, type ParentProps } from "solid-js"
|
||||||
import { createComponentTheme, type ComponentTheme } from "./component"
|
import { createComponentTheme, type ComponentTheme } from "./component"
|
||||||
import type { ContextKey, ResolvedTheme } from "./index"
|
import type { ContextKey, Mode, ResolvedTheme } from "./index"
|
||||||
|
|
||||||
type ThemeRuntime = {
|
type ThemeRuntime = {
|
||||||
readonly resolved: Accessor<ResolvedTheme>
|
readonly resolved: Accessor<ResolvedTheme>
|
||||||
|
readonly mode: Accessor<Mode>
|
||||||
readonly component: ComponentTheme
|
readonly component: ComponentTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThemeContext = createContext<ThemeRuntime>()
|
const ThemeContext = createContext<ThemeRuntime>()
|
||||||
|
|
||||||
export function ThemeProvider(props: ParentProps<{ theme: ResolvedTheme }>) {
|
export function ThemeProvider(props: ParentProps<{ theme: ResolvedTheme; mode?: Mode }>) {
|
||||||
const resolved = () => props.theme
|
const resolved = () => props.theme
|
||||||
|
const mode = () => props.mode ?? "light"
|
||||||
return createComponent(ThemeContext.Provider, {
|
return createComponent(ThemeContext.Provider, {
|
||||||
value: { resolved, component: createComponentTheme(resolved) },
|
value: { resolved, mode, component: createComponentTheme(resolved, mode) },
|
||||||
get children() {
|
get children() {
|
||||||
return props.children
|
return props.children
|
||||||
},
|
},
|
||||||
@@ -28,7 +30,7 @@ export function ContextProvider(props: ParentProps<{ context: ContextKey }>) {
|
|||||||
}
|
}
|
||||||
context()
|
context()
|
||||||
return createComponent(ThemeContext.Provider, {
|
return createComponent(ThemeContext.Provider, {
|
||||||
value: { resolved: parent.resolved, component: createComponentTheme(context) },
|
value: { resolved: parent.resolved, mode: parent.mode, component: createComponentTheme(context, parent.mode) },
|
||||||
get children() {
|
get children() {
|
||||||
return props.children
|
return props.children
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,17 +9,19 @@ import type { ContextKey } from "../../../src/theme/v2"
|
|||||||
|
|
||||||
test("provides reactive property, variant, state, and context accessors", () => {
|
test("provides reactive property, variant, state, and context accessors", () => {
|
||||||
const [resolved, setResolved] = createSignal(resolveTheme(selectTheme(DEFAULT_THEME, "light")))
|
const [resolved, setResolved] = createSignal(resolveTheme(selectTheme(DEFAULT_THEME, "light")))
|
||||||
|
const [mode, setMode] = createSignal<"light" | "dark">("light")
|
||||||
const [context, setContext] = createSignal<ContextKey>()
|
const [context, setContext] = createSignal<ContextKey>()
|
||||||
const theme = createComponentTheme(() => {
|
const theme = createComponentTheme(() => {
|
||||||
const key = context()
|
const key = context()
|
||||||
return key ? resolved().contexts[key] ?? resolved() : resolved()
|
return key ? resolved().contexts[key] ?? resolved() : resolved()
|
||||||
})
|
}, mode)
|
||||||
|
|
||||||
expect(theme.text()).toBe(resolved().text.default)
|
expect(theme.text()).toBe(resolved().text.default)
|
||||||
expect(theme.hue.accent(500)).toBe(resolved().hue.accent[500])
|
expect(theme.hue.accent(500)).toBe(resolved().hue.accent[500])
|
||||||
expect(theme.hue.interactive(500)).toBe(resolved().hue.interactive[500])
|
expect(theme.hue.interactive(500)).toBe(resolved().hue.interactive[500])
|
||||||
expect(theme.hue.gray(200)).toBe(resolved().hue.gray[200])
|
expect(theme.hue.gray(200)).toBe(resolved().hue.gray[200])
|
||||||
expect(theme.increase(theme.background.surface.offset(), 1)).toBe(resolved().hue.neutral[300])
|
expect(theme.increase(theme.background.surface.offset(), 1)).toBe(resolved().hue.neutral[300])
|
||||||
|
expect(theme.raise(theme.background.surface.offset())).toBe(resolved().hue.neutral[300])
|
||||||
expect(theme.decrease(theme.hue.red(300), 2)).toBe(resolved().hue.red[100])
|
expect(theme.decrease(theme.hue.red(300), 2)).toBe(resolved().hue.red[100])
|
||||||
expect(theme.increase(theme.hue.red(900), 3)).toBe(resolved().hue.red[900])
|
expect(theme.increase(theme.hue.red(900), 3)).toBe(resolved().hue.red[900])
|
||||||
expect(theme.decrease(theme.hue.red(100), 3)).toBe(resolved().hue.red[100])
|
expect(theme.decrease(theme.hue.red(100), 3)).toBe(resolved().hue.red[100])
|
||||||
@@ -81,6 +83,8 @@ test("provides reactive property, variant, state, and context accessors", () =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
setResolved(resolveTheme(selectTheme(DEFAULT_THEME, "dark")))
|
setResolved(resolveTheme(selectTheme(DEFAULT_THEME, "dark")))
|
||||||
|
setMode("dark")
|
||||||
expect(theme.text()).toBe(resolved().contexts["@context:elevated"]!.text.default)
|
expect(theme.text()).toBe(resolved().contexts["@context:elevated"]!.text.default)
|
||||||
expect(theme.decrease(theme.background.surface.offset(), 1)).toBe(resolved().hue.neutral[700])
|
expect(theme.decrease(theme.background.surface.offset(), 1)).toBe(resolved().hue.neutral[700])
|
||||||
|
expect(theme.raise(theme.background.surface.offset())).toBe(resolved().hue.neutral[700])
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user